@jsenv/core 23.2.2 → 23.4.2
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.
- package/{license → LICENSE} +0 -0
- package/package.json +13 -14
- package/readme.md +4 -4
- package/src/buildProject.js +12 -13
- package/src/execute.js +92 -93
- package/src/executeTestPlan.js +9 -8
- package/src/internal/browser-launcher/executeHtmlFile.js +26 -23
- package/src/internal/building/buildUsingRollup.js +3 -4
- package/src/internal/building/build_logs.js +7 -6
- package/src/internal/building/createJsenvRollupPlugin.js +9 -14
- package/src/internal/building/url_trace.js +3 -4
- package/src/internal/compiling/createCompiledFileService.js +21 -6
- package/src/internal/compiling/startCompileServer.js +55 -46
- package/src/internal/executing/coverage/babel_plugin_instrument.js +1 -0
- package/src/internal/executing/coverage/reportToCoverage.js +147 -120
- package/src/internal/executing/{coverage → coverage_empty}/createEmptyCoverage.js +0 -0
- package/src/internal/executing/coverage_empty/list_files_not_covered.js +20 -0
- package/src/internal/executing/{coverage → coverage_empty}/relativeUrlToEmptyCoverage.js +3 -4
- package/src/internal/executing/{coverage/generateCoverageHtmlDirectory.js → coverage_reporter/coverage_reporter_html_directory.js} +11 -4
- package/src/internal/executing/{coverage/generateCoverageJsonFile.js → coverage_reporter/coverage_reporter_json_file.js} +0 -0
- package/src/internal/executing/{coverage/generateCoverageTextLog.js → coverage_reporter/coverage_reporter_text_log.js} +4 -2
- package/src/internal/executing/{coverage → coverage_reporter}/istanbulCoverageMapFromCoverage.js +0 -0
- package/src/internal/executing/{coverage/normalizeIstanbulCoverage.js → coverage_utils/file_by_file_coverage.js} +9 -7
- package/src/internal/executing/coverage_utils/istanbul_coverage_composition.js +28 -0
- package/src/internal/executing/coverage_utils/v8_and_istanbul.js +38 -0
- package/src/internal/executing/coverage_utils/v8_coverage_composition.js +23 -0
- package/src/internal/executing/coverage_utils/v8_coverage_from_directory.js +65 -0
- package/src/internal/executing/coverage_utils/v8_coverage_to_istanbul.js +90 -0
- package/src/internal/executing/createSummaryLog.js +15 -15
- package/src/internal/executing/executeConcurrently.js +92 -32
- package/src/internal/executing/executePlan.js +84 -81
- package/src/internal/executing/executionLogs.js +14 -18
- package/src/internal/executing/execution_colors.js +6 -12
- package/src/internal/executing/launchAndExecute.js +172 -169
- package/src/internal/node-launcher/createControllableNodeProcess.js +26 -23
- package/src/launchBrowser.js +72 -69
- package/src/launchNode.js +11 -99
- package/src/startExploring.js +2 -17
- package/src/abort/abortable.js +0 -172
- package/src/abort/callback_list.js +0 -64
- package/src/abort/callback_race.js +0 -34
- package/src/abort/cleaner.js +0 -22
- package/src/abort/main.js +0 -32
- package/src/abort/process_teardown_events.js +0 -59
- package/src/internal/createCallbackList.js +0 -21
- package/src/internal/executing/coverage/composeIstanbulCoverages.js +0 -108
- package/src/internal/executing/coverage/composeV8Coverages.js +0 -20
- package/src/internal/executing/coverage/istanbulCoverageFromCoverages.js +0 -43
- package/src/internal/executing/coverage/istanbulCoverageFromV8Coverage.js +0 -79
- package/src/internal/executing/coverage/v8CoverageFromAllV8Coverages.js +0 -40
- package/src/internal/executing/coverage/v8CoverageFromNodeV8Directory.js +0 -67
- package/src/internal/executing/logUtils.js +0 -30
- package/src/internal/executing/writeLog.js +0 -106
- package/src/internal/executing/writeLog.test-manual.js +0 -62
- package/src/internal/logs/log_style.js +0 -40
- package/src/signal/signal.js +0 -65
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
export const createCallbackList = () => {
|
|
2
|
-
let callbacks = []
|
|
3
|
-
|
|
4
|
-
const add = (callback) => {
|
|
5
|
-
if (typeof callback !== "function") {
|
|
6
|
-
throw new Error(`callback must be a function, got ${callback}`)
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
// don't register twice
|
|
10
|
-
const existingCallback = callbacks.find((callbackCandidate) => {
|
|
11
|
-
return callbackCandidate === callback
|
|
12
|
-
})
|
|
13
|
-
if (existingCallback) {
|
|
14
|
-
if (typeof process.emitWarning === "object") {
|
|
15
|
-
process.emitWarning(`Trying to register same callback twice`, {
|
|
16
|
-
CODE: "CALLBACK_DUPLICATION",
|
|
17
|
-
detail: `It's often the sign that code is executd more than once`,
|
|
18
|
-
})
|
|
19
|
-
} else {
|
|
20
|
-
console.warn(`Trying to add same callback twice`)
|
|
21
|
-
}
|
|
22
|
-
} else {
|
|
23
|
-
callbacks = [...callbacks, callback]
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
return () => {
|
|
27
|
-
remove(callback)
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
const remove = (callback) => {
|
|
32
|
-
callbacks = arrayWithout(callbacks, callback)
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
const clear = () => {
|
|
36
|
-
callbacks = []
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
const copy = () => {
|
|
40
|
-
return callbacks.slice()
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
return {
|
|
44
|
-
add,
|
|
45
|
-
remove,
|
|
46
|
-
clear,
|
|
47
|
-
copy,
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
const arrayWithout = (array, item) => {
|
|
52
|
-
if (array.length === 0) return array
|
|
53
|
-
const arrayWithoutItem = []
|
|
54
|
-
let i = 0
|
|
55
|
-
while (i < array.length) {
|
|
56
|
-
const value = array[i]
|
|
57
|
-
i++
|
|
58
|
-
if (value === item) {
|
|
59
|
-
continue
|
|
60
|
-
}
|
|
61
|
-
arrayWithoutItem.push(value)
|
|
62
|
-
}
|
|
63
|
-
return arrayWithoutItem
|
|
64
|
-
}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* See callback_race.md
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
export const raceCallbacks = (raceDescription, winnerCallback) => {
|
|
6
|
-
const cleanCallbacks = []
|
|
7
|
-
let done = false
|
|
8
|
-
|
|
9
|
-
const cleanup = () => {
|
|
10
|
-
const cleanCallbacksCopy = cleanCallbacks.slice()
|
|
11
|
-
cleanCallbacks.length = 0
|
|
12
|
-
cleanCallbacksCopy.forEach((clean) => {
|
|
13
|
-
clean()
|
|
14
|
-
})
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
Object.keys(raceDescription).forEach((candidateName) => {
|
|
18
|
-
const register = raceDescription[candidateName]
|
|
19
|
-
const returnValue = register((data) => {
|
|
20
|
-
if (done) return
|
|
21
|
-
done = true
|
|
22
|
-
cleanup()
|
|
23
|
-
winnerCallback({
|
|
24
|
-
name: candidateName,
|
|
25
|
-
data,
|
|
26
|
-
})
|
|
27
|
-
})
|
|
28
|
-
if (typeof returnValue === "function") {
|
|
29
|
-
cleanCallbacks.push(returnValue)
|
|
30
|
-
}
|
|
31
|
-
})
|
|
32
|
-
|
|
33
|
-
return cleanup
|
|
34
|
-
}
|
package/src/abort/cleaner.js
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { createCallbackList } from "./callback_list.js"
|
|
2
|
-
|
|
3
|
-
export const createCleaner = () => {
|
|
4
|
-
const callbackList = createCallbackList()
|
|
5
|
-
|
|
6
|
-
const addCallback = (callback) => {
|
|
7
|
-
return callbackList.add(callback)
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
const clean = async (reason) => {
|
|
11
|
-
const callbacks = callbackList.copy()
|
|
12
|
-
callbackList.clear()
|
|
13
|
-
|
|
14
|
-
await Promise.all(
|
|
15
|
-
callbacks.map(async (callback) => {
|
|
16
|
-
await callback(reason)
|
|
17
|
-
}),
|
|
18
|
-
)
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
return { addCallback, clean }
|
|
22
|
-
}
|
package/src/abort/main.js
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* When starting an http server there is two distinct things
|
|
3
|
-
* that code may want to do:
|
|
4
|
-
* 1. Abort the server while it's starting
|
|
5
|
-
* 2. Stop server onces its started
|
|
6
|
-
*
|
|
7
|
-
* This can be achieved with the following code where
|
|
8
|
-
* server is aborted if it takes more than 1s to start
|
|
9
|
-
* and immediatly stopped once started
|
|
10
|
-
*
|
|
11
|
-
* const abortController = new AbortController()
|
|
12
|
-
* setTimeout(() => { abortController.abort() }, 1000)
|
|
13
|
-
* const server = await startServer({
|
|
14
|
-
* abortSignal: abortController.signal
|
|
15
|
-
* })
|
|
16
|
-
* await server.stop()
|
|
17
|
-
*
|
|
18
|
-
* In order to implement this kind of API two helpers are exported
|
|
19
|
-
* here:
|
|
20
|
-
* 1. "Abort" which can be used to throw an abort error
|
|
21
|
-
* while server is starting
|
|
22
|
-
* 2. "Cleanup" which can be used to track how to cleanup all the things
|
|
23
|
-
* done to start the server
|
|
24
|
-
*
|
|
25
|
-
* Same concepts could be reused when spwaning a child process, a worker, etc..
|
|
26
|
-
*
|
|
27
|
-
*/
|
|
28
|
-
|
|
29
|
-
export { Abortable } from "./abortable.js"
|
|
30
|
-
|
|
31
|
-
// when will be a package this should be a Node.js export only
|
|
32
|
-
export { raceProcessTeardownEvents } from "./process_teardown_events.js"
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import { raceCallbacks } from "./callback_race.js"
|
|
2
|
-
|
|
3
|
-
export const raceProcessTeardownEvents = (processTeardownEvents, callback) => {
|
|
4
|
-
return raceCallbacks(
|
|
5
|
-
{
|
|
6
|
-
...(processTeardownEvents.SIGHUP ? SIGHUP_CALLBACK : {}),
|
|
7
|
-
...(processTeardownEvents.SIGTERM ? SIGTERM_CALLBACK : {}),
|
|
8
|
-
...(processTeardownEvents.SIGINT ? SIGINT_CALLBACK : {}),
|
|
9
|
-
...(processTeardownEvents.beforeExit ? BEFORE_EXIT_CALLBACK : {}),
|
|
10
|
-
...(processTeardownEvents.exit ? EXIT_CALLBACK : {}),
|
|
11
|
-
},
|
|
12
|
-
callback,
|
|
13
|
-
)
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
const SIGHUP_CALLBACK = {
|
|
17
|
-
SIGHUP: (cb) => {
|
|
18
|
-
process.on("SIGHUP", cb)
|
|
19
|
-
return () => {
|
|
20
|
-
process.removeListener("SIGHUP", cb)
|
|
21
|
-
}
|
|
22
|
-
},
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
const SIGTERM_CALLBACK = {
|
|
26
|
-
SIGTERM: (cb) => {
|
|
27
|
-
process.on("SIGTERM", cb)
|
|
28
|
-
return () => {
|
|
29
|
-
process.removeListener("SIGTERM", cb)
|
|
30
|
-
}
|
|
31
|
-
},
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
const BEFORE_EXIT_CALLBACK = {
|
|
35
|
-
beforeExit: (cb) => {
|
|
36
|
-
process.on("beforeExit", cb)
|
|
37
|
-
return () => {
|
|
38
|
-
process.removeListener("beforeExit", cb)
|
|
39
|
-
}
|
|
40
|
-
},
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
const EXIT_CALLBACK = {
|
|
44
|
-
exit: (cb) => {
|
|
45
|
-
process.on("exit", cb)
|
|
46
|
-
return () => {
|
|
47
|
-
process.removeListener("exit", cb)
|
|
48
|
-
}
|
|
49
|
-
},
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
const SIGINT_CALLBACK = {
|
|
53
|
-
SIGINT: (cb) => {
|
|
54
|
-
process.on("SIGINT", cb)
|
|
55
|
-
return () => {
|
|
56
|
-
process.removeListener("SIGINT", cb)
|
|
57
|
-
}
|
|
58
|
-
},
|
|
59
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
export const createCallbackList = () => {
|
|
2
|
-
const callbackSet = new Set()
|
|
3
|
-
|
|
4
|
-
const register = (callback) => {
|
|
5
|
-
callbackSet.add(callback)
|
|
6
|
-
return () => {
|
|
7
|
-
callbackSet.delete(callback)
|
|
8
|
-
}
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
const notify = (...args) => {
|
|
12
|
-
callbackSet.forEach((callback) => {
|
|
13
|
-
callback(...args)
|
|
14
|
-
})
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
return {
|
|
18
|
-
register,
|
|
19
|
-
notify,
|
|
20
|
-
}
|
|
21
|
-
}
|
|
@@ -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,79 +0,0 @@
|
|
|
1
|
-
import { urlToFileSystemPath } from "@jsenv/filesystem"
|
|
2
|
-
|
|
3
|
-
import { require } from "@jsenv/core/src/internal/require.js"
|
|
4
|
-
|
|
5
|
-
import { composeIstanbulCoverages } from "./composeIstanbulCoverages.js"
|
|
6
|
-
|
|
7
|
-
export const istanbulCoverageFromV8Coverage = async (v8Coverage) => {
|
|
8
|
-
const v8ToIstanbul = require("v8-to-istanbul")
|
|
9
|
-
const sourcemapCache = v8Coverage["source-map-cache"]
|
|
10
|
-
const istanbulCoverages = await Promise.all(
|
|
11
|
-
v8Coverage.result.map(async (fileV8Coverage) => {
|
|
12
|
-
const { source } = fileV8Coverage
|
|
13
|
-
let sources
|
|
14
|
-
// when v8 coverage comes from playwright (chromium) v8Coverage.source is set
|
|
15
|
-
if (typeof source === "string") {
|
|
16
|
-
sources = { source }
|
|
17
|
-
}
|
|
18
|
-
// when v8 coverage comes from Node.js, the source can be read from sourcemapCache
|
|
19
|
-
else if (sourcemapCache) {
|
|
20
|
-
sources = sourcesFromSourceMapCache(fileV8Coverage.url, sourcemapCache)
|
|
21
|
-
}
|
|
22
|
-
const path = urlToFileSystemPath(fileV8Coverage.url)
|
|
23
|
-
|
|
24
|
-
const converter = v8ToIstanbul(
|
|
25
|
-
path,
|
|
26
|
-
// wrapperLength is undefined we don't need it
|
|
27
|
-
// https://github.com/istanbuljs/v8-to-istanbul/blob/2b54bc97c5edf8a37b39a171ec29134ba9bfd532/lib/v8-to-istanbul.js#L27
|
|
28
|
-
undefined,
|
|
29
|
-
sources,
|
|
30
|
-
)
|
|
31
|
-
await converter.load()
|
|
32
|
-
|
|
33
|
-
converter.applyCoverage(fileV8Coverage.functions)
|
|
34
|
-
const istanbulCoverage = converter.toIstanbul()
|
|
35
|
-
return istanbulCoverage
|
|
36
|
-
}),
|
|
37
|
-
)
|
|
38
|
-
|
|
39
|
-
const istanbulCoverageComposed = composeIstanbulCoverages(istanbulCoverages)
|
|
40
|
-
return markCoverageAsConverted(istanbulCoverageComposed)
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
const markCoverageAsConverted = (istanbulCoverage) => {
|
|
44
|
-
const istanbulCoverageMarked = {}
|
|
45
|
-
Object.keys(istanbulCoverage).forEach((key) => {
|
|
46
|
-
istanbulCoverageMarked[key] = {
|
|
47
|
-
...istanbulCoverage[key],
|
|
48
|
-
fromV8: true,
|
|
49
|
-
}
|
|
50
|
-
})
|
|
51
|
-
return istanbulCoverageMarked
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
const sourcesFromSourceMapCache = (url, sourceMapCache) => {
|
|
55
|
-
const sourceMapAndLineLengths = sourceMapCache[url]
|
|
56
|
-
if (!sourceMapAndLineLengths) {
|
|
57
|
-
return {}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
const { data, lineLengths } = sourceMapAndLineLengths
|
|
61
|
-
// See: https://github.com/nodejs/node/pull/34305
|
|
62
|
-
if (!data) {
|
|
63
|
-
return undefined
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
const sources = {
|
|
67
|
-
sourcemap: data,
|
|
68
|
-
...(lineLengths ? { source: sourcesFromLineLengths(lineLengths) } : {}),
|
|
69
|
-
}
|
|
70
|
-
return sources
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
const sourcesFromLineLengths = (lineLengths) => {
|
|
74
|
-
let source = ""
|
|
75
|
-
lineLengths.forEach((length) => {
|
|
76
|
-
source += `${"".padEnd(length, ".")}\n`
|
|
77
|
-
})
|
|
78
|
-
return source
|
|
79
|
-
}
|
|
@@ -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
|
-
}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
// https://github.com/yarnpkg/yarn/blob/master/src/reporters/console/util.js
|
|
2
|
-
// https://github.com/yarnpkg/yarn/blob/master/src/reporters/console/progress-bar.js
|
|
3
|
-
// https://github.com/sindresorhus/log-update/blob/master/index.js
|
|
4
|
-
// see https://github.com/jsenv/jsenv-core/issues/59
|
|
5
|
-
import readline from "node:readline"
|
|
6
|
-
import tty from "node:tty"
|
|
7
|
-
|
|
8
|
-
import { createSupportsColor } from "supports-color"
|
|
9
|
-
|
|
10
|
-
const CLEAR_WHOLE_LINE = 0
|
|
11
|
-
|
|
12
|
-
export const clearLine = (stdout = process.stdout) => {
|
|
13
|
-
if (createSupportsColor(stdout)) {
|
|
14
|
-
readline.clearLine(stdout, CLEAR_WHOLE_LINE)
|
|
15
|
-
readline.cursorTo(stdout, 0)
|
|
16
|
-
} else if (stdout instanceof tty.WriteStream) {
|
|
17
|
-
if (stdout.columns > 0) {
|
|
18
|
-
stdout.write(`\r${" ".repeat(stdout.columns - 1)}`)
|
|
19
|
-
}
|
|
20
|
-
stdout.write(`\r`)
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export const toStartOfLine = (stdout = process.stdout) => {
|
|
25
|
-
if (createSupportsColor(stdout)) {
|
|
26
|
-
readline.cursorTo(stdout, 0)
|
|
27
|
-
} else {
|
|
28
|
-
stdout.write("\r")
|
|
29
|
-
}
|
|
30
|
-
}
|