Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
B
bootstrap
Project overview
Project overview
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Administrator
bootstrap
Commits
a8139a03
Commit
a8139a03
authored
Jan 19, 2015
by
XhmikosR
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Update QUnit to v1.17.0.
parent
4fd01b7a
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
972 additions
and
549 deletions
+972
-549
js/tests/vendor/qunit.css
js/tests/vendor/qunit.css
+47
-4
js/tests/vendor/qunit.js
js/tests/vendor/qunit.js
+925
-545
No files found.
js/tests/vendor/qunit.css
View file @
a8139a03
/*!
* QUnit 1.1
5
.0
* QUnit 1.1
7
.0
* http://qunitjs.com/
*
* Copyright
2014
jQuery Foundation and other contributors
* Copyright jQuery Foundation and other contributors
* Released under the MIT license
* http://jquery.org/license
*
* Date: 201
4-08-08T16:00
Z
* Date: 201
5-01-19T11:58
Z
*/
/** Font Family and Sizes */
...
...
@@ -77,6 +77,18 @@
#qunit-modulefilter-container
{
float
:
right
;
padding
:
0.2em
;
}
.qunit-url-config
{
display
:
inline-block
;
padding
:
0.1em
;
}
.qunit-filter
{
display
:
block
;
float
:
right
;
margin-left
:
1em
;
}
/** Tests: Pass/Fail */
...
...
@@ -91,7 +103,19 @@
list-style-position
:
inside
;
}
#qunit-tests
.hidepass
li
.pass
,
#qunit-tests
.hidepass
li
.running
{
#qunit-tests
>
li
{
display
:
none
;
}
#qunit-tests
li
.running
,
#qunit-tests
li
.pass
,
#qunit-tests
li
.fail
,
#qunit-tests
li
.skipped
{
display
:
list-item
;
}
#qunit-tests
.hidepass
li
.running
,
#qunit-tests
.hidepass
li
.pass
{
display
:
none
;
}
...
...
@@ -99,6 +123,10 @@
cursor
:
pointer
;
}
#qunit-tests
li
.skipped
strong
{
cursor
:
default
;
}
#qunit-tests
li
a
{
padding
:
0.5em
;
color
:
#C2CCD1
;
...
...
@@ -211,6 +239,21 @@
#qunit-banner
.qunit-fail
{
background-color
:
#EE5757
;
}
/*** Skipped tests */
#qunit-tests
.skipped
{
background-color
:
#EBECE9
;
}
#qunit-tests
.qunit-skipped-label
{
background-color
:
#F4FF77
;
display
:
inline-block
;
font-style
:
normal
;
color
:
#366097
;
line-height
:
1.8em
;
padding
:
0
0.5em
;
margin
:
-0.4em
0.4em
-0.4em
0
;
}
/** Result */
...
...
js/tests/vendor/qunit.js
View file @
a8139a03
/*!
* QUnit 1.1
5
.0
* QUnit 1.1
7
.0
* http://qunitjs.com/
*
* Copyright
2014
jQuery Foundation and other contributors
* Copyright jQuery Foundation and other contributors
* Released under the MIT license
* http://jquery.org/license
*
* Date: 201
4-08-08T16:00
Z
* Date: 201
5-01-19T11:58
Z
*/
(
function
(
window
)
{
...
...
@@ -14,6 +14,7 @@
var
QUnit
,
config
,
onErrorFnPrev
,
loggingCallbacks
=
{},
fileName
=
(
sourceFromStacktrace
(
0
)
||
""
).
replace
(
/
(
:
\d
+
)
+
\)?
/
,
""
).
replace
(
/.+
\/
/
,
""
),
toString
=
Object
.
prototype
.
toString
,
hasOwn
=
Object
.
prototype
.
hasOwnProperty
,
...
...
@@ -22,11 +23,13 @@ var QUnit,
now
=
Date
.
now
||
function
()
{
return
new
Date
().
getTime
();
},
globalStartCalled
=
false
,
runStarted
=
false
,
setTimeout
=
window
.
setTimeout
,
clearTimeout
=
window
.
clearTimeout
,
defined
=
{
document
:
typeof
window
.
document
!==
"
undefined
"
,
setTimeout
:
typeof
window
.
setTimeout
!==
"
undefined
"
,
document
:
window
.
document
!==
undefined
,
setTimeout
:
window
.
setTimeout
!==
undefined
,
sessionStorage
:
(
function
()
{
var
x
=
"
qunit-test-string
"
;
try
{
...
...
@@ -86,132 +89,7 @@ var QUnit,
return
vals
;
};
// Root QUnit object.
// `QUnit` initialized at top of scope
QUnit
=
{
// call on start of module test to prepend name to all tests
module
:
function
(
name
,
testEnvironment
)
{
config
.
currentModule
=
name
;
config
.
currentModuleTestEnvironment
=
testEnvironment
;
config
.
modules
[
name
]
=
true
;
},
asyncTest
:
function
(
testName
,
expected
,
callback
)
{
if
(
arguments
.
length
===
2
)
{
callback
=
expected
;
expected
=
null
;
}
QUnit
.
test
(
testName
,
expected
,
callback
,
true
);
},
test
:
function
(
testName
,
expected
,
callback
,
async
)
{
var
test
;
if
(
arguments
.
length
===
2
)
{
callback
=
expected
;
expected
=
null
;
}
test
=
new
Test
({
testName
:
testName
,
expected
:
expected
,
async
:
async
,
callback
:
callback
,
module
:
config
.
currentModule
,
moduleTestEnvironment
:
config
.
currentModuleTestEnvironment
,
stack
:
sourceFromStacktrace
(
2
)
});
if
(
!
validTest
(
test
)
)
{
return
;
}
test
.
queue
();
},
start
:
function
(
count
)
{
var
message
;
// QUnit hasn't been initialized yet.
// Note: RequireJS (et al) may delay onLoad
if
(
config
.
semaphore
===
undefined
)
{
QUnit
.
begin
(
function
()
{
// This is triggered at the top of QUnit.load, push start() to the event loop, to allow QUnit.load to finish first
setTimeout
(
function
()
{
QUnit
.
start
(
count
);
});
});
return
;
}
config
.
semaphore
-=
count
||
1
;
// don't start until equal number of stop-calls
if
(
config
.
semaphore
>
0
)
{
return
;
}
// Set the starting time when the first test is run
QUnit
.
config
.
started
=
QUnit
.
config
.
started
||
now
();
// ignore if start is called more often then stop
if
(
config
.
semaphore
<
0
)
{
config
.
semaphore
=
0
;
message
=
"
Called start() while already started (QUnit.config.semaphore was 0 already)
"
;
if
(
config
.
current
)
{
QUnit
.
pushFailure
(
message
,
sourceFromStacktrace
(
2
)
);
}
else
{
throw
new
Error
(
message
);
}
return
;
}
// A slight delay, to avoid any current callbacks
if
(
defined
.
setTimeout
)
{
setTimeout
(
function
()
{
if
(
config
.
semaphore
>
0
)
{
return
;
}
if
(
config
.
timeout
)
{
clearTimeout
(
config
.
timeout
);
}
config
.
blocking
=
false
;
process
(
true
);
},
13
);
}
else
{
config
.
blocking
=
false
;
process
(
true
);
}
},
stop
:
function
(
count
)
{
config
.
semaphore
+=
count
||
1
;
config
.
blocking
=
true
;
if
(
config
.
testTimeout
&&
defined
.
setTimeout
)
{
clearTimeout
(
config
.
timeout
);
config
.
timeout
=
setTimeout
(
function
()
{
QUnit
.
ok
(
false
,
"
Test timed out
"
);
config
.
semaphore
=
1
;
QUnit
.
start
();
},
config
.
testTimeout
);
}
}
};
// We use the prototype to distinguish between properties that should
// be exposed as globals (and in exports) and those that shouldn't
(
function
()
{
function
F
()
{}
F
.
prototype
=
QUnit
;
QUnit
=
new
F
();
// Make F QUnit's constructor so that we can add to the prototype later
QUnit
.
constructor
=
F
;
}());
QUnit
=
{};
/**
* Config object: Maintain internal state
...
...
@@ -225,10 +103,6 @@ config = {
// block until document ready
blocking
:
true
,
// when enabled, show only failing tests
// gets persisted through sessionStorage and can be changed in UI via checkbox
hidepassed
:
false
,
// by default, run previously failed tests first
// very useful in combination with "Hide passed tests" checked
reorder
:
true
,
...
...
@@ -245,24 +119,40 @@ config = {
// add checkboxes that are persisted in the query-string
// when enabled, the id is set to `true` as a `QUnit.config` property
urlConfig
:
[
{
id
:
"
hidepassed
"
,
label
:
"
Hide passed tests
"
,
tooltip
:
"
Only show tests and assertions that fail. Stored as query-strings.
"
},
{
id
:
"
noglobals
"
,
label
:
"
Check for Globals
"
,
tooltip
:
"
Enabling this will test if any test introduces new properties on the `window` object. Stored as query-strings.
"
tooltip
:
"
Enabling this will test if any test introduces new properties on the
"
+
"
`window` object. Stored as query-strings.
"
},
{
id
:
"
notrycatch
"
,
label
:
"
No try-catch
"
,
tooltip
:
"
Enabling this will run tests outside of a try-catch block. Makes debugging exceptions in IE reasonable. Stored as query-strings.
"
tooltip
:
"
Enabling this will run tests outside of a try-catch block. Makes debugging
"
+
"
exceptions in IE reasonable. Stored as query-strings.
"
}
],
// Set of all modules.
modules
:
{},
modules
:
[],
// The first unnamed module
currentModule
:
{
name
:
""
,
tests
:
[]
},
callbacks
:
{}
};
// Push a loose unnamed module to the modules collection
config
.
modules
.
push
(
config
.
currentModule
);
// Initialize more QUnit.config and QUnit.urlParams
(
function
()
{
var
i
,
current
,
...
...
@@ -286,22 +176,22 @@ config = {
}
}
if
(
urlParams
.
filter
===
true
)
{
delete
urlParams
.
filter
;
}
QUnit
.
urlParams
=
urlParams
;
// String search anywhere in moduleName+testName
config
.
filter
=
urlParams
.
filter
;
// Exact match of the module name
config
.
module
=
urlParams
.
module
;
config
.
testNumber
=
[];
if
(
urlParams
.
testNumber
)
{
config
.
testId
=
[];
if
(
urlParams
.
testId
)
{
// Ensure that urlParams.testNumber is an array
urlParams
.
testNumber
=
[].
concat
(
urlParams
.
testNumber
);
for
(
i
=
0
;
i
<
urlParams
.
testNumber
.
length
;
i
++
)
{
current
=
urlParams
.
testNumber
[
i
];
config
.
testNumber
.
push
(
parseInt
(
current
,
10
)
);
// Ensure that urlParams.testId is an array
urlParams
.
testId
=
[].
concat
(
urlParams
.
testId
);
for
(
i
=
0
;
i
<
urlParams
.
testId
.
length
;
i
++
)
{
config
.
testId
.
push
(
urlParams
.
testId
[
i
]
);
}
}
...
...
@@ -309,8 +199,130 @@ config = {
QUnit
.
isLocal
=
location
.
protocol
===
"
file:
"
;
}());
// Root QUnit object.
// `QUnit` initialized at top of scope
extend
(
QUnit
,
{
// call on start of module test to prepend name to all tests
module
:
function
(
name
,
testEnvironment
)
{
var
currentModule
=
{
name
:
name
,
testEnvironment
:
testEnvironment
,
tests
:
[]
};
// DEPRECATED: handles setup/teardown functions,
// beforeEach and afterEach should be used instead
if
(
testEnvironment
&&
testEnvironment
.
setup
)
{
testEnvironment
.
beforeEach
=
testEnvironment
.
setup
;
delete
testEnvironment
.
setup
;
}
if
(
testEnvironment
&&
testEnvironment
.
teardown
)
{
testEnvironment
.
afterEach
=
testEnvironment
.
teardown
;
delete
testEnvironment
.
teardown
;
}
config
.
modules
.
push
(
currentModule
);
config
.
currentModule
=
currentModule
;
},
// DEPRECATED: QUnit.asyncTest() will be removed in QUnit 2.0.
asyncTest
:
function
(
testName
,
expected
,
callback
)
{
if
(
arguments
.
length
===
2
)
{
callback
=
expected
;
expected
=
null
;
}
QUnit
.
test
(
testName
,
expected
,
callback
,
true
);
},
test
:
function
(
testName
,
expected
,
callback
,
async
)
{
var
test
;
if
(
arguments
.
length
===
2
)
{
callback
=
expected
;
expected
=
null
;
}
test
=
new
Test
({
testName
:
testName
,
expected
:
expected
,
async
:
async
,
callback
:
callback
});
test
.
queue
();
},
skip
:
function
(
testName
)
{
var
test
=
new
Test
({
testName
:
testName
,
skip
:
true
});
test
.
queue
();
},
// DEPRECATED: The functionality of QUnit.start() will be altered in QUnit 2.0.
// In QUnit 2.0, invoking it will ONLY affect the `QUnit.config.autostart` blocking behavior.
start
:
function
(
count
)
{
var
globalStartAlreadyCalled
=
globalStartCalled
;
if
(
!
config
.
current
)
{
globalStartCalled
=
true
;
if
(
runStarted
)
{
throw
new
Error
(
"
Called start() outside of a test context while already started
"
);
}
else
if
(
globalStartAlreadyCalled
||
count
>
1
)
{
throw
new
Error
(
"
Called start() outside of a test context too many times
"
);
}
else
if
(
config
.
autostart
)
{
throw
new
Error
(
"
Called start() outside of a test context when
"
+
"
QUnit.config.autostart was true
"
);
}
else
if
(
!
config
.
pageLoaded
)
{
// The page isn't completely loaded yet, so bail out and let `QUnit.load` handle it
config
.
autostart
=
true
;
return
;
}
}
else
{
// If a test is running, adjust its semaphore
config
.
current
.
semaphore
-=
count
||
1
;
// Don't start until equal number of stop-calls
if
(
config
.
current
.
semaphore
>
0
)
{
return
;
}
// throw an Error if start is called more often than stop
if
(
config
.
current
.
semaphore
<
0
)
{
config
.
current
.
semaphore
=
0
;
QUnit
.
pushFailure
(
"
Called start() while already started (test's semaphore was 0 already)
"
,
sourceFromStacktrace
(
2
)
);
return
;
}
}
resumeProcessing
();
},
// DEPRECATED: QUnit.stop() will be removed in QUnit 2.0.
stop
:
function
(
count
)
{
// If there isn't a test running, don't allow QUnit.stop() to be called
if
(
!
config
.
current
)
{
throw
new
Error
(
"
Called stop() outside of a test context
"
);
}
// If a test is running, adjust its semaphore
config
.
current
.
semaphore
+=
count
||
1
;
pauseProcessing
();
},
config
:
config
,
// Safe object type checking
...
...
@@ -351,78 +363,65 @@ extend( QUnit, {
return
undefined
;
},
url
:
function
(
params
)
{
params
=
extend
(
extend
(
{},
QUnit
.
urlParams
),
params
);
var
key
,
querystring
=
"
?
"
;
for
(
key
in
params
)
{
if
(
hasOwn
.
call
(
params
,
key
)
)
{
querystring
+=
encodeURIComponent
(
key
)
+
"
=
"
+
encodeURIComponent
(
params
[
key
]
)
+
"
&
"
;
}
}
return
window
.
location
.
protocol
+
"
//
"
+
window
.
location
.
host
+
window
.
location
.
pathname
+
querystring
.
slice
(
0
,
-
1
);
},
extend
:
extend
});
/**
* @deprecated: Created for backwards compatibility with test runner that set the hook function
* into QUnit.{hook}, instead of invoking it and passing the hook function.
* QUnit.constructor is set to the empty F() above so that we can add to it's prototype here.
* Doing this allows us to tell if the following methods have been overwritten on the actual
* QUnit object.
*/
extend
(
QUnit
.
constructor
.
prototype
,
{
extend
:
extend
,
// Logging callbacks; all receive a single argument with the listed properties
// run test/logs.html for any related changes
begin
:
registerLoggingCallback
(
"
begin
"
),
load
:
function
()
{
config
.
pageLoaded
=
true
;
// done: { failed, passed, total, runtime }
done
:
registerLoggingCallback
(
"
done
"
),
// Initialize the configuration options
extend
(
config
,
{
stats
:
{
all
:
0
,
bad
:
0
},
moduleStats
:
{
all
:
0
,
bad
:
0
},
started
:
0
,
updateRate
:
1000
,
autostart
:
true
,
filter
:
""
},
true
);
// log: { result, actual, expected, message }
log
:
registerLoggingCallback
(
"
log
"
),
config
.
blocking
=
false
;
// testStart: { name }
testStart
:
registerLoggingCallback
(
"
testStart
"
),
if
(
config
.
autostart
)
{
resumeProcessing
();
}
}
});
// testDone: { name, failed, passed, total, runtime }
testDone
:
registerLoggingCallback
(
"
testDone
"
),
// Register logging callbacks
(
function
()
{
var
i
,
l
,
key
,
callbacks
=
[
"
begin
"
,
"
done
"
,
"
log
"
,
"
testStart
"
,
"
testDone
"
,
"
moduleStart
"
,
"
moduleDone
"
];
function
registerLoggingCallback
(
key
)
{
var
loggingCallback
=
function
(
callback
)
{
if
(
QUnit
.
objectType
(
callback
)
!==
"
function
"
)
{
throw
new
Error
(
"
QUnit logging methods require a callback function as their first parameters.
"
);
}
// moduleStart: { name }
moduleStart
:
registerLoggingCallback
(
"
moduleStart
"
),
config
.
callbacks
[
key
].
push
(
callback
);
};
// moduleDone: { name, failed, passed, total }
moduleDone
:
registerLoggingCallback
(
"
moduleDone
"
)
});
// DEPRECATED: This will be removed on QUnit 2.0.0+
// Stores the registered functions allowing restoring
// at verifyLoggingCallbacks() if modified
loggingCallbacks
[
key
]
=
loggingCallback
;
QUnit
.
load
=
function
()
{
runLoggingCallbacks
(
"
begin
"
,
{
totalTests
:
Test
.
count
});
return
loggingCallback
;
}
// Initialize the configuration options
extend
(
config
,
{
stats
:
{
all
:
0
,
bad
:
0
},
moduleStats
:
{
all
:
0
,
bad
:
0
},
started
:
0
,
updateRate
:
1000
,
autostart
:
true
,
filter
:
""
,
semaphore
:
1
},
true
);
for
(
i
=
0
,
l
=
callbacks
.
length
;
i
<
l
;
i
++
)
{
key
=
callbacks
[
i
];
config
.
blocking
=
false
;
// Initialize key collection of logging callback
if
(
QUnit
.
objectType
(
config
.
callbacks
[
key
]
)
===
"
undefined
"
)
{
config
.
callbacks
[
key
]
=
[];
}
if
(
config
.
autostart
)
{
QUnit
.
start
();
QUnit
[
key
]
=
registerLoggingCallback
(
key
);
}
};
}
)()
;
// `onErrorFnPrev` initialized at top of scope
// Preserve other handlers
...
...
@@ -448,7 +447,7 @@ window.onerror = function( error, filePath, linerNr ) {
}
else
{
QUnit
.
test
(
"
global failure
"
,
extend
(
function
()
{
QUnit
.
pushFailure
(
error
,
filePath
+
"
:
"
+
linerNr
);
},
{
validTest
:
validTest
}
)
);
},
{
validTest
:
true
}
)
);
}
return
false
;
}
...
...
@@ -457,21 +456,25 @@ window.onerror = function( error, filePath, linerNr ) {
};
function
done
()
{
var
runtime
,
passed
;
config
.
autorun
=
true
;
// Log the last module results
if
(
config
.
previousModule
)
{
runLoggingCallbacks
(
"
moduleDone
"
,
{
name
:
config
.
previousModule
,
name
:
config
.
previousModule
.
name
,
tests
:
config
.
previousModule
.
tests
,
failed
:
config
.
moduleStats
.
bad
,
passed
:
config
.
moduleStats
.
all
-
config
.
moduleStats
.
bad
,
total
:
config
.
moduleStats
.
all
total
:
config
.
moduleStats
.
all
,
runtime
:
now
()
-
config
.
moduleStats
.
started
});
}
delete
config
.
previousModule
;
var
runtime
=
now
()
-
config
.
started
,
passed
=
config
.
stats
.
all
-
config
.
stats
.
bad
;
runtime
=
now
()
-
config
.
started
;
passed
=
config
.
stats
.
all
-
config
.
stats
.
bad
;
runLoggingCallbacks
(
"
done
"
,
{
failed
:
config
.
stats
.
bad
,
...
...
@@ -481,47 +484,6 @@ function done() {
});
}
/** @return Boolean: true if this test should be ran */
function
validTest
(
test
)
{
var
include
,
filter
=
config
.
filter
&&
config
.
filter
.
toLowerCase
(),
module
=
config
.
module
&&
config
.
module
.
toLowerCase
(),
fullName
=
(
test
.
module
+
"
:
"
+
test
.
testName
).
toLowerCase
();
// Internally-generated tests are always valid
if
(
test
.
callback
&&
test
.
callback
.
validTest
===
validTest
)
{
delete
test
.
callback
.
validTest
;
return
true
;
}
if
(
config
.
testNumber
.
length
>
0
)
{
if
(
inArray
(
test
.
testNumber
,
config
.
testNumber
)
<
0
)
{
return
false
;
}
}
if
(
module
&&
(
!
test
.
module
||
test
.
module
.
toLowerCase
()
!==
module
)
)
{
return
false
;
}
if
(
!
filter
)
{
return
true
;
}
include
=
filter
.
charAt
(
0
)
!==
"
!
"
;
if
(
!
include
)
{
filter
=
filter
.
slice
(
1
);
}
// If the filter matches, we need to honour include
if
(
fullName
.
indexOf
(
filter
)
!==
-
1
)
{
return
include
;
}
// Otherwise, do the opposite
return
!
include
;
}
// Doesn't support IE6 to IE9
// See also https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error/Stack
function
extractStacktrace
(
e
,
offset
)
{
...
...
@@ -565,15 +527,27 @@ function extractStacktrace( e, offset ) {
return
e
.
sourceURL
+
"
:
"
+
e
.
line
;
}
}
function
sourceFromStacktrace
(
offset
)
{
try
{
throw
new
Error
();
}
catch
(
e
)
{
return
extractStacktrace
(
e
,
offset
);
var
e
=
new
Error
();
if
(
!
e
.
stack
)
{
try
{
throw
e
;
}
catch
(
err
)
{
// This should already be true in most browsers
e
=
err
;
}
}
return
extractStacktrace
(
e
,
offset
);
}
function
synchronize
(
callback
,
last
)
{
if
(
QUnit
.
objectType
(
callback
)
===
"
array
"
)
{
while
(
callback
.
length
)
{
synchronize
(
callback
.
shift
()
);
}
return
;
}
config
.
queue
.
push
(
callback
);
if
(
config
.
autorun
&&
!
config
.
blocking
)
{
...
...
@@ -586,10 +560,16 @@ function process( last ) {
process
(
last
);
}
var
start
=
now
();
config
.
depth
=
config
.
depth
?
config
.
depth
+
1
:
1
;
config
.
depth
=
(
config
.
depth
||
0
)
+
1
;
while
(
config
.
queue
.
length
&&
!
config
.
blocking
)
{
if
(
!
defined
.
setTimeout
||
config
.
updateRate
<=
0
||
(
(
now
()
-
start
)
<
config
.
updateRate
)
)
{
if
(
!
defined
.
setTimeout
||
config
.
updateRate
<=
0
||
(
(
now
()
-
start
)
<
config
.
updateRate
)
)
{
if
(
config
.
current
)
{
// Reset async tracking for each phase of the Test lifecycle
config
.
current
.
usedAsync
=
false
;
}
config
.
queue
.
shift
()();
}
else
{
setTimeout
(
next
,
13
);
...
...
@@ -602,6 +582,79 @@ function process( last ) {
}
}
function
begin
()
{
var
i
,
l
,
modulesLog
=
[];
// If the test run hasn't officially begun yet
if
(
!
config
.
started
)
{
// Record the time of the test run's beginning
config
.
started
=
now
();
verifyLoggingCallbacks
();
// Delete the loose unnamed module if unused.
if
(
config
.
modules
[
0
].
name
===
""
&&
config
.
modules
[
0
].
tests
.
length
===
0
)
{
config
.
modules
.
shift
();
}
// Avoid unnecessary information by not logging modules' test environments
for
(
i
=
0
,
l
=
config
.
modules
.
length
;
i
<
l
;
i
++
)
{
modulesLog
.
push
({
name
:
config
.
modules
[
i
].
name
,
tests
:
config
.
modules
[
i
].
tests
});
}
// The test run is officially beginning now
runLoggingCallbacks
(
"
begin
"
,
{
totalTests
:
Test
.
count
,
modules
:
modulesLog
});
}
config
.
blocking
=
false
;
process
(
true
);
}
function
resumeProcessing
()
{
runStarted
=
true
;
// A slight delay to allow this iteration of the event loop to finish (more assertions, etc.)
if
(
defined
.
setTimeout
)
{
setTimeout
(
function
()
{
if
(
config
.
current
&&
config
.
current
.
semaphore
>
0
)
{
return
;
}
if
(
config
.
timeout
)
{
clearTimeout
(
config
.
timeout
);
}
begin
();
},
13
);
}
else
{
begin
();
}
}
function
pauseProcessing
()
{
config
.
blocking
=
true
;
if
(
config
.
testTimeout
&&
defined
.
setTimeout
)
{
clearTimeout
(
config
.
timeout
);
config
.
timeout
=
setTimeout
(
function
()
{
if
(
config
.
current
)
{
config
.
current
.
semaphore
=
0
;
QUnit
.
pushFailure
(
"
Test timed out
"
,
sourceFromStacktrace
(
2
)
);
}
else
{
throw
new
Error
(
"
Test timed out
"
);
}
resumeProcessing
();
},
config
.
testTimeout
);
}
}
function
saveGlobal
()
{
config
.
pollution
=
[];
...
...
@@ -671,18 +724,6 @@ function extend( a, b, undefOnly ) {
return
a
;
}
function
registerLoggingCallback
(
key
)
{
// Initialize key collection of logging callback
if
(
QUnit
.
objectType
(
config
.
callbacks
[
key
]
)
===
"
undefined
"
)
{
config
.
callbacks
[
key
]
=
[];
}
return
function
(
callback
)
{
config
.
callbacks
[
key
].
push
(
callback
);
};
}
function
runLoggingCallbacks
(
key
,
args
)
{
var
i
,
l
,
callbacks
;
...
...
@@ -692,6 +733,34 @@ function runLoggingCallbacks( key, args ) {
}
}
// DEPRECATED: This will be removed on 2.0.0+
// This function verifies if the loggingCallbacks were modified by the user
// If so, it will restore it, assign the given callback and print a console warning
function
verifyLoggingCallbacks
()
{
var
loggingCallback
,
userCallback
;
for
(
loggingCallback
in
loggingCallbacks
)
{
if
(
QUnit
[
loggingCallback
]
!==
loggingCallbacks
[
loggingCallback
]
)
{
userCallback
=
QUnit
[
loggingCallback
];
// Restore the callback function
QUnit
[
loggingCallback
]
=
loggingCallbacks
[
loggingCallback
];
// Assign the deprecated given callback
QUnit
[
loggingCallback
](
userCallback
);
if
(
window
.
console
&&
window
.
console
.
warn
)
{
window
.
console
.
warn
(
"
QUnit.
"
+
loggingCallback
+
"
was replaced with a new value.
\n
"
+
"
Please, check out the documentation on how to apply logging callbacks.
\n
"
+
"
Reference: http://api.qunitjs.com/category/callbacks/
"
);
}
}
}
}
// from jquery.js
function
inArray
(
elem
,
array
)
{
if
(
array
.
indexOf
)
{
...
...
@@ -708,16 +777,46 @@ function inArray( elem, array ) {
}
function
Test
(
settings
)
{
var
i
,
l
;
++
Test
.
count
;
extend
(
this
,
settings
);
this
.
assert
=
new
Assert
(
this
);
this
.
assertions
=
[];
this
.
testNumber
=
++
Test
.
count
;
this
.
semaphore
=
0
;
this
.
usedAsync
=
false
;
this
.
module
=
config
.
currentModule
;
this
.
stack
=
sourceFromStacktrace
(
3
);
// Register unique strings
for
(
i
=
0
,
l
=
this
.
module
.
tests
;
i
<
l
.
length
;
i
++
)
{
if
(
this
.
module
.
tests
[
i
].
name
===
this
.
testName
)
{
this
.
testName
+=
"
"
;
}
}
this
.
testId
=
generateHash
(
this
.
module
.
name
,
this
.
testName
);
this
.
module
.
tests
.
push
({
name
:
this
.
testName
,
testId
:
this
.
testId
});
if
(
settings
.
skip
)
{
// Skipped tests will fully ignore any sent callback
this
.
callback
=
function
()
{};
this
.
async
=
false
;
this
.
expected
=
0
;
}
else
{
this
.
assert
=
new
Assert
(
this
);
}
}
Test
.
count
=
0
;
Test
.
prototype
=
{
setup
:
function
()
{
before
:
function
()
{
if
(
// Emit moduleStart when we're switching from one module to another
...
...
@@ -731,47 +830,43 @@ Test.prototype = {
)
{
if
(
hasOwn
.
call
(
config
,
"
previousModule
"
)
)
{
runLoggingCallbacks
(
"
moduleDone
"
,
{
name
:
config
.
previousModule
,
name
:
config
.
previousModule
.
name
,
tests
:
config
.
previousModule
.
tests
,
failed
:
config
.
moduleStats
.
bad
,
passed
:
config
.
moduleStats
.
all
-
config
.
moduleStats
.
bad
,
total
:
config
.
moduleStats
.
all
total
:
config
.
moduleStats
.
all
,
runtime
:
now
()
-
config
.
moduleStats
.
started
});
}
config
.
previousModule
=
this
.
module
;
config
.
moduleStats
=
{
all
:
0
,
bad
:
0
};
config
.
moduleStats
=
{
all
:
0
,
bad
:
0
,
started
:
now
()
};
runLoggingCallbacks
(
"
moduleStart
"
,
{
name
:
this
.
module
name
:
this
.
module
.
name
,
tests
:
this
.
module
.
tests
});
}
config
.
current
=
this
;
this
.
testEnvironment
=
extend
({
setup
:
function
()
{},
teardown
:
function
()
{}
},
this
.
moduleTestEnvironment
);
this
.
testEnvironment
=
extend
(
{},
this
.
module
.
testEnvironment
);
delete
this
.
testEnvironment
.
beforeEach
;
delete
this
.
testEnvironment
.
afterEach
;
this
.
started
=
now
();
runLoggingCallbacks
(
"
testStart
"
,
{
name
:
this
.
testName
,
module
:
this
.
module
,
test
Number
:
this
.
testNumber
module
:
this
.
module
.
name
,
test
Id
:
this
.
testId
});
if
(
!
config
.
pollution
)
{
saveGlobal
();
}
if
(
config
.
notrycatch
)
{
this
.
testEnvironment
.
setup
.
call
(
this
.
testEnvironment
,
this
.
assert
);
return
;
}
try
{
this
.
testEnvironment
.
setup
.
call
(
this
.
testEnvironment
,
this
.
assert
);
}
catch
(
e
)
{
this
.
pushFailure
(
"
Setup failed on
"
+
this
.
testName
+
"
:
"
+
(
e
.
message
||
e
),
extractStacktrace
(
e
,
0
)
);
}
},
run
:
function
()
{
var
promise
;
config
.
current
=
this
;
if
(
this
.
async
)
{
...
...
@@ -781,18 +876,17 @@ Test.prototype = {
this
.
callbackStarted
=
now
();
if
(
config
.
notrycatch
)
{
this
.
callback
.
call
(
this
.
testEnvironment
,
this
.
assert
);
this
.
callbackRuntime
=
now
()
-
this
.
callbackStarted
;
promise
=
this
.
callback
.
call
(
this
.
testEnvironment
,
this
.
assert
);
this
.
resolvePromise
(
promise
)
;
return
;
}
try
{
this
.
callback
.
call
(
this
.
testEnvironment
,
this
.
assert
);
this
.
callbackRuntime
=
now
()
-
this
.
callbackStarted
;
promise
=
this
.
callback
.
call
(
this
.
testEnvironment
,
this
.
assert
);
this
.
resolvePromise
(
promise
)
;
}
catch
(
e
)
{
this
.
callbackRuntime
=
now
()
-
this
.
callbackStarted
;
this
.
pushFailure
(
"
Died on test #
"
+
(
this
.
assertions
.
length
+
1
)
+
"
"
+
this
.
stack
+
"
:
"
+
(
e
.
message
||
e
),
extractStacktrace
(
e
,
0
)
);
this
.
pushFailure
(
"
Died on test #
"
+
(
this
.
assertions
.
length
+
1
)
+
"
"
+
this
.
stack
+
"
:
"
+
(
e
.
message
||
e
),
extractStacktrace
(
e
,
0
)
);
// else next test will carry the responsibility
saveGlobal
();
...
...
@@ -803,31 +897,59 @@ Test.prototype = {
}
}
},
teardown
:
function
()
{
config
.
current
=
this
;
if
(
config
.
notrycatch
)
{
if
(
typeof
this
.
callbackRuntime
===
"
undefined
"
)
{
this
.
callbackRuntime
=
now
()
-
this
.
callbackStarted
;
after
:
function
()
{
checkPollution
();
},
queueHook
:
function
(
hook
,
hookName
)
{
var
promise
,
test
=
this
;
return
function
runHook
()
{
config
.
current
=
test
;
if
(
config
.
notrycatch
)
{
promise
=
hook
.
call
(
test
.
testEnvironment
,
test
.
assert
);
test
.
resolvePromise
(
promise
,
hookName
);
return
;
}
this
.
testEnvironment
.
teardown
.
call
(
this
.
testEnvironment
,
this
.
assert
);
return
;
}
else
{
try
{
this
.
testEnvironment
.
teardown
.
call
(
this
.
testEnvironment
,
this
.
assert
);
}
catch
(
e
)
{
this
.
pushFailure
(
"
Teardown failed on
"
+
this
.
testName
+
"
:
"
+
(
e
.
message
||
e
),
extractStacktrace
(
e
,
0
)
);
promise
=
hook
.
call
(
test
.
testEnvironment
,
test
.
assert
);
test
.
resolvePromise
(
promise
,
hookName
);
}
catch
(
error
)
{
test
.
pushFailure
(
hookName
+
"
failed on
"
+
test
.
testName
+
"
:
"
+
(
error
.
message
||
error
),
extractStacktrace
(
error
,
0
)
);
}
};
},
// Currently only used for module level hooks, can be used to add global level ones
hooks
:
function
(
handler
)
{
var
hooks
=
[];
// Hooks are ignored on skipped tests
if
(
this
.
skip
)
{
return
hooks
;
}
checkPollution
();
if
(
this
.
module
.
testEnvironment
&&
QUnit
.
objectType
(
this
.
module
.
testEnvironment
[
handler
]
)
===
"
function
"
)
{
hooks
.
push
(
this
.
queueHook
(
this
.
module
.
testEnvironment
[
handler
],
handler
)
);
}
return
hooks
;
},
finish
:
function
()
{
config
.
current
=
this
;
if
(
config
.
requireExpects
&&
this
.
expected
===
null
)
{
this
.
pushFailure
(
"
Expected number of assertions to be defined, but expect() was not called.
"
,
this
.
stack
);
this
.
pushFailure
(
"
Expected number of assertions to be defined, but expect() was
"
+
"
not called.
"
,
this
.
stack
);
}
else
if
(
this
.
expected
!==
null
&&
this
.
expected
!==
this
.
assertions
.
length
)
{
this
.
pushFailure
(
"
Expected
"
+
this
.
expected
+
"
assertions, but
"
+
this
.
assertions
.
length
+
"
were run
"
,
this
.
stack
);
this
.
pushFailure
(
"
Expected
"
+
this
.
expected
+
"
assertions, but
"
+
this
.
assertions
.
length
+
"
were run
"
,
this
.
stack
);
}
else
if
(
this
.
expected
===
null
&&
!
this
.
assertions
.
length
)
{
this
.
pushFailure
(
"
Expected at least one assertion, but none were run - call expect(0) to accept zero assertions.
"
,
this
.
stack
);
this
.
pushFailure
(
"
Expected at least one assertion, but none were run - call
"
+
"
expect(0) to accept zero assertions.
"
,
this
.
stack
);
}
var
i
,
...
...
@@ -847,7 +969,8 @@ Test.prototype = {
runLoggingCallbacks
(
"
testDone
"
,
{
name
:
this
.
testName
,
module
:
this
.
module
,
module
:
this
.
module
.
name
,
skipped
:
!!
this
.
skip
,
failed
:
bad
,
passed
:
this
.
assertions
.
length
-
bad
,
total
:
this
.
assertions
.
length
,
...
...
@@ -855,12 +978,17 @@ Test.prototype = {
// HTML Reporter use
assertions
:
this
.
assertions
,
test
Number
:
this
.
testNumber
,
test
Id
:
this
.
testId
,
// DEPRECATED: this property will be removed in 2.0.0, use runtime instead
duration
:
this
.
runtime
});
// QUnit.reset() is deprecated and will be replaced for a new
// fixture reset function on QUnit 2.0/2.1.
// It's still called here for backwards compatibility handling
QUnit
.
reset
();
config
.
current
=
undefined
;
},
...
...
@@ -868,26 +996,39 @@ Test.prototype = {
var
bad
,
test
=
this
;
if
(
!
this
.
valid
()
)
{
return
;
}
function
run
()
{
// each of these can by async
synchronize
(
function
()
{
test
.
setup
();
});
synchronize
(
function
()
{
test
.
run
();
});
synchronize
(
function
()
{
test
.
teardown
();
});
synchronize
(
function
()
{
test
.
finish
();
});
synchronize
([
function
()
{
test
.
before
();
},
test
.
hooks
(
"
beforeEach
"
),
function
()
{
test
.
run
();
},
test
.
hooks
(
"
afterEach
"
).
reverse
(),
function
()
{
test
.
after
();
},
function
()
{
test
.
finish
();
}
]);
}
// `bad` initialized at top of scope
// defer when previous test run passed, if storage is available
bad
=
QUnit
.
config
.
reorder
&&
defined
.
sessionStorage
&&
+
sessionStorage
.
getItem
(
"
qunit-test-
"
+
this
.
module
+
"
-
"
+
this
.
testName
);
+
sessionStorage
.
getItem
(
"
qunit-test-
"
+
this
.
module
.
name
+
"
-
"
+
this
.
testName
);
if
(
bad
)
{
run
();
...
...
@@ -899,13 +1040,14 @@ Test.prototype = {
push
:
function
(
result
,
actual
,
expected
,
message
)
{
var
source
,
details
=
{
module
:
this
.
module
,
module
:
this
.
module
.
name
,
name
:
this
.
testName
,
result
:
result
,
message
:
message
,
actual
:
actual
,
expected
:
expected
,
testNumber
:
this
.
testNumber
testId
:
this
.
testId
,
runtime
:
now
()
-
this
.
started
};
if
(
!
result
)
{
...
...
@@ -926,16 +1068,18 @@ Test.prototype = {
pushFailure
:
function
(
message
,
source
,
actual
)
{
if
(
!
this
instanceof
Test
)
{
throw
new
Error
(
"
pushFailure() assertion outside test context, was
"
+
sourceFromStacktrace
(
2
)
);
throw
new
Error
(
"
pushFailure() assertion outside test context, was
"
+
sourceFromStacktrace
(
2
)
);
}
var
details
=
{
module
:
this
.
module
,
module
:
this
.
module
.
name
,
name
:
this
.
testName
,
result
:
false
,
message
:
message
||
"
error
"
,
actual
:
actual
||
null
,
testNumber
:
this
.
testNumber
testId
:
this
.
testId
,
runtime
:
now
()
-
this
.
started
};
if
(
source
)
{
...
...
@@ -948,20 +1092,132 @@ Test.prototype = {
result
:
false
,
message
:
message
});
},
resolvePromise
:
function
(
promise
,
phase
)
{
var
then
,
message
,
test
=
this
;
if
(
promise
!=
null
)
{
then
=
promise
.
then
;
if
(
QUnit
.
objectType
(
then
)
===
"
function
"
)
{
QUnit
.
stop
();
then
.
call
(
promise
,
QUnit
.
start
,
function
(
error
)
{
message
=
"
Promise rejected
"
+
(
!
phase
?
"
during
"
:
phase
.
replace
(
/Each$/
,
""
)
)
+
"
"
+
test
.
testName
+
"
:
"
+
(
error
.
message
||
error
);
test
.
pushFailure
(
message
,
extractStacktrace
(
error
,
0
)
);
// else next test will carry the responsibility
saveGlobal
();
// Unblock
QUnit
.
start
();
}
);
}
}
},
valid
:
function
()
{
var
include
,
filter
=
config
.
filter
,
module
=
QUnit
.
urlParams
.
module
&&
QUnit
.
urlParams
.
module
.
toLowerCase
(),
fullName
=
(
this
.
module
.
name
+
"
:
"
+
this
.
testName
).
toLowerCase
();
// Internally-generated tests are always valid
if
(
this
.
callback
&&
this
.
callback
.
validTest
)
{
return
true
;
}
if
(
config
.
testId
.
length
>
0
&&
inArray
(
this
.
testId
,
config
.
testId
)
<
0
)
{
return
false
;
}
if
(
module
&&
(
!
this
.
module
.
name
||
this
.
module
.
name
.
toLowerCase
()
!==
module
)
)
{
return
false
;
}
if
(
!
filter
)
{
return
true
;
}
include
=
filter
.
charAt
(
0
)
!==
"
!
"
;
if
(
!
include
)
{
filter
=
filter
.
toLowerCase
().
slice
(
1
);
}
// If the filter matches, we need to honour include
if
(
fullName
.
indexOf
(
filter
)
!==
-
1
)
{
return
include
;
}
// Otherwise, do the opposite
return
!
include
;
}
};
// Resets the test setup. Useful for tests that modify the DOM.
/*
DEPRECATED: Use multiple tests instead of resetting inside a test.
Use testStart or testDone for custom cleanup.
This method will throw an error in 2.0, and will be removed in 2.1
*/
QUnit
.
reset
=
function
()
{
// Return on non-browser environments
// This is necessary to not break on node tests
if
(
typeof
window
===
"
undefined
"
)
{
return
;
}
var
fixture
=
defined
.
document
&&
document
.
getElementById
&&
document
.
getElementById
(
"
qunit-fixture
"
);
if
(
fixture
)
{
fixture
.
innerHTML
=
config
.
fixture
;
}
};
QUnit
.
pushFailure
=
function
()
{
if
(
!
QUnit
.
config
.
current
)
{
throw
new
Error
(
"
pushFailure() assertion outside test context, in
"
+
sourceFromStacktrace
(
2
)
);
throw
new
Error
(
"
pushFailure() assertion outside test context, in
"
+
sourceFromStacktrace
(
2
)
);
}
// Gets current test obj
var
currentTest
=
QUnit
.
config
.
current
.
assert
.
test
;
var
currentTest
=
QUnit
.
config
.
current
;
return
currentTest
.
pushFailure
.
apply
(
currentTest
,
arguments
);
};
// Based on Java's String.hashCode, a simple but not
// rigorously collision resistant hashing function
function
generateHash
(
module
,
testName
)
{
var
hex
,
i
=
0
,
hash
=
0
,
str
=
module
+
"
\
x1C
"
+
testName
,
len
=
str
.
length
;
for
(
;
i
<
len
;
i
++
)
{
hash
=
(
(
hash
<<
5
)
-
hash
)
+
str
.
charCodeAt
(
i
);
hash
|=
0
;
}
// Convert the possibly negative integer hash code into an 8 character hex string, which isn't
// strictly necessary but increases user understanding that the id is a SHA-like hash
hex
=
(
0x100000000
+
hash
).
toString
(
16
);
if
(
hex
.
length
<
8
)
{
hex
=
"
0000000
"
+
hex
;
}
return
hex
.
slice
(
-
8
);
}
function
Assert
(
testContext
)
{
this
.
test
=
testContext
;
}
...
...
@@ -969,7 +1225,8 @@ function Assert( testContext ) {
// Assert helpers
QUnit
.
assert
=
Assert
.
prototype
=
{
// Specify the number of expected assertions to guarantee that failed test (no assertions are run at all) don't slip through.
// Specify the number of expected assertions to guarantee that failed test
// (no assertions are run at all) don't slip through.
expect
:
function
(
asserts
)
{
if
(
arguments
.
length
===
1
)
{
this
.
test
.
expected
=
asserts
;
...
...
@@ -978,20 +1235,51 @@ QUnit.assert = Assert.prototype = {
}
},
// Increment this Test's semaphore counter, then return a single-use function that
// decrements that counter a maximum of once.
async
:
function
()
{
var
test
=
this
.
test
,
popped
=
false
;
test
.
semaphore
+=
1
;
test
.
usedAsync
=
true
;
pauseProcessing
();
return
function
done
()
{
if
(
!
popped
)
{
test
.
semaphore
-=
1
;
popped
=
true
;
resumeProcessing
();
}
else
{
test
.
pushFailure
(
"
Called the callback returned from `assert.async` more than once
"
,
sourceFromStacktrace
(
2
)
);
}
};
},
// Exports test.push() to the user API
push
:
function
()
{
var
assert
=
this
;
push
:
function
(
/* result, actual, expected, message */
)
{
var
assert
=
this
,
currentTest
=
(
assert
instanceof
Assert
&&
assert
.
test
)
||
QUnit
.
config
.
current
;
// Backwards compatibility fix.
// Allows the direct use of global exported assertions and QUnit.assert.*
// Although, it's use is not recommended as it can leak assertions
// to other tests from async tests, because we only get a reference to the current test,
// not exactly the test where assertion were intended to be called.
if
(
!
QUnit
.
config
.
curren
t
)
{
if
(
!
currentTes
t
)
{
throw
new
Error
(
"
assertion outside test context, in
"
+
sourceFromStacktrace
(
2
)
);
}
if
(
currentTest
.
usedAsync
===
true
&&
currentTest
.
semaphore
===
0
)
{
currentTest
.
pushFailure
(
"
Assertion after the final `assert.async` was resolved
"
,
sourceFromStacktrace
(
2
)
);
// Allow this assertion to continue running anyway...
}
if
(
!
(
assert
instanceof
Assert
)
)
{
assert
=
QUnit
.
config
.
curren
t
.
assert
;
assert
=
currentTes
t
.
assert
;
}
return
assert
.
test
.
push
.
apply
(
assert
.
test
,
arguments
);
},
...
...
@@ -1005,11 +1293,7 @@ QUnit.assert = Assert.prototype = {
ok
:
function
(
result
,
message
)
{
message
=
message
||
(
result
?
"
okay
"
:
"
failed, expected argument to be truthy, was:
"
+
QUnit
.
dump
.
parse
(
result
)
);
if
(
!!
result
)
{
this
.
push
(
true
,
result
,
true
,
message
);
}
else
{
this
.
test
.
pushFailure
(
message
,
null
,
result
);
}
this
.
push
(
!!
result
,
result
,
true
,
message
);
},
/**
...
...
@@ -1017,7 +1301,7 @@ QUnit.assert = Assert.prototype = {
* Prints out both actual and expected values.
* @name equal
* @function
* @example equal( format( "
Received {0} bytes.", 2), "Received 2 bytes.", "format()
replaces {0} with next argument" );
* @example equal( format( "
{0} bytes.", 2), "2 bytes.", "
replaces {0} with next argument" );
*/
equal
:
function
(
actual
,
expected
,
message
)
{
/*jshint eqeqeq:false */
...
...
@@ -1143,6 +1427,13 @@ QUnit.assert = Assert.prototype = {
}
};
// Provide an alternative to assert.throws(), for enviroments that consider throws a reserved word
// Known to us are: Closure Compiler, Narwhal
(
function
()
{
/*jshint sub:true */
Assert
.
prototype
.
raises
=
Assert
.
prototype
[
"
throws
"
];
}());
// Test for equality any JavaScript type.
// Author: Philippe Rathé <prathe@gmail.com>
QUnit
.
equiv
=
(
function
()
{
...
...
@@ -1356,7 +1647,8 @@ QUnit.equiv = (function() {
}
// apply transition with (1..n) arguments
}(
args
[
0
],
args
[
1
]
)
)
&&
innerEquiv
.
apply
(
this
,
args
.
splice
(
1
,
args
.
length
-
1
)
)
);
}(
args
[
0
],
args
[
1
]
)
)
&&
innerEquiv
.
apply
(
this
,
args
.
splice
(
1
,
args
.
length
-
1
)
)
);
};
return
innerEquiv
;
...
...
@@ -1386,6 +1678,11 @@ QUnit.dump = (function() {
function
array
(
arr
,
stack
)
{
var
i
=
arr
.
length
,
ret
=
new
Array
(
i
);
if
(
dump
.
maxDepth
&&
dump
.
depth
>
dump
.
maxDepth
)
{
return
"
[object Array]
"
;
}
this
.
up
();
while
(
i
--
)
{
ret
[
i
]
=
this
.
parse
(
arr
[
i
],
undefined
,
stack
);
...
...
@@ -1396,25 +1693,28 @@ QUnit.dump = (function() {
var
reName
=
/^function
(\w
+
)
/
,
dump
=
{
// type is used mostly internally, you can fix a (custom)type in advance
parse
:
function
(
obj
,
type
,
stack
)
{
stack
=
stack
||
[];
var
inStack
,
res
,
parser
=
this
.
parsers
[
type
||
this
.
typeOf
(
obj
)
];
type
=
typeof
parser
;
inStack
=
inArray
(
obj
,
stack
);
// objType is used mostly internally, you can fix a (custom) type in advance
parse
:
function
(
obj
,
objType
,
stack
)
{
stack
=
stack
||
[];
var
res
,
parser
,
parserType
,
inStack
=
inArray
(
obj
,
stack
);
if
(
inStack
!==
-
1
)
{
return
"
recursion(
"
+
(
inStack
-
stack
.
length
)
+
"
)
"
;
}
if
(
type
===
"
function
"
)
{
objType
=
objType
||
this
.
typeOf
(
obj
);
parser
=
this
.
parsers
[
objType
];
parserType
=
typeof
parser
;
if
(
parserType
===
"
function
"
)
{
stack
.
push
(
obj
);
res
=
parser
.
call
(
this
,
obj
,
stack
);
stack
.
pop
();
return
res
;
}
return
(
t
ype
===
"
string
"
)
?
parser
:
this
.
parsers
.
error
;
return
(
parserT
ype
===
"
string
"
)
?
parser
:
this
.
parsers
.
error
;
},
typeOf
:
function
(
obj
)
{
var
type
;
...
...
@@ -1428,7 +1728,9 @@ QUnit.dump = (function() {
type
=
"
date
"
;
}
else
if
(
QUnit
.
is
(
"
function
"
,
obj
)
)
{
type
=
"
function
"
;
}
else
if
(
typeof
obj
.
setInterval
!==
undefined
&&
typeof
obj
.
document
!==
"
undefined
"
&&
typeof
obj
.
nodeType
===
"
undefined
"
)
{
}
else
if
(
obj
.
setInterval
!==
undefined
&&
obj
.
document
!==
undefined
&&
obj
.
nodeType
===
undefined
)
{
type
=
"
window
"
;
}
else
if
(
obj
.
nodeType
===
9
)
{
type
=
"
document
"
;
...
...
@@ -1440,7 +1742,9 @@ QUnit.dump = (function() {
toString
.
call
(
obj
)
===
"
[object Array]
"
||
// NodeList objects
(
typeof
obj
.
length
===
"
number
"
&&
typeof
obj
.
item
!==
"
undefined
"
&&
(
obj
.
length
?
obj
.
item
(
0
)
===
obj
[
0
]
:
(
obj
.
item
(
0
)
===
null
&&
typeof
obj
[
0
]
===
"
undefined
"
)
)
)
(
typeof
obj
.
length
===
"
number
"
&&
obj
.
item
!==
undefined
&&
(
obj
.
length
?
obj
.
item
(
0
)
===
obj
[
0
]
:
(
obj
.
item
(
0
)
===
null
&&
obj
[
0
]
===
undefined
)
)
)
)
{
type
=
"
array
"
;
}
else
if
(
obj
.
constructor
===
Error
.
prototype
.
constructor
)
{
...
...
@@ -1451,7 +1755,7 @@ QUnit.dump = (function() {
return
type
;
},
separator
:
function
()
{
return
this
.
multiline
?
this
.
HTML
?
"
<br />
"
:
"
\n
"
:
this
.
HTML
?
"
&
nbsp
;
"
:
"
"
;
return
this
.
multiline
?
this
.
HTML
?
"
<br />
"
:
"
\n
"
:
this
.
HTML
?
"
&
#160
;
"
:
"
"
;
},
// extra can be a number, shortcut for increasing-calling-decreasing
indent
:
function
(
extra
)
{
...
...
@@ -1460,7 +1764,7 @@ QUnit.dump = (function() {
}
var
chr
=
this
.
indentChar
;
if
(
this
.
HTML
)
{
chr
=
chr
.
replace
(
/
\t
/g
,
"
"
).
replace
(
/ /g
,
"
&
nbsp
;
"
);
chr
=
chr
.
replace
(
/
\t
/g
,
"
"
).
replace
(
/ /g
,
"
&
#160
;
"
);
}
return
new
Array
(
this
.
depth
+
(
extra
||
0
)
).
join
(
chr
);
},
...
...
@@ -1479,6 +1783,8 @@ QUnit.dump = (function() {
join
:
join
,
//
depth
:
1
,
maxDepth
:
5
,
// This is the list of parsers, to modify them, use dump.setParser
parsers
:
{
window
:
"
[Window]
"
,
...
...
@@ -1491,6 +1797,7 @@ QUnit.dump = (function() {
"
undefined
"
:
"
undefined
"
,
"
function
"
:
function
(
fn
)
{
var
ret
=
"
function
"
,
// functions never have name in IE
name
=
"
name
"
in
fn
?
fn
.
name
:
(
reName
.
exec
(
fn
)
||
[]
)[
1
];
...
...
@@ -1506,8 +1813,13 @@ QUnit.dump = (function() {
nodelist
:
array
,
"
arguments
"
:
array
,
object
:
function
(
map
,
stack
)
{
/*jshint forin:false */
var
ret
=
[],
keys
,
key
,
val
,
i
,
nonEnumerableProperties
;
var
keys
,
key
,
val
,
i
,
nonEnumerableProperties
,
ret
=
[];
if
(
dump
.
maxDepth
&&
dump
.
depth
>
dump
.
maxDepth
)
{
return
"
[object Object]
"
;
}
dump
.
up
();
keys
=
[];
for
(
key
in
map
)
{
...
...
@@ -1526,7 +1838,8 @@ QUnit.dump = (function() {
for
(
i
=
0
;
i
<
keys
.
length
;
i
++
)
{
key
=
keys
[
i
];
val
=
map
[
key
];
ret
.
push
(
dump
.
parse
(
key
,
"
key
"
)
+
"
:
"
+
dump
.
parse
(
val
,
undefined
,
stack
)
);
ret
.
push
(
dump
.
parse
(
key
,
"
key
"
)
+
"
:
"
+
dump
.
parse
(
val
,
undefined
,
stack
)
);
}
dump
.
down
();
return
join
(
"
{
"
,
ret
,
"
}
"
);
...
...
@@ -1543,10 +1856,12 @@ QUnit.dump = (function() {
for
(
i
=
0
,
len
=
attrs
.
length
;
i
<
len
;
i
++
)
{
val
=
attrs
[
i
].
nodeValue
;
// IE6 includes all attributes in .attributes, even ones not explicitly set.
// Those have values like undefined, null, 0, false, "" or "inherit".
// IE6 includes all attributes in .attributes, even ones not explicitly
// set. Those have values like undefined, null, 0, false, "" or
// "inherit".
if
(
val
&&
val
!==
"
inherit
"
)
{
ret
+=
"
"
+
attrs
[
i
].
nodeName
+
"
=
"
+
dump
.
parse
(
val
,
"
attribute
"
);
ret
+=
"
"
+
attrs
[
i
].
nodeName
+
"
=
"
+
dump
.
parse
(
val
,
"
attribute
"
);
}
}
}
...
...
@@ -1653,9 +1968,17 @@ if ( typeof window !== "undefined" ) {
window
.
QUnit
=
QUnit
;
}
// For
CommonJS environments, export everything
if
(
typeof
module
!==
"
undefined
"
&&
module
.
exports
)
{
// For
nodejs
if
(
typeof
module
!==
"
undefined
"
&&
module
&&
module
.
exports
)
{
module
.
exports
=
QUnit
;
// For consistency with CommonJS environments' exports
module
.
exports
.
QUnit
=
QUnit
;
}
// For CommonJS with exports, but without module.exports, like Rhino
if
(
typeof
exports
!==
"
undefined
"
&&
exports
)
{
exports
.
QUnit
=
QUnit
;
}
// Get a reference to the global object, like window in browsers
...
...
@@ -1664,6 +1987,7 @@ if ( typeof module !== "undefined" && module.exports ) {
})()
));
/*istanbul ignore next */
// jscs:disable maximumLineLength
/*
* Javascript Diff Algorithm
* By John Resig (http://ejohn.org/)
...
...
@@ -1810,6 +2134,7 @@ QUnit.diff = (function() {
return
str
;
};
}());
// jscs:enable
(
function
()
{
...
...
@@ -1828,7 +2153,6 @@ QUnit.init = function() {
config
.
autorun
=
false
;
config
.
filter
=
""
;
config
.
queue
=
[];
config
.
semaphore
=
1
;
// Return on non-browser environments
// This is necessary to not break on node tests
...
...
@@ -1867,27 +2191,7 @@ QUnit.init = function() {
result
.
id
=
"
qunit-testresult
"
;
result
.
className
=
"
result
"
;
tests
.
parentNode
.
insertBefore
(
result
,
tests
);
result
.
innerHTML
=
"
Running...<br/>
"
;
}
};
// Resets the test setup. Useful for tests that modify the DOM.
/*
DEPRECATED: Use multiple tests instead of resetting inside a test.
Use testStart or testDone for custom cleanup.
This method will throw an error in 2.0, and will be removed in 2.1
*/
QUnit
.
reset
=
function
()
{
// Return on non-browser environments
// This is necessary to not break on node tests
if
(
typeof
window
===
"
undefined
"
)
{
return
;
}
var
fixture
=
id
(
"
qunit-fixture
"
);
if
(
fixture
)
{
fixture
.
innerHTML
=
config
.
fixture
;
result
.
innerHTML
=
"
Running...<br /> 
"
;
}
};
...
...
@@ -1899,7 +2203,7 @@ if ( typeof window === "undefined" ) {
var
config
=
QUnit
.
config
,
hasOwn
=
Object
.
prototype
.
hasOwnProperty
,
defined
=
{
document
:
typeof
window
.
document
!==
"
undefined
"
,
document
:
window
.
document
!==
undefined
,
sessionStorage
:
(
function
()
{
var
x
=
"
qunit-test-string
"
;
try
{
...
...
@@ -1910,7 +2214,8 @@ var config = QUnit.config,
return
false
;
}
}())
};
},
modulesList
=
[];
/**
* Escape text for attribute or text content.
...
...
@@ -2020,13 +2325,16 @@ function getUrlConfigHtml() {
escaped
=
escapeText
(
val
.
id
);
escapedTooltip
=
escapeText
(
val
.
tooltip
);
config
[
val
.
id
]
=
QUnit
.
urlParams
[
val
.
id
];
if
(
config
[
val
.
id
]
===
undefined
)
{
config
[
val
.
id
]
=
QUnit
.
urlParams
[
val
.
id
];
}
if
(
!
val
.
value
||
typeof
val
.
value
===
"
string
"
)
{
urlConfigHtml
+=
"
<input id='qunit-urlconfig-
"
+
escaped
+
"
' name='
"
+
escaped
+
"
' type='checkbox'
"
+
(
val
.
value
?
"
value='
"
+
escapeText
(
val
.
value
)
+
"
'
"
:
""
)
+
(
config
[
val
.
id
]
?
"
checked='checked'
"
:
""
)
+
"
title='
"
+
escapedTooltip
+
"
'><label for='qunit-urlconfig-
"
+
escaped
+
"
title='
"
+
escapedTooltip
+
"
'
/
><label for='qunit-urlconfig-
"
+
escaped
+
"
' title='
"
+
escapedTooltip
+
"
'>
"
+
val
.
label
+
"
</label>
"
;
}
else
{
urlConfigHtml
+=
"
<label for='qunit-urlconfig-
"
+
escaped
+
...
...
@@ -2064,69 +2372,145 @@ function getUrlConfigHtml() {
return
urlConfigHtml
;
}
// Handle "click" events on toolbar checkboxes and "change" for select menus.
// Updates the URL with the new state of `config.urlConfig` values.
function
toolbarChanged
()
{
var
updatedUrl
,
value
,
field
=
this
,
params
=
{};
// Detect if field is a select menu or a checkbox
if
(
"
selectedIndex
"
in
field
)
{
value
=
field
.
options
[
field
.
selectedIndex
].
value
||
undefined
;
}
else
{
value
=
field
.
checked
?
(
field
.
defaultValue
||
true
)
:
undefined
;
}
params
[
field
.
name
]
=
value
;
updatedUrl
=
setUrl
(
params
);
if
(
"
hidepassed
"
===
field
.
name
&&
"
replaceState
"
in
window
.
history
)
{
config
[
field
.
name
]
=
value
||
false
;
if
(
value
)
{
addClass
(
id
(
"
qunit-tests
"
),
"
hidepass
"
);
}
else
{
removeClass
(
id
(
"
qunit-tests
"
),
"
hidepass
"
);
}
// It is not necessary to refresh the whole page
window
.
history
.
replaceState
(
null
,
""
,
updatedUrl
);
}
else
{
window
.
location
=
updatedUrl
;
}
}
function
setUrl
(
params
)
{
var
key
,
querystring
=
"
?
"
;
params
=
QUnit
.
extend
(
QUnit
.
extend
(
{},
QUnit
.
urlParams
),
params
);
for
(
key
in
params
)
{
if
(
hasOwn
.
call
(
params
,
key
)
)
{
if
(
params
[
key
]
===
undefined
)
{
continue
;
}
querystring
+=
encodeURIComponent
(
key
);
if
(
params
[
key
]
!==
true
)
{
querystring
+=
"
=
"
+
encodeURIComponent
(
params
[
key
]
);
}
querystring
+=
"
&
"
;
}
}
return
location
.
protocol
+
"
//
"
+
location
.
host
+
location
.
pathname
+
querystring
.
slice
(
0
,
-
1
);
}
function
applyUrlParams
()
{
var
selectBox
=
id
(
"
qunit-modulefilter
"
),
selection
=
decodeURIComponent
(
selectBox
.
options
[
selectBox
.
selectedIndex
].
value
),
filter
=
id
(
"
qunit-filter-input
"
).
value
;
window
.
location
=
setUrl
({
module
:
(
selection
===
""
)
?
undefined
:
selection
,
filter
:
(
filter
===
""
)
?
undefined
:
filter
,
// Remove testId filter
testId
:
undefined
});
}
function
toolbarUrlConfigContainer
()
{
var
urlConfigContainer
=
document
.
createElement
(
"
span
"
);
urlConfigContainer
.
innerHTML
=
getUrlConfigHtml
();
addClass
(
urlConfigContainer
,
"
qunit-url-config
"
);
// For oldIE support:
// * Add handlers to the individual elements instead of the container
// * Use "click" instead of "change" for checkboxes
// * Fallback from event.target to event.srcElement
addEvents
(
urlConfigContainer
.
getElementsByTagName
(
"
input
"
),
"
click
"
,
function
(
event
)
{
var
params
=
{},
target
=
event
.
target
||
event
.
srcElement
;
params
[
target
.
name
]
=
target
.
checked
?
target
.
defaultValue
||
true
:
undefined
;
window
.
location
=
QUnit
.
url
(
params
);
});
addEvents
(
urlConfigContainer
.
getElementsByTagName
(
"
select
"
),
"
change
"
,
function
(
event
)
{
var
params
=
{},
target
=
event
.
target
||
event
.
srcElement
;
params
[
target
.
name
]
=
target
.
options
[
target
.
selectedIndex
].
value
||
undefined
;
window
.
location
=
QUnit
.
url
(
params
);
});
addEvents
(
urlConfigContainer
.
getElementsByTagName
(
"
input
"
),
"
click
"
,
toolbarChanged
);
addEvents
(
urlConfigContainer
.
getElementsByTagName
(
"
select
"
),
"
change
"
,
toolbarChanged
);
return
urlConfigContainer
;
}
function
getModuleNames
()
{
var
i
,
moduleNames
=
[];
function
toolbarLooseFilter
()
{
var
filter
=
document
.
createElement
(
"
form
"
),
label
=
document
.
createElement
(
"
label
"
),
input
=
document
.
createElement
(
"
input
"
),
button
=
document
.
createElement
(
"
button
"
);
addClass
(
filter
,
"
qunit-filter
"
);
label
.
innerHTML
=
"
Filter:
"
;
input
.
type
=
"
text
"
;
input
.
value
=
config
.
filter
||
""
;
input
.
name
=
"
filter
"
;
input
.
id
=
"
qunit-filter-input
"
;
button
.
innerHTML
=
"
Go
"
;
for
(
i
in
config
.
modules
)
{
if
(
config
.
modules
.
hasOwnProperty
(
i
)
)
{
moduleNames
.
push
(
i
);
label
.
appendChild
(
input
);
filter
.
appendChild
(
label
);
filter
.
appendChild
(
button
);
addEvent
(
filter
,
"
submit
"
,
function
(
ev
)
{
applyUrlParams
();
if
(
ev
&&
ev
.
preventDefault
)
{
ev
.
preventDefault
();
}
}
moduleNames
.
sort
(
function
(
a
,
b
)
{
return
a
.
localeCompare
(
b
);
return
false
;
});
return
moduleNames
;
return
filter
;
}
function
toolbarModuleFilterHtml
()
{
var
i
,
moduleFilterHtml
=
""
,
moduleNames
=
getModuleNames
();
moduleFilterHtml
=
""
;
if
(
moduleNames
.
length
<=
1
)
{
if
(
!
modulesList
.
length
)
{
return
false
;
}
modulesList
.
sort
(
function
(
a
,
b
)
{
return
a
.
localeCompare
(
b
);
});
moduleFilterHtml
+=
"
<label for='qunit-modulefilter'>Module: </label>
"
+
"
<select id='qunit-modulefilter' name='modulefilter'><option value=''
"
+
(
config
.
module
===
undefined
?
"
selected='selected'
"
:
""
)
+
(
QUnit
.
urlParams
.
module
===
undefined
?
"
selected='selected'
"
:
""
)
+
"
>< All Modules ></option>
"
;
for
(
i
=
0
;
i
<
module
Names
.
length
;
i
++
)
{
for
(
i
=
0
;
i
<
module
sList
.
length
;
i
++
)
{
moduleFilterHtml
+=
"
<option value='
"
+
escapeText
(
encodeURIComponent
(
module
Names
[
i
]
)
)
+
"
'
"
+
(
config
.
module
===
moduleNames
[
i
]
?
"
selected='selected'
"
:
""
)
+
"
>
"
+
escapeText
(
module
Names
[
i
]
)
+
"
</option>
"
;
escapeText
(
encodeURIComponent
(
module
sList
[
i
]
)
)
+
"
'
"
+
(
QUnit
.
urlParams
.
module
===
modulesList
[
i
]
?
"
selected='selected'
"
:
""
)
+
"
>
"
+
escapeText
(
module
sList
[
i
]
)
+
"
</option>
"
;
}
moduleFilterHtml
+=
"
</select>
"
;
...
...
@@ -2134,7 +2518,8 @@ function toolbarModuleFilterHtml() {
}
function
toolbarModuleFilter
()
{
var
moduleFilter
=
document
.
createElement
(
"
span
"
),
var
toolbar
=
id
(
"
qunit-testrunner-toolbar
"
),
moduleFilter
=
document
.
createElement
(
"
span
"
),
moduleFilterHtml
=
toolbarModuleFilterHtml
();
if
(
!
moduleFilterHtml
)
{
...
...
@@ -2144,75 +2529,27 @@ function toolbarModuleFilter() {
moduleFilter
.
setAttribute
(
"
id
"
,
"
qunit-modulefilter-container
"
);
moduleFilter
.
innerHTML
=
moduleFilterHtml
;
addEvent
(
moduleFilter
.
lastChild
,
"
change
"
,
function
()
{
var
selectBox
=
moduleFilter
.
getElementsByTagName
(
"
select
"
)[
0
],
selectedModule
=
decodeURIComponent
(
selectBox
.
options
[
selectBox
.
selectedIndex
].
value
);
window
.
location
=
QUnit
.
url
({
module
:
(
selectedModule
===
""
)
?
undefined
:
selectedModule
,
// Remove any existing filters
filter
:
undefined
,
testNumber
:
undefined
});
});
return
moduleFilter
;
}
function
toolbarFilter
()
{
var
testList
=
id
(
"
qunit-tests
"
),
filter
=
document
.
createElement
(
"
input
"
);
addEvent
(
moduleFilter
.
lastChild
,
"
change
"
,
applyUrlParams
);
filter
.
type
=
"
checkbox
"
;
filter
.
id
=
"
qunit-filter-pass
"
;
addEvent
(
filter
,
"
click
"
,
function
()
{
if
(
filter
.
checked
)
{
addClass
(
testList
,
"
hidepass
"
);
if
(
defined
.
sessionStorage
)
{
sessionStorage
.
setItem
(
"
qunit-filter-passed-tests
"
,
"
true
"
);
}
}
else
{
removeClass
(
testList
,
"
hidepass
"
);
if
(
defined
.
sessionStorage
)
{
sessionStorage
.
removeItem
(
"
qunit-filter-passed-tests
"
);
}
}
});
if
(
config
.
hidepassed
||
defined
.
sessionStorage
&&
sessionStorage
.
getItem
(
"
qunit-filter-passed-tests
"
)
)
{
filter
.
checked
=
true
;
addClass
(
testList
,
"
hidepass
"
);
}
return
filter
;
}
function
toolbarLabel
()
{
var
label
=
document
.
createElement
(
"
label
"
);
label
.
setAttribute
(
"
for
"
,
"
qunit-filter-pass
"
);
label
.
setAttribute
(
"
title
"
,
"
Only show tests and assertions that fail. Stored in sessionStorage.
"
);
label
.
innerHTML
=
"
Hide passed tests
"
;
return
label
;
toolbar
.
appendChild
(
moduleFilter
);
}
function
appendToolbar
()
{
var
moduleFilter
,
toolbar
=
id
(
"
qunit-testrunner-toolbar
"
);
var
toolbar
=
id
(
"
qunit-testrunner-toolbar
"
);
if
(
toolbar
)
{
toolbar
.
appendChild
(
toolbarFilter
()
);
toolbar
.
appendChild
(
toolbarLabel
()
);
toolbar
.
appendChild
(
toolbarUrlConfigContainer
()
);
toolbar
.
appendChild
(
toolbarLooseFilter
()
);
}
}
moduleFilter
=
toolbarModuleFilter
();
if
(
moduleFilter
)
{
toolbar
.
appendChild
(
moduleFilter
);
}
function
appendHeader
()
{
var
header
=
id
(
"
qunit-header
"
);
if
(
header
)
{
header
.
innerHTML
=
"
<a href='
"
+
setUrl
({
filter
:
undefined
,
module
:
undefined
,
testId
:
undefined
})
+
"
'>
"
+
header
.
innerHTML
+
"
</a>
"
;
}
}
...
...
@@ -2221,9 +2558,6 @@ function appendBanner() {
if
(
banner
)
{
banner
.
className
=
""
;
banner
.
innerHTML
=
"
<a href='
"
+
QUnit
.
url
({
filter
:
undefined
,
module
:
undefined
,
testNumber
:
undefined
})
+
"
'>
"
+
banner
.
innerHTML
+
"
</a>
"
;
}
}
...
...
@@ -2241,7 +2575,7 @@ function appendTestResults() {
result
.
id
=
"
qunit-testresult
"
;
result
.
className
=
"
result
"
;
tests
.
parentNode
.
insertBefore
(
result
,
tests
);
result
.
innerHTML
=
"
Running...<br
> 
;
"
;
result
.
innerHTML
=
"
Running...<br
/> 
;
"
;
}
}
...
...
@@ -2255,28 +2589,84 @@ function storeFixture() {
function
appendUserAgent
()
{
var
userAgent
=
id
(
"
qunit-userAgent
"
);
if
(
userAgent
)
{
userAgent
.
innerHTML
=
navigator
.
userAgent
;
userAgent
.
innerHTML
=
""
;
userAgent
.
appendChild
(
document
.
createTextNode
(
navigator
.
userAgent
)
);
}
}
function
appendTestsList
(
modules
)
{
var
i
,
l
,
x
,
z
,
test
,
moduleObj
;
for
(
i
=
0
,
l
=
modules
.
length
;
i
<
l
;
i
++
)
{
moduleObj
=
modules
[
i
];
if
(
moduleObj
.
name
)
{
modulesList
.
push
(
moduleObj
.
name
);
}
for
(
x
=
0
,
z
=
moduleObj
.
tests
.
length
;
x
<
z
;
x
++
)
{
test
=
moduleObj
.
tests
[
x
];
appendTest
(
test
.
name
,
test
.
testId
,
moduleObj
.
name
);
}
}
}
function
appendTest
(
name
,
testId
,
moduleName
)
{
var
title
,
rerunTrigger
,
testBlock
,
assertList
,
tests
=
id
(
"
qunit-tests
"
);
if
(
!
tests
)
{
return
;
}
title
=
document
.
createElement
(
"
strong
"
);
title
.
innerHTML
=
getNameHtml
(
name
,
moduleName
);
rerunTrigger
=
document
.
createElement
(
"
a
"
);
rerunTrigger
.
innerHTML
=
"
Rerun
"
;
rerunTrigger
.
href
=
setUrl
({
testId
:
testId
});
testBlock
=
document
.
createElement
(
"
li
"
);
testBlock
.
appendChild
(
title
);
testBlock
.
appendChild
(
rerunTrigger
);
testBlock
.
id
=
"
qunit-test-output-
"
+
testId
;
assertList
=
document
.
createElement
(
"
ol
"
);
assertList
.
className
=
"
qunit-assert-list
"
;
testBlock
.
appendChild
(
assertList
);
tests
.
appendChild
(
testBlock
);
}
// HTML Reporter initialization and load
QUnit
.
begin
(
function
()
{
QUnit
.
begin
(
function
(
details
)
{
var
qunit
=
id
(
"
qunit
"
);
// Fixture is the only one necessary to run without the #qunit element
storeFixture
();
if
(
qunit
)
{
qunit
.
innerHTML
=
"
<h1 id='qunit-header'>
"
+
escapeText
(
document
.
title
)
+
"
</h1>
"
+
"
<h2 id='qunit-banner'></h2>
"
+
"
<div id='qunit-testrunner-toolbar'></div>
"
+
"
<h2 id='qunit-userAgent'></h2>
"
+
"
<ol id='qunit-tests'></ol>
"
;
"
<h1 id='qunit-header'>
"
+
escapeText
(
document
.
title
)
+
"
</h1>
"
+
"
<h2 id='qunit-banner'></h2>
"
+
"
<div id='qunit-testrunner-toolbar'></div>
"
+
"
<h2 id='qunit-userAgent'></h2>
"
+
"
<ol id='qunit-tests'></ol>
"
;
}
appendHeader
();
appendBanner
();
appendTestResults
();
appendUserAgent
();
appendToolbar
();
storeFixture
();
appendTestsList
(
details
.
modules
);
toolbarModuleFilter
();
if
(
qunit
&&
config
.
hidepassed
)
{
addClass
(
qunit
.
lastChild
,
"
hidepass
"
);
}
});
QUnit
.
done
(
function
(
details
)
{
...
...
@@ -2286,7 +2676,7 @@ QUnit.done(function( details ) {
html
=
[
"
Tests completed in
"
,
details
.
runtime
,
"
milliseconds.<br>
"
,
"
milliseconds.<br
/
>
"
,
"
<span class='passed'>
"
,
details
.
passed
,
"
</span> assertions of <span class='total'>
"
,
...
...
@@ -2343,35 +2733,20 @@ function getNameHtml( name, module ) {
}
QUnit
.
testStart
(
function
(
details
)
{
var
a
,
b
,
li
,
running
,
assertList
,
name
=
getNameHtml
(
details
.
name
,
details
.
module
),
tests
=
id
(
"
qunit-tests
"
);
if
(
tests
)
{
b
=
document
.
createElement
(
"
strong
"
);
b
.
innerHTML
=
name
;
a
=
document
.
createElement
(
"
a
"
);
a
.
innerHTML
=
"
Rerun
"
;
a
.
href
=
QUnit
.
url
({
testNumber
:
details
.
testNumber
});
li
=
document
.
createElement
(
"
li
"
);
li
.
appendChild
(
b
);
li
.
appendChild
(
a
);
li
.
className
=
"
running
"
;
li
.
id
=
"
qunit-test-output
"
+
details
.
testNumber
;
assertList
=
document
.
createElement
(
"
ol
"
);
assertList
.
className
=
"
qunit-assert-list
"
;
var
running
,
testBlock
;
li
.
appendChild
(
assertList
);
testBlock
=
id
(
"
qunit-test-output-
"
+
details
.
testId
);
if
(
testBlock
)
{
testBlock
.
className
=
"
running
"
;
}
else
{
tests
.
appendChild
(
li
);
// Report later registered tests
appendTest
(
details
.
name
,
details
.
testId
,
details
.
module
);
}
running
=
id
(
"
qunit-testresult
"
);
if
(
running
)
{
running
.
innerHTML
=
"
Running: <br
>
"
+
name
;
running
.
innerHTML
=
"
Running: <br
/>
"
+
getNameHtml
(
details
.
name
,
details
.
module
)
;
}
});
...
...
@@ -2379,7 +2754,7 @@ QUnit.testStart(function( details ) {
QUnit
.
log
(
function
(
details
)
{
var
assertList
,
assertLi
,
message
,
expected
,
actual
,
testItem
=
id
(
"
qunit-test-output
"
+
details
.
testNumber
);
testItem
=
id
(
"
qunit-test-output
-
"
+
details
.
testId
);
if
(
!
testItem
)
{
return
;
...
...
@@ -2387,6 +2762,7 @@ QUnit.log(function( details ) {
message
=
escapeText
(
details
.
message
)
||
(
details
.
result
?
"
okay
"
:
"
failed
"
);
message
=
"
<span class='test-message'>
"
+
message
+
"
</span>
"
;
message
+=
"
<span class='runtime'>@
"
+
details
.
runtime
+
"
ms</span>
"
;
// pushFailure doesn't provide details.expected
// when it calls, it's implicit to also not show expected and diff stuff
...
...
@@ -2430,19 +2806,15 @@ QUnit.log(function( details ) {
QUnit
.
testDone
(
function
(
details
)
{
var
testTitle
,
time
,
testItem
,
assertList
,
good
,
bad
,
testCounts
,
good
,
bad
,
testCounts
,
skipped
,
tests
=
id
(
"
qunit-tests
"
);
// QUnit.reset() is deprecated and will be replaced for a new
// fixture reset function on QUnit 2.0/2.1.
// It's still called here for backwards compatibility handling
QUnit
.
reset
();
if
(
!
tests
)
{
return
;
}
testItem
=
id
(
"
qunit-test-output
"
+
details
.
testNumber
);
testItem
=
id
(
"
qunit-test-output-
"
+
details
.
testId
);
assertList
=
testItem
.
getElementsByTagName
(
"
ol
"
)[
0
];
good
=
details
.
passed
;
...
...
@@ -2471,20 +2843,28 @@ QUnit.testDone(function( details ) {
testTitle
.
innerHTML
+=
"
<b class='counts'>(
"
+
testCounts
+
details
.
assertions
.
length
+
"
)</b>
"
;
addEvent
(
testTitle
,
"
click
"
,
function
()
{
toggleClass
(
assertList
,
"
qunit-collapsed
"
);
});
time
=
document
.
createElement
(
"
span
"
);
time
.
className
=
"
runtime
"
;
time
.
innerHTML
=
details
.
runtime
+
"
ms
"
;
if
(
details
.
skipped
)
{
testItem
.
className
=
"
skipped
"
;
skipped
=
document
.
createElement
(
"
em
"
);
skipped
.
className
=
"
qunit-skipped-label
"
;
skipped
.
innerHTML
=
"
skipped
"
;
testItem
.
insertBefore
(
skipped
,
testTitle
);
}
else
{
addEvent
(
testTitle
,
"
click
"
,
function
()
{
toggleClass
(
assertList
,
"
qunit-collapsed
"
);
});
testItem
.
className
=
bad
?
"
fail
"
:
"
pass
"
;
testItem
.
className
=
bad
?
"
fail
"
:
"
pass
"
;
testItem
.
insertBefore
(
time
,
assertList
);
time
=
document
.
createElement
(
"
span
"
);
time
.
className
=
"
runtime
"
;
time
.
innerHTML
=
details
.
runtime
+
"
ms
"
;
testItem
.
insertBefore
(
time
,
assertList
);
}
});
if
(
!
defined
.
document
||
document
.
readyState
===
"
complete
"
)
{
config
.
pageLoaded
=
true
;
config
.
autorun
=
true
;
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment