@@ -22,13 +22,22 @@ import {
2222 TS_ESTREE_DIR_PATH ,
2323} from './parse-raw-common.ts' ;
2424import { makeUnitsFromTest } from './typescript-make-units-from-test.ts' ;
25+ import type { Node , ParserOptions } from '../src-js/index.js' ;
2526
2627const { hasOwn } = Object ,
2728 { isArray } = Array ;
2829
30+ interface ExtendedParserOptions extends ParserOptions {
31+ experimentalRawTransfer ?: boolean ;
32+ experimentalParent ?: boolean ;
33+ experimentalLazy ?: boolean ;
34+ }
35+
36+ type TestCaseProps = string | { filename : string ; sourceText : string } ;
37+
2938// Run test case and return whether it passes.
3039// This is the entry point when run as a worker.
31- export default async function ( data ) {
40+ export default async function ( data : { type : number ; props : TestCaseProps } ) : Promise < boolean > {
3241 try {
3342 await runCase ( data , simpleExpect ) ;
3443 return true ;
@@ -40,35 +49,43 @@ export default async function (data) {
4049// Run test case with specified `expect` implementation.
4150// If test fails, will throw an error.
4251// Can be called from main thread.
43- export async function runCase ( { type, props } , expect ) {
52+ export async function runCase (
53+ { type, props } : { type : number ; props : TestCaseProps } ,
54+ expect : ExpectFunction ,
55+ ) : Promise < void > {
4456 const rangeParent = ( type & TEST_TYPE_RANGE_PARENT ) !== 0 ,
4557 lazy = ( type & TEST_TYPE_LAZY ) !== 0 ,
4658 pretty = ( type & TEST_TYPE_PRETTY ) !== 0 ;
4759 type &= TEST_TYPE_MAIN_MASK ;
4860
4961 switch ( type ) {
5062 case TEST_TYPE_TEST262 :
51- await runTest262Case ( props , rangeParent , lazy , expect ) ;
63+ await runTest262Case ( props as string , rangeParent , lazy , expect ) ;
5264 break ;
5365 case TEST_TYPE_JSX :
54- await runJsxCase ( props , rangeParent , lazy , expect ) ;
66+ await runJsxCase ( props as string , rangeParent , lazy , expect ) ;
5567 break ;
5668 case TEST_TYPE_TS :
57- await runTsCase ( props , rangeParent , lazy , expect ) ;
69+ await runTsCase ( props as string , rangeParent , lazy , expect ) ;
5870 break ;
5971 case TEST_TYPE_FIXTURE :
60- await runFixture ( props , rangeParent , lazy , pretty , expect ) ;
72+ await runFixture ( props as string , rangeParent , lazy , pretty , expect ) ;
6173 break ;
6274 case TEST_TYPE_INLINE_FIXTURE :
63- await runInlineFixture ( props , rangeParent , lazy , pretty , expect ) ;
75+ await runInlineFixture ( props as { filename : string ; sourceText : string } , rangeParent , lazy , pretty , expect ) ;
6476 break ;
6577 default :
6678 throw new Error ( 'Unexpected test type' ) ;
6779 }
6880}
6981
7082// Run Test262 test case
71- async function runTest262Case ( path , rangeParent , lazy , expect ) {
83+ async function runTest262Case (
84+ path : string ,
85+ rangeParent : boolean ,
86+ lazy : boolean ,
87+ expect : ExpectFunction ,
88+ ) : Promise < void > {
7289 const filename = basename ( path ) ;
7390 const [ sourceText , acornJson ] = await Promise . all ( [
7491 readFile ( pathJoin ( TEST262_DIR_PATH , path ) , 'utf8' ) ,
@@ -93,7 +110,12 @@ async function runTest262Case(path, rangeParent, lazy, expect) {
93110}
94111
95112// Run JSX test case
96- async function runJsxCase ( filename , rangeParent , lazy , expect ) {
113+ async function runJsxCase (
114+ filename : string ,
115+ rangeParent : boolean ,
116+ lazy : boolean ,
117+ expect : ExpectFunction ,
118+ ) : Promise < void > {
97119 const sourcePath = pathJoin ( JSX_DIR_PATH , filename ) ,
98120 jsonPath = sourcePath . slice ( 0 , - 1 ) + 'on' ; // `.jsx` -> `.json`
99121 const [ sourceText , acornJson ] = await Promise . all ( [ readFile ( sourcePath , 'utf8' ) , readFile ( jsonPath , 'utf8' ) ] ) ;
@@ -120,7 +142,7 @@ const TS_CASE_HEADER = '__ESTREE_TEST__:PASS:\n```json\n';
120142const TS_CASE_FOOTER = '\n```\n' ;
121143const TS_CASE_FOOTER_LEN = TS_CASE_FOOTER . length ;
122144
123- async function runTsCase ( path , rangeParent , lazy , expect ) {
145+ async function runTsCase ( path : string , rangeParent : boolean , lazy : boolean , expect : ExpectFunction ) : Promise < void > {
124146 const tsPath = path . slice ( 0 , - 3 ) ; // Trim off `.md`
125147 let [ sourceText , casesJson ] = await Promise . all ( [
126148 readFile ( pathJoin ( TS_DIR_PATH , tsPath ) , 'utf8' ) ,
@@ -140,7 +162,7 @@ async function runTsCase(path, rangeParent, lazy, expect) {
140162 for ( let i = 0 ; i < tests . length ; i ++ ) {
141163 const { name : filename , content : code , sourceType } = tests [ i ] ;
142164
143- const options = {
165+ const options : ExtendedParserOptions = {
144166 sourceType : sourceType . module ? 'module' : 'unambiguous' ,
145167 astType : 'ts' ,
146168 preserveParens : false ,
@@ -156,8 +178,7 @@ async function runTsCase(path, rangeParent, lazy, expect) {
156178 continue ;
157179 }
158180
159- // @ts -ignore
160- const { program, errors } = parseSync ( filename , code , options ) ;
181+ const { program, errors } = parseSync ( filename , code , options as ParserOptions ) ;
161182 const oxcJson = stringifyAcornTest262Style ( program ) ;
162183
163184 const estreeJson = estreeJsons [ i ] ;
@@ -168,8 +189,7 @@ async function runTsCase(path, rangeParent, lazy, expect) {
168189 // Fall back to comparing to AST parsed via JSON transfer.
169190 // We can fail to match the TS-ESLint snapshots where there are syntax errors,
170191 // because our parser is not recoverable.
171- // @ts -ignore
172- const standard = parseSync ( filename , code , { ...options , experimentalRawTransfer : false } ) ;
192+ const standard = parseSync ( filename , code , { ...options , experimentalRawTransfer : false } as ParserOptions ) ;
173193 const standardJson = stringifyAcornTest262Style ( standard . program ) ;
174194 const errorsStandard = standard . errors ;
175195
@@ -183,7 +203,13 @@ async function runTsCase(path, rangeParent, lazy, expect) {
183203}
184204
185205// Test raw transfer output matches standard (via JSON) output for a fixture file
186- async function runFixture ( path , rangeParent , lazy , pretty , expect ) {
206+ async function runFixture (
207+ path : string ,
208+ rangeParent : boolean ,
209+ lazy : boolean ,
210+ pretty : boolean ,
211+ expect : ExpectFunction ,
212+ ) : Promise < void > {
187213 const filename = basename ( path ) ;
188214 const sourceText = await readFile ( pathJoin ( ROOT_DIR_PATH , path ) , 'utf8' ) ;
189215
@@ -197,7 +223,13 @@ async function runFixture(path, rangeParent, lazy, pretty, expect) {
197223}
198224
199225// Test raw transfer output matches standard (via JSON) output for a fixture, with provided source text
200- async function runInlineFixture ( { filename, sourceText } , rangeParent , lazy , pretty , expect ) {
226+ async function runInlineFixture (
227+ { filename, sourceText } : { filename : string ; sourceText : string } ,
228+ rangeParent : boolean ,
229+ lazy : boolean ,
230+ pretty : boolean ,
231+ expect : ExpectFunction ,
232+ ) : Promise < void > {
201233 if ( rangeParent ) {
202234 testRangeParent ( filename , sourceText , null , expect ) ;
203235 } else if ( lazy ) {
@@ -208,17 +240,21 @@ async function runInlineFixture({ filename, sourceText }, rangeParent, lazy, pre
208240}
209241
210242// Test `range` and `parent` fields are correct on all AST nodes.
211- function testRangeParent ( filename , sourceText , options , expect ) {
212- // @ts -ignore
243+ function testRangeParent (
244+ filename : string ,
245+ sourceText : string ,
246+ options : ExtendedParserOptions | null ,
247+ expect : ExpectFunction ,
248+ ) : void {
213249 const ret = parseSync ( filename , sourceText , {
214250 ...options ,
215251 range : true ,
216252 experimentalRawTransfer : true ,
217253 experimentalParent : true ,
218- } ) ;
254+ } as ParserOptions ) ;
219255
220- let parent = null ;
221- function walk ( node ) {
256+ let parent : any = null ;
257+ function walk ( node : null | Node [ ] | Node ) : void {
222258 if ( node === null || typeof node !== 'object' ) return ;
223259
224260 if ( isArray ( node ) ) {
@@ -260,21 +296,25 @@ function testRangeParent(filename, sourceText, options, expect) {
260296
261297// Test lazy deserialization does not throw an error.
262298// We don't test the correctness of the output.
263- function testLazy ( filename , sourceText , options ) {
264- // @ts -ignore
299+ function testLazy ( filename : string , sourceText : string , options : ExtendedParserOptions | null ) : void {
265300 const ret = parseSync ( filename , sourceText , {
266301 ...options ,
267302 experimentalRawTransfer : false ,
268303 experimentalLazy : true ,
269- } ) ;
304+ } as ParserOptions ) ;
270305 JSON . stringify ( ret . program ) ;
271306 JSON . stringify ( ret . comments ) ;
272307 JSON . stringify ( ret . errors ) ;
273308 JSON . stringify ( ret . module ) ;
274309}
275310
276311// Assert raw transfer output matches standard (via JSON) output
277- function assertRawAndStandardMatch ( filename , sourceText , pretty , expect ) {
312+ function assertRawAndStandardMatch (
313+ filename : string ,
314+ sourceText : string ,
315+ pretty : boolean ,
316+ expect : ExpectFunction ,
317+ ) : void {
278318 const retStandard = parseSync ( filename , sourceText ) ;
279319 const {
280320 program : programStandard ,
@@ -290,8 +330,7 @@ function assertRawAndStandardMatch(filename, sourceText, pretty, expect) {
290330 moveStartAndEndToLast ( moduleStandard . staticExports , true ) ;
291331 moveStartAndEndToLast ( moduleStandard . dynamicImports , false ) ;
292332
293- // @ts -ignore
294- const retRaw = parseSync ( filename , sourceText , { experimentalRawTransfer : true } ) ;
333+ const retRaw = parseSync ( filename , sourceText , { experimentalRawTransfer : true } as ParserOptions ) ;
295334 const { program : programRaw , comments : commentsRaw } = retRaw ;
296335 // Remove `null` values, to match what NAPI-RS does
297336 const moduleRaw = removeNullProperties ( retRaw . module ) ;
@@ -309,14 +348,17 @@ function assertRawAndStandardMatch(filename, sourceText, pretty, expect) {
309348 expect ( jsonRaw ) . toEqual ( jsonStandard ) ;
310349}
311350
312- function moveStartAndEndToLast ( arr , reorderEntries ) {
351+ function moveStartAndEndToLast < T extends { entries ?: any [ ] ; start : number ; end : number } > (
352+ arr : T [ ] ,
353+ reorderEntries : boolean ,
354+ ) : void {
313355 for ( const obj of arr ) {
314356 const { start, end } = obj ;
315357 delete obj . start ;
316358 delete obj . end ;
317359 obj . start = start ;
318360 obj . end = end ;
319- if ( reorderEntries ) moveStartAndEndToLast ( obj . entries , false ) ;
361+ if ( reorderEntries && obj . entries ) moveStartAndEndToLast ( obj . entries , false ) ;
320362 }
321363}
322364
@@ -329,14 +371,14 @@ function moveStartAndEndToLast(arr, reorderEntries) {
329371// }
330372// ```
331373// For speed, extract `sourceType` with a slice, rather than parsing the JSON.
332- function getSourceTypeFromJSON ( json ) {
374+ function getSourceTypeFromJSON ( json : string ) : 'script' | 'module' {
333375 const index = json . lastIndexOf ( '"sourceType": "' ) ;
334- return json . slice ( index + 15 , index + 21 ) ;
376+ return json . slice ( index + 15 , index + 21 ) as 'script' | 'module' ;
335377}
336378
337379// Stringify to JSON, replacing values which are invalid in JSON.
338380// If `pretty === true`, JSON is pretty-printed.
339- function stringify ( obj , pretty ) {
381+ function stringify ( obj : any , pretty : boolean ) : string {
340382 return JSON . stringify (
341383 obj ,
342384 ( _key , value ) => {
@@ -354,7 +396,7 @@ function stringify(obj, pretty) {
354396const INFINITY_PLACEHOLDER = '__INFINITY__INFINITY__INFINITY__' ;
355397const INFINITY_REGEXP = new RegExp ( `"${ INFINITY_PLACEHOLDER } "` , 'g' ) ;
356398
357- function stringifyAcornTest262Style ( obj ) {
399+ function stringifyAcornTest262Style ( obj : any ) : string {
358400 let containsInfinity = false ;
359401 const json = JSON . stringify (
360402 obj ,
@@ -373,16 +415,24 @@ function stringifyAcornTest262Style(obj) {
373415}
374416
375417// Remove `null` values, to match what NAPI-RS does
376- function removeNullProperties ( obj ) {
418+ function removeNullProperties ( obj : any ) : any {
377419 return JSON . parse ( JSON . stringify ( obj , ( _key , value ) => ( value === null ? undefined : value ) ) ) ;
378420}
379421
422+ // Type for expect function
423+ interface ExpectFunction {
424+ ( value : any ) : {
425+ toEqual : ( expected : any ) => void ;
426+ toBe : ( expected : any ) => void ;
427+ } ;
428+ }
429+
380430// Very simple `expect` implementation.
381431// Only supports `expect(x).toEqual(y)` and `expect(x).toBe(y)`, and both use only a simple `===` comparison.
382432// Therefore, only works for primitive values e.g. strings.
383- function simpleExpect ( value ) {
384- const toBe = ( expected ) => {
433+ const simpleExpect : ExpectFunction = ( value : any ) => {
434+ const toBe = ( expected : any ) : void => {
385435 if ( value !== expected ) throw new Error ( 'Mismatch' ) ;
386436 } ;
387437 return { toEqual : toBe , toBe } ;
388- }
438+ } ;
0 commit comments