2023-05-15 08:22:53 -04:00
# ! / u s r / b i n / e n v - S d e n o r u n - - a l l o w - r e a d = . - - a l l o w - w r i t e = . - - a l l o w - r u n = g i t
2024-01-01 14:58:21 -05:00
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
2023-03-21 09:38:07 -04:00
2023-05-15 08:22:53 -04:00
/** This copies the test files according to the config file `cli/tests/node_compat/config.jsonc` */
2023-03-21 09:38:07 -04:00
import { walk } from "../../test_util/std/fs/walk.ts" ;
2023-05-15 08:22:53 -04:00
import { sep } from "../../test_util/std/path/mod.ts" ;
2023-03-21 09:38:07 -04:00
import { ensureFile } from "../../test_util/std/fs/ensure_file.ts" ;
import { writeAll } from "../../test_util/std/streams/write_all.ts" ;
import { withoutAll } from "../../test_util/std/collections/without_all.ts" ;
import { relative } from "../../test_util/std/path/posix.ts" ;
import { config , ignoreList } from "../../cli/tests/node_compat/common.ts" ;
const encoder = new TextEncoder ( ) ;
const NODE_VERSION = config . nodeVersion ;
const NODE_IGNORED_TEST_DIRS = [
"addons" ,
"async-hooks" ,
"cctest" ,
"common" ,
"doctool" ,
"embedding" ,
"fixtures" ,
"fuzzers" ,
"js-native-api" ,
"node-api" ,
"overlapped-checker" ,
"report" ,
"testpy" ,
"tick-processor" ,
"tools" ,
"v8-updates" ,
"wasi" ,
"wpt" ,
] ;
2023-05-15 08:22:53 -04:00
const VENDORED_NODE_TEST = new URL ( "node/test/" , import . meta . url ) ;
2023-03-21 09:38:07 -04:00
const NODE_COMPAT_TEST_DEST_URL = new URL (
"../../cli/tests/node_compat/test/" ,
import . meta . url ,
) ;
async function getNodeTests ( ) : Promise < string [ ] > {
const paths : string [ ] = [ ] ;
2023-05-15 08:22:53 -04:00
const rootPath = VENDORED_NODE_TEST . href . slice ( 7 ) ;
2023-03-21 09:38:07 -04:00
for await (
2023-05-15 08:22:53 -04:00
const item of walk ( VENDORED_NODE_TEST , { exts : [ ".js" ] } )
2023-03-21 09:38:07 -04:00
) {
const path = relative ( rootPath , item . path ) ;
if ( NODE_IGNORED_TEST_DIRS . every ( ( dir ) = > ! path . startsWith ( dir ) ) ) {
paths . push ( path ) ;
}
}
return paths . sort ( ) ;
}
function getDenoTests() {
return Object . entries ( config . tests )
. filter ( ( [ testDir ] ) = > ! NODE_IGNORED_TEST_DIRS . includes ( testDir ) )
. flatMap ( ( [ testDir , tests ] ) = > tests . map ( ( test ) = > testDir + "/" + test ) ) ;
}
async function updateToDo() {
const file = await Deno . open ( new URL ( "./TODO.md" , import . meta . url ) , {
write : true ,
create : true ,
truncate : true ,
} ) ;
const missingTests = withoutAll ( await getNodeTests ( ) , await getDenoTests ( ) ) ;
await file . write ( encoder . encode ( ` <!-- deno-fmt-ignore-file -->
# Remaining Node Tests
2023-06-02 02:05:32 -04:00
NOTE : This file should not be manually edited . Please edit \ ` cli/tests/node_compat/config.json \` and run \` deno task setup \` in \` tools/node_compat \` dir instead.
2023-03-21 09:38:07 -04:00
Total : $ { missingTests . length }
` ));
for ( const test of missingTests ) {
await file . write (
encoder . encode (
` - [ ${ test } ](https://github.com/nodejs/node/tree/v ${ NODE_VERSION } /test/ ${ test } ) \ n ` ,
) ,
) ;
}
file . close ( ) ;
}
async function clearTests() {
console . log ( "Cleaning up previous tests" ) ;
for await (
const file of walk ( NODE_COMPAT_TEST_DEST_URL , {
includeDirs : false ,
skip : ignoreList ,
} )
) {
await Deno . remove ( file . path ) ;
}
}
/** Checks if file has entry in config.json */
function hasEntry ( file : string , suite : string ) {
return Array . isArray ( config . tests [ suite ] ) &&
config . tests [ suite ] . includes ( file ) ;
}
async function copyTests() {
console . log ( "Copying test files..." ) ;
2023-05-15 08:22:53 -04:00
for await ( const entry of walk ( VENDORED_NODE_TEST , { skip : ignoreList } ) ) {
2023-03-21 09:38:07 -04:00
const fragments = entry . path . split ( sep ) ;
// suite is the directory name after test/. For example, if the file is
2023-06-26 09:10:27 -04:00
// "node_compat/node/test/fixtures/policy/main.mjs"
2023-03-21 09:38:07 -04:00
// then suite is "fixtures/policy"
2023-05-15 08:22:53 -04:00
const suite = fragments . slice ( fragments . indexOf ( "node_compat" ) + 3 , - 1 )
2023-03-21 09:38:07 -04:00
. join ( "/" ) ;
if ( ! hasEntry ( entry . name , suite ) ) {
continue ;
}
const dest = new URL ( ` ${ suite } / ${ entry . name } ` , NODE_COMPAT_TEST_DEST_URL ) ;
await ensureFile ( dest ) ;
const destFile = await Deno . open ( dest , {
create : true ,
truncate : true ,
write : true ,
} ) ;
const srcFile = await Deno . open (
2023-05-15 08:22:53 -04:00
new URL ( ` ${ suite } / ${ entry . name } ` , VENDORED_NODE_TEST ) ,
2023-03-21 09:38:07 -04:00
) ;
2023-05-15 08:22:53 -04:00
// Add header to js files
2023-04-17 11:36:49 -04:00
if ( dest . pathname . endsWith ( "js" ) ) {
await writeAll (
destFile ,
encoder . encode ( ` // deno-fmt-ignore-file
2023-03-21 09:38:07 -04:00
// deno-lint-ignore-file
// Copyright Joyent and Node contributors. All rights reserved. MIT license.
// Taken from Node ${NODE_VERSION}
2023-06-02 02:05:32 -04:00
// This file is automatically generated by \`tools/node_compat/setup.ts\`. Do not modify this file manually.
2023-03-21 09:38:07 -04:00
` ),
2023-04-17 11:36:49 -04:00
) ;
}
2023-03-21 09:38:07 -04:00
await srcFile . readable . pipeTo ( destFile . writable ) ;
}
}
// main
await clearTests ( ) ;
await copyTests ( ) ;
await updateToDo ( ) ;
2023-05-15 08:22:53 -04:00
if ( Deno . args [ 0 ] === "--check" ) {
const cmd = new Deno . Command ( "git" , { args : [ "status" , "-s" ] } ) ;
const { stdout } = await cmd . output ( ) ;
if ( stdout . length > 0 ) {
console . log ( "The following files have been changed:" ) ;
console . log ( new TextDecoder ( ) . decode ( stdout ) ) ;
Deno . exit ( 1 ) ;
}
}