@jsenv/test 1.1.2 → 1.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/dist/jsenv_test.js +4 -2
  2. package/package.json +3 -3
  3. package/src/coverage/babel_plugin_instrument.js +15 -15
  4. package/src/coverage/coverage_reporter_html_directory.js +10 -10
  5. package/src/coverage/coverage_reporter_json_file.js +7 -7
  6. package/src/coverage/coverage_reporter_text_log.js +8 -8
  7. package/src/coverage/empty_coverage_factory.js +24 -24
  8. package/src/coverage/file_by_file_coverage.js +10 -10
  9. package/src/coverage/istanbul_coverage_composition.js +16 -16
  10. package/src/coverage/istanbul_coverage_map_from_coverage.js +8 -8
  11. package/src/coverage/list_files_not_covered.js +4 -4
  12. package/src/coverage/missing_coverage.js +17 -17
  13. package/src/coverage/report_to_coverage.js +52 -52
  14. package/src/coverage/v8_and_istanbul.js +17 -16
  15. package/src/coverage/v8_coverage.js +8 -8
  16. package/src/coverage/v8_coverage_composition.js +12 -12
  17. package/src/coverage/v8_coverage_node_directory.js +42 -42
  18. package/src/coverage/v8_coverage_to_istanbul.js +45 -45
  19. package/src/execution/execute.js +21 -21
  20. package/src/execution/execute_steps.js +129 -129
  21. package/src/execution/execute_test_plan.js +72 -68
  22. package/src/execution/execution_colors.js +2 -2
  23. package/src/execution/execution_steps.js +20 -20
  24. package/src/execution/gc.js +5 -5
  25. package/src/execution/logs_file_execution.js +126 -126
  26. package/src/execution/logs_file_execution.test.mjs +11 -11
  27. package/src/execution/run.js +51 -51
  28. package/src/execution/web_server_param.js +24 -24
  29. package/src/main.js +7 -7
  30. package/src/runtime_browsers/chromium.js +7 -7
  31. package/src/runtime_browsers/firefox.js +10 -10
  32. package/src/runtime_browsers/middleware_istanbul.js +23 -23
  33. package/src/runtime_browsers/middleware_js_supervisor.js +32 -32
  34. package/src/runtime_browsers/using_playwright.js +186 -186
  35. package/src/runtime_browsers/webkit.js +11 -11
  36. package/src/runtime_node/child_exec_options.js +43 -43
  37. package/src/runtime_node/controllable_child_process.mjs +47 -47
  38. package/src/runtime_node/controllable_worker_thread.mjs +37 -37
  39. package/src/runtime_node/exec_options.js +26 -26
  40. package/src/runtime_node/execute_using_dynamic_import.js +26 -26
  41. package/src/runtime_node/exit_codes.js +4 -4
  42. package/src/runtime_node/importmap_node_loader.mjs +24 -24
  43. package/src/runtime_node/importmap_node_loader_file_url.js +1 -1
  44. package/src/runtime_node/kill_process_tree.js +30 -30
  45. package/src/runtime_node/no_experimental_warnings.cjs +4 -4
  46. package/src/runtime_node/no_experimental_warnings_file_url.js +1 -1
  47. package/src/runtime_node/node_child_process.js +128 -128
  48. package/src/runtime_node/node_execution_performance.js +28 -28
  49. package/src/runtime_node/node_worker_thread.js +108 -108
  50. package/src/runtime_node/profiler_v8_coverage.js +21 -21
@@ -1,37 +1,38 @@
1
- import { createDetailedMessage } from "@jsenv/log"
1
+ import { createDetailedMessage } from "@jsenv/log";
2
2
 
3
3
  export const composeV8AndIstanbul = (
4
4
  v8FileByFileCoverage,
5
5
  istanbulFileByFileCoverage,
6
6
  { coverageV8ConflictWarning },
7
7
  ) => {
8
- const fileByFileCoverage = {}
9
- const v8Files = Object.keys(v8FileByFileCoverage)
10
- const istanbulFiles = Object.keys(istanbulFileByFileCoverage)
8
+ const fileByFileCoverage = {};
9
+ const v8Files = Object.keys(v8FileByFileCoverage);
10
+ const istanbulFiles = Object.keys(istanbulFileByFileCoverage);
11
11
 
12
12
  v8Files.forEach((key) => {
13
- fileByFileCoverage[key] = v8FileByFileCoverage[key]
14
- })
13
+ fileByFileCoverage[key] = v8FileByFileCoverage[key];
14
+ });
15
15
  istanbulFiles.forEach((key) => {
16
- const v8Coverage = v8FileByFileCoverage[key]
16
+ const v8Coverage = v8FileByFileCoverage[key];
17
17
  if (v8Coverage) {
18
18
  if (coverageV8ConflictWarning) {
19
19
  console.warn(
20
20
  createDetailedMessage(
21
21
  `Coverage conflict on "${key}", found two coverage that cannot be merged together: v8 and istanbul. The istanbul coverage will be ignored.`,
22
22
  {
23
- details: `This happens when a file is executed on a runtime using v8 coverage (node or chromium) and on runtime using istanbul coverage (firefox or webkit)`,
24
- suggestion:
25
- "You can disable this warning with coverageV8ConflictWarning: false",
23
+ "details": `This happens when a file is executed on a runtime using v8 coverage (node or chromium) and on runtime using istanbul coverage (firefox or webkit)`,
24
+ "suggestion":
25
+ "disable this warning with coverageV8ConflictWarning: false",
26
+ "suggestion 2": `force coverage using istanbul with coverageMethodForBrowsers: "istanbul"`,
26
27
  },
27
28
  ),
28
- )
29
+ );
29
30
  }
30
- fileByFileCoverage[key] = v8Coverage
31
+ fileByFileCoverage[key] = v8Coverage;
31
32
  } else {
32
- fileByFileCoverage[key] = istanbulFileByFileCoverage[key]
33
+ fileByFileCoverage[key] = istanbulFileByFileCoverage[key];
33
34
  }
34
- })
35
+ });
35
36
 
36
- return fileByFileCoverage
37
- }
37
+ return fileByFileCoverage;
38
+ };
@@ -1,4 +1,4 @@
1
- import { URL_META } from "@jsenv/url-meta"
1
+ import { URL_META } from "@jsenv/url-meta";
2
2
 
3
3
  export const filterV8Coverage = async (
4
4
  v8Coverage,
@@ -7,20 +7,20 @@ export const filterV8Coverage = async (
7
7
  const associations = URL_META.resolveAssociations(
8
8
  { cover: coverageConfig },
9
9
  rootDirectoryUrl,
10
- )
10
+ );
11
11
  const urlShouldBeCovered = (url) => {
12
12
  const { cover } = URL_META.applyAssociations({
13
13
  url: new URL(url, rootDirectoryUrl).href,
14
14
  associations,
15
- })
16
- return cover
17
- }
15
+ });
16
+ return cover;
17
+ };
18
18
 
19
19
  const v8CoverageFiltered = {
20
20
  ...v8Coverage,
21
21
  result: v8Coverage.result.filter((fileReport) =>
22
22
  urlShouldBeCovered(fileReport.url),
23
23
  ),
24
- }
25
- return v8CoverageFiltered
26
- }
24
+ };
25
+ return v8CoverageFiltered;
26
+ };
@@ -1,24 +1,24 @@
1
- import { requireFromJsenv } from "@jsenv/core/src/helpers/require_from_jsenv.js"
1
+ import { requireFromJsenv } from "@jsenv/core/src/helpers/require_from_jsenv.js";
2
2
 
3
3
  export const composeTwoV8Coverages = (firstV8Coverage, secondV8Coverage) => {
4
4
  if (secondV8Coverage.result.length === 0) {
5
- return firstV8Coverage
5
+ return firstV8Coverage;
6
6
  }
7
7
 
8
8
  // eslint-disable-next-line import/no-unresolved
9
- const { mergeProcessCovs } = requireFromJsenv("@c88/v8-coverage")
9
+ const { mergeProcessCovs } = requireFromJsenv("@c88/v8-coverage");
10
10
  // "mergeProcessCovs" do not preserves source-map-cache during the merge
11
11
  // so we store sourcemap cache now
12
- const sourceMapCache = {}
12
+ const sourceMapCache = {};
13
13
  const visit = (coverageReport) => {
14
14
  if (coverageReport["source-map-cache"]) {
15
- Object.assign(sourceMapCache, coverageReport["source-map-cache"])
15
+ Object.assign(sourceMapCache, coverageReport["source-map-cache"]);
16
16
  }
17
- }
18
- visit(firstV8Coverage)
19
- visit(secondV8Coverage)
20
- const v8Coverage = mergeProcessCovs([firstV8Coverage, secondV8Coverage])
21
- v8Coverage["source-map-cache"] = sourceMapCache
17
+ };
18
+ visit(firstV8Coverage);
19
+ visit(secondV8Coverage);
20
+ const v8Coverage = mergeProcessCovs([firstV8Coverage, secondV8Coverage]);
21
+ v8Coverage["source-map-cache"] = sourceMapCache;
22
22
 
23
- return v8Coverage
24
- }
23
+ return v8Coverage;
24
+ };
@@ -1,7 +1,7 @@
1
- import { readFileSync, readdirSync } from "node:fs"
2
- import { assertAndNormalizeDirectoryUrl } from "@jsenv/filesystem"
3
- import { createDetailedMessage } from "@jsenv/log"
4
- import { Abort } from "@jsenv/abort"
1
+ import { readFileSync, readdirSync } from "node:fs";
2
+ import { assertAndNormalizeDirectoryUrl } from "@jsenv/filesystem";
3
+ import { createDetailedMessage } from "@jsenv/log";
4
+ import { Abort } from "@jsenv/abort";
5
5
 
6
6
  export const readNodeV8CoverageDirectory = async ({
7
7
  logger,
@@ -9,77 +9,77 @@ export const readNodeV8CoverageDirectory = async ({
9
9
  onV8Coverage,
10
10
  maxMsWaitingForNodeToWriteCoverageFile = 2000,
11
11
  }) => {
12
- const NODE_V8_COVERAGE = process.env.NODE_V8_COVERAGE
13
- const operation = Abort.startOperation()
14
- operation.addAbortSignal(signal)
12
+ const NODE_V8_COVERAGE = process.env.NODE_V8_COVERAGE;
13
+ const operation = Abort.startOperation();
14
+ operation.addAbortSignal(signal);
15
15
 
16
- let timeSpentTrying = 0
16
+ let timeSpentTrying = 0;
17
17
  const tryReadDirectory = async () => {
18
- const dirContent = readdirSync(NODE_V8_COVERAGE)
18
+ const dirContent = readdirSync(NODE_V8_COVERAGE);
19
19
  if (dirContent.length > 0) {
20
- return dirContent
20
+ return dirContent;
21
21
  }
22
22
  if (timeSpentTrying < maxMsWaitingForNodeToWriteCoverageFile) {
23
- await new Promise((resolve) => setTimeout(resolve, 200))
24
- timeSpentTrying += 200
25
- logger.debug("retry to read coverage directory")
26
- return tryReadDirectory()
23
+ await new Promise((resolve) => setTimeout(resolve, 200));
24
+ timeSpentTrying += 200;
25
+ logger.debug("retry to read coverage directory");
26
+ return tryReadDirectory();
27
27
  }
28
- logger.warn(`v8 coverage directory is empty at ${NODE_V8_COVERAGE}`)
29
- return dirContent
30
- }
28
+ logger.warn(`v8 coverage directory is empty at ${NODE_V8_COVERAGE}`);
29
+ return dirContent;
30
+ };
31
31
 
32
32
  try {
33
- operation.throwIfAborted()
34
- const dirContent = await tryReadDirectory()
33
+ operation.throwIfAborted();
34
+ const dirContent = await tryReadDirectory();
35
35
 
36
36
  const coverageDirectoryUrl = assertAndNormalizeDirectoryUrl(
37
37
  NODE_V8_COVERAGE,
38
38
  "NODE_V8_COVERAGE",
39
- )
39
+ );
40
40
 
41
41
  await dirContent.reduce(async (previous, dirEntry) => {
42
- operation.throwIfAborted()
43
- await previous
42
+ operation.throwIfAborted();
43
+ await previous;
44
44
 
45
- const dirEntryUrl = new URL(dirEntry, coverageDirectoryUrl)
45
+ const dirEntryUrl = new URL(dirEntry, coverageDirectoryUrl);
46
46
  const tryReadJsonFile = async () => {
47
- const fileContent = String(readFileSync(dirEntryUrl))
47
+ const fileContent = String(readFileSync(dirEntryUrl));
48
48
  if (fileContent === "") {
49
49
  if (timeSpentTrying < maxMsWaitingForNodeToWriteCoverageFile) {
50
- await new Promise((resolve) => setTimeout(resolve, 200))
51
- timeSpentTrying += 200
52
- return tryReadJsonFile()
50
+ await new Promise((resolve) => setTimeout(resolve, 200));
51
+ timeSpentTrying += 200;
52
+ return tryReadJsonFile();
53
53
  }
54
- console.warn(`Coverage JSON file is empty at ${dirEntryUrl}`)
55
- return null
54
+ console.warn(`Coverage JSON file is empty at ${dirEntryUrl}`);
55
+ return null;
56
56
  }
57
57
 
58
58
  try {
59
- const fileAsJson = JSON.parse(fileContent)
60
- return fileAsJson
59
+ const fileAsJson = JSON.parse(fileContent);
60
+ return fileAsJson;
61
61
  } catch (e) {
62
62
  if (timeSpentTrying < maxMsWaitingForNodeToWriteCoverageFile) {
63
- await new Promise((resolve) => setTimeout(resolve, 200))
64
- timeSpentTrying += 200
65
- return tryReadJsonFile()
63
+ await new Promise((resolve) => setTimeout(resolve, 200));
64
+ timeSpentTrying += 200;
65
+ return tryReadJsonFile();
66
66
  }
67
67
  console.warn(
68
68
  createDetailedMessage(`Error while reading coverage file`, {
69
69
  "error stack": e.stack,
70
70
  "file": dirEntryUrl,
71
71
  }),
72
- )
73
- return null
72
+ );
73
+ return null;
74
74
  }
75
- }
75
+ };
76
76
 
77
- const fileContent = await tryReadJsonFile()
77
+ const fileContent = await tryReadJsonFile();
78
78
  if (fileContent) {
79
- await onV8Coverage(fileContent)
79
+ await onV8Coverage(fileContent);
80
80
  }
81
- }, Promise.resolve())
81
+ }, Promise.resolve());
82
82
  } finally {
83
- await operation.end()
83
+ await operation.end();
84
84
  }
85
- }
85
+ };
@@ -1,33 +1,33 @@
1
- import { urlToFileSystemPath } from "@jsenv/urls"
2
- import { Abort } from "@jsenv/abort"
3
- import { requireFromJsenv } from "@jsenv/core/src/helpers/require_from_jsenv.js"
1
+ import { urlToFileSystemPath } from "@jsenv/urls";
2
+ import { Abort } from "@jsenv/abort";
3
+ import { requireFromJsenv } from "@jsenv/core/src/helpers/require_from_jsenv.js";
4
4
 
5
- import { composeTwoFileByFileIstanbulCoverages } from "./istanbul_coverage_composition.js"
5
+ import { composeTwoFileByFileIstanbulCoverages } from "./istanbul_coverage_composition.js";
6
6
 
7
7
  export const v8CoverageToIstanbul = async (v8Coverage, { signal }) => {
8
- const operation = Abort.startOperation()
9
- operation.addAbortSignal(signal)
8
+ const operation = Abort.startOperation();
9
+ operation.addAbortSignal(signal);
10
10
 
11
11
  try {
12
- const v8ToIstanbul = requireFromJsenv("v8-to-istanbul")
13
- const sourcemapCache = v8Coverage["source-map-cache"]
14
- let istanbulCoverageComposed = null
12
+ const v8ToIstanbul = requireFromJsenv("v8-to-istanbul");
13
+ const sourcemapCache = v8Coverage["source-map-cache"];
14
+ let istanbulCoverageComposed = null;
15
15
 
16
16
  await v8Coverage.result.reduce(async (previous, fileV8Coverage) => {
17
- operation.throwIfAborted()
18
- await previous
17
+ operation.throwIfAborted();
18
+ await previous;
19
19
 
20
- const { source } = fileV8Coverage
21
- let sources
20
+ const { source } = fileV8Coverage;
21
+ let sources;
22
22
  // when v8 coverage comes from playwright (chromium) v8Coverage.source is set
23
23
  if (typeof source === "string") {
24
- sources = { source }
24
+ sources = { source };
25
25
  }
26
26
  // when v8 coverage comes from Node.js, the source can be read from sourcemapCache
27
27
  else if (sourcemapCache) {
28
- sources = sourcesFromSourceMapCache(fileV8Coverage.url, sourcemapCache)
28
+ sources = sourcesFromSourceMapCache(fileV8Coverage.url, sourcemapCache);
29
29
  }
30
- const path = urlToFileSystemPath(fileV8Coverage.url)
30
+ const path = urlToFileSystemPath(fileV8Coverage.url);
31
31
 
32
32
  const converter = v8ToIstanbul(
33
33
  path,
@@ -35,65 +35,65 @@ export const v8CoverageToIstanbul = async (v8Coverage, { signal }) => {
35
35
  // https://github.com/istanbuljs/v8-to-istanbul/blob/2b54bc97c5edf8a37b39a171ec29134ba9bfd532/lib/v8-to-istanbul.js#L27
36
36
  undefined,
37
37
  sources,
38
- )
39
- await converter.load()
38
+ );
39
+ await converter.load();
40
40
 
41
- converter.applyCoverage(fileV8Coverage.functions)
42
- const istanbulCoverage = converter.toIstanbul()
41
+ converter.applyCoverage(fileV8Coverage.functions);
42
+ const istanbulCoverage = converter.toIstanbul();
43
43
 
44
44
  istanbulCoverageComposed = istanbulCoverageComposed
45
45
  ? composeTwoFileByFileIstanbulCoverages(
46
46
  istanbulCoverageComposed,
47
47
  istanbulCoverage,
48
48
  )
49
- : istanbulCoverage
50
- }, Promise.resolve())
49
+ : istanbulCoverage;
50
+ }, Promise.resolve());
51
51
 
52
52
  if (!istanbulCoverageComposed) {
53
- return {}
53
+ return {};
54
54
  }
55
- istanbulCoverageComposed = markAsConvertedFromV8(istanbulCoverageComposed)
56
- return istanbulCoverageComposed
55
+ istanbulCoverageComposed = markAsConvertedFromV8(istanbulCoverageComposed);
56
+ return istanbulCoverageComposed;
57
57
  } finally {
58
- await operation.end()
58
+ await operation.end();
59
59
  }
60
- }
60
+ };
61
61
 
62
62
  const markAsConvertedFromV8 = (fileByFileCoverage) => {
63
- const fileByFileMarked = {}
63
+ const fileByFileMarked = {};
64
64
  Object.keys(fileByFileCoverage).forEach((key) => {
65
- const fileCoverage = fileByFileCoverage[key]
65
+ const fileCoverage = fileByFileCoverage[key];
66
66
  fileByFileMarked[key] = {
67
67
  ...fileCoverage,
68
68
  fromV8: true,
69
- }
70
- })
71
- return fileByFileMarked
72
- }
69
+ };
70
+ });
71
+ return fileByFileMarked;
72
+ };
73
73
 
74
74
  const sourcesFromSourceMapCache = (url, sourceMapCache) => {
75
- const sourceMapAndLineLengths = sourceMapCache[url]
75
+ const sourceMapAndLineLengths = sourceMapCache[url];
76
76
  if (!sourceMapAndLineLengths) {
77
- return {}
77
+ return {};
78
78
  }
79
79
 
80
- const { data, lineLengths } = sourceMapAndLineLengths
80
+ const { data, lineLengths } = sourceMapAndLineLengths;
81
81
  // See: https://github.com/nodejs/node/pull/34305
82
82
  if (!data) {
83
- return undefined
83
+ return undefined;
84
84
  }
85
85
 
86
86
  const sources = {
87
87
  sourcemap: data,
88
88
  ...(lineLengths ? { source: sourcesFromLineLengths(lineLengths) } : {}),
89
- }
90
- return sources
91
- }
89
+ };
90
+ return sources;
91
+ };
92
92
 
93
93
  const sourcesFromLineLengths = (lineLengths) => {
94
- let source = ""
94
+ let source = "";
95
95
  lineLengths.forEach((length) => {
96
- source += `${"".padEnd(length, ".")}\n`
97
- })
98
- return source
99
- }
96
+ source += `${"".padEnd(length, ".")}\n`;
97
+ });
98
+ return source;
99
+ };
@@ -10,12 +10,12 @@
10
10
  * - Most of the logic lives in "./run.js" used by executeTestPlan to run tests
11
11
  */
12
12
 
13
- import { Abort, raceProcessTeardownEvents } from "@jsenv/abort"
14
- import { assertAndNormalizeDirectoryUrl } from "@jsenv/filesystem"
15
- import { createLogger } from "@jsenv/log"
13
+ import { Abort, raceProcessTeardownEvents } from "@jsenv/abort";
14
+ import { assertAndNormalizeDirectoryUrl } from "@jsenv/filesystem";
15
+ import { createLogger } from "@jsenv/log";
16
16
 
17
- import { assertAndNormalizeWebServer } from "./web_server_param.js"
18
- import { run } from "./run.js"
17
+ import { assertAndNormalizeWebServer } from "./web_server_param.js";
18
+ import { run } from "./run.js";
19
19
 
20
20
  export const execute = async ({
21
21
  signal = new AbortController().signal,
@@ -39,13 +39,13 @@ export const execute = async ({
39
39
 
40
40
  ignoreError = false,
41
41
  }) => {
42
- const logger = createLogger({ logLevel })
42
+ const logger = createLogger({ logLevel });
43
43
  rootDirectoryUrl = assertAndNormalizeDirectoryUrl(
44
44
  rootDirectoryUrl,
45
45
  "rootDirectoryUrl",
46
- )
47
- const executeOperation = Abort.startOperation()
48
- executeOperation.addAbortSignal(signal)
46
+ );
47
+ const executeOperation = Abort.startOperation();
48
+ executeOperation.addAbortSignal(signal);
49
49
  if (handleSIGINT) {
50
50
  executeOperation.addAbortSource((abort) => {
51
51
  return raceProcessTeardownEvents(
@@ -53,22 +53,22 @@ export const execute = async ({
53
53
  SIGINT: true,
54
54
  },
55
55
  abort,
56
- )
57
- })
56
+ );
57
+ });
58
58
  }
59
59
 
60
60
  if (runtime.type === "browser") {
61
- await assertAndNormalizeWebServer(webServer)
61
+ await assertAndNormalizeWebServer(webServer);
62
62
  }
63
63
 
64
- let resultTransformer = (result) => result
64
+ let resultTransformer = (result) => result;
65
65
  runtimeParams = {
66
66
  rootDirectoryUrl,
67
67
  webServer,
68
68
  fileRelativeUrl,
69
69
  importMap,
70
70
  ...runtimeParams,
71
- }
71
+ };
72
72
 
73
73
  let result = await run({
74
74
  signal: executeOperation.signal,
@@ -82,13 +82,13 @@ export const execute = async ({
82
82
  collectPerformance,
83
83
  runtime,
84
84
  runtimeParams,
85
- })
86
- result = resultTransformer(result)
85
+ });
86
+ result = resultTransformer(result);
87
87
 
88
88
  try {
89
89
  if (result.status === "failed") {
90
90
  if (ignoreError) {
91
- return result
91
+ return result;
92
92
  }
93
93
  /*
94
94
  Warning: when node launched with --unhandled-rejections=strict, despites
@@ -102,10 +102,10 @@ export const execute = async ({
102
102
  ```
103
103
  But it feels like a hack.
104
104
  */
105
- throw result.errors[result.errors.length - 1]
105
+ throw result.errors[result.errors.length - 1];
106
106
  }
107
- return result
107
+ return result;
108
108
  } finally {
109
- await executeOperation.end()
109
+ await executeOperation.end();
110
110
  }
111
- }
111
+ };