Skip to content

Commit e9ff12e

Browse files
Fix coverage
1 parent 903aa80 commit e9ff12e

5 files changed

Lines changed: 1506 additions & 7 deletions

File tree

packages/dart_node_coverage/lib/src/runtime.dart

Lines changed: 67 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ extension type _NodeFS(JSObject _) implements JSObject {
1616
external void writeFileSync(JSString path, JSString data);
1717
external void mkdirSync(JSString path, JSObject? options);
1818
external bool existsSync(JSString path);
19+
external JSString readFileSync(JSString path, [JSString? encoding]);
1920
}
2021

2122
/// Extension type for Node.js path module
@@ -92,6 +93,9 @@ String getCoverageJson() {
9293
}
9394

9495
/// Write coverage data to a file (Node.js only)
96+
///
97+
/// CRITICAL: Merges with existing coverage data instead of overwriting.
98+
/// Multiple test files call this function and we accumulate coverage.
9599
void writeCoverageFile(String outputPath) {
96100
// Load Node.js modules
97101
final fsResult = _global.require.callAsFunction(null, 'fs'.toJS);
@@ -105,7 +109,6 @@ void writeCoverageFile(String outputPath) {
105109
}
106110

107111
// Type-checked casts: safe after isA<JSObject>() verification
108-
// Extension type constructors require JSObject, casts are required for js_interop
109112
final fs = _NodeFS(fsResult as JSObject);
110113
final pathMod = _NodePath(pathResult as JSObject);
111114

@@ -116,7 +119,69 @@ void writeCoverageFile(String outputPath) {
116119
fs.mkdirSync(dir, options);
117120
}
118121

119-
// Write coverage data
122+
// Get current coverage data
123+
final currentData = _getCoverageData();
124+
125+
// If file exists, read and merge
126+
if (fs.existsSync(outputPath.toJS)) {
127+
try {
128+
final existing = fs.readFileSync(outputPath.toJS, 'utf8'.toJS);
129+
final json = (globalContext as JSObject)['JSON'] as JSObject;
130+
final parse = json['parse'] as JSFunction;
131+
final existingData = parse.callAsFunction(json, existing) as JSObject;
132+
133+
// Merge existing into current
134+
_mergeData(currentData, existingData);
135+
} catch (_) {
136+
// Corrupt/empty file - ignore and overwrite
137+
}
138+
}
139+
140+
// Write merged data
120141
final jsonData = getCoverageJson();
121142
fs.writeFileSync(outputPath.toJS, jsonData.toJS);
122143
}
144+
145+
/// Merge existing coverage data into current data
146+
void _mergeData(JSObject current, JSObject existing) {
147+
final objClass = (globalContext as JSObject)['Object'] as JSObject;
148+
final keys = objClass['keys'] as JSFunction;
149+
final fileKeys = keys.callAsFunction(objClass, existing) as JSArray;
150+
151+
final fileCount = (fileKeys.getProperty('length'.toJS) as JSNumber).toDartInt;
152+
for (var i = 0; i < fileCount; i++) {
153+
final fileKeyRaw = fileKeys.getProperty(i.toJS);
154+
if (fileKeyRaw == null) continue;
155+
final fileKey = fileKeyRaw as JSString;
156+
final existingFileCov = existing.getProperty(fileKey) as JSObject;
157+
158+
// Get or create file coverage
159+
final hasFile = (current.hasProperty(fileKey) as JSBoolean).toDart;
160+
final currentFileCov = hasFile
161+
? current.getProperty(fileKey) as JSObject
162+
: JSObject();
163+
164+
if (!hasFile) {
165+
current.setProperty(fileKey, currentFileCov);
166+
}
167+
168+
// Merge line counts
169+
final lineKeys = keys.callAsFunction(objClass, existingFileCov) as JSArray;
170+
final lineCount = (lineKeys.getProperty('length'.toJS) as JSNumber).toDartInt;
171+
172+
for (var j = 0; j < lineCount; j++) {
173+
final lineKeyRaw = lineKeys.getProperty(j.toJS);
174+
if (lineKeyRaw == null) continue;
175+
final lineKey = lineKeyRaw;
176+
final existingCount = existingFileCov.getProperty(lineKey) as JSNumber;
177+
final hasLine = (currentFileCov.hasProperty(lineKey) as JSBoolean).toDart;
178+
final currentCount = hasLine
179+
? (currentFileCov.getProperty(lineKey) as JSNumber).toDartDouble
180+
: 0.0;
181+
182+
// Add counts together
183+
final merged = currentCount + existingCount.toDartDouble;
184+
currentFileCov.setProperty(lineKey, merged.toJS);
185+
}
186+
}
187+
}

0 commit comments

Comments
 (0)