Commits

Anonymous committed 91525b2

Merging in workaround for regex replace bug in Spidermonkey;Latest round of unit testing for riak.js

Comments (0)

Files changed (5)

apps/erlang_js/priv/json2.js

 // ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
 
             if (/^[\],:{}\s]*$/.
-test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@').
-replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').
+test(text.replace(/\\(?:["\\\/bfnt]|u[0-9a-fA-F]{4})/g, '@').
+replace(/"[^"\\\n]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').
 replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
 
 // In the third stage we use the eval function to compile the text into a

client_lib/javascript/riak.js

 							 callback(true, JSON.parse(req.responseText), req);
 						       }
 						       else {
-							 callback(false, null, req);
-						       }
-						     } } });
+							 try {
+							   var error = {error: JSON.parse(req.responseText)};
+							   callback(false, error, req);
+							 }
+							 catch (e) {
+							   callback(false, null, req);
+							 }
+						       } } } });
 };
 
 /** Start RiakMapper internals **/
   if (typeof options.source === 'function') {
       options.source = options.source.toString();
   }
-  if (options.language === null || options.language === undefined) {
+  if ((starter.map === null ||
+       starter.reduce === null) && (options.language === null || options.language === undefined)) {
     options.language = 'javascript';
   }
   if (starter.map === null) {
  * @return RiakMapper object
  */
 RiakBucket.prototype.reduce = function(options) {
-  var mapper = new RiakMapper(this.client, this.bucket);
+  var mapper = new RiakMapper(this.client, this.name);
   return mapper.reduce(options);
 };
 
  * @return RiakMapper object
  */
 RiakBucket.prototype.link = function(options) {
-  var mapper = new RiakMapper(this.client, this.bucket);
+  var mapper = new RiakMapper(this.client, this.name);
+  options.bucket = this.name;
   return mapper.link(options);
 };
 

client_lib/javascript/tests/setup

 #!/bin/sh
 
+## Edit these values to point to point to
+## your Riak server.
+HOST=localhost
+PORT=8098
+
 populate_mapred_data() {
     echo "Populating test map/reduce data"
-    curl -X PUT -H "content-type:text/plain" -H "Link:</riak/mr_test/second>;riaktag=\"test\"" http://$1:8098/riak/mr_test/first --data "1"
-    curl -X PUT -H "content-type: text/plain" -H "Link: </riak/mr_test/third>;riaktag=\"test\"" http://$1:8098/riak/mr_test/second --data "1"
-    curl -X PUT -H "content-type: text/plain" http://$1:8098/riak/mr_test/third --data "1"
+    curl -X PUT -H "content-type:text/plain" -H "Link:</riak/mr_test/second>;riaktag=\"test\"" http://$1:$2/riak/mr_test/first --data "1"
+    curl -X PUT -H "content-type: text/plain" -H "Link: </riak/mr_test/third>;riaktag=\"test\"" http://$1:$2/riak/mr_test/second --data "1"
+    curl -X PUT -H "content-type: text/plain" http://$1:$2/riak/mr_test/third --data "1"
 }
 
 clear_mapred_data() {
     echo "Deleting test map/reduce data"
-    curl --silent -X DELETE http://$1:8098/riak/mr_test/first -o /dev/null
-    curl --silent -X DELETE http://$1:8098/riak/mr_test/second -o /dev/null
-    curl --silent -X DELETE http://$1:8098/riak/mr_test/third -o /dev/null
+    curl --silent -X DELETE http://$1:$2/riak/mr_test/first -o /dev/null
+    curl --silent -X DELETE http://$1:$2/riak/mr_test/second -o /dev/null
+    curl --silent -X DELETE http://$1:$2/riak/mr_test/third -o /dev/null
 }
 
 clear_test_data() {
     echo "Deleting test data"
-    curl --silent -X DELETE http://$1:8098/riak/basho_test/td1 -o /dev/null
+    curl --silent -X DELETE http://$1:$2/riak/basho_test/td1 -o /dev/null
 }
 
 case $1 in
     "-i")
 	for file in `ls *.js ../*.js`; do
 	    echo "Storing `basename $file`"
-	    curl -X PUT -H "content-type:text/javascript" http://$2:8098/riak/basho_test/`basename $file` --data-binary @$file
+	    curl -X PUT -H "content-type:text/javascript" http://$HOST:$PORT/riak/basho_test/`basename $file` --data-binary @$file
 	done
 	for file in `ls *.html`; do
 	    echo "Storing $file"
-	    curl -X PUT -H "content-type:text/html" http://$2:8098/riak/basho_test/$file --data-binary @$file
+	    curl -X PUT -H "content-type:text/html" http://$HOST:$PORT/riak/basho_test/$file --data-binary @$file
 	done
 	for file in `ls *.css`; do
 	    echo "Storing $file"
-	    curl -X PUT -H "content-type:text/css" http://$2:8098/riak/basho_test/$file --data-binary @$file
+	    curl -X PUT -H "content-type:text/css" http://$HOST:$PORT/riak/basho_test/$file --data-binary @$file
 	done
-	clear_test_data $2
-	populate_mapred_data $2
+	clear_test_data $HOST $PORT
+	populate_mapred_data $HOST $PORT
 	;;
     "-c")
 	clear_test_data
     "-u")
 	for file in `ls *.js *.css *.html ../*.js`; do
 	    echo "Deleting `basename $file`"
-	    curl --silent -X DELETE http://$2:8098/riak/basho_test/`basename $file` -o /dev/null
+	    curl --silent -X DELETE http://$HOST:$PORT/riak/basho_test/`basename $file` -o /dev/null
 	done
-	clear_test_data $2
-	clear_mapred_data $2
+	clear_test_data $HOST $PORT
+	clear_mapred_data $HOST $PORT
 	;;
     *)
-	echo "$0 -i host (to install test infrastructure)"
-	echo "$0 -c host (to clear test data)"
-	echo "$0 -d host (to uninstall test infrastructure)"
+	echo "$0 -i to install test infrastructure"
+	echo "$0 -c to clear transient test data"
+	echo "$0 -d to uninstall test infrastructure"
 esac

client_lib/javascript/tests/tests.html

     <h2 id="qunit-banner"></h2>
     <h2 id="qunit-userAgent"></h2>
     <ol id="qunit-tests"></ol>
+    Note: Unit tests may report spurious errors if the page is refreshed. Shift-Refresh is the path to true testing nirvana!
   </body>
 </html>
 </html>

client_lib/javascript/tests/unit_tests.js

 var MR_TEST_BUCKET = 'mr_test';
 
 var currentClient = null;
-var currentBucket = null;
-var currentObject = null;
 
 /** Start helpers **/
-function log(output) {
-  if (console !== undefined) {
-    console.log(output);
-  }
-};
-
 function findLink(object, tag, link) {
   var found = false;
   var links = object.getLinks();
   }
   return found;
 };
+
+function setupClient() {
+  currentClient = new RiakClient();
+};
+
+function setupBucket(test) {
+  setupClient();
+  currentClient.bucket(TEST_BUCKET, test);
+}
+
+function setupObject(createIfMissing, test) {
+  setupClient();
+  if (createIfMissing === true) {
+    setupBucket(function(bucket, req) {
+		  bucket.get_or_new('td1', test); } );
+  }
+  else {
+    setupBucket(function(bucket, req) {
+		bucket.get('td1', test); } );
+  }
+}
+
+function storeObject(test) {
+  setupClient();
+  setupObject(true, function(obj, req) {
+		obj.store(test); } );
+}
+
 /** End helpers **/
 
 function lookupMissingObject() {
   stop();
-  currentClient = new RiakClient();
-  currentClient.bucket(TEST_BUCKET, function(bucket, req) {
-			 currentBucket = bucket;
-			 currentBucket.get("td1", function(object, req) {
-					     ok(object == null, "Nonexistent object returns null");
-					     start(); } ); } );
+  setupObject(false, function(object, req) {
+		ok(object == null, "Nonexistent object returns null");
+		start(); } );
 };
 
 function createMissingObject() {
   stop();
-  currentBucket.get_or_new("td1", function(object, req) {
-				      ok(object, "Nonexistent object created");
-				      start(); } );
+  setupObject(true, function(object, req) {
+		ok(object, "Nonexistent object created");
+		start(); } );
 };
 
 function storeMissingObject() {
   stop();
-  currentBucket.get_or_new("td1", function(object, req) {
-			     object.store(function(object, req) {
-					    ok(object !== null, "Object saved");
-					    ok(object.vclock !== null &&
-					       object.vclock.length > 0, "Object vclock set");
-					    currentObject = object;
-					    start(); } ); } );
+  setupObject(true, function(object, req) {
+		object.store(function(object, req) {
+			       ok(object !== null, "Object saved");
+			       ok(object.vclock !== null &&
+				  object.vclock.length > 0, "Object vclock set");
+			       start(); } ); } );
 };
 
 function updateObject() {
   stop();
-  currentObject.store(function(n, req) {
-			if (n !== null) {
-			  equals(n !== null, true, "Object saved");
-			  ok(n.vclock !== null &&
-			     n.vclock.length > 0, "Object vclock set");
-			  n.body = "Testing";
-			  n.contentType = "text/plain";
-			  n.store(function(newObj, req) {
-				    ok(newObj != null, "Object updated");
-				    ok(newObj.vclock !== n.vclock, "Vclock changed");
-				    currentObject = newObj;
-				    start(); } );
-			}
-			else {
-			  throw("Object not updated!");
-			} } );
+  storeObject(function(obj, req) {
+		ok(obj !== null, "Object saved");
+		ok(obj.vclock !== null &&
+		   obj.vclock.length > 0, "Object vclock set");
+		obj.body = "Testing";
+		obj.contentType = "text/plain";
+		obj.store(function(newObj, req) {
+			  ok(newObj != null, "Object updated");
+			  ok(newObj.vclock !== obj.vclock, "Vclock changed");
+			  start(); } ); } );
 };
 
 function deleteObject() {
   stop();
-  currentObject.remove(function(flag, req) {
-			 ok(flag === true, "Object deleted");
-			 start(); } );
+  storeObject(function(obj, req) {
+		obj.remove(function(flag, req) {
+			     ok(flag === true, "Object deleted");
+			     start(); } ); } );
 };
 
 function storeLink() {
   stop();
   var link = '/riak/' + TEST_BUCKET + '/td1';
-  currentBucket.get_or_new("td1", function(object, req) {
-			     object.store(function(object, req) {
-					    ok(object !== null, "Object saved");
-					    ok(object.links.length == 1, "New object has 1 link");
-					    object.addLink(link, "testlink");
-					    object.store(function(newObj, req) {
-							   ok(newObj !== null, "Object saved");
-							   ok(newObj.vclock !== object.vclock, "Vclock changed");
-							   ok(newObj.getLinks().length == 2, "Link was saved");
-							   ok(findLink(newObj, "testlink", link), "Link was found in collection");
-							   currentObject = newObj;
-							   start(); } ); } ); } );
+  storeObject(function(object, req) {
+		object.store(function(object, req) {
+			       ok(object !== null, "Object saved");
+			       ok(object.links.length == 1, "New object has 1 link");
+			       object.addLink(link, "testlink");
+			       object.store(function(newObj, req) {
+					      ok(newObj !== null, "Object saved");
+					      ok(newObj.vclock !== object.vclock, "Vclock changed");
+					      ok(newObj.getLinks().length == 2, "Link was saved");
+					      ok(findLink(newObj, "testlink", link), "Link was found in collection");
+					      start(); } ); } ); } );
 };
 
 function deleteLink() {
   stop();
-  currentObject.links = [];
-  currentObject.store(function(obj, req) {
-			ok(obj !== null, "Object saved");
-			equals(obj.links.length, 1, "Links collection reset");
-			currentObject = obj;
-			start(); } );
+  setupObject(false, function(obj, req) {
+		obj.clearLinks();
+		obj.store(function(n, req) {
+			    ok(n !== null, "Object saved");
+			    equals(n.links.length, 1, "Links collection reset");
+			    start(); } ); } );
 };
 
 function readNValue() {
   stop();
-  currentClient.bucket(TEST_BUCKET, function(bucket, req) {
-			 ok(bucket.nValue() > 0, "N-Value default is set");
-			 currentBucket = bucket;
-			 start(); } );
+  setupBucket(function(bucket, req) {
+		ok(bucket.nValue() > 0, "N-Value is set");
+		start(); } );
 }
 
 function readAllowMult() {
   stop();
-  currentClient.bucket(TEST_BUCKET, function(bucket, req) {
-		       equals(bucket.allowsMultiples(), false, "allowsMultiples defaults to false");
-		       currentBucket = bucket;
-		       start(); } );
+  setupBucket(function(bucket, req) {
+		equals(bucket.allowsMultiples(), false, "allowsMultiples defaults to false");
+		start(); } );
 }
 
 function updateNValue() {
   stop();
-  currentBucket.nValue(5);
-  currentBucket.store(function(bucket, req) {
-			equals(bucket.nValue(), 5, "N-Value updated");
-		        bucket.nValue(3);
-		        bucket.store(function(b, req) {
-				     equals(b.nValue(), 3);
-				     currentBucket = b;
-				     start(); } ); } );
+  setupBucket(function(bucket, req) {
+		var old = bucket.nValue();
+		bucket.nValue(bucket.nValue() + 1);
+		bucket.store(function(nb, req) {
+			       equals(nb.nValue(), 4, "N-Value updated");
+		               nb.nValue(nb.nValue() - 1);
+		               nb.store(function(b, req) {
+					  equals(b.nValue(), old);
+					  start(); } ); } ); } );
 }
 
 function updateAllowMult() {
   stop();
-  currentBucket.allowsMultiples(true);
-  currentBucket.store(function(bucket, req) {
-			equals(bucket.allowsMultiples(), true, "allowsMultiples updated");
-		        bucket.allowsMultiples(false);
-		        bucket.store(function(b, req) {
-				     equals(b.allowsMultiples(), false, "allowsMultiples reset to default");
-				     currentBucket = b;
-				     start(); } ); } );
-}
-
-function updateSmallClock() {
-  stop();
-  currentBucket.props.small_vclock = 5;
-  currentBucket.store(function(b, req) {
-		      equals(b.props.small_vclock, 5),
-		      currentBucket = b;
-		      start(); } );
+  setupBucket(function(bucket, req) {
+		bucket.allowsMultiples(true);
+		bucket.store(function(nb, req) {
+			       equals(nb.allowsMultiples(), true, "allowsMultiples updated");
+			       nb.allowsMultiples(false);
+			       nb.store(function(b, req) {
+					  equals(b.allowsMultiples(), false, "allowsMultiples reset to default");
+					  start(); } ); } ); } );
 }
 
 function bucketMap() {
   stop();
+  setupClient();
   currentClient.bucket(MR_TEST_BUCKET, function(bucket, req) {
 			   bucket.map({language: 'javascript',
 				       name: 'Riak.mapValuesJson',
 				       keep: true}).run(function(flag, results, req) {
+							  ok(flag, 'Job ran successfully');
 							  ok(results !== null, 'Map results not null');
 							  equals(results.length, 3, 'Map results contain data');
 							  start(); } ); } );
 
 function bucketMapReduce() {
   stop();
+  setupClient();
+  currentClient.bucket(MR_TEST_BUCKET, function(bucket, req) {
+			 bucket.map({language: 'javascript',
+				     name: 'Riak.mapValuesJson',
+				     keep: false}).reduce({language: 'javascript',
+							   name: 'Riak.reduceSum',
+							   keep: true}).run(function(flag, results, req) {
+									      ok(flag, 'Job ran successfully');
+									      ok(results !== null, 'Reduce results not null');
+									      equals(results.length, 1, 'Map/Reduce results contain data');
+									      equals(results[0], 3, 'Map/Reduce summed correctly');
+									      start(); } ); } );
 }
 
-$(document).ready(function() {
-		    module("Storage");
-		    test("Lookup missing object", 1, lookupMissingObject);
-		    test("Create", 1, createMissingObject);
-		    test("Store", 2, storeMissingObject);
-		    test("Update", 4, updateObject);
-		    test("Delete", 1, deleteObject);
+function objectMap() {
+  stop();
+  setupClient();
+  currentClient.bucket(MR_TEST_BUCKET, function(bucket, req) {
+			 bucket.get('first', function(obj, req) {
+				      ok(obj, 'M/R test object found');
+				      obj.map({language: 'javascript',
+					       source: function(obj)  { return Riak.mapValuesJson(obj); },
+					       keep: true}).run(function(flag, results, req) {
+								  ok(flag, 'Job ran successfully');
+								  ok(results !== null, 'Map results not null');
+								  equals(results.length, 1, 'Map results contain data');
+								  equals(results[0], 1, 'Map results are correct');
+								  start(); } ); } ); } );
+}
 
-		    module("Links");
-		    test("Create", 1, createMissingObject);
-		    test("Update", 6, storeLink);
-		    test("Delete", 2, deleteLink);
+function objectMapReduce() {
+  stop();
+  setupClient();
+  currentClient.bucket(MR_TEST_BUCKET, function(bucket, req) {
+			 bucket.get('first', function(obj, req) {
+				      ok(obj, 'M/R test object found');
+				      obj.map({language: 'javascript',
+					       source: function(obj)  { return Riak.mapValuesJson(obj); },
+					       keep: false}).reduce({language: 'javascript',
+								     source: function(value, arg) { return [value[0] * 5]; },
+								     keep: true}).run(function(flag, results, req) {
+											ok(flag, 'Job ran successfully');
+											ok(results !== null, 'Map results not null');
+											equals(results.length, 1, 'Map results contain data');
+											equals(results[0], 5, 'Reduce results are correct');
+											start(); } ); } ); } );
+}
 
-		    module("Bucket Properties");
-		    test("N-Value", 1, readNValue);
-		    test("Update N-Value", 2, updateNValue);
-		    test("Allow Multiples", 1, readAllowMult);
-		    test("Update Allow Multiples", 2, updateAllowMult);
-		    test("Set Small Clock Bucket Property", 1, updateSmallClock);
+function bucketLinkWalk() {
+  stop();
+  setupClient();
+  currentClient.bucket(MR_TEST_BUCKET, function(bucket, req) {
+			 bucket.link({tag: 'test'}).run(function(flag, results, req) {
+							  ok(flag, 'Job ran successfully');
+							  ok(results !== null, 'Map results not null');
+							  equals(results.length, 2, 'Link results are correct');
+							  start(); } ); } );
+}
 
-		    module("Map/Reduce");
-		    test("Bucket-level map", 2, bucketMap); } );
+function badMap() {
+  stop();
+  setupClient();
+  currentClient.bucket(MR_TEST_BUCKET, function(bucket, req) {
+			   bucket.map({language: 'javascript',
+				       source: function(value) { return [JSON.parse(value)]; },
+				       keep: true}).run(function(flag, results, req) {
+							  ok(!flag, 'Job failed');
+							  ok(results.error !== null, 'Error returned from server');
+							  ok(results.error.lineno > 0, 'Line number given');
+							  ok(results.error.message.length > 0, 'Error message given');
+							  start(); } ); } );
+
+}
+
+function runTests() {
+  module("Storage");
+  /*test("Lookup missing object", 1, lookupMissingObject);*/
+  test("Create", 1, createMissingObject);
+  test("Store", 2, storeMissingObject);
+  test("Update", 4, updateObject);
+  test("Delete", 1, deleteObject);
+
+  module("Links");
+  test("Create", 1, createMissingObject);
+  test("Update", 6, storeLink);
+  test("Delete", 2, deleteLink);
+
+  module("Bucket Properties");
+  test("N-Value", 1, readNValue);
+  test("Update N-Value", 2, updateNValue);
+  test("Allow Multiples", 1, readAllowMult);
+  test("Update Allow Multiples", 2, updateAllowMult);
+
+  module("Map/Reduce");
+  test("Bucket-level map", 3, bucketMap);
+  test("Bucket-level map/reduce", 4, bucketMapReduce);
+  test("Object-level map", 5, objectMap);
+  test("Object-level map/reduce", 5, objectMapReduce);
+  test("Bad Map job", 4, badMap);
+
+  module("Link walking");
+  test("Bucket-level link walk", 3, bucketLinkWalk);
+}
+
+$(document).ready(runTests);
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.