2024-07-24 20:26:54 -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 - - c o n f i g = t e s t s / c o n f i g / d e n o . j s o n
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
2024-08-20 15:14:37 -04:00
// deno-lint-ignore-file no-console
chore: move cli/tests/ -> tests/ (#22369)
This looks like a massive PR, but it's only a move from cli/tests ->
tests, and updates of relative paths for files.
This is the first step towards aggregate all of the integration test
files under tests/, which will lead to a set of integration tests that
can run without the CLI binary being built.
While we could leave these tests under `cli`, it would require us to
keep a more complex directory structure for the various test runners. In
addition, we have a lot of complexity to ignore various test files in
the `cli` project itself (cargo publish exclusion rules, autotests =
false, etc).
And finally, the `tests/` folder will eventually house the `test_ffi`,
`test_napi` and other testing code, reducing the size of the root repo
directory.
For easier review, the extremely large and noisy "move" is in the first
commit (with no changes -- just a move), while the remainder of the
changes to actual files is in the second commit.
2024-02-10 15:22:13 -05:00
/** This copies the test files according to the config file `tests/node_compat/config.jsonc` */
2023-03-21 09:38:07 -04:00
2024-07-25 01:30:28 -04:00
import { walk } from "@std/fs/walk" ;
import { SEPARATOR } from "@std/path/constants" ;
import { ensureFile } from "@std/fs/ensure-file" ;
import { writeAll } from "@std/io/write-all" ;
import { withoutAll } from "@std/collections/without-all" ;
import { relative } from "@std/path/posix/relative" ;
2024-11-25 08:35:53 -05:00
import { version } from "./suite/node_version.ts" ;
2023-03-21 09:38:07 -04:00
2024-04-02 18:24:55 -04:00
import { config , ignoreList } from "../common.ts" ;
2023-03-21 09:38:07 -04:00
const encoder = new TextEncoder ( ) ;
2024-11-25 08:35:53 -05:00
const NODE_VERSION = version ;
2023-03-21 09:38:07 -04:00
2024-12-02 10:05:59 -05:00
export const NODE_IGNORED_TEST_DIRS = [
2023-03-21 09:38:07 -04:00
"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" ,
] ;
2024-12-02 10:05:59 -05:00
export const VENDORED_NODE_TEST = new URL ( "./suite/test/" , import . meta . url ) ;
export const NODE_COMPAT_TEST_DEST_URL = new URL (
2024-04-02 18:24:55 -04:00
"../test/" ,
2023-03-21 09:38:07 -04:00
import . meta . url ,
) ;
2024-12-02 10:05:59 -05:00
export async function getNodeTests ( ) : Promise < string [ ] > {
2023-03-21 09:38:07 -04:00
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 ( ) ;
}
2024-12-02 10:05:59 -05:00
export function getDenoTests() {
2023-03-21 09:38:07 -04:00
return Object . entries ( config . tests )
. filter ( ( [ testDir ] ) = > ! NODE_IGNORED_TEST_DIRS . includes ( testDir ) )
. flatMap ( ( [ testDir , tests ] ) = > tests . map ( ( test ) = > testDir + "/" + test ) ) ;
}
async function updateToDo() {
2024-01-21 18:20:59 -05:00
using file = await Deno . open ( new URL ( "./TODO.md" , import . meta . url ) , {
2023-03-21 09:38:07 -04:00
write : true ,
create : true ,
truncate : true ,
} ) ;
2024-11-26 08:51:57 -05:00
const nodeTests = await getNodeTests ( ) ;
const portedTests = getDenoTests ( ) ;
const remainingTests = withoutAll ( nodeTests , portedTests ) ;
const numPorted = portedTests . length ;
const numMissing = remainingTests . length ;
const numTotal = nodeTests . length ;
const portedPercentage = ( numPorted / numTotal * 100 ) . toFixed ( 2 ) ;
const remainingPercentage = ( numMissing / numTotal * 100 ) . toFixed ( 2 ) ;
2023-03-21 09:38:07 -04:00
await file . write ( encoder . encode ( ` <!-- deno-fmt-ignore-file -->
# Remaining Node Tests
2024-11-26 08:51:57 -05:00
$ { numPorted } tests out of $ { numTotal } have been ported from Node $ { NODE_VERSION } ( $ { portedPercentage } % ported , $ { remainingPercentage } % remaining ) .
2024-04-02 18:24:55 -04:00
NOTE : This file should not be manually edited . Please edit \ ` tests/node_compat/config.json \` and run \` deno task setup \` in \` tests/node_compat/runner \` dir instead.
2023-03-21 09:38:07 -04:00
` ));
2024-11-26 08:51:57 -05:00
for ( const test of remainingTests ) {
2023-03-21 09:38:07 -04:00
await file . write (
encoder . encode (
` - [ ${ test } ](https://github.com/nodejs/node/tree/v ${ NODE_VERSION } /test/ ${ test } ) \ n ` ,
) ,
) ;
}
}
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 } ) ) {
2024-04-01 21:57:05 -04:00
const fragments = entry . path . split ( SEPARATOR ) ;
2023-03-21 09:38:07 -04:00
// 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"
2024-04-02 18:24:55 -04:00
const suite = fragments . slice ( fragments . indexOf ( "node_compat" ) + 4 , - 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}
2024-04-02 18:24:55 -04:00
// This file is automatically generated by \`tests/node_compat/runner/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 ) ;
}
}