Skip to content
Toggle navigation
Toggle navigation
This project
Loading...
Sign in
brainfood
/
videojs-contrib-hls
Go to a project
Toggle navigation
Toggle navigation pinning
Projects
Groups
Snippets
Help
Project
Activity
Repository
Graphs
Network
Create a new issue
Commits
Issue Boards
Files
Commits
Network
Compare
Branches
Tags
599fb470
authored
2014-03-22 15:07:06 -0400
by
Gary Katsevman
Browse Files
Options
Browse Files
Tag
Download
Email Patches
Plain Diff
Switch to use npm sinon
1 parent
bf3cf7b6
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
6 additions
and
1759 deletions
libs/sinon/sinon-server-1.9.0.js
package.json
test/videojs-hls.html
libs/sinon/sinon-server-1.9.0.js
deleted
100644 → 0
View file @
bf3cf7b
/**
* Sinon.JS 1.9.0, 2014/03/05
*
* @author Christian Johansen (christian@cjohansen.no)
* @author Contributors: https://github.com/cjohansen/Sinon.JS/blob/master/AUTHORS
*
* (The BSD License)
*
* Copyright (c) 2010-2014, Christian Johansen, christian@cjohansen.no
* 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 Christian Johansen nor the names of his 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 HOLDER 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.
*/
/*jslint eqeqeq: false, onevar: false, forin: true, nomen: false, regexp: false, plusplus: false*/
/*global module, require, __dirname, document*/
/**
* Sinon core utilities. For internal use only.
*
* @author Christian Johansen (christian@cjohansen.no)
* @license BSD
*
* Copyright (c) 2010-2013 Christian Johansen
*/
var
sinon
=
(
function
(
formatio
)
{
var
div
=
typeof
document
!=
"undefined"
&&
document
.
createElement
(
"div"
);
var
hasOwn
=
Object
.
prototype
.
hasOwnProperty
;
function
isDOMNode
(
obj
)
{
var
success
=
false
;
try
{
obj
.
appendChild
(
div
);
success
=
div
.
parentNode
==
obj
;
}
catch
(
e
)
{
return
false
;
}
finally
{
try
{
obj
.
removeChild
(
div
);
}
catch
(
e
)
{
// Remove failed, not much we can do about that
}
}
return
success
;
}
function
isElement
(
obj
)
{
return
div
&&
obj
&&
obj
.
nodeType
===
1
&&
isDOMNode
(
obj
);
}
function
isFunction
(
obj
)
{
return
typeof
obj
===
"function"
||
!!
(
obj
&&
obj
.
constructor
&&
obj
.
call
&&
obj
.
apply
);
}
function
mirrorProperties
(
target
,
source
)
{
for
(
var
prop
in
source
)
{
if
(
!
hasOwn
.
call
(
target
,
prop
))
{
target
[
prop
]
=
source
[
prop
];
}
}
}
function
isRestorable
(
obj
)
{
return
typeof
obj
===
"function"
&&
typeof
obj
.
restore
===
"function"
&&
obj
.
restore
.
sinon
;
}
var
sinon
=
{
wrapMethod
:
function
wrapMethod
(
object
,
property
,
method
)
{
if
(
!
object
)
{
throw
new
TypeError
(
"Should wrap property of object"
);
}
if
(
typeof
method
!=
"function"
)
{
throw
new
TypeError
(
"Method wrapper should be function"
);
}
var
wrappedMethod
=
object
[
property
],
error
;
if
(
!
isFunction
(
wrappedMethod
))
{
error
=
new
TypeError
(
"Attempted to wrap "
+
(
typeof
wrappedMethod
)
+
" property "
+
property
+
" as function"
);
}
if
(
wrappedMethod
.
restore
&&
wrappedMethod
.
restore
.
sinon
)
{
error
=
new
TypeError
(
"Attempted to wrap "
+
property
+
" which is already wrapped"
);
}
if
(
wrappedMethod
.
calledBefore
)
{
var
verb
=
!!
wrappedMethod
.
returns
?
"stubbed"
:
"spied on"
;
error
=
new
TypeError
(
"Attempted to wrap "
+
property
+
" which is already "
+
verb
);
}
if
(
error
)
{
if
(
wrappedMethod
.
_stack
)
{
error
.
stack
+=
'\n--------------\n'
+
wrappedMethod
.
_stack
;
}
throw
error
;
}
// IE 8 does not support hasOwnProperty on the window object and Firefox has a problem
// when using hasOwn.call on objects from other frames.
var
owned
=
object
.
hasOwnProperty
?
object
.
hasOwnProperty
(
property
)
:
hasOwn
.
call
(
object
,
property
);
object
[
property
]
=
method
;
method
.
displayName
=
property
;
// Set up a stack trace which can be used later to find what line of
// code the original method was created on.
method
.
_stack
=
(
new
Error
(
'Stack Trace for original'
)).
stack
;
method
.
restore
=
function
()
{
// For prototype properties try to reset by delete first.
// If this fails (ex: localStorage on mobile safari) then force a reset
// via direct assignment.
if
(
!
owned
)
{
delete
object
[
property
];
}
if
(
object
[
property
]
===
method
)
{
object
[
property
]
=
wrappedMethod
;
}
};
method
.
restore
.
sinon
=
true
;
mirrorProperties
(
method
,
wrappedMethod
);
return
method
;
},
extend
:
function
extend
(
target
)
{
for
(
var
i
=
1
,
l
=
arguments
.
length
;
i
<
l
;
i
+=
1
)
{
for
(
var
prop
in
arguments
[
i
])
{
if
(
arguments
[
i
].
hasOwnProperty
(
prop
))
{
target
[
prop
]
=
arguments
[
i
][
prop
];
}
// DONT ENUM bug, only care about toString
if
(
arguments
[
i
].
hasOwnProperty
(
"toString"
)
&&
arguments
[
i
].
toString
!=
target
.
toString
)
{
target
.
toString
=
arguments
[
i
].
toString
;
}
}
}
return
target
;
},
create
:
function
create
(
proto
)
{
var
F
=
function
()
{};
F
.
prototype
=
proto
;
return
new
F
();
},
deepEqual
:
function
deepEqual
(
a
,
b
)
{
if
(
sinon
.
match
&&
sinon
.
match
.
isMatcher
(
a
))
{
return
a
.
test
(
b
);
}
if
(
typeof
a
!=
"object"
||
typeof
b
!=
"object"
)
{
return
a
===
b
;
}
if
(
isElement
(
a
)
||
isElement
(
b
))
{
return
a
===
b
;
}
if
(
a
===
b
)
{
return
true
;
}
if
((
a
===
null
&&
b
!==
null
)
||
(
a
!==
null
&&
b
===
null
))
{
return
false
;
}
if
(
a
instanceof
RegExp
&&
b
instanceof
RegExp
)
{
return
(
a
.
source
===
b
.
source
)
&&
(
a
.
global
===
b
.
global
)
&&
(
a
.
ignoreCase
===
b
.
ignoreCase
)
&&
(
a
.
multiline
===
b
.
multiline
);
}
var
aString
=
Object
.
prototype
.
toString
.
call
(
a
);
if
(
aString
!=
Object
.
prototype
.
toString
.
call
(
b
))
{
return
false
;
}
if
(
aString
==
"[object Date]"
)
{
return
a
.
valueOf
()
===
b
.
valueOf
();
}
var
prop
,
aLength
=
0
,
bLength
=
0
;
if
(
aString
==
"[object Array]"
&&
a
.
length
!==
b
.
length
)
{
return
false
;
}
for
(
prop
in
a
)
{
aLength
+=
1
;
if
(
!
deepEqual
(
a
[
prop
],
b
[
prop
]))
{
return
false
;
}
}
for
(
prop
in
b
)
{
bLength
+=
1
;
}
return
aLength
==
bLength
;
},
functionName
:
function
functionName
(
func
)
{
var
name
=
func
.
displayName
||
func
.
name
;
// Use function decomposition as a last resort to get function
// name. Does not rely on function decomposition to work - if it
// doesn't debugging will be slightly less informative
// (i.e. toString will say 'spy' rather than 'myFunc').
if
(
!
name
)
{
var
matches
=
func
.
toString
().
match
(
/function
([^\s\(]
+
)
/
);
name
=
matches
&&
matches
[
1
];
}
return
name
;
},
functionToString
:
function
toString
()
{
if
(
this
.
getCall
&&
this
.
callCount
)
{
var
thisValue
,
prop
,
i
=
this
.
callCount
;
while
(
i
--
)
{
thisValue
=
this
.
getCall
(
i
).
thisValue
;
for
(
prop
in
thisValue
)
{
if
(
thisValue
[
prop
]
===
this
)
{
return
prop
;
}
}
}
}
return
this
.
displayName
||
"sinon fake"
;
},
getConfig
:
function
(
custom
)
{
var
config
=
{};
custom
=
custom
||
{};
var
defaults
=
sinon
.
defaultConfig
;
for
(
var
prop
in
defaults
)
{
if
(
defaults
.
hasOwnProperty
(
prop
))
{
config
[
prop
]
=
custom
.
hasOwnProperty
(
prop
)
?
custom
[
prop
]
:
defaults
[
prop
];
}
}
return
config
;
},
format
:
function
(
val
)
{
return
""
+
val
;
},
defaultConfig
:
{
injectIntoThis
:
true
,
injectInto
:
null
,
properties
:
[
"spy"
,
"stub"
,
"mock"
,
"clock"
,
"server"
,
"requests"
],
useFakeTimers
:
true
,
useFakeServer
:
true
},
timesInWords
:
function
timesInWords
(
count
)
{
return
count
==
1
&&
"once"
||
count
==
2
&&
"twice"
||
count
==
3
&&
"thrice"
||
(
count
||
0
)
+
" times"
;
},
calledInOrder
:
function
(
spies
)
{
for
(
var
i
=
1
,
l
=
spies
.
length
;
i
<
l
;
i
++
)
{
if
(
!
spies
[
i
-
1
].
calledBefore
(
spies
[
i
])
||
!
spies
[
i
].
called
)
{
return
false
;
}
}
return
true
;
},
orderByFirstCall
:
function
(
spies
)
{
return
spies
.
sort
(
function
(
a
,
b
)
{
// uuid, won't ever be equal
var
aCall
=
a
.
getCall
(
0
);
var
bCall
=
b
.
getCall
(
0
);
var
aId
=
aCall
&&
aCall
.
callId
||
-
1
;
var
bId
=
bCall
&&
bCall
.
callId
||
-
1
;
return
aId
<
bId
?
-
1
:
1
;
});
},
log
:
function
()
{},
logError
:
function
(
label
,
err
)
{
var
msg
=
label
+
" threw exception: "
;
sinon
.
log
(
msg
+
"["
+
err
.
name
+
"] "
+
err
.
message
);
if
(
err
.
stack
)
{
sinon
.
log
(
err
.
stack
);
}
setTimeout
(
function
()
{
err
.
message
=
msg
+
err
.
message
;
throw
err
;
},
0
);
},
typeOf
:
function
(
value
)
{
if
(
value
===
null
)
{
return
"null"
;
}
else
if
(
value
===
undefined
)
{
return
"undefined"
;
}
var
string
=
Object
.
prototype
.
toString
.
call
(
value
);
return
string
.
substring
(
8
,
string
.
length
-
1
).
toLowerCase
();
},
createStubInstance
:
function
(
constructor
)
{
if
(
typeof
constructor
!==
"function"
)
{
throw
new
TypeError
(
"The constructor should be a function."
);
}
return
sinon
.
stub
(
sinon
.
create
(
constructor
.
prototype
));
},
restore
:
function
(
object
)
{
if
(
object
!==
null
&&
typeof
object
===
"object"
)
{
for
(
var
prop
in
object
)
{
if
(
isRestorable
(
object
[
prop
]))
{
object
[
prop
].
restore
();
}
}
}
else
if
(
isRestorable
(
object
))
{
object
.
restore
();
}
}
};
var
isNode
=
typeof
module
!==
"undefined"
&&
module
.
exports
;
var
isAMD
=
typeof
define
===
'function'
&&
typeof
define
.
amd
===
'object'
&&
define
.
amd
;
if
(
isAMD
)
{
define
(
function
(){
return
sinon
;
});
}
else
if
(
isNode
)
{
try
{
formatio
=
require
(
"formatio"
);
}
catch
(
e
)
{}
module
.
exports
=
sinon
;
module
.
exports
.
spy
=
require
(
"./sinon/spy"
);
module
.
exports
.
spyCall
=
require
(
"./sinon/call"
);
module
.
exports
.
behavior
=
require
(
"./sinon/behavior"
);
module
.
exports
.
stub
=
require
(
"./sinon/stub"
);
module
.
exports
.
mock
=
require
(
"./sinon/mock"
);
module
.
exports
.
collection
=
require
(
"./sinon/collection"
);
module
.
exports
.
assert
=
require
(
"./sinon/assert"
);
module
.
exports
.
sandbox
=
require
(
"./sinon/sandbox"
);
module
.
exports
.
test
=
require
(
"./sinon/test"
);
module
.
exports
.
testCase
=
require
(
"./sinon/test_case"
);
module
.
exports
.
assert
=
require
(
"./sinon/assert"
);
module
.
exports
.
match
=
require
(
"./sinon/match"
);
}
if
(
formatio
)
{
var
formatter
=
formatio
.
configure
({
quoteStrings
:
false
});
sinon
.
format
=
function
()
{
return
formatter
.
ascii
.
apply
(
formatter
,
arguments
);
};
}
else
if
(
isNode
)
{
try
{
var
util
=
require
(
"util"
);
sinon
.
format
=
function
(
value
)
{
return
typeof
value
==
"object"
&&
value
.
toString
===
Object
.
prototype
.
toString
?
util
.
inspect
(
value
)
:
value
;
};
}
catch
(
e
)
{
/* Node, but no util module - would be very old, but better safe than
sorry */
}
}
return
sinon
;
}(
typeof
formatio
==
"object"
&&
formatio
));
/*jslint eqeqeq: false, onevar: false*/
/*global sinon, module, require, ActiveXObject, XMLHttpRequest, DOMParser*/
/**
* Minimal Event interface implementation
*
* Original implementation by Sven Fuchs: https://gist.github.com/995028
* Modifications and tests by Christian Johansen.
*
* @author Sven Fuchs (svenfuchs@artweb-design.de)
* @author Christian Johansen (christian@cjohansen.no)
* @license BSD
*
* Copyright (c) 2011 Sven Fuchs, Christian Johansen
*/
if
(
typeof
sinon
==
"undefined"
)
{
this
.
sinon
=
{};
}
(
function
()
{
var
push
=
[].
push
;
sinon
.
Event
=
function
Event
(
type
,
bubbles
,
cancelable
,
target
)
{
this
.
initEvent
(
type
,
bubbles
,
cancelable
,
target
);
};
sinon
.
Event
.
prototype
=
{
initEvent
:
function
(
type
,
bubbles
,
cancelable
,
target
)
{
this
.
type
=
type
;
this
.
bubbles
=
bubbles
;
this
.
cancelable
=
cancelable
;
this
.
target
=
target
;
},
stopPropagation
:
function
()
{},
preventDefault
:
function
()
{
this
.
defaultPrevented
=
true
;
}
};
sinon
.
ProgressEvent
=
function
ProgressEvent
(
type
,
progressEventRaw
,
target
)
{
this
.
initEvent
(
type
,
false
,
false
,
target
);
this
.
loaded
=
progressEventRaw
.
loaded
||
null
;
this
.
total
=
progressEventRaw
.
total
||
null
;
};
sinon
.
ProgressEvent
.
prototype
=
new
sinon
.
Event
();
sinon
.
ProgressEvent
.
prototype
.
constructor
=
sinon
.
ProgressEvent
;
sinon
.
CustomEvent
=
function
CustomEvent
(
type
,
customData
,
target
)
{
this
.
initEvent
(
type
,
false
,
false
,
target
);
this
.
detail
=
customData
.
detail
||
null
;
};
sinon
.
CustomEvent
.
prototype
=
new
sinon
.
Event
();
sinon
.
CustomEvent
.
prototype
.
constructor
=
sinon
.
CustomEvent
;
sinon
.
EventTarget
=
{
addEventListener
:
function
addEventListener
(
event
,
listener
)
{
this
.
eventListeners
=
this
.
eventListeners
||
{};
this
.
eventListeners
[
event
]
=
this
.
eventListeners
[
event
]
||
[];
push
.
call
(
this
.
eventListeners
[
event
],
listener
);
},
removeEventListener
:
function
removeEventListener
(
event
,
listener
)
{
var
listeners
=
this
.
eventListeners
&&
this
.
eventListeners
[
event
]
||
[];
for
(
var
i
=
0
,
l
=
listeners
.
length
;
i
<
l
;
++
i
)
{
if
(
listeners
[
i
]
==
listener
)
{
return
listeners
.
splice
(
i
,
1
);
}
}
},
dispatchEvent
:
function
dispatchEvent
(
event
)
{
var
type
=
event
.
type
;
var
listeners
=
this
.
eventListeners
&&
this
.
eventListeners
[
type
]
||
[];
for
(
var
i
=
0
;
i
<
listeners
.
length
;
i
++
)
{
if
(
typeof
listeners
[
i
]
==
"function"
)
{
listeners
[
i
].
call
(
this
,
event
);
}
else
{
listeners
[
i
].
handleEvent
(
event
);
}
}
return
!!
event
.
defaultPrevented
;
}
};
}());
/**
* @depend ../../sinon.js
* @depend event.js
*/
/*jslint eqeqeq: false, onevar: false*/
/*global sinon, module, require, ActiveXObject, XMLHttpRequest, DOMParser*/
/**
* Fake XMLHttpRequest object
*
* @author Christian Johansen (christian@cjohansen.no)
* @license BSD
*
* Copyright (c) 2010-2013 Christian Johansen
*/
// wrapper for global
(
function
(
global
)
{
if
(
typeof
sinon
===
"undefined"
)
{
global
.
sinon
=
{};
}
var
supportsProgress
=
typeof
ProgressEvent
!==
"undefined"
;
var
supportsCustomEvent
=
typeof
CustomEvent
!==
"undefined"
;
sinon
.
xhr
=
{
XMLHttpRequest
:
global
.
XMLHttpRequest
};
var
xhr
=
sinon
.
xhr
;
xhr
.
GlobalXMLHttpRequest
=
global
.
XMLHttpRequest
;
xhr
.
GlobalActiveXObject
=
global
.
ActiveXObject
;
xhr
.
supportsActiveX
=
typeof
xhr
.
GlobalActiveXObject
!=
"undefined"
;
xhr
.
supportsXHR
=
typeof
xhr
.
GlobalXMLHttpRequest
!=
"undefined"
;
xhr
.
workingXHR
=
xhr
.
supportsXHR
?
xhr
.
GlobalXMLHttpRequest
:
xhr
.
supportsActiveX
?
function
()
{
return
new
xhr
.
GlobalActiveXObject
(
"MSXML2.XMLHTTP.3.0"
)
}
:
false
;
xhr
.
supportsCORS
=
'withCredentials'
in
(
new
sinon
.
xhr
.
GlobalXMLHttpRequest
());
/*jsl:ignore*/
var
unsafeHeaders
=
{
"Accept-Charset"
:
true
,
"Accept-Encoding"
:
true
,
"Connection"
:
true
,
"Content-Length"
:
true
,
"Cookie"
:
true
,
"Cookie2"
:
true
,
"Content-Transfer-Encoding"
:
true
,
"Date"
:
true
,
"Expect"
:
true
,
"Host"
:
true
,
"Keep-Alive"
:
true
,
"Referer"
:
true
,
"TE"
:
true
,
"Trailer"
:
true
,
"Transfer-Encoding"
:
true
,
"Upgrade"
:
true
,
"User-Agent"
:
true
,
"Via"
:
true
};
/*jsl:end*/
function
FakeXMLHttpRequest
()
{
this
.
readyState
=
FakeXMLHttpRequest
.
UNSENT
;
this
.
requestHeaders
=
{};
this
.
requestBody
=
null
;
this
.
status
=
0
;
this
.
statusText
=
""
;
this
.
upload
=
new
UploadProgress
();
if
(
sinon
.
xhr
.
supportsCORS
)
{
this
.
withCredentials
=
false
;
}
var
xhr
=
this
;
var
events
=
[
"loadstart"
,
"load"
,
"abort"
,
"loadend"
];
function
addEventListener
(
eventName
)
{
xhr
.
addEventListener
(
eventName
,
function
(
event
)
{
var
listener
=
xhr
[
"on"
+
eventName
];
if
(
listener
&&
typeof
listener
==
"function"
)
{
listener
.
call
(
this
,
event
);
}
});
}
for
(
var
i
=
events
.
length
-
1
;
i
>=
0
;
i
--
)
{
addEventListener
(
events
[
i
]);
}
if
(
typeof
FakeXMLHttpRequest
.
onCreate
==
"function"
)
{
FakeXMLHttpRequest
.
onCreate
(
this
);
}
}
// An upload object is created for each
// FakeXMLHttpRequest and allows upload
// events to be simulated using uploadProgress
// and uploadError.
function
UploadProgress
()
{
this
.
eventListeners
=
{
"progress"
:
[],
"load"
:
[],
"abort"
:
[],
"error"
:
[]
}
}
UploadProgress
.
prototype
.
addEventListener
=
function
(
event
,
listener
)
{
this
.
eventListeners
[
event
].
push
(
listener
);
};
UploadProgress
.
prototype
.
removeEventListener
=
function
(
event
,
listener
)
{
var
listeners
=
this
.
eventListeners
[
event
]
||
[];
for
(
var
i
=
0
,
l
=
listeners
.
length
;
i
<
l
;
++
i
)
{
if
(
listeners
[
i
]
==
listener
)
{
return
listeners
.
splice
(
i
,
1
);
}
}
};
UploadProgress
.
prototype
.
dispatchEvent
=
function
(
event
)
{
var
listeners
=
this
.
eventListeners
[
event
.
type
]
||
[];
for
(
var
i
=
0
,
listener
;
(
listener
=
listeners
[
i
])
!=
null
;
i
++
)
{
listener
(
event
);
}
};
function
verifyState
(
xhr
)
{
if
(
xhr
.
readyState
!==
FakeXMLHttpRequest
.
OPENED
)
{
throw
new
Error
(
"INVALID_STATE_ERR"
);
}
if
(
xhr
.
sendFlag
)
{
throw
new
Error
(
"INVALID_STATE_ERR"
);
}
}
// filtering to enable a white-list version of Sinon FakeXhr,
// where whitelisted requests are passed through to real XHR
function
each
(
collection
,
callback
)
{
if
(
!
collection
)
return
;
for
(
var
i
=
0
,
l
=
collection
.
length
;
i
<
l
;
i
+=
1
)
{
callback
(
collection
[
i
]);
}
}
function
some
(
collection
,
callback
)
{
for
(
var
index
=
0
;
index
<
collection
.
length
;
index
++
)
{
if
(
callback
(
collection
[
index
])
===
true
)
return
true
;
}
return
false
;
}
// largest arity in XHR is 5 - XHR#open
var
apply
=
function
(
obj
,
method
,
args
)
{
switch
(
args
.
length
)
{
case
0
:
return
obj
[
method
]();
case
1
:
return
obj
[
method
](
args
[
0
]);
case
2
:
return
obj
[
method
](
args
[
0
],
args
[
1
]);
case
3
:
return
obj
[
method
](
args
[
0
],
args
[
1
],
args
[
2
]);
case
4
:
return
obj
[
method
](
args
[
0
],
args
[
1
],
args
[
2
],
args
[
3
]);
case
5
:
return
obj
[
method
](
args
[
0
],
args
[
1
],
args
[
2
],
args
[
3
],
args
[
4
]);
}
};
FakeXMLHttpRequest
.
filters
=
[];
FakeXMLHttpRequest
.
addFilter
=
function
(
fn
)
{
this
.
filters
.
push
(
fn
)
};
var
IE6Re
=
/MSIE 6/
;
FakeXMLHttpRequest
.
defake
=
function
(
fakeXhr
,
xhrArgs
)
{
var
xhr
=
new
sinon
.
xhr
.
workingXHR
();
each
([
"open"
,
"setRequestHeader"
,
"send"
,
"abort"
,
"getResponseHeader"
,
"getAllResponseHeaders"
,
"addEventListener"
,
"overrideMimeType"
,
"removeEventListener"
],
function
(
method
)
{
fakeXhr
[
method
]
=
function
()
{
return
apply
(
xhr
,
method
,
arguments
);
};
});
var
copyAttrs
=
function
(
args
)
{
each
(
args
,
function
(
attr
)
{
try
{
fakeXhr
[
attr
]
=
xhr
[
attr
]
}
catch
(
e
)
{
if
(
!
IE6Re
.
test
(
navigator
.
userAgent
))
throw
e
;
}
});
};
var
stateChange
=
function
()
{
fakeXhr
.
readyState
=
xhr
.
readyState
;
if
(
xhr
.
readyState
>=
FakeXMLHttpRequest
.
HEADERS_RECEIVED
)
{
copyAttrs
([
"status"
,
"statusText"
]);
}
if
(
xhr
.
readyState
>=
FakeXMLHttpRequest
.
LOADING
)
{
copyAttrs
([
"responseText"
]);
}
if
(
xhr
.
readyState
===
FakeXMLHttpRequest
.
DONE
)
{
copyAttrs
([
"responseXML"
]);
}
if
(
fakeXhr
.
onreadystatechange
)
fakeXhr
.
onreadystatechange
.
call
(
fakeXhr
,
{
target
:
fakeXhr
});
};
if
(
xhr
.
addEventListener
)
{
for
(
var
event
in
fakeXhr
.
eventListeners
)
{
if
(
fakeXhr
.
eventListeners
.
hasOwnProperty
(
event
))
{
each
(
fakeXhr
.
eventListeners
[
event
],
function
(
handler
)
{
xhr
.
addEventListener
(
event
,
handler
);
});
}
}
xhr
.
addEventListener
(
"readystatechange"
,
stateChange
);
}
else
{
xhr
.
onreadystatechange
=
stateChange
;
}
apply
(
xhr
,
"open"
,
xhrArgs
);
};
FakeXMLHttpRequest
.
useFilters
=
false
;
function
verifyRequestOpened
(
xhr
)
{
if
(
xhr
.
readyState
!=
FakeXMLHttpRequest
.
OPENED
)
{
throw
new
Error
(
"INVALID_STATE_ERR - "
+
xhr
.
readyState
);
}
}
function
verifyRequestSent
(
xhr
)
{
if
(
xhr
.
readyState
==
FakeXMLHttpRequest
.
DONE
)
{
throw
new
Error
(
"Request done"
);
}
}
function
verifyHeadersReceived
(
xhr
)
{
if
(
xhr
.
async
&&
xhr
.
readyState
!=
FakeXMLHttpRequest
.
HEADERS_RECEIVED
)
{
throw
new
Error
(
"No headers received"
);
}
}
function
verifyResponseBodyType
(
body
)
{
if
(
typeof
body
!=
"string"
)
{
var
error
=
new
Error
(
"Attempted to respond to fake XMLHttpRequest with "
+
body
+
", which is not a string."
);
error
.
name
=
"InvalidBodyException"
;
throw
error
;
}
}
sinon
.
extend
(
FakeXMLHttpRequest
.
prototype
,
sinon
.
EventTarget
,
{
async
:
true
,
open
:
function
open
(
method
,
url
,
async
,
username
,
password
)
{
this
.
method
=
method
;
this
.
url
=
url
;
this
.
async
=
typeof
async
==
"boolean"
?
async
:
true
;
this
.
username
=
username
;
this
.
password
=
password
;
this
.
responseText
=
null
;
this
.
responseXML
=
null
;
this
.
requestHeaders
=
{};
this
.
sendFlag
=
false
;
if
(
sinon
.
FakeXMLHttpRequest
.
useFilters
===
true
)
{
var
xhrArgs
=
arguments
;
var
defake
=
some
(
FakeXMLHttpRequest
.
filters
,
function
(
filter
)
{
return
filter
.
apply
(
this
,
xhrArgs
)
});
if
(
defake
)
{
return
sinon
.
FakeXMLHttpRequest
.
defake
(
this
,
arguments
);
}
}
this
.
readyStateChange
(
FakeXMLHttpRequest
.
OPENED
);
},
readyStateChange
:
function
readyStateChange
(
state
)
{
this
.
readyState
=
state
;
if
(
typeof
this
.
onreadystatechange
==
"function"
)
{
try
{
this
.
onreadystatechange
();
}
catch
(
e
)
{
sinon
.
logError
(
"Fake XHR onreadystatechange handler"
,
e
);
}
}
this
.
dispatchEvent
(
new
sinon
.
Event
(
"readystatechange"
));
switch
(
this
.
readyState
)
{
case
FakeXMLHttpRequest
.
DONE
:
this
.
dispatchEvent
(
new
sinon
.
Event
(
"load"
,
false
,
false
,
this
));
this
.
dispatchEvent
(
new
sinon
.
Event
(
"loadend"
,
false
,
false
,
this
));
this
.
upload
.
dispatchEvent
(
new
sinon
.
Event
(
"load"
,
false
,
false
,
this
));
if
(
supportsProgress
)
{
this
.
upload
.
dispatchEvent
(
new
sinon
.
ProgressEvent
(
'progress'
,
{
loaded
:
100
,
total
:
100
}));
}
break
;
}
},
setRequestHeader
:
function
setRequestHeader
(
header
,
value
)
{
verifyState
(
this
);
if
(
unsafeHeaders
[
header
]
||
/^
(
Sec-|Proxy-
)
/
.
test
(
header
))
{
throw
new
Error
(
"Refused to set unsafe header \""
+
header
+
"\""
);
}
if
(
this
.
requestHeaders
[
header
])
{
this
.
requestHeaders
[
header
]
+=
","
+
value
;
}
else
{
this
.
requestHeaders
[
header
]
=
value
;
}
},
// Helps testing
setResponseHeaders
:
function
setResponseHeaders
(
headers
)
{
verifyRequestOpened
(
this
);
this
.
responseHeaders
=
{};
for
(
var
header
in
headers
)
{
if
(
headers
.
hasOwnProperty
(
header
))
{
this
.
responseHeaders
[
header
]
=
headers
[
header
];
}
}
if
(
this
.
async
)
{
this
.
readyStateChange
(
FakeXMLHttpRequest
.
HEADERS_RECEIVED
);
}
else
{
this
.
readyState
=
FakeXMLHttpRequest
.
HEADERS_RECEIVED
;
}
},
// Currently treats ALL data as a DOMString (i.e. no Document)
send
:
function
send
(
data
)
{
verifyState
(
this
);
if
(
!
/^
(
get|head
)
$/i
.
test
(
this
.
method
))
{
if
(
this
.
requestHeaders
[
"Content-Type"
])
{
var
value
=
this
.
requestHeaders
[
"Content-Type"
].
split
(
";"
);
this
.
requestHeaders
[
"Content-Type"
]
=
value
[
0
]
+
";charset=utf-8"
;
}
else
{
this
.
requestHeaders
[
"Content-Type"
]
=
"text/plain;charset=utf-8"
;
}
this
.
requestBody
=
data
;
}
this
.
errorFlag
=
false
;
this
.
sendFlag
=
this
.
async
;
this
.
readyStateChange
(
FakeXMLHttpRequest
.
OPENED
);
if
(
typeof
this
.
onSend
==
"function"
)
{
this
.
onSend
(
this
);
}
this
.
dispatchEvent
(
new
sinon
.
Event
(
"loadstart"
,
false
,
false
,
this
));
},
abort
:
function
abort
()
{
this
.
aborted
=
true
;
this
.
responseText
=
null
;
this
.
errorFlag
=
true
;
this
.
requestHeaders
=
{};
if
(
this
.
readyState
>
sinon
.
FakeXMLHttpRequest
.
UNSENT
&&
this
.
sendFlag
)
{
this
.
readyStateChange
(
sinon
.
FakeXMLHttpRequest
.
DONE
);
this
.
sendFlag
=
false
;
}
this
.
readyState
=
sinon
.
FakeXMLHttpRequest
.
UNSENT
;
this
.
dispatchEvent
(
new
sinon
.
Event
(
"abort"
,
false
,
false
,
this
));
this
.
upload
.
dispatchEvent
(
new
sinon
.
Event
(
"abort"
,
false
,
false
,
this
));
if
(
typeof
this
.
onerror
===
"function"
)
{
this
.
onerror
();
}
},
getResponseHeader
:
function
getResponseHeader
(
header
)
{
if
(
this
.
readyState
<
FakeXMLHttpRequest
.
HEADERS_RECEIVED
)
{
return
null
;
}
if
(
/^Set-Cookie2
?
$/i
.
test
(
header
))
{
return
null
;
}
header
=
header
.
toLowerCase
();
for
(
var
h
in
this
.
responseHeaders
)
{
if
(
h
.
toLowerCase
()
==
header
)
{
return
this
.
responseHeaders
[
h
];
}
}
return
null
;
},
getAllResponseHeaders
:
function
getAllResponseHeaders
()
{
if
(
this
.
readyState
<
FakeXMLHttpRequest
.
HEADERS_RECEIVED
)
{
return
""
;
}
var
headers
=
""
;
for
(
var
header
in
this
.
responseHeaders
)
{
if
(
this
.
responseHeaders
.
hasOwnProperty
(
header
)
&&
!
/^Set-Cookie2
?
$/i
.
test
(
header
))
{
headers
+=
header
+
": "
+
this
.
responseHeaders
[
header
]
+
"\r\n"
;
}
}
return
headers
;
},
setResponseBody
:
function
setResponseBody
(
body
)
{
verifyRequestSent
(
this
);
verifyHeadersReceived
(
this
);
verifyResponseBodyType
(
body
);
var
chunkSize
=
this
.
chunkSize
||
10
;
var
index
=
0
;
this
.
responseText
=
""
;
do
{
if
(
this
.
async
)
{
this
.
readyStateChange
(
FakeXMLHttpRequest
.
LOADING
);
}
this
.
responseText
+=
body
.
substring
(
index
,
index
+
chunkSize
);
index
+=
chunkSize
;
}
while
(
index
<
body
.
length
);
var
type
=
this
.
getResponseHeader
(
"Content-Type"
);
if
(
this
.
responseText
&&
(
!
type
||
/
(
text
\/
xml
)
|
(
application
\/
xml
)
|
(\+
xml
)
/
.
test
(
type
)))
{
try
{
this
.
responseXML
=
FakeXMLHttpRequest
.
parseXML
(
this
.
responseText
);
}
catch
(
e
)
{
// Unable to parse XML - no biggie
}
}
if
(
this
.
async
)
{
this
.
readyStateChange
(
FakeXMLHttpRequest
.
DONE
);
}
else
{
this
.
readyState
=
FakeXMLHttpRequest
.
DONE
;
}
},
respond
:
function
respond
(
status
,
headers
,
body
)
{
this
.
status
=
typeof
status
==
"number"
?
status
:
200
;
this
.
statusText
=
FakeXMLHttpRequest
.
statusCodes
[
this
.
status
];
this
.
setResponseHeaders
(
headers
||
{});
this
.
setResponseBody
(
body
||
""
);
},
uploadProgress
:
function
uploadProgress
(
progressEventRaw
)
{
if
(
supportsProgress
)
{
this
.
upload
.
dispatchEvent
(
new
sinon
.
ProgressEvent
(
"progress"
,
progressEventRaw
));
}
},
uploadError
:
function
uploadError
(
error
)
{
if
(
supportsCustomEvent
)
{
this
.
upload
.
dispatchEvent
(
new
sinon
.
CustomEvent
(
"error"
,
{
"detail"
:
error
}));
}
}
});
sinon
.
extend
(
FakeXMLHttpRequest
,
{
UNSENT
:
0
,
OPENED
:
1
,
HEADERS_RECEIVED
:
2
,
LOADING
:
3
,
DONE
:
4
});
// Borrowed from JSpec
FakeXMLHttpRequest
.
parseXML
=
function
parseXML
(
text
)
{
var
xmlDoc
;
if
(
typeof
DOMParser
!=
"undefined"
)
{
var
parser
=
new
DOMParser
();
xmlDoc
=
parser
.
parseFromString
(
text
,
"text/xml"
);
}
else
{
xmlDoc
=
new
ActiveXObject
(
"Microsoft.XMLDOM"
);
xmlDoc
.
async
=
"false"
;
xmlDoc
.
loadXML
(
text
);
}
return
xmlDoc
;
};
FakeXMLHttpRequest
.
statusCodes
=
{
100
:
"Continue"
,
101
:
"Switching Protocols"
,
200
:
"OK"
,
201
:
"Created"
,
202
:
"Accepted"
,
203
:
"Non-Authoritative Information"
,
204
:
"No Content"
,
205
:
"Reset Content"
,
206
:
"Partial Content"
,
300
:
"Multiple Choice"
,
301
:
"Moved Permanently"
,
302
:
"Found"
,
303
:
"See Other"
,
304
:
"Not Modified"
,
305
:
"Use Proxy"
,
307
:
"Temporary Redirect"
,
400
:
"Bad Request"
,
401
:
"Unauthorized"
,
402
:
"Payment Required"
,
403
:
"Forbidden"
,
404
:
"Not Found"
,
405
:
"Method Not Allowed"
,
406
:
"Not Acceptable"
,
407
:
"Proxy Authentication Required"
,
408
:
"Request Timeout"
,
409
:
"Conflict"
,
410
:
"Gone"
,
411
:
"Length Required"
,
412
:
"Precondition Failed"
,
413
:
"Request Entity Too Large"
,
414
:
"Request-URI Too Long"
,
415
:
"Unsupported Media Type"
,
416
:
"Requested Range Not Satisfiable"
,
417
:
"Expectation Failed"
,
422
:
"Unprocessable Entity"
,
500
:
"Internal Server Error"
,
501
:
"Not Implemented"
,
502
:
"Bad Gateway"
,
503
:
"Service Unavailable"
,
504
:
"Gateway Timeout"
,
505
:
"HTTP Version Not Supported"
};
sinon
.
useFakeXMLHttpRequest
=
function
()
{
sinon
.
FakeXMLHttpRequest
.
restore
=
function
restore
(
keepOnCreate
)
{
if
(
xhr
.
supportsXHR
)
{
global
.
XMLHttpRequest
=
xhr
.
GlobalXMLHttpRequest
;
}
if
(
xhr
.
supportsActiveX
)
{
global
.
ActiveXObject
=
xhr
.
GlobalActiveXObject
;
}
delete
sinon
.
FakeXMLHttpRequest
.
restore
;
if
(
keepOnCreate
!==
true
)
{
delete
sinon
.
FakeXMLHttpRequest
.
onCreate
;
}
};
if
(
xhr
.
supportsXHR
)
{
global
.
XMLHttpRequest
=
sinon
.
FakeXMLHttpRequest
;
}
if
(
xhr
.
supportsActiveX
)
{
global
.
ActiveXObject
=
function
ActiveXObject
(
objId
)
{
if
(
objId
==
"Microsoft.XMLHTTP"
||
/^Msxml2
\.
XMLHTTP/i
.
test
(
objId
))
{
return
new
sinon
.
FakeXMLHttpRequest
();
}
return
new
xhr
.
GlobalActiveXObject
(
objId
);
};
}
return
sinon
.
FakeXMLHttpRequest
;
};
sinon
.
FakeXMLHttpRequest
=
FakeXMLHttpRequest
;
})(
typeof
global
===
"object"
?
global
:
this
);
if
(
typeof
module
!==
'undefined'
&&
module
.
exports
)
{
module
.
exports
=
sinon
;
}
/**
* @depend fake_xml_http_request.js
*/
/*jslint eqeqeq: false, onevar: false, regexp: false, plusplus: false*/
/*global module, require, window*/
/**
* The Sinon "server" mimics a web server that receives requests from
* sinon.FakeXMLHttpRequest and provides an API to respond to those requests,
* both synchronously and asynchronously. To respond synchronuously, canned
* answers have to be provided upfront.
*
* @author Christian Johansen (christian@cjohansen.no)
* @license BSD
*
* Copyright (c) 2010-2013 Christian Johansen
*/
if
(
typeof
sinon
==
"undefined"
)
{
var
sinon
=
{};
}
sinon
.
fakeServer
=
(
function
()
{
var
push
=
[].
push
;
function
F
()
{}
function
create
(
proto
)
{
F
.
prototype
=
proto
;
return
new
F
();
}
function
responseArray
(
handler
)
{
var
response
=
handler
;
if
(
Object
.
prototype
.
toString
.
call
(
handler
)
!=
"[object Array]"
)
{
response
=
[
200
,
{},
handler
];
}
if
(
typeof
response
[
2
]
!=
"string"
)
{
throw
new
TypeError
(
"Fake server response body should be string, but was "
+
typeof
response
[
2
]);
}
return
response
;
}
var
wloc
=
typeof
window
!==
"undefined"
?
window
.
location
:
{};
var
rCurrLoc
=
new
RegExp
(
"^"
+
wloc
.
protocol
+
"//"
+
wloc
.
host
);
function
matchOne
(
response
,
reqMethod
,
reqUrl
)
{
var
rmeth
=
response
.
method
;
var
matchMethod
=
!
rmeth
||
rmeth
.
toLowerCase
()
==
reqMethod
.
toLowerCase
();
var
url
=
response
.
url
;
var
matchUrl
=
!
url
||
url
==
reqUrl
||
(
typeof
url
.
test
==
"function"
&&
url
.
test
(
reqUrl
));
return
matchMethod
&&
matchUrl
;
}
function
match
(
response
,
request
)
{
var
requestUrl
=
request
.
url
;
if
(
!
/^https
?
:
\/\/
/
.
test
(
requestUrl
)
||
rCurrLoc
.
test
(
requestUrl
))
{
requestUrl
=
requestUrl
.
replace
(
rCurrLoc
,
""
);
}
if
(
matchOne
(
response
,
this
.
getHTTPMethod
(
request
),
requestUrl
))
{
if
(
typeof
response
.
response
==
"function"
)
{
var
ru
=
response
.
url
;
var
args
=
[
request
].
concat
(
ru
&&
typeof
ru
.
exec
==
"function"
?
ru
.
exec
(
requestUrl
).
slice
(
1
)
:
[]);
return
response
.
response
.
apply
(
response
,
args
);
}
return
true
;
}
return
false
;
}
function
log
(
response
,
request
)
{
var
str
;
str
=
"Request:\n"
+
sinon
.
format
(
request
)
+
"\n\n"
;
str
+=
"Response:\n"
+
sinon
.
format
(
response
)
+
"\n\n"
;
sinon
.
log
(
str
);
}
return
{
create
:
function
()
{
var
server
=
create
(
this
);
this
.
xhr
=
sinon
.
useFakeXMLHttpRequest
();
server
.
requests
=
[];
this
.
xhr
.
onCreate
=
function
(
xhrObj
)
{
server
.
addRequest
(
xhrObj
);
};
return
server
;
},
addRequest
:
function
addRequest
(
xhrObj
)
{
var
server
=
this
;
push
.
call
(
this
.
requests
,
xhrObj
);
xhrObj
.
onSend
=
function
()
{
server
.
handleRequest
(
this
);
if
(
server
.
autoRespond
&&
!
server
.
responding
)
{
setTimeout
(
function
()
{
server
.
responding
=
false
;
server
.
respond
();
},
server
.
autoRespondAfter
||
10
);
server
.
responding
=
true
;
}
};
},
getHTTPMethod
:
function
getHTTPMethod
(
request
)
{
if
(
this
.
fakeHTTPMethods
&&
/post/i
.
test
(
request
.
method
))
{
var
matches
=
(
request
.
requestBody
||
""
).
match
(
/_method=
([^\b
;
]
+
)
/
);
return
!!
matches
?
matches
[
1
]
:
request
.
method
;
}
return
request
.
method
;
},
handleRequest
:
function
handleRequest
(
xhr
)
{
if
(
xhr
.
async
)
{
if
(
!
this
.
queue
)
{
this
.
queue
=
[];
}
push
.
call
(
this
.
queue
,
xhr
);
}
else
{
this
.
processRequest
(
xhr
);
}
},
respondWith
:
function
respondWith
(
method
,
url
,
body
)
{
if
(
arguments
.
length
==
1
&&
typeof
method
!=
"function"
)
{
this
.
response
=
responseArray
(
method
);
return
;
}
if
(
!
this
.
responses
)
{
this
.
responses
=
[];
}
if
(
arguments
.
length
==
1
)
{
body
=
method
;
url
=
method
=
null
;
}
if
(
arguments
.
length
==
2
)
{
body
=
url
;
url
=
method
;
method
=
null
;
}
push
.
call
(
this
.
responses
,
{
method
:
method
,
url
:
url
,
response
:
typeof
body
==
"function"
?
body
:
responseArray
(
body
)
});
},
respond
:
function
respond
()
{
if
(
arguments
.
length
>
0
)
this
.
respondWith
.
apply
(
this
,
arguments
);
var
queue
=
this
.
queue
||
[];
var
requests
=
queue
.
splice
(
0
);
var
request
;
while
(
request
=
requests
.
shift
())
{
this
.
processRequest
(
request
);
}
},
processRequest
:
function
processRequest
(
request
)
{
try
{
if
(
request
.
aborted
)
{
return
;
}
var
response
=
this
.
response
||
[
404
,
{},
""
];
if
(
this
.
responses
)
{
for
(
var
l
=
this
.
responses
.
length
,
i
=
l
-
1
;
i
>=
0
;
i
--
)
{
if
(
match
.
call
(
this
,
this
.
responses
[
i
],
request
))
{
response
=
this
.
responses
[
i
].
response
;
break
;
}
}
}
if
(
request
.
readyState
!=
4
)
{
log
(
response
,
request
);
request
.
respond
(
response
[
0
],
response
[
1
],
response
[
2
]);
}
}
catch
(
e
)
{
sinon
.
logError
(
"Fake server request processing"
,
e
);
}
},
restore
:
function
restore
()
{
return
this
.
xhr
.
restore
&&
this
.
xhr
.
restore
.
apply
(
this
.
xhr
,
arguments
);
}
};
}());
if
(
typeof
module
!==
'undefined'
&&
module
.
exports
)
{
module
.
exports
=
sinon
;
}
/*jslint eqeqeq: false, plusplus: false, evil: true, onevar: false, browser: true, forin: false*/
/*global module, require, window*/
/**
* Fake timer API
* setTimeout
* setInterval
* clearTimeout
* clearInterval
* tick
* reset
* Date
*
* Inspired by jsUnitMockTimeOut from JsUnit
*
* @author Christian Johansen (christian@cjohansen.no)
* @license BSD
*
* Copyright (c) 2010-2013 Christian Johansen
*/
if
(
typeof
sinon
==
"undefined"
)
{
var
sinon
=
{};
}
(
function
(
global
)
{
var
id
=
1
;
function
addTimer
(
args
,
recurring
)
{
if
(
args
.
length
===
0
)
{
throw
new
Error
(
"Function requires at least 1 parameter"
);
}
if
(
typeof
args
[
0
]
===
"undefined"
)
{
throw
new
Error
(
"Callback must be provided to timer calls"
);
}
var
toId
=
id
++
;
var
delay
=
args
[
1
]
||
0
;
if
(
!
this
.
timeouts
)
{
this
.
timeouts
=
{};
}
this
.
timeouts
[
toId
]
=
{
id
:
toId
,
func
:
args
[
0
],
callAt
:
this
.
now
+
delay
,
invokeArgs
:
Array
.
prototype
.
slice
.
call
(
args
,
2
)
};
if
(
recurring
===
true
)
{
this
.
timeouts
[
toId
].
interval
=
delay
;
}
return
toId
;
}
function
parseTime
(
str
)
{
if
(
!
str
)
{
return
0
;
}
var
strings
=
str
.
split
(
":"
);
var
l
=
strings
.
length
,
i
=
l
;
var
ms
=
0
,
parsed
;
if
(
l
>
3
||
!
/^
(\d\d
:
){0,2}\d\d?
$/
.
test
(
str
))
{
throw
new
Error
(
"tick only understands numbers and 'h:m:s'"
);
}
while
(
i
--
)
{
parsed
=
parseInt
(
strings
[
i
],
10
);
if
(
parsed
>=
60
)
{
throw
new
Error
(
"Invalid time "
+
str
);
}
ms
+=
parsed
*
Math
.
pow
(
60
,
(
l
-
i
-
1
));
}
return
ms
*
1000
;
}
function
createObject
(
object
)
{
var
newObject
;
if
(
Object
.
create
)
{
newObject
=
Object
.
create
(
object
);
}
else
{
var
F
=
function
()
{};
F
.
prototype
=
object
;
newObject
=
new
F
();
}
newObject
.
Date
.
clock
=
newObject
;
return
newObject
;
}
sinon
.
clock
=
{
now
:
0
,
create
:
function
create
(
now
)
{
var
clock
=
createObject
(
this
);
if
(
typeof
now
==
"number"
)
{
clock
.
now
=
now
;
}
if
(
!!
now
&&
typeof
now
==
"object"
)
{
throw
new
TypeError
(
"now should be milliseconds since UNIX epoch"
);
}
return
clock
;
},
setTimeout
:
function
setTimeout
(
callback
,
timeout
)
{
return
addTimer
.
call
(
this
,
arguments
,
false
);
},
clearTimeout
:
function
clearTimeout
(
timerId
)
{
if
(
!
this
.
timeouts
)
{
this
.
timeouts
=
[];
}
if
(
timerId
in
this
.
timeouts
)
{
delete
this
.
timeouts
[
timerId
];
}
},
setInterval
:
function
setInterval
(
callback
,
timeout
)
{
return
addTimer
.
call
(
this
,
arguments
,
true
);
},
clearInterval
:
function
clearInterval
(
timerId
)
{
this
.
clearTimeout
(
timerId
);
},
setImmediate
:
function
setImmediate
(
callback
)
{
var
passThruArgs
=
Array
.
prototype
.
slice
.
call
(
arguments
,
1
);
return
addTimer
.
call
(
this
,
[
callback
,
0
].
concat
(
passThruArgs
),
false
);
},
clearImmediate
:
function
clearImmediate
(
timerId
)
{
this
.
clearTimeout
(
timerId
);
},
tick
:
function
tick
(
ms
)
{
ms
=
typeof
ms
==
"number"
?
ms
:
parseTime
(
ms
);
var
tickFrom
=
this
.
now
,
tickTo
=
this
.
now
+
ms
,
previous
=
this
.
now
;
var
timer
=
this
.
firstTimerInRange
(
tickFrom
,
tickTo
);
var
firstException
;
while
(
timer
&&
tickFrom
<=
tickTo
)
{
if
(
this
.
timeouts
[
timer
.
id
])
{
tickFrom
=
this
.
now
=
timer
.
callAt
;
try
{
this
.
callTimer
(
timer
);
}
catch
(
e
)
{
firstException
=
firstException
||
e
;
}
}
timer
=
this
.
firstTimerInRange
(
previous
,
tickTo
);
previous
=
tickFrom
;
}
this
.
now
=
tickTo
;
if
(
firstException
)
{
throw
firstException
;
}
return
this
.
now
;
},
firstTimerInRange
:
function
(
from
,
to
)
{
var
timer
,
smallest
=
null
,
originalTimer
;
for
(
var
id
in
this
.
timeouts
)
{
if
(
this
.
timeouts
.
hasOwnProperty
(
id
))
{
if
(
this
.
timeouts
[
id
].
callAt
<
from
||
this
.
timeouts
[
id
].
callAt
>
to
)
{
continue
;
}
if
(
smallest
===
null
||
this
.
timeouts
[
id
].
callAt
<
smallest
)
{
originalTimer
=
this
.
timeouts
[
id
];
smallest
=
this
.
timeouts
[
id
].
callAt
;
timer
=
{
func
:
this
.
timeouts
[
id
].
func
,
callAt
:
this
.
timeouts
[
id
].
callAt
,
interval
:
this
.
timeouts
[
id
].
interval
,
id
:
this
.
timeouts
[
id
].
id
,
invokeArgs
:
this
.
timeouts
[
id
].
invokeArgs
};
}
}
}
return
timer
||
null
;
},
callTimer
:
function
(
timer
)
{
if
(
typeof
timer
.
interval
==
"number"
)
{
this
.
timeouts
[
timer
.
id
].
callAt
+=
timer
.
interval
;
}
else
{
delete
this
.
timeouts
[
timer
.
id
];
}
try
{
if
(
typeof
timer
.
func
==
"function"
)
{
timer
.
func
.
apply
(
null
,
timer
.
invokeArgs
);
}
else
{
eval
(
timer
.
func
);
}
}
catch
(
e
)
{
var
exception
=
e
;
}
if
(
!
this
.
timeouts
[
timer
.
id
])
{
if
(
exception
)
{
throw
exception
;
}
return
;
}
if
(
exception
)
{
throw
exception
;
}
},
reset
:
function
reset
()
{
this
.
timeouts
=
{};
},
Date
:
(
function
()
{
var
NativeDate
=
Date
;
function
ClockDate
(
year
,
month
,
date
,
hour
,
minute
,
second
,
ms
)
{
// Defensive and verbose to avoid potential harm in passing
// explicit undefined when user does not pass argument
switch
(
arguments
.
length
)
{
case
0
:
return
new
NativeDate
(
ClockDate
.
clock
.
now
);
case
1
:
return
new
NativeDate
(
year
);
case
2
:
return
new
NativeDate
(
year
,
month
);
case
3
:
return
new
NativeDate
(
year
,
month
,
date
);
case
4
:
return
new
NativeDate
(
year
,
month
,
date
,
hour
);
case
5
:
return
new
NativeDate
(
year
,
month
,
date
,
hour
,
minute
);
case
6
:
return
new
NativeDate
(
year
,
month
,
date
,
hour
,
minute
,
second
);
default
:
return
new
NativeDate
(
year
,
month
,
date
,
hour
,
minute
,
second
,
ms
);
}
}
return
mirrorDateProperties
(
ClockDate
,
NativeDate
);
}())
};
function
mirrorDateProperties
(
target
,
source
)
{
if
(
source
.
now
)
{
target
.
now
=
function
now
()
{
return
target
.
clock
.
now
;
};
}
else
{
delete
target
.
now
;
}
if
(
source
.
toSource
)
{
target
.
toSource
=
function
toSource
()
{
return
source
.
toSource
();
};
}
else
{
delete
target
.
toSource
;
}
target
.
toString
=
function
toString
()
{
return
source
.
toString
();
};
target
.
prototype
=
source
.
prototype
;
target
.
parse
=
source
.
parse
;
target
.
UTC
=
source
.
UTC
;
target
.
prototype
.
toUTCString
=
source
.
prototype
.
toUTCString
;
for
(
var
prop
in
source
)
{
if
(
source
.
hasOwnProperty
(
prop
))
{
target
[
prop
]
=
source
[
prop
];
}
}
return
target
;
}
var
methods
=
[
"Date"
,
"setTimeout"
,
"setInterval"
,
"clearTimeout"
,
"clearInterval"
];
if
(
typeof
global
.
setImmediate
!==
"undefined"
)
{
methods
.
push
(
"setImmediate"
);
}
if
(
typeof
global
.
clearImmediate
!==
"undefined"
)
{
methods
.
push
(
"clearImmediate"
);
}
function
restore
()
{
var
method
;
for
(
var
i
=
0
,
l
=
this
.
methods
.
length
;
i
<
l
;
i
++
)
{
method
=
this
.
methods
[
i
];
if
(
global
[
method
].
hadOwnProperty
)
{
global
[
method
]
=
this
[
"_"
+
method
];
}
else
{
try
{
delete
global
[
method
];
}
catch
(
e
)
{}
}
}
// Prevent multiple executions which will completely remove these props
this
.
methods
=
[];
}
function
stubGlobal
(
method
,
clock
)
{
clock
[
method
].
hadOwnProperty
=
Object
.
prototype
.
hasOwnProperty
.
call
(
global
,
method
);
clock
[
"_"
+
method
]
=
global
[
method
];
if
(
method
==
"Date"
)
{
var
date
=
mirrorDateProperties
(
clock
[
method
],
global
[
method
]);
global
[
method
]
=
date
;
}
else
{
global
[
method
]
=
function
()
{
return
clock
[
method
].
apply
(
clock
,
arguments
);
};
for
(
var
prop
in
clock
[
method
])
{
if
(
clock
[
method
].
hasOwnProperty
(
prop
))
{
global
[
method
][
prop
]
=
clock
[
method
][
prop
];
}
}
}
global
[
method
].
clock
=
clock
;
}
sinon
.
useFakeTimers
=
function
useFakeTimers
(
now
)
{
var
clock
=
sinon
.
clock
.
create
(
now
);
clock
.
restore
=
restore
;
clock
.
methods
=
Array
.
prototype
.
slice
.
call
(
arguments
,
typeof
now
==
"number"
?
1
:
0
);
if
(
clock
.
methods
.
length
===
0
)
{
clock
.
methods
=
methods
;
}
for
(
var
i
=
0
,
l
=
clock
.
methods
.
length
;
i
<
l
;
i
++
)
{
stubGlobal
(
clock
.
methods
[
i
],
clock
);
}
return
clock
;
};
}(
typeof
global
!=
"undefined"
&&
typeof
global
!==
"function"
?
global
:
this
));
sinon
.
timers
=
{
setTimeout
:
setTimeout
,
clearTimeout
:
clearTimeout
,
setImmediate
:
(
typeof
setImmediate
!==
"undefined"
?
setImmediate
:
undefined
),
clearImmediate
:
(
typeof
clearImmediate
!==
"undefined"
?
clearImmediate
:
undefined
),
setInterval
:
setInterval
,
clearInterval
:
clearInterval
,
Date
:
Date
};
if
(
typeof
module
!==
'undefined'
&&
module
.
exports
)
{
module
.
exports
=
sinon
;
}
/**
* @depend fake_server.js
* @depend fake_timers.js
*/
/*jslint browser: true, eqeqeq: false, onevar: false*/
/*global sinon*/
/**
* Add-on for sinon.fakeServer that automatically handles a fake timer along with
* the FakeXMLHttpRequest. The direct inspiration for this add-on is jQuery
* 1.3.x, which does not use xhr object's onreadystatehandler at all - instead,
* it polls the object for completion with setInterval. Dispite the direct
* motivation, there is nothing jQuery-specific in this file, so it can be used
* in any environment where the ajax implementation depends on setInterval or
* setTimeout.
*
* @author Christian Johansen (christian@cjohansen.no)
* @license BSD
*
* Copyright (c) 2010-2013 Christian Johansen
*/
(
function
()
{
function
Server
()
{}
Server
.
prototype
=
sinon
.
fakeServer
;
sinon
.
fakeServerWithClock
=
new
Server
();
sinon
.
fakeServerWithClock
.
addRequest
=
function
addRequest
(
xhr
)
{
if
(
xhr
.
async
)
{
if
(
typeof
setTimeout
.
clock
==
"object"
)
{
this
.
clock
=
setTimeout
.
clock
;
}
else
{
this
.
clock
=
sinon
.
useFakeTimers
();
this
.
resetClock
=
true
;
}
if
(
!
this
.
longestTimeout
)
{
var
clockSetTimeout
=
this
.
clock
.
setTimeout
;
var
clockSetInterval
=
this
.
clock
.
setInterval
;
var
server
=
this
;
this
.
clock
.
setTimeout
=
function
(
fn
,
timeout
)
{
server
.
longestTimeout
=
Math
.
max
(
timeout
,
server
.
longestTimeout
||
0
);
return
clockSetTimeout
.
apply
(
this
,
arguments
);
};
this
.
clock
.
setInterval
=
function
(
fn
,
timeout
)
{
server
.
longestTimeout
=
Math
.
max
(
timeout
,
server
.
longestTimeout
||
0
);
return
clockSetInterval
.
apply
(
this
,
arguments
);
};
}
}
return
sinon
.
fakeServer
.
addRequest
.
call
(
this
,
xhr
);
};
sinon
.
fakeServerWithClock
.
respond
=
function
respond
()
{
var
returnVal
=
sinon
.
fakeServer
.
respond
.
apply
(
this
,
arguments
);
if
(
this
.
clock
)
{
this
.
clock
.
tick
(
this
.
longestTimeout
||
0
);
this
.
longestTimeout
=
0
;
if
(
this
.
resetClock
)
{
this
.
clock
.
restore
();
this
.
resetClock
=
false
;
}
}
return
returnVal
;
};
sinon
.
fakeServerWithClock
.
restore
=
function
restore
()
{
if
(
this
.
clock
)
{
this
.
clock
.
restore
();
}
return
sinon
.
fakeServer
.
restore
.
apply
(
this
,
arguments
);
};
}());
package.json
View file @
599fb47
...
...
@@ -19,6 +19,7 @@
},
"dependencies"
:
{
"video.js"
:
"git+https://github.com/dmlap/video-js.git#v4.3.0-10"
,
"videojs-contrib-media-sources"
:
"git+https://github.com/dmlap/videojs-contrib-media-sources.git#hotfix/misc-fixes"
"videojs-contrib-media-sources"
:
"git+https://github.com/dmlap/videojs-contrib-media-sources.git#hotfix/misc-fixes"
,
"sinon"
:
"~1.9.0"
}
}
...
...
test/videojs-hls.html
View file @
599fb47
...
...
@@ -4,7 +4,10 @@
<meta
charset=
"utf-8"
>
<title>
video.js HLS Plugin Test Suite
</title>
<!-- Load sinon server for fakeXHR -->
<script
src=
"../libs/sinon/sinon-server-1.9.0.js"
></script>
<script
src=
"../node_modules/sinon/lib/sinon.js"
></script>
<script
src=
"../node_modules/sinon/lib/sinon/util/event.js"
></script>
<script
src=
"../node_modules/sinon/lib/sinon/util/xhr_ie.js"
></script>
<script
src=
"../node_modules/sinon/lib/sinon/util/fake_xml_http_request.js"
></script>
<!-- Load local QUnit. -->
<link
rel=
"stylesheet"
href=
"../libs/qunit/qunit.css"
media=
"screen"
>
...
...
Please
register
or
sign in
to post a comment