Browse files

Marked v0.6

  • Loading branch information...
1 parent e78876a commit 9ff2dd0c2223f328c16900f4324f4374c50863e9 @atesgoral committed Mar 25, 2009
Showing with 393 additions and 1 deletion.
  1. +1 −0 jsunity/CHANGES.txt
  2. +391 −0 jsunity/downloads/jsunity-0.6.js
  3. +1 −1 jsunity/jsunity.js
View
1 jsunity/CHANGES.txt
@@ -1,3 +1,4 @@
+0.6
- Improved assertion messages, added custom message argument
- Renamed assert[Not]Equals to assert[Not]Equal and made it more lax than the
new assert[Not]Identical
View
391 jsunity/downloads/jsunity-0.6.js
@@ -0,0 +1,391 @@
+//<%
+/**
+ * jsUnity Universal JavaScript Testing Framework v0.6
+ * http://jsunity.com/
+ *
+ * Copyright (c) 2009 Ates Goral
+ * Licensed under the MIT license.
+ * http://www.opensource.org/licenses/mit-license.php
+ */
+
+jsUnity = (function () {
+ function fmt(str) {
+ var a = Array.prototype.slice.call(arguments, 1);
+ return str.replace(/\?/g, function () { return a.shift(); });
+ }
+
+ function hash(v) {
+ if (v instanceof Object) {
+ var arr = [];
+
+ for (var p in v) {
+ arr.push(p);
+ arr.push(hash(v[p]));
+ }
+
+ return arr.join("#");
+ } else {
+ return String(v);
+ }
+ }
+
+ var defaultAssertions = {
+ assertException: function (fn, message) {
+ try {
+ fn instanceof Function && fn();
+ } catch (e) {
+ return;
+ }
+
+ throw fmt("?: (?) does not raise an exception or not a function",
+ message || "assertException", fn);
+ },
+
+ assertTrue: function (actual, message) {
+ if (!actual) {
+ throw fmt("?: (?) does not evaluate to true",
+ message || "assertTrue", actual);
+ }
+ },
+
+ assertFalse: function (actual, message) {
+ if (actual) {
+ throw fmt("?: (?) does not evaluate to false",
+ message || "assertFalse", actual);
+ }
+ },
+
+ assertIdentical: function (expected, actual, message) {
+ if (expected !== actual) {
+ throw fmt("?: (?) is not identical to (?)",
+ message || "assertIdentical", actual, expected);
+ }
+ },
+
+ assertNotIdentical: function (expected, actual, message) {
+ if (expected === actual) {
+ throw fmt("?: (?) is identical to (?)",
+ message || "assertNotIdentical", actual, expected);
+ }
+ },
+
+ assertEqual: function (expected, actual, message) {
+ if (hash(expected) != hash(actual)) {
+ throw fmt("?: (?) is not equal to (?)",
+ message || "assertEqual", actual, expected);
+ }
+ },
+
+ assertNotEqual: function (expected, actual, message) {
+ if (hash(expected) == hash(actual)) {
+ throw fmt("?: (?) is equal to (?)",
+ message || "assertNotEqual", actual, expected);
+ }
+ },
+
+ assertMatch: function (re, actual, message) {
+ if (!re.test(actual)) {
+ throw fmt("?: (?) does not match (?)",
+ message || "assertMatch", actual, re);
+ }
+ },
+
+ assertNotMatch: function (re, actual, message) {
+ if (re.test(actual)) {
+ throw fmt("?: (?) matches (?)",
+ message || "assertNotMatch", actual, re);
+ }
+ },
+
+ assertTypeOf: function (typ, actual, message) {
+ if (typeof actual !== typ) {
+ throw fmt("?: (?) is not of type (?)",
+ message || "assertTypeOf", actual, typ);
+ }
+ },
+
+ assertNotTypeOf: function (typ, actual, message) {
+ if (typeof actual === typ) {
+ throw fmt("?: (?) is of type (?)",
+ message || "assertNotTypeOf", actual, typ);
+ }
+ },
+
+ assertInstanceOf: function (cls, actual, message) {
+ if (!(actual instanceof cls)) {
+ throw fmt("?: (?) is not an instance of (?)",
+ message || "assertInstanceOf", actual, cls);
+ }
+ },
+
+ assertNotInstanceOf: function (cls, actual, message) {
+ if (actual instanceof cls) {
+ throw fmt("?: (?) is an instance of (?)",
+ message || "assertNotInstanceOf", actual, cls);
+ }
+ },
+
+ assertNull: function (actual, message) {
+ if (actual !== null) {
+ throw fmt("?: (?) is not null",
+ message || "assertNull", actual);
+ }
+ },
+
+ assertNotNull: function (actual, message) {
+ if (actual === null) {
+ throw fmt("?: (?) is null",
+ message || "assertNotNull", actual);
+ }
+ },
+
+ assertUndefined: function (actual, message) {
+ if (actual !== undefined) {
+ throw fmt("?: (?) is not undefined",
+ message || "assertUndefined", actual);
+ }
+ },
+
+ assertNotUndefined: function (actual, message) {
+ if (actual === undefined) {
+ throw fmt("?: (?) is undefined",
+ message || "assertNotUndefined", actual);
+ }
+ },
+
+ assertNaN: function (actual, message) {
+ if (!isNaN(actual)) {
+ throw fmt("?: (?) is not NaN",
+ message || "assertNaN", actual);
+ }
+ },
+
+ assertNotNaN: function (actual, message) {
+ if (isNaN(actual)) {
+ throw fmt("?: (?) is NaN",
+ message || "assertNotNaN", actual);
+ }
+ },
+
+ fail: function (message) {
+ throw message || "fail";
+ }
+ };
+
+ function plural(cnt, unit) {
+ return cnt + " " + unit + (cnt == 1 ? "" : "s");
+ }
+
+ function splitFunction(fn) {
+ var tokens =
+ /^[\s\r\n]*function[\s\r\n]*([^\(\s\r\n]*?)[\s\r\n]*\([^\)\s\r\n]*\)[\s\r\n]*\{((?:[^}]*\}?)+)\}[\s\r\n]*$/
+ .exec(fn);
+
+ if (!tokens) {
+ throw "Invalid function.";
+ }
+
+ return {
+ name: tokens[1].length ? tokens[1] : undefined,
+ body: tokens[2]
+ };
+ }
+
+ var probeOutside = function () {
+ try {
+ return eval(
+ [ "typeof ", " === \"function\" && ", "" ].join(arguments[0]));
+ } catch (e) {
+ return false;
+ }
+ };
+
+ function parseSuiteString(str) {
+ var obj = {};
+
+ var probeInside = new Function(
+ splitFunction(probeOutside).body + str);
+
+ var tokenRe = /(\w+)/g; // todo: wiser regex
+ var tokens;
+
+ while ((tokens = tokenRe.exec(str))) {
+ var token = tokens[1];
+ var fn;
+
+ if (!obj[token]
+ && (fn = probeInside(token))
+ && fn != probeOutside(token)) {
+
+ obj[token] = fn;
+ }
+ }
+
+ return parseSuiteObject(obj);
+ }
+
+ function parseSuiteFunction(fn) {
+ var fnParts = splitFunction(fn);
+ var suite = parseSuiteString(fnParts.body);
+
+ suite.suiteName = fnParts.name;
+
+ return suite;
+ }
+
+ function parseSuiteArray(tests) {
+ var obj = {};
+
+ for (var i = 0; i < tests.length; i++) {
+ var item = tests[i];
+
+ if (!obj[item]) {
+ switch (typeof item) {
+ case "function":
+ var fnParts = splitFunction(item);
+ obj[fnParts.name] = item;
+ break;
+ case "string":
+ var fn;
+
+ if (fn = probeOutside(item)) {
+ obj[item] = fn;
+ }
+ }
+ }
+ }
+
+ return parseSuiteObject(obj);
+ }
+
+ function parseSuiteObject(obj) {
+ var suite = new jsUnity.TestSuite(obj.suiteName, obj);
+
+ for (var name in obj) {
+ if (obj.hasOwnProperty(name)) {
+ var fn = obj[name];
+
+ if (typeof fn === "function") {
+ if (/^test/.test(name)) {
+ suite.tests.push({ name: name, fn: fn });
+ } else if (/^setUp|tearDown$/.test(name)) {
+ suite[name] = fn;
+ }
+ }
+ }
+ }
+
+ return suite;
+ }
+
+ return {
+ TestSuite: function (suiteName, scope) {
+ this.suiteName = suiteName;
+ this.scope = scope;
+ this.tests = [];
+ this.setUp = undefined;
+ this.tearDown = undefined;
+ },
+
+ TestResults: function () {
+ this.suiteName = undefined;
+ this.total = 0;
+ this.passed = 0;
+ this.failed = 0;
+ this.duration = 0;
+ },
+
+ assertions: defaultAssertions,
+
+ env: {
+ defaultScope: this,
+
+ getDate: function () {
+ return new Date();
+ }
+ },
+
+ attachAssertions: function (scope) {
+ scope = scope || this.env.defaultScope;
+
+ for (var fn in jsUnity.assertions) {
+ scope[fn] = jsUnity.assertions[fn];
+ }
+ },
+
+ log: function () {},
+
+ error: function (s) { this.log("[ERROR] " + s); },
+
+ compile: function (v) {
+ if (v instanceof jsUnity.TestSuite) {
+ return v;
+ } else if (v instanceof Function) {
+ return parseSuiteFunction(v);
+ } else if (v instanceof Array) {
+ return parseSuiteArray(v);
+ } else if (v instanceof Object) {
+ return parseSuiteObject(v);
+ } else if (typeof v === "string") {
+ return parseSuiteString(v);
+ } else {
+ throw "Argument must be a function, array, object, string or "
+ + "TestSuite instance.";
+ }
+ },
+
+ run: function () {
+ var results = new jsUnity.TestResults();
+
+ var suiteNames = [];
+ var start = jsUnity.env.getDate();
+
+ for (var i = 0; i < arguments.length; i++) {
+ try {
+ var suite = jsUnity.compile(arguments[i]);
+ } catch (e) {
+ this.error("Invalid test suite: " + e);
+ return false;
+ }
+
+ var cnt = suite.tests.length;
+
+ this.log("Running "
+ + (suite.suiteName || "unnamed test suite"));
+ this.log(plural(cnt, "test") + " found");
+
+ suiteNames.push(suite.suiteName);
+ results.total += cnt;
+
+ for (var j = 0; j < cnt; j++) {
+ var test = suite.tests[j];
+
+ try {
+ suite.setUp && suite.setUp();
+ test.fn.call(suite.scope);
+ suite.tearDown && suite.tearDown();
+
+ results.passed++;
+
+ this.log("[PASSED] " + test.name);
+ } catch (e) {
+ suite.tearDown && suite.tearDown();
+
+ this.log("[FAILED] " + test.name + ": " + e);
+ }
+ }
+ }
+
+ results.suiteName = suiteNames.join(",");
+ results.failed = results.total - results.passed;
+ results.duration = jsUnity.env.getDate() - start;
+
+ this.log(plural(results.passed, "test") + " passed");
+ this.log(plural(results.failed, "test") + " failed");
+ this.log(plural(results.duration, "millisecond") + " elapsed");
+
+ return results;
+ }
+ };
+})();
+//%>
View
2 jsunity/jsunity.js
@@ -1,6 +1,6 @@
//<%
/**
- * jsUnity Universal JavaScript Testing Framework v0.5
+ * jsUnity Universal JavaScript Testing Framework v0.6
* http://jsunity.com/
*
* Copyright (c) 2009 Ates Goral

0 comments on commit 9ff2dd0

Please sign in to comment.