2022-03-25 15:47:14 +01:00
import { Context } from "./ExtractComments" ;
2022-04-04 03:38:25 +02:00
import { ScriptExtraction } from "./ScriptExtraction" ;
2022-03-25 15:47:14 +01:00
2022-04-04 03:38:25 +02:00
export type Script = ( Statement | Equality ) [ ]
export interface Equality {
2022-03-25 15:47:14 +01:00
tag : '=='
lhs : string
2022-04-04 03:38:25 +02:00
rhs : string ,
2022-04-08 04:39:17 +02:00
// Line number in the single script
2022-04-04 03:38:25 +02:00
line : number
2022-03-25 15:47:14 +01:00
}
2022-04-04 03:38:25 +02:00
export interface Statement {
2022-03-25 15:47:14 +01:00
tag : 'Statement'
stmt : string
}
/ * *
* Represents a single unit test somewhere in a file .
* /
export default class UnitTest {
public body : Script ;
public context : Context ;
private _extraImports : string [ ] ;
private constructor ( body : Script , context : Context , extraImports : string [ ] ) {
this . body = body ;
this . context = context ;
this . _extraImports = extraImports ;
}
public static FromComment ( comment : string , context : Context ) : UnitTest [ ] {
const imports = ScriptExtraction . extractImports ( comment )
2022-04-08 17:56:56 +02:00
return ScriptExtraction . extractScripts ( comment ) . map (
( { script , name } , i ) = >
2022-03-25 15:47:14 +01:00
new UnitTest ( script , {
. . . context ,
2022-04-08 04:39:17 +02:00
linenumber : ( context . linenumber ? ? 0 ) ,
2022-03-25 15:47:14 +01:00
testname : name ? ? 'doctest ' + i
} , imports ) )
}
public static FromComments ( comms : { comment : string , context : Context } [ ] ) : UnitTest [ ] {
const result : UnitTest [ ] = [ ]
for ( const comm of comms ) {
result . push ( . . . UnitTest . FromComment ( comm . comment , comm . context ) )
}
return result
}
public getImports ( ) : string [ ] {
return [ . . . this . _extraImports , 'import "mocha"' , 'import {expect as __expect} from "chai"' ]
}
/ * *
* Generates the mocha test code for this unit test .
* Will only construct the 'it(' should . . . . ' ) { __expect ( x ) . deep . eq ( y ) } part
* /
public generateCode() {
const script = this . body
. map ( s = > {
if ( s . tag == 'Statement' ) {
return s . stmt
} else {
2022-04-08 17:56:56 +02:00
return ` __expect( ${ s . lhs } , "failed at ${ this . context . functionname } ( ${ this . context . filepath } : ${ 1 + s . line + ( this . context . linenumber ? ? 0 ) } :1)").to.deep.equal( ${ s . rhs } ) `
2022-03-25 15:47:14 +01:00
}
} )
. map ( x = > '\n ' + x )
. join ( '' )
return ` it( ${ this . getName ( ) } , () => { ${ script } \ n}) `
}
private getName() {
return JSON . stringify ( this . context . testname ? ? this . context . functionname )
}
}