From: Jörn Zaefferer Date: Sat, 16 Sep 2006 12:19:56 +0000 (+0000) Subject: Refactored test suite: All tests are now compiled into one file, runs much faster... X-Git-Url: http://git.asbjorn.biz/?p=jquery.git;a=commitdiff_plain;h=f6ecc6a95c4046f53d1f0d75af213305c2bd7ea7 Refactored test suite: All tests are now compiled into one file, runs much faster and does not require ugly synchronization; Changed build.xml (tested) and Makefile (not tested!); Replaced calls to cmpOK() with ok(), removed cmpOK(); Tests can now call reset() to be able to always test against the unmodified test setup --- diff --git a/Makefile b/Makefile index 31f3182..72b3b04 100644 --- a/Makefile +++ b/Makefile @@ -70,6 +70,7 @@ test: ${JQ} @@echo " - Copying over script files." @@cp -fR ${BUILD_DIR}/test/js ${TEST_DIR}/js + @@cp -f ${BUILD_DIR}/test/index.html ${TEST_DIR} @@echo " - Compiling Test Cases" @@${JAR} ${BUILD_DIR}/test/test.js ${JQ} ${TEST_DIR} diff --git a/build.xml b/build.xml index 7cf2ab9..839214f 100644 --- a/build.xml +++ b/build.xml @@ -62,7 +62,8 @@ - + + diff --git a/build/test/index.html b/build/test/index.html index e05c176..31bf43d 100644 --- a/build/test/index.html +++ b/build/test/index.html @@ -4,7 +4,7 @@ diff --git a/build/test/js/test.js b/build/test/js/test.js index d478b63..ec6f9c0 100644 --- a/build/test/js/test.js +++ b/build/test/js/test.js @@ -1,143 +1,121 @@ -var queue = []; -var blocking = false; - -function reset(fixture) { - synchronize(function() { - document.getElementById('main').innerHTML = fixture; - }); -} - -function synchronize(callback) { - queue[queue.length] = callback; - if(!blocking) { - process(); - } -} - -function process() { - while(queue.length && !blocking) { - var call = queue[0]; - queue = queue.slice(1); - call(); - } -} - -function runTests(files) { - var fixture = document.getElementById('main').innerHTML; +function runTest(file) { var startTime = new Date(); - for( var i=0; i < files.length; i++) { - runTest( files, i ); - reset(fixture); - } - synchronize(function() { + var Test; + var stats = { + all: 0, + bad: 0 + }; + var fixture = document.getElementById('main').innerHTML; + $.get(file,function(js) { + js = js.replace(/</g, "<").replace(/>/g, ">").replace(/&/g, "&"); + eval(js); var runTime = new Date() - startTime; - // lets use jQuery for this, its not important anyway - $('body').append('
Tests completed in ' + runTime + ' milliseconds.'); + var result = document.createElement("div"); + result.innerHTML = 'Tests completed in ' + runTime + ' milliseconds.
' + + stats.bad + ' tests of ' + stats.all + ' failed.'; + document.getElementsByTagName("body")[0].appendChild(result); }); -} - -function runTest( files, num ) { - synchronize(function() { - blocking = true; - $.get(files[num],function(js) { - evaluateTest(files, num, js); - }); - }); -} - -function evaluateTest(files, num, js) { - var Test = []; - js = js.replace(/</g, "<").replace(/>/g, ">").replace(/&/g, "&"); - try { - eval(js); - } catch(e) { - if(typeof console != "undefined") { - console.error(e); - console.debug(js); + function test(name, callback) { + Test = []; + try { + callback(); + } catch(e) { + if(typeof console != "undefined") { + console.error("Test " + name + " died, exception and test follows"); + console.error(e); + console.warn(callback.toString()); + } + Test.push( [ false, "Died on test #" + (Test.length+1) + ": " + e ] ); } - Test.push( [ false, "Died on test #" + (Test.length+1) + ": " + e ] ); - } - - var good = 0, bad = 0; - var ol = document.createElement("ol"); - - var li = "", state = "pass"; - for ( var i = 0; i < Test.length; i++ ) { + reset(); + + var good = 0, bad = 0; + var ol = document.createElement("ol"); + + var li = "", state = "pass"; + for ( var i = 0; i < Test.length; i++ ) { + var li = document.createElement("li"); + li.className = Test[i][0] ? "pass" : "fail"; + li.innerHTML = Test[i][1]; + ol.appendChild( li ); + + stats.all++; + if ( !Test[i][0] ) { + state = "fail"; + bad++; + stats.bad++; + } else good++; + } + var li = document.createElement("li"); - li.className = Test[i][0] ? "pass" : "fail"; - li.innerHTML = Test[i][1]; - ol.appendChild( li ); - - if ( !Test[i][0] ) { - state = "fail"; - bad++; - } else good++; - } - - var li = document.createElement("li"); - li.className = state; - - var b = document.createElement("b"); - b.innerHTML = files[num] + " (" + bad + ", " + good + ", " + Test.length + ")"; - b.onclick = function(){ - var n = this.nextSibling; - if ( jQuery.css( n, "display" ) == "none" ) - n.style.display = "block"; - else - n.style.display = "none"; - }; - li.appendChild( b ); - - li.appendChild( ol ); - - document.getElementById("tests").appendChild( li ); - - blocking = false; - process(); + li.className = state; - function ok(a, msg) { - Test.push( [ !!a, msg ] ); + var b = document.createElement("b"); + b.innerHTML = name + " (" + bad + ", " + good + ", " + Test.length + ")"; + b.onclick = function(){ + var n = this.nextSibling; + if ( jQuery.css( n, "display" ) == "none" ) + n.style.display = "block"; + else + n.style.display = "none"; + }; + li.appendChild( b ); + li.appendChild( ol ); + + document.getElementById("tests").appendChild( li ); } - function cmpOK( a, c, b, msg ) { - var res; - eval( "res = (a " + c + " b)" ); - Test.push( [ res, msg ] ); + function reset() { + document.getElementById('main').innerHTML = fixture; } + /** + * Asserts true. + * @example ok( $("a").size() > 5, "There must be at least 5 anchors" ); + */ + function ok(a, msg) { + Test.push( [ !!a, msg ] ); + } + + /** + * Asserts that two arrays are the same + */ function isSet(a, b, msg) { var ret = true; - if ( a && b && a.length == b.length ) { for ( var i in a ) if ( a[i] != b[i] ) ret = false; } else ret = false; - if ( !ret && console ) console.log( msg, a, b ); - Test.push( [ ret, msg ] ); } + /** + * Returns an array of elements with the given IDs, eg. + * @example q("main", "foo", "bar") + * @result [
, , ] + */ function q() { var r = []; - for ( var i = 0; i < arguments.length; i++ ) r.push( document.getElementById( arguments[i] ) ); - return r; } + /** + * Asserts that a select matches the given IDs + * @example t("Check for something", "//[a]", ["foo", "baar"]); + * @result returns true if "//[a]" return two elements with the IDs 'foo' and 'baar' + */ function t(a,b,c) { var f = jQuery.find(b); - var s = ""; for ( var i = 0; i < f.length; i++ ) s += (s && ",") + '"' + f[i].id + '"'; - isSet(f, q.apply(q,c), a + " (" + b + ")"); } -} \ No newline at end of file +} diff --git a/build/test/test.js b/build/test/test.js index 96773ff..6553d9c 100644 --- a/build/test/test.js +++ b/build/test/test.js @@ -1,39 +1,31 @@ load( "build/js/writeFile.js", "build/js/parse.js" ); -var dir = arguments[1]; - -var indexFile = readFile( "build/test/index.html" ); -var testFile = readFile( "build/test/test.html" ); +function addParams(name, params) { + if(params.length > 0) { + name += "("; + for ( var i = 0; i < params.length; i++) { + name += params[i].type + ", "; + } + return name.substring(0, name.length - 2) + ")"; + } else { + return name + "()"; + } +} +function addTestWrapper(name, test) { + return 'test("' + name + '", function() {\n' + test + '\n});'; +} +var dir = arguments[1]; var jq = parse( readFile( arguments[0] ) ); -var fileList = []; -var count = 1; +var testFile = []; for ( var i = 0; i < jq.length; i++ ) { if ( jq[i].tests.length > 0 ) { - var name = count + "-" + jq[i].name; - if(count < 100) { - name = "0" + name; - } - if(count < 10) { - name = "0" + name; - } - - var fileName = "tests/" + name + ".js"; - - writeFile( dir + "/" + fileName, jq[i].tests.join("\n") ); - - fileList.push( fileName ); - - count++; + var method = jq[i]; + var name = addParams(method.name, method.params); + testFile[testFile.length] = addTestWrapper(name, method.tests.join("\n")); } } -var fileString = ""; -for ( var i = 0; i < fileList.length; i++ ) { - if ( fileString ) fileString += ", "; - fileString += "'" + fileList[i] + "'"; -} - -writeFile( dir + "/index.html", indexFile.replace( /{FILES}/g, fileString ) ); +writeFile( dir + "/tests.js", testFile.join("\n") ); \ No newline at end of file diff --git a/src/jquery/jquery.js b/src/jquery/jquery.js index bc98854..11cd56e 100644 --- a/src/jquery/jquery.js +++ b/src/jquery/jquery.js @@ -203,7 +203,7 @@ jQuery.fn = jQuery.prototype = { * @before * @result 2 * - * @test cmpOK( $("div").length, "==", 2, "Get Number of Elements Found" ); + * @test ok( $("div").length == 2, "Get Number of Elements Found" ); * * @property * @name length @@ -218,7 +218,7 @@ jQuery.fn = jQuery.prototype = { * @before * @result 2 * - * @test cmpOK( $("div").size(), "==", 2, "Get Number of Elements Found" ); + * @test ok( $("div").size() == 2, "Get Number of Elements Found" ); * * @name size * @type Number @@ -252,7 +252,7 @@ jQuery.fn = jQuery.prototype = { * @before * @result [ ] * - * @test cmpOK( $("div").get(0), "==", document.getElementById("main"), "Get A Single Element" ); + * @test ok( $("div").get(0) == document.getElementById("main"), "Get A Single Element" ); * * @name get * @type Element @@ -1035,7 +1035,7 @@ jQuery.fn = jQuery.prototype = { * @example $("p").not("#selected") * @before

Hello

Hello Again

* @result [

Hello

] - * @test cmpOK($("#main > p#ap > a").not("#google").length, "==", 2, ".not") + * @test ok($("#main > p#ap > a").not("#google").length == 2, ".not") * * @name not * @type jQuery @@ -1549,7 +1549,7 @@ jQuery.extend({ * @test t( "Element Selector", "div", ["main","foo"] ); * @test t( "Element Selector", "body", ["body"] ); * @test t( "Element Selector", "html", ["html"] ); - * @test cmpOK( $("*").size(), ">=", 30, "Element Selector" ); + * @test ok( $("*").size() >= 30, "Element Selector" ); * @test t( "Parent Element", "div div", ["foo"] ); * * @test t( "ID Selector", "#body", ["body"] ); @@ -1606,7 +1606,7 @@ jQuery.extend({ * @test t( "Element Preceded By", "p ~ div", ["foo"] ); * @test t( "Not", "a.blog:not(.link)", ["mark"] ); * - * @test cmpOK( jQuery.find("//*").length, ">=", 30, "All Elements (//*)" ); + * @test ok( jQuery.find("//*").length >= 30, "All Elements (//*)" ); * @test t( "All Div Elements", "//div", ["main","foo"] ); * @test t( "Absolute Path", "/html/body", ["body"] ); * @test t( "Absolute Path w/ *", "/* /body", ["body"] );