2014-06-05 19:55:49 -04:00
/ *
2016-01-19 17:57:58 -05:00
Copyright ( c ) 2008 - 2015 Pivotal Labs
Permission is hereby granted , free of charge , to any person obtaining
a copy of this software and associated documentation files ( the
"Software" ) , to deal in the Software without restriction , including
without limitation the rights to use , copy , modify , merge , publish ,
distribute , sublicense , and / or sell copies of the Software , and to
permit persons to whom the Software is furnished to do so , subject to
the following conditions :
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software .
THE SOFTWARE IS PROVIDED "AS IS" , WITHOUT WARRANTY OF ANY KIND ,
EXPRESS OR IMPLIED , INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY , FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT . IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM , DAMAGES OR OTHER LIABILITY , WHETHER IN AN ACTION
OF CONTRACT , TORT OR OTHERWISE , ARISING FROM , OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE .
* /
var getJasmineRequireObj = ( function ( jasmineGlobal ) {
var jasmineRequire ;
if ( typeof module !== 'undefined' && module . exports ) {
if ( typeof global !== 'undefined' ) {
jasmineGlobal = global ;
} else {
jasmineGlobal = { } ;
}
jasmineRequire = exports ;
2014-06-05 19:55:49 -04:00
} else {
2016-01-19 17:57:58 -05:00
if ( typeof window !== 'undefined' && typeof window . toString === 'function' && window . toString ( ) === '[object GjsGlobal]' ) {
jasmineGlobal = window ;
}
jasmineRequire = jasmineGlobal . jasmineRequire = jasmineGlobal . jasmineRequire || { } ;
2014-06-05 19:55:49 -04:00
}
2016-01-19 17:57:58 -05:00
function getJasmineRequire ( ) {
return jasmineRequire ;
}
getJasmineRequire ( ) . core = function ( jRequire ) {
var j$ = { } ;
jRequire . base ( j$ , jasmineGlobal ) ;
j$ . util = jRequire . util ( ) ;
j$ . errors = jRequire . errors ( ) ;
j$ . Any = jRequire . Any ( j$ ) ;
j$ . Anything = jRequire . Anything ( j$ ) ;
j$ . CallTracker = jRequire . CallTracker ( ) ;
j$ . MockDate = jRequire . MockDate ( ) ;
j$ . Clock = jRequire . Clock ( ) ;
j$ . DelayedFunctionScheduler = jRequire . DelayedFunctionScheduler ( ) ;
j$ . Env = jRequire . Env ( j$ ) ;
j$ . ExceptionFormatter = jRequire . ExceptionFormatter ( ) ;
j$ . Expectation = jRequire . Expectation ( ) ;
j$ . buildExpectationResult = jRequire . buildExpectationResult ( ) ;
j$ . JsApiReporter = jRequire . JsApiReporter ( ) ;
j$ . matchersUtil = jRequire . matchersUtil ( j$ ) ;
j$ . ObjectContaining = jRequire . ObjectContaining ( j$ ) ;
j$ . ArrayContaining = jRequire . ArrayContaining ( j$ ) ;
j$ . pp = jRequire . pp ( j$ ) ;
j$ . QueueRunner = jRequire . QueueRunner ( j$ ) ;
j$ . ReportDispatcher = jRequire . ReportDispatcher ( ) ;
j$ . Spec = jRequire . Spec ( j$ ) ;
j$ . SpyRegistry = jRequire . SpyRegistry ( j$ ) ;
j$ . SpyStrategy = jRequire . SpyStrategy ( ) ;
j$ . StringMatching = jRequire . StringMatching ( j$ ) ;
j$ . Suite = jRequire . Suite ( j$ ) ;
j$ . Timer = jRequire . Timer ( ) ;
j$ . TreeProcessor = jRequire . TreeProcessor ( ) ;
j$ . version = jRequire . version ( ) ;
j$ . Order = jRequire . Order ( ) ;
j$ . matchers = jRequire . requireMatchers ( jRequire , j$ ) ;
return j$ ;
} ;
return getJasmineRequire ;
} ) ( this ) ;
2014-06-05 19:55:49 -04:00
getJasmineRequireObj ( ) . requireMatchers = function ( jRequire , j$ ) {
var availableMatchers = [
2016-01-19 17:57:58 -05:00
'toBe' ,
'toBeCloseTo' ,
'toBeDefined' ,
'toBeFalsy' ,
'toBeGreaterThan' ,
'toBeLessThan' ,
'toBeNaN' ,
'toBeNull' ,
'toBeTruthy' ,
'toBeUndefined' ,
'toContain' ,
'toEqual' ,
'toHaveBeenCalled' ,
'toHaveBeenCalledWith' ,
'toHaveBeenCalledTimes' ,
'toMatch' ,
'toThrow' ,
'toThrowError'
2014-06-05 19:55:49 -04:00
] ,
matchers = { } ;
for ( var i = 0 ; i < availableMatchers . length ; i ++ ) {
var name = availableMatchers [ i ] ;
matchers [ name ] = jRequire [ name ] ( j$ ) ;
}
return matchers ;
} ;
2016-01-19 17:57:58 -05:00
getJasmineRequireObj ( ) . base = function ( j$ , jasmineGlobal ) {
2014-06-05 19:55:49 -04:00
j$ . unimplementedMethod _ = function ( ) {
2016-01-19 17:57:58 -05:00
throw new Error ( 'unimplemented method' ) ;
2014-06-05 19:55:49 -04:00
} ;
j$ . MAX _PRETTY _PRINT _DEPTH = 40 ;
2016-01-19 17:57:58 -05:00
j$ . MAX _PRETTY _PRINT _ARRAY _LENGTH = 100 ;
2014-06-05 19:55:49 -04:00
j$ . DEFAULT _TIMEOUT _INTERVAL = 5000 ;
2016-01-19 17:57:58 -05:00
j$ . getGlobal = function ( ) {
return jasmineGlobal ;
} ;
2014-06-05 19:55:49 -04:00
j$ . getEnv = function ( options ) {
var env = j$ . currentEnv _ = j$ . currentEnv _ || new j$ . Env ( options ) ;
//jasmine. singletons in here (setTimeout blah blah).
return env ;
} ;
j$ . isArray _ = function ( value ) {
2016-01-19 17:57:58 -05:00
return j$ . isA _ ( 'Array' , value ) ;
2014-06-05 19:55:49 -04:00
} ;
j$ . isString _ = function ( value ) {
2016-01-19 17:57:58 -05:00
return j$ . isA _ ( 'String' , value ) ;
2014-06-05 19:55:49 -04:00
} ;
j$ . isNumber _ = function ( value ) {
2016-01-19 17:57:58 -05:00
return j$ . isA _ ( 'Number' , value ) ;
2014-06-05 19:55:49 -04:00
} ;
j$ . isA _ = function ( typeName , value ) {
return Object . prototype . toString . apply ( value ) === '[object ' + typeName + ']' ;
} ;
j$ . isDomNode = function ( obj ) {
return obj . nodeType > 0 ;
} ;
2016-01-19 17:57:58 -05:00
j$ . fnNameFor = function ( func ) {
return func . name || func . toString ( ) . match ( /^\s*function\s*(\w*)\s*\(/ ) [ 1 ] ;
} ;
2014-06-05 19:55:49 -04:00
j$ . any = function ( clazz ) {
return new j$ . Any ( clazz ) ;
} ;
2016-01-19 17:57:58 -05:00
j$ . anything = function ( ) {
return new j$ . Anything ( ) ;
} ;
2014-06-05 19:55:49 -04:00
j$ . objectContaining = function ( sample ) {
return new j$ . ObjectContaining ( sample ) ;
} ;
2016-01-19 17:57:58 -05:00
j$ . stringMatching = function ( expected ) {
return new j$ . StringMatching ( expected ) ;
} ;
j$ . arrayContaining = function ( sample ) {
return new j$ . ArrayContaining ( sample ) ;
} ;
2014-06-05 19:55:49 -04:00
j$ . createSpy = function ( name , originalFn ) {
var spyStrategy = new j$ . SpyStrategy ( {
name : name ,
fn : originalFn ,
getSpy : function ( ) { return spy ; }
} ) ,
callTracker = new j$ . CallTracker ( ) ,
spy = function ( ) {
2016-01-19 17:57:58 -05:00
var callData = {
2014-06-05 19:55:49 -04:00
object : this ,
args : Array . prototype . slice . apply ( arguments )
2016-01-19 17:57:58 -05:00
} ;
callTracker . track ( callData ) ;
var returnValue = spyStrategy . exec . apply ( this , arguments ) ;
callData . returnValue = returnValue ;
return returnValue ;
2014-06-05 19:55:49 -04:00
} ;
for ( var prop in originalFn ) {
if ( prop === 'and' || prop === 'calls' ) {
2016-01-19 17:57:58 -05:00
throw new Error ( 'Jasmine spies would overwrite the \'and\' and \'calls\' properties on the object being spied upon' ) ;
2014-06-05 19:55:49 -04:00
}
spy [ prop ] = originalFn [ prop ] ;
}
spy . and = spyStrategy ;
spy . calls = callTracker ;
return spy ;
} ;
j$ . isSpy = function ( putativeSpy ) {
if ( ! putativeSpy ) {
return false ;
}
return putativeSpy . and instanceof j$ . SpyStrategy &&
putativeSpy . calls instanceof j$ . CallTracker ;
} ;
j$ . createSpyObj = function ( baseName , methodNames ) {
2016-01-19 17:57:58 -05:00
if ( j$ . isArray _ ( baseName ) && j$ . util . isUndefined ( methodNames ) ) {
methodNames = baseName ;
baseName = 'unknown' ;
}
2014-06-05 19:55:49 -04:00
if ( ! j$ . isArray _ ( methodNames ) || methodNames . length === 0 ) {
2016-01-19 17:57:58 -05:00
throw 'createSpyObj requires a non-empty array of method names to create spies for' ;
2014-06-05 19:55:49 -04:00
}
var obj = { } ;
for ( var i = 0 ; i < methodNames . length ; i ++ ) {
obj [ methodNames [ i ] ] = j$ . createSpy ( baseName + '.' + methodNames [ i ] ) ;
}
return obj ;
} ;
} ;
getJasmineRequireObj ( ) . util = function ( ) {
var util = { } ;
util . inherit = function ( childClass , parentClass ) {
var Subclass = function ( ) {
} ;
Subclass . prototype = parentClass . prototype ;
childClass . prototype = new Subclass ( ) ;
} ;
util . htmlEscape = function ( str ) {
if ( ! str ) {
return str ;
}
return str . replace ( /&/g , '&' )
. replace ( /</g , '<' )
. replace ( />/g , '>' ) ;
} ;
util . argsToArray = function ( args ) {
var arrayOfArgs = [ ] ;
for ( var i = 0 ; i < args . length ; i ++ ) {
arrayOfArgs . push ( args [ i ] ) ;
}
return arrayOfArgs ;
} ;
util . isUndefined = function ( obj ) {
return obj === void 0 ;
} ;
2016-01-19 17:57:58 -05:00
util . arrayContains = function ( array , search ) {
var i = array . length ;
while ( i -- ) {
if ( array [ i ] === search ) {
return true ;
}
}
return false ;
} ;
util . clone = function ( obj ) {
if ( Object . prototype . toString . apply ( obj ) === '[object Array]' ) {
return obj . slice ( ) ;
}
var cloned = { } ;
for ( var prop in obj ) {
if ( obj . hasOwnProperty ( prop ) ) {
cloned [ prop ] = obj [ prop ] ;
}
}
return cloned ;
} ;
2014-06-05 19:55:49 -04:00
return util ;
} ;
getJasmineRequireObj ( ) . Spec = function ( j$ ) {
function Spec ( attrs ) {
this . expectationFactory = attrs . expectationFactory ;
this . resultCallback = attrs . resultCallback || function ( ) { } ;
this . id = attrs . id ;
this . description = attrs . description || '' ;
2016-01-19 17:57:58 -05:00
this . queueableFn = attrs . queueableFn ;
this . beforeAndAfterFns = attrs . beforeAndAfterFns || function ( ) { return { befores : [ ] , afters : [ ] } ; } ;
this . userContext = attrs . userContext || function ( ) { return { } ; } ;
2014-06-05 19:55:49 -04:00
this . onStart = attrs . onStart || function ( ) { } ;
this . getSpecName = attrs . getSpecName || function ( ) { return '' ; } ;
this . expectationResultFactory = attrs . expectationResultFactory || function ( ) { } ;
this . queueRunnerFactory = attrs . queueRunnerFactory || function ( ) { } ;
this . catchingExceptions = attrs . catchingExceptions || function ( ) { return true ; } ;
2016-01-19 17:57:58 -05:00
this . throwOnExpectationFailure = ! ! attrs . throwOnExpectationFailure ;
2014-06-05 19:55:49 -04:00
2016-01-19 17:57:58 -05:00
if ( ! this . queueableFn . fn ) {
2014-06-05 19:55:49 -04:00
this . pend ( ) ;
}
this . result = {
id : this . id ,
description : this . description ,
fullName : this . getFullName ( ) ,
2016-01-19 17:57:58 -05:00
failedExpectations : [ ] ,
passedExpectations : [ ] ,
pendingReason : ''
2014-06-05 19:55:49 -04:00
} ;
}
2016-01-19 17:57:58 -05:00
Spec . prototype . addExpectationResult = function ( passed , data , isError ) {
var expectationResult = this . expectationResultFactory ( data ) ;
2014-06-05 19:55:49 -04:00
if ( passed ) {
2016-01-19 17:57:58 -05:00
this . result . passedExpectations . push ( expectationResult ) ;
} else {
this . result . failedExpectations . push ( expectationResult ) ;
if ( this . throwOnExpectationFailure && ! isError ) {
throw new j$ . errors . ExpectationFailed ( ) ;
}
2014-06-05 19:55:49 -04:00
}
} ;
Spec . prototype . expect = function ( actual ) {
return this . expectationFactory ( actual , this ) ;
} ;
2016-01-19 17:57:58 -05:00
Spec . prototype . execute = function ( onComplete , enabled ) {
var self = this ;
2014-06-05 19:55:49 -04:00
this . onStart ( this ) ;
2016-01-19 17:57:58 -05:00
if ( ! this . isExecutable ( ) || this . markedPending || enabled === false ) {
complete ( enabled ) ;
2014-06-05 19:55:49 -04:00
return ;
}
2016-01-19 17:57:58 -05:00
var fns = this . beforeAndAfterFns ( ) ;
var allFns = fns . befores . concat ( this . queueableFn ) . concat ( fns . afters ) ;
2014-06-05 19:55:49 -04:00
this . queueRunnerFactory ( {
2016-01-19 17:57:58 -05:00
queueableFns : allFns ,
onException : function ( ) { self . onException . apply ( self , arguments ) ; } ,
onComplete : complete ,
userContext : this . userContext ( )
2014-06-05 19:55:49 -04:00
} ) ;
2016-01-19 17:57:58 -05:00
function complete ( enabledAgain ) {
self . result . status = self . status ( enabledAgain ) ;
2014-06-05 19:55:49 -04:00
self . resultCallback ( self . result ) ;
if ( onComplete ) {
onComplete ( ) ;
}
}
} ;
2016-01-19 17:57:58 -05:00
Spec . prototype . onException = function onException ( e ) {
if ( Spec . isPendingSpecException ( e ) ) {
this . pend ( extractCustomPendingMessage ( e ) ) ;
return ;
}
if ( e instanceof j$ . errors . ExpectationFailed ) {
return ;
}
this . addExpectationResult ( false , {
matcherName : '' ,
passed : false ,
expected : '' ,
actual : '' ,
error : e
} , true ) ;
} ;
2014-06-05 19:55:49 -04:00
Spec . prototype . disable = function ( ) {
this . disabled = true ;
} ;
2016-01-19 17:57:58 -05:00
Spec . prototype . pend = function ( message ) {
2014-06-05 19:55:49 -04:00
this . markedPending = true ;
2016-01-19 17:57:58 -05:00
if ( message ) {
this . result . pendingReason = message ;
}
2014-06-05 19:55:49 -04:00
} ;
2016-01-19 17:57:58 -05:00
Spec . prototype . getResult = function ( ) {
this . result . status = this . status ( ) ;
return this . result ;
} ;
Spec . prototype . status = function ( enabled ) {
if ( this . disabled || enabled === false ) {
2014-06-05 19:55:49 -04:00
return 'disabled' ;
}
if ( this . markedPending ) {
return 'pending' ;
}
if ( this . result . failedExpectations . length > 0 ) {
return 'failed' ;
} else {
return 'passed' ;
}
} ;
2016-01-19 17:57:58 -05:00
Spec . prototype . isExecutable = function ( ) {
return ! this . disabled ;
} ;
2014-06-05 19:55:49 -04:00
Spec . prototype . getFullName = function ( ) {
return this . getSpecName ( this ) ;
} ;
2016-01-19 17:57:58 -05:00
var extractCustomPendingMessage = function ( e ) {
var fullMessage = e . toString ( ) ,
boilerplateStart = fullMessage . indexOf ( Spec . pendingSpecExceptionMessage ) ,
boilerplateEnd = boilerplateStart + Spec . pendingSpecExceptionMessage . length ;
return fullMessage . substr ( boilerplateEnd ) ;
} ;
Spec . pendingSpecExceptionMessage = '=> marked Pending' ;
2014-06-05 19:55:49 -04:00
Spec . isPendingSpecException = function ( e ) {
2016-01-19 17:57:58 -05:00
return ! ! ( e && e . toString && e . toString ( ) . indexOf ( Spec . pendingSpecExceptionMessage ) !== - 1 ) ;
2014-06-05 19:55:49 -04:00
} ;
return Spec ;
} ;
2016-01-19 17:57:58 -05:00
if ( typeof window == void 0 && typeof exports == 'object' ) {
2014-06-05 19:55:49 -04:00
exports . Spec = jasmineRequire . Spec ;
}
2016-01-19 17:57:58 -05:00
/*jshint bitwise: false*/
getJasmineRequireObj ( ) . Order = function ( ) {
function Order ( options ) {
this . random = 'random' in options ? options . random : true ;
var seed = this . seed = options . seed || generateSeed ( ) ;
this . sort = this . random ? randomOrder : naturalOrder ;
function naturalOrder ( items ) {
return items ;
}
function randomOrder ( items ) {
var copy = items . slice ( ) ;
copy . sort ( function ( a , b ) {
return jenkinsHash ( seed + a . id ) - jenkinsHash ( seed + b . id ) ;
} ) ;
return copy ;
}
function generateSeed ( ) {
return String ( Math . random ( ) ) . slice ( - 5 ) ;
}
// Bob Jenkins One-at-a-Time Hash algorithm is a non-cryptographic hash function
// used to get a different output when the key changes slighly.
// We use your return to sort the children randomly in a consistent way when
// used in conjunction with a seed
function jenkinsHash ( key ) {
var hash , i ;
for ( hash = i = 0 ; i < key . length ; ++ i ) {
hash += key . charCodeAt ( i ) ;
hash += ( hash << 10 ) ;
hash ^= ( hash >> 6 ) ;
}
hash += ( hash << 3 ) ;
hash ^= ( hash >> 11 ) ;
hash += ( hash << 15 ) ;
return hash ;
}
}
return Order ;
} ;
2014-06-05 19:55:49 -04:00
getJasmineRequireObj ( ) . Env = function ( j$ ) {
function Env ( options ) {
options = options || { } ;
var self = this ;
var global = options . global || j$ . getGlobal ( ) ;
var totalSpecsDefined = 0 ;
var catchExceptions = true ;
var realSetTimeout = j$ . getGlobal ( ) . setTimeout ;
var realClearTimeout = j$ . getGlobal ( ) . clearTimeout ;
2016-01-19 17:57:58 -05:00
this . clock = new j$ . Clock ( global , function ( ) { return new j$ . DelayedFunctionScheduler ( ) ; } , new j$ . MockDate ( global ) ) ;
2014-06-05 19:55:49 -04:00
var runnableLookupTable = { } ;
2016-01-19 17:57:58 -05:00
var runnableResources = { } ;
2014-06-05 19:55:49 -04:00
var currentSpec = null ;
2016-01-19 17:57:58 -05:00
var currentlyExecutingSuites = [ ] ;
var currentDeclarationSuite = null ;
var throwOnExpectationFailure = false ;
var random = false ;
var seed = null ;
var currentSuite = function ( ) {
return currentlyExecutingSuites [ currentlyExecutingSuites . length - 1 ] ;
} ;
var currentRunnable = function ( ) {
return currentSpec || currentSuite ( ) ;
} ;
2014-06-05 19:55:49 -04:00
var reporter = new j$ . ReportDispatcher ( [
2016-01-19 17:57:58 -05:00
'jasmineStarted' ,
'jasmineDone' ,
'suiteStarted' ,
'suiteDone' ,
'specStarted' ,
'specDone'
2014-06-05 19:55:49 -04:00
] ) ;
this . specFilter = function ( ) {
return true ;
} ;
this . addCustomEqualityTester = function ( tester ) {
2016-01-19 17:57:58 -05:00
if ( ! currentRunnable ( ) ) {
throw new Error ( 'Custom Equalities must be added in a before function or a spec' ) ;
}
runnableResources [ currentRunnable ( ) . id ] . customEqualityTesters . push ( tester ) ;
} ;
this . addMatchers = function ( matchersToAdd ) {
if ( ! currentRunnable ( ) ) {
throw new Error ( 'Matchers must be added in a before function or a spec' ) ;
}
var customMatchers = runnableResources [ currentRunnable ( ) . id ] . customMatchers ;
for ( var matcherName in matchersToAdd ) {
customMatchers [ matcherName ] = matchersToAdd [ matcherName ] ;
}
2014-06-05 19:55:49 -04:00
} ;
j$ . Expectation . addCoreMatchers ( j$ . matchers ) ;
var nextSpecId = 0 ;
var getNextSpecId = function ( ) {
return 'spec' + nextSpecId ++ ;
} ;
var nextSuiteId = 0 ;
var getNextSuiteId = function ( ) {
return 'suite' + nextSuiteId ++ ;
} ;
var expectationFactory = function ( actual , spec ) {
return j$ . Expectation . Factory ( {
util : j$ . matchersUtil ,
2016-01-19 17:57:58 -05:00
customEqualityTesters : runnableResources [ spec . id ] . customEqualityTesters ,
customMatchers : runnableResources [ spec . id ] . customMatchers ,
2014-06-05 19:55:49 -04:00
actual : actual ,
addExpectationResult : addExpectationResult
} ) ;
function addExpectationResult ( passed , result ) {
return spec . addExpectationResult ( passed , result ) ;
}
} ;
2016-01-19 17:57:58 -05:00
var defaultResourcesForRunnable = function ( id , parentRunnableId ) {
var resources = { spies : [ ] , customEqualityTesters : [ ] , customMatchers : { } } ;
if ( runnableResources [ parentRunnableId ] ) {
resources . customEqualityTesters = j$ . util . clone ( runnableResources [ parentRunnableId ] . customEqualityTesters ) ;
resources . customMatchers = j$ . util . clone ( runnableResources [ parentRunnableId ] . customMatchers ) ;
}
runnableResources [ id ] = resources ;
2014-06-05 19:55:49 -04:00
} ;
2016-01-19 17:57:58 -05:00
var clearResourcesForRunnable = function ( id ) {
spyRegistry . clearSpies ( ) ;
delete runnableResources [ id ] ;
2014-06-05 19:55:49 -04:00
} ;
2016-01-19 17:57:58 -05:00
var beforeAndAfterFns = function ( suite ) {
2014-06-05 19:55:49 -04:00
return function ( ) {
2016-01-19 17:57:58 -05:00
var befores = [ ] ,
afters = [ ] ;
2014-06-05 19:55:49 -04:00
while ( suite ) {
2016-01-19 17:57:58 -05:00
befores = befores . concat ( suite . beforeFns ) ;
2014-06-05 19:55:49 -04:00
afters = afters . concat ( suite . afterFns ) ;
2016-01-19 17:57:58 -05:00
2014-06-05 19:55:49 -04:00
suite = suite . parentSuite ;
}
2016-01-19 17:57:58 -05:00
return {
befores : befores . reverse ( ) ,
afters : afters
} ;
2014-06-05 19:55:49 -04:00
} ;
} ;
var getSpecName = function ( spec , suite ) {
return suite . getFullName ( ) + ' ' + spec . description ;
} ;
// TODO: we may just be able to pass in the fn instead of wrapping here
var buildExpectationResult = j$ . buildExpectationResult ,
2016-01-19 17:57:58 -05:00
exceptionFormatter = new j$ . ExceptionFormatter ( ) ,
expectationResultFactory = function ( attrs ) {
attrs . messageFormatter = exceptionFormatter . message ;
attrs . stackFormatter = exceptionFormatter . stack ;
2014-06-05 19:55:49 -04:00
2016-01-19 17:57:58 -05:00
return buildExpectationResult ( attrs ) ;
} ;
2014-06-05 19:55:49 -04:00
// TODO: fix this naming, and here's where the value comes in
this . catchExceptions = function ( value ) {
catchExceptions = ! ! value ;
return catchExceptions ;
} ;
this . catchingExceptions = function ( ) {
return catchExceptions ;
} ;
var maximumSpecCallbackDepth = 20 ;
var currentSpecCallbackDepth = 0 ;
function clearStack ( fn ) {
currentSpecCallbackDepth ++ ;
if ( currentSpecCallbackDepth >= maximumSpecCallbackDepth ) {
currentSpecCallbackDepth = 0 ;
realSetTimeout ( fn , 0 ) ;
} else {
fn ( ) ;
}
}
var catchException = function ( e ) {
return j$ . Spec . isPendingSpecException ( e ) || catchExceptions ;
} ;
2016-01-19 17:57:58 -05:00
this . throwOnExpectationFailure = function ( value ) {
throwOnExpectationFailure = ! ! value ;
} ;
this . throwingExpectationFailures = function ( ) {
return throwOnExpectationFailure ;
} ;
this . randomizeTests = function ( value ) {
random = ! ! value ;
} ;
this . randomTests = function ( ) {
return random ;
} ;
this . seed = function ( value ) {
if ( value ) {
seed = value ;
}
return seed ;
} ;
2014-06-05 19:55:49 -04:00
var queueRunnerFactory = function ( options ) {
options . catchException = catchException ;
options . clearStack = options . clearStack || clearStack ;
2016-01-19 17:57:58 -05:00
options . timeout = { setTimeout : realSetTimeout , clearTimeout : realClearTimeout } ;
options . fail = self . fail ;
2014-06-05 19:55:49 -04:00
new j$ . QueueRunner ( options ) . execute ( ) ;
} ;
var topSuite = new j$ . Suite ( {
env : this ,
id : getNextSuiteId ( ) ,
description : 'Jasmine__TopLevel__Suite' ,
2016-01-19 17:57:58 -05:00
queueRunner : queueRunnerFactory
2014-06-05 19:55:49 -04:00
} ) ;
runnableLookupTable [ topSuite . id ] = topSuite ;
2016-01-19 17:57:58 -05:00
defaultResourcesForRunnable ( topSuite . id ) ;
currentDeclarationSuite = topSuite ;
2014-06-05 19:55:49 -04:00
this . topSuite = function ( ) {
return topSuite ;
} ;
this . execute = function ( runnablesToRun ) {
2016-01-19 17:57:58 -05:00
if ( ! runnablesToRun ) {
if ( focusedRunnables . length ) {
runnablesToRun = focusedRunnables ;
} else {
runnablesToRun = [ topSuite . id ] ;
}
}
var order = new j$ . Order ( {
random : random ,
seed : seed
} ) ;
var processor = new j$ . TreeProcessor ( {
tree : topSuite ,
runnableIds : runnablesToRun ,
queueRunnerFactory : queueRunnerFactory ,
nodeStart : function ( suite ) {
currentlyExecutingSuites . push ( suite ) ;
defaultResourcesForRunnable ( suite . id , suite . parentSuite . id ) ;
reporter . suiteStarted ( suite . result ) ;
} ,
nodeComplete : function ( suite , result ) {
if ( ! suite . disabled ) {
clearResourcesForRunnable ( suite . id ) ;
}
currentlyExecutingSuites . pop ( ) ;
reporter . suiteDone ( result ) ;
} ,
orderChildren : function ( node ) {
return order . sort ( node . children ) ;
}
} ) ;
2014-06-05 19:55:49 -04:00
2016-01-19 17:57:58 -05:00
if ( ! processor . processTree ( ) . valid ) {
throw new Error ( 'Invalid order: would cause a beforeAll or afterAll to be run multiple times' ) ;
2014-06-05 19:55:49 -04:00
}
reporter . jasmineStarted ( {
totalSpecsDefined : totalSpecsDefined
} ) ;
2016-01-19 17:57:58 -05:00
processor . execute ( function ( ) {
reporter . jasmineDone ( {
order : order
} ) ;
} ) ;
2014-06-05 19:55:49 -04:00
} ;
this . addReporter = function ( reporterToAdd ) {
reporter . addReporter ( reporterToAdd ) ;
} ;
2016-01-19 17:57:58 -05:00
var spyRegistry = new j$ . SpyRegistry ( { currentSpies : function ( ) {
if ( ! currentRunnable ( ) ) {
throw new Error ( 'Spies must be created in a before function or a spec' ) ;
2014-06-05 19:55:49 -04:00
}
2016-01-19 17:57:58 -05:00
return runnableResources [ currentRunnable ( ) . id ] . spies ;
} } ) ;
2014-06-05 19:55:49 -04:00
2016-01-19 17:57:58 -05:00
this . spyOn = function ( ) {
return spyRegistry . spyOn . apply ( spyRegistry , arguments ) ;
2014-06-05 19:55:49 -04:00
} ;
var suiteFactory = function ( description ) {
var suite = new j$ . Suite ( {
env : self ,
id : getNextSuiteId ( ) ,
description : description ,
2016-01-19 17:57:58 -05:00
parentSuite : currentDeclarationSuite ,
expectationFactory : expectationFactory ,
expectationResultFactory : expectationResultFactory ,
throwOnExpectationFailure : throwOnExpectationFailure
2014-06-05 19:55:49 -04:00
} ) ;
runnableLookupTable [ suite . id ] = suite ;
return suite ;
} ;
this . describe = function ( description , specDefinitions ) {
var suite = suiteFactory ( description ) ;
2016-01-19 17:57:58 -05:00
if ( specDefinitions . length > 0 ) {
throw new Error ( 'describe does not expect a done parameter' ) ;
}
if ( currentDeclarationSuite . markedPending ) {
suite . pend ( ) ;
}
addSpecsToSuite ( suite , specDefinitions ) ;
return suite ;
} ;
this . xdescribe = function ( description , specDefinitions ) {
var suite = suiteFactory ( description ) ;
suite . pend ( ) ;
addSpecsToSuite ( suite , specDefinitions ) ;
return suite ;
} ;
var focusedRunnables = [ ] ;
this . fdescribe = function ( description , specDefinitions ) {
var suite = suiteFactory ( description ) ;
suite . isFocused = true ;
focusedRunnables . push ( suite . id ) ;
unfocusAncestor ( ) ;
addSpecsToSuite ( suite , specDefinitions ) ;
2014-06-05 19:55:49 -04:00
2016-01-19 17:57:58 -05:00
return suite ;
} ;
function addSpecsToSuite ( suite , specDefinitions ) {
var parentSuite = currentDeclarationSuite ;
2014-06-05 19:55:49 -04:00
parentSuite . addChild ( suite ) ;
2016-01-19 17:57:58 -05:00
currentDeclarationSuite = suite ;
2014-06-05 19:55:49 -04:00
var declarationError = null ;
try {
specDefinitions . call ( suite ) ;
} catch ( e ) {
declarationError = e ;
}
if ( declarationError ) {
2016-01-19 17:57:58 -05:00
self . it ( 'encountered a declaration exception' , function ( ) {
2014-06-05 19:55:49 -04:00
throw declarationError ;
} ) ;
}
2016-01-19 17:57:58 -05:00
currentDeclarationSuite = parentSuite ;
}
2014-06-05 19:55:49 -04:00
2016-01-19 17:57:58 -05:00
function findFocusedAncestor ( suite ) {
while ( suite ) {
if ( suite . isFocused ) {
return suite . id ;
}
suite = suite . parentSuite ;
}
2014-06-05 19:55:49 -04:00
2016-01-19 17:57:58 -05:00
return null ;
}
2014-06-05 19:55:49 -04:00
2016-01-19 17:57:58 -05:00
function unfocusAncestor ( ) {
var focusedAncestor = findFocusedAncestor ( currentDeclarationSuite ) ;
if ( focusedAncestor ) {
for ( var i = 0 ; i < focusedRunnables . length ; i ++ ) {
if ( focusedRunnables [ i ] === focusedAncestor ) {
focusedRunnables . splice ( i , 1 ) ;
break ;
}
}
}
}
2014-06-05 19:55:49 -04:00
2016-01-19 17:57:58 -05:00
var specFactory = function ( description , fn , suite , timeout ) {
totalSpecsDefined ++ ;
2014-06-05 19:55:49 -04:00
var spec = new j$ . Spec ( {
id : getNextSpecId ( ) ,
2016-01-19 17:57:58 -05:00
beforeAndAfterFns : beforeAndAfterFns ( suite ) ,
2014-06-05 19:55:49 -04:00
expectationFactory : expectationFactory ,
resultCallback : specResultCallback ,
getSpecName : function ( spec ) {
return getSpecName ( spec , suite ) ;
} ,
onStart : specStarted ,
description : description ,
expectationResultFactory : expectationResultFactory ,
queueRunnerFactory : queueRunnerFactory ,
2016-01-19 17:57:58 -05:00
userContext : function ( ) { return suite . clonedSharedUserContext ( ) ; } ,
queueableFn : {
fn : fn ,
timeout : function ( ) { return timeout || j$ . DEFAULT _TIMEOUT _INTERVAL ; }
} ,
throwOnExpectationFailure : throwOnExpectationFailure
2014-06-05 19:55:49 -04:00
} ) ;
runnableLookupTable [ spec . id ] = spec ;
if ( ! self . specFilter ( spec ) ) {
spec . disable ( ) ;
}
return spec ;
function specResultCallback ( result ) {
2016-01-19 17:57:58 -05:00
clearResourcesForRunnable ( spec . id ) ;
2014-06-05 19:55:49 -04:00
currentSpec = null ;
reporter . specDone ( result ) ;
}
2016-01-19 17:57:58 -05:00
function specStarted ( spec ) {
currentSpec = spec ;
defaultResourcesForRunnable ( spec . id , suite . id ) ;
reporter . specStarted ( spec . result ) ;
}
2014-06-05 19:55:49 -04:00
} ;
2016-01-19 17:57:58 -05:00
this . it = function ( description , fn , timeout ) {
var spec = specFactory ( description , fn , currentDeclarationSuite , timeout ) ;
if ( currentDeclarationSuite . markedPending ) {
spec . pend ( ) ;
}
currentDeclarationSuite . addChild ( spec ) ;
return spec ;
2014-06-05 19:55:49 -04:00
} ;
2016-01-19 17:57:58 -05:00
this . xit = function ( ) {
var spec = this . it . apply ( this , arguments ) ;
spec . pend ( 'Temporarily disabled with xit' ) ;
2014-06-05 19:55:49 -04:00
return spec ;
} ;
2016-01-19 17:57:58 -05:00
this . fit = function ( description , fn , timeout ) {
var spec = specFactory ( description , fn , currentDeclarationSuite , timeout ) ;
currentDeclarationSuite . addChild ( spec ) ;
focusedRunnables . push ( spec . id ) ;
unfocusAncestor ( ) ;
2014-06-05 19:55:49 -04:00
return spec ;
} ;
this . expect = function ( actual ) {
2016-01-19 17:57:58 -05:00
if ( ! currentRunnable ( ) ) {
throw new Error ( '\'expect\' was used when there was no current spec, this could be because an asynchronous test timed out' ) ;
}
return currentRunnable ( ) . expect ( actual ) ;
} ;
this . beforeEach = function ( beforeEachFunction , timeout ) {
currentDeclarationSuite . beforeEach ( {
fn : beforeEachFunction ,
timeout : function ( ) { return timeout || j$ . DEFAULT _TIMEOUT _INTERVAL ; }
} ) ;
} ;
this . beforeAll = function ( beforeAllFunction , timeout ) {
currentDeclarationSuite . beforeAll ( {
fn : beforeAllFunction ,
timeout : function ( ) { return timeout || j$ . DEFAULT _TIMEOUT _INTERVAL ; }
} ) ;
} ;
this . afterEach = function ( afterEachFunction , timeout ) {
currentDeclarationSuite . afterEach ( {
fn : afterEachFunction ,
timeout : function ( ) { return timeout || j$ . DEFAULT _TIMEOUT _INTERVAL ; }
} ) ;
2014-06-05 19:55:49 -04:00
} ;
2016-01-19 17:57:58 -05:00
this . afterAll = function ( afterAllFunction , timeout ) {
currentDeclarationSuite . afterAll ( {
fn : afterAllFunction ,
timeout : function ( ) { return timeout || j$ . DEFAULT _TIMEOUT _INTERVAL ; }
} ) ;
2014-06-05 19:55:49 -04:00
} ;
2016-01-19 17:57:58 -05:00
this . pending = function ( message ) {
var fullMessage = j$ . Spec . pendingSpecExceptionMessage ;
if ( message ) {
fullMessage += message ;
}
throw fullMessage ;
2014-06-05 19:55:49 -04:00
} ;
2016-01-19 17:57:58 -05:00
this . fail = function ( error ) {
var message = 'Failed' ;
if ( error ) {
message += ': ' ;
message += error . message || error ;
}
currentRunnable ( ) . addExpectationResult ( false , {
matcherName : '' ,
passed : false ,
expected : '' ,
actual : '' ,
message : message ,
error : error && error . message ? error : null
} ) ;
2014-06-05 19:55:49 -04:00
} ;
}
return Env ;
} ;
getJasmineRequireObj ( ) . JsApiReporter = function ( ) {
var noopTimer = {
start : function ( ) { } ,
elapsed : function ( ) { return 0 ; }
} ;
function JsApiReporter ( options ) {
var timer = options . timer || noopTimer ,
2016-01-19 17:57:58 -05:00
status = 'loaded' ;
2014-06-05 19:55:49 -04:00
this . started = false ;
this . finished = false ;
2016-01-19 17:57:58 -05:00
this . runDetails = { } ;
2014-06-05 19:55:49 -04:00
this . jasmineStarted = function ( ) {
this . started = true ;
status = 'started' ;
timer . start ( ) ;
} ;
var executionTime ;
2016-01-19 17:57:58 -05:00
this . jasmineDone = function ( runDetails ) {
2014-06-05 19:55:49 -04:00
this . finished = true ;
2016-01-19 17:57:58 -05:00
this . runDetails = runDetails ;
2014-06-05 19:55:49 -04:00
executionTime = timer . elapsed ( ) ;
status = 'done' ;
} ;
this . status = function ( ) {
return status ;
} ;
2016-01-19 17:57:58 -05:00
var suites = [ ] ,
suites _hash = { } ;
2014-06-05 19:55:49 -04:00
this . suiteStarted = function ( result ) {
2016-01-19 17:57:58 -05:00
suites _hash [ result . id ] = result ;
2014-06-05 19:55:49 -04:00
} ;
this . suiteDone = function ( result ) {
storeSuite ( result ) ;
} ;
2016-01-19 17:57:58 -05:00
this . suiteResults = function ( index , length ) {
return suites . slice ( index , index + length ) ;
} ;
2014-06-05 19:55:49 -04:00
function storeSuite ( result ) {
2016-01-19 17:57:58 -05:00
suites . push ( result ) ;
suites _hash [ result . id ] = result ;
2014-06-05 19:55:49 -04:00
}
this . suites = function ( ) {
2016-01-19 17:57:58 -05:00
return suites _hash ;
2014-06-05 19:55:49 -04:00
} ;
var specs = [ ] ;
this . specDone = function ( result ) {
specs . push ( result ) ;
} ;
this . specResults = function ( index , length ) {
return specs . slice ( index , index + length ) ;
} ;
this . specs = function ( ) {
return specs ;
} ;
this . executionTime = function ( ) {
return executionTime ;
} ;
}
return JsApiReporter ;
} ;
2016-01-19 17:57:58 -05:00
getJasmineRequireObj ( ) . CallTracker = function ( ) {
2014-06-05 19:55:49 -04:00
2016-01-19 17:57:58 -05:00
function CallTracker ( ) {
var calls = [ ] ;
2014-06-05 19:55:49 -04:00
2016-01-19 17:57:58 -05:00
this . track = function ( context ) {
calls . push ( context ) ;
} ;
2014-06-05 19:55:49 -04:00
2016-01-19 17:57:58 -05:00
this . any = function ( ) {
return ! ! calls . length ;
} ;
2014-06-05 19:55:49 -04:00
this . count = function ( ) {
return calls . length ;
} ;
this . argsFor = function ( index ) {
var call = calls [ index ] ;
return call ? call . args : [ ] ;
} ;
this . all = function ( ) {
return calls ;
} ;
this . allArgs = function ( ) {
var callArgs = [ ] ;
for ( var i = 0 ; i < calls . length ; i ++ ) {
callArgs . push ( calls [ i ] . args ) ;
}
return callArgs ;
} ;
this . first = function ( ) {
return calls [ 0 ] ;
} ;
this . mostRecent = function ( ) {
return calls [ calls . length - 1 ] ;
} ;
this . reset = function ( ) {
calls = [ ] ;
} ;
}
return CallTracker ;
} ;
getJasmineRequireObj ( ) . Clock = function ( ) {
2016-01-19 17:57:58 -05:00
function Clock ( global , delayedFunctionSchedulerFactory , mockDate ) {
2014-06-05 19:55:49 -04:00
var self = this ,
realTimingFunctions = {
setTimeout : global . setTimeout ,
clearTimeout : global . clearTimeout ,
setInterval : global . setInterval ,
clearInterval : global . clearInterval
} ,
fakeTimingFunctions = {
setTimeout : setTimeout ,
clearTimeout : clearTimeout ,
setInterval : setInterval ,
clearInterval : clearInterval
} ,
installed = false ,
2016-01-19 17:57:58 -05:00
delayedFunctionScheduler ,
2014-06-05 19:55:49 -04:00
timer ;
2016-01-19 17:57:58 -05:00
2014-06-05 19:55:49 -04:00
self . install = function ( ) {
2016-01-19 17:57:58 -05:00
if ( ! originalTimingFunctionsIntact ( ) ) {
throw new Error ( 'Jasmine Clock was unable to install over custom global timer functions. Is the clock already installed?' ) ;
}
2014-06-05 19:55:49 -04:00
replace ( global , fakeTimingFunctions ) ;
timer = fakeTimingFunctions ;
2016-01-19 17:57:58 -05:00
delayedFunctionScheduler = delayedFunctionSchedulerFactory ( ) ;
2014-06-05 19:55:49 -04:00
installed = true ;
2016-01-19 17:57:58 -05:00
return self ;
2014-06-05 19:55:49 -04:00
} ;
self . uninstall = function ( ) {
2016-01-19 17:57:58 -05:00
delayedFunctionScheduler = null ;
mockDate . uninstall ( ) ;
2014-06-05 19:55:49 -04:00
replace ( global , realTimingFunctions ) ;
2016-01-19 17:57:58 -05:00
2014-06-05 19:55:49 -04:00
timer = realTimingFunctions ;
installed = false ;
} ;
2016-01-19 17:57:58 -05:00
self . withMock = function ( closure ) {
this . install ( ) ;
try {
closure ( ) ;
} finally {
this . uninstall ( ) ;
}
} ;
self . mockDate = function ( initialDate ) {
mockDate . install ( initialDate ) ;
} ;
2014-06-05 19:55:49 -04:00
self . setTimeout = function ( fn , delay , params ) {
if ( legacyIE ( ) ) {
if ( arguments . length > 2 ) {
2016-01-19 17:57:58 -05:00
throw new Error ( 'IE < 9 cannot support extra params to setTimeout without a polyfill' ) ;
2014-06-05 19:55:49 -04:00
}
return timer . setTimeout ( fn , delay ) ;
}
return Function . prototype . apply . apply ( timer . setTimeout , [ global , arguments ] ) ;
} ;
self . setInterval = function ( fn , delay , params ) {
if ( legacyIE ( ) ) {
if ( arguments . length > 2 ) {
2016-01-19 17:57:58 -05:00
throw new Error ( 'IE < 9 cannot support extra params to setInterval without a polyfill' ) ;
2014-06-05 19:55:49 -04:00
}
return timer . setInterval ( fn , delay ) ;
}
return Function . prototype . apply . apply ( timer . setInterval , [ global , arguments ] ) ;
} ;
self . clearTimeout = function ( id ) {
return Function . prototype . call . apply ( timer . clearTimeout , [ global , id ] ) ;
} ;
self . clearInterval = function ( id ) {
return Function . prototype . call . apply ( timer . clearInterval , [ global , id ] ) ;
} ;
self . tick = function ( millis ) {
if ( installed ) {
2016-01-19 17:57:58 -05:00
delayedFunctionScheduler . tick ( millis , function ( millis ) { mockDate . tick ( millis ) ; } ) ;
2014-06-05 19:55:49 -04:00
} else {
2016-01-19 17:57:58 -05:00
throw new Error ( 'Mock clock is not installed, use jasmine.clock().install()' ) ;
2014-06-05 19:55:49 -04:00
}
} ;
return self ;
2016-01-19 17:57:58 -05:00
function originalTimingFunctionsIntact ( ) {
return global . setTimeout === realTimingFunctions . setTimeout &&
global . clearTimeout === realTimingFunctions . clearTimeout &&
global . setInterval === realTimingFunctions . setInterval &&
global . clearInterval === realTimingFunctions . clearInterval ;
}
2014-06-05 19:55:49 -04:00
function legacyIE ( ) {
//if these methods are polyfilled, apply will be present
return ! ( realTimingFunctions . setTimeout || realTimingFunctions . setInterval ) . apply ;
}
function replace ( dest , source ) {
for ( var prop in source ) {
dest [ prop ] = source [ prop ] ;
}
}
function setTimeout ( fn , delay ) {
return delayedFunctionScheduler . scheduleFunction ( fn , delay , argSlice ( arguments , 2 ) ) ;
}
function clearTimeout ( id ) {
return delayedFunctionScheduler . removeFunctionWithId ( id ) ;
}
function setInterval ( fn , interval ) {
return delayedFunctionScheduler . scheduleFunction ( fn , interval , argSlice ( arguments , 2 ) , true ) ;
}
function clearInterval ( id ) {
return delayedFunctionScheduler . removeFunctionWithId ( id ) ;
}
function argSlice ( argsObj , n ) {
2016-01-19 17:57:58 -05:00
return Array . prototype . slice . call ( argsObj , n ) ;
2014-06-05 19:55:49 -04:00
}
}
return Clock ;
} ;
getJasmineRequireObj ( ) . DelayedFunctionScheduler = function ( ) {
function DelayedFunctionScheduler ( ) {
var self = this ;
var scheduledLookup = [ ] ;
var scheduledFunctions = { } ;
var currentTime = 0 ;
var delayedFnCount = 0 ;
2016-01-19 17:57:58 -05:00
self . tick = function ( millis , tickDate ) {
2014-06-05 19:55:49 -04:00
millis = millis || 0 ;
var endTime = currentTime + millis ;
2016-01-19 17:57:58 -05:00
runScheduledFunctions ( endTime , tickDate ) ;
2014-06-05 19:55:49 -04:00
currentTime = endTime ;
} ;
self . scheduleFunction = function ( funcToCall , millis , params , recurring , timeoutKey , runAtMillis ) {
var f ;
if ( typeof ( funcToCall ) === 'string' ) {
/* jshint evil: true */
f = function ( ) { return eval ( funcToCall ) ; } ;
/* jshint evil: false */
} else {
f = funcToCall ;
}
millis = millis || 0 ;
timeoutKey = timeoutKey || ++ delayedFnCount ;
runAtMillis = runAtMillis || ( currentTime + millis ) ;
var funcToSchedule = {
runAtMillis : runAtMillis ,
funcToCall : f ,
recurring : recurring ,
params : params ,
timeoutKey : timeoutKey ,
millis : millis
} ;
if ( runAtMillis in scheduledFunctions ) {
scheduledFunctions [ runAtMillis ] . push ( funcToSchedule ) ;
} else {
scheduledFunctions [ runAtMillis ] = [ funcToSchedule ] ;
scheduledLookup . push ( runAtMillis ) ;
scheduledLookup . sort ( function ( a , b ) {
return a - b ;
} ) ;
}
return timeoutKey ;
} ;
self . removeFunctionWithId = function ( timeoutKey ) {
for ( var runAtMillis in scheduledFunctions ) {
var funcs = scheduledFunctions [ runAtMillis ] ;
var i = indexOfFirstToPass ( funcs , function ( func ) {
return func . timeoutKey === timeoutKey ;
} ) ;
if ( i > - 1 ) {
if ( funcs . length === 1 ) {
delete scheduledFunctions [ runAtMillis ] ;
deleteFromLookup ( runAtMillis ) ;
} else {
funcs . splice ( i , 1 ) ;
}
// intervals get rescheduled when executed, so there's never more
// than a single scheduled function with a given timeoutKey
break ;
}
}
} ;
return self ;
function indexOfFirstToPass ( array , testFn ) {
var index = - 1 ;
for ( var i = 0 ; i < array . length ; ++ i ) {
if ( testFn ( array [ i ] ) ) {
index = i ;
break ;
}
}
return index ;
}
function deleteFromLookup ( key ) {
var value = Number ( key ) ;
var i = indexOfFirstToPass ( scheduledLookup , function ( millis ) {
return millis === value ;
} ) ;
if ( i > - 1 ) {
scheduledLookup . splice ( i , 1 ) ;
}
}
function reschedule ( scheduledFn ) {
self . scheduleFunction ( scheduledFn . funcToCall ,
scheduledFn . millis ,
scheduledFn . params ,
true ,
scheduledFn . timeoutKey ,
scheduledFn . runAtMillis + scheduledFn . millis ) ;
}
2016-01-19 17:57:58 -05:00
function forEachFunction ( funcsToRun , callback ) {
for ( var i = 0 ; i < funcsToRun . length ; ++ i ) {
callback ( funcsToRun [ i ] ) ;
}
}
function runScheduledFunctions ( endTime , tickDate ) {
tickDate = tickDate || function ( ) { } ;
2014-06-05 19:55:49 -04:00
if ( scheduledLookup . length === 0 || scheduledLookup [ 0 ] > endTime ) {
2016-01-19 17:57:58 -05:00
tickDate ( endTime ) ;
2014-06-05 19:55:49 -04:00
return ;
}
do {
2016-01-19 17:57:58 -05:00
var newCurrentTime = scheduledLookup . shift ( ) ;
tickDate ( newCurrentTime - currentTime ) ;
currentTime = newCurrentTime ;
2014-06-05 19:55:49 -04:00
var funcsToRun = scheduledFunctions [ currentTime ] ;
delete scheduledFunctions [ currentTime ] ;
2016-01-19 17:57:58 -05:00
forEachFunction ( funcsToRun , function ( funcToRun ) {
2014-06-05 19:55:49 -04:00
if ( funcToRun . recurring ) {
reschedule ( funcToRun ) ;
}
2016-01-19 17:57:58 -05:00
} ) ;
forEachFunction ( funcsToRun , function ( funcToRun ) {
funcToRun . funcToCall . apply ( null , funcToRun . params || [ ] ) ;
} ) ;
2014-06-05 19:55:49 -04:00
} while ( scheduledLookup . length > 0 &&
2016-01-19 17:57:58 -05:00
// checking first if we're out of time prevents setTimeout(0)
// scheduled in a funcToRun from forcing an extra iteration
currentTime !== endTime &&
scheduledLookup [ 0 ] <= endTime ) ;
2014-06-05 19:55:49 -04:00
}
}
return DelayedFunctionScheduler ;
} ;
getJasmineRequireObj ( ) . ExceptionFormatter = function ( ) {
function ExceptionFormatter ( ) {
this . message = function ( error ) {
2016-01-19 17:57:58 -05:00
var message = '' ;
if ( error . name && error . message ) {
message += error . name + ': ' + error . message ;
} else {
message += error . toString ( ) + ' thrown' ;
}
2014-06-05 19:55:49 -04:00
if ( error . fileName || error . sourceURL ) {
2016-01-19 17:57:58 -05:00
message += ' in ' + ( error . fileName || error . sourceURL ) ;
2014-06-05 19:55:49 -04:00
}
if ( error . line || error . lineNumber ) {
2016-01-19 17:57:58 -05:00
message += ' (line ' + ( error . line || error . lineNumber ) + ')' ;
2014-06-05 19:55:49 -04:00
}
return message ;
} ;
this . stack = function ( error ) {
return error ? error . stack : null ;
} ;
}
return ExceptionFormatter ;
} ;
getJasmineRequireObj ( ) . Expectation = function ( ) {
function Expectation ( options ) {
this . util = options . util || { buildFailureMessage : function ( ) { } } ;
this . customEqualityTesters = options . customEqualityTesters || [ ] ;
this . actual = options . actual ;
this . addExpectationResult = options . addExpectationResult || function ( ) { } ;
this . isNot = options . isNot ;
2016-01-19 17:57:58 -05:00
var customMatchers = options . customMatchers || { } ;
for ( var matcherName in customMatchers ) {
this [ matcherName ] = Expectation . prototype . wrapCompare ( matcherName , customMatchers [ matcherName ] ) ;
2014-06-05 19:55:49 -04:00
}
}
Expectation . prototype . wrapCompare = function ( name , matcherFactory ) {
return function ( ) {
var args = Array . prototype . slice . call ( arguments , 0 ) ,
expected = args . slice ( 0 ) ,
2016-01-19 17:57:58 -05:00
message = '' ;
2014-06-05 19:55:49 -04:00
args . unshift ( this . actual ) ;
var matcher = matcherFactory ( this . util , this . customEqualityTesters ) ,
2016-01-19 17:57:58 -05:00
matcherCompare = matcher . compare ;
2014-06-05 19:55:49 -04:00
function defaultNegativeCompare ( ) {
var result = matcher . compare . apply ( null , args ) ;
result . pass = ! result . pass ;
return result ;
}
if ( this . isNot ) {
matcherCompare = matcher . negativeCompare || defaultNegativeCompare ;
}
var result = matcherCompare . apply ( null , args ) ;
if ( ! result . pass ) {
if ( ! result . message ) {
args . unshift ( this . isNot ) ;
args . unshift ( name ) ;
message = this . util . buildFailureMessage . apply ( null , args ) ;
} else {
2016-01-19 17:57:58 -05:00
if ( Object . prototype . toString . apply ( result . message ) === '[object Function]' ) {
message = result . message ( ) ;
} else {
message = result . message ;
}
2014-06-05 19:55:49 -04:00
}
}
if ( expected . length == 1 ) {
expected = expected [ 0 ] ;
}
// TODO: how many of these params are needed?
this . addExpectationResult (
result . pass ,
{
matcherName : name ,
passed : result . pass ,
message : message ,
actual : this . actual ,
expected : expected // TODO: this may need to be arrayified/sliced
}
) ;
} ;
} ;
Expectation . addCoreMatchers = function ( matchers ) {
var prototype = Expectation . prototype ;
for ( var matcherName in matchers ) {
var matcher = matchers [ matcherName ] ;
prototype [ matcherName ] = prototype . wrapCompare ( matcherName , matcher ) ;
}
} ;
Expectation . Factory = function ( options ) {
options = options || { } ;
var expect = new Expectation ( options ) ;
// TODO: this would be nice as its own Object - NegativeExpectation
// TODO: copy instead of mutate options
options . isNot = true ;
expect . not = new Expectation ( options ) ;
return expect ;
} ;
return Expectation ;
} ;
//TODO: expectation result may make more sense as a presentation of an expectation.
getJasmineRequireObj ( ) . buildExpectationResult = function ( ) {
function buildExpectationResult ( options ) {
var messageFormatter = options . messageFormatter || function ( ) { } ,
stackFormatter = options . stackFormatter || function ( ) { } ;
2016-01-19 17:57:58 -05:00
var result = {
2014-06-05 19:55:49 -04:00
matcherName : options . matcherName ,
message : message ( ) ,
stack : stack ( ) ,
passed : options . passed
} ;
2016-01-19 17:57:58 -05:00
if ( ! result . passed ) {
result . expected = options . expected ;
result . actual = options . actual ;
}
return result ;
2014-06-05 19:55:49 -04:00
function message ( ) {
if ( options . passed ) {
2016-01-19 17:57:58 -05:00
return 'Passed.' ;
2014-06-05 19:55:49 -04:00
} else if ( options . message ) {
return options . message ;
} else if ( options . error ) {
return messageFormatter ( options . error ) ;
}
2016-01-19 17:57:58 -05:00
return '' ;
2014-06-05 19:55:49 -04:00
}
function stack ( ) {
if ( options . passed ) {
2016-01-19 17:57:58 -05:00
return '' ;
2014-06-05 19:55:49 -04:00
}
var error = options . error ;
if ( ! error ) {
try {
throw new Error ( message ( ) ) ;
} catch ( e ) {
error = e ;
}
}
return stackFormatter ( error ) ;
}
}
return buildExpectationResult ;
} ;
2016-01-19 17:57:58 -05:00
getJasmineRequireObj ( ) . MockDate = function ( ) {
function MockDate ( global ) {
var self = this ;
var currentTime = 0 ;
2014-06-05 19:55:49 -04:00
2016-01-19 17:57:58 -05:00
if ( ! global || ! global . Date ) {
self . install = function ( ) { } ;
self . tick = function ( ) { } ;
self . uninstall = function ( ) { } ;
return self ;
}
2014-06-05 19:55:49 -04:00
2016-01-19 17:57:58 -05:00
var GlobalDate = global . Date ;
2014-06-05 19:55:49 -04:00
2016-01-19 17:57:58 -05:00
self . install = function ( mockDate ) {
if ( mockDate instanceof GlobalDate ) {
currentTime = mockDate . getTime ( ) ;
} else {
currentTime = new GlobalDate ( ) . getTime ( ) ;
}
2014-06-05 19:55:49 -04:00
2016-01-19 17:57:58 -05:00
global . Date = FakeDate ;
2014-06-05 19:55:49 -04:00
} ;
2016-01-19 17:57:58 -05:00
self . tick = function ( millis ) {
millis = millis || 0 ;
currentTime = currentTime + millis ;
} ;
2014-06-05 19:55:49 -04:00
2016-01-19 17:57:58 -05:00
self . uninstall = function ( ) {
currentTime = 0 ;
global . Date = GlobalDate ;
} ;
2014-06-05 19:55:49 -04:00
2016-01-19 17:57:58 -05:00
createDateProperties ( ) ;
2014-06-05 19:55:49 -04:00
2016-01-19 17:57:58 -05:00
return self ;
function FakeDate ( ) {
switch ( arguments . length ) {
case 0 :
return new GlobalDate ( currentTime ) ;
case 1 :
return new GlobalDate ( arguments [ 0 ] ) ;
case 2 :
return new GlobalDate ( arguments [ 0 ] , arguments [ 1 ] ) ;
case 3 :
return new GlobalDate ( arguments [ 0 ] , arguments [ 1 ] , arguments [ 2 ] ) ;
case 4 :
return new GlobalDate ( arguments [ 0 ] , arguments [ 1 ] , arguments [ 2 ] , arguments [ 3 ] ) ;
case 5 :
return new GlobalDate ( arguments [ 0 ] , arguments [ 1 ] , arguments [ 2 ] , arguments [ 3 ] ,
arguments [ 4 ] ) ;
case 6 :
return new GlobalDate ( arguments [ 0 ] , arguments [ 1 ] , arguments [ 2 ] , arguments [ 3 ] ,
arguments [ 4 ] , arguments [ 5 ] ) ;
default :
return new GlobalDate ( arguments [ 0 ] , arguments [ 1 ] , arguments [ 2 ] , arguments [ 3 ] ,
arguments [ 4 ] , arguments [ 5 ] , arguments [ 6 ] ) ;
}
}
function createDateProperties ( ) {
FakeDate . prototype = GlobalDate . prototype ;
FakeDate . now = function ( ) {
if ( GlobalDate . now ) {
return currentTime ;
} else {
throw new Error ( 'Browser does not support Date.now()' ) ;
}
} ;
FakeDate . toSource = GlobalDate . toSource ;
FakeDate . toString = GlobalDate . toString ;
FakeDate . parse = GlobalDate . parse ;
FakeDate . UTC = GlobalDate . UTC ;
}
}
return MockDate ;
2014-06-05 19:55:49 -04:00
} ;
getJasmineRequireObj ( ) . pp = function ( j$ ) {
function PrettyPrinter ( ) {
this . ppNestLevel _ = 0 ;
2016-01-19 17:57:58 -05:00
this . seen = [ ] ;
2014-06-05 19:55:49 -04:00
}
PrettyPrinter . prototype . format = function ( value ) {
this . ppNestLevel _ ++ ;
try {
if ( j$ . util . isUndefined ( value ) ) {
this . emitScalar ( 'undefined' ) ;
} else if ( value === null ) {
this . emitScalar ( 'null' ) ;
2016-01-19 17:57:58 -05:00
} else if ( value === 0 && 1 / value === - Infinity ) {
this . emitScalar ( '-0' ) ;
2014-06-05 19:55:49 -04:00
} else if ( value === j$ . getGlobal ( ) ) {
this . emitScalar ( '<global>' ) ;
} else if ( value . jasmineToString ) {
this . emitScalar ( value . jasmineToString ( ) ) ;
} else if ( typeof value === 'string' ) {
this . emitString ( value ) ;
} else if ( j$ . isSpy ( value ) ) {
2016-01-19 17:57:58 -05:00
this . emitScalar ( 'spy on ' + value . and . identity ( ) ) ;
2014-06-05 19:55:49 -04:00
} else if ( value instanceof RegExp ) {
this . emitScalar ( value . toString ( ) ) ;
} else if ( typeof value === 'function' ) {
this . emitScalar ( 'Function' ) ;
} else if ( typeof value . nodeType === 'number' ) {
this . emitScalar ( 'HTMLNode' ) ;
} else if ( value instanceof Date ) {
this . emitScalar ( 'Date(' + value + ')' ) ;
2016-01-19 17:57:58 -05:00
} else if ( value . toString && typeof value === 'object' && ! ( value instanceof Array ) && value . toString !== Object . prototype . toString ) {
this . emitScalar ( value . toString ( ) ) ;
} else if ( j$ . util . arrayContains ( this . seen , value ) ) {
2014-06-05 19:55:49 -04:00
this . emitScalar ( '<circular reference: ' + ( j$ . isArray _ ( value ) ? 'Array' : 'Object' ) + '>' ) ;
} else if ( j$ . isArray _ ( value ) || j$ . isA _ ( 'Object' , value ) ) {
2016-01-19 17:57:58 -05:00
this . seen . push ( value ) ;
2014-06-05 19:55:49 -04:00
if ( j$ . isArray _ ( value ) ) {
this . emitArray ( value ) ;
} else {
this . emitObject ( value ) ;
}
2016-01-19 17:57:58 -05:00
this . seen . pop ( ) ;
2014-06-05 19:55:49 -04:00
} else {
this . emitScalar ( value . toString ( ) ) ;
}
} finally {
this . ppNestLevel _ -- ;
}
} ;
PrettyPrinter . prototype . iterateObject = function ( obj , fn ) {
for ( var property in obj ) {
2016-01-19 17:57:58 -05:00
if ( ! Object . prototype . hasOwnProperty . call ( obj , property ) ) { continue ; }
2014-06-05 19:55:49 -04:00
fn ( property , obj . _ _lookupGetter _ _ ? ( ! j$ . util . isUndefined ( obj . _ _lookupGetter _ _ ( property ) ) &&
2016-01-19 17:57:58 -05:00
obj . _ _lookupGetter _ _ ( property ) !== null ) : false ) ;
2014-06-05 19:55:49 -04:00
}
} ;
PrettyPrinter . prototype . emitArray = j$ . unimplementedMethod _ ;
PrettyPrinter . prototype . emitObject = j$ . unimplementedMethod _ ;
PrettyPrinter . prototype . emitScalar = j$ . unimplementedMethod _ ;
PrettyPrinter . prototype . emitString = j$ . unimplementedMethod _ ;
function StringPrettyPrinter ( ) {
PrettyPrinter . call ( this ) ;
this . string = '' ;
}
j$ . util . inherit ( StringPrettyPrinter , PrettyPrinter ) ;
StringPrettyPrinter . prototype . emitScalar = function ( value ) {
this . append ( value ) ;
} ;
StringPrettyPrinter . prototype . emitString = function ( value ) {
2016-01-19 17:57:58 -05:00
this . append ( '\'' + value + '\'' ) ;
2014-06-05 19:55:49 -04:00
} ;
StringPrettyPrinter . prototype . emitArray = function ( array ) {
if ( this . ppNestLevel _ > j$ . MAX _PRETTY _PRINT _DEPTH ) {
2016-01-19 17:57:58 -05:00
this . append ( 'Array' ) ;
2014-06-05 19:55:49 -04:00
return ;
}
2016-01-19 17:57:58 -05:00
var length = Math . min ( array . length , j$ . MAX _PRETTY _PRINT _ARRAY _LENGTH ) ;
2014-06-05 19:55:49 -04:00
this . append ( '[ ' ) ;
2016-01-19 17:57:58 -05:00
for ( var i = 0 ; i < length ; i ++ ) {
2014-06-05 19:55:49 -04:00
if ( i > 0 ) {
this . append ( ', ' ) ;
}
this . format ( array [ i ] ) ;
}
2016-01-19 17:57:58 -05:00
if ( array . length > length ) {
this . append ( ', ...' ) ;
}
var self = this ;
var first = array . length === 0 ;
this . iterateObject ( array , function ( property , isGetter ) {
if ( property . match ( /^\d+$/ ) ) {
return ;
}
if ( first ) {
first = false ;
} else {
self . append ( ', ' ) ;
}
self . formatProperty ( array , property , isGetter ) ;
} ) ;
2014-06-05 19:55:49 -04:00
this . append ( ' ]' ) ;
} ;
StringPrettyPrinter . prototype . emitObject = function ( obj ) {
2016-01-19 17:57:58 -05:00
var constructorName = obj . constructor ? j$ . fnNameFor ( obj . constructor ) : 'null' ;
this . append ( constructorName ) ;
2014-06-05 19:55:49 -04:00
if ( this . ppNestLevel _ > j$ . MAX _PRETTY _PRINT _DEPTH ) {
return ;
}
var self = this ;
2016-01-19 17:57:58 -05:00
this . append ( '({ ' ) ;
2014-06-05 19:55:49 -04:00
var first = true ;
this . iterateObject ( obj , function ( property , isGetter ) {
if ( first ) {
first = false ;
} else {
self . append ( ', ' ) ;
}
2016-01-19 17:57:58 -05:00
self . formatProperty ( obj , property , isGetter ) ;
2014-06-05 19:55:49 -04:00
} ) ;
2016-01-19 17:57:58 -05:00
this . append ( ' })' ) ;
} ;
StringPrettyPrinter . prototype . formatProperty = function ( obj , property , isGetter ) {
this . append ( property ) ;
this . append ( ': ' ) ;
if ( isGetter ) {
this . append ( '<getter>' ) ;
} else {
this . format ( obj [ property ] ) ;
}
2014-06-05 19:55:49 -04:00
} ;
StringPrettyPrinter . prototype . append = function ( value ) {
this . string += value ;
} ;
return function ( value ) {
var stringPrettyPrinter = new StringPrettyPrinter ( ) ;
stringPrettyPrinter . format ( value ) ;
return stringPrettyPrinter . string ;
} ;
} ;
2016-01-19 17:57:58 -05:00
getJasmineRequireObj ( ) . QueueRunner = function ( j$ ) {
function once ( fn ) {
var called = false ;
return function ( ) {
if ( ! called ) {
called = true ;
fn ( ) ;
}
} ;
}
2014-06-05 19:55:49 -04:00
function QueueRunner ( attrs ) {
2016-01-19 17:57:58 -05:00
this . queueableFns = attrs . queueableFns || [ ] ;
2014-06-05 19:55:49 -04:00
this . onComplete = attrs . onComplete || function ( ) { } ;
this . clearStack = attrs . clearStack || function ( fn ) { fn ( ) ; } ;
this . onException = attrs . onException || function ( ) { } ;
this . catchException = attrs . catchException || function ( ) { return true ; } ;
2016-01-19 17:57:58 -05:00
this . userContext = attrs . userContext || { } ;
this . timeout = attrs . timeout || { setTimeout : setTimeout , clearTimeout : clearTimeout } ;
this . fail = attrs . fail || function ( ) { } ;
2014-06-05 19:55:49 -04:00
}
QueueRunner . prototype . execute = function ( ) {
2016-01-19 17:57:58 -05:00
this . run ( this . queueableFns , 0 ) ;
2014-06-05 19:55:49 -04:00
} ;
2016-01-19 17:57:58 -05:00
QueueRunner . prototype . run = function ( queueableFns , recursiveIndex ) {
var length = queueableFns . length ,
self = this ,
iterativeIndex ;
2014-06-05 19:55:49 -04:00
for ( iterativeIndex = recursiveIndex ; iterativeIndex < length ; iterativeIndex ++ ) {
2016-01-19 17:57:58 -05:00
var queueableFn = queueableFns [ iterativeIndex ] ;
if ( queueableFn . fn . length > 0 ) {
attemptAsync ( queueableFn ) ;
return ;
2014-06-05 19:55:49 -04:00
} else {
2016-01-19 17:57:58 -05:00
attemptSync ( queueableFn ) ;
2014-06-05 19:55:49 -04:00
}
}
var runnerDone = iterativeIndex >= length ;
if ( runnerDone ) {
this . clearStack ( this . onComplete ) ;
}
2016-01-19 17:57:58 -05:00
function attemptSync ( queueableFn ) {
2014-06-05 19:55:49 -04:00
try {
2016-01-19 17:57:58 -05:00
queueableFn . fn . call ( self . userContext ) ;
2014-06-05 19:55:49 -04:00
} catch ( e ) {
2016-01-19 17:57:58 -05:00
handleException ( e , queueableFn ) ;
2014-06-05 19:55:49 -04:00
}
}
2016-01-19 17:57:58 -05:00
function attemptAsync ( queueableFn ) {
var clearTimeout = function ( ) {
Function . prototype . apply . apply ( self . timeout . clearTimeout , [ j$ . getGlobal ( ) , [ timeoutId ] ] ) ;
} ,
next = once ( function ( ) {
clearTimeout ( timeoutId ) ;
self . run ( queueableFns , iterativeIndex + 1 ) ;
} ) ,
timeoutId ;
next . fail = function ( ) {
self . fail . apply ( null , arguments ) ;
next ( ) ;
} ;
if ( queueableFn . timeout ) {
timeoutId = Function . prototype . apply . apply ( self . timeout . setTimeout , [ j$ . getGlobal ( ) , [ function ( ) {
var error = new Error ( 'Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.' ) ;
onException ( error ) ;
next ( ) ;
} , queueableFn . timeout ( ) ] ] ) ;
}
2014-06-05 19:55:49 -04:00
try {
2016-01-19 17:57:58 -05:00
queueableFn . fn . call ( self . userContext , next ) ;
2014-06-05 19:55:49 -04:00
} catch ( e ) {
2016-01-19 17:57:58 -05:00
handleException ( e , queueableFn ) ;
2014-06-05 19:55:49 -04:00
next ( ) ;
}
}
2016-01-19 17:57:58 -05:00
function onException ( e ) {
2014-06-05 19:55:49 -04:00
self . onException ( e ) ;
2016-01-19 17:57:58 -05:00
}
function handleException ( e , queueableFn ) {
onException ( e ) ;
2014-06-05 19:55:49 -04:00
if ( ! self . catchException ( e ) ) {
//TODO: set a var when we catch an exception and
//use a finally block to close the loop in a nice way..
throw e ;
}
}
} ;
return QueueRunner ;
} ;
getJasmineRequireObj ( ) . ReportDispatcher = function ( ) {
function ReportDispatcher ( methods ) {
var dispatchedMethods = methods || [ ] ;
for ( var i = 0 ; i < dispatchedMethods . length ; i ++ ) {
var method = dispatchedMethods [ i ] ;
this [ method ] = ( function ( m ) {
return function ( ) {
dispatch ( m , arguments ) ;
} ;
} ( method ) ) ;
}
var reporters = [ ] ;
this . addReporter = function ( reporter ) {
reporters . push ( reporter ) ;
} ;
return this ;
function dispatch ( method , args ) {
for ( var i = 0 ; i < reporters . length ; i ++ ) {
var reporter = reporters [ i ] ;
if ( reporter [ method ] ) {
reporter [ method ] . apply ( reporter , args ) ;
}
}
}
}
return ReportDispatcher ;
} ;
2016-01-19 17:57:58 -05:00
getJasmineRequireObj ( ) . SpyRegistry = function ( j$ ) {
function SpyRegistry ( options ) {
options = options || { } ;
var currentSpies = options . currentSpies || function ( ) { return [ ] ; } ;
this . spyOn = function ( obj , methodName ) {
if ( j$ . util . isUndefined ( obj ) ) {
throw new Error ( 'spyOn could not find an object to spy upon for ' + methodName + '()' ) ;
}
if ( j$ . util . isUndefined ( methodName ) ) {
throw new Error ( 'No method name supplied' ) ;
}
if ( j$ . util . isUndefined ( obj [ methodName ] ) ) {
throw new Error ( methodName + '() method does not exist' ) ;
}
if ( obj [ methodName ] && j$ . isSpy ( obj [ methodName ] ) ) {
//TODO?: should this return the current spy? Downside: may cause user confusion about spy state
throw new Error ( methodName + ' has already been spied upon' ) ;
}
var descriptor ;
try {
descriptor = Object . getOwnPropertyDescriptor ( obj , methodName ) ;
} catch ( e ) {
// IE 8 doesn't support `definePropery` on non-DOM nodes
}
if ( descriptor && ! ( descriptor . writable || descriptor . set ) ) {
throw new Error ( methodName + ' is not declared writable or has no setter' ) ;
}
var spy = j$ . createSpy ( methodName , obj [ methodName ] ) ;
currentSpies ( ) . push ( {
spy : spy ,
baseObj : obj ,
methodName : methodName ,
originalValue : obj [ methodName ]
} ) ;
obj [ methodName ] = spy ;
return spy ;
} ;
this . clearSpies = function ( ) {
var spies = currentSpies ( ) ;
for ( var i = 0 ; i < spies . length ; i ++ ) {
var spyEntry = spies [ i ] ;
spyEntry . baseObj [ spyEntry . methodName ] = spyEntry . originalValue ;
}
} ;
}
return SpyRegistry ;
} ;
2014-06-05 19:55:49 -04:00
getJasmineRequireObj ( ) . SpyStrategy = function ( ) {
function SpyStrategy ( options ) {
options = options || { } ;
2016-01-19 17:57:58 -05:00
var identity = options . name || 'unknown' ,
originalFn = options . fn || function ( ) { } ,
getSpy = options . getSpy || function ( ) { } ,
plan = function ( ) { } ;
2014-06-05 19:55:49 -04:00
this . identity = function ( ) {
return identity ;
} ;
this . exec = function ( ) {
return plan . apply ( this , arguments ) ;
} ;
this . callThrough = function ( ) {
plan = originalFn ;
return getSpy ( ) ;
} ;
this . returnValue = function ( value ) {
plan = function ( ) {
return value ;
} ;
return getSpy ( ) ;
} ;
2016-01-19 17:57:58 -05:00
this . returnValues = function ( ) {
var values = Array . prototype . slice . call ( arguments ) ;
plan = function ( ) {
return values . shift ( ) ;
} ;
return getSpy ( ) ;
} ;
2014-06-05 19:55:49 -04:00
this . throwError = function ( something ) {
var error = ( something instanceof Error ) ? something : new Error ( something ) ;
plan = function ( ) {
throw error ;
} ;
return getSpy ( ) ;
} ;
this . callFake = function ( fn ) {
plan = fn ;
return getSpy ( ) ;
} ;
2016-01-19 17:57:58 -05:00
this . stub = function ( fn ) {
plan = function ( ) { } ;
return getSpy ( ) ;
} ;
}
return SpyStrategy ;
} ;
getJasmineRequireObj ( ) . Suite = function ( j$ ) {
function Suite ( attrs ) {
this . env = attrs . env ;
this . id = attrs . id ;
this . parentSuite = attrs . parentSuite ;
this . description = attrs . description ;
this . expectationFactory = attrs . expectationFactory ;
this . expectationResultFactory = attrs . expectationResultFactory ;
this . throwOnExpectationFailure = ! ! attrs . throwOnExpectationFailure ;
this . beforeFns = [ ] ;
this . afterFns = [ ] ;
this . beforeAllFns = [ ] ;
this . afterAllFns = [ ] ;
this . disabled = false ;
this . children = [ ] ;
this . result = {
id : this . id ,
description : this . description ,
fullName : this . getFullName ( ) ,
failedExpectations : [ ]
} ;
}
Suite . prototype . expect = function ( actual ) {
return this . expectationFactory ( actual , this ) ;
} ;
Suite . prototype . getFullName = function ( ) {
var fullName = this . description ;
for ( var parentSuite = this . parentSuite ; parentSuite ; parentSuite = parentSuite . parentSuite ) {
if ( parentSuite . parentSuite ) {
fullName = parentSuite . description + ' ' + fullName ;
}
}
return fullName ;
} ;
Suite . prototype . disable = function ( ) {
this . disabled = true ;
} ;
Suite . prototype . pend = function ( message ) {
this . markedPending = true ;
} ;
Suite . prototype . beforeEach = function ( fn ) {
this . beforeFns . unshift ( fn ) ;
} ;
Suite . prototype . beforeAll = function ( fn ) {
this . beforeAllFns . push ( fn ) ;
} ;
Suite . prototype . afterEach = function ( fn ) {
this . afterFns . unshift ( fn ) ;
} ;
Suite . prototype . afterAll = function ( fn ) {
this . afterAllFns . push ( fn ) ;
} ;
Suite . prototype . addChild = function ( child ) {
this . children . push ( child ) ;
} ;
Suite . prototype . status = function ( ) {
if ( this . disabled ) {
return 'disabled' ;
}
if ( this . markedPending ) {
return 'pending' ;
}
if ( this . result . failedExpectations . length > 0 ) {
return 'failed' ;
} else {
return 'finished' ;
}
} ;
Suite . prototype . isExecutable = function ( ) {
return ! this . disabled ;
} ;
Suite . prototype . canBeReentered = function ( ) {
return this . beforeAllFns . length === 0 && this . afterAllFns . length === 0 ;
} ;
Suite . prototype . getResult = function ( ) {
this . result . status = this . status ( ) ;
return this . result ;
} ;
Suite . prototype . sharedUserContext = function ( ) {
if ( ! this . sharedContext ) {
this . sharedContext = this . parentSuite ? clone ( this . parentSuite . sharedUserContext ( ) ) : { } ;
}
return this . sharedContext ;
} ;
Suite . prototype . clonedSharedUserContext = function ( ) {
return clone ( this . sharedUserContext ( ) ) ;
} ;
Suite . prototype . onException = function ( ) {
if ( arguments [ 0 ] instanceof j$ . errors . ExpectationFailed ) {
return ;
}
if ( isAfterAll ( this . children ) ) {
var data = {
matcherName : '' ,
passed : false ,
expected : '' ,
actual : '' ,
error : arguments [ 0 ]
} ;
this . result . failedExpectations . push ( this . expectationResultFactory ( data ) ) ;
} else {
for ( var i = 0 ; i < this . children . length ; i ++ ) {
var child = this . children [ i ] ;
child . onException . apply ( child , arguments ) ;
}
}
} ;
Suite . prototype . addExpectationResult = function ( ) {
if ( isAfterAll ( this . children ) && isFailure ( arguments ) ) {
var data = arguments [ 1 ] ;
this . result . failedExpectations . push ( this . expectationResultFactory ( data ) ) ;
if ( this . throwOnExpectationFailure ) {
throw new j$ . errors . ExpectationFailed ( ) ;
}
} else {
for ( var i = 0 ; i < this . children . length ; i ++ ) {
var child = this . children [ i ] ;
try {
child . addExpectationResult . apply ( child , arguments ) ;
} catch ( e ) {
// keep going
}
}
}
} ;
function isAfterAll ( children ) {
return children && children [ 0 ] . result . status ;
}
function isFailure ( args ) {
return ! args [ 0 ] ;
}
function clone ( obj ) {
var clonedObj = { } ;
for ( var prop in obj ) {
if ( obj . hasOwnProperty ( prop ) ) {
clonedObj [ prop ] = obj [ prop ] ;
}
}
return clonedObj ;
}
return Suite ;
} ;
if ( typeof window == void 0 && typeof exports == 'object' ) {
exports . Suite = jasmineRequire . Suite ;
}
getJasmineRequireObj ( ) . Timer = function ( ) {
var defaultNow = ( function ( Date ) {
return function ( ) { return new Date ( ) . getTime ( ) ; } ;
} ) ( Date ) ;
function Timer ( options ) {
options = options || { } ;
var now = options . now || defaultNow ,
startTime ;
this . start = function ( ) {
startTime = now ( ) ;
} ;
this . elapsed = function ( ) {
return now ( ) - startTime ;
} ;
}
return Timer ;
} ;
getJasmineRequireObj ( ) . TreeProcessor = function ( ) {
function TreeProcessor ( attrs ) {
var tree = attrs . tree ,
runnableIds = attrs . runnableIds ,
queueRunnerFactory = attrs . queueRunnerFactory ,
nodeStart = attrs . nodeStart || function ( ) { } ,
nodeComplete = attrs . nodeComplete || function ( ) { } ,
orderChildren = attrs . orderChildren || function ( node ) { return node . children ; } ,
stats = { valid : true } ,
processed = false ,
defaultMin = Infinity ,
defaultMax = 1 - Infinity ;
this . processTree = function ( ) {
processNode ( tree , false ) ;
processed = true ;
return stats ;
} ;
this . execute = function ( done ) {
if ( ! processed ) {
this . processTree ( ) ;
}
if ( ! stats . valid ) {
throw 'invalid order' ;
}
var childFns = wrapChildren ( tree , 0 ) ;
queueRunnerFactory ( {
queueableFns : childFns ,
userContext : tree . sharedUserContext ( ) ,
onException : function ( ) {
tree . onException . apply ( tree , arguments ) ;
} ,
onComplete : done
} ) ;
} ;
function runnableIndex ( id ) {
for ( var i = 0 ; i < runnableIds . length ; i ++ ) {
if ( runnableIds [ i ] === id ) {
return i ;
}
}
}
function processNode ( node , parentEnabled ) {
var executableIndex = runnableIndex ( node . id ) ;
if ( executableIndex !== undefined ) {
parentEnabled = true ;
}
parentEnabled = parentEnabled && node . isExecutable ( ) ;
if ( ! node . children ) {
stats [ node . id ] = {
executable : parentEnabled && node . isExecutable ( ) ,
segments : [ {
index : 0 ,
owner : node ,
nodes : [ node ] ,
min : startingMin ( executableIndex ) ,
max : startingMax ( executableIndex )
} ]
} ;
} else {
var hasExecutableChild = false ;
var orderedChildren = orderChildren ( node ) ;
for ( var i = 0 ; i < orderedChildren . length ; i ++ ) {
var child = orderedChildren [ i ] ;
processNode ( child , parentEnabled ) ;
if ( ! stats . valid ) {
return ;
}
var childStats = stats [ child . id ] ;
hasExecutableChild = hasExecutableChild || childStats . executable ;
}
stats [ node . id ] = {
executable : hasExecutableChild
} ;
segmentChildren ( node , orderedChildren , stats [ node . id ] , executableIndex ) ;
if ( ! node . canBeReentered ( ) && stats [ node . id ] . segments . length > 1 ) {
stats = { valid : false } ;
}
}
}
function startingMin ( executableIndex ) {
return executableIndex === undefined ? defaultMin : executableIndex ;
}
function startingMax ( executableIndex ) {
return executableIndex === undefined ? defaultMax : executableIndex ;
}
function segmentChildren ( node , orderedChildren , nodeStats , executableIndex ) {
var currentSegment = { index : 0 , owner : node , nodes : [ ] , min : startingMin ( executableIndex ) , max : startingMax ( executableIndex ) } ,
result = [ currentSegment ] ,
lastMax = defaultMax ,
orderedChildSegments = orderChildSegments ( orderedChildren ) ;
function isSegmentBoundary ( minIndex ) {
return lastMax !== defaultMax && minIndex !== defaultMin && lastMax < minIndex - 1 ;
}
for ( var i = 0 ; i < orderedChildSegments . length ; i ++ ) {
var childSegment = orderedChildSegments [ i ] ,
maxIndex = childSegment . max ,
minIndex = childSegment . min ;
if ( isSegmentBoundary ( minIndex ) ) {
currentSegment = { index : result . length , owner : node , nodes : [ ] , min : defaultMin , max : defaultMax } ;
result . push ( currentSegment ) ;
}
currentSegment . nodes . push ( childSegment ) ;
currentSegment . min = Math . min ( currentSegment . min , minIndex ) ;
currentSegment . max = Math . max ( currentSegment . max , maxIndex ) ;
lastMax = maxIndex ;
}
nodeStats . segments = result ;
}
function orderChildSegments ( children ) {
var specifiedOrder = [ ] ,
unspecifiedOrder = [ ] ;
for ( var i = 0 ; i < children . length ; i ++ ) {
var child = children [ i ] ,
segments = stats [ child . id ] . segments ;
for ( var j = 0 ; j < segments . length ; j ++ ) {
var seg = segments [ j ] ;
if ( seg . min === defaultMin ) {
unspecifiedOrder . push ( seg ) ;
} else {
specifiedOrder . push ( seg ) ;
}
}
}
specifiedOrder . sort ( function ( a , b ) {
return a . min - b . min ;
} ) ;
return specifiedOrder . concat ( unspecifiedOrder ) ;
}
function executeNode ( node , segmentNumber ) {
if ( node . children ) {
return {
fn : function ( done ) {
nodeStart ( node ) ;
queueRunnerFactory ( {
onComplete : function ( ) {
nodeComplete ( node , node . getResult ( ) ) ;
done ( ) ;
} ,
queueableFns : wrapChildren ( node , segmentNumber ) ,
userContext : node . sharedUserContext ( ) ,
onException : function ( ) {
node . onException . apply ( node , arguments ) ;
}
} ) ;
}
} ;
} else {
return {
fn : function ( done ) { node . execute ( done , stats [ node . id ] . executable ) ; }
} ;
}
}
function wrapChildren ( node , segmentNumber ) {
var result = [ ] ,
segmentChildren = stats [ node . id ] . segments [ segmentNumber ] . nodes ;
for ( var i = 0 ; i < segmentChildren . length ; i ++ ) {
result . push ( executeNode ( segmentChildren [ i ] . owner , segmentChildren [ i ] . index ) ) ;
}
if ( ! stats [ node . id ] . executable ) {
return result ;
}
return node . beforeAllFns . concat ( result ) . concat ( node . afterAllFns ) ;
}
}
return TreeProcessor ;
} ;
getJasmineRequireObj ( ) . Any = function ( j$ ) {
function Any ( expectedObject ) {
if ( typeof expectedObject === 'undefined' ) {
throw new TypeError (
'jasmine.any() expects to be passed a constructor function. ' +
'Please pass one or use jasmine.anything() to match any object.'
) ;
}
this . expectedObject = expectedObject ;
}
Any . prototype . asymmetricMatch = function ( other ) {
if ( this . expectedObject == String ) {
return typeof other == 'string' || other instanceof String ;
}
if ( this . expectedObject == Number ) {
return typeof other == 'number' || other instanceof Number ;
}
if ( this . expectedObject == Function ) {
return typeof other == 'function' || other instanceof Function ;
}
if ( this . expectedObject == Object ) {
return typeof other == 'object' ;
}
if ( this . expectedObject == Boolean ) {
return typeof other == 'boolean' ;
}
return other instanceof this . expectedObject ;
} ;
Any . prototype . jasmineToString = function ( ) {
return '<jasmine.any(' + j$ . fnNameFor ( this . expectedObject ) + ')>' ;
} ;
2014-06-05 19:55:49 -04:00
2016-01-19 17:57:58 -05:00
return Any ;
2014-06-05 19:55:49 -04:00
} ;
2016-01-19 17:57:58 -05:00
getJasmineRequireObj ( ) . Anything = function ( j$ ) {
2014-06-05 19:55:49 -04:00
2016-01-19 17:57:58 -05:00
function Anything ( ) { }
2014-06-05 19:55:49 -04:00
2016-01-19 17:57:58 -05:00
Anything . prototype . asymmetricMatch = function ( other ) {
return ! j$ . util . isUndefined ( other ) && other !== null ;
} ;
2014-06-05 19:55:49 -04:00
2016-01-19 17:57:58 -05:00
Anything . prototype . jasmineToString = function ( ) {
return '<jasmine.anything>' ;
} ;
return Anything ;
} ;
getJasmineRequireObj ( ) . ArrayContaining = function ( j$ ) {
function ArrayContaining ( sample ) {
this . sample = sample ;
2014-06-05 19:55:49 -04:00
}
2016-01-19 17:57:58 -05:00
ArrayContaining . prototype . asymmetricMatch = function ( other ) {
var className = Object . prototype . toString . call ( this . sample ) ;
if ( className !== '[object Array]' ) { throw new Error ( 'You must provide an array to arrayContaining, not \'' + this . sample + '\'.' ) ; }
for ( var i = 0 ; i < this . sample . length ; i ++ ) {
var item = this . sample [ i ] ;
if ( ! j$ . matchersUtil . contains ( other , item ) ) {
return false ;
2014-06-05 19:55:49 -04:00
}
}
2016-01-19 17:57:58 -05:00
return true ;
2014-06-05 19:55:49 -04:00
} ;
2016-01-19 17:57:58 -05:00
ArrayContaining . prototype . jasmineToString = function ( ) {
return '<jasmine.arrayContaining(' + jasmine . pp ( this . sample ) + ')>' ;
2014-06-05 19:55:49 -04:00
} ;
2016-01-19 17:57:58 -05:00
return ArrayContaining ;
} ;
2014-06-05 19:55:49 -04:00
2016-01-19 17:57:58 -05:00
getJasmineRequireObj ( ) . ObjectContaining = function ( j$ ) {
2014-06-05 19:55:49 -04:00
2016-01-19 17:57:58 -05:00
function ObjectContaining ( sample ) {
this . sample = sample ;
}
function getPrototype ( obj ) {
if ( Object . getPrototypeOf ) {
return Object . getPrototypeOf ( obj ) ;
}
if ( obj . constructor . prototype == obj ) {
return null ;
2014-06-05 19:55:49 -04:00
}
2016-01-19 17:57:58 -05:00
return obj . constructor . prototype ;
}
2014-06-05 19:55:49 -04:00
2016-01-19 17:57:58 -05:00
function hasProperty ( obj , property ) {
if ( ! obj ) {
return false ;
2014-06-05 19:55:49 -04:00
}
2016-01-19 17:57:58 -05:00
if ( Object . prototype . hasOwnProperty . call ( obj , property ) ) {
return true ;
}
2014-06-05 19:55:49 -04:00
2016-01-19 17:57:58 -05:00
return hasProperty ( getPrototype ( obj ) , property ) ;
}
2014-06-05 19:55:49 -04:00
2016-01-19 17:57:58 -05:00
ObjectContaining . prototype . asymmetricMatch = function ( other ) {
if ( typeof ( this . sample ) !== 'object' ) { throw new Error ( 'You must provide an object to objectContaining, not \'' + this . sample + '\'.' ) ; }
2014-06-05 19:55:49 -04:00
2016-01-19 17:57:58 -05:00
for ( var property in this . sample ) {
if ( ! hasProperty ( other , property ) ||
! j$ . matchersUtil . equals ( this . sample [ property ] , other [ property ] ) ) {
return false ;
2014-06-05 19:55:49 -04:00
}
}
2016-01-19 17:57:58 -05:00
return true ;
2014-06-05 19:55:49 -04:00
} ;
2016-01-19 17:57:58 -05:00
ObjectContaining . prototype . jasmineToString = function ( ) {
return '<jasmine.objectContaining(' + j$ . pp ( this . sample ) + ')>' ;
} ;
return ObjectContaining ;
2014-06-05 19:55:49 -04:00
} ;
2016-01-19 17:57:58 -05:00
getJasmineRequireObj ( ) . StringMatching = function ( j$ ) {
2014-06-05 19:55:49 -04:00
2016-01-19 17:57:58 -05:00
function StringMatching ( expected ) {
if ( ! j$ . isString _ ( expected ) && ! j$ . isA _ ( 'RegExp' , expected ) ) {
throw new Error ( 'Expected is not a String or a RegExp' ) ;
}
2014-06-05 19:55:49 -04:00
2016-01-19 17:57:58 -05:00
this . regexp = new RegExp ( expected ) ;
}
2014-06-05 19:55:49 -04:00
2016-01-19 17:57:58 -05:00
StringMatching . prototype . asymmetricMatch = function ( other ) {
return this . regexp . test ( other ) ;
} ;
2014-06-05 19:55:49 -04:00
2016-01-19 17:57:58 -05:00
StringMatching . prototype . jasmineToString = function ( ) {
return '<jasmine.stringMatching(' + this . regexp + ')>' ;
} ;
2014-06-05 19:55:49 -04:00
2016-01-19 17:57:58 -05:00
return StringMatching ;
2014-06-05 19:55:49 -04:00
} ;
2016-01-19 17:57:58 -05:00
getJasmineRequireObj ( ) . errors = function ( ) {
function ExpectationFailed ( ) { }
ExpectationFailed . prototype = new Error ( ) ;
ExpectationFailed . prototype . constructor = ExpectationFailed ;
return {
ExpectationFailed : ExpectationFailed
} ;
} ;
2014-06-05 19:55:49 -04:00
getJasmineRequireObj ( ) . matchersUtil = function ( j$ ) {
// TODO: what to do about jasmine.pp not being inject? move to JSON.stringify? gut PrettyPrinter?
return {
equals : function ( a , b , customTesters ) {
customTesters = customTesters || [ ] ;
return eq ( a , b , [ ] , [ ] , customTesters ) ;
} ,
contains : function ( haystack , needle , customTesters ) {
customTesters = customTesters || [ ] ;
2016-01-19 17:57:58 -05:00
if ( ( Object . prototype . toString . apply ( haystack ) === '[object Array]' ) ||
( ! ! haystack && ! haystack . indexOf ) )
{
2014-06-05 19:55:49 -04:00
for ( var i = 0 ; i < haystack . length ; i ++ ) {
if ( eq ( haystack [ i ] , needle , [ ] , [ ] , customTesters ) ) {
return true ;
}
}
return false ;
}
2016-01-19 17:57:58 -05:00
return ! ! haystack && haystack . indexOf ( needle ) >= 0 ;
2014-06-05 19:55:49 -04:00
} ,
buildFailureMessage : function ( ) {
var args = Array . prototype . slice . call ( arguments , 0 ) ,
matcherName = args [ 0 ] ,
isNot = args [ 1 ] ,
actual = args [ 2 ] ,
expected = args . slice ( 3 ) ,
englishyPredicate = matcherName . replace ( /[A-Z]/g , function ( s ) { return ' ' + s . toLowerCase ( ) ; } ) ;
2016-01-19 17:57:58 -05:00
var message = 'Expected ' +
2014-06-05 19:55:49 -04:00
j$ . pp ( actual ) +
2016-01-19 17:57:58 -05:00
( isNot ? ' not ' : ' ' ) +
2014-06-05 19:55:49 -04:00
englishyPredicate ;
if ( expected . length > 0 ) {
for ( var i = 0 ; i < expected . length ; i ++ ) {
if ( i > 0 ) {
2016-01-19 17:57:58 -05:00
message += ',' ;
2014-06-05 19:55:49 -04:00
}
2016-01-19 17:57:58 -05:00
message += ' ' + j$ . pp ( expected [ i ] ) ;
2014-06-05 19:55:49 -04:00
}
}
2016-01-19 17:57:58 -05:00
return message + '.' ;
2014-06-05 19:55:49 -04:00
}
} ;
2016-01-19 17:57:58 -05:00
function isAsymmetric ( obj ) {
return obj && j$ . isA _ ( 'Function' , obj . asymmetricMatch ) ;
}
function asymmetricMatch ( a , b ) {
var asymmetricA = isAsymmetric ( a ) ,
asymmetricB = isAsymmetric ( b ) ;
if ( asymmetricA && asymmetricB ) {
return undefined ;
}
if ( asymmetricA ) {
return a . asymmetricMatch ( b ) ;
}
if ( asymmetricB ) {
return b . asymmetricMatch ( a ) ;
}
}
2014-06-05 19:55:49 -04:00
// Equality function lovingly adapted from isEqual in
// [Underscore](http://underscorejs.org)
function eq ( a , b , aStack , bStack , customTesters ) {
var result = true ;
2016-01-19 17:57:58 -05:00
var asymmetricResult = asymmetricMatch ( a , b ) ;
if ( ! j$ . util . isUndefined ( asymmetricResult ) ) {
return asymmetricResult ;
}
2014-06-05 19:55:49 -04:00
for ( var i = 0 ; i < customTesters . length ; i ++ ) {
var customTesterResult = customTesters [ i ] ( a , b ) ;
if ( ! j$ . util . isUndefined ( customTesterResult ) ) {
return customTesterResult ;
}
}
if ( a instanceof Error && b instanceof Error ) {
return a . message == b . message ;
}
// Identical objects are equal. `0 === -0`, but they aren't identical.
// See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal).
if ( a === b ) { return a !== 0 || 1 / a == 1 / b ; }
// A strict comparison is necessary because `null == undefined`.
if ( a === null || b === null ) { return a === b ; }
var className = Object . prototype . toString . call ( a ) ;
if ( className != Object . prototype . toString . call ( b ) ) { return false ; }
switch ( className ) {
// Strings, numbers, dates, and booleans are compared by value.
case '[object String]' :
// Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is
// equivalent to `new String("5")`.
return a == String ( b ) ;
case '[object Number]' :
// `NaN`s are equivalent, but non-reflexive. An `egal` comparison is performed for
// other numeric values.
return a != + a ? b != + b : ( a === 0 ? 1 / a == 1 / b : a == + b ) ;
case '[object Date]' :
case '[object Boolean]' :
// Coerce dates and booleans to numeric primitive values. Dates are compared by their
// millisecond representations. Note that invalid dates with millisecond representations
// of `NaN` are not equivalent.
return + a == + b ;
// RegExps are compared by their source patterns and flags.
case '[object RegExp]' :
return a . source == b . source &&
a . global == b . global &&
a . multiline == b . multiline &&
a . ignoreCase == b . ignoreCase ;
}
if ( typeof a != 'object' || typeof b != 'object' ) { return false ; }
2016-01-19 17:57:58 -05:00
var aIsDomNode = j$ . isDomNode ( a ) ;
var bIsDomNode = j$ . isDomNode ( b ) ;
if ( aIsDomNode && bIsDomNode ) {
// At first try to use DOM3 method isEqualNode
if ( a . isEqualNode ) {
return a . isEqualNode ( b ) ;
}
// IE8 doesn't support isEqualNode, try to use outerHTML && innerText
var aIsElement = a instanceof Element ;
var bIsElement = b instanceof Element ;
if ( aIsElement && bIsElement ) {
return a . outerHTML == b . outerHTML ;
}
if ( aIsElement || bIsElement ) {
return false ;
}
return a . innerText == b . innerText && a . textContent == b . textContent ;
}
if ( aIsDomNode || bIsDomNode ) {
return false ;
}
2014-06-05 19:55:49 -04:00
// Assume equality for cyclic structures. The algorithm for detecting cyclic
// structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`.
var length = aStack . length ;
while ( length -- ) {
// Linear search. Performance is inversely proportional to the number of
// unique nested structures.
if ( aStack [ length ] == a ) { return bStack [ length ] == b ; }
}
// Add the first object to the stack of traversed objects.
aStack . push ( a ) ;
bStack . push ( b ) ;
var size = 0 ;
// Recursively compare objects and arrays.
2016-01-19 17:57:58 -05:00
// Compare array lengths to determine if a deep comparison is necessary.
if ( className == '[object Array]' && a . length !== b . length ) {
result = false ;
}
if ( result ) {
2014-06-05 19:55:49 -04:00
// Objects with different constructors are not equivalent, but `Object`s
2016-01-19 17:57:58 -05:00
// or `Array`s from different frames are.
if ( className !== '[object Array]' ) {
var aCtor = a . constructor , bCtor = b . constructor ;
if ( aCtor !== bCtor && ! ( isFunction ( aCtor ) && aCtor instanceof aCtor &&
isFunction ( bCtor ) && bCtor instanceof bCtor ) ) {
return false ;
}
2014-06-05 19:55:49 -04:00
}
// Deep compare objects.
for ( var key in a ) {
if ( has ( a , key ) ) {
// Count the expected number of properties.
size ++ ;
// Deep compare each member.
if ( ! ( result = has ( b , key ) && eq ( a [ key ] , b [ key ] , aStack , bStack , customTesters ) ) ) { break ; }
}
}
// Ensure that both objects contain the same number of properties.
if ( result ) {
for ( key in b ) {
if ( has ( b , key ) && ! ( size -- ) ) { break ; }
}
result = ! size ;
}
}
// Remove the first object from the stack of traversed objects.
aStack . pop ( ) ;
bStack . pop ( ) ;
return result ;
function has ( obj , key ) {
2016-01-19 17:57:58 -05:00
return Object . prototype . hasOwnProperty . call ( obj , key ) ;
2014-06-05 19:55:49 -04:00
}
function isFunction ( obj ) {
return typeof obj === 'function' ;
}
}
} ;
getJasmineRequireObj ( ) . toBe = function ( ) {
function toBe ( ) {
return {
compare : function ( actual , expected ) {
return {
pass : actual === expected
} ;
}
} ;
}
return toBe ;
} ;
getJasmineRequireObj ( ) . toBeCloseTo = function ( ) {
function toBeCloseTo ( ) {
return {
compare : function ( actual , expected , precision ) {
if ( precision !== 0 ) {
precision = precision || 2 ;
}
return {
pass : Math . abs ( expected - actual ) < ( Math . pow ( 10 , - precision ) / 2 )
} ;
}
} ;
}
return toBeCloseTo ;
} ;
getJasmineRequireObj ( ) . toBeDefined = function ( ) {
function toBeDefined ( ) {
return {
compare : function ( actual ) {
return {
pass : ( void 0 !== actual )
} ;
}
} ;
}
return toBeDefined ;
} ;
getJasmineRequireObj ( ) . toBeFalsy = function ( ) {
function toBeFalsy ( ) {
return {
compare : function ( actual ) {
return {
pass : ! ! ! actual
} ;
}
} ;
}
return toBeFalsy ;
} ;
getJasmineRequireObj ( ) . toBeGreaterThan = function ( ) {
function toBeGreaterThan ( ) {
return {
compare : function ( actual , expected ) {
return {
pass : actual > expected
} ;
}
} ;
}
return toBeGreaterThan ;
} ;
getJasmineRequireObj ( ) . toBeLessThan = function ( ) {
function toBeLessThan ( ) {
return {
compare : function ( actual , expected ) {
return {
pass : actual < expected
} ;
}
} ;
}
return toBeLessThan ;
} ;
getJasmineRequireObj ( ) . toBeNaN = function ( j$ ) {
function toBeNaN ( ) {
return {
compare : function ( actual ) {
var result = {
pass : ( actual !== actual )
} ;
if ( result . pass ) {
2016-01-19 17:57:58 -05:00
result . message = 'Expected actual not to be NaN.' ;
2014-06-05 19:55:49 -04:00
} else {
2016-01-19 17:57:58 -05:00
result . message = function ( ) { return 'Expected ' + j$ . pp ( actual ) + ' to be NaN.' ; } ;
2014-06-05 19:55:49 -04:00
}
return result ;
}
} ;
}
return toBeNaN ;
} ;
getJasmineRequireObj ( ) . toBeNull = function ( ) {
function toBeNull ( ) {
return {
compare : function ( actual ) {
return {
pass : actual === null
} ;
}
} ;
}
return toBeNull ;
} ;
getJasmineRequireObj ( ) . toBeTruthy = function ( ) {
function toBeTruthy ( ) {
return {
compare : function ( actual ) {
return {
pass : ! ! actual
} ;
}
} ;
}
return toBeTruthy ;
} ;
getJasmineRequireObj ( ) . toBeUndefined = function ( ) {
function toBeUndefined ( ) {
return {
compare : function ( actual ) {
return {
pass : void 0 === actual
} ;
}
} ;
}
return toBeUndefined ;
} ;
getJasmineRequireObj ( ) . toContain = function ( ) {
function toContain ( util , customEqualityTesters ) {
customEqualityTesters = customEqualityTesters || [ ] ;
return {
compare : function ( actual , expected ) {
return {
pass : util . contains ( actual , expected , customEqualityTesters )
} ;
}
} ;
}
return toContain ;
} ;
getJasmineRequireObj ( ) . toEqual = function ( ) {
function toEqual ( util , customEqualityTesters ) {
customEqualityTesters = customEqualityTesters || [ ] ;
return {
compare : function ( actual , expected ) {
var result = {
pass : false
} ;
result . pass = util . equals ( actual , expected , customEqualityTesters ) ;
return result ;
}
} ;
}
return toEqual ;
} ;
getJasmineRequireObj ( ) . toHaveBeenCalled = function ( j$ ) {
function toHaveBeenCalled ( ) {
return {
compare : function ( actual ) {
var result = { } ;
if ( ! j$ . isSpy ( actual ) ) {
throw new Error ( 'Expected a spy, but got ' + j$ . pp ( actual ) + '.' ) ;
}
if ( arguments . length > 1 ) {
throw new Error ( 'toHaveBeenCalled does not take arguments, use toHaveBeenCalledWith' ) ;
}
result . pass = actual . calls . any ( ) ;
result . message = result . pass ?
2016-01-19 17:57:58 -05:00
'Expected spy ' + actual . and . identity ( ) + ' not to have been called.' :
'Expected spy ' + actual . and . identity ( ) + ' to have been called.' ;
2014-06-05 19:55:49 -04:00
return result ;
}
} ;
}
return toHaveBeenCalled ;
} ;
2016-01-19 17:57:58 -05:00
getJasmineRequireObj ( ) . toHaveBeenCalledTimes = function ( j$ ) {
function toHaveBeenCalledTimes ( ) {
return {
compare : function ( actual , expected ) {
if ( ! j$ . isSpy ( actual ) ) {
throw new Error ( 'Expected a spy, but got ' + j$ . pp ( actual ) + '.' ) ;
}
var args = Array . prototype . slice . call ( arguments , 0 ) ,
result = { pass : false } ;
if ( ! expected ) {
throw new Error ( 'Expected times failed is required as an argument.' ) ;
}
actual = args [ 0 ] ;
var calls = actual . calls . count ( ) ;
var timesMessage = expected === 1 ? 'once' : expected + ' times' ;
result . pass = calls === expected ;
result . message = result . pass ?
'Expected spy ' + actual . and . identity ( ) + ' not to have been called ' + timesMessage + '. It was called ' + calls + ' times.' :
'Expected spy ' + actual . and . identity ( ) + ' to have been called ' + timesMessage + '. It was called ' + calls + ' times.' ;
return result ;
}
} ;
}
return toHaveBeenCalledTimes ;
} ;
2014-06-05 19:55:49 -04:00
getJasmineRequireObj ( ) . toHaveBeenCalledWith = function ( j$ ) {
2016-01-19 17:57:58 -05:00
function toHaveBeenCalledWith ( util , customEqualityTesters ) {
2014-06-05 19:55:49 -04:00
return {
compare : function ( ) {
var args = Array . prototype . slice . call ( arguments , 0 ) ,
actual = args [ 0 ] ,
expectedArgs = args . slice ( 1 ) ,
result = { pass : false } ;
if ( ! j$ . isSpy ( actual ) ) {
throw new Error ( 'Expected a spy, but got ' + j$ . pp ( actual ) + '.' ) ;
}
if ( ! actual . calls . any ( ) ) {
2016-01-19 17:57:58 -05:00
result . message = function ( ) { return 'Expected spy ' + actual . and . identity ( ) + ' to have been called with ' + j$ . pp ( expectedArgs ) + ' but it was never called.' ; } ;
2014-06-05 19:55:49 -04:00
return result ;
}
2016-01-19 17:57:58 -05:00
if ( util . contains ( actual . calls . allArgs ( ) , expectedArgs , customEqualityTesters ) ) {
2014-06-05 19:55:49 -04:00
result . pass = true ;
2016-01-19 17:57:58 -05:00
result . message = function ( ) { return 'Expected spy ' + actual . and . identity ( ) + ' not to have been called with ' + j$ . pp ( expectedArgs ) + ' but it was.' ; } ;
2014-06-05 19:55:49 -04:00
} else {
2016-01-19 17:57:58 -05:00
result . message = function ( ) { return 'Expected spy ' + actual . and . identity ( ) + ' to have been called with ' + j$ . pp ( expectedArgs ) + ' but actual calls were ' + j$ . pp ( actual . calls . allArgs ( ) ) . replace ( /^\[ | \]$/g , '' ) + '.' ; } ;
2014-06-05 19:55:49 -04:00
}
return result ;
}
} ;
}
return toHaveBeenCalledWith ;
} ;
2016-01-19 17:57:58 -05:00
getJasmineRequireObj ( ) . toMatch = function ( j$ ) {
2014-06-05 19:55:49 -04:00
function toMatch ( ) {
return {
compare : function ( actual , expected ) {
2016-01-19 17:57:58 -05:00
if ( ! j$ . isString _ ( expected ) && ! j$ . isA _ ( 'RegExp' , expected ) ) {
throw new Error ( 'Expected is not a String or a RegExp' ) ;
}
2014-06-05 19:55:49 -04:00
var regexp = new RegExp ( expected ) ;
return {
pass : regexp . test ( actual )
} ;
}
} ;
}
return toMatch ;
} ;
getJasmineRequireObj ( ) . toThrow = function ( j$ ) {
function toThrow ( util ) {
return {
compare : function ( actual , expected ) {
var result = { pass : false } ,
threw = false ,
thrown ;
2016-01-19 17:57:58 -05:00
if ( typeof actual != 'function' ) {
throw new Error ( 'Actual is not a Function' ) ;
2014-06-05 19:55:49 -04:00
}
try {
actual ( ) ;
} catch ( e ) {
threw = true ;
thrown = e ;
}
if ( ! threw ) {
2016-01-19 17:57:58 -05:00
result . message = 'Expected function to throw an exception.' ;
2014-06-05 19:55:49 -04:00
return result ;
}
if ( arguments . length == 1 ) {
result . pass = true ;
2016-01-19 17:57:58 -05:00
result . message = function ( ) { return 'Expected function not to throw, but it threw ' + j$ . pp ( thrown ) + '.' ; } ;
2014-06-05 19:55:49 -04:00
return result ;
}
if ( util . equals ( thrown , expected ) ) {
result . pass = true ;
2016-01-19 17:57:58 -05:00
result . message = function ( ) { return 'Expected function not to throw ' + j$ . pp ( expected ) + '.' ; } ;
2014-06-05 19:55:49 -04:00
} else {
2016-01-19 17:57:58 -05:00
result . message = function ( ) { return 'Expected function to throw ' + j$ . pp ( expected ) + ', but it threw ' + j$ . pp ( thrown ) + '.' ; } ;
2014-06-05 19:55:49 -04:00
}
return result ;
}
} ;
}
return toThrow ;
} ;
getJasmineRequireObj ( ) . toThrowError = function ( j$ ) {
2016-01-19 17:57:58 -05:00
function toThrowError ( ) {
2014-06-05 19:55:49 -04:00
return {
compare : function ( actual ) {
var threw = false ,
2016-01-19 17:57:58 -05:00
pass = { pass : true } ,
fail = { pass : false } ,
thrown ;
if ( typeof actual != 'function' ) {
throw new Error ( 'Actual is not a Function' ) ;
2014-06-05 19:55:49 -04:00
}
2016-01-19 17:57:58 -05:00
var errorMatcher = getMatcher . apply ( null , arguments ) ;
2014-06-05 19:55:49 -04:00
try {
actual ( ) ;
} catch ( e ) {
threw = true ;
thrown = e ;
}
if ( ! threw ) {
2016-01-19 17:57:58 -05:00
fail . message = 'Expected function to throw an Error.' ;
return fail ;
2014-06-05 19:55:49 -04:00
}
if ( ! ( thrown instanceof Error ) ) {
2016-01-19 17:57:58 -05:00
fail . message = function ( ) { return 'Expected function to throw an Error, but it threw ' + j$ . pp ( thrown ) + '.' ; } ;
return fail ;
2014-06-05 19:55:49 -04:00
}
2016-01-19 17:57:58 -05:00
if ( errorMatcher . hasNoSpecifics ( ) ) {
pass . message = 'Expected function not to throw an Error, but it threw ' + j$ . fnNameFor ( thrown ) + '.' ;
return pass ;
2014-06-05 19:55:49 -04:00
}
2016-01-19 17:57:58 -05:00
if ( errorMatcher . matches ( thrown ) ) {
pass . message = function ( ) {
return 'Expected function not to throw ' + errorMatcher . errorTypeDescription + errorMatcher . messageDescription ( ) + '.' ;
} ;
return pass ;
} else {
fail . message = function ( ) {
return 'Expected function to throw ' + errorMatcher . errorTypeDescription + errorMatcher . messageDescription ( ) +
', but it threw ' + errorMatcher . thrownDescription ( thrown ) + '.' ;
} ;
return fail ;
2014-06-05 19:55:49 -04:00
}
2016-01-19 17:57:58 -05:00
}
} ;
2014-06-05 19:55:49 -04:00
2016-01-19 17:57:58 -05:00
function getMatcher ( ) {
var expected = null ,
errorType = null ;
2014-06-05 19:55:49 -04:00
2016-01-19 17:57:58 -05:00
if ( arguments . length == 2 ) {
expected = arguments [ 1 ] ;
if ( isAnErrorType ( expected ) ) {
errorType = expected ;
expected = null ;
2014-06-05 19:55:49 -04:00
}
2016-01-19 17:57:58 -05:00
} else if ( arguments . length > 2 ) {
errorType = arguments [ 1 ] ;
expected = arguments [ 2 ] ;
if ( ! isAnErrorType ( errorType ) ) {
throw new Error ( 'Expected error type is not an Error.' ) ;
}
}
2014-06-05 19:55:49 -04:00
2016-01-19 17:57:58 -05:00
if ( expected && ! isStringOrRegExp ( expected ) ) {
2014-06-05 19:55:49 -04:00
if ( errorType ) {
2016-01-19 17:57:58 -05:00
throw new Error ( 'Expected error message is not a string or RegExp.' ) ;
} else {
throw new Error ( 'Expected is not an Error, string, or RegExp.' ) ;
2014-06-05 19:55:49 -04:00
}
2016-01-19 17:57:58 -05:00
}
2014-06-05 19:55:49 -04:00
2016-01-19 17:57:58 -05:00
function messageMatch ( message ) {
if ( typeof expected == 'string' ) {
return expected == message ;
} else {
return expected . test ( message ) ;
2014-06-05 19:55:49 -04:00
}
2016-01-19 17:57:58 -05:00
}
2014-06-05 19:55:49 -04:00
2016-01-19 17:57:58 -05:00
return {
errorTypeDescription : errorType ? j$ . fnNameFor ( errorType ) : 'an exception' ,
thrownDescription : function ( thrown ) {
var thrownName = errorType ? j$ . fnNameFor ( thrown . constructor ) : 'an exception' ,
thrownMessage = '' ;
if ( expected ) {
thrownMessage = ' with message ' + j$ . pp ( thrown . message ) ;
}
return thrownName + thrownMessage ;
} ,
messageDescription : function ( ) {
if ( expected === null ) {
return '' ;
} else if ( expected instanceof RegExp ) {
return ' with a message matching ' + j$ . pp ( expected ) ;
2014-06-05 19:55:49 -04:00
} else {
2016-01-19 17:57:58 -05:00
return ' with message ' + j$ . pp ( expected ) ;
2014-06-05 19:55:49 -04:00
}
2016-01-19 17:57:58 -05:00
} ,
hasNoSpecifics : function ( ) {
return expected === null && errorType === null ;
} ,
matches : function ( error ) {
return ( errorType === null || error instanceof errorType ) &&
( expected === null || messageMatch ( error . message ) ) ;
2014-06-05 19:55:49 -04:00
}
2016-01-19 17:57:58 -05:00
} ;
}
2014-06-05 19:55:49 -04:00
2016-01-19 17:57:58 -05:00
function isStringOrRegExp ( potential ) {
return potential instanceof RegExp || ( typeof potential == 'string' ) ;
}
2014-06-05 19:55:49 -04:00
2016-01-19 17:57:58 -05:00
function isAnErrorType ( type ) {
if ( typeof type !== 'function' ) {
return false ;
}
2014-06-05 19:55:49 -04:00
2016-01-19 17:57:58 -05:00
var Surrogate = function ( ) { } ;
Surrogate . prototype = type . prototype ;
return ( new Surrogate ( ) ) instanceof Error ;
}
}
2014-06-05 19:55:49 -04:00
2016-01-19 17:57:58 -05:00
return toThrowError ;
} ;
2014-06-05 19:55:49 -04:00
2016-01-19 17:57:58 -05:00
getJasmineRequireObj ( ) . interface = function ( jasmine , env ) {
var jasmineInterface = {
describe : function ( description , specDefinitions ) {
return env . describe ( description , specDefinitions ) ;
} ,
2014-06-05 19:55:49 -04:00
2016-01-19 17:57:58 -05:00
xdescribe : function ( description , specDefinitions ) {
return env . xdescribe ( description , specDefinitions ) ;
} ,
2014-06-05 19:55:49 -04:00
2016-01-19 17:57:58 -05:00
fdescribe : function ( description , specDefinitions ) {
return env . fdescribe ( description , specDefinitions ) ;
} ,
2014-06-05 19:55:49 -04:00
2016-01-19 17:57:58 -05:00
it : function ( ) {
return env . it . apply ( env , arguments ) ;
} ,
2014-06-05 19:55:49 -04:00
2016-01-19 17:57:58 -05:00
xit : function ( ) {
return env . xit . apply ( env , arguments ) ;
} ,
2014-06-05 19:55:49 -04:00
2016-01-19 17:57:58 -05:00
fit : function ( ) {
return env . fit . apply ( env , arguments ) ;
} ,
beforeEach : function ( ) {
return env . beforeEach . apply ( env , arguments ) ;
} ,
afterEach : function ( ) {
return env . afterEach . apply ( env , arguments ) ;
} ,
beforeAll : function ( ) {
return env . beforeAll . apply ( env , arguments ) ;
} ,
afterAll : function ( ) {
return env . afterAll . apply ( env , arguments ) ;
} ,
expect : function ( actual ) {
return env . expect ( actual ) ;
} ,
pending : function ( ) {
return env . pending . apply ( env , arguments ) ;
} ,
fail : function ( ) {
return env . fail . apply ( env , arguments ) ;
} ,
spyOn : function ( obj , methodName ) {
return env . spyOn ( obj , methodName ) ;
} ,
jsApiReporter : new jasmine . JsApiReporter ( {
timer : new jasmine . Timer ( )
} ) ,
jasmine : jasmine
} ;
jasmine . addCustomEqualityTester = function ( tester ) {
env . addCustomEqualityTester ( tester ) ;
} ;
jasmine . addMatchers = function ( matchers ) {
return env . addMatchers ( matchers ) ;
} ;
jasmine . clock = function ( ) {
return env . clock ;
} ;
return jasmineInterface ;
2014-06-05 19:55:49 -04:00
} ;
getJasmineRequireObj ( ) . version = function ( ) {
2016-01-19 17:57:58 -05:00
return '2.4.1' ;
} ;