blob: 7f8a07877e1f26023e86ba98f30586b5c297e9fc [file] [log] [blame]
// 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);
return value.replace(/^\s+|\s+$/g,"");
}
}
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:5984" : window;
CouchDB.request = function(method, uri, options) {
var full_uri = "http://" + CouchDB.host + 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 couchTests) {
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 = couchTests[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);
try {
p("Version: "+CouchDB.getVersion()+"\n");
runAllTestsConsole();
// runTestConsole(tests.attachments);
} catch (e) {
p(e.toString());
}
p("\nFinished");