65 lines
2.7 KiB
TypeScript
65 lines
2.7 KiB
TypeScript
// SPDX-License-Identifier: LicenseRef-ConusAI-Template-1.0
|
|
// Every place outside the tests that stands up an app's fake platform either serves the app's
|
|
// deployment (`deployment:` -- its business gateway, captured e-mail and notifications, as `pnpm dev`
|
|
// does) or says, in a marker comment just above the call, why its app needs none. A new stack that
|
|
// forgets it fails here by name instead of refusing every business procedure (TEMPLATE-LESSON proc-5).
|
|
|
|
import { readdirSync, readFileSync, statSync } from "node:fs"
|
|
import { join, relative } from "node:path"
|
|
import { describe, expect, it } from "vitest"
|
|
|
|
const ROOT = new URL("..", import.meta.url).pathname
|
|
const MARKER = "// fake-platform: no deployment:"
|
|
const SKIP = new Set(["node_modules", "dist", "test", "__tests__", ".logs", ".dev", ".git"])
|
|
|
|
function sources(dir: string): string[] {
|
|
return readdirSync(dir).flatMap((name) => {
|
|
if (SKIP.has(name)) return []
|
|
const path = join(dir, name)
|
|
if (statSync(path).isDirectory()) return sources(path)
|
|
return /\.(ts|tsx|mjs|js)$/.test(name) && !/\.test\./.test(name) ? [path] : []
|
|
})
|
|
}
|
|
|
|
/** The text of each `startFakePlatform(…)` call in a file, with the lines just above it. */
|
|
function calls(text: string): Array<{ line: number; call: string; above: string }> {
|
|
const found: Array<{ line: number; call: string; above: string }> = []
|
|
for (let at = text.indexOf("startFakePlatform("); at >= 0; at = text.indexOf("startFakePlatform(", at + 1)) {
|
|
let depth = 0
|
|
let end = at + "startFakePlatform".length
|
|
for (; end < text.length; end++) {
|
|
if (text[end] === "(") depth++
|
|
if (text[end] === ")" && --depth === 0) break
|
|
}
|
|
const line = text.slice(0, at).split("\n").length
|
|
found.push({
|
|
line,
|
|
call: text.slice(at, end + 1),
|
|
above: text
|
|
.split("\n")
|
|
.slice(Math.max(0, line - 4), line - 1)
|
|
.join("\n"),
|
|
})
|
|
}
|
|
return found
|
|
}
|
|
|
|
describe("every fake platform the template stands up", () => {
|
|
const sites = sources(ROOT).flatMap((path) =>
|
|
calls(readFileSync(path, "utf8")).map((site) => ({ ...site, file: relative(ROOT, path) })),
|
|
)
|
|
|
|
it("finds the stacks it holds to the rule", () => {
|
|
expect(sites.map((site) => site.file).sort()).toEqual(
|
|
expect.arrayContaining(["e2e/support/stack.ts", "scripts/dev.mjs"]),
|
|
)
|
|
})
|
|
|
|
it("serves the app's deployment, or says why its app needs none", () => {
|
|
const missing = sites
|
|
.filter((site) => !/\bdeployment\s*:/.test(site.call) && !site.above.includes(MARKER))
|
|
.map((site) => `${site.file}:${site.line}`)
|
|
expect(missing, `pass \`deployment\` to startFakePlatform, or state why not with "${MARKER} <reason>"`).toEqual([])
|
|
})
|
|
})
|