summaryrefslogtreecommitdiff
path: root/cli/tests/node_compat/test.ts
blob: 213a2797436f7dbc265aedb5b230b524ffa952dc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
import { magenta } from "std/fmt/colors.ts";
import { dirname, fromFileUrl, join } from "std/path/mod.ts";
import { fail } from "std/testing/asserts.ts";
import { config, getPathsFromTestSuites } from "./common.ts";

// If the test case is invoked like
// deno test -A cli/tests/node_compat/test.ts -- <test-names>
// Use the test-names as filters
const filters = Deno.args;
const hasFilters = filters.length > 0;

/**
 * This script will run the test files specified in the configuration file
 *
 * Each test file will be run independently and wait until completion, if an abnormal
 * code for the test is reported, the test suite will fail immediately
 */

const toolsPath = dirname(fromFileUrl(import.meta.url));
const stdRootUrl = new URL("../../", import.meta.url).href;
const testPaths = getPathsFromTestSuites(config.tests);
const cwd = new URL(".", import.meta.url);
const importMap = "import_map.json";
const windowsIgnorePaths = new Set(
  getPathsFromTestSuites(config.windowsIgnore),
);
const darwinIgnorePaths = new Set(
  getPathsFromTestSuites(config.darwinIgnore),
);

const decoder = new TextDecoder();

for await (const path of testPaths) {
  // If filter patterns are given and any pattern doesn't match
  // to the file path, then skip the case
  if (
    filters.length > 0 &&
    filters.every((pattern) => !path.includes(pattern))
  ) {
    continue;
  }
  const isTodo = path.includes("TODO");
  const ignore =
    (Deno.build.os === "windows" && windowsIgnorePaths.has(path)) ||
    (Deno.build.os === "darwin" && darwinIgnorePaths.has(path)) || isTodo;
  Deno.test({
    name: `Node.js compatibility "${path}"`,
    ignore,
    fn: async () => {
      const testCase = join(toolsPath, "test", path);

      const v8Flags = ["--stack-size=4000"];
      const testSource = await Deno.readTextFile(testCase);
      // TODO(kt3k): Parse `Flags` directive correctly
      if (testSource.includes("Flags: --expose_externalize_string")) {
        v8Flags.push("--expose-externalize-string");
      }

      const args = [
        "run",
        "-A",
        "--quiet",
        "--unstable",
        //"--unsafely-ignore-certificate-errors",
        "--v8-flags=" + v8Flags.join(),
        testCase.endsWith(".mjs") ? "--import-map=" + importMap : "runner.ts",
        testCase,
      ];

      // Pipe stdout in order to output each test result as Deno.test output
      // That way the tests will respect the `--quiet` option when provided
      const command = new Deno.Command(Deno.execPath(), {
        args,
        env: {
          DENO_NODE_COMPAT_URL: stdRootUrl,
        },
        cwd,
      });
      const { code, stdout, stderr } = await command.output();

      if (code !== 0) {
        // If the test case failed, show the stdout, stderr, and instruction
        // for repeating the single test case.
        if (stdout.length) console.log(decoder.decode(stdout));
        console.log(`Error: "${path}" failed`);
        console.log(
          "You can repeat only this test with the command:",
          magenta(
            `./target/debug/deno test -A --import-map cli/tests/node_compat/import_map.json cli/tests/node_compat/test.ts -- ${path}`,
          ),
        );
        fail(decoder.decode(stderr));
      } else if (hasFilters) {
        // Even if the test case is successful, shows the stdout and stderr
        // when test case filtering is specified.
        if (stdout.length) console.log(decoder.decode(stdout));
        if (stderr.length) console.log(decoder.decode(stderr));
      }
    },
  });
}

function checkConfigTestFilesOrder(testFileLists: Array<string[]>) {
  for (let testFileList of testFileLists) {
    testFileList = testFileList.filter((name) => !name.startsWith("TODO:"));
    const sortedTestList = JSON.parse(JSON.stringify(testFileList));
    sortedTestList.sort();
    if (JSON.stringify(testFileList) !== JSON.stringify(sortedTestList)) {
      throw new Error(
        `File names in \`config.json\` are not correct order.`,
      );
    }
  }
}

if (!hasFilters) {
  Deno.test("checkConfigTestFilesOrder", function () {
    checkConfigTestFilesOrder([
      ...Object.keys(config.ignore).map((suite) => config.ignore[suite]),
      ...Object.keys(config.tests).map((suite) => config.tests[suite]),
    ]);
  });
}