From c3895666598fe5c02f6d900d04db189cedeeb23c Mon Sep 17 00:00:00 2001 From: "Jeremy@marzhillstudios.com" Date: Tue, 28 Oct 2008 02:23:24 +0000 Subject: [PATCH] fixes for IE contributed by mike from the joose project git-svn-id: https://test-tap.googlecode.com/svn/trunk@4 62346678-a08d-11dd-9c66-c9f8973bfffa --- TODO | 2 + lib/Test/TAP.js | 16 +++- lib/Test/TAP/Class.js | 14 ++- lib/Test/TAPBrowser.js | 213 +++++++++++++++++++++++------------------ tests/01_tap.t.js | 23 +++-- tests/TapHarness.html | 11 ++- tmpl/TapHarness.html | 12 +-- 7 files changed, 168 insertions(+), 123 deletions(-) diff --git a/TODO b/TODO index e69de29..797d285 100644 --- a/TODO +++ b/TODO @@ -0,0 +1,2 @@ +[] skip and todo tests need to handle exceptions better +[] diff --git a/lib/Test/TAP.js b/lib/Test/TAP.js index aa5e442..cdaf8c3 100644 --- a/lib/Test/TAP.js +++ b/lib/Test/TAP.js @@ -97,15 +97,19 @@ Test.TAP.prototype.todo = function(func) { self.mk_tap = tapper; } -Test.TAP.prototype.skip = function(crit, reason, func) { +Test.TAP.prototype.skip = function(crit, reason, count, func) { var self = this; if (crit) { var tapper = self.mk_tap; self.mk_tap = function(ok, desc) { - tapper.apply(self, [ok, "# SKIP: "+reason]); + tapper.apply(self, [ok, desc]); + } + for(var i = 0; i < count; i++) { + self.fail("# SKIP "+reason) } - func(); self.mk_tap = tapper; + } else { + func(); } } @@ -201,7 +205,11 @@ Tests that a string matches the regex. Test.TAP.prototype.like = function(string, regex, desc) { this._pass_if(function(){ - return string.match(regex); + if(regex instanceof RegExp) { + return string.match(regex) + } else { + return string.indexOf(regex) != -1 + } }, desc) } diff --git a/lib/Test/TAP/Class.js b/lib/Test/TAP/Class.js index 46c78a6..53b2740 100644 --- a/lib/Test/TAP/Class.js +++ b/lib/Test/TAP/Class.js @@ -90,7 +90,7 @@ Test.TAP.Class.prototype.run_it = function(method) { } finally { // Delete globals which were created during test execution - // THis avoid conflicts between tests when running multiple tests in a r + // THis avoid conflicts between tests when running multiple tests in a row for(var name in top) { if(!originalGlobal[name]) { delete top[name] @@ -149,33 +149,41 @@ Test.TAP.Class.prototype.run_tests = function() { } var run = function () { if(self.finished) { + console.log('methods = '+methods+' length: '+methods.length+' Interval: '+testRunInterval); + //console.log('count = '+count+' Interval: '+testRunInterval); if(count > 0) { if(self.on_finished) { onFinish() self.on_finished() } } + console.log('made it past count test for interval: '+testRunInterval); if(methods.length == 0) { + console.log('clearing interval: '+testRunInterval); clearInterval(testRunInterval) if(self.on_finished_all) { self.on_finished_all() } } else { + console.log('we are finished but methods is not long enough interval: '+testRunInterval); self.finished = false; } } else { - if(self.planned == "no_plan" || self.planned == 0 || self.counter >= self.planned) { + if(self.planned == "no_plan" + || self.planned == 0 + || self.counter >= self.planned) { self.finished = true } } }; - testRunInterval = setInterval(run, 10) + testRunInterval = setInterval(run, 50) run(); var methodname; while (methodname = methods.shift()) { self.run_it(methodname); count++ } + run(); return self; }; diff --git a/lib/Test/TAPBrowser.js b/lib/Test/TAPBrowser.js index 7d8c828..af30e33 100644 --- a/lib/Test/TAPBrowser.js +++ b/lib/Test/TAPBrowser.js @@ -1,99 +1,124 @@ -function load(path) { - var url = location.pathname + "#" + encodeURIComponent(path.replace(/^\.\//, '')) - Test.TAP.prototype.diag('loading: '+path+' (run in a single window)...'); - var req = new XMLHttpRequest(); - req.open("GET", path, false); - req.send(null); - if (req.readyState == 4) { - var testobj = eval(req.responseText); - return testobj; - } -} - -function createScriptTag(library) { - var path = library.replace(/\./g, '/')+'.js'; - var script = document.createElement("script"); - script.src = lib+'/'+path; - return script; -} - -function loadlib(library) { - document.body.appendChild(createScriptTag(library)); -} - -function loadTest(test) { - var path = testlib+'/'+test; - return load(path); -} - -function loadComponents() { - for (c in toLoad) { - var comp = toLoad[c]; - loadlib(comp); - } -} - -function runtest(t) { - var outtxt = ""; - var div = document.createElement("div"); +Test.TAPBrowser = function (path, tests) { + this.test_path = path; - var onclick = function () { - var c = div.className; - if (c.match(/big/)) { - c = c.replace(/big/, "small"); - } else if (c.match(/small/)) { - c = c.replace(/small/, "big"); - } - div.className = c; - }; - div.addEventListener('click', onclick, true); - - div.className = 'test small'; - document.body.appendChild(div); + this.parseLocation() - var outfunc = function(text) { - if (text) { - outtxt += text; - div.innerHTML = div.innerHTML + "\n" + text + "
" - } - } - - // set globally for synchronous run - Test.TAP.prototype.out = outfunc; - var testobj = loadTest(t); - if (!testobj) { - alert ("Test Object: "+t+" did not load"); - throw new ReferenceError("Test Object did now load"); - } - // also set to instance for asynchronous output - testobj.out = outfunc - - testobj.on_finished = function () { - if (outtxt.match(/(not ok|Test Suite Crashed)/g) ) { - div.className += ' fail'; - div.className.replace(/small/, 'big'); - } else { - div.className += ' pass'; - } - results.push(div); - } - - setTimeout(function () { - testobj.run_tests() - }, 0) -} - -var test = loc.match(/.+[#?](.*)\??.*/); - -loadComponents(); - -window.onload = function() { - var testlist = []; - if (test) { - runtest(test[1]); + if(this.params.test) { + this.tests = [this.params.test]; } else { - for (t in tests) { - runtest(tests[t]); - } + this.tests = tests + } + + if(this.params.real_world) { + var world = new Test.RealWorld() + world[this.params.real_world]() } } + +Test.TAPBrowser.prototype = { + + parseLocation: function () { + var info = {}; + var hash = new String(location.hash) + if(hash.length > 1) { + var parts = hash.substr(1).split(";") + for(var i = 0; i < parts.length; i++) { + var pair = parts[i].split("="); + info[pair[0]] = pair[1] + } + } + this.params = info; + }, + + loadTest: function (t) { + + var path = this.createPath(t); + + var url = location.pathname + "#test=" + encodeURIComponent(path.replace(/^\.\//, '')) + Test.TAP.prototype.diag('loading: '+path+' (run in a single window)...'); + + var req = new XMLHttpRequest(); + req.open("GET", path, false); + req.send(null); + + // TODO is this AJAX Impl. robust enough? + if (req.readyState == 4) { + if(window && window.console && console.log) { + console.log("Evaluating test file "+path) + } + var testobj; + try { + var js = req.responseText; + // TODO this needs to be added to every source file instead + testobj = eval(js); + } catch(e) { + throw(e) + } + return testobj; + } + }, + + createPath: function (t) { + var path = this.test_path +'/'+t; + return path + }, + + runTest: function (t) { + var outtxt = ""; + var div = document.createElement("div"); + + var onclick = function () { + var c = div.className; + if (c.match(/big/)) { + c = c.replace(/big/, "small"); + } else if (c.match(/small/)) { + c = c.replace(/small/, "big"); + } + div.className = c; + }; + div.addEventListener('click', onclick, true); + + div.className = 'test small'; + document.body.appendChild(div); + + var outfunc = function(text) { + if (text) { + outtxt += text; + div.innerHTML = div.innerHTML + "\n" + text + "
" + } + } + + // set globally for synchronous run + Test.TAP.prototype.out = outfunc; + var testobj = this.loadTest(t); + if (!testobj) { + alert ("Test Object: "+t+" did not load"); + throw new ReferenceError("Test Object did now load"); + } + // also set to instance for asynchronous output + testobj.out = outfunc + + testobj.on_finished = function () { + if (outtxt.match(/(not ok|Test Suite Crashed)/g) ) { + div.className += ' fail'; + div.className.replace(/small/, 'big'); + } else { + div.className += ' pass'; + } + } + + setTimeout(function () { + testobj.run_tests(); + }, 0) + }, + + run: function () { + for (var i = 0; i < this.tests.length; i++) { + var t = this.tests[i] + this.runTest(t) + } + } + +} + + diff --git a/tests/01_tap.t.js b/tests/01_tap.t.js index 678781c..39a222a 100644 --- a/tests/01_tap.t.js +++ b/tests/01_tap.t.js @@ -2,9 +2,7 @@ var out = "nothing yet"; var diag = ""; var t = new Test.TAP.Class(); // the real TAP -//t.plan('no_plan'); t.plan(27); -//t.plan()); t.testCan = function () { var self = this; @@ -133,6 +131,7 @@ t.testPass = function() { } t.testPlan = function() { + var self = this; // setup fake test object var f = new Test.TAP(); // the TAP that's failing f.out = function(newout) { out = newout }; @@ -140,11 +139,11 @@ t.testPlan = function() { // begin real tests! f.ok(false, 'false fails'); - this.is(f.counter, 1, 'counter increments by one'); - this.is(f.planned, 2, 'planned = 2'); + self.is(f.counter, 1, 'counter increments by one'); + self.is(f.planned, 2, 'planned = 2'); } -t.testTodo = function() { +t.testTodoSkip = function() { var self = this; var out; self.can_ok(Test.TAP, 'todo', 'skip'); @@ -154,23 +153,23 @@ t.testTodo = function() { f.todo(function() { f.ok(true, 'true is true'); - self.like(out, /ok 1 - # TODO: true is true/g, - 'the non todo output is suitably formatted'); }); + self.like(out, /ok 1 - # TODO: true is true/g, + 'the non todo output is suitably formatted'); f.ok(!false, 'not false is true'); self.like(out, /ok 2 -/g, 'the regular output is suitably formatted'); - - f.skip(true, 'because I said so', + + f.skip(true, 'because I said so', 1, function() { f.is(1, 2, 'one is two'); - self.like(out, /^not ok 3 - # SKIP: because I said so$/, - 'the skipped output is suitably formatted'); } ); + self.like(out, /^not ok 3 - # SKIP because I said so$/, + 'the skipped output is suitably formatted'); f.is(1, 1, 'one is one'); self.like(out, /ok 4 - one is one/, 'the non skipped output is suitable formatted'); -} +}; return t; })() diff --git a/tests/TapHarness.html b/tests/TapHarness.html index 4a1ed1d..9c9785b 100644 --- a/tests/TapHarness.html +++ b/tests/TapHarness.html @@ -4,6 +4,7 @@ + @@ -33,20 +34,22 @@ /** Configuration options * */ - var toLoad = []; var tests = [ '01_tap.t.js', ]; - var lib = '../lib'; var testlib = '.'; /** Setup * */ - var loc = String(top.location); - var results = []; This is the Test.TAP.Class and company test harness for the browser. + diff --git a/tmpl/TapHarness.html b/tmpl/TapHarness.html index f418164..467239e 100644 --- a/tmpl/TapHarness.html +++ b/tmpl/TapHarness.html @@ -34,15 +34,9 @@ /** Configuration options * */ - var toLoad = [ - '', - ]; - var tests = [ '', ]; - // Change this to your javascript library location - var lib = '../lib'; // Change this to the path of your test scripts var testlib = '.'; @@ -53,5 +47,11 @@ var results = []; +