Skip to content

Commit 2b6b627

Browse files
committed
test: stabilize plugin boundary invariants
1 parent 97dfbe0 commit 2b6b627

1 file changed

Lines changed: 51 additions & 41 deletions

File tree

src/plugins/contracts/boundary-invariants.test.ts

Lines changed: 51 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { readFileSync } from "node:fs";
2-
import { dirname, resolve } from "node:path";
1+
import { readFileSync, readdirSync } from "node:fs";
2+
import { dirname, relative, resolve, sep } from "node:path";
33
import { fileURLToPath } from "node:url";
44
import { describe, expect, it } from "vitest";
55

@@ -33,13 +33,43 @@ const ALLOWED_CHANNEL_BUNDLED_METADATA_CONSUMERS = new Set([
3333
"src/channels/plugins/session-conversation.bundled-fallback.test.ts",
3434
]);
3535

36+
type FileFilter = {
37+
excludeTests?: boolean;
38+
testOnly?: boolean;
39+
};
40+
41+
function listTsFiles(rootRelativePath: string, filter: FileFilter = {}): string[] {
42+
const root = resolve(REPO_ROOT, rootRelativePath);
43+
const files: string[] = [];
44+
45+
function walk(directory: string) {
46+
for (const entry of readdirSync(directory, { withFileTypes: true })) {
47+
const fullPath = resolve(directory, entry.name);
48+
if (entry.isDirectory()) {
49+
walk(fullPath);
50+
continue;
51+
}
52+
if (!entry.isFile() || !entry.name.endsWith(".ts")) {
53+
continue;
54+
}
55+
const repoRelativePath = relative(REPO_ROOT, fullPath).split(sep).join("/");
56+
if (filter.excludeTests && repoRelativePath.endsWith(".test.ts")) {
57+
continue;
58+
}
59+
if (filter.testOnly && !repoRelativePath.endsWith(".test.ts")) {
60+
continue;
61+
}
62+
files.push(repoRelativePath);
63+
}
64+
}
65+
66+
walk(root);
67+
return files.toSorted();
68+
}
69+
3670
describe("plugin contract boundary invariants", () => {
37-
it("keeps bundled-capability-metadata confined to contract/test inventory", async () => {
38-
const { globSync } = await import("glob");
39-
const files = globSync("src/**/*.ts", {
40-
cwd: REPO_ROOT,
41-
nodir: true,
42-
});
71+
it("keeps bundled-capability-metadata confined to contract/test inventory", () => {
72+
const files = listTsFiles("src");
4373
const offenders = files.filter((file) => {
4474
if (ALLOWED_BUNDLED_CAPABILITY_METADATA_CONSUMERS.has(file)) {
4575
return false;
@@ -50,26 +80,17 @@ describe("plugin contract boundary invariants", () => {
5080
expect(offenders).toEqual([]);
5181
});
5282

53-
it("keeps the bundled contract inventory out of non-test runtime code", async () => {
54-
const { globSync } = await import("glob");
55-
const files = globSync("src/**/*.ts", {
56-
cwd: REPO_ROOT,
57-
nodir: true,
58-
ignore: ["src/**/*.test.ts"],
59-
});
83+
it("keeps the bundled contract inventory out of non-test runtime code", () => {
84+
const files = listTsFiles("src", { excludeTests: true });
6085
const offenders = files.filter((file) => {
6186
const source = readFileSync(resolve(REPO_ROOT, file), "utf8");
6287
return source.includes("contracts/inventory/bundled-capability-metadata");
6388
});
6489
expect(offenders).toEqual([]);
6590
});
6691

67-
it("keeps core tests off bundled extension deep imports", async () => {
68-
const { globSync } = await import("glob");
69-
const files = globSync("src/**/*.test.ts", {
70-
cwd: REPO_ROOT,
71-
nodir: true,
72-
});
92+
it("keeps core tests off bundled extension deep imports", () => {
93+
const files = listTsFiles("src", { testOnly: true });
7394
const offenders = files.filter((file) => {
7495
if (ALLOWED_EXTENSION_PATH_STRING_TESTS.has(file)) {
7596
return false;
@@ -84,12 +105,8 @@ describe("plugin contract boundary invariants", () => {
84105
expect(offenders).toEqual([]);
85106
});
86107

87-
it("keeps plugin contract tests off bundled path helpers unless the test is explicitly about paths", async () => {
88-
const { globSync } = await import("glob");
89-
const files = globSync("src/plugins/contracts/**/*.test.ts", {
90-
cwd: REPO_ROOT,
91-
nodir: true,
92-
});
108+
it("keeps plugin contract tests off bundled path helpers unless the test is explicitly about paths", () => {
109+
const files = listTsFiles("src/plugins/contracts", { testOnly: true });
93110
const offenders = files.filter((file) => {
94111
if (ALLOWED_CONTRACT_BUNDLED_PATH_HELPERS.has(file)) {
95112
return false;
@@ -100,13 +117,8 @@ describe("plugin contract boundary invariants", () => {
100117
expect(offenders).toEqual([]);
101118
});
102119

103-
it("keeps channel production code off bundled-plugin-metadata helpers", async () => {
104-
const { globSync } = await import("glob");
105-
const files = globSync("src/channels/**/*.ts", {
106-
cwd: REPO_ROOT,
107-
nodir: true,
108-
ignore: ["src/channels/**/*.test.ts"],
109-
});
120+
it("keeps channel production code off bundled-plugin-metadata helpers", () => {
121+
const files = listTsFiles("src/channels", { excludeTests: true });
110122
const offenders = files.filter((file) => {
111123
if (ALLOWED_CHANNEL_BUNDLED_METADATA_CONSUMERS.has(file)) {
112124
return false;
@@ -117,13 +129,11 @@ describe("plugin contract boundary invariants", () => {
117129
expect(offenders).toEqual([]);
118130
});
119131

120-
it("keeps contract loaders off hand-built bundled extension paths", async () => {
121-
const { globSync } = await import("glob");
122-
const files = globSync("src/{plugins,channels}/**/*.ts", {
123-
cwd: REPO_ROOT,
124-
nodir: true,
125-
ignore: ["src/**/*.test.ts"],
126-
});
132+
it("keeps contract loaders off hand-built bundled extension paths", () => {
133+
const files = [
134+
...listTsFiles("src/plugins", { excludeTests: true }),
135+
...listTsFiles("src/channels", { excludeTests: true }),
136+
].toSorted();
127137
const offenders = files.filter((file) => {
128138
const source = readFileSync(resolve(REPO_ROOT, file), "utf8");
129139
return /extensions\/\$\{|\.\.\/\.\.\/\.\.\/\.\.\/extensions\//u.test(source);

0 commit comments

Comments
 (0)