📄 runner.js
字号:
if(groupOrNs.substr(0, 4)=="url:"){ this.registerUrl(groupOrNs); }else{ this.registerTest("ungrouped", groupOrNs); } } if(arguments.length == 1){ this.debug("invalid args passed to doh.register():", groupOrNs, ",", testOrNull); return; } if(typeof testOrNull == "string"){ if(testOrNull.substr(0, 4)=="url:"){ this.registerUrl(testOrNull); }else{ this.registerTest(groupOrNs, testOrNull); } // this.registerTestNs(groupOrNs, testOrNull); return; } if(doh._isArray(testOrNull)){ this.registerTests(groupOrNs, testOrNull); return; } this.registerTest(groupOrNs, testOrNull);}//// Assertions and In-Test Utilities//doh.t = doh.assertTrue = function(/*Object*/ condition){ // summary: // is the passed item "truthy"? if(arguments.length != 1){ throw doh._AssertFailure("assertTrue failed because it was not passed exactly 1 argument"); } if(!eval(condition)){ throw doh._AssertFailure("assertTrue('" + condition + "') failed"); }}doh.f = doh.assertFalse = function(/*Object*/ condition){ // summary: // is the passed item "falsey"? if(arguments.length != 1){ throw doh._AssertFailure("assertFalse failed because it was not passed exactly 1 argument"); } if(eval(condition)){ throw doh._AssertFailure("assertFalse('" + condition + "') failed"); }}doh.e = doh.assertError = function(/*Error object*/expectedError, /*Object*/scope, /*String*/functionName, /*Array*/args){ // summary: // Test for a certain error to be thrown by the given function. // example: // t.assertError(dojox.data.QueryReadStore.InvalidAttributeError, store, "getValue", [item, "NOT THERE"]); // t.assertError(dojox.data.QueryReadStore.InvalidItemError, store, "getValue", ["not an item", "NOT THERE"]); try{ scope[functionName].apply(scope, args); }catch (e){ if(e instanceof expectedError){ return true; }else{ throw new doh._AssertFailure("assertError() failed:\n\texpected error\n\t\t"+expectedError+"\n\tbut got\n\t\t"+e+"\n\n"); } } throw new doh._AssertFailure("assertError() failed:\n\texpected error\n\t\t"+expectedError+"\n\tbut no error caught\n\n");}doh.is = doh.assertEqual = function(/*Object*/ expected, /*Object*/ actual){ // summary: // are the passed expected and actual objects/values deeply // equivalent? // Compare undefined always with three equal signs, because undefined==null // is true, but undefined===null is false. if((expected === undefined)&&(actual === undefined)){ return true; } if(arguments.length < 2){ throw doh._AssertFailure("assertEqual failed because it was not passed 2 arguments"); } if((expected === actual)||(expected == actual)){ return true; } if( (this._isArray(expected) && this._isArray(actual))&& (this._arrayEq(expected, actual)) ){ return true; } if( ((typeof expected == "object")&&((typeof actual == "object")))&& (this._objPropEq(expected, actual)) ){ return true; } throw new doh._AssertFailure("assertEqual() failed:\n\texpected\n\t\t"+expected+"\n\tbut got\n\t\t"+actual+"\n\n");}doh._arrayEq = function(expected, actual){ if(expected.length != actual.length){ return false; } // FIXME: we're not handling circular refs. Do we care? for(var x=0; x<expected.length; x++){ if(!doh.assertEqual(expected[x], actual[x])){ return false; } } return true;}doh._objPropEq = function(expected, actual){ if(expected instanceof Date){ return actual instanceof Date && expected.getTime()==actual.getTime(); } // Make sure ALL THE SAME properties are in both objects! for(var x in actual){ // Lets check "actual" here, expected is checked below. if(expected[x] === undefined){ return false; } }; for(var x in expected){ if(!doh.assertEqual(expected[x], actual[x])){ return false; } } return true;}doh._isArray = function(it){ return (it && it instanceof Array || typeof it == "array" || (dojo["NodeList"] !== undefined && it instanceof dojo.NodeList));}//// Runner-Wrapper//doh._setupGroupForRun = function(/*String*/ groupName, /*Integer*/ idx){ var tg = this._groups[groupName]; this.debug(this._line); this.debug("GROUP", "\""+groupName+"\"", "has", tg.length, "test"+((tg.length > 1) ? "s" : "")+" to run");}doh._handleFailure = function(groupName, fixture, e){ // this.debug("FAILED test:", fixture.name); // mostly borrowed from JUM this._groups[groupName].failures++; var out = ""; if(e instanceof this._AssertFailure){ this._failureCount++; if(e["fileName"]){ out += e.fileName + ':'; } if(e["lineNumber"]){ out += e.lineNumber + ' '; } out += e+": "+e.message; this.debug("\t_AssertFailure:", out); }else{ this._errorCount++; } this.debug(e); if(fixture.runTest["toSource"]){ var ss = fixture.runTest.toSource(); this.debug("\tERROR IN:\n\t\t", ss); }else{ this.debug("\tERROR IN:\n\t\t", fixture.runTest); } if(e.rhinoException){ e.rhinoException.printStackTrace(); }else if(e.javaException){ e.javaException.printStackTrace(); } }try{ setTimeout(function(){}, 0);}catch(e){ setTimeout = function(func){ return func(); }}doh._runFixture = function(groupName, fixture){ var tg = this._groups[groupName]; this._testStarted(groupName, fixture); var threw = false; var err = null; // run it, catching exceptions and reporting them try{ // let doh reference "this.group.thinger..." which can be set by // another test or group-level setUp function fixture.group = tg; // only execute the parts of the fixture we've got if(fixture["setUp"]){ fixture.setUp(this); } if(fixture["runTest"]){ // should we error out of a fixture doesn't have a runTest? fixture.startTime = new Date(); var ret = fixture.runTest(this); fixture.endTime = new Date(); // if we get a deferred back from the test runner, we know we're // gonna wait for an async result. It's up to the test code to trap // errors and give us an errback or callback. if(ret instanceof doh.Deferred){ tg.inFlight++; ret.groupName = groupName; ret.fixture = fixture; ret.addErrback(function(err){ doh._handleFailure(groupName, fixture, err); }); var retEnd = function(){ if(fixture["tearDown"]){ fixture.tearDown(doh); } tg.inFlight--; if((!tg.inFlight)&&(tg.iterated)){ doh._groupFinished(groupName, (!tg.failures)); } doh._testFinished(groupName, fixture, ret.results[0]); if(doh._paused){ doh.run(); } } var timer = setTimeout(function(){ // ret.cancel(); // retEnd(); ret.errback(new Error("test timeout in "+fixture.name.toString())); }, fixture["timeout"]||1000); ret.addBoth(function(arg){ clearTimeout(timer); retEnd(); }); if(ret.fired < 0){ doh.pause(); } return ret; } } if(fixture["tearDown"]){ fixture.tearDown(this); } }catch(e){ threw = true; err = e; if(!fixture.endTime){ fixture.endTime = new Date(); } } var d = new doh.Deferred(); setTimeout(this.hitch(this, function(){ if(threw){ this._handleFailure(groupName, fixture, err); } this._testFinished(groupName, fixture, (!threw)); if((!tg.inFlight)&&(tg.iterated)){ doh._groupFinished(groupName, (!tg.failures)); }else if(tg.inFlight > 0){ setTimeout(this.hitch(this, function(){ doh.runGroup(groupName); // , idx); }), 100); this._paused = true; } if(doh._paused){ doh.run(); } }), 30); doh.pause(); return d;}doh._testId = 0;doh.runGroup = function(/*String*/ groupName, /*Integer*/ idx){ // summary: // runs the specified test group // the general structure of the algorithm is to run through the group's // list of doh, checking before and after each of them to see if we're in // a paused state. This can be caused by the test returning a deferred or // the user hitting the pause button. In either case, we want to halt // execution of the test until something external to us restarts it. This // means we need to pickle off enough state to pick up where we left off. // FIXME: need to make fixture execution async!! var tg = this._groups[groupName]; if(tg.skip === true){ return; } if(this._isArray(tg)){ if(idx<=tg.length){ if((!tg.inFlight)&&(tg.iterated == true)){ if(tg["tearDown"]){ tg.tearDown(this); } doh._groupFinished(groupName, (!tg.failures)); return; } } if(!idx){ tg.inFlight = 0; tg.iterated = false; tg.failures = 0; } doh._groupStarted(groupName); if(!idx){ this._setupGroupForRun(groupName, idx); if(tg["setUp"]){ tg.setUp(this); } } for(var y=(idx||0); y<tg.length; y++){ if(this._paused){ this._currentTest = y; // this.debug("PAUSED at:", tg[y].name, this._currentGroup, this._currentTest); return; } doh._runFixture(groupName, tg[y]); if(this._paused){ this._currentTest = y+1; if(this._currentTest == tg.length){ tg.iterated = true; } // this.debug("PAUSED at:", tg[y].name, this._currentGroup, this._currentTest); return; } } tg.iterated = true; if(!tg.inFlight){ if(tg["tearDown"]){ tg.tearDown(this); } doh._groupFinished(groupName, (!tg.failures)); } }}doh._onEnd = function(){}doh._report = function(){ // summary: // a private method to be implemented/replaced by the "locally // appropriate" test runner // this.debug("ERROR:"); // this.debug("\tNO REPORTING OUTPUT AVAILABLE."); // this.debug("\tIMPLEMENT doh._report() IN YOUR TEST RUNNER"); this.debug(this._line); this.debug("| TEST SUMMARY:"); this.debug(this._line); this.debug("\t", this._testCount, "tests in", this._groupCount, "groups"); this.debug("\t", this._errorCount, "errors"); this.debug("\t", this._failureCount, "failures");}doh.togglePaused = function(){ this[(this._paused) ? "run" : "pause"]();}doh.pause = function(){ // summary: // halt test run. Can be resumed. this._paused = true;}doh.run = function(){ // summary: // begins or resumes the test process. // this.debug("STARTING"); this._paused = false; var cg = this._currentGroup; var ct = this._currentTest; var found = false; if(!cg){ this._init(); // we weren't paused found = true; } this._currentGroup = null; this._currentTest = null; for(var x in this._groups){ if( ( (!found)&&(x == cg) )||( found ) ){ if(this._paused){ return; } this._currentGroup = x; if(!found){ found = true; this.runGroup(x, ct); }else{ this.runGroup(x); } if(this._paused){ return; } } } this._currentGroup = null; this._currentTest = null; this._paused = false; this._onEnd(); this._report();}tests = doh;(function(){ // scop protection try{ if(typeof dojo != "undefined"){ dojo.platformRequire({ browser: ["doh._browserRunner"], rhino: ["doh._rhinoRunner"], spidermonkey: ["doh._rhinoRunner"] }); var _shouldRequire = (dojo.isBrowser) ? (dojo.global == dojo.global["parent"]) : true; if(_shouldRequire){ if(dojo.isBrowser){ dojo.addOnLoad(function(){ if(dojo.byId("testList")){ var _tm = ( (dojo.global.testModule && dojo.global.testModule.length) ? dojo.global.testModule : "dojo.tests.module"); dojo.forEach(_tm.split(","), dojo.require, dojo); setTimeout(function(){ doh.run(); }, 500); } }); }else{ // dojo.require("doh._base"); } } }else{ if( (typeof load == "function")&& ( (typeof Packages == "function")|| (typeof Packages == "object") ) ){ throw new Error(); }else if(typeof load == "function"){ throw new Error(); } } }catch(e){ print("\n"+doh._line); print("The Dojo Unit Test Harness, $Rev$"); print("Copyright (c) 2007, The Dojo Foundation, All Rights Reserved"); print(doh._line, "\n"); load("_rhinoRunner.js"); try{ var dojoUrl = "../../dojo/dojo.js"; var testUrl = ""; var testModule = "dojo.tests.module"; for(var x=0; x<arguments.length; x++){ if(arguments[x].indexOf("=") > 0){ var tp = arguments[x].split("="); if(tp[0] == "dojoUrl"){ dojoUrl = tp[1]; } if(tp[0] == "testUrl"){ testUrl = tp[1]; } if(tp[0] == "testModule"){ testModule = tp[1]; } } } if(dojoUrl.length){ if(!this["djConfig"]){ djConfig = {}; } djConfig.baseUrl = dojoUrl.split("dojo.js")[0]; load(dojoUrl); } if(testUrl.length){ load(testUrl); } if(testModule.length){ dojo.forEach(testModule.split(","), dojo.require, dojo); } }catch(e){ print("An exception occurred: " + e); } doh.run(); }}).apply(this, typeof arguments != "undefined" ? arguments : [null]);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -