react-native-coverage 0.1.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.
- package/Coverage.podspec +20 -0
- package/LICENSE +202 -0
- package/README.md +125 -0
- package/android/build.gradle +51 -0
- package/android/rn-coverage-jacoco.gradle +132 -0
- package/android/rn-coverage.gradle +68 -0
- package/android/src/main/AndroidManifest.xml +2 -0
- package/android/src/main/java/com/coverage/CoverageModule.kt +53 -0
- package/android/src/main/java/com/coverage/CoveragePackage.kt +35 -0
- package/app.plugin.js +1 -0
- package/bin/rn-coverage.js +11 -0
- package/cocoapods/coverage_post_install.rb +197 -0
- package/docs/cli.md +51 -0
- package/docs/config.md +27 -0
- package/docs/index.md +16 -0
- package/docs/integration/android.md +83 -0
- package/docs/integration/ci-appium.md +41 -0
- package/docs/integration/e2e-timing.md +20 -0
- package/docs/integration/ios.md +77 -0
- package/docs/integration/js.md +38 -0
- package/docs/pattern-c.md +5 -0
- package/docs/releasing.md +88 -0
- package/docs.json +24 -0
- package/ios/Coverage.h +5 -0
- package/ios/Coverage.mm +47 -0
- package/ios/CoverageConfig.h +21 -0
- package/ios/CoverageProfile.h +22 -0
- package/ios/CoverageProfile.mm +358 -0
- package/lib/module/NativeCoverage.js +10 -0
- package/lib/module/NativeCoverage.js.map +1 -0
- package/lib/module/assert-coverage.js +181 -0
- package/lib/module/assert-coverage.js.map +1 -0
- package/lib/module/cli/index.js +229 -0
- package/lib/module/cli/index.js.map +1 -0
- package/lib/module/config.js +83 -0
- package/lib/module/config.js.map +1 -0
- package/lib/module/exit-codes.js +22 -0
- package/lib/module/exit-codes.js.map +1 -0
- package/lib/module/index.js +35 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/js-coverage.js +172 -0
- package/lib/module/js-coverage.js.map +1 -0
- package/lib/module/node.js +15 -0
- package/lib/module/node.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/module/path-rewrite.js +44 -0
- package/lib/module/path-rewrite.js.map +1 -0
- package/lib/module/process-ios-native-coverage.js +258 -0
- package/lib/module/process-ios-native-coverage.js.map +1 -0
- package/lib/module/pull-native-coverage.js +210 -0
- package/lib/module/pull-native-coverage.js.map +1 -0
- package/lib/typescript/example-dynamic/App.d.ts +6 -0
- package/lib/typescript/example-dynamic/App.d.ts.map +1 -0
- package/lib/typescript/package.json +1 -0
- package/lib/typescript/src/NativeCoverage.d.ts +16 -0
- package/lib/typescript/src/NativeCoverage.d.ts.map +1 -0
- package/lib/typescript/src/assert-coverage.d.ts +53 -0
- package/lib/typescript/src/assert-coverage.d.ts.map +1 -0
- package/lib/typescript/src/cli/index.d.ts +4 -0
- package/lib/typescript/src/cli/index.d.ts.map +1 -0
- package/lib/typescript/src/config.d.ts +93 -0
- package/lib/typescript/src/config.d.ts.map +1 -0
- package/lib/typescript/src/exit-codes.d.ts +16 -0
- package/lib/typescript/src/exit-codes.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +16 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/lib/typescript/src/js-coverage.d.ts +36 -0
- package/lib/typescript/src/js-coverage.d.ts.map +1 -0
- package/lib/typescript/src/node.d.ts +14 -0
- package/lib/typescript/src/node.d.ts.map +1 -0
- package/lib/typescript/src/path-rewrite.d.ts +12 -0
- package/lib/typescript/src/path-rewrite.d.ts.map +1 -0
- package/lib/typescript/src/process-ios-native-coverage.d.ts +61 -0
- package/lib/typescript/src/process-ios-native-coverage.d.ts.map +1 -0
- package/lib/typescript/src/pull-native-coverage.d.ts +38 -0
- package/lib/typescript/src/pull-native-coverage.d.ts.map +1 -0
- package/package.json +184 -0
- package/plugin/build/index.d.ts +21 -0
- package/plugin/build/index.js +153 -0
- package/react-native-coverage.config.js.example +47 -0
- package/react-native.config.js +9 -0
- package/src/NativeCoverage.ts +16 -0
- package/src/assert-coverage.ts +260 -0
- package/src/cli/index.ts +420 -0
- package/src/config.ts +189 -0
- package/src/exit-codes.ts +20 -0
- package/src/index.tsx +35 -0
- package/src/js-coverage.ts +213 -0
- package/src/node.ts +52 -0
- package/src/path-rewrite.ts +52 -0
- package/src/process-ios-native-coverage.ts +425 -0
- package/src/pull-native-coverage.ts +269 -0
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import fs from 'node:fs';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import { DEFAULT_COVERAGE_CONFIG } from "./config.js";
|
|
6
|
+
import { EXIT_OK, EXIT_STRICT_EMPTY } from "./exit-codes.js";
|
|
7
|
+
function failEmpty(strict, message) {
|
|
8
|
+
if (strict) {
|
|
9
|
+
return {
|
|
10
|
+
code: EXIT_STRICT_EMPTY,
|
|
11
|
+
message
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
return {
|
|
15
|
+
code: EXIT_OK,
|
|
16
|
+
message: `(soft) ${message}`
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Parse LCOV and count SF: paths matching configured includes.
|
|
21
|
+
* When `lcovPathIncludes` is empty, any SF: path counts as a match.
|
|
22
|
+
* `linesHit` sums `LH:` only for matched source files.
|
|
23
|
+
*/
|
|
24
|
+
export function analyzeLcov(lcovPath, lcovPathIncludes = []) {
|
|
25
|
+
const text = fs.readFileSync(lcovPath, 'utf8');
|
|
26
|
+
let sourceFileCount = 0;
|
|
27
|
+
let matchedPathHits = 0;
|
|
28
|
+
let linesHit = 0;
|
|
29
|
+
let currentMatched = false;
|
|
30
|
+
for (const line of text.split('\n')) {
|
|
31
|
+
if (line.startsWith('SF:')) {
|
|
32
|
+
sourceFileCount += 1;
|
|
33
|
+
const sf = line.slice(3).replace(/\\/g, '/');
|
|
34
|
+
currentMatched = lcovPathIncludes.length === 0 || lcovPathIncludes.some(include => sf.includes(include) || sf.startsWith(include));
|
|
35
|
+
if (currentMatched) {
|
|
36
|
+
matchedPathHits += 1;
|
|
37
|
+
}
|
|
38
|
+
} else if (line.startsWith('LH:') && currentMatched) {
|
|
39
|
+
linesHit += Number(line.slice(3)) || 0;
|
|
40
|
+
} else if (line.startsWith('end_of_record')) {
|
|
41
|
+
currentMatched = false;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return {
|
|
45
|
+
sourceFileCount,
|
|
46
|
+
matchedPathHits,
|
|
47
|
+
linesHit
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Assert iOS (or any) LCOV has expected path hits with actual line coverage.
|
|
53
|
+
* Exit 2 in strict mode when missing/empty/no matched SF: paths/no LH hits.
|
|
54
|
+
*/
|
|
55
|
+
export function assertIosLcov(lcovPath, strict, config = DEFAULT_COVERAGE_CONFIG, cwd = process.cwd()) {
|
|
56
|
+
const relative = path.relative(cwd, lcovPath) || lcovPath;
|
|
57
|
+
const includes = config.assert.lcovPathIncludes;
|
|
58
|
+
if (!fs.existsSync(lcovPath)) {
|
|
59
|
+
return failEmpty(strict, `iOS LCOV missing: ${relative}`);
|
|
60
|
+
}
|
|
61
|
+
const stat = fs.statSync(lcovPath);
|
|
62
|
+
if (stat.size === 0) {
|
|
63
|
+
return failEmpty(strict, `iOS LCOV empty (0 bytes): ${relative}`);
|
|
64
|
+
}
|
|
65
|
+
const {
|
|
66
|
+
sourceFileCount,
|
|
67
|
+
matchedPathHits,
|
|
68
|
+
linesHit
|
|
69
|
+
} = analyzeLcov(lcovPath, includes);
|
|
70
|
+
if (matchedPathHits === 0 || linesHit === 0) {
|
|
71
|
+
const includeDesc = includes.length > 0 ? includes.join(', ') : '(any SF: path)';
|
|
72
|
+
return failEmpty(strict, `iOS LCOV has no expected path/line hits [${includeDesc}] (sourceFiles=${sourceFileCount}, matchedPathHits=${matchedPathHits}, linesHit=${linesHit}): ${relative}`);
|
|
73
|
+
}
|
|
74
|
+
return {
|
|
75
|
+
code: EXIT_OK,
|
|
76
|
+
message: `iOS ok: matchedPathHits=${matchedPathHits} sourceFiles=${sourceFileCount} linesHit=${linesHit} (${relative})`
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Parse Jacoco XML package rollups. Matchers are case-insensitive substrings
|
|
81
|
+
* of `<package name="...">`. Empty matchers → all packages.
|
|
82
|
+
*
|
|
83
|
+
* Jacoco uses `/` separators (`com/coverage/fixture`); configs often use Java
|
|
84
|
+
* dots (`coverage.fixture`). Normalize both so either form matches.
|
|
85
|
+
*/
|
|
86
|
+
export function analyzeJacocoXml(xmlPath, packageIncludes = []) {
|
|
87
|
+
const xml = fs.readFileSync(xmlPath, 'utf8');
|
|
88
|
+
const packageBlocks = [...xml.matchAll(/<package name="([^"]+)"[^>]*>([\s\S]*?)<\/package>/g)];
|
|
89
|
+
const normalizePkg = value => value.toLowerCase().replace(/[./]/g, '/');
|
|
90
|
+
const normalizedIncludes = packageIncludes.map(normalizePkg);
|
|
91
|
+
let packageCount = 0;
|
|
92
|
+
let lineCovered = 0;
|
|
93
|
+
let lineMissed = 0;
|
|
94
|
+
for (const match of packageBlocks) {
|
|
95
|
+
const name = match[1];
|
|
96
|
+
const body = match[2];
|
|
97
|
+
const normalizedName = normalizePkg(name);
|
|
98
|
+
if (normalizedIncludes.length > 0 && !normalizedIncludes.some(m => normalizedName.includes(m))) {
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
packageCount += 1;
|
|
102
|
+
const trailing = body.match(/((?:<counter type="[^"]+" missed="\d+" covered="\d+"\/>\s*)+)$/);
|
|
103
|
+
if (!trailing) {
|
|
104
|
+
continue;
|
|
105
|
+
}
|
|
106
|
+
for (const c of trailing[1].matchAll(/<counter type="(LINE|INSTRUCTION)" missed="(\d+)" covered="(\d+)"\/>/g)) {
|
|
107
|
+
if (c[1] === 'LINE') {
|
|
108
|
+
lineMissed += Number(c[2]);
|
|
109
|
+
lineCovered += Number(c[3]);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
return {
|
|
114
|
+
packageCount,
|
|
115
|
+
lineCovered,
|
|
116
|
+
lineMissed
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Assert Android Jacoco XML has expected package LINE hits.
|
|
122
|
+
* Exit 2 in strict mode when missing/empty/no covered lines in matched packages.
|
|
123
|
+
*/
|
|
124
|
+
export function assertAndroidJacoco(xmlPath, strict, config = DEFAULT_COVERAGE_CONFIG, cwd = process.cwd()) {
|
|
125
|
+
const relative = path.relative(cwd, xmlPath) || xmlPath;
|
|
126
|
+
const includes = config.assert.jacocoPackageIncludes.length > 0 ? config.assert.jacocoPackageIncludes : config.android.libraryProjectMatchers;
|
|
127
|
+
if (!fs.existsSync(xmlPath)) {
|
|
128
|
+
return failEmpty(strict, `Android Jacoco XML missing: ${relative}`);
|
|
129
|
+
}
|
|
130
|
+
const stat = fs.statSync(xmlPath);
|
|
131
|
+
if (stat.size === 0) {
|
|
132
|
+
return failEmpty(strict, `Android Jacoco XML empty (0 bytes): ${relative}`);
|
|
133
|
+
}
|
|
134
|
+
const {
|
|
135
|
+
packageCount,
|
|
136
|
+
lineCovered,
|
|
137
|
+
lineMissed
|
|
138
|
+
} = analyzeJacocoXml(xmlPath, includes);
|
|
139
|
+
if (packageCount === 0 || lineCovered === 0) {
|
|
140
|
+
const includeDesc = includes.length > 0 ? includes.join(', ') : '(any package)';
|
|
141
|
+
return failEmpty(strict, `Android Jacoco has empty package hits [${includeDesc}] (packages=${packageCount}, lineCovered=${lineCovered}, lineMissed=${lineMissed}): ${relative}`);
|
|
142
|
+
}
|
|
143
|
+
return {
|
|
144
|
+
code: EXIT_OK,
|
|
145
|
+
message: `Android ok: packages=${packageCount} lineCovered=${lineCovered} lineMissed=${lineMissed} (${relative})`
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Post-pipeline presence check. Returns the highest-priority failure code
|
|
150
|
+
* (prefer EXIT_STRICT_EMPTY over EXIT_OK).
|
|
151
|
+
*/
|
|
152
|
+
export function assertCoverage(options = {}) {
|
|
153
|
+
const config = options.config ?? DEFAULT_COVERAGE_CONFIG;
|
|
154
|
+
const strict = options.strict ?? config.strict;
|
|
155
|
+
const cwd = options.cwd ?? process.cwd();
|
|
156
|
+
const platform = options.platform ?? 'all';
|
|
157
|
+
const lcov = options.lcov ?? path.resolve(cwd, config.assert.defaultLcovPath);
|
|
158
|
+
const jacocoXml = options.jacocoXml ?? path.resolve(cwd, config.assert.defaultJacocoXmlPath);
|
|
159
|
+
const results = [];
|
|
160
|
+
if (platform === 'ios' || platform === 'all') {
|
|
161
|
+
results.push(assertIosLcov(lcov, strict, config, cwd));
|
|
162
|
+
}
|
|
163
|
+
if (platform === 'android' || platform === 'all') {
|
|
164
|
+
results.push(assertAndroidJacoco(jacocoXml, strict, config, cwd));
|
|
165
|
+
}
|
|
166
|
+
let code = EXIT_OK;
|
|
167
|
+
const messages = [];
|
|
168
|
+
for (const result of results) {
|
|
169
|
+
messages.push(result.message);
|
|
170
|
+
if (result.code === EXIT_STRICT_EMPTY) {
|
|
171
|
+
code = EXIT_STRICT_EMPTY;
|
|
172
|
+
} else if (result.code !== EXIT_OK && code === EXIT_OK) {
|
|
173
|
+
code = result.code;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
return {
|
|
177
|
+
code,
|
|
178
|
+
message: messages.join('\n')
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
//# sourceMappingURL=assert-coverage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["fs","path","DEFAULT_COVERAGE_CONFIG","EXIT_OK","EXIT_STRICT_EMPTY","failEmpty","strict","message","code","analyzeLcov","lcovPath","lcovPathIncludes","text","readFileSync","sourceFileCount","matchedPathHits","linesHit","currentMatched","line","split","startsWith","sf","slice","replace","length","some","include","includes","Number","assertIosLcov","config","cwd","process","relative","assert","existsSync","stat","statSync","size","includeDesc","join","analyzeJacocoXml","xmlPath","packageIncludes","xml","packageBlocks","matchAll","normalizePkg","value","toLowerCase","normalizedIncludes","map","packageCount","lineCovered","lineMissed","match","name","body","normalizedName","m","trailing","c","assertAndroidJacoco","jacocoPackageIncludes","android","libraryProjectMatchers","assertCoverage","options","platform","lcov","resolve","defaultLcovPath","jacocoXml","defaultJacocoXmlPath","results","push","messages","result"],"sourceRoot":"../../src","sources":["assert-coverage.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
|
|
4
|
+
import { Command } from 'commander';
|
|
5
|
+
import { assertCoverage } from "../assert-coverage.js";
|
|
6
|
+
import { loadCoverageConfig } from "../config.js";
|
|
7
|
+
import { EXIT_ERROR, EXIT_OK, EXIT_STRICT_EMPTY, StrictEmptyError } from "../exit-codes.js";
|
|
8
|
+
import { exportIosLcov, reportIosHtml, summarizeIos } from "../process-ios-native-coverage.js";
|
|
9
|
+
import { pullAndroidCoverageWithRetry, pullIosCoverage, resolveAndroidDeviceId, runJacocoTestReport } from "../pull-native-coverage.js";
|
|
10
|
+
import { pullAndroidJsCoverage, pullIosJsCoverage, reportJsCoverage } from "../js-coverage.js";
|
|
11
|
+
export { EXIT_OK, EXIT_ERROR, EXIT_STRICT_EMPTY };
|
|
12
|
+
function applyStrictOverride(config, rootOpts) {
|
|
13
|
+
if (rootOpts.strict === true) {
|
|
14
|
+
config.strict = true;
|
|
15
|
+
} else if (rootOpts.strict === false) {
|
|
16
|
+
config.strict = false;
|
|
17
|
+
}
|
|
18
|
+
return config;
|
|
19
|
+
}
|
|
20
|
+
function rootOptsFrom(cmd) {
|
|
21
|
+
// android/ios subcommands: parent.parent is program
|
|
22
|
+
// assert: parent is program
|
|
23
|
+
const parent = cmd.parent;
|
|
24
|
+
if (parent?.parent) {
|
|
25
|
+
return parent.parent.opts() ?? {};
|
|
26
|
+
}
|
|
27
|
+
return parent?.opts() ?? {};
|
|
28
|
+
}
|
|
29
|
+
function mapErrorToExit(error) {
|
|
30
|
+
// Exit 2 only for explicit empty/missing coverage-hit guards.
|
|
31
|
+
// Tooling/config failures (e.g. missing app binary) stay exit 1.
|
|
32
|
+
if (error instanceof StrictEmptyError) {
|
|
33
|
+
return EXIT_STRICT_EMPTY;
|
|
34
|
+
}
|
|
35
|
+
return EXIT_ERROR;
|
|
36
|
+
}
|
|
37
|
+
async function main() {
|
|
38
|
+
const program = new Command();
|
|
39
|
+
program.name('rn-coverage').description('Native coverage CLI for React Native (pull / export / report / summary / assert). Pattern C: dedicated test apps only.').option('-c, --config <path>', 'Path to react-native-coverage.config.js').option('--strict', 'Fail with exit 2 when artifacts/hits are empty').option('--no-strict', 'Warn instead of exit 2 on empty artifacts');
|
|
40
|
+
program.command('android').description('Android coverage commands').addCommand(new Command('pull').description('Pull .ec coverage from a connected device/emulator').option('--device <id>', 'adb device serial').option('--output <dir>', 'Local output directory').option('--retries <n>', 'Retry count while waiting for .ec', '15').action(async (opts, cmd) => {
|
|
41
|
+
const rootOpts = rootOptsFrom(cmd);
|
|
42
|
+
const config = applyStrictOverride(await loadCoverageConfig(process.cwd(), rootOpts.config), rootOpts);
|
|
43
|
+
try {
|
|
44
|
+
const deviceId = resolveAndroidDeviceId(opts.device);
|
|
45
|
+
const pulled = await pullAndroidCoverageWithRetry(deviceId, {
|
|
46
|
+
softFail: !config.strict,
|
|
47
|
+
outputDir: opts.output,
|
|
48
|
+
retries: Number(opts.retries) || 15,
|
|
49
|
+
config
|
|
50
|
+
});
|
|
51
|
+
if (!pulled && config.strict) {
|
|
52
|
+
console.error('[rn-coverage] Android coverage.ec missing (strict)');
|
|
53
|
+
process.exitCode = EXIT_STRICT_EMPTY;
|
|
54
|
+
}
|
|
55
|
+
} catch (error) {
|
|
56
|
+
console.error(`[rn-coverage] ${error.message}`);
|
|
57
|
+
process.exitCode = mapErrorToExit(error);
|
|
58
|
+
}
|
|
59
|
+
})).addCommand(new Command('report').description('Run jacocoTestReport then assert Jacoco XML LINE hits (exit 2 if strict empty)').option('--android-dir <path>', 'Android project directory', 'android').option('--jacoco-xml <path>', 'Jacoco XML path to assert after report').action(async (opts, cmd) => {
|
|
60
|
+
const rootOpts = rootOptsFrom(cmd);
|
|
61
|
+
const config = applyStrictOverride(await loadCoverageConfig(process.cwd(), rootOpts.config), rootOpts);
|
|
62
|
+
const result = runJacocoTestReport({
|
|
63
|
+
androidDir: opts.androidDir,
|
|
64
|
+
jacocoXml: opts.jacocoXml,
|
|
65
|
+
config
|
|
66
|
+
});
|
|
67
|
+
if (!result.ok) {
|
|
68
|
+
process.exitCode = result.exitCode;
|
|
69
|
+
}
|
|
70
|
+
}));
|
|
71
|
+
program.command('ios').description('iOS coverage commands').addCommand(new Command('pull').description('Pull .profraw from a simulator app container').requiredOption('--device <udid>', 'Simulator UDID').option('--output <dir>', 'Local output directory').action(async (opts, cmd) => {
|
|
72
|
+
const rootOpts = rootOptsFrom(cmd);
|
|
73
|
+
const config = applyStrictOverride(await loadCoverageConfig(process.cwd(), rootOpts.config), rootOpts);
|
|
74
|
+
try {
|
|
75
|
+
const pulled = pullIosCoverage(opts.device, {
|
|
76
|
+
outputDir: opts.output,
|
|
77
|
+
softFail: !config.strict,
|
|
78
|
+
config
|
|
79
|
+
});
|
|
80
|
+
if (pulled.length === 0 && config.strict) {
|
|
81
|
+
process.exitCode = EXIT_STRICT_EMPTY;
|
|
82
|
+
}
|
|
83
|
+
} catch (error) {
|
|
84
|
+
console.error(`[rn-coverage] ${error.message}`);
|
|
85
|
+
process.exitCode = mapErrorToExit(error);
|
|
86
|
+
}
|
|
87
|
+
})).addCommand(new Command('export').description('Merge profraw and export LCOV via llvm-cov (asserts path hits; exit 2 if strict empty)').requiredOption('--derived-data <path>', 'Xcode derived data path').option('--configuration <name>', 'Xcode configuration', 'Debug').option('--app-name <name>', 'App product name').option('--output <path>', 'LCOV output path', 'coverage/ios/lcov.info').action(async (opts, cmd) => {
|
|
88
|
+
const rootOpts = rootOptsFrom(cmd);
|
|
89
|
+
const config = applyStrictOverride(await loadCoverageConfig(process.cwd(), rootOpts.config), rootOpts);
|
|
90
|
+
try {
|
|
91
|
+
await exportIosLcov({
|
|
92
|
+
derivedData: opts.derivedData,
|
|
93
|
+
configuration: opts.configuration,
|
|
94
|
+
appName: opts.appName ?? config.app.iosProductName,
|
|
95
|
+
output: opts.output,
|
|
96
|
+
config
|
|
97
|
+
});
|
|
98
|
+
} catch (error) {
|
|
99
|
+
console.error(`[rn-coverage] ${error.message}`);
|
|
100
|
+
process.exitCode = mapErrorToExit(error);
|
|
101
|
+
}
|
|
102
|
+
})).addCommand(new Command('report').description('HTML report via llvm-cov show -format=html').requiredOption('--derived-data <path>', 'Xcode derived data path').option('--configuration <name>', 'Xcode configuration', 'Debug').option('--app-name <name>', 'App product name').option('--profdata <path>', 'Merged profdata path', 'coverage/ios/profdata').option('--output-dir <path>', 'HTML output directory', 'coverage/ios/html').action(async (opts, cmd) => {
|
|
103
|
+
const rootOpts = rootOptsFrom(cmd);
|
|
104
|
+
const config = applyStrictOverride(await loadCoverageConfig(process.cwd(), rootOpts.config), rootOpts);
|
|
105
|
+
try {
|
|
106
|
+
reportIosHtml({
|
|
107
|
+
derivedData: opts.derivedData,
|
|
108
|
+
configuration: opts.configuration,
|
|
109
|
+
appName: opts.appName,
|
|
110
|
+
profdata: opts.profdata,
|
|
111
|
+
outputDir: opts.outputDir,
|
|
112
|
+
config
|
|
113
|
+
});
|
|
114
|
+
} catch (error) {
|
|
115
|
+
console.error(`[rn-coverage] ${error.message}`);
|
|
116
|
+
process.exitCode = mapErrorToExit(error);
|
|
117
|
+
}
|
|
118
|
+
})).addCommand(new Command('summary').description('Terminal summary via llvm-cov report').requiredOption('--derived-data <path>', 'Xcode derived data path').option('--configuration <name>', 'Xcode configuration', 'Debug').option('--app-name <name>', 'App product name').option('--profdata <path>', 'Merged profdata path', 'coverage/ios/profdata').action(async (opts, cmd) => {
|
|
119
|
+
const rootOpts = rootOptsFrom(cmd);
|
|
120
|
+
const config = applyStrictOverride(await loadCoverageConfig(process.cwd(), rootOpts.config), rootOpts);
|
|
121
|
+
try {
|
|
122
|
+
summarizeIos({
|
|
123
|
+
derivedData: opts.derivedData,
|
|
124
|
+
configuration: opts.configuration,
|
|
125
|
+
appName: opts.appName,
|
|
126
|
+
profdata: opts.profdata,
|
|
127
|
+
config
|
|
128
|
+
});
|
|
129
|
+
} catch (error) {
|
|
130
|
+
console.error(`[rn-coverage] ${error.message}`);
|
|
131
|
+
process.exitCode = mapErrorToExit(error);
|
|
132
|
+
}
|
|
133
|
+
}));
|
|
134
|
+
program.command('js').description('Istanbul/NYC TypeScript coverage (source-map remap after Metro e2e)').addCommand(new Command('pull').description('Pull coverage-final.json written by flush()/dumpJsCoverage').option('--platform <name>', 'android | ios', 'android').option('--device <id>', 'adb serial or simulator UDID').option('--output <dir>', 'Local output directory', 'coverage/js').action(async (opts, cmd) => {
|
|
135
|
+
const rootOpts = rootOptsFrom(cmd);
|
|
136
|
+
const config = applyStrictOverride(await loadCoverageConfig(process.cwd(), rootOpts.config), rootOpts);
|
|
137
|
+
try {
|
|
138
|
+
if (opts.platform === 'android') {
|
|
139
|
+
const deviceId = resolveAndroidDeviceId(opts.device);
|
|
140
|
+
const pulled = pullAndroidJsCoverage(deviceId, {
|
|
141
|
+
softFail: !config.strict,
|
|
142
|
+
outputDir: opts.output,
|
|
143
|
+
config
|
|
144
|
+
});
|
|
145
|
+
if (!pulled && config.strict) {
|
|
146
|
+
process.exitCode = EXIT_STRICT_EMPTY;
|
|
147
|
+
}
|
|
148
|
+
} else if (opts.platform === 'ios') {
|
|
149
|
+
if (!opts.device) {
|
|
150
|
+
console.error('[rn-coverage] js pull --platform ios requires --device <udid>');
|
|
151
|
+
process.exitCode = EXIT_ERROR;
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
const pulled = pullIosJsCoverage(opts.device, {
|
|
155
|
+
softFail: !config.strict,
|
|
156
|
+
outputDir: opts.output,
|
|
157
|
+
config
|
|
158
|
+
});
|
|
159
|
+
if (!pulled && config.strict) {
|
|
160
|
+
process.exitCode = EXIT_STRICT_EMPTY;
|
|
161
|
+
}
|
|
162
|
+
} else {
|
|
163
|
+
console.error(`[rn-coverage] js pull: --platform must be android|ios (got ${opts.platform})`);
|
|
164
|
+
process.exitCode = EXIT_ERROR;
|
|
165
|
+
}
|
|
166
|
+
} catch (error) {
|
|
167
|
+
console.error(`[rn-coverage] ${error.message}`);
|
|
168
|
+
process.exitCode = mapErrorToExit(error);
|
|
169
|
+
}
|
|
170
|
+
})).addCommand(new Command('report').description('NYC report from coverage-final.json (sourceMap remap → lcov.info)').requiredOption('--input <path>', 'coverage-final.json or directory of Istanbul JSON').option('--output <dir>', 'Report directory', 'coverage/js').option('--cwd <path>', 'NYC cwd for include globs', process.cwd()).option('--nyc-config <path>', 'Path to nyc.config.js').action(async (opts, cmd) => {
|
|
171
|
+
const rootOpts = rootOptsFrom(cmd);
|
|
172
|
+
const config = applyStrictOverride(await loadCoverageConfig(process.cwd(), rootOpts.config), rootOpts);
|
|
173
|
+
try {
|
|
174
|
+
const result = reportJsCoverage({
|
|
175
|
+
input: opts.input,
|
|
176
|
+
outputDir: opts.output,
|
|
177
|
+
cwd: opts.cwd,
|
|
178
|
+
nycConfig: opts.nycConfig,
|
|
179
|
+
softFail: !config.strict
|
|
180
|
+
});
|
|
181
|
+
if (!result.ok && config.strict) {
|
|
182
|
+
process.exitCode = EXIT_STRICT_EMPTY;
|
|
183
|
+
}
|
|
184
|
+
} catch (error) {
|
|
185
|
+
console.error(`[rn-coverage] ${error.message}`);
|
|
186
|
+
process.exitCode = mapErrorToExit(error);
|
|
187
|
+
}
|
|
188
|
+
}));
|
|
189
|
+
program.command('assert').description('Post-pipeline presence check (exit 2 on empty/missing expected hits)').option('--platform <name>', 'ios | android | all (default: all)', 'all').option('--lcov <path>', 'LCOV file to assert non-empty expected hits').option('--jacoco-xml <path>', 'Jacoco XML to assert non-empty LINE hits').action(async (opts, cmd) => {
|
|
190
|
+
const rootOpts = rootOptsFrom(cmd);
|
|
191
|
+
const config = applyStrictOverride(await loadCoverageConfig(process.cwd(), rootOpts.config), rootOpts);
|
|
192
|
+
if (!['ios', 'android', 'all'].includes(opts.platform)) {
|
|
193
|
+
console.error(`[rn-coverage] assert: --platform must be ios|android|all (got ${opts.platform})`);
|
|
194
|
+
process.exitCode = EXIT_ERROR;
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
const result = assertCoverage({
|
|
198
|
+
platform: opts.platform,
|
|
199
|
+
lcov: opts.lcov,
|
|
200
|
+
jacocoXml: opts.jacocoXml,
|
|
201
|
+
strict: config.strict,
|
|
202
|
+
config
|
|
203
|
+
});
|
|
204
|
+
if (result.code === EXIT_OK) {
|
|
205
|
+
for (const line of result.message.split('\n')) {
|
|
206
|
+
console.log(`[rn-coverage] assert: ${line}`);
|
|
207
|
+
}
|
|
208
|
+
console.log('[rn-coverage] assert: ok');
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
for (const line of result.message.split('\n')) {
|
|
212
|
+
if (config.strict) {
|
|
213
|
+
console.error(`[rn-coverage] assert: ${line}`);
|
|
214
|
+
} else {
|
|
215
|
+
console.warn(`[rn-coverage] assert: ${line}`);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
if (result.code === EXIT_STRICT_EMPTY) {
|
|
219
|
+
console.error('[rn-coverage] assert: FAIL empty or missing native coverage (exit 2)');
|
|
220
|
+
}
|
|
221
|
+
process.exitCode = result.code;
|
|
222
|
+
});
|
|
223
|
+
await program.parseAsync(process.argv);
|
|
224
|
+
}
|
|
225
|
+
main().catch(error => {
|
|
226
|
+
console.error(`[rn-coverage] ${error.message}`);
|
|
227
|
+
process.exitCode = EXIT_ERROR;
|
|
228
|
+
});
|
|
229
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["Command","assertCoverage","loadCoverageConfig","EXIT_ERROR","EXIT_OK","EXIT_STRICT_EMPTY","StrictEmptyError","exportIosLcov","reportIosHtml","summarizeIos","pullAndroidCoverageWithRetry","pullIosCoverage","resolveAndroidDeviceId","runJacocoTestReport","pullAndroidJsCoverage","pullIosJsCoverage","reportJsCoverage","applyStrictOverride","config","rootOpts","strict","rootOptsFrom","cmd","parent","opts","mapErrorToExit","error","main","program","name","description","option","command","addCommand","action","process","cwd","deviceId","device","pulled","softFail","outputDir","output","retries","Number","console","exitCode","message","result","androidDir","jacocoXml","ok","requiredOption","length","derivedData","configuration","appName","app","iosProductName","profdata","platform","input","nycConfig","includes","lcov","code","line","split","log","warn","parseAsync","argv","catch"],"sourceRoot":"../../../src","sources":["cli/index.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import fs from 'node:fs';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import { pathToFileURL } from 'node:url';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Neutral defaults — no consumer product names.
|
|
9
|
+
* Pattern C: this package targets dedicated test apps only.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
export const DEFAULT_COVERAGE_CONFIG = {
|
|
13
|
+
nativeModuleName: 'Coverage',
|
|
14
|
+
app: {
|
|
15
|
+
androidApplicationId: 'com.example.coverage',
|
|
16
|
+
iosBundleId: 'com.example.coverage',
|
|
17
|
+
iosProductName: 'CoverageExample'
|
|
18
|
+
},
|
|
19
|
+
ios: {
|
|
20
|
+
frameworkNamePrefixes: []
|
|
21
|
+
},
|
|
22
|
+
android: {
|
|
23
|
+
libraryProjectMatchers: [],
|
|
24
|
+
detoxStagingPath: '/data/local/tmp/coverage/coverage.ec',
|
|
25
|
+
coverageRelativePath: 'files/coverage.ec',
|
|
26
|
+
jacocoReportXml: 'android/app/build/reports/jacoco/jacocoTestReport/jacocoTestReport.xml'
|
|
27
|
+
},
|
|
28
|
+
js: {
|
|
29
|
+
androidRelativePath: 'files/coverage-final.json',
|
|
30
|
+
androidStagingPath: '/data/local/tmp/coverage/coverage-final.json',
|
|
31
|
+
iosRelativePath: 'Documents/coverage-final.json'
|
|
32
|
+
},
|
|
33
|
+
sourcePathRewrite: [],
|
|
34
|
+
strict: true,
|
|
35
|
+
assert: {
|
|
36
|
+
lcovPathIncludes: ['packages/'],
|
|
37
|
+
jacocoPackageIncludes: [],
|
|
38
|
+
defaultLcovPath: 'coverage/ios/lcov.info',
|
|
39
|
+
defaultJacocoXmlPath: 'android/app/build/reports/jacoco/jacocoTestReport/jacocoTestReport.xml'
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
export function resolveCoverageConfig(input = {}) {
|
|
43
|
+
return {
|
|
44
|
+
nativeModuleName: input.nativeModuleName ?? DEFAULT_COVERAGE_CONFIG.nativeModuleName,
|
|
45
|
+
app: {
|
|
46
|
+
...DEFAULT_COVERAGE_CONFIG.app,
|
|
47
|
+
...input.app
|
|
48
|
+
},
|
|
49
|
+
ios: {
|
|
50
|
+
...DEFAULT_COVERAGE_CONFIG.ios,
|
|
51
|
+
...input.ios
|
|
52
|
+
},
|
|
53
|
+
android: {
|
|
54
|
+
...DEFAULT_COVERAGE_CONFIG.android,
|
|
55
|
+
...input.android
|
|
56
|
+
},
|
|
57
|
+
js: {
|
|
58
|
+
...DEFAULT_COVERAGE_CONFIG.js,
|
|
59
|
+
...input.js
|
|
60
|
+
},
|
|
61
|
+
sourcePathRewrite: input.sourcePathRewrite ?? DEFAULT_COVERAGE_CONFIG.sourcePathRewrite,
|
|
62
|
+
strict: input.strict ?? DEFAULT_COVERAGE_CONFIG.strict,
|
|
63
|
+
assert: {
|
|
64
|
+
...DEFAULT_COVERAGE_CONFIG.assert,
|
|
65
|
+
...input.assert
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
const CONFIG_FILENAMES = ['react-native-coverage.config.js', 'react-native-coverage.config.cjs', 'react-native-coverage.config.mjs'];
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Load config from `cwd` (or `configPath`). Missing file → defaults.
|
|
73
|
+
*/
|
|
74
|
+
export async function loadCoverageConfig(cwd = process.cwd(), configPath) {
|
|
75
|
+
const resolvedPath = configPath != null ? path.resolve(cwd, configPath) : CONFIG_FILENAMES.map(name => path.join(cwd, name)).find(p => fs.existsSync(p));
|
|
76
|
+
if (resolvedPath == null || !fs.existsSync(resolvedPath)) {
|
|
77
|
+
return resolveCoverageConfig();
|
|
78
|
+
}
|
|
79
|
+
const mod = await import(pathToFileURL(resolvedPath).href);
|
|
80
|
+
const raw = mod.default ?? mod;
|
|
81
|
+
return resolveCoverageConfig(raw);
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["fs","path","pathToFileURL","DEFAULT_COVERAGE_CONFIG","nativeModuleName","app","androidApplicationId","iosBundleId","iosProductName","ios","frameworkNamePrefixes","android","libraryProjectMatchers","detoxStagingPath","coverageRelativePath","jacocoReportXml","js","androidRelativePath","androidStagingPath","iosRelativePath","sourcePathRewrite","strict","assert","lcovPathIncludes","jacocoPackageIncludes","defaultLcovPath","defaultJacocoXmlPath","resolveCoverageConfig","input","CONFIG_FILENAMES","loadCoverageConfig","cwd","process","configPath","resolvedPath","resolve","map","name","join","find","p","existsSync","mod","href","raw","default"],"sourceRoot":"../../src","sources":["config.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* CLI / library exit codes for presence / silent-fail guards.
|
|
5
|
+
*
|
|
6
|
+
* Aligns with the RNFB interim assert contract (exit 2 = strict empty).
|
|
7
|
+
*/
|
|
8
|
+
export const EXIT_OK = 0;
|
|
9
|
+
/** Unexpected error / bad invocation / tooling failure. */
|
|
10
|
+
export const EXIT_ERROR = 1;
|
|
11
|
+
/** Strict empty-hit / missing artifact (CI guard). */
|
|
12
|
+
export const EXIT_STRICT_EMPTY = 2;
|
|
13
|
+
|
|
14
|
+
/** Thrown when a strict presence guard fails (map to exit 2 in the CLI). */
|
|
15
|
+
export class StrictEmptyError extends Error {
|
|
16
|
+
exitCode = EXIT_STRICT_EMPTY;
|
|
17
|
+
constructor(message) {
|
|
18
|
+
super(message);
|
|
19
|
+
this.name = 'StrictEmptyError';
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=exit-codes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["EXIT_OK","EXIT_ERROR","EXIT_STRICT_EMPTY","StrictEmptyError","Error","exitCode","constructor","message","name"],"sourceRoot":"../../src","sources":["exit-codes.ts"],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA,OAAO,MAAMA,OAAO,GAAG,CAAC;AACxB;AACA,OAAO,MAAMC,UAAU,GAAG,CAAC;AAC3B;AACA,OAAO,MAAMC,iBAAiB,GAAG,CAAC;;AAElC;AACA,OAAO,MAAMC,gBAAgB,SAASC,KAAK,CAAC;EACjCC,QAAQ,GAAGH,iBAAiB;EAErCI,WAAWA,CAACC,OAAe,EAAE;IAC3B,KAAK,CAACA,OAAO,CAAC;IACd,IAAI,CAACC,IAAI,GAAG,kBAAkB;EAChC;AACF","ignoreList":[]}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import Coverage from "./NativeCoverage.js";
|
|
4
|
+
export { default as Coverage } from "./NativeCoverage.js";
|
|
5
|
+
/**
|
|
6
|
+
* Flush in-process native coverage buffers to disk.
|
|
7
|
+
* iOS: LLVM multi-image (mode c). Android: Jacoco/Emma RT dump.
|
|
8
|
+
*
|
|
9
|
+
* React Native entry only — Node/CLI APIs live under `react-native-coverage/node`.
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Flush Istanbul JS coverage (when Metro instrumented) then native buffers.
|
|
13
|
+
* No-op for JS dump when `global.__coverage__` is absent.
|
|
14
|
+
*/
|
|
15
|
+
export function flush() {
|
|
16
|
+
try {
|
|
17
|
+
const coverage = globalThis.__coverage__;
|
|
18
|
+
if (coverage != null && typeof Coverage.dumpJsCoverage === 'function') {
|
|
19
|
+
Coverage.dumpJsCoverage(JSON.stringify(coverage));
|
|
20
|
+
}
|
|
21
|
+
} catch {
|
|
22
|
+
// Older native binaries without dumpJsCoverage — native flush still runs.
|
|
23
|
+
}
|
|
24
|
+
Coverage.flush();
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** Write `global.__coverage__` only (no native Emma/LLVM flush). */
|
|
28
|
+
export function flushJs() {
|
|
29
|
+
const coverage = globalThis.__coverage__;
|
|
30
|
+
if (coverage == null) {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
Coverage.dumpJsCoverage(JSON.stringify(coverage));
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["Coverage","default","flush","coverage","globalThis","__coverage__","dumpJsCoverage","JSON","stringify","flushJs"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;AAAA,OAAOA,QAAQ,MAAM,qBAAkB;AAEvC,SAASC,OAAO,IAAID,QAAQ,QAAQ,qBAAkB;AAGtD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,OAAO,SAASE,KAAKA,CAAA,EAAS;EAC5B,IAAI;IACF,MAAMC,QAAQ,GAAIC,UAAU,CAAgCC,YAAY;IACxE,IAAIF,QAAQ,IAAI,IAAI,IAAI,OAAOH,QAAQ,CAACM,cAAc,KAAK,UAAU,EAAE;MACrEN,QAAQ,CAACM,cAAc,CAACC,IAAI,CAACC,SAAS,CAACL,QAAQ,CAAC,CAAC;IACnD;EACF,CAAC,CAAC,MAAM;IACN;EAAA;EAEFH,QAAQ,CAACE,KAAK,CAAC,CAAC;AAClB;;AAEA;AACA,OAAO,SAASO,OAAOA,CAAA,EAAS;EAC9B,MAAMN,QAAQ,GAAIC,UAAU,CAAgCC,YAAY;EACxE,IAAIF,QAAQ,IAAI,IAAI,EAAE;IACpB;EACF;EACAH,QAAQ,CAACM,cAAc,CAACC,IAAI,CAACC,SAAS,CAACL,QAAQ,CAAC,CAAC;AACnD","ignoreList":[]}
|