@jsenv/core 23.3.0 → 23.5.0

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 (36) hide show
  1. package/package.json +5 -5
  2. package/readme.md +4 -4
  3. package/src/execute.js +0 -6
  4. package/src/executeTestPlan.js +12 -10
  5. package/src/internal/browser-launcher/executeHtmlFile.js +20 -16
  6. package/src/internal/compiling/createCompiledFileService.js +13 -1
  7. package/src/internal/executing/coverage/babel_plugin_instrument.js +1 -0
  8. package/src/internal/executing/coverage/reportToCoverage.js +160 -119
  9. package/src/internal/executing/{coverage → coverage_missing}/createEmptyCoverage.js +0 -0
  10. package/src/internal/executing/coverage_missing/list_files_not_covered.js +20 -0
  11. package/src/internal/executing/coverage_missing/missing_coverage.js +46 -0
  12. package/src/internal/executing/{coverage → coverage_missing}/relativeUrlToEmptyCoverage.js +12 -8
  13. package/src/internal/executing/{coverage/generateCoverageHtmlDirectory.js → coverage_reporter/coverage_reporter_html_directory.js} +11 -4
  14. package/src/internal/executing/{coverage/generateCoverageJsonFile.js → coverage_reporter/coverage_reporter_json_file.js} +0 -0
  15. package/src/internal/executing/{coverage/generateCoverageTextLog.js → coverage_reporter/coverage_reporter_text_log.js} +4 -2
  16. package/src/internal/executing/{coverage → coverage_reporter}/istanbulCoverageMapFromCoverage.js +0 -0
  17. package/src/internal/executing/{coverage/normalizeIstanbulCoverage.js → coverage_utils/file_by_file_coverage.js} +9 -7
  18. package/src/internal/executing/coverage_utils/istanbul_coverage_composition.js +28 -0
  19. package/src/internal/executing/coverage_utils/v8_and_istanbul.js +38 -0
  20. package/src/internal/executing/coverage_utils/v8_coverage_composition.js +23 -0
  21. package/src/internal/executing/coverage_utils/v8_coverage_from_directory.js +77 -0
  22. package/src/internal/executing/{coverage/istanbulCoverageFromV8Coverage.js → coverage_utils/v8_coverage_to_istanbul.js} +38 -17
  23. package/src/internal/executing/createSummaryLog.js +5 -9
  24. package/src/internal/executing/executeConcurrently.js +199 -115
  25. package/src/internal/executing/executePlan.js +8 -5
  26. package/src/internal/executing/executionLogs.js +66 -37
  27. package/src/internal/executing/execution_colors.js +2 -1
  28. package/src/internal/executing/launchAndExecute.js +63 -58
  29. package/src/internal/logs/msAsDuration.js +4 -3
  30. package/src/launchBrowser.js +8 -8
  31. package/src/launchNode.js +5 -93
  32. package/src/internal/executing/coverage/composeIstanbulCoverages.js +0 -108
  33. package/src/internal/executing/coverage/composeV8Coverages.js +0 -20
  34. package/src/internal/executing/coverage/istanbulCoverageFromCoverages.js +0 -43
  35. package/src/internal/executing/coverage/v8CoverageFromAllV8Coverages.js +0 -40
  36. package/src/internal/executing/coverage/v8CoverageFromNodeV8Directory.js +0 -67
@@ -1,7 +1,9 @@
1
+ import cuid from "cuid"
1
2
  import { createLogger, createDetailedMessage } from "@jsenv/logger"
2
3
  import { Abort, raceCallbacks } from "@jsenv/abort"
4
+ import { resolveUrl, writeFile } from "@jsenv/filesystem"
3
5
 
4
- import { composeIstanbulCoverages } from "./coverage/composeIstanbulCoverages.js"
6
+ import { composeTwoFileByFileIstanbulCoverages } from "./coverage_utils/istanbul_coverage_composition.js"
5
7
 
6
8
  export const launchAndExecute = async ({
7
9
  signal = new AbortController().signal,
@@ -12,13 +14,11 @@ export const launchAndExecute = async ({
12
14
  executeParams,
13
15
 
14
16
  allocatedMs,
15
- measureDuration = false,
16
17
  mirrorConsole = false,
17
18
  captureConsole = false, // rename collectConsole ?
18
- collectRuntimeName = false,
19
- collectRuntimeVersion = false,
20
19
  inheritCoverage = false,
21
20
  collectCoverage = false,
21
+ coverageTempDirectoryUrl,
22
22
  measurePerformance,
23
23
  collectPerformance = false,
24
24
 
@@ -39,8 +39,6 @@ export const launchAndExecute = async ({
39
39
  // by default throw on error after execution
40
40
  throw error
41
41
  },
42
-
43
- coverageV8MergeConflictIsExpected,
44
42
  } = {}) => {
45
43
  const logger = createLogger({ logLevel: launchAndExecuteLogLevel })
46
44
 
@@ -101,25 +99,14 @@ export const launchAndExecute = async ({
101
99
  )
102
100
  }
103
101
 
104
- if (collectRuntimeName) {
105
- executionResultTransformer = composeTransformer(
106
- executionResultTransformer,
107
- (executionResult) => {
108
- executionResult.runtimeName = runtime.name
109
- return executionResult
110
- },
111
- )
112
- }
113
-
114
- if (collectRuntimeVersion) {
115
- executionResultTransformer = composeTransformer(
116
- executionResultTransformer,
117
- (executionResult) => {
118
- executionResult.runtimeVersion = runtime.version
119
- return executionResult
120
- },
121
- )
122
- }
102
+ executionResultTransformer = composeTransformer(
103
+ executionResultTransformer,
104
+ (executionResult) => {
105
+ executionResult.runtimeName = runtime.name
106
+ executionResult.runtimeVersion = runtime.version
107
+ return executionResult
108
+ },
109
+ )
123
110
 
124
111
  if (
125
112
  inheritCoverage &&
@@ -131,40 +118,61 @@ export const launchAndExecute = async ({
131
118
  executionResultTransformer = composeTransformer(
132
119
  executionResultTransformer,
133
120
  (executionResult) => {
134
- const { coverage, ...rest } = executionResult
135
- // ensure the coverage of the executed file is taken into account
136
- global.__coverage__ = composeIstanbulCoverages([
121
+ const { coverage } = executionResult
122
+ // propagate coverage from execution to this process
123
+ global.__coverage__ = composeTwoFileByFileIstanbulCoverages(
137
124
  global.__coverage__ || {},
138
125
  coverage || {},
139
- ])
140
- if (collectCoverageSaved) {
141
- return executionResult
126
+ )
127
+
128
+ if (!collectCoverageSaved) {
129
+ delete executionResult.coverage
142
130
  }
143
- return rest
131
+
132
+ return executionResult
144
133
  },
145
134
  )
146
135
  }
147
136
 
148
- // indirectCoverage is a feature making possible to collect
149
- // coverage generated by executing a node process which executes
150
- // a browser. The coverage coming the browser executionwould be lost
151
- // if not propagated somehow.
152
- // This is possible if the node process collect the browser coverage
153
- // and write it into global.__indirectCoverage__
154
- // This is used by jsenv during tests execution
155
137
  if (collectCoverage) {
156
138
  executionResultTransformer = composeTransformer(
157
139
  executionResultTransformer,
158
- (executionResult) => {
159
- const { coverage = {}, indirectCoverage } = executionResult
140
+ async (executionResult) => {
141
+ // we do not keep coverage in memory, it can grow very big
142
+ // instead we store it on the filesystem, they will be read and merged together later on
143
+ // in "executeConcurrently"
144
+ const { coverage } = executionResult
145
+ if (coverage) {
146
+ const coverageFileUrl = resolveUrl(
147
+ `./${runtime.name}/${cuid()}`,
148
+ coverageTempDirectoryUrl,
149
+ )
150
+ await writeFile(coverageFileUrl, JSON.stringify(coverage, null, " "))
151
+ executionResult.coverageFileUrl = coverageFileUrl
152
+ delete executionResult.coverage
153
+ }
154
+
155
+ // indirectCoverage is a feature making possible to collect
156
+ // coverage generated by executing a node process which executes
157
+ // a browser. The coverage coming the browser execution would be lost
158
+ // if not propagated somehow.
159
+ // This is possible if the node process collect the browser coverage
160
+ // and write it into global.__indirectCoverage__
161
+ // This is used by jsenv during tests execution
162
+ const { indirectCoverage } = executionResult
160
163
  if (indirectCoverage) {
161
- executionResult.coverage = composeIstanbulCoverages(
162
- [coverage, indirectCoverage],
163
- {
164
- coverageV8MergeConflictIsExpected,
165
- },
164
+ const indirectCoverageFileUrl = resolveUrl(
165
+ `./${runtime.name}/${cuid()}`,
166
+ coverageTempDirectoryUrl,
167
+ )
168
+ await writeFile(
169
+ indirectCoverageFileUrl,
170
+ JSON.stringify(indirectCoverage, null, " "),
166
171
  )
172
+ executionResult.indirectCoverageFileUrl = indirectCoverageFileUrl
173
+ delete executionResult.indirectCoverage
167
174
  }
175
+
168
176
  return executionResult
169
177
  },
170
178
  )
@@ -176,23 +184,20 @@ export const launchAndExecute = async ({
176
184
  // executionResult.coverage is undefined or {}
177
185
  // we delete it just to have a cleaner object
178
186
  delete executionResult.coverage
187
+ delete executionResult.indirectCoverage
179
188
  return executionResult
180
189
  },
181
190
  )
182
191
  }
183
192
 
184
- if (measureDuration) {
185
- const startMs = Date.now()
186
- executionResultTransformer = composeTransformer(
187
- executionResultTransformer,
188
- (executionResult) => {
189
- const endMs = Date.now()
190
- executionResult.startMs = startMs
191
- executionResult.endMs = endMs
192
- return executionResult
193
- },
194
- )
195
- }
193
+ const startMs = Date.now()
194
+ executionResultTransformer = composeTransformer(
195
+ executionResultTransformer,
196
+ (executionResult) => {
197
+ executionResult.duration = Date.now() - startMs
198
+ return executionResult
199
+ },
200
+ )
196
201
 
197
202
  try {
198
203
  const runtimeLabel = `${runtime.name}/${runtime.version}`
@@ -2,10 +2,11 @@ import { require } from "../require.js"
2
2
 
3
3
  const humanizeDuration = require("humanize-duration")
4
4
 
5
- export const msAsDuration = (metricValue) => {
6
- return humanizeDuration(metricValue, {
5
+ export const msAsDuration = (ms) => {
6
+ return humanizeDuration(ms, {
7
7
  largest: 2,
8
- maxDecimalPoints: metricValue < 0.1 ? 3 : metricValue < 1000 ? 2 : 1,
8
+ maxDecimalPoints: ms < 0.1 ? 3 : ms < 1000 ? 2 : ms < 60000 ? 1 : 0,
9
+ delimiter: " and ",
9
10
  // units: ["s"]
10
11
  })
11
12
  }
@@ -37,7 +37,7 @@ chromiumRuntime.launch = async ({
37
37
  collectPerformance,
38
38
  measurePerformance,
39
39
  collectCoverage,
40
- coverageConfig,
40
+ coverageIgnorePredicate,
41
41
  coverageForceIstanbul,
42
42
 
43
43
  headless = true,
@@ -115,7 +115,7 @@ chromiumRuntime.launch = async ({
115
115
  collectPerformance,
116
116
  measurePerformance,
117
117
  collectCoverage,
118
- coverageConfig,
118
+ coverageIgnorePredicate,
119
119
  coverageForceIstanbul,
120
120
  coveragePlaywrightAPIAvailable: true,
121
121
  })
@@ -151,7 +151,7 @@ firefoxRuntime.launch = async ({
151
151
  collectPerformance,
152
152
  measurePerformance,
153
153
  collectCoverage,
154
- coverageConfig,
154
+ coverageIgnorePredicate,
155
155
  coverageForceIstanbul,
156
156
 
157
157
  headless = true,
@@ -194,7 +194,7 @@ firefoxRuntime.launch = async ({
194
194
  collectPerformance,
195
195
  measurePerformance,
196
196
  collectCoverage,
197
- coverageConfig,
197
+ coverageIgnorePredicate,
198
198
  coverageForceIstanbul,
199
199
  })
200
200
 
@@ -229,7 +229,7 @@ webkitRuntime.launch = async ({
229
229
  collectPerformance,
230
230
  measurePerformance,
231
231
  collectCoverage,
232
- coverageConfig,
232
+ coverageIgnorePredicate,
233
233
  coverageForceIstanbul,
234
234
 
235
235
  headless = true,
@@ -272,7 +272,7 @@ webkitRuntime.launch = async ({
272
272
  collectPerformance,
273
273
  measurePerformance,
274
274
  collectCoverage,
275
- coverageConfig,
275
+ coverageIgnorePredicate,
276
276
  coverageForceIstanbul,
277
277
  ignoreErrorHook: (error) => {
278
278
  // we catch error during execution but safari throw unhandled rejection
@@ -378,7 +378,7 @@ const browserToRuntimeHooks = (
378
378
  collectPerformance,
379
379
  measurePerformance,
380
380
  collectCoverage,
381
- coverageConfig,
381
+ coverageIgnorePredicate,
382
382
  coverageForceIstanbul,
383
383
  coveragePlaywrightAPIAvailable = false,
384
384
  ignoreErrorHook = () => false,
@@ -451,9 +451,9 @@ const browserToRuntimeHooks = (
451
451
  measurePerformance,
452
452
  collectPerformance,
453
453
  collectCoverage,
454
- coverageConfig,
455
454
  coverageForceIstanbul,
456
455
  coveragePlaywrightAPIAvailable,
456
+ coverageIgnorePredicate,
457
457
  transformErrorHook,
458
458
  })
459
459
  return result
package/src/launchNode.js CHANGED
@@ -1,18 +1,9 @@
1
1
  import { Script } from "node:vm"
2
- import cuid from "cuid"
3
2
  import { loggerToLogLevel } from "@jsenv/logger"
4
- import {
5
- writeDirectory,
6
- resolveUrl,
7
- urlToFileSystemPath,
8
- removeFileSystemNode,
9
- moveDirectoryContent,
10
- } from "@jsenv/filesystem"
11
3
 
12
4
  import { jsenvCoreDirectoryUrl } from "@jsenv/core/src/internal/jsenvCoreDirectoryUrl.js"
13
5
  import { escapeRegexpSpecialCharacters } from "./internal/escapeRegexpSpecialCharacters.js"
14
6
  import { createControllableNodeProcess } from "./internal/node-launcher/createControllableNodeProcess.js"
15
- import { v8CoverageFromNodeV8Directory } from "./internal/executing/coverage/v8CoverageFromNodeV8Directory.js"
16
7
 
17
8
  export const nodeRuntime = {
18
9
  name: "node",
@@ -30,8 +21,8 @@ nodeRuntime.launch = async ({
30
21
  measurePerformance,
31
22
  collectPerformance,
32
23
  collectCoverage = false,
33
- coverageConfig,
34
24
  coverageForceIstanbul,
25
+ coverageConfig,
35
26
 
36
27
  debugPort,
37
28
  debugMode,
@@ -69,59 +60,10 @@ nodeRuntime.launch = async ({
69
60
  JSENV: true,
70
61
  }
71
62
 
72
- let finalizeExecutionResult
73
-
74
- if (collectCoverage) {
75
- // v8 coverage is written in a directoy and auto propagate to subprocesses
76
- // through process.env.NODE_V8_COVERAGE.
77
-
78
- if (coverageForceIstanbul) {
79
- // if we want to force istanbul, we will set process.env.NODE_V8_COVERAGE = ''
80
- // into the child_process
81
- env.NODE_V8_COVERAGE = ""
82
- }
83
- // } else if (process.env.NODE_V8_COVERAGE) {
84
- // // The V8_COVERAGE was already set by a parent process or command line.
85
- // // It's the caller that is interested into coverage, it's not anymore this script
86
- // // responsability to set process.env.NODE_V8_COVERAGE nor to read
87
- // // coverage files in the v8 directory.
88
- // }
89
- // In fact it is so that it's possible to go coverageception:
90
- // jsenv collect coverage for tests
91
- // which are testing that coverage can be collected for tests
92
- // this is possible because we overriding the child process NODE_V8_COVERAGE
93
- else {
94
- const NODE_V8_COVERAGE = await getNodeV8CoverageDir({
95
- projectDirectoryUrl,
96
- })
97
- env.NODE_V8_COVERAGE = NODE_V8_COVERAGE
98
-
99
- // the v8 coverage directory is available once the child process is disconnected
100
- finalizeExecutionResult = async (executionResult) => {
101
- if (
102
- executionResult.status === "timedout" ||
103
- executionResult.status === "aborted"
104
- ) {
105
- return executionResult
106
- }
107
-
108
- const coverage = await ensureV8CoverageDirClean(async () => {
109
- // prefer istanbul if available
110
- if (executionResult.coverage) {
111
- return executionResult.coverage
112
- }
113
-
114
- const v8Coverage = await v8CoverageFromNodeV8Directory({
115
- projectDirectoryUrl,
116
- NODE_V8_COVERAGE,
117
- coverageConfig,
118
- })
119
- return v8Coverage
120
- }, NODE_V8_COVERAGE)
121
- executionResult.coverage = coverage
122
- return executionResult
123
- }
124
- }
63
+ if (coverageForceIstanbul) {
64
+ // if we want to force istanbul, we will set process.env.NODE_V8_COVERAGE = ''
65
+ // into the child_process
66
+ env.NODE_V8_COVERAGE = ""
125
67
  }
126
68
 
127
69
  commandLineOptions = [
@@ -198,39 +140,9 @@ nodeRuntime.launch = async ({
198
140
  outputCallbackList,
199
141
  stop,
200
142
  execute,
201
- finalizeExecutionResult,
202
143
  }
203
144
  }
204
145
 
205
- const ensureV8CoverageDirClean = async (fn, NODE_V8_COVERAGE) => {
206
- try {
207
- return await fn()
208
- } finally {
209
- if (process.env.NODE_V8_COVERAGE === NODE_V8_COVERAGE) {
210
- // do not try to remove or copy coverage
211
- } else if (process.env.NODE_V8_COVERAGE) {
212
- await moveDirectoryContent({
213
- from: NODE_V8_COVERAGE,
214
- to: process.env.NODE_V8_COVERAGE,
215
- })
216
- await removeFileSystemNode(NODE_V8_COVERAGE, {})
217
- } else {
218
- await removeFileSystemNode(NODE_V8_COVERAGE, {
219
- recursive: true,
220
- })
221
- }
222
- }
223
- }
224
-
225
- const getNodeV8CoverageDir = async ({ projectDirectoryUrl }) => {
226
- const v8CoverageDirectory = resolveUrl(
227
- `./coverage-v8/${cuid()}`,
228
- projectDirectoryUrl,
229
- )
230
- await writeDirectory(v8CoverageDirectory, { allowUseless: true })
231
- return urlToFileSystemPath(v8CoverageDirectory)
232
- }
233
-
234
146
  const transformExecutionResult = (
235
147
  executionResult,
236
148
  { compileServerOrigin, projectDirectoryUrl },
@@ -1,108 +0,0 @@
1
- import { require } from "../../require.js"
2
-
3
- // https://github.com/istanbuljs/istanbuljs/blob/5405550c3868712b14fd8bfe0cbd6f2e7ac42279/packages/istanbul-lib-coverage/lib/coverage-map.js#L43
4
- export const composeIstanbulCoverages = (
5
- istanbulCoverages,
6
- { coverageV8MergeConflictIsExpected = false } = {},
7
- ) => {
8
- const coverageComposed = {}
9
-
10
- // we can't merge coverage coming from code instrumented by istanbul
11
- // with coverage coming from v8 and converted to istanbul, so we want to:
12
- // 1. Have istanbul and v8 as long as they don't cover the same file
13
- // 2. Choose istanbul or v8 depending which one cover the most
14
- // To do that we first merge all v8 together and istanbul together
15
- // To be able to know which one covers the most in case of merge conflict
16
- const coverageFromV8Conversion = {}
17
- const coverageFromIstanbul = {}
18
- istanbulCoverages.forEach((istanbulCoverage) => {
19
- Object.keys(istanbulCoverage).forEach((key) => {
20
- const istanbulFileCoverage = istanbulCoverage[key]
21
- if (istanbulFileCoverage.fromV8) {
22
- const existingCoverageForFile = coverageFromV8Conversion[key]
23
- if (existingCoverageForFile) {
24
- coverageFromV8Conversion[key] = merge(existingCoverageForFile, istanbulFileCoverage)
25
- } else {
26
- coverageFromV8Conversion[key] = istanbulFileCoverage
27
- }
28
- } else {
29
- const existingCoverageForFile = coverageFromIstanbul[key]
30
- if (existingCoverageForFile) {
31
- coverageFromIstanbul[key] = merge(existingCoverageForFile, istanbulFileCoverage)
32
- } else {
33
- coverageFromIstanbul[key] = istanbulFileCoverage
34
- }
35
- }
36
- })
37
- })
38
-
39
- Object.keys(coverageFromV8Conversion).forEach((key) => {
40
- const fileCoverageFromV8 = coverageFromV8Conversion[key]
41
- const fileCoverageFromIstanbul = coverageFromIstanbul[key]
42
- if (fileCoverageFromIstanbul) {
43
- const v8HitCount = hitCountFromFileCoverage(fileCoverageFromV8)
44
- const istanbulHitCount = hitCountFromFileCoverage(fileCoverageFromIstanbul)
45
- const coverageWithMostHit =
46
- v8HitCount >= istanbulHitCount ? fileCoverageFromV8 : fileCoverageFromIstanbul
47
-
48
- if (!coverageV8MergeConflictIsExpected) {
49
- // ideally when coverageV8MergeConflictIsExpected it would be a console.debug
50
- console.warn(
51
- formatMergeConflictBetweenV8AndIstanbulWarning({
52
- fileRelativeUrl: key,
53
- coverageKept: coverageWithMostHit,
54
- }),
55
- )
56
- }
57
- coverageComposed[key] = coverageWithMostHit
58
- } else {
59
- coverageComposed[key] = fileCoverageFromV8
60
- }
61
- })
62
-
63
- Object.keys(coverageFromIstanbul).forEach((key) => {
64
- const fileCoverageFromIstanbul = coverageFromIstanbul[key]
65
- const fileCoverageFromV8 = coverageFromV8Conversion[key]
66
- if (fileCoverageFromV8) {
67
- // already handled
68
- } else {
69
- coverageComposed[key] = fileCoverageFromIstanbul
70
- }
71
- })
72
-
73
- return coverageComposed
74
- }
75
-
76
- const hitCountFromFileCoverage = ({ b, s }) => {
77
- const statementHitCount = Object.keys(s).reduce((previous, key) => {
78
- return previous + s[key]
79
- }, 0)
80
-
81
- const branchHitCount = Object.keys(b).reduce((previous, key) => {
82
- const branchCount = b[key].reduce((previous, count) => {
83
- return previous + count
84
- }, 0)
85
- return previous + branchCount
86
- }, 0)
87
-
88
- return statementHitCount + branchHitCount
89
- }
90
-
91
- const merge = (istanbulFileCoverageA, istanbulFileCoverageB) => {
92
- const { createFileCoverage } = require("istanbul-lib-coverage")
93
- const istanbulFileCoverageObject = createFileCoverage(istanbulFileCoverageA)
94
- istanbulFileCoverageObject.merge(istanbulFileCoverageB)
95
- return istanbulFileCoverageObject.toJSON()
96
- }
97
-
98
- const formatMergeConflictBetweenV8AndIstanbulWarning = ({ fileRelativeUrl, coverageKept }) => {
99
- return `Cannot merge file coverage coming from v8 and istanbul.
100
- The one with most branch coverage will be kept and the other ignored.
101
- --- coverage kept ---
102
- ${coverageKept.fromV8 ? "v8" : "istanbul"}
103
- --- file ---
104
- ${fileRelativeUrl}
105
- --- suggestion ---
106
- If this is expected use coverageV8MergeConflictIsExpected to disable this warning
107
- `
108
- }
@@ -1,20 +0,0 @@
1
- import { require } from "@jsenv/core/src/internal/require.js"
2
-
3
- export const composeV8Coverages = (v8Coverages) => {
4
- const { mergeProcessCovs } = require("@c88/v8-coverage")
5
-
6
- // mergeCoverageReports do not preserves source-map-cache during the merge
7
- // so we store sourcemap cache now
8
- const sourceMapCache = {}
9
- v8Coverages.forEach((coverageReport) => {
10
- coverageReport.result.forEach((fileReport) => {
11
- if (fileReport["source-map-cache"]) {
12
- Object.assign(sourceMapCache, fileReport["source-map-cache"])
13
- }
14
- })
15
- })
16
-
17
- const v8Coverage = mergeProcessCovs(v8Coverages)
18
- v8Coverage["source-map-cache"] = sourceMapCache
19
- return v8Coverage
20
- }
@@ -1,43 +0,0 @@
1
- /**
2
- *
3
- * The goal is to get an istanbul coverage from a list of coverage that are either
4
- * v8Coverage or istanbul coverage
5
- *
6
- */
7
-
8
- import { composeV8Coverages } from "./composeV8Coverages.js"
9
- import { composeIstanbulCoverages } from "./composeIstanbulCoverages.js"
10
- import { istanbulCoverageFromV8Coverage } from "./istanbulCoverageFromV8Coverage.js"
11
- import { normalizeIstanbulCoverage } from "./normalizeIstanbulCoverage.js"
12
-
13
- export const istanbulCoverageFromCoverages = async (
14
- coverages,
15
- { projectDirectoryUrl, coverageV8MergeConflictIsExpected },
16
- ) => {
17
- const v8Coverages = []
18
- const istanbulCoverages = []
19
-
20
- coverages.forEach((coverage) => {
21
- if (coverage.result) {
22
- v8Coverages.push(coverage)
23
- } else {
24
- istanbulCoverages.push(normalizeIstanbulCoverage(coverage, projectDirectoryUrl))
25
- }
26
- })
27
-
28
- const v8CoverageComposed = composeV8Coverages(v8Coverages)
29
- const istanbulCoverageComposed = composeIstanbulCoverages(istanbulCoverages)
30
- const istanbulCoverageFromV8CoverageComposed = await istanbulCoverageFromV8Coverage(
31
- v8CoverageComposed,
32
- )
33
- const istanbulCoverage = composeIstanbulCoverages(
34
- [
35
- istanbulCoverageComposed,
36
- normalizeIstanbulCoverage(istanbulCoverageFromV8CoverageComposed, projectDirectoryUrl),
37
- ],
38
- {
39
- coverageV8MergeConflictIsExpected,
40
- },
41
- )
42
- return istanbulCoverage
43
- }
@@ -1,40 +0,0 @@
1
- import { resolveUrl, normalizeStructuredMetaMap, urlToMeta } from "@jsenv/filesystem"
2
-
3
- import { composeV8Coverages } from "./composeV8Coverages.js"
4
-
5
- export const v8CoverageFromAllV8Coverages = (
6
- allV8Coverages,
7
- { coverageRootUrl, coverageConfig },
8
- ) => {
9
- const v8Coverages = filterCoverageReports(allV8Coverages, {
10
- coverageRootUrl,
11
- coverageConfig,
12
- })
13
-
14
- const v8Coverage = composeV8Coverages(v8Coverages)
15
- return v8Coverage
16
- }
17
-
18
- const filterCoverageReports = (coverageReports, { coverageRootUrl, coverageConfig }) => {
19
- const structuredMetaMapForCover = normalizeStructuredMetaMap(
20
- {
21
- cover: coverageConfig,
22
- },
23
- coverageRootUrl,
24
- )
25
- const shouldIgnoreCoverage = (url) => {
26
- return !urlToMeta({
27
- url: resolveUrl(url, coverageRootUrl),
28
- structuredMetaMap: structuredMetaMapForCover,
29
- }).cover
30
- }
31
-
32
- return coverageReports.map((coverageReport) => {
33
- return {
34
- ...coverageReport,
35
- result: coverageReport.result.filter((fileReport) => {
36
- return !shouldIgnoreCoverage(fileReport.url)
37
- }),
38
- }
39
- })
40
- }
@@ -1,67 +0,0 @@
1
- import {
2
- assertAndNormalizeDirectoryUrl,
3
- readDirectory,
4
- readFile,
5
- resolveUrl,
6
- } from "@jsenv/filesystem"
7
- import { createDetailedMessage } from "@jsenv/logger"
8
-
9
- import { v8CoverageFromAllV8Coverages } from "./v8CoverageFromAllV8Coverages.js"
10
-
11
- export const v8CoverageFromNodeV8Directory = async ({
12
- projectDirectoryUrl,
13
- NODE_V8_COVERAGE,
14
- coverageConfig,
15
- }) => {
16
- const allV8Coverages = await readV8CoverageReportsFromDirectory(
17
- NODE_V8_COVERAGE,
18
- )
19
-
20
- const v8Coverage = v8CoverageFromAllV8Coverages(allV8Coverages, {
21
- coverageRootUrl: projectDirectoryUrl,
22
- coverageConfig,
23
- })
24
-
25
- return v8Coverage
26
- }
27
-
28
- const readV8CoverageReportsFromDirectory = async (coverageDirectory) => {
29
- const tryReadDirectory = async () => {
30
- const dirContent = await readDirectory(coverageDirectory)
31
- if (dirContent.length > 0) {
32
- return dirContent
33
- }
34
- console.warn(`v8 coverage directory is empty at ${coverageDirectory}`)
35
- return dirContent
36
- }
37
- const dirContent = await tryReadDirectory()
38
-
39
- const coverageReports = []
40
- const coverageDirectoryUrl = assertAndNormalizeDirectoryUrl(coverageDirectory)
41
- await Promise.all(
42
- dirContent.map(async (dirEntry) => {
43
- const dirEntryUrl = resolveUrl(dirEntry, coverageDirectoryUrl)
44
- const tryReadJsonFile = async () => {
45
- try {
46
- const fileContent = await readFile(dirEntryUrl, { as: "json" })
47
- return fileContent
48
- } catch (e) {
49
- console.warn(
50
- createDetailedMessage(`Error while reading coverage file`, {
51
- "error stack": e.stack,
52
- "file": dirEntryUrl,
53
- }),
54
- )
55
- return null
56
- }
57
- }
58
-
59
- const fileContent = await tryReadJsonFile()
60
- if (fileContent) {
61
- coverageReports.push(fileContent)
62
- }
63
- }),
64
- )
65
-
66
- return coverageReports
67
- }