refactor: move world concepts into engine
This commit is contained in:
parent
eeedcb8e48
commit
2d15c7ab8d
52 changed files with 3298 additions and 1558 deletions
|
|
@ -1,6 +1,6 @@
|
|||
import { expect, test } from "bun:test"
|
||||
import { readdirSync, readFileSync, statSync } from "node:fs"
|
||||
import { join } from "node:path"
|
||||
import { existsSync, readdirSync, readFileSync, statSync } from "node:fs"
|
||||
import path from "node:path"
|
||||
|
||||
// The engine is the reusable, content-agnostic layer: it must import nothing from
|
||||
// game (content) or app (browser glue). game -> engine and app -> game -> engine are
|
||||
|
|
@ -9,7 +9,7 @@ import { join } from "node:path"
|
|||
function tsFiles(dir: string): string[] {
|
||||
const out: string[] = []
|
||||
for (const name of readdirSync(dir)) {
|
||||
const p = join(dir, name)
|
||||
const p = path.join(dir, name)
|
||||
if (statSync(p).isDirectory()) {
|
||||
out.push(...tsFiles(p))
|
||||
} else if (p.endsWith(".ts")) {
|
||||
|
|
@ -19,14 +19,42 @@ function tsFiles(dir: string): string[] {
|
|||
return out
|
||||
}
|
||||
|
||||
function repositoryRoot(): string {
|
||||
const parent = new URL("..", import.meta.url).pathname
|
||||
return existsSync(path.join(parent, "app/renderer.ts")) ? parent : path.join(parent, "..")
|
||||
}
|
||||
|
||||
function importsLayer(source: string, layers: string): boolean {
|
||||
return new RegExp(`(?:from\\s+|import\\s*(?:\\(\\s*)?)["'][^"']*/(?:${layers})/`).test(source)
|
||||
}
|
||||
|
||||
test("engine imports nothing from game or app", () => {
|
||||
const engineDir = new URL("../engine", import.meta.url).pathname
|
||||
const offenders = tsFiles(engineDir).filter((f) => /from\s+["'][^"']*\/(?:game|app)\//.test(readFileSync(f, "utf8")))
|
||||
const engineDir = path.join(repositoryRoot(), "engine")
|
||||
const offenders = tsFiles(engineDir).filter((file) => importsLayer(readFileSync(file, "utf8"), "game|app"))
|
||||
expect(offenders).toEqual([])
|
||||
})
|
||||
|
||||
test("game imports nothing from app", () => {
|
||||
const gameDir = new URL("../game", import.meta.url).pathname
|
||||
const offenders = tsFiles(gameDir).filter((f) => /from\s+["'][^"']*\/app\//.test(readFileSync(f, "utf8")))
|
||||
const gameDir = path.join(repositoryRoot(), "game")
|
||||
const offenders = tsFiles(gameDir).filter((file) => importsLayer(readFileSync(file, "utf8"), "app"))
|
||||
expect(offenders).toEqual([])
|
||||
})
|
||||
|
||||
test("render driver and worker know no game content", () => {
|
||||
const root = repositoryRoot()
|
||||
const files = [path.join(root, "app/renderer.ts"), path.join(root, "app/render-worker.ts")]
|
||||
const offenders = files.filter((file) => importsLayer(readFileSync(file, "utf8"), "game"))
|
||||
expect(offenders).toEqual([])
|
||||
})
|
||||
|
||||
test("game exports no closed content-kind registries", () => {
|
||||
const gameDir = path.join(repositoryRoot(), "game")
|
||||
const offenders = tsFiles(gameDir).filter((file) => {
|
||||
const source = readFileSync(file, "utf8")
|
||||
return (
|
||||
/\b(?:export\s+)?(?:type|enum)\s+\w+Kind\b/.test(source) ||
|
||||
/\b(?:const|let|var)\s+\w*_(?:KINDS|REGISTRY)\b/.test(source)
|
||||
)
|
||||
})
|
||||
expect(offenders).toEqual([])
|
||||
})
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue