import mocha from 'mocha' ; import { run , Task , Effection , Operation } from 'effection' ; let world ; type TestFunction = ( this : mocha . Context , world : Task , scope : Task ) => Generator < Operation < any > , any , any > ; interface ItFunction { ( title , fn ? ) : void ; only ( title , fn ) : void ; skip ( title , fn ) : void ; } mocha . beforeEach ( async function ( ) { await Effection . reset ( ) ; world = run ( undefined , { labels : { name : 'world' } } ) ; } ) ; mocha . afterEach ( async function ( ) { world ! . halt ( ) ; await world ! . catchHalt ( ) ; world = undefined ; await Effection . halt ( ) ; } ) ; function runInWorld ( fn , name = "test" ) { return async function ( this ) { await world ! . run ( ( local ) => fn . bind ( this ) ( world ! , local ) , { ignoreError : true , yieldScope : world ! , labels : { name } } ) ; } ; } export const describe = mocha . describe ; export const beforeEach = ( fn ) : void => mocha . beforeEach ( runInWorld ( fn , "beforeEach" ) ) ; export const afterEach = ( fn ) : void => mocha . afterEach ( runInWorld ( fn , "afterEach" ) ) ; export const it = Object . assign ( ( title , fn ? ) => mocha . it ( title , fn ? runInWorld ( fn , `it(${ JSON . stringify ( title ) })` ) : fn ) , { only : ( title , fn ) => mocha . it . only ( title , runInWorld ( fn , `it(${ JSON . stringify ( title ) })` ) ) , skip : ( title , fn ) => mocha . it . skip ( title , runInWorld ( fn , `it(${ JSON . stringify ( title ) })` ) ) } ) ; export function captureError ( op ) { return function * ( ) { try { yield op ; } catch ( error ) { return error ; } throw new Error ( 'expected operation to throw an error, but it did not!' ) ; } ; }