1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/testing/modules/tests/xpcshell/test_assert.js Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,302 @@ 1.4 +/* Any copyright is dedicated to the Public Domain. 1.5 + http://creativecommons.org/publicdomain/zero/1.0/ */ 1.6 + 1.7 +// Test cases borrowed and adapted from: 1.8 +// https://github.com/joyent/node/blob/6101eb184db77d0b11eb96e48744e57ecce4b73d/test/simple/test-assert.js 1.9 +// MIT license: http://opensource.org/licenses/MIT 1.10 + 1.11 +function run_test() { 1.12 + let ns = {}; 1.13 + Components.utils.import("resource://testing-common/Assert.jsm", ns); 1.14 + let assert = new ns.Assert(); 1.15 + 1.16 + function makeBlock(f, ...args) { 1.17 + return function() { 1.18 + return f.apply(assert, args); 1.19 + }; 1.20 + } 1.21 + 1.22 + function protoCtrChain(o) { 1.23 + let result = []; 1.24 + while (o = o.__proto__) { 1.25 + result.push(o.constructor); 1.26 + } 1.27 + return result.join(); 1.28 + } 1.29 + 1.30 + function indirectInstanceOf(obj, cls) { 1.31 + if (obj instanceof cls) { 1.32 + return true; 1.33 + } 1.34 + let clsChain = protoCtrChain(cls.prototype); 1.35 + let objChain = protoCtrChain(obj); 1.36 + return objChain.slice(-clsChain.length) === clsChain; 1.37 + }; 1.38 + 1.39 + assert.ok(indirectInstanceOf(ns.Assert.AssertionError.prototype, Error), 1.40 + "Assert.AssertionError instanceof Error"); 1.41 + 1.42 + assert.throws(makeBlock(assert.ok, false), 1.43 + ns.Assert.AssertionError, "ok(false)"); 1.44 + 1.45 + assert.ok(true, "ok(true)"); 1.46 + 1.47 + assert.ok("test", "ok('test')"); 1.48 + 1.49 + assert.throws(makeBlock(assert.equal, true, false), ns.Assert.AssertionError, "equal"); 1.50 + 1.51 + assert.equal(null, null, "equal"); 1.52 + 1.53 + assert.equal(undefined, undefined, "equal"); 1.54 + 1.55 + assert.equal(null, undefined, "equal"); 1.56 + 1.57 + assert.equal(true, true, "equal"); 1.58 + 1.59 + assert.notEqual(true, false, "notEqual"); 1.60 + 1.61 + assert.throws(makeBlock(assert.notEqual, true, true), 1.62 + ns.Assert.AssertionError, "notEqual"); 1.63 + 1.64 + assert.throws(makeBlock(assert.strictEqual, 2, "2"), 1.65 + ns.Assert.AssertionError, "strictEqual"); 1.66 + 1.67 + assert.throws(makeBlock(assert.strictEqual, null, undefined), 1.68 + ns.Assert.AssertionError, "strictEqual"); 1.69 + 1.70 + assert.notStrictEqual(2, "2", "notStrictEqual"); 1.71 + 1.72 + // deepEquals joy! 1.73 + // 7.2 1.74 + assert.deepEqual(new Date(2000, 3, 14), new Date(2000, 3, 14), "deepEqual date"); 1.75 + 1.76 + assert.throws(makeBlock(assert.deepEqual, new Date(), new Date(2000, 3, 14)), 1.77 + ns.Assert.AssertionError, 1.78 + "deepEqual date"); 1.79 + 1.80 + // 7.3 1.81 + assert.deepEqual(/a/, /a/); 1.82 + assert.deepEqual(/a/g, /a/g); 1.83 + assert.deepEqual(/a/i, /a/i); 1.84 + assert.deepEqual(/a/m, /a/m); 1.85 + assert.deepEqual(/a/igm, /a/igm); 1.86 + assert.throws(makeBlock(assert.deepEqual, /ab/, /a/)); 1.87 + assert.throws(makeBlock(assert.deepEqual, /a/g, /a/)); 1.88 + assert.throws(makeBlock(assert.deepEqual, /a/i, /a/)); 1.89 + assert.throws(makeBlock(assert.deepEqual, /a/m, /a/)); 1.90 + assert.throws(makeBlock(assert.deepEqual, /a/igm, /a/im)); 1.91 + 1.92 + let re1 = /a/; 1.93 + re1.lastIndex = 3; 1.94 + assert.throws(makeBlock(assert.deepEqual, re1, /a/)); 1.95 + 1.96 + // 7.4 1.97 + assert.deepEqual(4, "4", "deepEqual == check"); 1.98 + assert.deepEqual(true, 1, "deepEqual == check"); 1.99 + assert.throws(makeBlock(assert.deepEqual, 4, "5"), 1.100 + ns.Assert.AssertionError, 1.101 + "deepEqual == check"); 1.102 + 1.103 + // 7.5 1.104 + // having the same number of owned properties && the same set of keys 1.105 + assert.deepEqual({a: 4}, {a: 4}); 1.106 + assert.deepEqual({a: 4, b: "2"}, {a: 4, b: "2"}); 1.107 + assert.deepEqual([4], ["4"]); 1.108 + assert.throws(makeBlock(assert.deepEqual, {a: 4}, {a: 4, b: true}), 1.109 + ns.Assert.AssertionError); 1.110 + assert.deepEqual(["a"], {0: "a"}); 1.111 + 1.112 + let a1 = [1, 2, 3]; 1.113 + let a2 = [1, 2, 3]; 1.114 + a1.a = "test"; 1.115 + a1.b = true; 1.116 + a2.b = true; 1.117 + a2.a = "test"; 1.118 + assert.throws(makeBlock(assert.deepEqual, Object.keys(a1), Object.keys(a2)), 1.119 + ns.Assert.AssertionError); 1.120 + assert.deepEqual(a1, a2); 1.121 + 1.122 + let nbRoot = { 1.123 + toString: function() { return this.first + " " + this.last; } 1.124 + }; 1.125 + 1.126 + function nameBuilder(first, last) { 1.127 + this.first = first; 1.128 + this.last = last; 1.129 + return this; 1.130 + } 1.131 + nameBuilder.prototype = nbRoot; 1.132 + 1.133 + function nameBuilder2(first, last) { 1.134 + this.first = first; 1.135 + this.last = last; 1.136 + return this; 1.137 + } 1.138 + nameBuilder2.prototype = nbRoot; 1.139 + 1.140 + let nb1 = new nameBuilder("Ryan", "Dahl"); 1.141 + let nb2 = new nameBuilder2("Ryan", "Dahl"); 1.142 + 1.143 + assert.deepEqual(nb1, nb2); 1.144 + 1.145 + nameBuilder2.prototype = Object; 1.146 + nb2 = new nameBuilder2("Ryan", "Dahl"); 1.147 + assert.throws(makeBlock(assert.deepEqual, nb1, nb2), ns.Assert.AssertionError); 1.148 + 1.149 + // String literal + object 1.150 + assert.throws(makeBlock(assert.deepEqual, "a", {}), ns.Assert.AssertionError); 1.151 + 1.152 + // Testing the throwing 1.153 + function thrower(errorConstructor) { 1.154 + throw new errorConstructor("test"); 1.155 + } 1.156 + let aethrow = makeBlock(thrower, ns.Assert.AssertionError); 1.157 + aethrow = makeBlock(thrower, ns.Assert.AssertionError); 1.158 + 1.159 + // the basic calls work 1.160 + assert.throws(makeBlock(thrower, ns.Assert.AssertionError), 1.161 + ns.Assert.AssertionError, "message"); 1.162 + assert.throws(makeBlock(thrower, ns.Assert.AssertionError), ns.Assert.AssertionError); 1.163 + assert.throws(makeBlock(thrower, ns.Assert.AssertionError)); 1.164 + 1.165 + // if not passing an error, catch all. 1.166 + assert.throws(makeBlock(thrower, TypeError)); 1.167 + 1.168 + // when passing a type, only catch errors of the appropriate type 1.169 + let threw = false; 1.170 + try { 1.171 + assert.throws(makeBlock(thrower, TypeError), ns.Assert.AssertionError); 1.172 + } catch (e) { 1.173 + threw = true; 1.174 + assert.ok(e instanceof TypeError, "type"); 1.175 + } 1.176 + assert.equal(true, threw, 1.177 + "Assert.throws with an explicit error is eating extra errors", 1.178 + ns.Assert.AssertionError); 1.179 + threw = false; 1.180 + 1.181 + function ifError(err) { 1.182 + if (err) { 1.183 + throw err; 1.184 + } 1.185 + } 1.186 + assert.throws(function() { 1.187 + ifError(new Error("test error")); 1.188 + }); 1.189 + 1.190 + // make sure that validating using constructor really works 1.191 + threw = false; 1.192 + try { 1.193 + assert.throws( 1.194 + function() { 1.195 + throw ({}); 1.196 + }, 1.197 + Array 1.198 + ); 1.199 + } catch (e) { 1.200 + threw = true; 1.201 + } 1.202 + assert.ok(threw, "wrong constructor validation"); 1.203 + 1.204 + // use a RegExp to validate error message 1.205 + assert.throws(makeBlock(thrower, TypeError), /test/); 1.206 + 1.207 + // use a fn to validate error object 1.208 + assert.throws(makeBlock(thrower, TypeError), function(err) { 1.209 + if ((err instanceof TypeError) && /test/.test(err)) { 1.210 + return true; 1.211 + } 1.212 + }); 1.213 + 1.214 + // Make sure deepEqual doesn't loop forever on circular refs 1.215 + 1.216 + let b = {}; 1.217 + b.b = b; 1.218 + 1.219 + let c = {}; 1.220 + c.b = c; 1.221 + 1.222 + let gotError = false; 1.223 + try { 1.224 + assert.deepEqual(b, c); 1.225 + } catch (e) { 1.226 + gotError = true; 1.227 + } 1.228 + 1.229 + dump("All OK\n"); 1.230 + assert.ok(gotError); 1.231 + 1.232 + function testAssertionMessage(actual, expected) { 1.233 + try { 1.234 + assert.equal(actual, ""); 1.235 + } catch (e) { 1.236 + assert.equal(e.toString(), 1.237 + ["AssertionError:", expected, "==", '""'].join(" ")); 1.238 + } 1.239 + } 1.240 + testAssertionMessage(undefined, '"undefined"'); 1.241 + testAssertionMessage(null, "null"); 1.242 + testAssertionMessage(true, "true"); 1.243 + testAssertionMessage(false, "false"); 1.244 + testAssertionMessage(0, "0"); 1.245 + testAssertionMessage(100, "100"); 1.246 + testAssertionMessage(NaN, '"NaN"'); 1.247 + testAssertionMessage(Infinity, '"Infinity"'); 1.248 + testAssertionMessage(-Infinity, '"-Infinity"'); 1.249 + testAssertionMessage("", '""'); 1.250 + testAssertionMessage("foo", '"foo"'); 1.251 + testAssertionMessage([], "[]"); 1.252 + testAssertionMessage([1, 2, 3], "[1,2,3]"); 1.253 + testAssertionMessage(/a/, '"/a/"'); 1.254 + testAssertionMessage(/abc/gim, '"/abc/gim"'); 1.255 + testAssertionMessage(function f() {}, '"function f() {}"'); 1.256 + testAssertionMessage({}, "{}"); 1.257 + testAssertionMessage({a: undefined, b: null}, '{"a":"undefined","b":null}'); 1.258 + testAssertionMessage({a: NaN, b: Infinity, c: -Infinity}, 1.259 + '{"a":"NaN","b":"Infinity","c":"-Infinity"}'); 1.260 + 1.261 + // https://github.com/joyent/node/issues/2893 1.262 + try { 1.263 + assert.throws(function () { 1.264 + ifError(null); 1.265 + }); 1.266 + } catch (e) { 1.267 + threw = true; 1.268 + assert.equal(e.message, "Missing expected exception.."); 1.269 + } 1.270 + assert.ok(threw); 1.271 + 1.272 + // https://github.com/joyent/node/issues/5292 1.273 + try { 1.274 + assert.equal(1, 2); 1.275 + } catch (e) { 1.276 + assert.equal(e.toString().split("\n")[0], "AssertionError: 1 == 2") 1.277 + } 1.278 + 1.279 + try { 1.280 + assert.equal(1, 2, "oh no"); 1.281 + } catch (e) { 1.282 + assert.equal(e.toString().split("\n")[0], "AssertionError: oh no - 1 == 2") 1.283 + } 1.284 + 1.285 + // Export Assert.jsm methods to become globally accessible. 1.286 + export_assertions(); 1.287 + 1.288 + // Test XPCShell-test integration: 1.289 + ok(true, "OK, this went well"); 1.290 + deepEqual(/a/g, /a/g, "deep equal should work on RegExp"); 1.291 + deepEqual(/a/igm, /a/igm, "deep equal should work on RegExp"); 1.292 + deepEqual({a: 4, b: "1"}, {b: "1", a: 4}, "deep equal should work on regular Object"); 1.293 + deepEqual(a1, a2, "deep equal should work on Array with Object properties"); 1.294 + 1.295 + // Test robustness of reporting: 1.296 + equal(new ns.Assert.AssertionError({ 1.297 + actual: { 1.298 + toJSON: function() { 1.299 + throw "bam!"; 1.300 + } 1.301 + }, 1.302 + expected: "foo", 1.303 + operator: "=" 1.304 + }).message, "[object Object] = \"foo\""); 1.305 +}