function description(msg) { print(msg); print("\nOn success, you will see a series of \"PASS\" messages, followed by \"TEST COMPLETE\".\n"); print(); } function debug(msg) { print(msg); } function escapeString(text) { return text.replace(/\0/g, ""); } function testPassed(msg) { print("PASS", escapeString(msg)); } function testFailed(msg) { print("FAIL", escapeString(msg)); } function areArraysEqual(_a, _b) { if (_a.length !== _b.length) return false; for (var i = 0; i < _a.length; i++) if (_a[i] !== _b[i]) return false; return true; } function isMinusZero(n) { // the only way to tell 0 from -0 in JS is the fact that 1/-0 is // -Infinity instead of Infinity return n === 0 && 1/n < 0; } function isResultCorrect(_actual, _expected) { if (_expected === 0) return _actual === _expected && (1/_actual) === (1/_expected); if (_actual === _expected) return true; if (typeof(_expected) == "number" && isNaN(_expected)) return typeof(_actual) == "number" && isNaN(_actual); if (Object.prototype.toString.call(_expected) == Object.prototype.toString.call([])) return areArraysEqual(_actual, _expected); return false; } function stringify(v) { if (v === 0 && 1/v < 0) return "-0"; else return "" + v; } function shouldBe(_a, _b) { if (typeof _a != "string" || typeof _b != "string") debug("WARN: shouldBe() expects string arguments"); var exception; var _av; try { _av = eval(_a); } catch (e) { exception = e; } var _bv = eval(_b); if (exception) testFailed(_a + " should be " + _bv + ". Threw exception " + exception); else if (isResultCorrect(_av, _bv)) testPassed(_a + " is " + _b); else if (typeof(_av) == typeof(_bv)) testFailed(_a + " should be " + _bv + ". Was " + stringify(_av) + "."); else testFailed(_a + " should be " + _bv + " (of type " + typeof _bv + "). Was " + _av + " (of type " + typeof _av + ")."); } function shouldBeTrue(_a) { shouldBe(_a, "true"); } function shouldBeFalse(_a) { shouldBe(_a, "false"); } function shouldBeNaN(_a) { shouldBe(_a, "NaN"); } function shouldBeNull(_a) { shouldBe(_a, "null"); } function shouldBeEqualToString(a, b) { var unevaledString = '"' + b.replace(/"/g, "\"") + '"'; shouldBe(a, unevaledString); } function shouldBeUndefined(_a) { var exception; var _av; try { _av = eval(_a); } catch (e) { exception = e; } if (exception) testFailed(_a + " should be undefined. Threw exception " + exception); else if (typeof _av == "undefined") testPassed(_a + " is undefined."); else testFailed(_a + " should be undefined. Was " + _av); } function shouldThrow(_a, _e) { var exception; var _av; try { _av = eval(_a); } catch (e) { exception = e; } var _ev; if (_e) _ev = eval(_e); if (exception) { if (typeof _e == "undefined" || exception == _ev) testPassed(_a + " threw exception " + exception + "."); else testFailed(_a + " should throw " + (typeof _e == "undefined" ? "an exception" : _ev) + ". Threw exception " + exception + "."); } else if (typeof _av == "undefined") testFailed(_a + " should throw " + (typeof _e == "undefined" ? "an exception" : _ev) + ". Was undefined."); else testFailed(_a + " should throw " + (typeof _e == "undefined" ? "an exception" : _ev) + ". Was " + _av + "."); }