import { ethers , Wallet } from 'ethers' ; import { Channel , State } from '../../src' ; import { requireValidProtocolTransition , ValidTransitionStatus } from '../../src/valid-transition' ; const walletA = Wallet . createRandom ( ) ; const walletB = Wallet . createRandom ( ) ; const channel = { chainId : '0x1' , channelNonce : 0 , participants : [ walletA . address , walletB . address ] , } ; const baseFromState = { turnNum : 0 , isFinal : false , appDefinition : ethers . constants . AddressZero , appData : '0x00' , outcome : [ { asset : ethers . constants . AddressZero , allocations : [ ] , metadata : '0x' } ] , channel , challengeDuration : 1 , } ; const baseToState = { ... baseFromState , turnNum : baseFromState . turnNum + 1 } ; type TestCase = [ Partial < State > , Partial < State > ] ; type TestCaseWithError = [ RegExp , Partial < State > , Partial < State > ] ; const valid = [ [ baseFromState , baseToState ] ] ; const incorrectTurnNumCases = [ [ /turnNum must increment by one/ , { } , { turnNum : baseToState . turnNum + 2 } ] , [ /turnNum must increment by one/ , { } , { turnNum : baseToState . turnNum + 3 } ] , ] ; const changedAConstantCases = [ [ /chainId must not change/ , { } , { channel : { ... baseToState . channel , chainId : '0x2' } } ] , [ /participants must not change/ , { } , { channel : { ... baseToState . channel , participants : [ baseToState . channel [ 0 ] ] } } ] , [ /channelNonce must not change/ , { } , { channel : { ... baseToState . channel , channelNonce : baseToState . channel . channelNonce + 1 } } ] , [ /appDefinition must not change/ , { } , { appDefinition : channel . participants [ 0 ] } ] , [ /challengeDuration must not change/ , { } , { challengeDuration : baseToState . challengeDuration + 1 } ] , ] ; const changedOutcomeWhenToIsFinal = [ [ /Outcome change verboten/ , { } , { isFinal : true , outcome : [ ] } ] , ] ; const fromFinalToNotFinal = [ [ /isFinal retrograde/ , { isFinal : true } , { } ] , ] ; const changedOutcomeDuringSetup = [ [ /Outcome change forbidden/ , { turnNum : 1 } , { turnNum : 2 , outcome : [ ] } , ] , ] ; const changedAppDataDuringSetup = [ [ /appData change forbidden/ , { turnNum : 1 } , { turnNum : 2 , appData : '0x02' } ] , ] ; const commonCase = [ [ { turnNum : 6 } , { turnNum : 7 } ] , ] ; function expectStatus ( fromOverrides , toOverrides , status ) { const from = { ... baseFromState , ... fromOverrides } ; const to = { ... baseToState , ... toOverrides } ; expect ( requireValidProtocolTransition ( from , to ) ) . toEqual ( status ) ; } function expectError ( fromOverrides , toOverrides , pattern ) { const from = { ... baseFromState , ... fromOverrides } ; const to = { ... baseToState , ... toOverrides } ; expect ( ( ) => requireValidProtocolTransition ( from , to ) ) . toThrow ( pattern ) ; } describe ( 'getValidProtocolTransitionStatus' , ( ) => { it . each ( valid ) ( 'Returns Status.True for valid cases ' , ( from , to ) => { expectStatus ( from , to , ValidTransitionStatus . True ) ; } ) ; it . each ( [ ... incorrectTurnNumCases , ... changedAConstantCases , ... changedOutcomeWhenToIsFinal , ... fromFinalToNotFinal , ... changedOutcomeDuringSetup , ... changedAppDataDuringSetup , ] ) ( 'Correctly throws error matching %p' , ( pattern , from , to ) => { expectError ( from , to , pattern ) ; } ) ; it . each ( [ ... commonCase ] ) ( 'Returns Status.NeedToCheckApp for otherwise valid cases ' , ( from , to ) => { expectStatus ( from , to , ValidTransitionStatus . NeedToCheckApp ) ; } ) ; } ) ;