2009-06-28 20:36:51 +00:00
/ * *
* Top level namespace for Jasmine , a lightweight JavaScript BDD / spec / testing framework .
2009-10-16 01:00:05 +00:00
*
2009-06-28 20:36:51 +00:00
* @ namespace
2009-06-16 14:13:45 +00:00
* /
var jasmine = { } ;
2009-06-28 20:36:51 +00:00
/ * *
* @ private
* /
2009-06-16 14:13:45 +00:00
jasmine . unimplementedMethod _ = function ( ) {
throw new Error ( "unimplemented method" ) ;
} ;
2009-10-06 05:36:10 +00:00
/ * *
* Large or small values here may result in slow test running & "Too much recursion" errors
2009-10-16 01:00:05 +00:00
*
2009-10-06 05:36:10 +00:00
* /
jasmine . UPDATE _INTERVAL = 250 ;
2009-06-28 20:36:51 +00:00
/ * *
* Allows for bound functions to be comapred . Internal use only .
*
* @ ignore
* @ private
* @ param base { Object } bound 'this' for the function
* @ param name { Function } function to find
* /
2009-06-16 14:13:45 +00:00
jasmine . bindOriginal _ = function ( base , name ) {
var original = base [ name ] ;
2009-11-01 04:47:11 +00:00
if ( original . apply ) {
return function ( ) {
2009-10-16 01:00:05 +00:00
return original . apply ( base , arguments ) ;
2009-11-01 04:47:11 +00:00
} ;
} else {
// IE support
return window [ name ] ;
}
2009-06-16 14:13:45 +00:00
} ;
jasmine . setTimeout = jasmine . bindOriginal _ ( window , 'setTimeout' ) ;
jasmine . clearTimeout = jasmine . bindOriginal _ ( window , 'clearTimeout' ) ;
jasmine . setInterval = jasmine . bindOriginal _ ( window , 'setInterval' ) ;
jasmine . clearInterval = jasmine . bindOriginal _ ( window , 'clearInterval' ) ;
jasmine . MessageResult = function ( text ) {
this . type = 'MessageResult' ;
this . text = text ;
this . trace = new Error ( ) ; // todo: test better
} ;
2009-10-30 00:03:24 +00:00
jasmine . ExpectationResult = function ( params ) {
2009-06-16 14:13:45 +00:00
this . type = 'ExpectationResult' ;
2009-10-30 00:03:24 +00:00
this . matcherName = params . matcherName ;
this . passed _ = params . passed ;
this . expected = params . expected ;
this . actual = params . actual ;
/** @deprecated */
this . details = params . details ;
this . message = this . passed _ ? 'Passed.' : params . message ;
this . trace = this . passed _ ? '' : new Error ( this . message ) ;
2009-06-16 14:13:45 +00:00
} ;
2009-08-19 15:50:56 +00:00
jasmine . ExpectationResult . prototype . passed = function ( ) {
return this . passed _ ;
} ;
2009-06-28 20:36:51 +00:00
/ * *
* Getter for the Jasmine environment . Ensures one gets created
* /
2009-06-16 14:13:45 +00:00
jasmine . getEnv = function ( ) {
return jasmine . currentEnv _ = jasmine . currentEnv _ || new jasmine . Env ( ) ;
} ;
2009-06-28 20:36:51 +00:00
/ * *
* @ ignore
* @ private
* @ param value
* @ returns { Boolean }
* /
2009-06-16 14:13:45 +00:00
jasmine . isArray _ = function ( value ) {
return value &&
2009-10-16 01:00:05 +00:00
typeof value === 'object' &&
typeof value . length === 'number' &&
typeof value . splice === 'function' &&
! ( value . propertyIsEnumerable ( 'length' ) ) ;
2009-06-16 14:13:45 +00:00
} ;
2009-06-28 20:36:51 +00:00
/ * *
* Pretty printer for expecations . Takes any object and turns it into a human - readable string .
*
* @ param value { Object } an object to be outputted
* @ returns { String }
* /
2009-06-16 14:13:45 +00:00
jasmine . pp = function ( value ) {
var stringPrettyPrinter = new jasmine . StringPrettyPrinter ( ) ;
stringPrettyPrinter . format ( value ) ;
return stringPrettyPrinter . string ;
} ;
2009-06-28 20:36:51 +00:00
/ * *
* Returns true if the object is a DOM Node .
*
* @ param { Object } obj object to check
* @ returns { Boolean }
* /
2009-06-16 14:13:45 +00:00
jasmine . isDomNode = function ( obj ) {
return obj [ 'nodeType' ] > 0 ;
} ;
2009-06-28 20:36:51 +00:00
/ * *
* Returns a matchable 'generic' object of the class type . For use in expecations of type when values don ' t matter .
*
* @ example
* // don't care about which function is passed in, as long as it's a function
* expect ( mySpy ) . wasCalledWith ( jasmine . any ( Function ) ) ;
*
* @ param { Class } clazz
* @ returns matchable object of the type clazz
* /
2009-06-16 14:13:45 +00:00
jasmine . any = function ( clazz ) {
return new jasmine . Matchers . Any ( clazz ) ;
} ;
2009-06-28 20:36:51 +00:00
/ * *
* Jasmine Spies are test doubles that can act as stubs , spies , fakes or when used in an expecation , mocks .
*
* Spies should be created in test setup , before expectations . They can then be checked , using the standard Jasmine
* expectation syntax . Spies can be checked if they were called or not and what the calling params were .
*
* A Spy has the following mehtod : wasCalled , callCount , mostRecentCall , and argsForCall ( see docs )
* Spies are torn down at the end of every spec .
*
* Note : Do < b > not < / b > c a l l n e w j a s m i n e . S p y ( ) d i r e c t l y - a s p y m u s t b e c r e a t e d u s i n g s p y O n , j a s m i n e . c r e a t e S p y o r j a s m i n e . c r e a t e S p y O b j .
2009-10-16 01:00:05 +00:00
*
2009-06-28 20:36:51 +00:00
* @ example
* // a stub
* var myStub = jasmine . createSpy ( 'myStub' ) ; // can be used anywhere
*
* // spy example
* var foo = {
* not : function ( bool ) { return ! bool ; }
* }
*
* // actual foo.not will not be called, execution stops
* spyOn ( foo , 'not' ) ;
// foo.not spied upon, execution will continue to implementation
* spyOn ( foo , 'not' ) . andCallThrough ( ) ;
*
* // fake example
* var foo = {
* not : function ( bool ) { return ! bool ; }
* }
*
* // foo.not(val) will return val
* spyOn ( foo , 'not' ) . andCallFake ( function ( value ) { return value ; } ) ;
*
* // mock example
* foo . not ( 7 == 7 ) ;
* expect ( foo . not ) . wasCalled ( ) ;
* expect ( foo . not ) . wasCalledWith ( true ) ;
*
* @ constructor
* @ see spyOn , jasmine . createSpy , jasmine . createSpyObj
* @ param { String } name
* /
jasmine . Spy = function ( name ) {
/ * *
* The name of the spy , if provided .
* /
this . identity = name || 'unknown' ;
/ * *
* Is this Object a spy ?
* /
this . isSpy = true ;
/ * *
* The acutal function this spy stubs .
* /
2009-10-16 01:00:05 +00:00
this . plan = function ( ) {
} ;
2009-06-28 20:36:51 +00:00
/ * *
* Tracking of the most recent call to the spy .
* @ example
* var mySpy = jasmine . createSpy ( 'foo' ) ;
* mySpy ( 1 , 2 ) ;
* mySpy . mostRecentCall . args = [ 1 , 2 ] ;
* /
this . mostRecentCall = { } ;
/ * *
* Holds arguments for each call to the spy , indexed by call count
* @ example
* var mySpy = jasmine . createSpy ( 'foo' ) ;
* mySpy ( 1 , 2 ) ;
* mySpy ( 7 , 8 ) ;
* mySpy . mostRecentCall . args = [ 7 , 8 ] ;
* mySpy . argsForCall [ 0 ] = [ 1 , 2 ] ;
* mySpy . argsForCall [ 1 ] = [ 7 , 8 ] ;
* /
this . argsForCall = [ ] ;
2009-10-13 21:48:09 +00:00
this . calls = [ ] ;
2009-06-28 20:36:51 +00:00
} ;
/ * *
* Tells a spy to call through to the actual implemenatation .
*
* @ example
* var foo = {
* bar : function ( ) { // do some stuff }
* }
2009-10-16 01:00:05 +00:00
*
2009-06-28 20:36:51 +00:00
* // defining a spy on an existing property: foo.bar
* spyOn ( foo , 'bar' ) . andCallThrough ( ) ;
* /
jasmine . Spy . prototype . andCallThrough = function ( ) {
this . plan = this . originalValue ;
return this ;
} ;
/ * *
* For setting the return value of a spy .
*
* @ example
* // defining a spy from scratch: foo() returns 'baz'
* var foo = jasmine . createSpy ( 'spy on foo' ) . andReturn ( 'baz' ) ;
*
* // defining a spy on an existing property: foo.bar() returns 'baz'
* spyOn ( foo , 'bar' ) . andReturn ( 'baz' ) ;
*
* @ param { Object } value
* /
jasmine . Spy . prototype . andReturn = function ( value ) {
this . plan = function ( ) {
return value ;
} ;
return this ;
} ;
/ * *
* For throwing an exception when a spy is called .
*
* @ example
* // defining a spy from scratch: foo() throws an exception w/ message 'ouch'
* var foo = jasmine . createSpy ( 'spy on foo' ) . andThrow ( 'baz' ) ;
*
* // defining a spy on an existing property: foo.bar() throws an exception w/ message 'ouch'
* spyOn ( foo , 'bar' ) . andThrow ( 'baz' ) ;
*
* @ param { String } exceptionMsg
* /
jasmine . Spy . prototype . andThrow = function ( exceptionMsg ) {
this . plan = function ( ) {
throw exceptionMsg ;
} ;
return this ;
} ;
/ * *
* Calls an alternate implementation when a spy is called .
*
* @ example
* var baz = function ( ) {
* // do some stuff, return something
* }
* // defining a spy from scratch: foo() calls the function baz
* var foo = jasmine . createSpy ( 'spy on foo' ) . andCall ( baz ) ;
*
* // defining a spy on an existing property: foo.bar() calls an anonymnous function
* spyOn ( foo , 'bar' ) . andCall ( function ( ) { return 'baz' ; } ) ;
*
* @ param { Function } fakeFunc
* /
jasmine . Spy . prototype . andCallFake = function ( fakeFunc ) {
this . plan = fakeFunc ;
return this ;
} ;
/ * *
* Resets all of a spy ' s the tracking variables so that it can be used again .
*
* @ example
* spyOn ( foo , 'bar' ) ;
*
* foo . bar ( ) ;
*
* expect ( foo . bar . callCount ) . toEqual ( 1 ) ;
*
* foo . bar . reset ( ) ;
*
* expect ( foo . bar . callCount ) . toEqual ( 0 ) ;
* /
jasmine . Spy . prototype . reset = function ( ) {
this . wasCalled = false ;
this . callCount = 0 ;
this . argsForCall = [ ] ;
2009-10-13 21:48:09 +00:00
this . calls = [ ] ;
2009-06-28 20:36:51 +00:00
this . mostRecentCall = { } ;
} ;
2009-06-16 14:13:45 +00:00
jasmine . createSpy = function ( name ) {
2009-06-28 20:36:51 +00:00
2009-06-16 14:13:45 +00:00
var spyObj = function ( ) {
spyObj . wasCalled = true ;
spyObj . callCount ++ ;
var args = jasmine . util . argsToArray ( arguments ) ;
2009-06-28 20:36:51 +00:00
spyObj . mostRecentCall . object = this ;
spyObj . mostRecentCall . args = args ;
2009-06-16 14:13:45 +00:00
spyObj . argsForCall . push ( args ) ;
2009-10-13 21:48:09 +00:00
spyObj . calls . push ( { object : this , args : args } ) ;
2009-06-16 14:13:45 +00:00
return spyObj . plan . apply ( this , arguments ) ;
} ;
2009-06-28 20:36:51 +00:00
var spy = new jasmine . Spy ( name ) ;
2009-10-16 01:00:05 +00:00
for ( var prop in spy ) {
2009-06-28 20:36:51 +00:00
spyObj [ prop ] = spy [ prop ] ;
}
2009-10-16 01:00:05 +00:00
2009-06-16 14:13:45 +00:00
spyObj . reset ( ) ;
return spyObj ;
} ;
2009-06-28 20:36:51 +00:00
/ * *
* Creates a more complicated spy : an Object that has every property a function that is a spy . Used for stubbing something
* large in one call .
*
* @ param { String } baseName name of spy class
* @ param { Array } methodNames array of names of methods to make spies
* /
2009-06-16 14:13:45 +00:00
jasmine . createSpyObj = function ( baseName , methodNames ) {
var obj = { } ;
for ( var i = 0 ; i < methodNames . length ; i ++ ) {
obj [ methodNames [ i ] ] = jasmine . createSpy ( baseName + '.' + methodNames [ i ] ) ;
}
return obj ;
} ;
jasmine . log = function ( message ) {
2009-09-28 18:13:44 +00:00
jasmine . getEnv ( ) . currentSpec . log ( message ) ;
2009-06-16 14:13:45 +00:00
} ;
2009-06-28 20:36:51 +00:00
/ * *
* Function that installs a spy on an existing object ' s method name . Used within a Spec to create a spy .
*
* @ example
* // spy example
* var foo = {
* not : function ( bool ) { return ! bool ; }
* }
* spyOn ( foo , 'not' ) ; // actual foo.not will not be called, execution stops
*
* @ see jasmine . createSpy
* @ param obj
* @ param methodName
* @ returns a Jasmine spy that can be chained with all spy methods
* /
2009-06-16 14:13:45 +00:00
var spyOn = function ( obj , methodName ) {
return jasmine . getEnv ( ) . currentSpec . spyOn ( obj , methodName ) ;
} ;
2009-06-28 20:36:51 +00:00
/ * *
* Creates a Jasmine spec that will be added to the current suite .
*
* // TODO: pending tests
*
* @ example
* it ( 'should be true' , function ( ) {
* expect ( true ) . toEqual ( true ) ;
* } ) ;
*
* @ param { String } desc description of this specification
* @ param { Function } func defines the preconditions and expectations of the spec
* /
2009-06-16 14:13:45 +00:00
var it = function ( desc , func ) {
return jasmine . getEnv ( ) . it ( desc , func ) ;
} ;
2009-06-28 20:36:51 +00:00
/ * *
* Creates a < em > disabled < / e m > J a s m i n e s p e c .
*
* A convenience method that allows existing specs to be disabled temporarily during development .
*
* @ param { String } desc description of this specification
* @ param { Function } func defines the preconditions and expectations of the spec
* /
2009-06-16 14:13:45 +00:00
var xit = function ( desc , func ) {
return jasmine . getEnv ( ) . xit ( desc , func ) ;
} ;
2009-06-28 20:36:51 +00:00
/ * *
* Starts a chain for a Jasmine expectation .
*
* It is passed an Object that is the actual value and should chain to one of the many
* jasmine . Matchers functions .
*
* @ param { Object } actual Actual value to test against and expected value
* /
2009-06-16 14:13:45 +00:00
var expect = function ( actual ) {
return jasmine . getEnv ( ) . currentSpec . expect ( actual ) ;
} ;
2009-06-28 20:36:51 +00:00
/ * *
* Defines part of a jasmine spec . Used in cominbination with waits or waitsFor in asynchrnous specs .
*
* @ param { Function } func Function that defines part of a jasmine spec .
* /
2009-06-16 14:13:45 +00:00
var runs = function ( func ) {
jasmine . getEnv ( ) . currentSpec . runs ( func ) ;
} ;
2009-06-28 20:36:51 +00:00
/ * *
* Waits for a timeout before moving to the next runs ( ) - defined block .
* @ param { Number } timeout
* /
2009-06-16 14:13:45 +00:00
var waits = function ( timeout ) {
jasmine . getEnv ( ) . currentSpec . waits ( timeout ) ;
} ;
2009-06-28 20:36:51 +00:00
/ * *
* Waits for the latchFunction to return true before proceeding to the next runs ( ) - defined block .
2009-10-16 01:00:05 +00:00
*
2009-06-28 20:36:51 +00:00
* @ param { Number } timeout
* @ param { Function } latchFunction
* @ param { String } message
* /
2009-06-16 14:13:45 +00:00
var waitsFor = function ( timeout , latchFunction , message ) {
jasmine . getEnv ( ) . currentSpec . waitsFor ( timeout , latchFunction , message ) ;
} ;
2009-06-28 20:36:51 +00:00
/ * *
* A function that is called before each spec in a suite .
*
* Used for spec setup , including validating assumptions .
*
* @ param { Function } beforeEachFunction
* /
2009-06-16 14:13:45 +00:00
var beforeEach = function ( beforeEachFunction ) {
jasmine . getEnv ( ) . beforeEach ( beforeEachFunction ) ;
} ;
2009-06-28 20:36:51 +00:00
/ * *
* A function that is called after each spec in a suite .
*
* Used for restoring any state that is hijacked during spec execution .
*
* @ param { Function } afterEachFunction
* /
2009-06-16 14:13:45 +00:00
var afterEach = function ( afterEachFunction ) {
jasmine . getEnv ( ) . afterEach ( afterEachFunction ) ;
} ;
2009-06-28 20:36:51 +00:00
/ * *
* Defines a suite of specifications .
*
* Stores the description and all defined specs in the Jasmine environment as one suite of specs . Variables declared
* are accessible by calls to beforeEach , it , and afterEach . Describe blocks can be nested , allowing for specialization
* of setup in some tests .
*
* @ example
* // TODO: a simple suite
*
* // TODO: a simple suite with a nested describe block
*
* @ param { String } description A string , usually the class under test .
* @ param { Function } specDefinitions function that defines several specs .
* /
2009-06-16 14:13:45 +00:00
var describe = function ( description , specDefinitions ) {
return jasmine . getEnv ( ) . describe ( description , specDefinitions ) ;
} ;
2009-06-28 20:36:51 +00:00
/ * *
* Disables a suite of specifications . Used to disable some suites in a file , or files , temporarily during development .
*
* @ param { String } description A string , usually the class under test .
* @ param { Function } specDefinitions function that defines several specs .
* /
2009-06-16 14:13:45 +00:00
var xdescribe = function ( description , specDefinitions ) {
return jasmine . getEnv ( ) . xdescribe ( description , specDefinitions ) ;
} ;
2009-06-28 20:36:51 +00:00
2009-06-16 14:13:45 +00:00
jasmine . XmlHttpRequest = XMLHttpRequest ;
// Provide the XMLHttpRequest class for IE 5.x-6.x:
if ( typeof XMLHttpRequest == "undefined" ) jasmine . XmlHttpRequest = function ( ) {
try {
return new ActiveXObject ( "Msxml2.XMLHTTP.6.0" ) ;
} catch ( e ) {
}
try {
return new ActiveXObject ( "Msxml2.XMLHTTP.3.0" ) ;
} catch ( e ) {
}
try {
return new ActiveXObject ( "Msxml2.XMLHTTP" ) ;
} catch ( e ) {
}
try {
return new ActiveXObject ( "Microsoft.XMLHTTP" ) ;
} catch ( e ) {
}
throw new Error ( "This browser does not support XMLHttpRequest." ) ;
} ;
2009-06-28 20:36:51 +00:00
/ * *
* Adds suite files to an HTML document so that they are executed , thus adding them to the current
* Jasmine environment .
*
* @ param { String } url path to the file to include
* @ param { Boolean } opt _global
* /
2009-06-16 14:13:45 +00:00
jasmine . include = function ( url , opt _global ) {
if ( opt _global ) {
document . write ( '<script type="text/javascript" src="' + url + '"></' + 'script>' ) ;
} else {
var xhr ;
try {
xhr = new jasmine . XmlHttpRequest ( ) ;
xhr . open ( "GET" , url , false ) ;
xhr . send ( null ) ;
} catch ( e ) {
throw new Error ( "couldn't fetch " + url + ": " + e ) ;
}
return eval ( xhr . responseText ) ;
}
} ;
2009-08-21 05:16:14 +00:00
jasmine . version _ = {
"major" : 0 ,
2009-10-17 03:10:20 +00:00
"minor" : 10 ,
2009-08-21 05:16:14 +00:00
"build" : 0 ,
2009-11-01 04:47:11 +00:00
"revision" : 1257050679
2009-08-21 05:16:14 +00:00
} ;
2009-06-28 20:36:51 +00:00
/ * *
* @ namespace
* /
2009-06-16 14:13:45 +00:00
jasmine . util = { } ;
2009-06-28 20:36:51 +00:00
/ * *
* Declare that a child class inherite it ' s prototype from the parent class .
*
* @ private
* @ param { Function } childClass
* @ param { Function } parentClass
* /
2009-06-16 14:13:45 +00:00
jasmine . util . inherit = function ( childClass , parentClass ) {
var subclass = function ( ) {
} ;
subclass . prototype = parentClass . prototype ;
childClass . prototype = new subclass ;
} ;
jasmine . util . formatException = function ( e ) {
var lineNumber ;
if ( e . line ) {
lineNumber = e . line ;
}
else if ( e . lineNumber ) {
lineNumber = e . lineNumber ;
}
var file ;
if ( e . sourceURL ) {
file = e . sourceURL ;
}
else if ( e . fileName ) {
file = e . fileName ;
}
var message = ( e . name && e . message ) ? ( e . name + ': ' + e . message ) : e . toString ( ) ;
if ( file && lineNumber ) {
message += ' in ' + file + ' (line ' + lineNumber + ')' ;
}
return message ;
} ;
jasmine . util . htmlEscape = function ( str ) {
if ( ! str ) return str ;
return str . replace ( /&/g , '&' )
. replace ( /</g , '<' )
. replace ( />/g , '>' ) ;
} ;
jasmine . util . argsToArray = function ( args ) {
var arrayOfArgs = [ ] ;
for ( var i = 0 ; i < args . length ; i ++ ) arrayOfArgs . push ( args [ i ] ) ;
return arrayOfArgs ;
} ;
2009-10-30 00:03:24 +00:00
jasmine . util . extend = function ( destination , source ) {
for ( var property in source ) destination [ property ] = source [ property ] ;
return destination ;
} ;
2009-07-09 00:55:25 +00:00
/ * *
* Environment for Jasmine
2009-07-09 01:18:17 +00:00
*
* @ constructor
2009-07-09 00:55:25 +00:00
* /
2009-06-16 14:13:45 +00:00
jasmine . Env = function ( ) {
this . currentSpec = null ;
this . currentSuite = null ;
2009-09-28 23:23:21 +00:00
this . currentRunner _ = new jasmine . Runner ( this ) ;
2009-06-16 14:13:45 +00:00
2009-07-09 00:55:25 +00:00
this . reporter = new jasmine . MultiReporter ( ) ;
2009-10-06 05:36:10 +00:00
this . updateInterval = jasmine . UPDATE _INTERVAL
2009-06-16 14:13:45 +00:00
this . lastUpdate = 0 ;
this . specFilter = function ( ) {
return true ;
} ;
this . nextSpecId _ = 0 ;
2009-07-29 00:27:52 +00:00
this . nextSuiteId _ = 0 ;
2009-06-16 14:13:45 +00:00
this . equalityTesters _ = [ ] ;
} ;
jasmine . Env . prototype . setTimeout = jasmine . setTimeout ;
jasmine . Env . prototype . clearTimeout = jasmine . clearTimeout ;
jasmine . Env . prototype . setInterval = jasmine . setInterval ;
jasmine . Env . prototype . clearInterval = jasmine . clearInterval ;
2009-09-28 18:13:44 +00:00
/ * *
* @ returns an object containing jasmine version build info , if set .
* /
2009-08-21 05:16:14 +00:00
jasmine . Env . prototype . version = function ( ) {
if ( jasmine . version _ ) {
2009-08-21 14:00:54 +00:00
return jasmine . version _ ;
2009-08-21 05:16:14 +00:00
} else {
2009-08-21 14:00:54 +00:00
throw new Error ( 'Version not set' ) ;
2009-08-21 05:16:14 +00:00
}
} ;
2009-09-28 18:13:44 +00:00
/ * *
* @ returns a sequential integer starting at 0
* /
jasmine . Env . prototype . nextSpecId = function ( ) {
return this . nextSpecId _ ++ ;
} ;
/ * *
* @ returns a sequential integer starting at 0
* /
jasmine . Env . prototype . nextSuiteId = function ( ) {
return this . nextSuiteId _ ++ ;
} ;
2009-07-09 00:55:25 +00:00
/ * *
* Register a reporter to receive status updates from Jasmine .
2009-07-09 01:18:17 +00:00
* @ param { jasmine . Reporter } reporter An object which will receive status updates .
2009-07-09 00:55:25 +00:00
* /
jasmine . Env . prototype . addReporter = function ( reporter ) {
this . reporter . addReporter ( reporter ) ;
} ;
2009-06-16 14:13:45 +00:00
jasmine . Env . prototype . execute = function ( ) {
2009-09-28 23:23:21 +00:00
this . currentRunner _ . execute ( ) ;
2009-06-16 14:13:45 +00:00
} ;
jasmine . Env . prototype . describe = function ( description , specDefinitions ) {
var suite = new jasmine . Suite ( this , description , specDefinitions , this . currentSuite ) ;
var parentSuite = this . currentSuite ;
if ( parentSuite ) {
2009-08-01 22:28:39 +00:00
parentSuite . add ( suite ) ;
2009-06-16 14:13:45 +00:00
} else {
2009-09-28 23:23:21 +00:00
this . currentRunner _ . add ( suite ) ;
2009-06-16 14:13:45 +00:00
}
this . currentSuite = suite ;
specDefinitions . call ( suite ) ;
this . currentSuite = parentSuite ;
return suite ;
} ;
jasmine . Env . prototype . beforeEach = function ( beforeEachFunction ) {
2009-09-28 23:23:21 +00:00
if ( this . currentSuite ) {
this . currentSuite . beforeEach ( beforeEachFunction ) ;
} else {
this . currentRunner _ . beforeEach ( beforeEachFunction ) ;
}
} ;
jasmine . Env . prototype . currentRunner = function ( ) {
return this . currentRunner _ ;
2009-06-16 14:13:45 +00:00
} ;
jasmine . Env . prototype . afterEach = function ( afterEachFunction ) {
2009-09-28 23:23:21 +00:00
if ( this . currentSuite ) {
this . currentSuite . afterEach ( afterEachFunction ) ;
} else {
this . currentRunner _ . afterEach ( afterEachFunction ) ;
}
2009-06-16 14:13:45 +00:00
} ;
jasmine . Env . prototype . xdescribe = function ( desc , specDefinitions ) {
return {
execute : function ( ) {
}
} ;
} ;
jasmine . Env . prototype . it = function ( description , func ) {
var spec = new jasmine . Spec ( this , this . currentSuite , description ) ;
2009-08-01 22:28:39 +00:00
this . currentSuite . add ( spec ) ;
2009-06-16 14:13:45 +00:00
this . currentSpec = spec ;
if ( func ) {
2009-08-01 17:43:03 +00:00
spec . runs ( func ) ;
2009-06-16 14:13:45 +00:00
}
return spec ;
} ;
jasmine . Env . prototype . xit = function ( desc , func ) {
return {
2009-09-28 18:13:44 +00:00
id : this . nextSpecId ( ) ,
2009-06-16 14:13:45 +00:00
runs : function ( ) {
}
} ;
} ;
jasmine . Env . prototype . compareObjects _ = function ( a , b , mismatchKeys , mismatchValues ) {
if ( a . _ _Jasmine _been _here _before _ _ === b && b . _ _Jasmine _been _here _before _ _ === a ) {
return true ;
}
a . _ _Jasmine _been _here _before _ _ = b ;
b . _ _Jasmine _been _here _before _ _ = a ;
var hasKey = function ( obj , keyName ) {
return obj != null && obj [ keyName ] !== undefined ;
} ;
for ( var property in b ) {
if ( ! hasKey ( a , property ) && hasKey ( b , property ) ) {
2009-10-30 00:03:24 +00:00
mismatchKeys . push ( "expected has key '" + property + "', but missing from actual." ) ;
2009-06-16 14:13:45 +00:00
}
}
for ( property in a ) {
if ( ! hasKey ( b , property ) && hasKey ( a , property ) ) {
2009-10-30 00:03:24 +00:00
mismatchKeys . push ( "expected missing key '" + property + "', but present in actual." ) ;
2009-06-16 14:13:45 +00:00
}
}
for ( property in b ) {
if ( property == '__Jasmine_been_here_before__' ) continue ;
if ( ! this . equals _ ( a [ property ] , b [ property ] , mismatchKeys , mismatchValues ) ) {
2009-10-30 00:03:24 +00:00
mismatchValues . push ( "'" + property + "' was '" + ( b [ property ] ? jasmine . util . htmlEscape ( b [ property ] . toString ( ) ) : b [ property ] ) + "' in expected, but was '" + ( a [ property ] ? jasmine . util . htmlEscape ( a [ property ] . toString ( ) ) : a [ property ] ) + "' in actual." ) ;
2009-06-16 14:13:45 +00:00
}
}
if ( jasmine . isArray _ ( a ) && jasmine . isArray _ ( b ) && a . length != b . length ) {
mismatchValues . push ( "arrays were not the same length" ) ;
}
delete a . _ _Jasmine _been _here _before _ _ ;
delete b . _ _Jasmine _been _here _before _ _ ;
return ( mismatchKeys . length == 0 && mismatchValues . length == 0 ) ;
} ;
jasmine . Env . prototype . equals _ = function ( a , b , mismatchKeys , mismatchValues ) {
mismatchKeys = mismatchKeys || [ ] ;
mismatchValues = mismatchValues || [ ] ;
if ( a === b ) return true ;
if ( a === undefined || a === null || b === undefined || b === null ) {
return ( a == undefined && b == undefined ) ;
}
if ( jasmine . isDomNode ( a ) && jasmine . isDomNode ( b ) ) {
return a === b ;
}
if ( a instanceof Date && b instanceof Date ) {
return a . getTime ( ) == b . getTime ( ) ;
}
if ( a instanceof jasmine . Matchers . Any ) {
return a . matches ( b ) ;
}
if ( b instanceof jasmine . Matchers . Any ) {
return b . matches ( a ) ;
}
if ( typeof a === "object" && typeof b === "object" ) {
return this . compareObjects _ ( a , b , mismatchKeys , mismatchValues ) ;
}
for ( var i = 0 ; i < this . equalityTesters _ . length ; i ++ ) {
var equalityTester = this . equalityTesters _ [ i ] ;
var result = equalityTester ( a , b , this , mismatchKeys , mismatchValues ) ;
if ( result !== undefined ) return result ;
}
//Straight check
return ( a === b ) ;
} ;
jasmine . Env . prototype . contains _ = function ( haystack , needle ) {
if ( jasmine . isArray _ ( haystack ) ) {
for ( var i = 0 ; i < haystack . length ; i ++ ) {
if ( this . equals _ ( haystack [ i ] , needle ) ) return true ;
}
return false ;
}
return haystack . indexOf ( needle ) >= 0 ;
} ;
jasmine . Env . prototype . addEqualityTester = function ( equalityTester ) {
this . equalityTesters _ . push ( equalityTester ) ;
} ;
2009-07-09 01:18:17 +00:00
/ * * N o - o p b a s e c l a s s f o r J a s m i n e r e p o r t e r s .
*
* @ constructor
* /
jasmine . Reporter = function ( ) {
} ;
2009-07-09 01:33:15 +00:00
//noinspection JSUnusedLocalSymbols
jasmine . Reporter . prototype . reportRunnerStarting = function ( runner ) {
} ;
2009-07-09 01:18:17 +00:00
//noinspection JSUnusedLocalSymbols
jasmine . Reporter . prototype . reportRunnerResults = function ( runner ) {
} ;
//noinspection JSUnusedLocalSymbols
jasmine . Reporter . prototype . reportSuiteResults = function ( suite ) {
} ;
//noinspection JSUnusedLocalSymbols
jasmine . Reporter . prototype . reportSpecResults = function ( spec ) {
} ;
//noinspection JSUnusedLocalSymbols
2009-07-10 21:35:24 +00:00
jasmine . Reporter . prototype . log = function ( str ) {
2009-07-09 01:18:17 +00:00
} ;
2009-07-30 05:27:11 +00:00
/ * *
* Blocks are functions with executable code that make up a spec .
*
* @ constructor
* @ param { jasmine . Env } env
* @ param { Function } func
* @ param { jasmine . Spec } spec
* /
jasmine . Block = function ( env , func , spec ) {
2009-06-16 14:13:45 +00:00
this . env = env ;
2009-07-30 05:27:11 +00:00
this . func = func ;
this . spec = spec ;
2009-06-16 14:13:45 +00:00
} ;
2009-08-21 05:16:14 +00:00
jasmine . Block . prototype . execute = function ( onComplete ) {
2009-07-30 05:27:11 +00:00
try {
this . func . apply ( this . spec ) ;
} catch ( e ) {
2009-09-28 18:13:44 +00:00
this . spec . fail ( e ) ;
2009-07-30 05:27:11 +00:00
}
2009-08-04 06:09:50 +00:00
onComplete ( ) ;
2009-06-16 14:13:45 +00:00
} ;
2009-08-01 17:43:03 +00:00
/ * * J a v a S c r i p t A P I r e p o r t e r .
2009-06-28 20:36:51 +00:00
*
2009-07-30 05:27:11 +00:00
* @ constructor
2009-06-28 20:36:51 +00:00
* /
2009-08-01 17:43:03 +00:00
jasmine . JsApiReporter = function ( ) {
this . started = false ;
this . finished = false ;
2009-09-28 18:13:44 +00:00
this . suites _ = [ ] ;
this . results _ = { } ;
2009-08-01 17:43:03 +00:00
} ;
2009-06-16 14:13:45 +00:00
2009-08-01 17:43:03 +00:00
jasmine . JsApiReporter . prototype . reportRunnerStarting = function ( runner ) {
this . started = true ;
2009-09-02 14:52:11 +00:00
var suites = runner . suites ( ) ;
2009-09-02 04:21:54 +00:00
for ( var i = 0 ; i < suites . length ; i ++ ) {
var suite = suites [ i ] ;
2009-09-28 18:13:44 +00:00
this . suites _ . push ( this . summarize _ ( suite ) ) ;
2009-08-01 17:43:03 +00:00
}
2009-06-16 14:13:45 +00:00
} ;
2009-09-28 18:13:44 +00:00
jasmine . JsApiReporter . prototype . suites = function ( ) {
return this . suites _ ;
} ;
2009-08-01 17:43:03 +00:00
jasmine . JsApiReporter . prototype . summarize _ = function ( suiteOrSpec ) {
2009-09-02 04:21:54 +00:00
var isSuite = suiteOrSpec instanceof jasmine . Suite
2009-08-01 17:43:03 +00:00
var summary = {
id : suiteOrSpec . id ,
name : suiteOrSpec . description ,
2009-09-02 04:21:54 +00:00
type : isSuite ? 'suite' : 'spec' ,
2009-08-01 17:43:03 +00:00
children : [ ]
} ;
2009-09-02 04:21:54 +00:00
if ( isSuite ) {
2009-09-02 14:30:31 +00:00
var specs = suiteOrSpec . specs ( ) ;
2009-09-02 04:21:54 +00:00
for ( var i = 0 ; i < specs . length ; i ++ ) {
summary . children . push ( this . summarize _ ( specs [ i ] ) ) ;
2009-08-01 17:43:03 +00:00
}
2009-07-30 05:27:11 +00:00
}
2009-08-01 17:43:03 +00:00
return summary ;
2009-06-16 14:13:45 +00:00
} ;
2009-09-28 18:13:44 +00:00
jasmine . JsApiReporter . prototype . results = function ( ) {
return this . results _ ;
} ;
jasmine . JsApiReporter . prototype . resultsForSpec = function ( specId ) {
return this . results _ [ specId ] ;
} ;
2009-08-01 17:43:03 +00:00
//noinspection JSUnusedLocalSymbols
jasmine . JsApiReporter . prototype . reportRunnerResults = function ( runner ) {
this . finished = true ;
2009-06-16 14:13:45 +00:00
} ;
2009-08-01 17:43:03 +00:00
//noinspection JSUnusedLocalSymbols
jasmine . JsApiReporter . prototype . reportSuiteResults = function ( suite ) {
2009-06-16 14:13:45 +00:00
} ;
2009-08-01 17:43:03 +00:00
//noinspection JSUnusedLocalSymbols
jasmine . JsApiReporter . prototype . reportSpecResults = function ( spec ) {
2009-09-28 18:13:44 +00:00
this . results _ [ spec . id ] = {
messages : spec . results ( ) . getItems ( ) ,
result : spec . results ( ) . failedCount > 0 ? "failed" : "passed"
2009-08-01 17:43:03 +00:00
} ;
2009-06-16 14:13:45 +00:00
} ;
2009-08-01 17:43:03 +00:00
//noinspection JSUnusedLocalSymbols
jasmine . JsApiReporter . prototype . log = function ( str ) {
} ;
2009-09-30 05:09:30 +00:00
jasmine . JsApiReporter . prototype . resultsForSpecs = function ( specIds ) {
var results = { } ;
for ( var i = 0 ; i < specIds . length ; i ++ ) {
var specId = specIds [ i ] ;
results [ specId ] = this . summarizeResult _ ( this . results _ [ specId ] ) ;
}
return results ;
} ;
jasmine . JsApiReporter . prototype . summarizeResult _ = function ( result ) {
var summaryMessages = [ ] ;
for ( var messageIndex in result . messages ) {
var resultMessage = result . messages [ messageIndex ] ;
summaryMessages . push ( {
text : resultMessage . text ,
passed : resultMessage . passed ? resultMessage . passed ( ) : true ,
type : resultMessage . type ,
message : resultMessage . message ,
trace : {
stack : resultMessage . passed && ! resultMessage . passed ( ) ? resultMessage . trace . stack : undefined
}
} ) ;
} ;
var summaryResult = {
result : result . result ,
messages : summaryMessages
} ;
return summaryResult ;
} ;
2009-10-27 20:33:22 +00:00
/ * *
* @ constructor
* @ param { jasmine . Env } env
* @ param actual
* @ param { jasmine . NestedResults } results
* /
2009-10-30 00:03:24 +00:00
jasmine . Matchers = function ( env , actual , spec ) {
2009-08-01 17:43:03 +00:00
this . env = env ;
this . actual = actual ;
2009-10-30 00:03:24 +00:00
this . spec = spec ;
2009-08-01 17:43:03 +00:00
} ;
jasmine . Matchers . pp = function ( str ) {
return jasmine . util . htmlEscape ( jasmine . pp ( str ) ) ;
} ;
jasmine . Matchers . prototype . report = function ( result , failing _message , details ) {
2009-10-30 00:03:24 +00:00
var expectationResult = new jasmine . ExpectationResult ( {
passed : result ,
message : failing _message ,
details : details
} ) ;
this . spec . addMatcherResult ( expectationResult ) ;
2009-08-01 17:43:03 +00:00
return result ;
2009-06-16 14:13:45 +00:00
} ;
2009-10-31 02:29:19 +00:00
jasmine . Matchers . matcherFn _ = function ( matcherName , options ) {
return function ( ) {
2009-10-30 00:03:24 +00:00
jasmine . util . extend ( this , options ) ;
2009-10-30 03:33:01 +00:00
var matcherArgs = jasmine . util . argsToArray ( arguments ) ;
var args = [ this . actual ] . concat ( matcherArgs ) ;
2009-10-30 00:03:24 +00:00
var result = options . test . apply ( this , args ) ;
var message ;
if ( ! result ) {
message = options . message . apply ( this , args ) ;
}
var expectationResult = new jasmine . ExpectationResult ( {
matcherName : matcherName ,
passed : result ,
2009-10-30 03:33:01 +00:00
expected : matcherArgs . length > 1 ? matcherArgs : matcherArgs [ 0 ] ,
2009-10-30 00:03:24 +00:00
actual : this . actual ,
message : message
} ) ;
this . spec . addMatcherResult ( expectationResult ) ;
return result ;
} ;
2009-06-16 14:13:45 +00:00
} ;
2009-10-30 00:03:24 +00:00
2009-10-31 02:29:19 +00:00
2009-06-28 20:36:51 +00:00
/ * *
2009-10-30 00:03:24 +00:00
* toBe : compares the actual to the expected using ===
2009-08-01 17:43:03 +00:00
* @ param expected
* /
2009-10-30 00:03:24 +00:00
2009-10-31 02:29:19 +00:00
jasmine . Matchers . prototype . toBe = jasmine . Matchers . matcherFn _ ( 'toBe' , {
2009-10-30 00:03:24 +00:00
test : function ( actual , expected ) {
return actual === expected ;
} ,
message : function ( actual , expected ) {
return "Expected " + jasmine . pp ( actual ) + " to be " + jasmine . pp ( expected ) ;
}
} ) ;
2009-08-01 17:43:03 +00:00
/ * *
2009-10-30 00:03:24 +00:00
* toNotBe : compares the actual to the expected using !==
2009-08-01 17:43:03 +00:00
* @ param expected
2009-06-28 20:36:51 +00:00
* /
2009-10-31 02:29:19 +00:00
jasmine . Matchers . prototype . toNotBe = jasmine . Matchers . matcherFn _ ( 'toNotBe' , {
2009-10-30 00:03:24 +00:00
test : function ( actual , expected ) {
return actual !== expected ;
} ,
message : function ( actual , expected ) {
return "Expected " + jasmine . pp ( actual ) + " to not be " + jasmine . pp ( expected ) ;
}
} ) ;
2009-07-30 05:27:11 +00:00
2009-10-30 00:03:24 +00:00
/ * *
* toEqual : compares the actual to the expected using common sense equality . Handles Objects , Arrays , etc .
*
* @ param expected
* /
2009-08-01 17:43:03 +00:00
2009-10-31 02:29:19 +00:00
jasmine . Matchers . prototype . toEqual = jasmine . Matchers . matcherFn _ ( 'toEqual' , {
2009-10-30 00:03:24 +00:00
test : function ( actual , expected ) {
return this . env . equals _ ( actual , expected ) ;
} ,
message : function ( actual , expected ) {
return "Expected " + jasmine . pp ( actual ) + " to equal " + jasmine . pp ( expected ) ;
}
} ) ;
2009-08-01 17:43:03 +00:00
/ * *
2009-10-30 00:03:24 +00:00
* toNotEqual : compares the actual to the expected using the ! of jasmine . Matchers . toEqual
2009-08-01 17:43:03 +00:00
* @ param expected
* /
2009-10-31 02:29:19 +00:00
jasmine . Matchers . prototype . toNotEqual = jasmine . Matchers . matcherFn _ ( 'toNotEqual' , {
2009-10-30 00:03:24 +00:00
test : function ( actual , expected ) {
return ! this . env . equals _ ( actual , expected ) ;
} ,
message : function ( actual , expected ) {
return "Expected " + jasmine . pp ( actual ) + " to not equal " + jasmine . pp ( expected ) ;
}
} ) ;
2009-08-01 17:43:03 +00:00
/ * *
* Matcher that compares the actual to the expected using a regular expression . Constructs a RegExp , so takes
* a pattern or a String .
*
* @ param reg _exp
* /
2009-10-31 02:29:19 +00:00
jasmine . Matchers . prototype . toMatch = jasmine . Matchers . matcherFn _ ( 'toMatch' , {
2009-10-30 00:03:24 +00:00
test : function ( actual , expected ) {
return new RegExp ( expected ) . test ( actual ) ;
} ,
message : function ( actual , expected ) {
2009-10-30 03:33:01 +00:00
return jasmine . pp ( actual ) + " does not match the regular expression " + new RegExp ( expected ) . toString ( ) ;
2009-10-30 00:03:24 +00:00
}
} ) ;
2009-08-01 17:43:03 +00:00
/ * *
* Matcher that compares the actual to the expected using the boolean inverse of jasmine . Matchers . toMatch
* @ param reg _exp
* /
2009-10-30 00:03:24 +00:00
2009-10-31 02:29:19 +00:00
jasmine . Matchers . prototype . toNotMatch = jasmine . Matchers . matcherFn _ ( 'toNotMatch' , {
2009-10-30 00:03:24 +00:00
test : function ( actual , expected ) {
return ! ( new RegExp ( expected ) . test ( actual ) ) ;
} ,
message : function ( actual , expected ) {
2009-10-30 03:33:01 +00:00
return jasmine . pp ( actual ) + " should not match " + new RegExp ( expected ) . toString ( ) ;
2009-10-30 00:03:24 +00:00
}
} ) ;
2009-08-01 17:43:03 +00:00
/ * *
* Matcher that compares the acutal to undefined .
* /
2009-10-30 00:03:24 +00:00
2009-10-31 02:29:19 +00:00
jasmine . Matchers . prototype . toBeDefined = jasmine . Matchers . matcherFn _ ( 'toBeDefined' , {
2009-10-30 00:03:24 +00:00
test : function ( actual ) {
return ( actual !== undefined ) ;
} ,
message : function ( ) {
return 'Expected actual to not be undefined.' ;
}
} ) ;
/ * *
* Matcher that compares the acutal to undefined .
* /
2009-10-31 02:29:19 +00:00
jasmine . Matchers . prototype . toBeUndefined = jasmine . Matchers . matcherFn _ ( 'toBeUndefined' , {
2009-10-30 00:03:24 +00:00
test : function ( actual ) {
return ( actual === undefined ) ;
} ,
message : function ( actual ) {
return 'Expected ' + jasmine . pp ( actual ) + ' to be undefined.' ;
}
} ) ;
2009-08-01 17:43:03 +00:00
/ * *
* Matcher that compares the actual to null .
*
* /
2009-10-31 02:29:19 +00:00
jasmine . Matchers . prototype . toBeNull = jasmine . Matchers . matcherFn _ ( 'toBeNull' , {
2009-10-30 00:03:24 +00:00
test : function ( actual ) {
return ( actual === null ) ;
} ,
message : function ( actual ) {
return 'Expected ' + jasmine . pp ( actual ) + ' to be null.' ;
}
} ) ;
2009-08-01 17:43:03 +00:00
/ * *
* Matcher that boolean not - nots the actual .
* /
2009-10-31 02:29:19 +00:00
jasmine . Matchers . prototype . toBeTruthy = jasmine . Matchers . matcherFn _ ( 'toBeTruthy' , {
2009-10-30 00:03:24 +00:00
test : function ( actual ) {
return ! ! actual ;
} ,
message : function ( ) {
return 'Expected actual to be truthy' ;
}
} ) ;
2009-08-01 17:43:03 +00:00
/ * *
* Matcher that boolean nots the actual .
* /
2009-10-31 02:29:19 +00:00
jasmine . Matchers . prototype . toBeFalsy = jasmine . Matchers . matcherFn _ ( 'toBeFalsy' , {
2009-10-30 00:03:24 +00:00
test : function ( actual ) {
return ! actual ;
} ,
message : function ( actual ) {
return 'Expected ' + jasmine . pp ( actual ) + ' to be falsy' ;
}
} ) ;
2009-08-01 17:43:03 +00:00
/ * *
* Matcher that checks to see if the acutal , a Jasmine spy , was called .
* /
2009-10-30 00:03:24 +00:00
2009-10-31 02:29:19 +00:00
jasmine . Matchers . prototype . wasCalled = jasmine . Matchers . matcherFn _ ( 'wasCalled' , {
2009-10-30 00:03:24 +00:00
getActual _ : function ( ) {
var args = jasmine . util . argsToArray ( arguments ) ;
if ( args . length > 1 ) {
throw ( new Error ( 'wasCalled does not take arguments, use wasCalledWith' ) ) ;
}
return args . splice ( 0 , 1 ) [ 0 ] ;
} ,
test : function ( ) {
var actual = this . getActual _ . apply ( this , arguments ) ;
if ( ! actual || ! actual . isSpy ) {
return false ;
}
return actual . wasCalled ;
} ,
message : function ( ) {
var actual = this . getActual _ . apply ( this , arguments ) ;
if ( ! actual || ! actual . isSpy ) {
return 'Actual is not a spy.' ;
}
return "Expected spy " + actual . identity + " to have been called." ;
2009-06-16 14:13:45 +00:00
}
2009-10-30 00:03:24 +00:00
} ) ;
2009-06-16 14:13:45 +00:00
2009-08-01 17:43:03 +00:00
/ * *
* Matcher that checks to see if the acutal , a Jasmine spy , was not called .
* /
2009-10-31 02:29:19 +00:00
jasmine . Matchers . prototype . wasNotCalled = jasmine . Matchers . matcherFn _ ( 'wasNotCalled' , {
2009-10-30 00:03:24 +00:00
getActual _ : function ( ) {
var args = jasmine . util . argsToArray ( arguments ) ;
return args . splice ( 0 , 1 ) [ 0 ] ;
} ,
test : function ( ) {
var actual = this . getActual _ . apply ( this , arguments ) ;
if ( ! actual || ! actual . isSpy ) {
return false ;
}
return ! actual . wasCalled ;
} ,
message : function ( ) {
var actual = this . getActual _ . apply ( this , arguments ) ;
if ( ! actual || ! actual . isSpy ) {
return 'Actual is not a spy.' ;
}
return "Expected spy " + actual . identity + " to not have been called." ;
2009-06-16 14:13:45 +00:00
}
2009-10-30 00:03:24 +00:00
} ) ;
2009-10-31 02:29:19 +00:00
jasmine . Matchers . prototype . wasCalledWith = jasmine . Matchers . matcherFn _ ( 'wasCalledWith' , {
2009-10-30 00:03:24 +00:00
test : function ( ) {
var args = jasmine . util . argsToArray ( arguments ) ;
var actual = args . splice ( 0 , 1 ) [ 0 ] ;
if ( ! actual || ! actual . isSpy ) {
return false ;
}
return this . env . contains _ ( actual . argsForCall , args ) ;
} ,
message : function ( ) {
var args = jasmine . util . argsToArray ( arguments ) ;
var actual = args . splice ( 0 , 1 ) [ 0 ] ;
var message ;
if ( ! actual || ! actual . isSpy ) {
message = 'Actual is not a spy' ;
} else {
message = "Expected spy to have been called with " + jasmine . pp ( args ) + " but was called with " + actual . argsForCall ;
}
return message ;
}
} ) ;
2009-06-16 14:13:45 +00:00
2009-08-01 17:43:03 +00:00
/ * *
* Matcher that checks to see if the acutal , a Jasmine spy , was called with a set of parameters .
*
* @ example
*
* /
/ * *
* Matcher that checks that the expected item is an element in the actual Array .
*
* @ param { Object } item
* /
2009-10-30 00:03:24 +00:00
2009-10-31 02:29:19 +00:00
jasmine . Matchers . prototype . toContain = jasmine . Matchers . matcherFn _ ( 'toContain' , {
2009-10-30 00:03:24 +00:00
test : function ( actual , expected ) {
return this . env . contains _ ( actual , expected ) ;
} ,
message : function ( actual , expected ) {
return 'Expected ' + jasmine . pp ( actual ) + ' to contain ' + jasmine . pp ( expected ) ;
}
} ) ;
2009-06-16 14:13:45 +00:00
2009-08-01 17:43:03 +00:00
/ * *
* Matcher that checks that the expected item is NOT an element in the actual Array .
*
* @ param { Object } item
* /
2009-10-31 02:29:19 +00:00
jasmine . Matchers . prototype . toNotContain = jasmine . Matchers . matcherFn _ ( 'toNotContain' , {
2009-10-30 00:03:24 +00:00
test : function ( actual , expected ) {
return ! this . env . contains _ ( actual , expected ) ;
} ,
message : function ( actual , expected ) {
return 'Expected ' + jasmine . pp ( actual ) + ' to not contain ' + jasmine . pp ( expected ) ;
}
} ) ;
2009-10-31 02:29:19 +00:00
jasmine . Matchers . prototype . toBeLessThan = jasmine . Matchers . matcherFn _ ( 'toBeLessThan' , {
2009-10-30 00:03:24 +00:00
test : function ( actual , expected ) {
return actual < expected ;
} ,
message : function ( actual , expected ) {
return 'Expected ' + jasmine . pp ( actual ) + ' to be less than ' + jasmine . pp ( expected ) ;
}
} ) ;
2009-10-31 02:29:19 +00:00
jasmine . Matchers . prototype . toBeGreaterThan = jasmine . Matchers . matcherFn _ ( 'toBeGreaterThan' , {
2009-10-30 00:03:24 +00:00
test : function ( actual , expected ) {
return actual > expected ;
} ,
message : function ( actual , expected ) {
return 'Expected ' + jasmine . pp ( actual ) + ' to be greater than ' + jasmine . pp ( expected ) ;
}
} ) ;
2009-08-14 22:39:28 +00:00
2009-08-01 17:43:03 +00:00
/ * *
* Matcher that checks that the expected exception was thrown by the actual .
*
* @ param { String } expectedException
* /
2009-10-31 02:29:19 +00:00
jasmine . Matchers . prototype . toThrow = jasmine . Matchers . matcherFn _ ( 'toThrow' , {
2009-10-30 00:03:24 +00:00
getException _ : function ( actual , expected ) {
var exception ;
if ( typeof actual != 'function' ) {
throw new Error ( 'Actual is not a function' ) ;
}
try {
actual ( ) ;
} catch ( e ) {
exception = e ;
}
return exception ;
} ,
test : function ( actual , expected ) {
var result = false ;
var exception = this . getException _ ( actual , expected ) ;
if ( exception ) {
result = ( expected === undefined || this . env . equals _ ( exception . message || exception , expected . message || expected ) ) ;
}
return result ;
} ,
message : function ( actual , expected ) {
var exception = this . getException _ ( actual , expected ) ;
if ( exception && ( expected === undefined || ! this . env . equals _ ( exception . message || exception , expected . message || expected ) ) ) {
return [ "Expected function to throw" , expected . message || expected , ", but it threw" , exception . message || exception ] . join ( ' ' ) ;
} else {
return "Expected function to throw an exception." ;
2009-08-01 17:43:03 +00:00
}
}
2009-10-30 00:03:24 +00:00
} ) ;
2009-07-30 05:27:11 +00:00
2009-08-01 17:43:03 +00:00
jasmine . Matchers . Any = function ( expectedClass ) {
this . expectedClass = expectedClass ;
2009-07-30 05:41:38 +00:00
} ;
2009-08-01 17:43:03 +00:00
jasmine . Matchers . Any . prototype . matches = function ( other ) {
if ( this . expectedClass == String ) {
return typeof other == 'string' || other instanceof String ;
2009-07-30 05:27:11 +00:00
}
2009-08-01 17:43:03 +00:00
if ( this . expectedClass == Number ) {
return typeof other == 'number' || other instanceof Number ;
}
2009-07-30 05:27:11 +00:00
2009-08-01 17:43:03 +00:00
if ( this . expectedClass == Function ) {
return typeof other == 'function' || other instanceof Function ;
}
2009-07-30 05:27:11 +00:00
2009-08-01 17:43:03 +00:00
if ( this . expectedClass == Object ) {
return typeof other == 'object' ;
}
2009-07-30 05:27:11 +00:00
2009-08-01 17:43:03 +00:00
return other instanceof this . expectedClass ;
2009-06-16 14:13:45 +00:00
} ;
2009-08-01 17:43:03 +00:00
jasmine . Matchers . Any . prototype . toString = function ( ) {
return '<jasmine.any(' + this . expectedClass + ')>' ;
2009-07-30 05:27:11 +00:00
} ;
2009-08-01 17:43:03 +00:00
2009-06-28 20:36:51 +00:00
/ * *
2009-07-30 05:27:11 +00:00
* @ constructor
2009-06-28 20:36:51 +00:00
* /
2009-07-30 05:27:11 +00:00
jasmine . MultiReporter = function ( ) {
this . subReporters _ = [ ] ;
} ;
jasmine . util . inherit ( jasmine . MultiReporter , jasmine . Reporter ) ;
jasmine . MultiReporter . prototype . addReporter = function ( reporter ) {
this . subReporters _ . push ( reporter ) ;
2009-06-16 14:13:45 +00:00
} ;
2009-07-30 05:27:11 +00:00
( function ( ) {
var functionNames = [ "reportRunnerStarting" , "reportRunnerResults" , "reportSuiteResults" , "reportSpecResults" , "log" ] ;
for ( var i = 0 ; i < functionNames . length ; i ++ ) {
var functionName = functionNames [ i ] ;
jasmine . MultiReporter . prototype [ functionName ] = ( function ( functionName ) {
return function ( ) {
for ( var j = 0 ; j < this . subReporters _ . length ; j ++ ) {
var subReporter = this . subReporters _ [ j ] ;
if ( subReporter [ functionName ] ) {
subReporter [ functionName ] . apply ( subReporter , arguments ) ;
}
}
} ;
} ) ( functionName ) ;
}
} ) ( ) ;
2009-06-28 20:36:51 +00:00
/ * *
2009-07-30 05:27:11 +00:00
* Holds results for a set of Jasmine spec . Allows for the results array to hold another jasmine . NestedResults
2009-06-28 20:36:51 +00:00
*
2009-07-30 05:27:11 +00:00
* @ constructor
2009-06-28 20:36:51 +00:00
* /
2009-07-30 05:27:11 +00:00
jasmine . NestedResults = function ( ) {
/ * *
* The total count of results
* /
this . totalCount = 0 ;
/ * *
* Number of passed results
* /
this . passedCount = 0 ;
/ * *
* Number of failed results
* /
this . failedCount = 0 ;
/ * *
* Was this suite / spec skipped ?
* /
this . skipped = false ;
/ * *
* @ ignore
* /
this . items _ = [ ] ;
2009-06-16 14:13:45 +00:00
} ;
2009-06-28 20:36:51 +00:00
/ * *
2009-07-30 05:27:11 +00:00
* Roll up the result counts .
2009-06-28 20:36:51 +00:00
*
2009-07-30 05:27:11 +00:00
* @ param result
2009-06-28 20:36:51 +00:00
* /
2009-07-30 05:27:11 +00:00
jasmine . NestedResults . prototype . rollupCounts = function ( result ) {
this . totalCount += result . totalCount ;
this . passedCount += result . passedCount ;
this . failedCount += result . failedCount ;
} ;
/ * *
* Tracks a result ' s message .
* @ param message
* /
jasmine . NestedResults . prototype . log = function ( message ) {
this . items _ . push ( new jasmine . MessageResult ( message ) ) ;
} ;
/ * *
* Getter for the results : message & results .
* /
jasmine . NestedResults . prototype . getItems = function ( ) {
return this . items _ ;
} ;
/ * *
* Adds a result , tracking counts ( total , passed , & failed )
* @ param { jasmine . ExpectationResult | jasmine . NestedResults } result
* /
jasmine . NestedResults . prototype . addResult = function ( result ) {
if ( result . type != 'MessageResult' ) {
if ( result . items _ ) {
this . rollupCounts ( result ) ;
} else {
this . totalCount ++ ;
2009-08-19 15:50:56 +00:00
if ( result . passed ( ) ) {
2009-07-30 05:27:11 +00:00
this . passedCount ++ ;
} else {
this . failedCount ++ ;
}
2009-06-16 14:13:45 +00:00
}
}
2009-07-30 05:27:11 +00:00
this . items _ . push ( result ) ;
2009-06-16 14:13:45 +00:00
} ;
2009-07-30 05:27:11 +00:00
/ * *
* @ returns { Boolean } True if < b > everything < / b > b e l o w p a s s e d
* /
2009-08-01 22:28:39 +00:00
jasmine . NestedResults . prototype . passed = function ( ) {
2009-07-30 05:27:11 +00:00
return this . passedCount === this . totalCount ;
2009-08-08 15:53:15 +00:00
} ;
2009-07-30 05:27:11 +00:00
/ * *
2009-08-01 17:43:03 +00:00
* Base class for pretty printing for expectation results .
* /
jasmine . PrettyPrinter = function ( ) {
this . ppNestLevel _ = 0 ;
} ;
/ * *
* Formats a value in a nice , human - readable string .
2009-07-30 05:27:11 +00:00
*
2009-08-01 17:43:03 +00:00
* @ param value
* @ returns { String }
2009-07-30 05:27:11 +00:00
* /
2009-08-01 17:43:03 +00:00
jasmine . PrettyPrinter . prototype . format = function ( value ) {
if ( this . ppNestLevel _ > 40 ) {
// return '(jasmine.pp nested too deeply!)';
throw new Error ( 'jasmine.PrettyPrinter: format() nested too deeply!' ) ;
}
2009-06-16 14:13:45 +00:00
2009-08-01 17:43:03 +00:00
this . ppNestLevel _ ++ ;
try {
if ( value === undefined ) {
this . emitScalar ( 'undefined' ) ;
} else if ( value === null ) {
this . emitScalar ( 'null' ) ;
} else if ( value . navigator && value . frames && value . setTimeout ) {
this . emitScalar ( '<window>' ) ;
} else if ( value instanceof jasmine . Matchers . Any ) {
this . emitScalar ( value . toString ( ) ) ;
} else if ( typeof value === 'string' ) {
this . emitString ( value ) ;
} 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 + ')' ) ;
} else if ( value . _ _Jasmine _been _here _before _ _ ) {
this . emitScalar ( '<circular reference: ' + ( jasmine . isArray _ ( value ) ? 'Array' : 'Object' ) + '>' ) ;
} else if ( jasmine . isArray _ ( value ) || typeof value == 'object' ) {
value . _ _Jasmine _been _here _before _ _ = true ;
if ( jasmine . isArray _ ( value ) ) {
this . emitArray ( value ) ;
} else {
this . emitObject ( value ) ;
}
delete value . _ _Jasmine _been _here _before _ _ ;
} else {
this . emitScalar ( value . toString ( ) ) ;
}
} finally {
this . ppNestLevel _ -- ;
}
2009-07-30 05:27:11 +00:00
} ;
2009-06-16 14:13:45 +00:00
2009-08-01 17:43:03 +00:00
jasmine . PrettyPrinter . prototype . iterateObject = function ( obj , fn ) {
for ( var property in obj ) {
if ( property == '__Jasmine_been_here_before__' ) continue ;
2009-10-16 01:00:05 +00:00
fn ( property , obj . _ _lookupGetter _ _ ? ( obj . _ _lookupGetter _ _ ( property ) != null ) : false ) ;
2009-06-16 14:13:45 +00:00
}
2009-07-30 05:27:11 +00:00
} ;
2009-06-16 14:13:45 +00:00
2009-08-01 17:43:03 +00:00
jasmine . PrettyPrinter . prototype . emitArray = jasmine . unimplementedMethod _ ;
jasmine . PrettyPrinter . prototype . emitObject = jasmine . unimplementedMethod _ ;
jasmine . PrettyPrinter . prototype . emitScalar = jasmine . unimplementedMethod _ ;
jasmine . PrettyPrinter . prototype . emitString = jasmine . unimplementedMethod _ ;
jasmine . StringPrettyPrinter = function ( ) {
jasmine . PrettyPrinter . call ( this ) ;
this . string = '' ;
} ;
jasmine . util . inherit ( jasmine . StringPrettyPrinter , jasmine . PrettyPrinter ) ;
jasmine . StringPrettyPrinter . prototype . emitScalar = function ( value ) {
this . append ( value ) ;
} ;
jasmine . StringPrettyPrinter . prototype . emitString = function ( value ) {
this . append ( "'" + value + "'" ) ;
} ;
jasmine . StringPrettyPrinter . prototype . emitArray = function ( array ) {
this . append ( '[ ' ) ;
for ( var i = 0 ; i < array . length ; i ++ ) {
if ( i > 0 ) {
this . append ( ', ' ) ;
}
this . format ( array [ i ] ) ;
}
this . append ( ' ]' ) ;
} ;
jasmine . StringPrettyPrinter . prototype . emitObject = function ( obj ) {
var self = this ;
this . append ( '{ ' ) ;
var first = true ;
this . iterateObject ( obj , function ( property , isGetter ) {
if ( first ) {
first = false ;
} else {
self . append ( ', ' ) ;
}
self . append ( property ) ;
self . append ( ' : ' ) ;
if ( isGetter ) {
self . append ( '<getter>' ) ;
} else {
self . format ( obj [ property ] ) ;
}
} ) ;
this . append ( ' }' ) ;
2009-07-30 05:27:11 +00:00
} ;
2009-06-16 14:13:45 +00:00
2009-08-01 17:43:03 +00:00
jasmine . StringPrettyPrinter . prototype . append = function ( value ) {
this . string += value ;
2009-07-30 05:27:11 +00:00
} ;
2009-08-19 14:42:47 +00:00
jasmine . Queue = function ( env ) {
2009-06-16 14:13:45 +00:00
this . env = env ;
2009-08-01 21:56:29 +00:00
this . blocks = [ ] ;
2009-08-04 06:09:50 +00:00
this . running = false ;
2009-08-01 22:28:39 +00:00
this . index = 0 ;
2009-08-04 06:09:50 +00:00
this . offset = 0 ;
} ;
2009-10-13 21:22:47 +00:00
jasmine . Queue . prototype . addBefore = function ( block ) {
2009-08-04 06:09:50 +00:00
this . blocks . unshift ( block ) ;
2009-08-01 21:56:29 +00:00
} ;
jasmine . Queue . prototype . add = function ( block ) {
this . blocks . push ( block ) ;
} ;
2009-10-13 21:22:47 +00:00
jasmine . Queue . prototype . insertNext = function ( block ) {
2009-08-04 06:09:50 +00:00
this . blocks . splice ( ( this . index + this . offset + 1 ) , 0 , block ) ;
this . offset ++ ;
} ;
jasmine . Queue . prototype . start = function ( onComplete ) {
2009-10-13 21:22:47 +00:00
this . running = true ;
this . onComplete = onComplete ;
this . next _ ( ) ;
2009-08-01 22:28:39 +00:00
} ;
2009-10-13 21:22:47 +00:00
jasmine . Queue . prototype . isRunning = function ( ) {
2009-08-04 06:09:50 +00:00
return this . running ;
2009-08-01 21:56:29 +00:00
} ;
2009-10-13 21:22:47 +00:00
jasmine . Queue . LOOP _DONT _RECURSE = true ;
jasmine . Queue . prototype . next _ = function ( ) {
2009-08-01 22:28:39 +00:00
var self = this ;
2009-10-13 21:22:47 +00:00
var goAgain = true ;
while ( goAgain ) {
goAgain = false ;
2009-08-19 14:42:47 +00:00
if ( self . index < self . blocks . length ) {
2009-10-13 21:22:47 +00:00
var calledSynchronously = true ;
var completedSynchronously = false ;
2009-09-04 17:57:08 +00:00
2009-10-13 21:22:47 +00:00
var onComplete = function ( ) {
if ( jasmine . Queue . LOOP _DONT _RECURSE && calledSynchronously ) {
completedSynchronously = true ;
return ;
}
2009-08-01 21:56:29 +00:00
2009-10-13 21:22:47 +00:00
self . offset = 0 ;
self . index ++ ;
var now = new Date ( ) . getTime ( ) ;
if ( self . env . updateInterval && now - self . env . lastUpdate > self . env . updateInterval ) {
self . env . lastUpdate = now ;
self . env . setTimeout ( function ( ) {
self . next _ ( ) ;
} , 0 ) ;
} else {
if ( jasmine . Queue . LOOP _DONT _RECURSE && completedSynchronously ) {
goAgain = true ;
} else {
self . next _ ( ) ;
}
}
} ;
self . blocks [ self . index ] . execute ( onComplete ) ;
calledSynchronously = false ;
if ( completedSynchronously ) {
onComplete ( ) ;
}
} else {
self . running = false ;
if ( self . onComplete ) {
self . onComplete ( ) ;
}
}
2009-08-04 06:09:50 +00:00
}
2009-08-01 22:28:39 +00:00
} ;
2009-10-13 21:22:47 +00:00
jasmine . Queue . prototype . results = function ( ) {
2009-08-19 15:50:56 +00:00
var results = new jasmine . NestedResults ( ) ;
2009-08-01 22:28:39 +00:00
for ( var i = 0 ; i < this . blocks . length ; i ++ ) {
2009-09-28 18:13:44 +00:00
if ( this . blocks [ i ] . results ) {
results . addResult ( this . blocks [ i ] . results ( ) ) ;
2009-08-19 15:50:56 +00:00
}
2009-08-01 22:28:39 +00:00
}
return results ;
} ;
2009-07-30 05:27:11 +00:00
/ * J a s m i n e R e p o r t e r s . r e p o r t e r
* Base object that will get called whenever a Spec , Suite , or Runner is done . It is up to
* descendants of this object to do something with the results ( see json _reporter . js )
* /
jasmine . Reporters = { } ;
2009-06-16 14:13:45 +00:00
2009-07-30 05:27:11 +00:00
jasmine . Reporters . reporter = function ( callbacks ) {
var that = {
callbacks : callbacks || { } ,
doCallback : function ( callback , results ) {
if ( callback ) {
callback ( results ) ;
}
} ,
reportRunnerResults : function ( runner ) {
that . doCallback ( that . callbacks . runnerCallback , runner ) ;
} ,
reportSuiteResults : function ( suite ) {
that . doCallback ( that . callbacks . suiteCallback , suite ) ;
} ,
reportSpecResults : function ( spec ) {
that . doCallback ( that . callbacks . specCallback , spec ) ;
} ,
log : function ( str ) {
if ( console && console . log ) console . log ( str ) ;
}
} ;
return that ;
2009-06-16 14:13:45 +00:00
} ;
2009-08-01 17:43:03 +00:00
/ * *
* Runner
*
* @ constructor
* @ param { jasmine . Env } env
* /
jasmine . Runner = function ( env ) {
2009-08-13 05:12:28 +00:00
var self = this ;
self . env = env ;
2009-08-19 14:42:47 +00:00
self . queue = new jasmine . Queue ( env ) ;
2009-09-28 23:23:21 +00:00
self . before _ = [ ] ;
self . after _ = [ ] ;
2009-09-02 14:52:11 +00:00
self . suites _ = [ ] ;
2009-06-16 14:13:45 +00:00
} ;
2009-08-01 17:43:03 +00:00
jasmine . Runner . prototype . execute = function ( ) {
2009-08-13 05:12:28 +00:00
var self = this ;
if ( self . env . reporter . reportRunnerStarting ) {
self . env . reporter . reportRunnerStarting ( this ) ;
2009-08-01 17:43:03 +00:00
}
2009-08-19 15:50:56 +00:00
self . queue . start ( function ( ) {
self . finishCallback ( ) ;
} ) ;
2009-08-01 17:43:03 +00:00
} ;
2009-07-30 05:27:11 +00:00
2009-09-28 23:23:21 +00:00
jasmine . Runner . prototype . beforeEach = function ( beforeEachFunction ) {
beforeEachFunction . typeName = 'beforeEach' ;
this . before _ . push ( beforeEachFunction ) ;
} ;
jasmine . Runner . prototype . afterEach = function ( afterEachFunction ) {
afterEachFunction . typeName = 'afterEach' ;
this . after _ . push ( afterEachFunction ) ;
} ;
2009-08-01 17:43:03 +00:00
jasmine . Runner . prototype . finishCallback = function ( ) {
this . env . reporter . reportRunnerResults ( this ) ;
} ;
2009-08-19 15:50:56 +00:00
jasmine . Runner . prototype . addSuite = function ( suite ) {
2009-09-02 14:52:11 +00:00
this . suites _ . push ( suite ) ;
2009-08-19 15:50:56 +00:00
} ;
2009-08-19 14:42:47 +00:00
2009-08-13 05:12:28 +00:00
jasmine . Runner . prototype . add = function ( block ) {
2009-08-19 15:50:56 +00:00
if ( block instanceof jasmine . Suite ) {
this . addSuite ( block ) ;
}
2009-08-13 05:12:28 +00:00
this . queue . add ( block ) ;
} ;
2009-10-16 01:58:52 +00:00
jasmine . Runner . prototype . specs = function ( ) {
var suites = this . suites ( ) ;
var specs = [ ] ;
for ( var i = 0 ; i < suites . length ; i ++ ) {
specs = specs . concat ( suites [ i ] . specs ( ) ) ;
}
return specs ;
} ;
2009-09-02 14:52:11 +00:00
jasmine . Runner . prototype . suites = function ( ) {
return this . suites _ ;
2009-08-11 00:50:03 +00:00
} ;
2009-09-28 18:13:44 +00:00
jasmine . Runner . prototype . results = function ( ) {
return this . queue . results ( ) ;
} ;
2009-07-09 00:55:25 +00:00
/ * *
2009-07-30 05:27:11 +00:00
* Internal representation of a Jasmine specification , or test .
*
2009-07-09 00:55:25 +00:00
* @ constructor
2009-07-30 05:27:11 +00:00
* @ param { jasmine . Env } env
* @ param { jasmine . Suite } suite
* @ param { String } description
2009-07-09 00:55:25 +00:00
* /
2009-07-30 05:27:11 +00:00
jasmine . Spec = function ( env , suite , description ) {
2009-09-28 18:13:44 +00:00
if ( ! env ) {
throw new Error ( 'jasmine.Env() required' ) ;
2009-09-28 23:23:21 +00:00
}
;
2009-09-28 18:13:44 +00:00
if ( ! suite ) {
throw new Error ( 'jasmine.Suite() required' ) ;
2009-09-28 23:23:21 +00:00
}
;
2009-08-01 22:28:39 +00:00
var spec = this ;
2009-09-28 18:13:44 +00:00
spec . id = env . nextSpecId ? env . nextSpecId ( ) : null ;
2009-08-01 22:28:39 +00:00
spec . env = env ;
spec . suite = suite ;
spec . description = description ;
2009-08-19 14:42:47 +00:00
spec . queue = new jasmine . Queue ( env ) ;
2009-08-01 22:28:39 +00:00
spec . afterCallbacks = [ ] ;
spec . spies _ = [ ] ;
2009-07-30 05:27:11 +00:00
2009-09-28 18:13:44 +00:00
spec . results _ = new jasmine . NestedResults ( ) ;
spec . results _ . description = description ;
2009-08-01 22:28:39 +00:00
spec . matchersClass = null ;
2009-07-09 00:55:25 +00:00
} ;
2009-07-30 05:27:11 +00:00
jasmine . Spec . prototype . getFullName = function ( ) {
return this . suite . getFullName ( ) + ' ' + this . description + '.' ;
} ;
2009-09-28 18:13:44 +00:00
jasmine . Spec . prototype . results = function ( ) {
return this . results _ ;
} ;
jasmine . Spec . prototype . log = function ( message ) {
return this . results _ . log ( message ) ;
} ;
2009-11-01 04:47:11 +00:00
/** @deprecated */
jasmine . Spec . prototype . getResults = function ( ) {
return this . results _ ;
} ;
2009-08-01 17:43:03 +00:00
jasmine . Spec . prototype . runs = function ( func ) {
2009-07-30 05:27:11 +00:00
var block = new jasmine . Block ( this . env , func , this ) ;
2009-08-04 06:09:50 +00:00
this . addToQueue ( block ) ;
2009-08-01 17:43:03 +00:00
return this ;
} ;
2009-07-30 05:27:11 +00:00
2009-08-04 06:09:50 +00:00
jasmine . Spec . prototype . addToQueue = function ( block ) {
if ( this . queue . isRunning ( ) ) {
this . queue . insertNext ( block ) ;
} else {
this . queue . add ( block ) ;
}
} ;
2009-10-30 00:03:24 +00:00
jasmine . Spec . prototype . addMatcherResult = function ( result ) {
this . results _ . addResult ( result ) ;
} ;
2009-07-30 05:27:11 +00:00
jasmine . Spec . prototype . expect = function ( actual ) {
2009-10-30 00:03:24 +00:00
return new ( this . getMatchersClass _ ( ) ) ( this . env , actual , this ) ;
2009-06-16 14:13:45 +00:00
} ;
2009-07-30 05:27:11 +00:00
jasmine . Spec . prototype . waits = function ( timeout ) {
var waitsFunc = new jasmine . WaitsBlock ( this . env , timeout , this ) ;
2009-08-04 06:09:50 +00:00
this . addToQueue ( waitsFunc ) ;
2009-07-30 05:27:11 +00:00
return this ;
2009-06-16 14:13:45 +00:00
} ;
2009-07-30 05:27:11 +00:00
jasmine . Spec . prototype . waitsFor = function ( timeout , latchFunction , timeoutMessage ) {
var waitsForFunc = new jasmine . WaitsForBlock ( this . env , timeout , latchFunction , timeoutMessage , this ) ;
2009-08-04 06:09:50 +00:00
this . addToQueue ( waitsForFunc ) ;
2009-07-30 05:27:11 +00:00
return this ;
2009-06-16 14:13:45 +00:00
} ;
2009-09-28 18:13:44 +00:00
jasmine . Spec . prototype . fail = function ( e ) {
2009-10-30 00:03:24 +00:00
var expectationResult = new jasmine . ExpectationResult ( {
passed : false ,
message : e ? jasmine . util . formatException ( e ) : 'Exception'
} ) ;
this . results _ . addResult ( expectationResult ) ;
2009-06-16 14:13:45 +00:00
} ;
2009-07-30 05:27:11 +00:00
jasmine . Spec . prototype . getMatchersClass _ = function ( ) {
return this . matchersClass || jasmine . Matchers ;
2009-06-16 14:13:45 +00:00
} ;
2009-07-30 05:27:11 +00:00
jasmine . Spec . prototype . addMatchers = function ( matchersPrototype ) {
var parent = this . getMatchersClass _ ( ) ;
var newMatchersClass = function ( ) {
parent . apply ( this , arguments ) ;
} ;
jasmine . util . inherit ( newMatchersClass , parent ) ;
for ( var method in matchersPrototype ) {
newMatchersClass . prototype [ method ] = matchersPrototype [ method ] ;
2009-06-16 14:13:45 +00:00
}
2009-07-30 05:27:11 +00:00
this . matchersClass = newMatchersClass ;
2009-06-16 14:13:45 +00:00
} ;
2009-07-30 05:27:11 +00:00
jasmine . Spec . prototype . finishCallback = function ( ) {
this . env . reporter . reportSpecResults ( this ) ;
} ;
2009-06-16 14:13:45 +00:00
2009-08-04 06:09:50 +00:00
jasmine . Spec . prototype . finish = function ( onComplete ) {
2009-07-30 05:27:11 +00:00
this . removeAllSpies ( ) ;
this . finishCallback ( ) ;
2009-08-04 06:09:50 +00:00
if ( onComplete ) {
onComplete ( ) ;
2009-08-01 22:28:39 +00:00
}
2009-06-16 14:13:45 +00:00
} ;
2009-08-05 02:24:00 +00:00
jasmine . Spec . prototype . after = function ( doAfter , test ) {
2009-09-28 23:23:21 +00:00
if ( this . queue . isRunning ( ) ) {
2009-08-05 02:24:00 +00:00
this . queue . add ( new jasmine . Block ( this . env , doAfter , this ) ) ;
} else {
2009-09-28 23:23:21 +00:00
this . afterCallbacks . unshift ( doAfter ) ;
2009-08-05 02:24:00 +00:00
}
2009-06-16 14:13:45 +00:00
} ;
2009-08-04 06:09:50 +00:00
jasmine . Spec . prototype . execute = function ( onComplete ) {
2009-08-01 21:56:29 +00:00
var spec = this ;
if ( ! spec . env . specFilter ( spec ) ) {
2009-09-28 18:13:44 +00:00
spec . results _ . skipped = true ;
2009-08-19 15:50:56 +00:00
spec . finish ( onComplete ) ;
2009-07-30 05:27:11 +00:00
return ;
2009-06-16 14:13:45 +00:00
}
2009-08-21 05:16:14 +00:00
this . env . reporter . log ( '>> Jasmine Running ' + this . suite . description + ' ' + this . description + '...' ) ;
2009-06-16 14:13:45 +00:00
2009-08-01 21:56:29 +00:00
spec . env . currentSpec = spec ;
2009-06-16 14:13:45 +00:00
2009-08-04 14:12:39 +00:00
spec . addBeforesAndAftersToQueue ( ) ;
2009-06-16 14:13:45 +00:00
2009-08-04 06:09:50 +00:00
spec . queue . start ( function ( ) {
spec . finish ( onComplete ) ;
} ) ;
2009-06-16 14:13:45 +00:00
} ;
2009-08-04 14:12:39 +00:00
jasmine . Spec . prototype . addBeforesAndAftersToQueue = function ( ) {
2009-09-28 23:23:21 +00:00
var runner = this . env . currentRunner ( ) ;
2009-07-30 05:27:11 +00:00
for ( var suite = this . suite ; suite ; suite = suite . parentSuite ) {
2009-09-28 23:23:21 +00:00
for ( var i = 0 ; i < suite . before _ . length ; i ++ ) {
this . queue . addBefore ( new jasmine . Block ( this . env , suite . before _ [ i ] , this ) ) ;
2009-08-01 17:43:03 +00:00
}
2009-08-05 02:24:00 +00:00
}
2009-09-28 23:23:21 +00:00
for ( var i = 0 ; i < runner . before _ . length ; i ++ ) {
this . queue . addBefore ( new jasmine . Block ( this . env , runner . before _ [ i ] , this ) ) ;
}
2009-08-05 02:24:00 +00:00
for ( i = 0 ; i < this . afterCallbacks . length ; i ++ ) {
this . queue . add ( new jasmine . Block ( this . env , this . afterCallbacks [ i ] , this ) ) ;
}
for ( suite = this . suite ; suite ; suite = suite . parentSuite ) {
2009-09-28 23:23:21 +00:00
for ( var i = 0 ; i < suite . after _ . length ; i ++ ) {
this . queue . add ( new jasmine . Block ( this . env , suite . after _ [ i ] , this ) ) ;
2009-08-01 17:43:03 +00:00
}
2009-07-08 06:57:03 +00:00
}
2009-09-28 23:23:21 +00:00
for ( var i = 0 ; i < runner . after _ . length ; i ++ ) {
this . queue . add ( new jasmine . Block ( this . env , runner . after _ [ i ] , this ) ) ;
}
2009-06-16 14:13:45 +00:00
} ;
2009-08-01 17:43:03 +00:00
jasmine . Spec . prototype . explodes = function ( ) {
throw 'explodes function should not have been called' ;
} ;
jasmine . Spec . prototype . spyOn = function ( obj , methodName , ignoreMethodDoesntExist ) {
if ( obj == undefined ) {
throw "spyOn could not find an object to spy upon for " + methodName + "()" ;
2009-07-30 05:27:11 +00:00
}
2009-06-16 14:13:45 +00:00
2009-08-01 17:43:03 +00:00
if ( ! ignoreMethodDoesntExist && obj [ methodName ] === undefined ) {
throw methodName + '() method does not exist' ;
}
2009-06-16 14:13:45 +00:00
2009-08-01 17:43:03 +00:00
if ( ! ignoreMethodDoesntExist && obj [ methodName ] && obj [ methodName ] . isSpy ) {
throw new Error ( methodName + ' has already been spied upon' ) ;
}
var spyObj = jasmine . createSpy ( methodName ) ;
this . spies _ . push ( spyObj ) ;
spyObj . baseObj = obj ;
spyObj . methodName = methodName ;
spyObj . originalValue = obj [ methodName ] ;
obj [ methodName ] = spyObj ;
return spyObj ;
2009-06-16 14:13:45 +00:00
} ;
2009-08-01 17:43:03 +00:00
jasmine . Spec . prototype . removeAllSpies = function ( ) {
for ( var i = 0 ; i < this . spies _ . length ; i ++ ) {
var spy = this . spies _ [ i ] ;
spy . baseObj [ spy . methodName ] = spy . originalValue ;
}
this . spies _ = [ ] ;
2009-06-16 14:13:45 +00:00
} ;
2009-07-30 05:27:11 +00:00
/ * *
2009-08-01 17:43:03 +00:00
* Internal representation of a Jasmine suite .
2009-07-30 05:27:11 +00:00
*
2009-08-01 17:43:03 +00:00
* @ constructor
* @ param { jasmine . Env } env
* @ param { String } description
* @ param { Function } specDefinitions
* @ param { jasmine . Suite } parentSuite
2009-07-30 05:27:11 +00:00
* /
2009-08-01 17:43:03 +00:00
jasmine . Suite = function ( env , description , specDefinitions , parentSuite ) {
2009-08-27 21:21:10 +00:00
var self = this ;
2009-09-28 18:13:44 +00:00
self . id = env . nextSuiteId ? env . nextSuiteId ( ) : null ;
2009-08-01 22:28:39 +00:00
self . description = description ;
2009-08-19 14:42:47 +00:00
self . queue = new jasmine . Queue ( env ) ;
2009-08-01 22:28:39 +00:00
self . parentSuite = parentSuite ;
self . env = env ;
2009-09-28 23:23:21 +00:00
self . before _ = [ ] ;
self . after _ = [ ] ;
2009-09-02 14:30:31 +00:00
self . specs _ = [ ] ;
2009-07-30 05:27:11 +00:00
} ;
2009-08-01 22:28:39 +00:00
2009-08-01 17:43:03 +00:00
jasmine . Suite . prototype . getFullName = function ( ) {
var fullName = this . description ;
for ( var parentSuite = this . parentSuite ; parentSuite ; parentSuite = parentSuite . parentSuite ) {
fullName = parentSuite . description + ' ' + fullName ;
2009-06-16 14:13:45 +00:00
}
2009-08-01 17:43:03 +00:00
return fullName ;
2009-06-16 14:13:45 +00:00
} ;
2009-08-04 06:09:50 +00:00
jasmine . Suite . prototype . finish = function ( onComplete ) {
2009-08-01 17:43:03 +00:00
this . env . reporter . reportSuiteResults ( this ) ;
2009-08-01 22:28:39 +00:00
this . finished = true ;
2009-08-04 06:09:50 +00:00
if ( typeof ( onComplete ) == 'function' ) {
onComplete ( ) ;
2009-08-01 22:28:39 +00:00
}
2009-06-16 14:13:45 +00:00
} ;
2009-08-01 17:43:03 +00:00
jasmine . Suite . prototype . beforeEach = function ( beforeEachFunction ) {
beforeEachFunction . typeName = 'beforeEach' ;
2009-09-28 23:23:21 +00:00
this . before _ . push ( beforeEachFunction ) ;
2009-08-01 17:43:03 +00:00
} ;
2009-06-16 14:13:45 +00:00
2009-08-01 17:43:03 +00:00
jasmine . Suite . prototype . afterEach = function ( afterEachFunction ) {
afterEachFunction . typeName = 'afterEach' ;
2009-09-28 23:23:21 +00:00
this . after _ . push ( afterEachFunction ) ;
2009-08-01 17:43:03 +00:00
} ;
2009-06-16 14:13:45 +00:00
2009-09-28 18:13:44 +00:00
jasmine . Suite . prototype . results = function ( ) {
return this . queue . results ( ) ;
2009-08-01 17:43:03 +00:00
} ;
2009-06-16 14:13:45 +00:00
2009-08-01 22:28:39 +00:00
jasmine . Suite . prototype . add = function ( block ) {
2009-08-19 15:50:56 +00:00
if ( block instanceof jasmine . Suite ) {
2009-09-28 23:23:21 +00:00
this . env . currentRunner ( ) . addSuite ( block ) ;
2009-09-02 04:21:54 +00:00
} else {
2009-09-02 14:30:31 +00:00
this . specs _ . push ( block ) ;
2009-08-27 21:21:10 +00:00
}
2009-08-01 22:28:39 +00:00
this . queue . add ( block ) ;
} ;
2009-09-02 14:30:31 +00:00
jasmine . Suite . prototype . specs = function ( ) {
return this . specs _ ;
2009-09-02 04:21:54 +00:00
} ;
2009-08-04 06:09:50 +00:00
jasmine . Suite . prototype . execute = function ( onComplete ) {
var self = this ;
2009-08-27 21:21:10 +00:00
this . queue . start ( function ( ) {
self . finish ( onComplete ) ;
} ) ;
2009-08-01 22:28:39 +00:00
} ;
2009-08-01 17:43:03 +00:00
jasmine . WaitsBlock = function ( env , timeout , spec ) {
this . timeout = timeout ;
jasmine . Block . call ( this , env , null , spec ) ;
2009-06-16 14:13:45 +00:00
} ;
2009-08-01 17:43:03 +00:00
jasmine . util . inherit ( jasmine . WaitsBlock , jasmine . Block ) ;
2009-08-04 06:09:50 +00:00
jasmine . WaitsBlock . prototype . execute = function ( onComplete ) {
this . env . reporter . log ( '>> Jasmine waiting for ' + this . timeout + ' ms...' ) ;
this . env . setTimeout ( function ( ) {
onComplete ( ) ;
} , this . timeout ) ;
2009-08-01 17:43:03 +00:00
} ;
jasmine . WaitsForBlock = function ( env , timeout , latchFunction , message , spec ) {
this . timeout = timeout ;
this . latchFunction = latchFunction ;
this . message = message ;
this . totalTimeSpentWaitingForLatch = 0 ;
jasmine . Block . call ( this , env , null , spec ) ;
2009-06-16 14:13:45 +00:00
} ;
2009-08-01 17:43:03 +00:00
jasmine . util . inherit ( jasmine . WaitsForBlock , jasmine . Block ) ;
jasmine . WaitsForBlock . TIMEOUT _INCREMENT = 100 ;
2009-08-04 06:09:50 +00:00
jasmine . WaitsForBlock . prototype . execute = function ( onComplete ) {
2009-08-01 17:43:03 +00:00
var self = this ;
self . env . reporter . log ( '>> Jasmine waiting for ' + ( self . message || 'something to happen' ) ) ;
var latchFunctionResult ;
try {
latchFunctionResult = self . latchFunction . apply ( self . spec ) ;
} catch ( e ) {
2009-09-28 18:13:44 +00:00
self . spec . fail ( e ) ;
2009-08-04 06:09:50 +00:00
onComplete ( ) ;
2009-08-01 17:43:03 +00:00
return ;
}
if ( latchFunctionResult ) {
2009-08-04 06:09:50 +00:00
onComplete ( ) ;
2009-08-01 17:43:03 +00:00
} else if ( self . totalTimeSpentWaitingForLatch >= self . timeout ) {
var message = 'timed out after ' + self . timeout + ' msec waiting for ' + ( self . message || 'something to happen' ) ;
2009-09-28 18:13:44 +00:00
self . spec . fail ( {
2009-08-01 17:43:03 +00:00
name : 'timeout' ,
message : message
} ) ;
2009-08-01 22:28:39 +00:00
self . spec . _next ( ) ;
2009-08-01 17:43:03 +00:00
} else {
self . totalTimeSpentWaitingForLatch += jasmine . WaitsForBlock . TIMEOUT _INCREMENT ;
2009-08-04 06:09:50 +00:00
self . env . setTimeout ( function ( ) { self . execute ( onComplete ) ; } , jasmine . WaitsForBlock . TIMEOUT _INCREMENT ) ;
2009-08-01 17:43:03 +00:00
}
} ;
2009-07-30 05:27:11 +00:00
// Mock setTimeout, clearTimeout
// Contributed by Pivotal Computer Systems, www.pivotalsf.com
jasmine . FakeTimer = function ( ) {
this . reset ( ) ;
var self = this ;
self . setTimeout = function ( funcToCall , millis ) {
self . timeoutsMade ++ ;
self . scheduleFunction ( self . timeoutsMade , funcToCall , millis , false ) ;
return self . timeoutsMade ;
} ;
self . setInterval = function ( funcToCall , millis ) {
self . timeoutsMade ++ ;
self . scheduleFunction ( self . timeoutsMade , funcToCall , millis , true ) ;
return self . timeoutsMade ;
} ;
self . clearTimeout = function ( timeoutKey ) {
self . scheduledFunctions [ timeoutKey ] = undefined ;
} ;
self . clearInterval = function ( timeoutKey ) {
self . scheduledFunctions [ timeoutKey ] = undefined ;
} ;
} ;
jasmine . FakeTimer . prototype . reset = function ( ) {
this . timeoutsMade = 0 ;
this . scheduledFunctions = { } ;
this . nowMillis = 0 ;
} ;
jasmine . FakeTimer . prototype . tick = function ( millis ) {
var oldMillis = this . nowMillis ;
var newMillis = oldMillis + millis ;
this . runFunctionsWithinRange ( oldMillis , newMillis ) ;
this . nowMillis = newMillis ;
} ;
jasmine . FakeTimer . prototype . runFunctionsWithinRange = function ( oldMillis , nowMillis ) {
var scheduledFunc ;
var funcsToRun = [ ] ;
for ( var timeoutKey in this . scheduledFunctions ) {
scheduledFunc = this . scheduledFunctions [ timeoutKey ] ;
if ( scheduledFunc != undefined &&
scheduledFunc . runAtMillis >= oldMillis &&
scheduledFunc . runAtMillis <= nowMillis ) {
funcsToRun . push ( scheduledFunc ) ;
this . scheduledFunctions [ timeoutKey ] = undefined ;
}
}
if ( funcsToRun . length > 0 ) {
funcsToRun . sort ( function ( a , b ) {
return a . runAtMillis - b . runAtMillis ;
} ) ;
for ( var i = 0 ; i < funcsToRun . length ; ++ i ) {
try {
var funcToRun = funcsToRun [ i ] ;
this . nowMillis = funcToRun . runAtMillis ;
funcToRun . funcToCall ( ) ;
if ( funcToRun . recurring ) {
this . scheduleFunction ( funcToRun . timeoutKey ,
funcToRun . funcToCall ,
funcToRun . millis ,
true ) ;
}
} catch ( e ) {
}
}
this . runFunctionsWithinRange ( oldMillis , nowMillis ) ;
}
} ;
jasmine . FakeTimer . prototype . scheduleFunction = function ( timeoutKey , funcToCall , millis , recurring ) {
this . scheduledFunctions [ timeoutKey ] = {
runAtMillis : this . nowMillis + millis ,
funcToCall : funcToCall ,
recurring : recurring ,
timeoutKey : timeoutKey ,
millis : millis
} ;
} ;
jasmine . Clock = {
defaultFakeTimer : new jasmine . FakeTimer ( ) ,
reset : function ( ) {
jasmine . Clock . assertInstalled ( ) ;
jasmine . Clock . defaultFakeTimer . reset ( ) ;
} ,
tick : function ( millis ) {
jasmine . Clock . assertInstalled ( ) ;
jasmine . Clock . defaultFakeTimer . tick ( millis ) ;
} ,
runFunctionsWithinRange : function ( oldMillis , nowMillis ) {
jasmine . Clock . defaultFakeTimer . runFunctionsWithinRange ( oldMillis , nowMillis ) ;
} ,
scheduleFunction : function ( timeoutKey , funcToCall , millis , recurring ) {
jasmine . Clock . defaultFakeTimer . scheduleFunction ( timeoutKey , funcToCall , millis , recurring ) ;
} ,
useMock : function ( ) {
var spec = jasmine . getEnv ( ) . currentSpec ;
spec . after ( jasmine . Clock . uninstallMock ) ;
jasmine . Clock . installMock ( ) ;
} ,
installMock : function ( ) {
jasmine . Clock . installed = jasmine . Clock . defaultFakeTimer ;
} ,
uninstallMock : function ( ) {
jasmine . Clock . assertInstalled ( ) ;
jasmine . Clock . installed = jasmine . Clock . real ;
} ,
real : {
setTimeout : window . setTimeout ,
clearTimeout : window . clearTimeout ,
setInterval : window . setInterval ,
clearInterval : window . clearInterval
} ,
assertInstalled : function ( ) {
if ( jasmine . Clock . installed != jasmine . Clock . defaultFakeTimer ) {
throw new Error ( "Mock clock is not installed, use jasmine.Clock.useMock()" ) ;
}
2009-10-16 01:00:05 +00:00
} ,
2009-07-30 05:27:11 +00:00
installed : null
} ;
jasmine . Clock . installed = jasmine . Clock . real ;
2009-10-16 01:00:05 +00:00
//else for IE support
2009-07-30 05:27:11 +00:00
window . setTimeout = function ( funcToCall , millis ) {
2009-10-16 01:00:05 +00:00
if ( jasmine . Clock . installed . setTimeout . apply ) {
return jasmine . Clock . installed . setTimeout . apply ( this , arguments ) ;
} else {
return jasmine . Clock . installed . setTimeout ( funcToCall , millis ) ;
}
2009-07-30 05:27:11 +00:00
} ;
window . setInterval = function ( funcToCall , millis ) {
2009-10-16 01:00:05 +00:00
if ( jasmine . Clock . installed . setInterval . apply ) {
return jasmine . Clock . installed . setInterval . apply ( this , arguments ) ;
} else {
return jasmine . Clock . installed . setInterval ( funcToCall , millis ) ;
}
2009-07-30 05:27:11 +00:00
} ;
window . clearTimeout = function ( timeoutKey ) {
2009-10-16 01:00:05 +00:00
if ( jasmine . Clock . installed . clearTimeout . apply ) {
return jasmine . Clock . installed . clearTimeout . apply ( this , arguments ) ;
} else {
return jasmine . Clock . installed . clearTimeout ( timeoutKey ) ;
}
2009-07-30 05:27:11 +00:00
} ;
window . clearInterval = function ( timeoutKey ) {
2009-10-16 01:00:05 +00:00
if ( jasmine . Clock . installed . clearTimeout . apply ) {
return jasmine . Clock . installed . clearInterval . apply ( this , arguments ) ;
} else {
return jasmine . Clock . installed . clearInterval ( timeoutKey ) ;
}
2009-07-30 05:27:11 +00:00
} ;