website:
Tests for Batch Guide code snippets
and some refactoring.

Make target for upgrading the Syncbase Android version used
throught the tutorials and guides.

Change-Id: I88219c9c0f9f1c3fa0c8f1659a3c2d89ae37d46c
diff --git a/Makefile b/Makefile
index 2901a8c..fa24d44 100644
--- a/Makefile
+++ b/Makefile
@@ -108,6 +108,7 @@
 syncbaseAndroidDataModel  = syncbase/guides/data-model
 syncbaseAndroidDataFlow   = syncbase/guides/data-flow
 syncbaseAndroidDataSync   = syncbase/guides/synchronization
+syncbaseAndroidBatches    = syncbase/guides/batches
 
 # Scripts that 'complete' the named tutorials, creating all relevant files
 # (code, credentials, etc.) but skipping ephemeral steps like starting servers,
@@ -381,16 +382,13 @@
 
 # An ordering that lets us test all the Java tutorials faster than running the
 # individual tests in sequence.
-depsOneBigJavaTutorialTest = \
-	content/$(tutJavaFortune).md \
-	content/$(tutJavaAndroid).md
-
 depsOneBigSyncbaseAndroidTest = \
 	content/$(syncbaseAndroidQuickstart).md \
 	content/$(syncbaseAndroidFirstApp).md \
 	content/$(syncbaseAndroidDataModel).md \
 	content/$(syncbaseAndroidDataFlow).md \
-	content/$(syncbaseAndroidDataSync).md
+	content/$(syncbaseAndroidDataSync).md \
+	content/$(syncbaseAndroidBatches).md
 
 .PHONY: test
 test: test-site test-tutorials-core test-tutorials-java test-syncbase-android
@@ -445,3 +443,30 @@
 .PHONY: test-tutorials-no-install
 test-tutorials-no-install: build
 	$(MDRIP) --subshell test $(depsOneBigCoreTutorialTest)
+
+# Used to upgrade all occurrences of
+# dependencies {
+#  compile 'io.v:syncbase:<version>'
+# }
+# to the constant $SYNCBASE_ANDROID_VERSION defined below.
+#
+# This target should be used as part of the release process to update
+# the website to the stable release of Syncbase Android.
+#
+# Please run the `test-syncbase-android` after upgrade and fix
+# any breaking API changes in the tutorials and code snippets before
+# committing and submitting the changes.
+#
+# Example flow:
+#
+# # Change SYNCBASE_ANDROID_VERSION to the newest version.
+# make upgrade-syncbase-android
+# make test-syncbase-android
+# git stage .
+# git commit -m "Upgrading Syncbase Android Version"
+# jiri cl mail
+.PHONY: upgrade-syncbase-android
+# Change this to the desired version before running the target.
+SYNCBASE_ANDROID_VERSION=0.1.4
+upgrade-syncbase-android:
+	find content/syncbase -type f -exec sed -i "s/\(compile 'io.v:syncbase:\)\(.*\)'/\1$(SYNCBASE_ANDROID_VERSION)'/g" {} \;
\ No newline at end of file
diff --git a/content/syncbase/guides/batches.md b/content/syncbase/guides/batches.md
index 5beaf2b..7a24cf2 100644
--- a/content/syncbase/guides/batches.md
+++ b/content/syncbase/guides/batches.md
@@ -5,6 +5,27 @@
 toc: true
 = yaml =
 
+{{# helpers.hidden }}
+<!-- @setupEnvironment @test -->
+```
+export PROJECT_DIR=$(mktemp -d "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX")
+export FILE=$PROJECT_DIR/app/src/main/java/io/v/syncbase/example/Batches.java
+cp -r $JIRI_ROOT/website/tools/android_project_stubs/example/* $PROJECT_DIR
+cat - <<EOF >> $PROJECT_DIR/app/build.gradle
+dependencies {
+  compile 'io.v:syncbase:0.1.4'
+}
+EOF
+cat - <<EOF > $FILE
+package io.v.syncbase.example;
+import io.v.syncbase.*;
+public class Batches {
+  Database db;
+  void main() {
+EOF
+```
+{{/ helpers.hidden }}
+
 # Introduction
 
 A batch is a group of read and write operations that are logically related.
@@ -47,7 +68,6 @@
 data from multiple collections, peers will receive only the parts of the batch
 they are allowed to see.
 
-
 # Using Batches
 
 `BatchDatabase` is the entry point to the batch API. `BatchDatabase` is similar to
@@ -61,7 +81,9 @@
 It detects *concurrent batch* errors and handles retries and commit/aborts
 automatically.
 
+<!-- @runInBatch @test -->
 ```Java
+cat - <<EOF | sed 's/{{.*}}//' >> $FILE
 db.runInBatch(new Database.BatchOperation() {
   @Override
   public void run(BatchDatabase batchDb) {
@@ -74,6 +96,7 @@
     // No need to commit. RunInBatch will commit and retry if necessary.
   }
 }, new Database.BatchOptions());
+EOF
 ```
 
 {{# helpers.warning }}
@@ -86,7 +109,17 @@
 **The following code snippet demonstrates the *WRONG* way of using batches.**
 {{/ helpers.warning }}
 
+{{# helpers.hidden }}
+<!-- @newScopeStart @test -->
+```
+cat - <<EOF >> $FILE
+{
+EOF
+```
+{{/ helpers.hidden }}
+<!-- @runInBatchWrong @test -->
 ```Java
+cat - <<EOF | sed 's/{{.*}}//' >> $FILE
 // WRONG: c1 is NOT part of the batch.
 final Collection c1 = db.collection("collection1");
 {{# helpers.codedim }}
@@ -105,14 +138,33 @@
     }
 }, new Database.BatchOptions());
 {{/ helpers.codedim }}
+EOF
 ```
+{{# helpers.hidden }}
+<!-- @newScopeEnd @test -->
+```
+cat - <<EOF >> $FILE
+}
+EOF
+```
+{{/ helpers.hidden }}
 
 ### BeginBatch
 `BeginBatch` is an alternative approach to starting a batch operation. Unlike
 `RunInBatch`, it does not manage retries and commit/aborts. They are left
 to the developers to manage themselves.
 
+{{# helpers.hidden }}
+<!-- @newScopeStart @test -->
+```
+cat - <<EOF >> $FILE
+{
+EOF
+```
+{{/ helpers.hidden }}
+<!-- @beginBatch @test -->
 ```Java
+cat - <<EOF | sed 's/{{.*}}//' >> $FILE
 BatchDatabase batchDb = db.beginBatch(new Database.BatchOptions());
 
 Collection c1 = batchDb.collection("collection1");
@@ -122,7 +174,16 @@
 c2.put("myKey", "myValue");
 
 batchDb.commit();
+EOF
 ```
+{{# helpers.hidden }}
+<!-- @newScopeEnd @test -->
+```
+cat - <<EOF >> $FILE
+}
+EOF
+```
+{{/ helpers.hidden }}
 
 {{# helpers.warning }}
 ## Warning
@@ -132,7 +193,17 @@
 **The following code snippet demonstrates the *WRONG* way of using batches.**
 {{/ helpers.warning }}
 
+{{# helpers.hidden }}
+<!-- @newScopeStart @test -->
+```
+cat - <<EOF >> $FILE
+{
+EOF
+```
+{{/ helpers.hidden }}
+<!-- @beginBatch @test -->
 ```Java
+cat - <<EOF | sed 's/{{.*}}//' >> $FILE
 // WRONG: c1 is NOT part of the batch.
 Collection c1 = db.collection("collection1");
 {{# helpers.codedim }}
@@ -151,8 +222,16 @@
 
 // WRONG: Throws exception since c2 is from an already committed batch.
 c2.put("myKey", "myValue");
-
+EOF
 ```
+{{# helpers.hidden }}
+<!-- @newScopeEnd @test -->
+```
+cat - <<EOF >> $FILE
+}
+EOF
+```
+{{/ helpers.hidden }}
 
 # Summary
 
@@ -160,4 +239,15 @@
 * Use the recommended `runInBatch` method to perform batch operations to
 get the added benefit of automatic retries and commit/abort.
 * Ensure all collection references are obtained from `BatchDatabase` otherwise
-mutations may not be part of a batch.
\ No newline at end of file
+mutations may not be part of a batch.
+
+{{# helpers.hidden }}
+<!-- @compileSnippets_mayTakeMinutes @test -->
+```
+cat - <<EOF >> $FILE
+  }
+}
+EOF
+cd $PROJECT_DIR && ./gradlew assembleRelease
+```
+{{/ helpers.hidden }}
\ No newline at end of file
diff --git a/content/syncbase/guides/data-flow.md b/content/syncbase/guides/data-flow.md
index 0851d6e..e14bf12 100644
--- a/content/syncbase/guides/data-flow.md
+++ b/content/syncbase/guides/data-flow.md
@@ -9,13 +9,14 @@
 <!-- @setupEnvironment @test -->
 ```
 export PROJECT_DIR=$(mktemp -d "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX")
+export FILE=$PROJECT_DIR/app/src/main/java/io/v/syncbase/example/DataFlow.java
 cp -r $JIRI_ROOT/website/tools/android_project_stubs/example/* $PROJECT_DIR
 cat - <<EOF >> $PROJECT_DIR/app/build.gradle
 dependencies {
   compile 'io.v:syncbase:0.1.4'
 }
 EOF
-cat - <<EOF > $PROJECT_DIR/app/src/main/java/io/v/syncbase/example/DataFlow.java
+cat - <<EOF > $FILE
 package io.v.syncbase.example;
 import io.v.syncbase.*;
 import java.util.HashMap;
@@ -60,7 +61,7 @@
 
 <!-- @addWatchHandler @test -->
 ```
-cat - <<EOF >> $PROJECT_DIR/app/src/main/java/io/v/syncbase/example/DataFlow.java
+cat - <<EOF >> $FILE
 db.addWatchChangeHandler(new Database.WatchChangeHandler() {
 
   @Override
@@ -95,7 +96,7 @@
 {{# helpers.hidden }}
 <!-- @closeMainFunction @test -->
 ```
-cat - <<EOF >> $PROJECT_DIR/app/src/main/java/io/v/syncbase/example/DataFlow.java
+cat - <<EOF >> $FILE
   }
 EOF
 ```
@@ -104,7 +105,7 @@
 Modeling our in-memory state as a map of Todolist-Id to a map of (Task-Id, Task)
 <!-- @updateState @test -->
 ```
-cat - <<EOF >> $PROJECT_DIR/app/src/main/java/io/v/syncbase/example/DataFlow.java
+cat - <<EOF >> $FILE
 HashMap<String, Map<String, Task>> state = new HashMap<String, Map<String, Task>>();
 
 // Update the state based on the changes.
@@ -149,7 +150,7 @@
 {{# helpers.hidden }}
 <!-- @compileSnippets_mayTakeMinues @test -->
 ```
-cat - <<EOF >> $PROJECT_DIR/app/src/main/java/io/v/syncbase/example/DataFlow.java
+cat - <<EOF >> $FILE
 }
 EOF
 cd $PROJECT_DIR && ./gradlew assembleRelease
diff --git a/content/syncbase/guides/data-model.md b/content/syncbase/guides/data-model.md
index a2aad2a..5191d3f 100644
--- a/content/syncbase/guides/data-model.md
+++ b/content/syncbase/guides/data-model.md
@@ -9,13 +9,14 @@
 <!-- @setupEnvironment @test -->
 ```
 export PROJECT_DIR=$(mktemp -d "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX")
+export FILE=$PROJECT_DIR/app/src/main/java/io/v/syncbase/example/DataModel.java
 cp -r $JIRI_ROOT/website/tools/android_project_stubs/example/* $PROJECT_DIR
 cat - <<EOF >> $PROJECT_DIR/app/build.gradle
 dependencies {
   compile 'io.v:syncbase:0.1.4'
 }
 EOF
-cat - <<EOF > $PROJECT_DIR/app/src/main/java/io/v/syncbase/example/DataModel.java
+cat - <<EOF > $FILE
 package io.v.syncbase.example;
 import io.v.syncbase.*;
 import java.util.ArrayList;
@@ -50,7 +51,7 @@
 
 <!-- @createDatabase @test -->
 ```
-cat - <<EOF >> $PROJECT_DIR/app/src/main/java/io/v/syncbase/example/DataModel.java
+cat - <<EOF >> $FILE
 Syncbase.DatabaseOptions options = new Syncbase.DatabaseOptions();
 // dbOpt.cloudSyncbaseAddress = "<Your Cloud Syncbase Address>";
 // dbOpt.cloudSyncbaseBlessing = "<Your Cloud Syncbase Blessing>";
@@ -98,7 +99,7 @@
 
 <!-- @createCollection @test -->
 ```
-cat - <<EOF >> $PROJECT_DIR/app/src/main/java/io/v/syncbase/example/DataModel.java
+cat - <<EOF >> $FILE
 String collectionName = UUID.randomUUID().toString();
 Collection collection = db.collection(collectionName);
 
@@ -148,7 +149,7 @@
 
 <!-- @addPojoToCollection @test -->
 ```
-cat - <<EOF >> $PROJECT_DIR/app/src/main/java/io/v/syncbase/example/DataModel.java
+cat - <<EOF >> $FILE
 class MyPojo {
   String foo;
   Integer bar;
@@ -250,7 +251,7 @@
 {{# helpers.hidden }}
 <!-- @compileSnippets_mayTakeMinutes @test -->
 ```
-cat - <<EOF >> $PROJECT_DIR/app/src/main/java/io/v/syncbase/example/DataModel.java
+cat - <<EOF >> $FILE
   }
 }
 EOF
diff --git a/content/syncbase/guides/synchronization.md b/content/syncbase/guides/synchronization.md
index 779dcf3..6f0ec16 100644
--- a/content/syncbase/guides/synchronization.md
+++ b/content/syncbase/guides/synchronization.md
@@ -9,13 +9,14 @@
 <!-- @setupEnvironment @test -->
 ```
 export PROJECT_DIR=$(mktemp -d "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX")
+export FILE=$PROJECT_DIR/app/src/main/java/io/v/syncbase/example/DataSync.java
 cp -r $JIRI_ROOT/website/tools/android_project_stubs/example/* $PROJECT_DIR
 cat - <<EOF >> $PROJECT_DIR/app/build.gradle
 dependencies {
   compile 'io.v:syncbase:0.1.4'
 }
 EOF
-cat - <<EOF > $PROJECT_DIR/app/src/main/java/io/v/syncbase/example/DataSync.java
+cat - <<EOF > $FILE
 package io.v.syncbase.example;
 import io.v.syncbase.*;
 import java.util.Iterator;
@@ -78,7 +79,7 @@
 syncgroup:
 <!-- @inviteUser @test -->
 ```
-cat - <<EOF >> $PROJECT_DIR/app/src/main/java/io/v/syncbase/example/DataSync.java
+cat - <<EOF >> $FILE
 Collection collectionToShare = db.collection("myCollection");
 
 collectionToShare.getSyncgroup().inviteUser(userToInvite, AccessList.AccessLevel.READ);
@@ -88,7 +89,7 @@
 On the invitee side, we need to handle invite requests by registering a handler:
 <!-- @addInviteHandler @test -->
 ```
-cat - <<EOF >> $PROJECT_DIR/app/src/main/java/io/v/syncbase/example/DataSync.java
+cat - <<EOF >> $FILE
 db.addSyncgroupInviteHandler(new Database.SyncgroupInviteHandler() {
   @Override
   public void onInvite(SyncgroupInvite invite) {
@@ -125,7 +126,7 @@
 
 <!-- @unshareCollection @test -->
 ```
-cat - <<EOF >> $PROJECT_DIR/app/src/main/java/io/v/syncbase/example/DataSync.java
+cat - <<EOF >> $FILE
 Collection sharedCollection = db.collection("myCollection");
 
 sharedCollection.getSyncgroup().ejectUser(userToRemove);
@@ -144,7 +145,7 @@
 
 <!-- @getAllSyncgroups @test -->
 ```Java
-cat - <<EOF >> $PROJECT_DIR/app/src/main/java/io/v/syncbase/example/DataSync.java
+cat - <<EOF >> $FILE
 Iterator<Syncgroup> allSyncgroups = db.getSyncgroups();
 while(allSyncgroups.hasNext()) {
     Syncgroup sg = allSyncgroups.next();
@@ -166,7 +167,7 @@
 {{# helpers.hidden }}
 <!-- @compileSnippets_mayTakeMinutes @test -->
 ```
-cat - <<EOF >> $PROJECT_DIR/app/src/main/java/io/v/syncbase/example/DataSync.java
+cat - <<EOF >> $FILE
   }
 }
 EOF