Subversion Repositories Applications.papyrus

Compare Revisions

No changes between revisions

Ignore whitespace Rev 2149 → Rev 2150

/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", "&nbsp;&nbsp;&nbsp;&nbsp;");
msg = msg.replace(" ", "&nbsp;");
msg = msg.replace("\n", "<br>&nbsp;");
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 = "&#054;";
}else{
rolledUp = true;
for(var x=0; x<nodes.length; x++){
nodes[x].style.display = "none";
}
toggle.innerHTML = "&#052;";
}
};
}
 
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">&#052;</button>
<button id="pause" style="display: none;">&#059;</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>&nbsp;</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;">&#052;</td>
<td>
<input type="checkbox" checked>
</td>
<td>group name</td>
<td>10ms</td>
</tr>
<tr id="testTemplate" style="display: none;">
<td>&nbsp;</td>
<td>&nbsp;</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>