QUnit源码阅读(2):test基本执行流程
生活随笔
收集整理的這篇文章主要介紹了
QUnit源码阅读(2):test基本执行流程
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
// 直接上代碼
//step 1: write a simple test as the following. test("hello test", function() {ok(1 == "1", "Passed!"); });//step 2: 調(diào)用test函數(shù) QUnit = {//...test : function(testName, expected, callback, async) {//...//初始化test,test = new Test({name : name,testName : testName,expected : expected,async : async,callback : callback, //回調(diào)函數(shù), very important module : config.currentModule,moduleTestEnvironment : config.currentModuleTestEnvironment,stack : sourceFromStacktrace(2)});if (!validTest(test)) {return;}test.queue();},//... }//step 3: 調(diào)用test.queue函數(shù),在config.queue中存入test.init和queue的內(nèi)置函數(shù)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函數(shù) function synchronize(callback, last) {config.queue.push(callback);if (config.autorun && !config.blocking) {process(last);} }//step 5 調(diào)用Qunit.start函數(shù) QUnit.load = function() {runLoggingCallbacks("begin", QUnit, {});//I do not care, right now//... QUnit.init();//...if (config.autostart) {QUnit.start();} };//step 6, 調(diào)用 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后調(diào)用,即step 7} else {config.blocking = false;process(true);}},//... } //step 7: 調(diào)用 process(true) (function() {if (config.semaphore > 0) {return;}if (config.timeout) {clearTimeout(config.timeout);}config.blocking = false;process(true);//ref step 8 })() //step 8, 循環(huán)泵,整個(gè)test框架的調(diào)用驅(qū)動(dòng)函數(shù),將config.queue[]中的回調(diào)依次拿出來run //Attention: 利用函數(shù)window.setTimeout及next函數(shù)來不斷循環(huán)的技巧☆☆☆ 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 之后再次調(diào)用process(true).break;}}config.depth--;if (last && !config.blocking && !config.queue.length && config.depth === 0) {done();} }//step 9, 調(diào)用init函數(shù) Test.prototype = {//...init : function() {//... },//... }//step 10. 調(diào)用run函數(shù), 在 config.queue中放置更多的函數(shù)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. 調(diào)用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 將會(huì)調(diào)用我們在 step1中寫的匿名函數(shù)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: 調(diào)用 我們的測試函數(shù) (function() {ok(1 == "1", "Passed!"); });//step 13: ok函數(shù) 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: 調(diào)用test函數(shù) QUnit = {//...test : function(testName, expected, callback, async) {//...//初始化test,test = new Test({name : name,testName : testName,expected : expected,async : async,callback : callback, //回調(diào)函數(shù), very important module : config.currentModule,moduleTestEnvironment : config.currentModuleTestEnvironment,stack : sourceFromStacktrace(2)});if (!validTest(test)) {return;}test.queue();},//... }//step 3: 調(diào)用test.queue函數(shù),在config.queue中存入test.init和queue的內(nèi)置函數(shù)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函數(shù) function synchronize(callback, last) {config.queue.push(callback);if (config.autorun && !config.blocking) {process(last);} }//step 5 調(diào)用Qunit.start函數(shù) QUnit.load = function() {runLoggingCallbacks("begin", QUnit, {});//I do not care, right now//... QUnit.init();//...if (config.autostart) {QUnit.start();} };//step 6, 調(diào)用 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后調(diào)用,即step 7} else {config.blocking = false;process(true);}},//... } //step 7: 調(diào)用 process(true) (function() {if (config.semaphore > 0) {return;}if (config.timeout) {clearTimeout(config.timeout);}config.blocking = false;process(true);//ref step 8 })() //step 8, 循環(huán)泵,整個(gè)test框架的調(diào)用驅(qū)動(dòng)函數(shù),將config.queue[]中的回調(diào)依次拿出來run //Attention: 利用函數(shù)window.setTimeout及next函數(shù)來不斷循環(huán)的技巧☆☆☆ 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 之后再次調(diào)用process(true).break;}}config.depth--;if (last && !config.blocking && !config.queue.length && config.depth === 0) {done();} }//step 9, 調(diào)用init函數(shù) Test.prototype = {//...init : function() {//... },//... }//step 10. 調(diào)用run函數(shù), 在 config.queue中放置更多的函數(shù)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. 調(diào)用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 將會(huì)調(diào)用我們在 step1中寫的匿名函數(shù)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: 調(diào)用 我們的測試函數(shù) (function() {ok(1 == "1", "Passed!"); });//step 13: ok函數(shù) 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" );//... },//... });
轉(zhuǎn)載于:https://www.cnblogs.com/dachengxu/archive/2012/11/23/2784368.html
總結(jié)
以上是生活随笔為你收集整理的QUnit源码阅读(2):test基本执行流程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: VC++ 删除当前读取行 代码
- 下一篇: CentOS6.3的Grub启动项的me