Skip to content

Commit 2d255e1

Browse files
committed
build: support kcov for testing
1 parent 9fca391 commit 2d255e1

File tree

4 files changed

+73
-10
lines changed

4 files changed

+73
-10
lines changed

build.zig

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ pub fn build(b: *std.Build) void {
2323
"Emit documents to <zig-out>/docs (default: false)",
2424
) orelse false;
2525

26+
const kcov = b.option([]const []const u8, "kcov", "Arguments for kcov in testing (default: null = disabled)");
27+
2628
const stepCheck = b.step("check", "Build but don't install");
2729
const stepTest = b.step("test", "Run library tests");
2830
const stepCompatTest = b.step("test-compat", "Run compatibility tests");
@@ -95,11 +97,26 @@ pub fn build(b: *std.Build) void {
9597

9698
stepCheck.dependOn(&rewriter.step);
9799

98-
const COMPAT_RUN_CMD = "ZIGPAK_REWRITER=$1 bun test";
99-
100-
const runCompatTest = b.addSystemCommand(&.{ "bun", "exec", COMPAT_RUN_CMD });
101-
runCompatTest.addArtifactArg(rewriter);
102-
stepCompatTest.dependOn(&runCompatTest.step);
100+
if (kcov) |args| {
101+
const COMPAT_RUN_CMD = "ZIGPAK_REWRITER=$1 KCOV=kcov KCOV_ARGS=\"--include-path=$2 $3\" KCOV_REPORT=$4 bun test";
102+
103+
const kcovArgs = std.mem.join(
104+
b.allocator,
105+
" ",
106+
args[0..@max(args.len - 1, 0)],
107+
) catch @panic("OOM");
108+
109+
const runCompatTest = b.addSystemCommand(&.{ "bun", "exec", COMPAT_RUN_CMD });
110+
runCompatTest.addArtifactArg(rewriter);
111+
runCompatTest.addArgs(&.{ b.build_root.path orelse ".", kcovArgs, args[args.len - 1] });
112+
stepCompatTest.dependOn(&runCompatTest.step);
113+
} else {
114+
const COMPAT_RUN_CMD = "ZIGPAK_REWRITER=$1 bun test";
115+
116+
const runCompatTest = b.addSystemCommand(&.{ "bun", "exec", COMPAT_RUN_CMD });
117+
runCompatTest.addArtifactArg(rewriter);
118+
stepCompatTest.dependOn(&runCompatTest.step);
119+
}
103120
}
104121

105122
{
@@ -109,8 +126,21 @@ pub fn build(b: *std.Build) void {
109126
.optimize = optimize,
110127
});
111128

112-
const run_main_tests = b.addRunArtifact(tests);
113-
114-
stepTest.dependOn(&run_main_tests.step);
129+
if (kcov) |args| {
130+
const run = b.addSystemCommand(&.{"kcov"});
131+
const includeArg = std.fmt.allocPrint(
132+
b.allocator,
133+
"--include-path={s}",
134+
.{b.build_root.path orelse "."},
135+
) catch @panic("OOM");
136+
run.addArg(includeArg);
137+
run.addArgs(args);
138+
run.addArtifactArg(tests);
139+
run.enableTestRunnerMode();
140+
stepTest.dependOn(&run.step);
141+
} else {
142+
const run = b.addRunArtifact(tests);
143+
stepTest.dependOn(&run.step);
144+
}
115145
}
116146
}

bunfig.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[test]
2+
preload = ["./tests/kcov.ts"]

tests/kcov.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { afterAll } from "bun:test";
2+
import { mkdir, rm } from "node:fs/promises";
3+
4+
export const KCOV = process.env["KCOV"];
5+
export const KCOV_ARGS = process.env["KCOV_ARGS"] ?? "";
6+
const KCOV_REPORT = process.env["KCOV_REPORT"] ?? "./zig-out/cov";
7+
8+
export const coverages = [] as string[];
9+
10+
if (KCOV) {
11+
afterAll(async () => {
12+
await mkdir(KCOV_REPORT, { recursive: true });
13+
await Bun.$`${KCOV} ${KCOV_ARGS} --merge ${KCOV_REPORT.split(" ")} ${coverages}`;
14+
await Promise.all(coverages.map((x) => rm(x, { recursive: true })));
15+
});
16+
}

tests/tools.ts

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,23 @@
1-
const REWRITER_PATH =
1+
import { coverages, KCOV, KCOV_ARGS } from "./kcov";
2+
import { mkdtempSync } from "node:fs";
3+
import { join } from "node:path";
4+
import { tmpdir } from "node:os";
5+
6+
const REWRITER =
27
process.env["ZIGPAK_REWRITER"] || "./zig-out/bin/zigpak-rewriter";
38

9+
function runRewriter(data: Uint8Array | ArrayBuffer | Buffer) {
10+
if (KCOV) {
11+
const collectPath = mkdtempSync(join(tmpdir(), "zigpak-"));
12+
coverages.push(collectPath);
13+
return Bun.$`${KCOV} ${KCOV_ARGS} --collect-only ${collectPath} ${REWRITER} < ${data}`;
14+
} else {
15+
return Bun.$`${REWRITER} < ${data}`;
16+
}
17+
}
18+
419
export async function rewriter(data: Uint8Array | ArrayBuffer | Buffer) {
5-
const { stdout, stderr, exitCode } = await Bun.$`${REWRITER_PATH} < ${data}`
20+
const { stdout, stderr, exitCode } = await runRewriter(data)
621
.quiet()
722
.nothrow();
823
if (stderr.length > 0) {

0 commit comments

Comments
 (0)