import { expect } from "chai" ; import { loadYamlFile } from "./util" ; export interface IBaseCase { description : string ; } /**
 * TestSpec - represent structure of yaml file containing spec test cases
 * TestCase - single test case, usually under test_cases property in yaml file
 */ interface TestSpec < TestCase extends IBaseCase > { title : string ; summary : string ; forksTimeline : string ; forks : string ; config : string ; runner : string ; handler : string ; testCases : TestCase [ ] ; } param { string } testYamlPath param { Function } testFunc param { Function } getInput param { Function } getExpected param { Function } getActual param { Function } shouldError param { Function } shouldSkip param { Function } expectFunc param timeout export function describeMultiSpec < TestCase extends IBaseCase , Result > ( testYamlPath , testFunc , getInput , getExpected , getActual , shouldError = ( testCase , index ) => false , shouldSkip = ( testCase , index ) => false , expectFunc = ( testCase , expect , expected , actual ) => expect ( actual ) . to . be . equal ( expected ) , timeout = 10 * 60 * 1000 ) { const testSpec = ( loadYamlFile ( testYamlPath ) as unknown ) as TestSpec < TestCase > ; const testSuiteName = `${ testSpec . runner } - ${ testSpec . handler } - ${ testSpec . title } - ${ testSpec . config }` ; describe ( testSuiteName , function ( ) { this . timeout ( timeout ) ; for ( const [ index , testCase ] of testSpec . testCases . entries ( ) ) { if ( shouldSkip ( testCase , index ) ) { continue ; } const description = index + ( testCase . description ? " - " + testCase . description : "" ) ; it ( description , function ( ) { const inputs = getInput ( testCase ) ; if ( shouldError ( testCase , index ) ) { expect ( testFunc . bind ( null , ... inputs ) ) . to . throw ( ) ; } else { const result = testFunc ( ... inputs ) ; const actual = getActual ( result ) ; const expected = getExpected ( testCase ) ; expectFunc ( testCase , expect , expected , actual ) ; } } ) ; } } ) ; }