1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
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);
}
};
|