53 lines
2.4 KiB
TypeScript
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)
|
|
})
|
|
})
|