X-Git-Url: http://git.asbjorn.biz/?a=blobdiff_plain;f=test%2Flib%2FTest%2FHarness.js;fp=test%2Flib%2FTest%2FHarness.js;h=e43dc5c92fbbd8f880a9b9a3d88963110550b93a;hb=e7a29e42391160949dc35c1af4b0d24ee1c8ad8f;hp=0000000000000000000000000000000000000000;hpb=139a9cd7d495922b0f6e8f79d5fb3239db59b5ba;p=jquery.git diff --git a/test/lib/Test/Harness.js b/test/lib/Test/Harness.js new file mode 100644 index 0000000..e43dc5c --- /dev/null +++ b/test/lib/Test/Harness.js @@ -0,0 +1,267 @@ +// # $Id: Kinetic.pm 1493 2005-04-07 19:20:18Z theory $ + +// Set up namespace. +if (typeof self != 'undefined') { + //Browser + if (typeof Test == 'undefined') Test = {PLATFORM: 'browser'}; + else Test.PLATFORM = 'browser'; +} else if (typeof _player != 'undefined'){ + //Director + if (typeof _global.Test != "object") _global.Test = {PLATFORM: 'director'}; + else _global.Test.PLATFORM = 'director'; +} else { + throw new Error("Test.Harness does not support your platform"); +} + +Test.Harness = function () {}; +Test.Harness.VERSION = '0.11'; +Test.Harness.Done = 0; + +// Stoopid IE. +Test.Harness.LF = typeof document != "undefined" + && typeof document.all != "undefined" + ? "\r" + : "\n"; + +Test.Harness.prototype.isDone = Test.Harness.isDone; + +/* + + bonus Number of individual todo tests unexpectedly passed + ran Number of individual tests ran + ok Number of individual tests passed + subSkipped Number of individual tests skipped + todo Number of individual todo tests + + files Number of test files ran + good Number of test files passed + bad Number of test files failed + tests Number of test files originally given + skipped Number of test files skipped + +*/ + +Test.Harness.prototype.bonus = 0; +Test.Harness.prototype.ran = 0; +Test.Harness.prototype.ok = 0; +Test.Harness.prototype.subSkipped = 0; +Test.Harness.prototype.todo = 0; +Test.Harness.prototype.files = 0; +Test.Harness.prototype.good = 0; +Test.Harness.prototype.bad = 0; +Test.Harness.prototype.tests = 0; +Test.Harness.prototype.skipped = 0; +Test.Harness.prototype.failures = []; + +Test.Harness.runTests = function () { + // XXX Can't handle inheritance, right? Or can we? + var harness = new Test.Harness(); + harness.runTests.apply(harness, arguments); +}; + +Test.Harness.prototype.outFileNames = function (files) { + var len = 0; + for (var i = 0; i < files.length; i++) { + if (files[i].length > len) len = files[i].length; + } + len += 3; + var ret = []; + for (var i = 0; i < files.length; i++) { + var outName = files[i]; + var add = len - files[i].length; + // Where is Perl's x operator when I need it?? + for (var j = 0; j < add; j++) { + outName += '.'; + } + ret.push(outName); + } + return ret; +}; + +Test.Harness.prototype.outputResults = function (test, file, fn, attrs) { + this.tests++; + this.ran += test.TestResults.length; + var fails = []; + var track = { + fn: file, + total: test.expectedTests, + ok: 0, + failList: [] + }; + + if (test.TestResults.length) { + this.files++; + var pass = true; + for (var i = 0; i < test.TestResults.length; i++) { + var ok = "ok"; + if (test.TestResults[i].ok) { + this.ok++; + track.ok++ + if (test.TestResults[i].type == 'todo') { + // Handle unexpected pass. + if (test.TestResults[i].actualOK) this.bonus++; + this.todo ++; + } else if (test.TestResults[i].type == 'skip') this.subSkipped++; + } else { + if (test.TestResults[i].type == 'todo') { + // Expected failure. + this.todo++; + } else { + pass = false; + track.failList.push(i + 1); + } + ok = "not ok"; // XXX Need to handle TODO and TODO Skipped. + } + + if (!pass || attrs.verbose) fn(test.TestResults[i].output); + } + + if (pass) { + this.good++; + fn("ok" + Test.Harness.LF); + } else { + this.bad++; + var err = "NOK # Failed "; + if (track.failList.length == 1) { + err += "test " + track.failList[0]; + } else { + err += "tests " + this._failList(track.failList); + } + fn(err + " in " + file + Test.Harness.LF); + } + } else if (test.SkipAll){ + // All tests skipped. + this.skipped++; + this.good++; + fn("1..0 # Skip 1" + Test.Harness.LF); + } else { + // Wha happened? Tests ran, but no results! + this.files++; + this.bad++; + fn("FAILED before any test output arrived" + Test.Harness.LF); + } + if (track.failList.length) this.failures.push(track); +}; + +Test.Harness.prototype._allOK = function () { + return this.bad == 0 && (this.ran || this.skipped) ? true : false; +}; + +Test.Harness.prototype.outputSummary = function (fn, time) { + var bonusmsg = this._bonusmsg(); + var pct; + if (this._allOK()) { + fn("All tests successful" + bonusmsg + '.' + Test.Harness.LF); + } else if (!this.tests) { + fn("FAILED—no tests were run for some reason." + Test.Harness.LF); + } else if (!this.ran) { + var blurb = this.tests == 1 ? "file" : "files"; + fn("FAILED—" + this.tests + " test " + blurb + " could be run, " + + "alas—no output ever seen." + Test.Harness.LF); + } else { + pct = this.good / this.tests * 100; + var pctOK = 100 * this.ok / this.ran; + var subpct = (this.ran - this.ok) + "/" + this.ran + + " subtests failed, " + pctOK.toPrecision(4) + "% okay."; + + if (this.bad) { + bonusmsg = bonusmsg.replace(/^,?\s*/, ''); + if (bonusmsg) fn(bonusmsg + '.' + Test.Harness.LF); + fn("Failed " + this.bad + "/" + this.tests + " test scripts, " + + pct.toPrecision(4) + "% okay. " + subpct + Test.Harness.LF); + } + this.formatFailures(fn); + } + + fn("Files=" + this.tests + ", Tests=" + this.ran + ", " + (time / 1000) + + " seconds" + Test.Harness.LF); +}; + +Test.Harness.prototype.formatFailures = function () { + var table = ''; + var failedStr = "Failed Test"; + var middleStr = " Total Fail Failed "; + var listStr = "List of Failed"; + var cols = 80; + + // Figure out our longest name string for formatting purposes. + var maxNamelen = failedStr.length; + for (var i = 0; i < this.failures.length; i++) { + var len = this.failures[i].length; + if (len > maxNamelen) maxNamelen = len; + } + + var listLen = cols - middleStr.length - maxNamelen.length; + if (listLen < listStr.length) { + listLen = listStr.length; + maxNamelen = cols - middleStr.length - listLen; + if (maxNamelen < failedStr.length) { + maxNamelen = failedStr.length; + cols = maxNamelen + middleStr.length + listLen; + } + } + + var out = failedStr; + if (out.length < maxNamelen) { + for (var j = out.length; j < maxNameLength; j++) { + out += ' '; + } + } + out += ' ' + middleStr; + // XXX Need to finish implementing the text-only version of the failures + // table. +}; + +Test.Harness.prototype._bonusmsg = function () { + var bonusmsg = ''; + if (this.bonus) { + bonusmsg = (" (" + this.bonus + " subtest" + (this.bonus > 1 ? 's' : '') + + " UNEXPECTEDLY SUCCEEDED)"); + } + + if (this.skipped) { + bonusmsg += ", " + this.skipped + " test" + + (this.skipped != 1 ? 's' : ''); + if (this.subSkipped) { + bonusmsg += " and " + this.subSkipped + " subtest" + + (this.subSkipped != 1 ? 's' : ''); + } + bonusmsg += ' skipped'; + } else if (this.subSkipped) { + bonusmsg += ", " + this.subSkipped + " subtest" + + (this.subSkipped != 1 ? 's' : '') + " skipped"; + } + + return bonusmsg; +} + +Test.Harness.prototype._failList = function (fails) { + var last = -1; + var dash = ''; + var list = []; + for (var i = 0; i < fails.length; i++) { + if (dash) { + // We're in a series of numbers. + if (fails[i] - 1 == last) { + // We're still in it. + last = fails[i]; + } else { + // End of the line. + list[list.length-1] += dash + last; + last = -1; + list.push(fails[i]); + dash = ''; + } + } else if (fails[i] - 1 == last) { + // We're in a new series. + last = fails[i]; + dash = '-'; + } else { + // Not in a sequence. + list.push(fails[i]); + last = fails[i]; + } + } + if (dash) list[list.length-1] += dash + last; + return list.join(' '); +}