QUnit源码阅读(2):test基本执行流程
生活随笔
收集整理的這篇文章主要介紹了
QUnit源码阅读(2):test基本执行流程
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
// 直接上代碼
//step 1: write a simple test as the following. test("hello test", function() {ok(1 == "1", "Passed!"); });//step 2: 調用test函數 QUnit = {//...test : function(testName, expected, callback, async) {//...//初始化test,test = new Test({name : name,testName : testName,expected : expected,async : async,callback : callback, //回調函數, very important module : config.currentModule,moduleTestEnvironment : config.currentModuleTestEnvironment,stack : sourceFromStacktrace(2)});if (!validTest(test)) {return;}test.queue();},//... }//step 3: 調用test.queue函數,在config.queue中存入test.init和queue的內置函數run。 Test.prototype = {//...queue : function() {var bad, test = this;synchronize(function() {test.init();});function run() {// each of these can by asyncsynchronize(function() {test.setup();});synchronize(function() {test.run();});synchronize(function() {test.teardown();});synchronize(function() {test.finish();});}// `bad` initialized at top of scope// defer when previous test run passed, if storage is availablebad = QUnit.config.reorder && defined.sessionStorage && +sessionStorage.getItem("qunit-test-" + this.module + "-" + this.testName);if (bad) {run();} else {synchronize(run, true);}}//... }//step 4.1 - 4.2 在config.queue中存入callback函數 function synchronize(callback, last) {config.queue.push(callback);if (config.autorun && !config.blocking) {process(last);} }//step 5 調用Qunit.start函數 QUnit.load = function() {runLoggingCallbacks("begin", QUnit, {});//I do not care, right now//... QUnit.init();//...if (config.autostart) {QUnit.start();} };//step 6, 調用 process(true) QUnit = {//...start : function(count) {config.semaphore -= count || 1;// don't start until equal number of stop-callsif (config.semaphore > 0) {return;}// ignore if start is called more often then stopif (config.semaphore < 0) {config.semaphore = 0;}// A slight delay, to avoid any current callbacksif (defined.setTimeout) {window.setTimeout(function() {if (config.semaphore > 0) {return;}if (config.timeout) {clearTimeout(config.timeout);}config.blocking = false;process(true);}, 13);//13ms后調用,即step 7} else {config.blocking = false;process(true);}},//... } //step 7: 調用 process(true) (function() {if (config.semaphore > 0) {return;}if (config.timeout) {clearTimeout(config.timeout);}config.blocking = false;process(true);//ref step 8 })() //step 8, 循環泵,整個test框架的調用驅動函數,將config.queue[]中的回調依次拿出來run //Attention: 利用函數window.setTimeout及next函數來不斷循環的技巧☆☆☆ function process(last) {function next() {process(last);}var start = new Date().getTime();config.depth = config.depth ? config.depth + 1 : 1;while (config.queue.length && !config.blocking) {if (!defined.setTimeout || config.updateRate <= 0 || ((new Date().getTime() - start ) < config.updateRate )) {config.queue.shift()();//Attention, this is very important.} else {window.setTimeout(next, 13);//Or, 13ms 之后再次調用process(true).break;}}config.depth--;if (last && !config.blocking && !config.queue.length && config.depth === 0) {done();} }//step 9, 調用init函數 Test.prototype = {//...init : function() {//... },//... }//step 10. 調用run函數, 在 config.queue中放置更多的函數test.setup, run, teardown, finish Test.prototype = {//...queue : function() {//...function run() {// each of these can by asyncsynchronize(function() {test.setup();});synchronize(function() {test.run();});synchronize(function() {test.teardown();});synchronize(function() {test.finish();});}//... } };//step 11. 調用test.setup, run, teardown, finish Test.prototype = {//...setup : function() {//... },run : function() {config.current = this;var running = id("qunit-testresult");if (running) {running.innerHTML = "Running: <br/>" + this.name;}if (this.async) {QUnit.stop();}//this.callback 將會調用我們在 step1中寫的匿名函數function() { ok(1 == "1", "Passed!");})//this.callback 的初始化請參考step2if (config.notrycatch) {this.callback.call(this.testEnvironment, QUnit.assert);return;}try {this.callback.call(this.testEnvironment, QUnit.assert);} catch( e ) {QUnit.pushFailure("Died on test #" + (this.assertions.length + 1) + " " + this.stack + ": " + e.message, extractStacktrace(e, 0));// else next test will carry the responsibility saveGlobal();// Restart the tests if they're blockingif (config.blocking) {QUnit.start();}}},teardown : function() {//... },finish : function() {//... }, };//step 12: 調用 我們的測試函數 (function() {ok(1 == "1", "Passed!"); });//step 13: ok函數 QUnit.assert = {/*** Asserts rough true-ish result.* @name ok* @function* @example ok( "asdfasdf".length > 5, "There must be at least 5 chars" );*/ok : function(result, msg) {//...result = !!result;//... },//...equal : function(actual, expected, message) {QUnit.push(expected == actual, actual, expected, message);}, }extend( QUnit, {//...push: function( result, actual, expected, message ) {//...message = escapeInnerText( message ) || ( result ? "okay" : "failed" );//... },//... });
//step 1: write a simple test as the following. test("hello test", function() {ok(1 == "1", "Passed!"); });//step 2: 調用test函數 QUnit = {//...test : function(testName, expected, callback, async) {//...//初始化test,test = new Test({name : name,testName : testName,expected : expected,async : async,callback : callback, //回調函數, very important module : config.currentModule,moduleTestEnvironment : config.currentModuleTestEnvironment,stack : sourceFromStacktrace(2)});if (!validTest(test)) {return;}test.queue();},//... }//step 3: 調用test.queue函數,在config.queue中存入test.init和queue的內置函數run。 Test.prototype = {//...queue : function() {var bad, test = this;synchronize(function() {test.init();});function run() {// each of these can by asyncsynchronize(function() {test.setup();});synchronize(function() {test.run();});synchronize(function() {test.teardown();});synchronize(function() {test.finish();});}// `bad` initialized at top of scope// defer when previous test run passed, if storage is availablebad = QUnit.config.reorder && defined.sessionStorage && +sessionStorage.getItem("qunit-test-" + this.module + "-" + this.testName);if (bad) {run();} else {synchronize(run, true);}}//... }//step 4.1 - 4.2 在config.queue中存入callback函數 function synchronize(callback, last) {config.queue.push(callback);if (config.autorun && !config.blocking) {process(last);} }//step 5 調用Qunit.start函數 QUnit.load = function() {runLoggingCallbacks("begin", QUnit, {});//I do not care, right now//... QUnit.init();//...if (config.autostart) {QUnit.start();} };//step 6, 調用 process(true) QUnit = {//...start : function(count) {config.semaphore -= count || 1;// don't start until equal number of stop-callsif (config.semaphore > 0) {return;}// ignore if start is called more often then stopif (config.semaphore < 0) {config.semaphore = 0;}// A slight delay, to avoid any current callbacksif (defined.setTimeout) {window.setTimeout(function() {if (config.semaphore > 0) {return;}if (config.timeout) {clearTimeout(config.timeout);}config.blocking = false;process(true);}, 13);//13ms后調用,即step 7} else {config.blocking = false;process(true);}},//... } //step 7: 調用 process(true) (function() {if (config.semaphore > 0) {return;}if (config.timeout) {clearTimeout(config.timeout);}config.blocking = false;process(true);//ref step 8 })() //step 8, 循環泵,整個test框架的調用驅動函數,將config.queue[]中的回調依次拿出來run //Attention: 利用函數window.setTimeout及next函數來不斷循環的技巧☆☆☆ function process(last) {function next() {process(last);}var start = new Date().getTime();config.depth = config.depth ? config.depth + 1 : 1;while (config.queue.length && !config.blocking) {if (!defined.setTimeout || config.updateRate <= 0 || ((new Date().getTime() - start ) < config.updateRate )) {config.queue.shift()();//Attention, this is very important.} else {window.setTimeout(next, 13);//Or, 13ms 之后再次調用process(true).break;}}config.depth--;if (last && !config.blocking && !config.queue.length && config.depth === 0) {done();} }//step 9, 調用init函數 Test.prototype = {//...init : function() {//... },//... }//step 10. 調用run函數, 在 config.queue中放置更多的函數test.setup, run, teardown, finish Test.prototype = {//...queue : function() {//...function run() {// each of these can by asyncsynchronize(function() {test.setup();});synchronize(function() {test.run();});synchronize(function() {test.teardown();});synchronize(function() {test.finish();});}//... } };//step 11. 調用test.setup, run, teardown, finish Test.prototype = {//...setup : function() {//... },run : function() {config.current = this;var running = id("qunit-testresult");if (running) {running.innerHTML = "Running: <br/>" + this.name;}if (this.async) {QUnit.stop();}//this.callback 將會調用我們在 step1中寫的匿名函數function() { ok(1 == "1", "Passed!");})//this.callback 的初始化請參考step2if (config.notrycatch) {this.callback.call(this.testEnvironment, QUnit.assert);return;}try {this.callback.call(this.testEnvironment, QUnit.assert);} catch( e ) {QUnit.pushFailure("Died on test #" + (this.assertions.length + 1) + " " + this.stack + ": " + e.message, extractStacktrace(e, 0));// else next test will carry the responsibility saveGlobal();// Restart the tests if they're blockingif (config.blocking) {QUnit.start();}}},teardown : function() {//... },finish : function() {//... }, };//step 12: 調用 我們的測試函數 (function() {ok(1 == "1", "Passed!"); });//step 13: ok函數 QUnit.assert = {/*** Asserts rough true-ish result.* @name ok* @function* @example ok( "asdfasdf".length > 5, "There must be at least 5 chars" );*/ok : function(result, msg) {//...result = !!result;//... },//...equal : function(actual, expected, message) {QUnit.push(expected == actual, actual, expected, message);}, }extend( QUnit, {//...push: function( result, actual, expected, message ) {//...message = escapeInnerText( message ) || ( result ? "okay" : "failed" );//... },//... });
轉載于:https://www.cnblogs.com/dachengxu/archive/2012/11/23/2784368.html
總結
以上是生活随笔為你收集整理的QUnit源码阅读(2):test基本执行流程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: VC++ 删除当前读取行 代码
- 下一篇: CentOS6.3的Grub启动项的me