summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorJohn Christopher Anderson <jchris@apache.org>2008-10-09 22:04:46 +0000
committerJohn Christopher Anderson <jchris@apache.org>2008-10-09 22:04:46 +0000
commit5b2760e14a60e7447f04b58879fcdbc0c45c04df (patch)
tree218bb23af2781d7170c4917ff678ef570150fb60 /test
parent929607cf0512010f45c9fbf8f38ef844996845f8 (diff)
make check now runs the JavaScript test suite
git-svn-id: https://svn.apache.org/repos/asf/incubator/couchdb/trunk@703276 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'test')
-rwxr-xr-xtest/runner.sh2
-rw-r--r--test/test.js252
2 files changed, 254 insertions, 0 deletions
diff --git a/test/runner.sh b/test/runner.sh
index ae0f1ef8..e071ad63 100755
--- a/test/runner.sh
+++ b/test/runner.sh
@@ -1,3 +1,5 @@
#!/bin/sh -e
erl -noshell -pa ../src/couchdb -pa ../src/mochiweb -eval "runner:run()"
+
+cat ../share/www/script/couch.js ../share/www/script/couch_tests.js test.js | ../src/couchdb/couchjs -
diff --git a/test/test.js b/test/test.js
new file mode 100644
index 00000000..1d3e989b
--- /dev/null
+++ b/test/test.js
@@ -0,0 +1,252 @@
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy
+// of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+// couch.js, with modifications
+
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy
+// of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+// some monkeypatches
+var JSON = {
+ parse : function(string) {
+ return eval('('+string+')');
+ },
+ stringify : function(obj) {
+ return toJSON(obj||null);
+ }
+};
+
+RegExp.escape = function(text) {
+ if (!arguments.callee.sRE) {
+ var specials = [
+ '/', '.', '*', '+', '?', '|',
+ '(', ')', '[', ']', '{', '}', '\\'
+ ];
+ arguments.callee.sRE = new RegExp(
+ '(\\' + specials.join('|\\') + ')', 'g'
+ );
+ }
+ return text.replace(arguments.callee.sRE, '\\$1');
+}
+
+// This is a JS wrapper for the curl function made available in couch_js.c,
+// it should be used in other JavaScripts that would like to make HTTP calls.
+
+var HTTP = (function() {
+ function parseCurl(string) {
+ var parts = string.split(/\r\n\r\n/);
+ var body = parts.pop();
+ var header = parts.pop();
+ var headers = header.split(/\n/);
+
+ var status = /HTTP\/1.\d (\d*)/.exec(header)[1];
+ return {
+ responseText: body,
+ status: parseInt(status),
+ getResponseHeader: function(key) {
+ var keymatcher = new RegExp(RegExp.escape(key), "i");
+ for (var i in headers) {
+ var h = headers[i];
+ if (keymatcher.test(h)) {
+ var value = h.substr(key.length+2);
+ value = value.slice(0, value.length-1);
+ return value;
+ }
+ }
+ return "";
+ }
+ }
+ };
+ return {
+ GET : function(url, body, headers) {
+ var st, urx = url, hx = (headers || null);
+ st = gethttp(urx, hx);
+ return parseCurl(st);
+ },
+ HEAD : function(url, body, headers) {
+ var st, urx = url, hx = (headers || null);
+ st = headhttp(urx, hx);
+ return parseCurl(st);
+ },
+ DELETE : function(url, body, headers) {
+ var st, urx = url, hx = (headers || null);
+ st = delhttp(urx, hx);
+ return parseCurl(st);
+ },
+ MOVE : function(url, body, headers) {
+ var st, urx = url, hx = (headers || null);
+ st = movehttp(urx, hx);
+ return parseCurl(st);
+ },
+ COPY : function(url, body, headers) {
+ var st, urx = url, hx = (headers || null);
+ st = copyhttp(urx, hx);
+ return parseCurl(st);
+ },
+ POST : function(url, body, headers) {
+ var st, urx = url, bx = (body || ""), hx = (headers || {});
+ hx['Content-Type'] = hx['Content-Type'] || "application/json";
+ st = posthttp(urx, bx, hx);
+ return parseCurl(st);
+ },
+ PUT : function(url, body, headers) {
+ var st, urx = url, bx = (body || ""), hx = (headers || {});
+ hx['Content-Type'] = hx['Content-Type'] || "application/json";
+ st = puthttp(urx, bx, hx);
+ return parseCurl(st);
+ }
+ };
+})();
+
+// Monkeypatches to CouchDB client for use of curl.
+
+CouchDB.host = (typeof window == 'undefined' || !window) ? "127.0.0.1" : window;
+CouchDB.port = 5984;
+
+CouchDB.request = function(method, uri, options) {
+ var full_uri = "http://" + CouchDB.host + ":" + CouchDB.port + uri;
+ options = options || {};
+ var response = HTTP[method](full_uri, options.body, options.headers);
+ return response;
+}
+
+
+function toJSON(val) {
+ if (typeof(val) == "undefined") {
+ throw {error:"bad_value", reason:"Cannot encode 'undefined' value as JSON"};
+ }
+ var subs = {'\b': '\\b', '\t': '\\t', '\n': '\\n', '\f': '\\f',
+ '\r': '\\r', '"' : '\\"', '\\': '\\\\'};
+ if (typeof(val) == "xml") { // E4X support
+ val = val.toXMLString();
+ }
+ return {
+ "Array": function(v) {
+ var buf = [];
+ for (var i = 0; i < v.length; i++) {
+ buf.push(toJSON(v[i]));
+ }
+ return "[" + buf.join(",") + "]";
+ },
+ "Boolean": function(v) {
+ return v.toString();
+ },
+ "Date": function(v) {
+ var f = function(n) { return n < 10 ? '0' + n : n }
+ return '"' + v.getUTCFullYear() + '-' +
+ f(v.getUTCMonth() + 1) + '-' +
+ f(v.getUTCDate()) + 'T' +
+ f(v.getUTCHours()) + ':' +
+ f(v.getUTCMinutes()) + ':' +
+ f(v.getUTCSeconds()) + 'Z"';
+ },
+ "Number": function(v) {
+ return isFinite(v) ? v.toString() : "null";
+ },
+ "Object": function(v) {
+ if (v === null) return "null";
+ var buf = [];
+ for (var k in v) {
+ if (!v.hasOwnProperty(k) || typeof(k) !== "string" || v[k] === undefined) {
+ continue;
+ }
+ buf.push(toJSON(k, val) + ": " + toJSON(v[k]));
+ }
+ return "{" + buf.join(",") + "}";
+ },
+ "String": function(v) {
+ if (/["\\\x00-\x1f]/.test(v)) {
+ v = v.replace(/([\x00-\x1f\\"])/g, function(a, b) {
+ var c = subs[b];
+ if (c) return c;
+ c = b.charCodeAt();
+ return '\\u00' + Math.floor(c / 16).toString(16) + (c % 16).toString(16);
+ });
+ }
+ return '"' + v + '"';
+ }
+ }[val != null ? val.constructor.name : "Object"](val);
+}
+
+
+
+// *************** Test Framework Console Adapter ****************** //
+
+var p = print;
+var numFailures = 0;
+
+function runAllTestsConsole() {
+ var numTests = 0;
+ var debug = false;
+ for (var t in tests) {
+ p(t);
+ if (t == "utf8") {
+ p("We skip the utf8 test because it fails due to problems in couch_js.c");
+ p("Run the in-browser tests to verify utf8.\n");
+ } else {
+ numTests += 1;
+ var testFun = tests[t];
+ runTestConsole(testFun, debug);
+ }
+ }
+ p("Results: "+numFailures.toString() + " failures in "+numTests+" tests.")
+};
+
+function runTestConsole(testFun, debug) {
+ var start = new Date().getTime();
+ try {
+ if (!debug) testFun = patchTest(testFun) || testFun;
+ testFun();
+ p("PASS");
+ } catch(e) {
+ p("ERROR");
+ p("Exception raised: "+e.toString());
+ p("Backtrace: "+e.stack);
+ }
+ var duration = new Date().getTime() - start;
+ p(duration+"ms\n");
+};
+
+
+// Use T to perform a test that returns false on failure and if the test fails,
+// display the line that failed.
+// Example:
+// T(MyValue==1);
+function T(arg1, arg2) {
+ if (!arg1) {
+ p("Assertion failed: "+(arg2 != null ? arg2 : arg1).toString());
+ numFailures += 1
+ }
+}
+
+p("Running CouchDB Test Suite\n");
+p("Host: "+CouchDB.host);
+p("Port: "+CouchDB.port);
+
+try {
+ p("Version: "+CouchDB.getVersion()+"\n");
+ runAllTestsConsole();
+ // runTestConsole(tests.attachments);
+} catch (e) {
+ p(e.toString());
+}
+
+p("\nFinished");