-
Notifications
You must be signed in to change notification settings - Fork 3k
Expand file tree
/
Copy pathgrowth-guardrails-entrypoints.test.ts
More file actions
141 lines (123 loc) · 4.83 KB
/
Copy pathgrowth-guardrails-entrypoints.test.ts
File metadata and controls
141 lines (123 loc) · 4.83 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
// SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
// SPDX-License-Identifier: Apache-2.0
import { spawnSync } from "node:child_process";
import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import { join, resolve } from "node:path";
import { pathToFileURL } from "node:url";
import { describe, expect, it } from "vitest";
const REPO_ROOT = resolve(import.meta.dirname, "..");
const ENTRYPOINT_ENV = {
BASE_SHA: "base",
GH_TOKEN: "token",
HEAD_REPO: "fork/repo",
HEAD_SHA: "head",
PR_NUMBER: "1",
REPO: "NVIDIA/NemoClaw",
} as const;
const FETCH_PRELOAD = `
const responses = JSON.parse(process.env.MOCK_RESPONSES ?? "[]");
globalThis.fetch = async () => new Response(JSON.stringify(responses.shift()), {
status: 200,
headers: { "content-type": "application/json" },
});
`;
function blobPayload(text: string | null): unknown {
return {
data: {
repository: {
f0:
text === null ? null : { __typename: "Blob", text, isBinary: false, isTruncated: false },
},
},
};
}
function runEntrypoint(
relativeToolPath: string,
responses: readonly unknown[],
): ReturnType<typeof spawnSync> {
const directory = mkdtempSync(join(tmpdir(), "growth-guardrail-entrypoint-"));
const preload = join(directory, "fetch-preload.mjs");
writeFileSync(preload, FETCH_PRELOAD);
const result = spawnSync(
process.execPath,
[
"--experimental-strip-types",
"--import",
pathToFileURL(preload).href,
resolve(REPO_ROOT, relativeToolPath),
],
{
cwd: REPO_ROOT,
encoding: "utf8",
env: {
...process.env,
...ENTRYPOINT_ENV,
MOCK_RESPONSES: JSON.stringify(responses),
},
},
);
rmSync(directory, { recursive: true, force: true });
return result;
}
describe("growth-guardrails executable entrypoints (#6953)", () => {
it("prints the conditional guardrail PASS diagnostic", () => {
const result = runEntrypoint("tools/growth-guardrails/test-conditionals.mts", [[]]);
expect(result.status).toBe(0);
expect(result.stdout).toContain(
"PASS: changed test files did not add if statements (0 at PR head vs 0 at base).",
);
});
it("prints the conditional guardrail FAIL heading and file detail", () => {
const result = runEntrypoint("tools/growth-guardrails/test-conditionals.mts", [
[{ filename: "test/a.test.ts", status: "modified" }],
blobPayload("it('a', () => { expect(1).toBe(1); });"),
blobPayload("it('a', () => { if (condition) expect(1).toBe(1); });"),
]);
expect(result.status).toBe(1);
expect(result.stderr).toContain("FAIL: changed test files add if statements.");
expect(result.stderr).toContain("test/a.test.ts: 1 if statement(s), up from 0");
});
it("prints the test-loop guardrail PASS diagnostic", () => {
const result = runEntrypoint("tools/growth-guardrails/test-loops.mts", [[]]);
expect(result.status).toBe(0);
expect(result.stdout).toContain(
"PASS: no changed test file increased its test-loop count (0 total at the latest PR commit vs 0 at base).",
);
});
it("prints the test-loop guardrail FAIL heading and file detail", () => {
const result = runEntrypoint("tools/growth-guardrails/test-loops.mts", [
[{ filename: "test/a.test.ts", status: "modified" }],
blobPayload("it('a', () => { expect(1).toBe(1); });"),
blobPayload("it('a', () => { for (const row of rows) expect(row).toBeDefined(); });"),
]);
expect(result.status).toBe(1);
expect(result.stderr).toContain("FAIL: changed test files increase test-loop counts.");
expect(result.stderr).toContain(
"test/a.test.ts: 1 test loop(s), up from 0",
);
expect(result.stderr).toContain(
"Move iteration needed for one behavior into a named helper outside the test callback. Use it.each or test.each when loop rows are independent cases.",
);
});
it("prints the size-budget guardrail PASS diagnostic", () => {
const result = runEntrypoint("tools/growth-guardrails/test-size-budget.mts", [
[],
blobPayload(null),
]);
expect(result.status).toBe(0);
expect(result.stdout).toContain(
"PASS: test size budget policy is monotonic and 0 changed test file(s) are within budget.",
);
});
it("prints the size-budget guardrail FAIL heading and budget detail", () => {
const result = runEntrypoint("tools/growth-guardrails/test-size-budget.mts", [
[{ filename: "ci/test-file-size-budget.json", status: "added" }],
blobPayload(null),
blobPayload('{"defaultMaxLines":2000,"legacyMaxLines":{}}'),
]);
expect(result.status).toBe(1);
expect(result.stderr).toContain("FAIL: test size budget policy would be weakened or exceeded.");
expect(result.stderr).toContain("defaultMaxLines increased from 1500 to 2000");
});
});