bintzwing/test/test.js
2010-05-26 15:34:42 -07:00

134 lines
3.7 KiB
JavaScript

sjcl.test = { vector: {}, all: {} };
/* A bit of a hack. Because sjcl.test will be reloaded several times
* for different variants of sjcl, but browserUtils will not, this
* variable keeps a permanent record of whether anything has failed.
*/
if (typeof browserUtil.allPassed === 'undefined') {
browserUtil.allPassed = true;
}
sjcl.test.TestCase = function(name, doRun) {
this.doRun = doRun;
this.name = name;
this.passes = 0;
this.failures = 0;
this.isUnimplemented = false;
sjcl.test.all[name] = this;
};
sjcl.test.TestCase.prototype = {
/** Pass some subtest of this test */
pass: function () { this.passes ++; },
/** Fail some subtest of this test */
fail: function (message) {
if (message !== undefined) {
this.log("fail", "*** FAIL *** " + this.name + ": " + message);
} else {
this.log("fail", "*** FAIL *** " + this.name);
}
this.failures ++;
browserUtil.allPassed = false;
},
unimplemented: function() {
this.isUnimplemented = true;
},
/** Log a message to the console */
log: browserUtil.write,
/** Require that the first argument is true; otherwise fail with the given message */
require: function (bool, message) {
if (bool) {
this.pass();
} else if (message !== undefined) {
this.fail(message);
} else {
this.fail("requirement failed");
}
},
/** Pause and then take the specified action. */
pauseAndThen: browserUtil.pauseAndThen,
/** Continuation-passing-style iteration */
cpsIterate: browserUtil.cpsIterate,
/** Continuation-passing-style iteration */
cpsMap: browserUtil.cpsMap,
/** Report the results of this test. */
report: function (repo) {
var t = (new Date()).valueOf() - this.startTime;
if (this.failures !== 0) {
repo.update("fail", "failed " + this.failures + " / " +
(this.passes + this.failures) + " tests. (" + t + " ms)");
} else if (this.passes === 1) {
repo.update("pass", "passed. (" + t + " ms)");
} else if (this.isUnimplemented) {
repo.update("unimplemented", "unimplemented");
} else {
repo.update("pass", "passed all " + this.passes + " tests. (" + t + " ms)");
}
browserUtil.writeNewline();
},
/** Run the test. */
run: function (ntests, i, cb) {
var thiz = this, repo = this.log("info", "Running " + this.name + "...");
this.startTime = (new Date()).valueOf();
this.pauseAndThen(function () {
thiz.doRun(function () {
thiz.report(repo);
cb && cb();
})
});
}
};
// pass a list of tests to run, or pass nothing and it will run them all
sjcl.test.run = function (tests, callback) {
var t;
if (tests === undefined || tests.length == 0) {
tests = [];
for (t in sjcl.test.all) {
if (sjcl.test.all.hasOwnProperty(t)) {
tests.push(t);
}
}
}
browserUtil.cpsMap(function (t, i, n, cb) {
sjcl.test.all[tests[i]].run(n, i+1, cb);
}, tests, true, callback);
};
/* Several test scripts rely on sjcl.codec.hex to parse their test
* vectors, but we are not guaranteed that sjcl.codec.hex is
* implemented.
*/
sjcl.codec = sjcl.codec || {};
sjcl.codec.hex = sjcl.codec.hex ||
{
fromBits: function (arr) {
var out = "", i, x;
for (i=0; i<arr.length; i++) {
out += ((arr[i]|0)+0xF00000000000).toString(16).substr(4);
}
return out.substr(0, sjcl.bitArray.bitLength(arr)/4);//.replace(/(.{8})/g, "$1 ");
},
toBits: function (str) {
var i, out=[], len;
str = str.replace(/\s|0x/g, "");
len = str.length;
str = str + "00000000";
for (i=0; i<str.length; i+=8) {
out.push(parseInt(str.substr(i,8),16)^0);
}
return sjcl.bitArray.clamp(out, len*4);
}
};