Files
template-app/test/boundaries.test.ts

53 lines
2.4 KiB
TypeScript

// SPDX-License-Identifier: LicenseRef-ConusAI-Template-1.0
// The boundary rules are generated from the folder tree (spec §2), so a module added tomorrow is
// covered without anybody editing a list. This suite is that promise.
import { createRequire } from "node:module"
import { describe, expect, it } from "vitest"
const require = createRequire(import.meta.url)
const { buildForbidden, listModules } = require("../scripts/dep-rules.cjs") as {
buildForbidden(
moduleIds: string[],
): { name: string; from: { path?: string; pathNot?: string }; to: { path?: string | string[]; circular?: boolean } }[]
listModules(root: string): string[]
}
const named = (rules: ReturnType<typeof buildForbidden>, name: string) => rules.find((rule) => rule.name === name)
describe("the generated boundary rules", () => {
it("find this app's modules on disk", () => {
const found = listModules(new URL("..", import.meta.url).pathname)
expect(Array.isArray(found)).toBe(true)
})
it("keep the worker entry out of every app but the worker", () => {
const rule = named(buildForbidden([]), "worker-entry-is-the-workers-own")
expect(rule?.from.pathNot).toBe("^apps/worker/")
// The resolved path, which is what dependency-cruiser matches on.
expect(rule?.to.path).toBe("@conusai-kit/core/dist/worker\\.")
})
it("keep a driver, an SDK and a framework out of a module's core", () => {
const rule = named(buildForbidden(["notes"]), "core-imports-no-engine-sdk-or-framework")
const patterns = (rule?.to.path ?? []) as string[]
expect(patterns.join("|")).toMatch(/kysely/)
expect(patterns.join("|")).toMatch(/next/)
expect(patterns.join("|")).toMatch(/@conusai-sdk/)
})
it("add a rule per module pair, so a module reaches another only through its contract", () => {
const rules = buildForbidden(["documents", "notes"])
expect(named(rules, "module-notes-crosses-only-contracts")?.to.path).toBe("^modules/(documents)/(?!contract/)")
expect(named(rules, "module-documents-crosses-only-contracts")?.to.path).toBe("^modules/(notes)/(?!contract/)")
})
it("add no module rule when there is only one module to cross into", () => {
expect(buildForbidden(["notes"]).some((rule) => rule.name.startsWith("module-"))).toBe(false)
})
it("refuse a cycle anywhere", () => {
expect(named(buildForbidden([]), "no-circular")?.to.circular).toBe(true)
})
})