@@ -270,33 +270,13 @@ export default function transform(root: SgRoot<Js>): string | null {
270270 }
271271 }
272272
273- // 3. Handle test.onFinish and test.onFailure
274- const lifecycleCalls = rootNode . findAll ( {
275- rule : {
276- kind : 'call_expression' ,
277- has : {
278- field : 'function' ,
279- regex : `^${ testVarName } \\.(onFinish|onFailure)$` ,
280- } ,
281- } ,
273+ // 3. Handle unsupported tape lifecycle methods using the same switch-based method transform.
274+ transformMethods ( rootNode , testVarName , edits , undefined , false , {
275+ allowedMethods : new Set ( [ 'onfinish' , 'onfailure' ] ) ,
276+ sourceFileName : root . filename ( ) ,
282277 } ) ;
283278
284- for ( const call of lifecycleCalls ) {
285- const { line, column } = call . range ( ) . start ;
286- const fileName = root . filename ( ) ;
287- const methodName =
288- call . field ( 'function' ) ?. field ( 'property' ) ?. text ( ) || 'lifecycle method' ;
289-
290- console . warn (
291- `[Codemod] Warning: ${ methodName } at ${ fileName } :${ line } :${ column } has no direct equivalent in node:test. Please migrate manually.` ,
292- ) ;
293-
294- const lines = call . text ( ) . split ( / \r ? \n / ) ;
295- const newText = lines
296- . map ( ( line , i ) => ( i === 0 ? `// TODO: ${ line } ` : `// ${ line } ` ) )
297- . join ( EOL ) ;
298- edits . push ( call . replace ( newText ) ) ;
299- }
279+ if ( ! edits . length ) return null ;
300280
301281 return rootNode . commitEdits ( edits ) ;
302282}
@@ -309,13 +289,18 @@ export default function transform(root: SgRoot<Js>): string | null {
309289 * @param edits the list of edits to apply
310290 * @param testCall the AST node of the test function call
311291 * @param useDone whether to use the done callback for ending tests
292+ * @param options optional transform controls
312293 */
313294function transformMethods (
314295 node : SgNode < Js > ,
315296 tName : string ,
316297 edits : Edit [ ] ,
317- testCall : SgNode < Js > ,
298+ testCall ? : SgNode < Js > ,
318299 useDone = false ,
300+ options ?: {
301+ allowedMethods ?: Set < string > ;
302+ sourceFileName ?: string ;
303+ } ,
319304) : boolean {
320305 let requiresAsync = false ;
321306 const calls = node . findAll ( {
@@ -335,19 +320,44 @@ function transformMethods(
335320 for ( const call of calls ) {
336321 const method = call . field ( 'function' ) ?. field ( 'property' ) ?. text ( ) ;
337322 if ( ! method ) continue ;
323+ const normalizedMethod = method . toLowerCase ( ) ;
324+
325+ if (
326+ options ?. allowedMethods &&
327+ ! options . allowedMethods . has ( normalizedMethod )
328+ ) {
329+ continue ;
330+ }
338331
339332 const args = call . field ( 'arguments' ) ;
340333 const func = call . field ( 'function' ) ;
341334
342- if ( ASSERTION_MAPPING [ method ] ) {
343- const newMethod = ASSERTION_MAPPING [ method ] ;
335+ const newMethod =
336+ ASSERTION_MAPPING [ method as keyof typeof ASSERTION_MAPPING ] ;
337+ if ( newMethod ) {
344338 if ( func ) {
345339 edits . push ( func . replace ( `assert.${ newMethod } ` ) ) ;
346340 }
347341 continue ;
348342 }
349343
350- switch ( method . toLowerCase ( ) ) {
344+ switch ( normalizedMethod ) {
345+ case 'onfinish' :
346+ case 'onfailure' : {
347+ const { line, column } = call . range ( ) . start ;
348+ const fileName = options ?. sourceFileName || node . getRoot ( ) . filename ( ) ;
349+
350+ console . warn (
351+ `[Codemod] Warning: ${ method } at ${ fileName } :${ line } :${ column } has no direct equivalent in node:test. Please migrate manually.` ,
352+ ) ;
353+
354+ const lines = call . text ( ) . split ( / \r ? \n / ) ;
355+ const newText = lines
356+ . map ( ( line , i ) => ( i === 0 ? `// TODO: ${ line } ` : `// ${ line } ` ) )
357+ . join ( EOL ) ;
358+ edits . push ( call . replace ( newText ) ) ;
359+ break ;
360+ }
351361 case 'notok' :
352362 case 'false' :
353363 // t.false(val, msg) -> assert.ok(!val, msg)
@@ -454,7 +464,7 @@ function transformMethods(
454464 const timeoutVal = timeoutArg . text ( ) ;
455465
456466 // Add to test options
457- const testArgs = testCall . field ( 'arguments' ) ;
467+ const testArgs = testCall ? .field ( 'arguments' ) ;
458468 if ( testArgs ) {
459469 const children = testArgs . children ( ) ;
460470 // children[0] is '(', children[last] is ')'
0 commit comments