/trunk/api/js/dojo1.0/util/doh/LICENSE |
---|
New file |
0,0 → 1,195 |
Dojo is availble under *either* the terms of the modified BSD license *or* the |
Academic Free License version 2.1. As a recipient of Dojo, you may choose which |
license to receive this code under (except as noted in per-module LICENSE |
files). Some modules may not be the copyright of the Dojo Foundation. These |
modules contain explicit declarations of copyright in both the LICENSE files in |
the directories in which they reside and in the code itself. No external |
contributions are allowed under licenses which are fundamentally incompatible |
with the AFL or BSD licenses that Dojo is distributed under. |
The text of the AFL and BSD licenses is reproduced below. |
------------------------------------------------------------------------------- |
The "New" BSD License: |
********************** |
Copyright (c) 2005-2007, The Dojo Foundation |
All rights reserved. |
Redistribution and use in source and binary forms, with or without |
modification, are permitted provided that the following conditions are met: |
* Redistributions of source code must retain the above copyright notice, this |
list of conditions and the following disclaimer. |
* Redistributions in binary form must reproduce the above copyright notice, |
this list of conditions and the following disclaimer in the documentation |
and/or other materials provided with the distribution. |
* Neither the name of the Dojo Foundation nor the names of its contributors |
may be used to endorse or promote products derived from this software |
without specific prior written permission. |
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE |
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
------------------------------------------------------------------------------- |
The Academic Free License, v. 2.1: |
********************************** |
This Academic Free License (the "License") applies to any original work of |
authorship (the "Original Work") whose owner (the "Licensor") has placed the |
following notice immediately following the copyright notice for the Original |
Work: |
Licensed under the Academic Free License version 2.1 |
1) Grant of Copyright License. Licensor hereby grants You a world-wide, |
royalty-free, non-exclusive, perpetual, sublicenseable license to do the |
following: |
a) to reproduce the Original Work in copies; |
b) to prepare derivative works ("Derivative Works") based upon the Original |
Work; |
c) to distribute copies of the Original Work and Derivative Works to the |
public; |
d) to perform the Original Work publicly; and |
e) to display the Original Work publicly. |
2) Grant of Patent License. Licensor hereby grants You a world-wide, |
royalty-free, non-exclusive, perpetual, sublicenseable license, under patent |
claims owned or controlled by the Licensor that are embodied in the Original |
Work as furnished by the Licensor, to make, use, sell and offer for sale the |
Original Work and Derivative Works. |
3) Grant of Source Code License. The term "Source Code" means the preferred |
form of the Original Work for making modifications to it and all available |
documentation describing how to modify the Original Work. Licensor hereby |
agrees to provide a machine-readable copy of the Source Code of the Original |
Work along with each copy of the Original Work that Licensor distributes. |
Licensor reserves the right to satisfy this obligation by placing a |
machine-readable copy of the Source Code in an information repository |
reasonably calculated to permit inexpensive and convenient access by You for as |
long as Licensor continues to distribute the Original Work, and by publishing |
the address of that information repository in a notice immediately following |
the copyright notice that applies to the Original Work. |
4) Exclusions From License Grant. Neither the names of Licensor, nor the names |
of any contributors to the Original Work, nor any of their trademarks or |
service marks, may be used to endorse or promote products derived from this |
Original Work without express prior written permission of the Licensor. Nothing |
in this License shall be deemed to grant any rights to trademarks, copyrights, |
patents, trade secrets or any other intellectual property of Licensor except as |
expressly stated herein. No patent license is granted to make, use, sell or |
offer to sell embodiments of any patent claims other than the licensed claims |
defined in Section 2. No right is granted to the trademarks of Licensor even if |
such marks are included in the Original Work. Nothing in this License shall be |
interpreted to prohibit Licensor from licensing under different terms from this |
License any Original Work that Licensor otherwise would have a right to |
license. |
5) This section intentionally omitted. |
6) Attribution Rights. You must retain, in the Source Code of any Derivative |
Works that You create, all copyright, patent or trademark notices from the |
Source Code of the Original Work, as well as any notices of licensing and any |
descriptive text identified therein as an "Attribution Notice." You must cause |
the Source Code for any Derivative Works that You create to carry a prominent |
Attribution Notice reasonably calculated to inform recipients that You have |
modified the Original Work. |
7) Warranty of Provenance and Disclaimer of Warranty. Licensor warrants that |
the copyright in and to the Original Work and the patent rights granted herein |
by Licensor are owned by the Licensor or are sublicensed to You under the terms |
of this License with the permission of the contributor(s) of those copyrights |
and patent rights. Except as expressly stated in the immediately proceeding |
sentence, the Original Work is provided under this License on an "AS IS" BASIS |
and WITHOUT WARRANTY, either express or implied, including, without limitation, |
the warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A PARTICULAR |
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY OF THE ORIGINAL WORK IS WITH YOU. |
This DISCLAIMER OF WARRANTY constitutes an essential part of this License. No |
license to Original Work is granted hereunder except under this disclaimer. |
8) Limitation of Liability. Under no circumstances and under no legal theory, |
whether in tort (including negligence), contract, or otherwise, shall the |
Licensor be liable to any person for any direct, indirect, special, incidental, |
or consequential damages of any character arising as a result of this License |
or the use of the Original Work including, without limitation, damages for loss |
of goodwill, work stoppage, computer failure or malfunction, or any and all |
other commercial damages or losses. This limitation of liability shall not |
apply to liability for death or personal injury resulting from Licensor's |
negligence to the extent applicable law prohibits such limitation. Some |
jurisdictions do not allow the exclusion or limitation of incidental or |
consequential damages, so this exclusion and limitation may not apply to You. |
9) Acceptance and Termination. If You distribute copies of the Original Work or |
a Derivative Work, You must make a reasonable effort under the circumstances to |
obtain the express assent of recipients to the terms of this License. Nothing |
else but this License (or another written agreement between Licensor and You) |
grants You permission to create Derivative Works based upon the Original Work |
or to exercise any of the rights granted in Section 1 herein, and any attempt |
to do so except under the terms of this License (or another written agreement |
between Licensor and You) is expressly prohibited by U.S. copyright law, the |
equivalent laws of other countries, and by international treaty. Therefore, by |
exercising any of the rights granted to You in Section 1 herein, You indicate |
Your acceptance of this License and all of its terms and conditions. |
10) Termination for Patent Action. This License shall terminate automatically |
and You may no longer exercise any of the rights granted to You by this License |
as of the date You commence an action, including a cross-claim or counterclaim, |
against Licensor or any licensee alleging that the Original Work infringes a |
patent. This termination provision shall not apply for an action alleging |
patent infringement by combinations of the Original Work with other software or |
hardware. |
11) Jurisdiction, Venue and Governing Law. Any action or suit relating to this |
License may be brought only in the courts of a jurisdiction wherein the |
Licensor resides or in which Licensor conducts its primary business, and under |
the laws of that jurisdiction excluding its conflict-of-law provisions. The |
application of the United Nations Convention on Contracts for the International |
Sale of Goods is expressly excluded. Any use of the Original Work outside the |
scope of this License or after its termination shall be subject to the |
requirements and penalties of the U.S. Copyright Act, 17 U.S.C. § 101 et |
seq., the equivalent laws of other countries, and international treaty. This |
section shall survive the termination of this License. |
12) Attorneys Fees. In any action to enforce the terms of this License or |
seeking damages relating thereto, the prevailing party shall be entitled to |
recover its costs and expenses, including, without limitation, reasonable |
attorneys' fees and costs incurred in connection with such action, including |
any appeal of such action. This section shall survive the termination of this |
License. |
13) Miscellaneous. This License represents the complete agreement concerning |
the subject matter hereof. If any provision of this License is held to be |
unenforceable, such provision shall be reformed only to the extent necessary to |
make it enforceable. |
14) Definition of "You" in This License. "You" throughout this License, whether |
in upper or lower case, means an individual or a legal entity exercising rights |
under, and complying with all of the terms of, this License. For legal |
entities, "You" includes any entity that controls, is controlled by, or is |
under common control with you. For purposes of this definition, "control" means |
(i) the power, direct or indirect, to cause the direction or management of such |
entity, whether by contract or otherwise, or (ii) ownership of fifty percent |
(50%) or more of the outstanding shares, or (iii) beneficial ownership of such |
entity. |
15) Right to Use. You may use the Original Work in all ways not otherwise |
restricted or conditioned by this License or by law, and Licensor promises not |
to interfere with or be responsible for such uses by You. |
This license is Copyright (C) 2003-2004 Lawrence E. Rosen. All rights reserved. |
Permission is hereby granted to copy and distribute this license without |
modification. This license may not be modified without the express written |
permission of its copyright owner. |
/trunk/api/js/dojo1.0/util/doh/_rhinoRunner.js |
---|
New file |
0,0 → 1,5 |
if(this["dojo"]){ |
dojo.provide("doh._rhinoRunner"); |
} |
doh.debug = print; |
/trunk/api/js/dojo1.0/util/doh/runner.js |
---|
New file |
0,0 → 1,931 |
// FIXME: need to add async tests |
// FIXME: need to handle URL wrapping and test registration/running from URLs |
// package system gunk. |
try{ |
dojo.provide("doh.runner"); |
}catch(e){ |
if(!this["doh"]){ |
doh = {}; |
} |
} |
// |
// Utility Functions and Classes |
// |
doh.selfTest = false; |
doh.hitch = function(/*Object*/thisObject, /*Function|String*/method /*, ...*/){ |
var args = []; |
for(var x=2; x<arguments.length; x++){ |
args.push(arguments[x]); |
} |
var fcn = ((typeof method == "string") ? thisObject[method] : method) || function(){}; |
return function(){ |
var ta = args.concat([]); // make a copy |
for(var x=0; x<arguments.length; x++){ |
ta.push(arguments[x]); |
} |
return fcn.apply(thisObject, ta); // Function |
}; |
} |
doh._mixin = function(/*Object*/ obj, /*Object*/ props){ |
// summary: |
// Adds all properties and methods of props to obj. This addition is |
// "prototype extension safe", so that instances of objects will not |
// pass along prototype defaults. |
var tobj = {}; |
for(var x in props){ |
// the "tobj" condition avoid copying properties in "props" |
// inherited from Object.prototype. For example, if obj has a custom |
// toString() method, don't overwrite it with the toString() method |
// that props inherited from Object.protoype |
if((typeof tobj[x] == "undefined") || (tobj[x] != props[x])){ |
obj[x] = props[x]; |
} |
} |
// IE doesn't recognize custom toStrings in for..in |
if( this["document"] |
&& document.all |
&& (typeof props["toString"] == "function") |
&& (props["toString"] != obj["toString"]) |
&& (props["toString"] != tobj["toString"]) |
){ |
obj.toString = props.toString; |
} |
return obj; // Object |
} |
doh.mixin = function(/*Object*/obj, /*Object...*/props){ |
// summary: Adds all properties and methods of props to obj. |
for(var i=1, l=arguments.length; i<l; i++){ |
doh._mixin(obj, arguments[i]); |
} |
return obj; // Object |
} |
doh.extend = function(/*Object*/ constructor, /*Object...*/ props){ |
// summary: |
// Adds all properties and methods of props to constructor's |
// prototype, making them available to all instances created with |
// constructor. |
for(var i=1, l=arguments.length; i<l; i++){ |
doh._mixin(constructor.prototype, arguments[i]); |
} |
return constructor; // Object |
} |
doh._line = "------------------------------------------------------------"; |
/* |
doh._delegate = function(obj, props){ |
// boodman-crockford delegation |
function TMP(){}; |
TMP.prototype = obj; |
var tmp = new TMP(); |
if(props){ |
dojo.lang.mixin(tmp, props); |
} |
return tmp; |
} |
*/ |
doh.debug = function(){ |
// summary: |
// takes any number of arguments and sends them to whatever debugging |
// or logging facility is available in this environment |
// YOUR TEST RUNNER NEEDS TO IMPLEMENT THIS |
} |
doh._AssertFailure = function(msg){ |
// idea for this as way of dis-ambiguating error types is from JUM. |
// The JUM is dead! Long live the JUM! |
if(!(this instanceof doh._AssertFailure)){ |
return new doh._AssertFailure(msg); |
} |
this.message = new String(msg||""); |
return this; |
} |
doh._AssertFailure.prototype = new Error(); |
doh._AssertFailure.prototype.constructor = doh._AssertFailure; |
doh._AssertFailure.prototype.name = "doh._AssertFailure"; |
doh.Deferred = function(canceller){ |
this.chain = []; |
this.id = this._nextId(); |
this.fired = -1; |
this.paused = 0; |
this.results = [null, null]; |
this.canceller = canceller; |
this.silentlyCancelled = false; |
}; |
doh.extend(doh.Deferred, { |
getTestCallback: function(cb, scope){ |
var _this = this; |
return function(){ |
try{ |
cb.apply(scope||dojo.global||_this, arguments); |
}catch(e){ |
_this.errback(e); |
return; |
} |
_this.callback(true); |
} |
}, |
getFunctionFromArgs: function(){ |
var a = arguments; |
if((a[0])&&(!a[1])){ |
if(typeof a[0] == "function"){ |
return a[0]; |
}else if(typeof a[0] == "string"){ |
return dojo.global[a[0]]; |
} |
}else if((a[0])&&(a[1])){ |
return doh.hitch(a[0], a[1]); |
} |
return null; |
}, |
makeCalled: function() { |
var deferred = new doh.Deferred(); |
deferred.callback(); |
return deferred; |
}, |
_nextId: (function(){ |
var n = 1; |
return function(){ return n++; }; |
})(), |
cancel: function(){ |
if(this.fired == -1){ |
if (this.canceller){ |
this.canceller(this); |
}else{ |
this.silentlyCancelled = true; |
} |
if(this.fired == -1){ |
this.errback(new Error("Deferred(unfired)")); |
} |
}else if( (this.fired == 0)&& |
(this.results[0] instanceof doh.Deferred)){ |
this.results[0].cancel(); |
} |
}, |
_pause: function(){ |
this.paused++; |
}, |
_unpause: function(){ |
this.paused--; |
if ((this.paused == 0) && (this.fired >= 0)) { |
this._fire(); |
} |
}, |
_continue: function(res){ |
this._resback(res); |
this._unpause(); |
}, |
_resback: function(res){ |
this.fired = ((res instanceof Error) ? 1 : 0); |
this.results[this.fired] = res; |
this._fire(); |
}, |
_check: function(){ |
if(this.fired != -1){ |
if(!this.silentlyCancelled){ |
throw new Error("already called!"); |
} |
this.silentlyCancelled = false; |
return; |
} |
}, |
callback: function(res){ |
this._check(); |
this._resback(res); |
}, |
errback: function(res){ |
this._check(); |
if(!(res instanceof Error)){ |
res = new Error(res); |
} |
this._resback(res); |
}, |
addBoth: function(cb, cbfn){ |
var enclosed = this.getFunctionFromArgs(cb, cbfn); |
if(arguments.length > 2){ |
enclosed = doh.hitch(null, enclosed, arguments, 2); |
} |
return this.addCallbacks(enclosed, enclosed); |
}, |
addCallback: function(cb, cbfn){ |
var enclosed = this.getFunctionFromArgs(cb, cbfn); |
if(arguments.length > 2){ |
enclosed = doh.hitch(null, enclosed, arguments, 2); |
} |
return this.addCallbacks(enclosed, null); |
}, |
addErrback: function(cb, cbfn){ |
var enclosed = this.getFunctionFromArgs(cb, cbfn); |
if(arguments.length > 2){ |
enclosed = doh.hitch(null, enclosed, arguments, 2); |
} |
return this.addCallbacks(null, enclosed); |
}, |
addCallbacks: function(cb, eb){ |
this.chain.push([cb, eb]) |
if(this.fired >= 0){ |
this._fire(); |
} |
return this; |
}, |
_fire: function(){ |
var chain = this.chain; |
var fired = this.fired; |
var res = this.results[fired]; |
var self = this; |
var cb = null; |
while (chain.length > 0 && this.paused == 0) { |
// Array |
var pair = chain.shift(); |
var f = pair[fired]; |
if(f == null){ |
continue; |
} |
try { |
res = f(res); |
fired = ((res instanceof Error) ? 1 : 0); |
if(res instanceof doh.Deferred){ |
cb = function(res){ |
self._continue(res); |
} |
this._pause(); |
} |
}catch(err){ |
fired = 1; |
res = err; |
} |
} |
this.fired = fired; |
this.results[fired] = res; |
if((cb)&&(this.paused)){ |
res.addBoth(cb); |
} |
} |
}); |
// |
// State Keeping and Reporting |
// |
doh._testCount = 0; |
doh._groupCount = 0; |
doh._errorCount = 0; |
doh._failureCount = 0; |
doh._currentGroup = null; |
doh._currentTest = null; |
doh._paused = true; |
doh._init = function(){ |
this._currentGroup = null; |
this._currentTest = null; |
this._errorCount = 0; |
this._failureCount = 0; |
this.debug(this._testCount, "tests to run in", this._groupCount, "groups"); |
} |
// doh._urls = []; |
doh._groups = {}; |
// |
// Test Registration |
// |
doh.registerTestNs = function(/*String*/ group, /*Object*/ ns){ |
// summary: |
// adds the passed namespace object to the list of objects to be |
// searched for test groups. Only "public" functions (not prefixed |
// with "_") will be added as tests to be run. If you'd like to use |
// fixtures (setUp(), tearDown(), and runTest()), please use |
// registerTest() or registerTests(). |
for(var x in ns){ |
if( (x.charAt(0) == "_") && |
(typeof ns[x] == "function") ){ |
this.registerTest(group, ns[x]); |
} |
} |
} |
doh._testRegistered = function(group, fixture){ |
// slot to be filled in |
} |
doh._groupStarted = function(group){ |
// slot to be filled in |
} |
doh._groupFinished = function(group, success){ |
// slot to be filled in |
} |
doh._testStarted = function(group, fixture){ |
// slot to be filled in |
} |
doh._testFinished = function(group, fixture, success){ |
// slot to be filled in |
} |
doh.registerGroup = function( /*String*/ group, |
/*Array||Function||Object*/ tests, |
/*Function*/ setUp, |
/*Function*/ tearDown){ |
// summary: |
// registers an entire group of tests at once and provides a setUp and |
// tearDown facility for groups. If you call this method with only |
// setUp and tearDown parameters, they will replace previously |
// installed setUp or tearDown functions for the group with the new |
// methods. |
// group: |
// string name of the group |
// tests: |
// either a function or an object or an array of functions/objects. If |
// an object, it must contain at *least* a "runTest" method, and may |
// also contain "setUp" and "tearDown" methods. These will be invoked |
// on either side of the "runTest" method (respectively) when the test |
// is run. If an array, it must contain objects matching the above |
// description or test functions. |
// setUp: a function for initializing the test group |
// tearDown: a function for initializing the test group |
if(tests){ |
this.register(group, tests); |
} |
if(setUp){ |
this._groups[group].setUp = setUp; |
} |
if(tearDown){ |
this._groups[group].tearDown = tearDown; |
} |
} |
doh._getTestObj = function(group, test){ |
var tObj = test; |
if(typeof test == "string"){ |
if(test.substr(0, 4)=="url:"){ |
return this.registerUrl(group, test); |
}else{ |
tObj = { |
name: test.replace("/\s/g", "_") |
}; |
tObj.runTest = new Function("t", test); |
} |
}else if(typeof test == "function"){ |
// if we didn't get a fixture, wrap the function |
tObj = { "runTest": test }; |
if(test["name"]){ |
tObj.name = test.name; |
}else{ |
try{ |
var fStr = "function "; |
var ts = tObj.runTest+""; |
if(0 <= ts.indexOf(fStr)){ |
tObj.name = ts.split(fStr)[1].split("(", 1)[0]; |
} |
// doh.debug(tObj.runTest.toSource()); |
}catch(e){ |
} |
} |
// FIXME: try harder to get the test name here |
} |
return tObj; |
} |
doh.registerTest = function(/*String*/ group, /*Function||Object*/ test){ |
// summary: |
// add the provided test function or fixture object to the specified |
// test group. |
// group: |
// string name of the group to add the test to |
// test: |
// either a function or an object. If an object, it must contain at |
// *least* a "runTest" method, and may also contain "setUp" and |
// "tearDown" methods. These will be invoked on either side of the |
// "runTest" method (respectively) when the test is run. |
if(!this._groups[group]){ |
this._groupCount++; |
this._groups[group] = []; |
this._groups[group].inFlight = 0; |
} |
var tObj = this._getTestObj(group, test); |
if(!tObj){ return; } |
this._groups[group].push(tObj); |
this._testCount++; |
this._testRegistered(group, tObj); |
return tObj; |
} |
doh.registerTests = function(/*String*/ group, /*Array*/ testArr){ |
// summary: |
// registers a group of tests, treating each element of testArr as |
// though it were being (along with group) passed to the registerTest |
// method. |
for(var x=0; x<testArr.length; x++){ |
this.registerTest(group, testArr[x]); |
} |
} |
// FIXME: move implementation to _browserRunner? |
doh.registerUrl = function( /*String*/ group, |
/*String*/ url, |
/*Integer*/ timeout){ |
this.debug("ERROR:"); |
this.debug("\tNO registerUrl() METHOD AVAILABLE."); |
// this._urls.push(url); |
} |
doh.registerString = function(group, str){ |
} |
// FIXME: remove the doh.add alias SRTL. |
doh.register = doh.add = function(groupOrNs, testOrNull){ |
// summary: |
// "magical" variant of registerTests, registerTest, and |
// registerTestNs. Will accept the calling arguments of any of these |
// methods and will correctly guess the right one to register with. |
if( (arguments.length == 1)&& |
(typeof groupOrNs == "string") ){ |
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: expected error |"+expectedError+"| but got |"+e+"|"); |
} |
} |
throw new doh._AssertFailure("assertError() failed: expected error |"+expectedError+"| but no error caught."); |
} |
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: expected |"+expected+"| but got |"+actual+"|"); |
} |
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){ |
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" || ((typeof 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); |
} |
} |
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){ |
} |
doh.run(); |
} |
})(); |
/trunk/api/js/dojo1.0/util/doh/_browserRunner.js |
---|
New file |
0,0 → 1,465 |
if(window["dojo"]){ |
dojo.provide("doh._browserRunner"); |
} |
// FIXME: need to add prompting for monkey-do testing |
// FIXME: need to implement progress bar |
// FIXME: need to implement errors in progress bar |
(function(){ |
if(window.parent == window){ |
// we're the top-dog window. |
// borrowed from Dojo, etc. |
var byId = function(id){ |
return document.getElementById(id); |
} |
var _addOnEvt = function( type, // string |
refOrName, // function or string |
scope){ // object, defaults is window |
if(!scope){ scope = window; } |
var funcRef = refOrName; |
if(typeof refOrName == "string"){ |
funcRef = scope[refOrName]; |
} |
var enclosedFunc = function(){ return funcRef.apply(scope, arguments); }; |
if((window["dojo"])&&(type == "load")){ |
dojo.addOnLoad(enclosedFunc); |
}else{ |
if(window["attachEvent"]){ |
window.attachEvent("on"+type, enclosedFunc); |
}else if(window["addEventListener"]){ |
window.addEventListener(type, enclosedFunc, false); |
}else if(document["addEventListener"]){ |
document.addEventListener(type, enclosedFunc, false); |
} |
} |
}; |
// |
// Over-ride or implement base runner.js-provided methods |
// |
var _logBacklog = []; |
var sendToLogPane = function(args, skip){ |
var msg = ""; |
for(var x=0; x<args.length; x++){ |
msg += " "+args[x]; |
} |
// workarounds for IE. Wheeee!!! |
msg = msg.replace("\t", " "); |
msg = msg.replace(" ", " "); |
msg = msg.replace("\n", "<br> "); |
if(!byId("logBody")){ |
_logBacklog.push(msg); |
return; |
}else if((_logBacklog.length)&&(!skip)){ |
var tm; |
while(tm=_logBacklog.shift()){ |
sendToLogPane(tm, true); |
} |
} |
var tn = document.createElement("div"); |
tn.innerHTML = msg; |
byId("logBody").appendChild(tn); |
} |
doh._init = (function(oi){ |
return function(){ |
var lb = byId("logBody"); |
if(lb){ |
// clear the console before each run |
while(lb.firstChild){ |
lb.removeChild(lb.firstChild); |
} |
} |
oi.apply(doh, arguments); |
} |
})(doh._init); |
if(this["opera"] && opera.postError){ |
doh.debug = function(){ |
var msg = ""; |
for(var x=0; x<arguments.length; x++){ |
msg += " "+arguments[x]; |
} |
sendToLogPane([msg]); |
opera.postError("DEBUG:"+msg); |
} |
}else if(window["console"]){ |
if(console.info){ |
doh.debug = function(){ |
sendToLogPane.call(window, arguments); |
console.debug.apply(console, arguments); |
} |
}else{ |
doh.debug = function(){ |
var msg = ""; |
for(var x=0; x<arguments.length; x++){ |
msg += " "+arguments[x]; |
} |
sendToLogPane([msg]); |
console.log("DEBUG:"+msg); |
} |
} |
}else{ |
doh.debug = function(){ |
sendToLogPane.call(window, arguments); |
} |
} |
var loaded = false; |
var groupTemplate = null; |
var testTemplate = null; |
var groupNodes = {}; |
var _groupTogglers = {}; |
var _getGroupToggler = function(group, toggle){ |
if(_groupTogglers[group]){ return _groupTogglers[group]; } |
var rolledUp = true; |
return _groupTogglers[group] = function(evt, forceOpen){ |
var nodes = groupNodes[group].__items; |
if(rolledUp||forceOpen){ |
rolledUp = false; |
for(var x=0; x<nodes.length; x++){ |
nodes[x].style.display = ""; |
} |
toggle.innerHTML = "6"; |
}else{ |
rolledUp = true; |
for(var x=0; x<nodes.length; x++){ |
nodes[x].style.display = "none"; |
} |
toggle.innerHTML = "4"; |
} |
}; |
} |
var addGroupToList = function(group){ |
if(!byId("testList")){ return; } |
var tb = byId("testList").tBodies[0]; |
var tg = groupTemplate.cloneNode(true); |
var tds = tg.getElementsByTagName("td"); |
var toggle = tds[0]; |
toggle.onclick = _getGroupToggler(group, toggle); |
var cb = tds[1].getElementsByTagName("input")[0]; |
cb.group = group; |
cb.onclick = function(evt){ |
doh._groups[group].skip = (!this.checked); |
} |
tds[2].innerHTML = group; |
tds[3].innerHTML = ""; |
tb.appendChild(tg); |
return tg; |
} |
var addFixtureToList = function(group, fixture){ |
if(!testTemplate){ return; } |
var cgn = groupNodes[group]; |
if(!cgn["__items"]){ cgn.__items = []; } |
var tn = testTemplate.cloneNode(true); |
var tds = tn.getElementsByTagName("td"); |
tds[2].innerHTML = fixture.name; |
tds[3].innerHTML = ""; |
var nn = (cgn.__lastFixture||cgn.__groupNode).nextSibling; |
if(nn){ |
nn.parentNode.insertBefore(tn, nn); |
}else{ |
cgn.__groupNode.parentNode.appendChild(tn); |
} |
// FIXME: need to make group display toggleable!! |
tn.style.display = "none"; |
cgn.__items.push(tn); |
return cgn.__lastFixture = tn; |
} |
var getFixtureNode = function(group, fixture){ |
if(groupNodes[group]){ |
return groupNodes[group][fixture.name]; |
} |
return null; |
} |
var getGroupNode = function(group){ |
if(groupNodes[group]){ |
return groupNodes[group].__groupNode; |
} |
return null; |
} |
var updateBacklog = []; |
doh._updateTestList = function(group, fixture, unwindingBacklog){ |
if(!loaded){ |
if(group && fixture){ |
updateBacklog.push([group, fixture]); |
} |
return; |
}else if((updateBacklog.length)&&(!unwindingBacklog)){ |
var tr; |
while(tr=updateBacklog.shift()){ |
doh._updateTestList(tr[0], tr[1], true); |
} |
} |
if(group && fixture){ |
if(!groupNodes[group]){ |
groupNodes[group] = { |
"__groupNode": addGroupToList(group) |
}; |
} |
if(!groupNodes[group][fixture.name]){ |
groupNodes[group][fixture.name] = addFixtureToList(group, fixture) |
} |
} |
} |
doh._testRegistered = doh._updateTestList; |
doh._groupStarted = function(group){ |
// console.debug("_groupStarted", group); |
var gn = getGroupNode(group); |
if(gn){ |
gn.className = "inProgress"; |
} |
} |
doh._groupFinished = function(group, success){ |
// console.debug("_groupFinished", group); |
var gn = getGroupNode(group); |
if(gn){ |
gn.className = (success) ? "success" : "failure"; |
} |
} |
doh._testStarted = function(group, fixture){ |
// console.debug("_testStarted", group, fixture.name); |
var fn = getFixtureNode(group, fixture); |
if(fn){ |
fn.className = "inProgress"; |
} |
} |
var _nameTimes = {}; |
var _playSound = function(name){ |
if(byId("hiddenAudio") && byId("audio") && byId("audio").checked){ |
// console.debug("playing:", name); |
var nt = _nameTimes[name]; |
// only play sounds once every second or so |
if((!nt)||(((new Date)-nt) > 700)){ |
_nameTimes[name] = new Date(); |
var tc = document.createElement("span"); |
byId("hiddenAudio").appendChild(tc); |
tc.innerHTML = '<embed src="_sounds/'+name+'.wav" autostart="true" loop="false" hidden="true" width="1" height="1"></embed>'; |
} |
} |
} |
doh._testFinished = function(group, fixture, success){ |
var fn = getFixtureNode(group, fixture); |
if(fn){ |
fn.getElementsByTagName("td")[3].innerHTML = (fixture.endTime-fixture.startTime)+"ms"; |
fn.className = (success) ? "success" : "failure"; |
if(!success){ |
_playSound("doh"); |
var gn = getGroupNode(group); |
if(gn){ |
gn.className = "failure"; |
_getGroupToggler(group)(null, true); |
} |
} |
} |
this.debug(((success) ? "PASSED" : "FAILED"), "test:", fixture.name); |
} |
// FIXME: move implementation to _browserRunner? |
doh.registerUrl = function( /*String*/ group, |
/*String*/ url, |
/*Integer*/ timeout){ |
var tg = new String(group); |
this.register(group, { |
name: url, |
setUp: function(){ |
doh.currentGroupName = tg; |
doh.currentGroup = this; |
doh.currentUrl = url; |
this.d = new doh.Deferred(); |
doh.currentTestDeferred = this.d; |
showTestPage(); |
byId("testBody").src = url; |
}, |
timeout: timeout||10000, // 10s |
// timeout: timeout||1000, // 10s |
runTest: function(){ |
// FIXME: implement calling into the url's groups here!! |
return this.d; |
}, |
tearDown: function(){ |
doh.currentGroupName = null; |
doh.currentGroup = null; |
doh.currentTestDeferred = null; |
doh.currentUrl = null; |
// this.d.errback(false); |
// byId("testBody").src = "about:blank"; |
showLogPage(); |
} |
}); |
} |
// |
// Utility code for runner.html |
// |
// var isSafari = navigator.appVersion.indexOf("Safari") >= 0; |
var tabzidx = 1; |
var _showTab = function(toShow, toHide){ |
// FIXME: I don't like hiding things this way. |
byId(toHide).style.display = "none"; |
with(byId(toShow).style){ |
display = ""; |
zIndex = ++tabzidx; |
} |
} |
showTestPage = function(){ |
_showTab("testBody", "logBody"); |
} |
showLogPage = function(){ |
_showTab("logBody", "testBody"); |
} |
var runAll = true; |
toggleRunAll = function(){ |
// would be easier w/ query...sigh |
runAll = (!runAll); |
if(!byId("testList")){ return; } |
var tb = byId("testList").tBodies[0]; |
var inputs = tb.getElementsByTagName("input"); |
var x=0; var tn; |
while(tn=inputs[x++]){ |
tn.checked = runAll; |
doh._groups[tn.group].skip = (!runAll); |
} |
} |
var listHeightTimer = null; |
var setListHeight = function(){ |
if(listHeightTimer){ |
clearTimeout(listHeightTimer); |
} |
var tl = byId("testList"); |
if(!tl){ return; } |
listHeightTimer = setTimeout(function(){ |
tl.style.display = "none"; |
tl.style.display = ""; |
}, 10); |
} |
_addOnEvt("resize", setListHeight); |
_addOnEvt("load", setListHeight); |
_addOnEvt("load", function(){ |
if(loaded){ return; } |
loaded = true; |
groupTemplate = byId("groupTemplate"); |
if(!groupTemplate){ |
// make sure we've got an ammenable DOM structure |
return; |
} |
groupTemplate.parentNode.removeChild(groupTemplate); |
groupTemplate.style.display = ""; |
testTemplate = byId("testTemplate"); |
testTemplate.parentNode.removeChild(testTemplate); |
testTemplate.style.display = ""; |
doh._updateTestList(); |
}); |
_addOnEvt("load", |
function(){ |
doh._onEnd = function(){ |
if(doh._failureCount == 0){ |
doh.debug("WOOHOO!!"); |
_playSound("woohoo"); |
}else{ |
console.debug("doh._failureCount:", doh._failureCount); |
} |
if(byId("play")){ |
toggleRunning(); |
} |
} |
if(!byId("play")){ |
// make sure we've got an ammenable DOM structure |
return; |
} |
var isRunning = false; |
var toggleRunning = function(){ |
// ugg, this would be so much better w/ dojo.query() |
if(isRunning){ |
byId("play").style.display = byId("pausedMsg").style.display = ""; |
byId("playingMsg").style.display = byId("pause").style.display = "none"; |
isRunning = false; |
}else{ |
byId("play").style.display = byId("pausedMsg").style.display = "none"; |
byId("playingMsg").style.display = byId("pause").style.display = ""; |
isRunning = true; |
} |
} |
doh.run = (function(oldRun){ |
return function(){ |
if(!doh._currentGroup){ |
toggleRunning(); |
} |
return oldRun.apply(doh, arguments); |
} |
})(doh.run); |
var btns = byId("toggleButtons").getElementsByTagName("span"); |
var node; var idx=0; |
while(node=btns[idx++]){ |
node.onclick = toggleRunning; |
} |
} |
); |
}else{ |
// we're in an iframe environment. Time to mix it up a bit. |
_doh = window.parent.doh; |
var _thisGroup = _doh.currentGroupName; |
var _thisUrl = _doh.currentUrl; |
if(_thisGroup){ |
doh._testRegistered = function(group, tObj){ |
_doh._updateTestList(_thisGroup, tObj); |
} |
doh._onEnd = function(){ |
_doh._errorCount += doh._errorCount; |
_doh._failureCount += doh._failureCount; |
_doh._testCount += doh._testCount; |
// should we be really adding raw group counts? |
_doh._groupCount += doh._groupCount; |
_doh.currentTestDeferred.callback(true); |
} |
var otr = doh._getTestObj; |
doh._getTestObj = function(){ |
var tObj = otr.apply(doh, arguments); |
tObj.name = _thisUrl+"::"+arguments[0]+"::"+tObj.name; |
return tObj; |
} |
doh.debug = doh.hitch(_doh, "debug"); |
doh.registerUrl = doh.hitch(_doh, "registerUrl"); |
doh._testStarted = function(group, fixture){ |
_doh._testStarted(_thisGroup, fixture); |
} |
doh._testFinished = function(g, f, s){ |
_doh._testFinished(_thisGroup, f, s); |
} |
doh._report = function(){}; |
} |
} |
})(); |
/trunk/api/js/dojo1.0/util/doh/_sounds/LICENSE |
---|
New file |
0,0 → 1,10 |
License Disclaimer: |
All contents of this directory are Copyright (c) the Dojo Foundation, with the |
following exceptions: |
------------------------------------------------------------------------------- |
woohoo.wav, doh.wav, dohaaa.wav: |
* Copyright original authors. |
Copied from: |
http://simpson-homer.com/homer-simpson-soundboard.html |
/trunk/api/js/dojo1.0/util/doh/_sounds/doh.wav |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/trunk/api/js/dojo1.0/util/doh/_sounds/doh.wav |
---|
New file |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/trunk/api/js/dojo1.0/util/doh/_sounds/woohoo.wav |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/trunk/api/js/dojo1.0/util/doh/_sounds/woohoo.wav |
---|
New file |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/trunk/api/js/dojo1.0/util/doh/_sounds/dohaaa.wav |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/trunk/api/js/dojo1.0/util/doh/_sounds/dohaaa.wav |
---|
New file |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/trunk/api/js/dojo1.0/util/doh/small_logo.png |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
/trunk/api/js/dojo1.0/util/doh/small_logo.png |
---|
New file |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/trunk/api/js/dojo1.0/util/doh/runner.html |
---|
New file |
0,0 → 1,283 |
<html> |
<!-- |
NOTE: we are INTENTIONALLY in quirks mode. It makes it much easier to |
get a "full screen" UI w/ straightforward CSS. |
--> |
<!-- |
// TODO: implement global progress bar |
// TODO: provide a UI for prompted tests |
--> |
<head> |
<title>The Dojo Unit Test Harness, $Rev$</title> |
<script type="text/javascript"> |
window.dojoUrl = "../../dojo/dojo.js"; |
window.testUrl = ""; |
window.testModule = ""; |
// parse out our test URL and our Dojo URL from the query string |
var qstr = window.location.search.substr(1); |
if(qstr.length){ |
var qparts = qstr.split("&"); |
for(var x=0; x<qparts.length; x++){ |
var tp = qparts[x].split("="); |
if(tp[0] == "dojoUrl"){ |
window.dojoUrl = tp[1]; |
} |
if(tp[0] == "testUrl"){ |
window.testUrl = tp[1]; |
} |
if(tp[0] == "testModule"){ |
window.testModule = tp[1]; |
} |
} |
} |
document.write("<scr"+"ipt type='text/javascript' djConfig='isDebug: true' src='"+dojoUrl+"'></scr"+"ipt>"); |
</script> |
<script type="text/javascript"> |
try{ |
dojo.require("doh.runner"); |
}catch(e){ |
document.write("<scr"+"ipt type='text/javascript' src='runner.js'></scr"+"ipt>"); |
document.write("<scr"+"ipt type='text/javascript' src='_browserRunner.js'></scr"+"ipt>"); |
} |
if(testUrl.length){ |
document.write("<scr"+"ipt type='text/javascript' src='"+testUrl+".js'></scr"+"ipt>"); |
} |
</script> |
<style type="text/css"> |
@import "../../dojo/resources/dojo.css"; |
/* |
body { |
margin: 0px; |
padding: 0px; |
font-size: 13px; |
color: #292929; |
font-family: Myriad, Lucida Grande, Bitstream Vera Sans, Arial, Helvetica, sans-serif; |
*font-size: small; |
*font: x-small; |
} |
th, td { |
font-size: 13px; |
color: #292929; |
font-family: Myriad, Lucida Grande, Bitstream Vera Sans, Arial, Helvetica, sans-serif; |
font-weight: normal; |
} |
* body { |
line-height: 1.25em; |
} |
table { |
border-collapse: collapse; |
} |
*/ |
#testLayout { |
position: relative; |
left: 0px; |
top: 0px; |
width: 100%; |
height: 100%; |
border: 1px solid black; |
border: 0px; |
} |
.tabBody { |
margin: 0px; |
padding: 0px; |
/* |
border: 1px solid black; |
*/ |
background-color: #DEDEDE; |
border: 0px; |
width: 100%; |
height: 100%; |
position: absolute; |
left: 0px; |
top: 0px; |
overflow: auto; |
} |
#logBody { |
padding-left: 5px; |
padding-top: 5px; |
font-family: Monaco, monospace; |
font-size: 11px; |
white-space: pre; |
} |
#progressOuter { |
background:#e9e9e9 url("http://svn.dojotoolkit.org/dojo/dijit/trunk/themes/tundra/dojoTundraGradientBg.png") repeat-x 0 0; |
/* |
border-color: #e8e8e8; |
*/ |
} |
#progressInner { |
background: blue url("http://svn.dojotoolkit.org/dojo/dijit/trunk/themes/tundra/bar.gif") repeat-x 0 0; |
width: 0%; |
position: relative; |
left: 0px; |
top: 0px; |
height: 100%; |
} |
#play, #pause { |
font-family: Webdings; |
font-size: 1.4em; |
border: 1px solid #DEDEDE; |
cursor: pointer; |
padding-right: 0.5em; |
} |
.header { |
border: 1px solid #DEDEDE; |
} |
button.tab { |
border-width: 1px 1px 0px 1px; |
border-style: solid; |
border-color: #DEDEDE; |
margin-right: 5px; |
} |
#testListContainer { |
/* |
border: 1px solid black; |
*/ |
position: relative; |
height: 99%; |
width: 100%; |
overflow: auto; |
} |
#testList { |
border-collapse: collapse; |
position: absolute; |
left: 0px; |
width: 100%; |
} |
#testList > tbody > tr > td { |
border-bottom: 1px solid #DEDEDE; |
border-right : 1px solid #DEDEDE; |
padding: 3px; |
} |
#testListHeader th { |
border-bottom: 1px solid #DEDEDE; |
border-right : 1px solid #DEDEDE; |
padding: 3px; |
font-weight: bolder; |
font-style: italic; |
} |
#toggleButtons { |
float: left; |
background-color: #DEDEDE; |
} |
tr.inProgress { |
background-color: #85afde; |
} |
tr.success { |
background-color: #7cdea7; |
} |
tr.failure { |
background-color: #de827b; |
} |
</style> |
</head> |
<body> |
<table id="testLayout" cellpadding="0" cellspacing="0" style="margin: 0;"> |
<tr valign="top" height="40"> |
<td colspan="2" id="logoBar"> |
<h3 style="margin: 5px 5px 0px 5px; float: left;">D.O.H.: The Dojo Objective Harness</h3> |
<img src="small_logo.png" height="40" style="margin: 0px 5px 0px 5px; float: right;"> |
<span style="margin: 10px 5px 0px 5px; float: right;"> |
<input type="checkbox" id="audio" name="audio"> |
<label for="audio">sounds?</label> |
</span> |
</td> |
</tr> |
<!-- |
<tr valign="top" height="10"> |
<td colspan="2" id="progressOuter"> |
<div id="progressInner">blah</div> |
</td> |
</tr> |
--> |
<tr valign="top" height="30"> |
<td width="30%" class="header"> |
<span id="toggleButtons" onclick="doh.togglePaused();"> |
<button id="play">4</button> |
<button id="pause" style="display: none;">;</button> |
</span> |
<span id="runningStatus"> |
<span id="pausedMsg">Stopped</span> |
<span id="playingMsg" style="display: none;">Tests Running</span> |
</span> |
</td> |
<td width="*" class="header" valign="bottom"> |
<button class="tab" onclick="showTestPage();">Test Page</button> |
<button class="tab" onclick="showLogPage();">Log</button> |
</td> |
</tr> |
<tr valign="top" style="border: 0; padding: 0; margin: 0;"> |
<td height="100%" style="border: 0; padding: 0; margin: 0;"> |
<div id="testListContainer"> |
<table cellpadding="0" cellspacing="0" border="0" |
width="100%" id="testList" style="margin: 0;"> |
<thead> |
<tr id="testListHeader" style="border: 0; padding: 0; margin: 0;" > |
<th> </th> |
<th width="20"> |
<input type="checkbox" checked |
onclick="toggleRunAll();"> |
</th> |
<th width="*" style="text-align: left;">test</th> |
<th width="50">time</th> |
</tr> |
</thead> |
<tbody valign="top"> |
<tr id="groupTemplate" style="display: none;"> |
<td style="font-family: Webdings; width: 15px;">4</td> |
<td> |
<input type="checkbox" checked> |
</td> |
<td>group name</td> |
<td>10ms</td> |
</tr> |
<tr id="testTemplate" style="display: none;"> |
<td> </td> |
<td> </td> |
<td style="padding-left: 20px;">test name</td> |
<td>10ms</td> |
</tr> |
</tbody> |
</table> |
</div> |
</td> |
<td> |
<div style="position: relative; width: 99%; height: 100%; top: 0px; left: 0px;"> |
<div class="tabBody" |
style="z-index: 1;"> |
<pre id="logBody"></pre> |
</div> |
<iframe id="testBody" class="tabBody" |
style="z-index: 0;"></iframe> |
<!-- |
src="http://redesign.dojotoolkit.org"></iframe> |
--> |
</div> |
</td> |
</tr> |
</table> |
<span id="hiddenAudio"></span> |
</body> |
</html> |