import { MatchingCallExpectation , MatchingPropertyExpectation , NotMatchingExpectation , } from '../expectation.mocks' ; import { CallStats , ExpectationRepository } from './expectation-repository' ; export type ExpectationRepositoryContract = { [ suite ] : ExpectationRepositoryTest [ ] ; } ; export type ExpectationRepositoryTest = { name : string ; test : ( repo : ExpectationRepository ) => ( ) => void ; } ; export const repoContractTests = { 'property expectations' : [ { name : 'should match the first expectation' , test : ( repo ) => ( ) => { repo . add ( new MatchingPropertyExpectation ( 'foo' , { value : 23 } ) ) ; expect ( repo . get ( 'foo' ) . value ) . toEqual ( 23 ) ; } , } , { name : 'should match the expectations in order' , test : ( repo ) => ( ) => { repo . add ( new MatchingPropertyExpectation ( 'foo' , { value : 23 } ) ) ; repo . add ( new MatchingPropertyExpectation ( 'foo' , { value : 42 } ) ) ; expect ( repo . get ( 'foo' ) . value ) . toEqual ( 23 ) ; expect ( repo . get ( 'foo' ) . value ) . toEqual ( 42 ) ; } , } , { name : 'should keep matching an expectation until it is fulfilled' , test : ( repo ) => ( ) => { const expectation = new MatchingPropertyExpectation ( 'foo' , { value : 23 , } ) ; expectation . setInvocationCount ( 2 , 3 ) ; repo . add ( expectation ) ; expect ( repo . get ( 'foo' ) . value ) . toEqual ( 23 ) ; expect ( repo . get ( 'foo' ) . value ) . toEqual ( 23 ) ; expect ( repo . get ( 'foo' ) . value ) . toEqual ( 23 ) ; } , } , ] , 'function expectations' : [ { name : 'should match the first expectation' , test : ( repo ) => ( ) => { repo . add ( new MatchingCallExpectation ( 'foo' , { value : 23 } ) ) ; expect ( repo . get ( 'foo' ) . value ( ) ) . toEqual ( 23 ) ; } , } , { name : 'should match the expectations in order' , test : ( repo ) => ( ) => { repo . add ( new MatchingCallExpectation ( 'foo' , { value : 23 } ) ) ; repo . add ( new MatchingCallExpectation ( 'foo' , { value : 42 } ) ) ; expect ( repo . get ( 'foo' ) . value ( ) ) . toEqual ( 23 ) ; expect ( repo . get ( 'foo' ) . value ( ) ) . toEqual ( 42 ) ; } , } , { name : 'should match property expectations before function expectations' , test : ( repo ) => ( ) => { repo . add ( new MatchingCallExpectation ( 'foo' , { value : 1 } ) ) ; repo . add ( new MatchingPropertyExpectation ( 'foo' , { value : ( ) => ( { value : 2 } ) , } ) ) ; expect ( repo . get ( 'foo' ) . value ( ) ) . toEqual ( { value : 2 } ) ; expect ( repo . get ( 'foo' ) . value ( ) ) . toEqual ( 1 ) ; } , } , { name : 'should keep matching an expectation until it is fulfilled' , test : ( repo ) => ( ) => { const expectation = new MatchingCallExpectation ( 'foo' , { value : 23 } ) ; expectation . setInvocationCount ( 2 , 3 ) ; repo . add ( expectation ) ; expect ( repo . get ( 'foo' ) . value ( ) ) . toEqual ( 23 ) ; expect ( repo . get ( 'foo' ) . value ( ) ) . toEqual ( 23 ) ; expect ( repo . get ( 'foo' ) . value ( ) ) . toEqual ( 23 ) ; } , } , { name : 'should throw if the value is an error' , test : ( repo ) => ( ) => { const expectation = new MatchingCallExpectation ( 'foo' , { value : new Error ( ) , isError : true , } ) ; repo . add ( expectation ) ; expect ( ( ) => repo . get ( 'foo' ) . value ( ) ) . toThrow ( ) ; } , } , ] , 'unmet expectations' : [ { name : 'should not have any unmet expectations in the beginning' , test : ( repo ) => ( ) => { expect ( repo . getUnmet ( ) ) . toEqual ( [ ] ) ; } , } , { name : 'should mark all added expectations as unmet' , test : ( repo ) => ( ) => { const e1 = new MatchingPropertyExpectation ( 'foo' , { value : 1 } ) ; const e2 = new MatchingPropertyExpectation ( 'bar' , { value : 1 } ) ; repo . add ( e1 ) ; repo . add ( e2 ) ; expect ( repo . getUnmet ( ) ) . toEqual ( [ e1 , e2 ] ) ; } , } , { name : 'should mark an expectation as met when it is completely fulfilled' , test : ( repo ) => ( ) => { const expectation = new MatchingPropertyExpectation ( 'foo' , { value : 23 , } ) ; expectation . setInvocationCount ( 2 , 3 ) ; repo . add ( expectation ) ; repo . get ( 'foo' ) ; repo . get ( 'foo' ) ; repo . get ( 'foo' ) ; expect ( repo . getUnmet ( ) ) . toEqual ( [ ] ) ; } , } , { name : 'should keep an expectation as unmet until it is completely fulfilled' , test : ( repo ) => ( ) => { const expectation = new MatchingPropertyExpectation ( 'foo' , { value : 23 , } ) ; expectation . setInvocationCount ( 2 , 3 ) ; repo . add ( expectation ) ; repo . get ( 'foo' ) ; expect ( repo . getUnmet ( ) ) . toEqual ( [ expectation ] ) ; repo . get ( 'foo' ) ; expect ( repo . getUnmet ( ) ) . toEqual ( [ ] ) ; } , } , ] , 'call stats' : [ { name : 'should start with empty call stats' , test : ( repo ) => ( ) => { const callStats = { expected : new Map ( ) , unexpected : new Map ( ) , } ; expect ( repo . getCallStats ( ) ) . toEqual ( callStats ) ; } , } , { name : 'it should record property accesses' , test : ( repo ) => ( ) => { repo . add ( new MatchingPropertyExpectation ( 'foo' , { value : 23 } ) ) ; repo . add ( new MatchingPropertyExpectation ( 'foo' , { value : 23 } ) ) ; repo . add ( new MatchingPropertyExpectation ( 'bar' , { value : 23 } ) ) ; repo . add ( new MatchingPropertyExpectation ( 'bar' , { value : 23 } ) ) ; repo . get ( 'foo' ) ; repo . get ( 'foo' ) ; repo . get ( 'bar' ) ; repo . get ( 'bar' ) ; const callStats = { expected : new Map ( [ [ 'foo' , [ { arguments : undefined } , { arguments : undefined } ] ] , [ 'bar' , [ { arguments : undefined } , { arguments : undefined } ] ] , ] ) , unexpected : new Map ( ) , } ; expect ( repo . getCallStats ( ) ) . toEqual ( callStats ) ; } , } , { name : 'it should record function calls' , test : ( repo ) => ( ) => { const expectation = new MatchingCallExpectation ( 'foo' , { value : 23 } ) ; repo . add ( expectation ) ; repo . get ( 'foo' ) . value ( 1 , 2 ) ; const callStats = { expected : new Map ( [ [ 'foo' , [ { arguments : undefined } , { arguments : [ 1 , 2 ] } ] ] , ] ) , unexpected : new Map ( ) , } ; expect ( repo . getCallStats ( ) ) . toEqual ( callStats ) ; } , } , { name : 'should record calls for unexpected access' , test : ( repo ) => ( ) => { try { repo . get ( 'foo' ) ; } catch ( e ) { } const callStats = { expected : new Map ( ) , unexpected : new Map ( [ [ 'foo' , [ { arguments : undefined } ] ] ] ) , } ; expect ( repo . getCallStats ( ) ) . toEqual ( callStats ) ; } , } , { name : 'should record calls for unexpected call' , test : ( repo ) => ( ) => { repo . add ( new NotMatchingExpectation ( 'foo' , { value : 23 } ) ) ; try { repo . get ( 'foo' ) . value ( 1 , 2 , 3 ) ; } catch ( e ) { } const callStats = { expected : new Map ( [ [ 'foo' , [ { arguments : undefined } ] ] ] ) , unexpected : new Map ( [ [ 'foo' , [ { arguments : [ 1 , 2 , 3 ] } ] ] ] ) , } ; expect ( repo . getCallStats ( ) ) . toEqual ( callStats ) ; } , } , ] , clearing : [ { name : 'should remove all expectations when clearing' , test : ( repo ) => ( ) => { repo . add ( new MatchingPropertyExpectation ( 'foo' , { value : 23 } ) ) ; repo . clear ( ) ; expect ( repo . getUnmet ( ) ) . toEqual ( [ ] ) ; } , } , { name : 'should clear all call stats' , test : ( repo ) => ( ) => { repo . add ( new MatchingPropertyExpectation ( 'foo' , { value : 23 } ) ) ; repo . get ( 'foo' ) ; try { repo . get ( 'foo' ) ; } catch ( e ) { } repo . clear ( ) ; const callStats = { expected : new Map ( ) , unexpected : new Map ( ) , } ; expect ( repo . getCallStats ( ) ) . toEqual ( callStats ) ; } , } , ] , stringify : [ { name : 'should return values for toString and friends' , test : ( repo ) => ( ) => { expect ( repo . get ( 'toString' ) . value ( ) ) . toBeTruthy ( ) ; expect ( repo . get ( '@@toStringTag' ) . value ) . toBeTruthy ( ) ; expect ( repo . get ( Symbol . toStringTag ) . value ) . toBeTruthy ( ) ; } , } , { name : 'should match expectations for toString and friends' , test : ( repo ) => ( ) => { repo . add ( new MatchingPropertyExpectation ( 'toString' , { value : ( ) => 'not a mock' , } ) ) ; repo . add ( new MatchingCallExpectation ( 'toString' , { value : 'I said not a mock' , } ) ) ; repo . add ( new MatchingPropertyExpectation ( '@@toStringTag' , { value : 'totally not a mock' , } ) ) ; repo . add ( new MatchingPropertyExpectation ( Symbol . toStringTag , { value : 'absolutely not a mock' , } ) ) ; expect ( repo . get ( 'toString' ) . value ( ) ) . toEqual ( 'not a mock' ) ; expect ( repo . get ( 'toString' ) . value ( ) ) . toEqual ( 'I said not a mock' ) ; expect ( repo . get ( '@@toStringTag' ) . value ) . toEqual ( 'totally not a mock' ) ; expect ( repo . get ( Symbol . toStringTag ) . value ) . toEqual ( 'absolutely not a mock' ) ; } , } , ] , getAllProperties : [ { name : 'should return all the properties that have expectations' , test : ( repo ) => ( ) => { repo . add ( new MatchingPropertyExpectation ( 'foo' , { value : 23 } ) ) ; repo . add ( new MatchingPropertyExpectation ( 'foo' , { value : 23 } ) ) ; repo . add ( new MatchingPropertyExpectation ( 'bar' , { value : 23 } ) ) ; expect ( repo . getAllProperties ( ) ) . toEqual ( [ 'foo' , 'bar' ] ) ; } , } , ] , } ;