chore: enforce test directory conventions (#496)

* chore: enforce test directory conventions

Move package, app, and tool tests out of src and add guard enforcement so source directories stay source-only.

* ci: use guard and package-scoped tests

Run the new repository guard in CI and keep test execution aligned with package-scoped commands after removing root aliases.

* ci: align stable release guard check

Use the new repository guard in stable release verification after replacing the residual-JS-only script.

* chore: tighten test layout enforcement

Enforce sibling tests directories, typecheck moved test suites with dedicated configs, and refresh remaining guidance that pointed at src-based tests.

* chore: clarify no-emit test tsconfigs

Explicitly disable declaration-only emit in test tsconfigs so review tooling sees they are no-emit typecheck configs.
This commit is contained in:
PerishFire
2026-05-05 15:34:22 +08:00
committed by GitHub
parent 16693fdfa8
commit bbdd4e84b5
90 changed files with 562 additions and 399 deletions
+2 -1
View File
@@ -15,10 +15,11 @@ Follow the root `AGENTS.md` first. This file only records module-level boundarie
- Keep `tools-pack` focused on packaging/runtime control and release artifact preparation. Runtime updater product integration remains a later phase.
- Pack-specific Electron builder resources belong under `tools/pack/resources/`; do not reference app/docs/download assets directly from pack logic.
- Namespace controls packaged data/log/runtime/cache paths. Ports are transient transport details and must not participate in path decisions.
- The package/build boundary of root `pnpm build` is intentionally unchanged in this round and should be handled by the future `tools-pack` task.
- There is no root `pnpm build` aggregate. Use package-scoped builds for source packages and `pnpm tools-pack ...` for packaged artifact build/install/release flows.
## Orchestration boundary
- Tool tests live in each tool's `tests/` directory, sibling to `src/`; keep `src/` source-only and do not add new `*.test.ts` or `*.test.tsx` files under `src/`.
- Orchestration layers must consume primitives from `@open-design/sidecar-proto`, `@open-design/sidecar`, and `@open-design/platform`.
- Do not hand-build `--od-stamp-*` args, process-scan regexes, runtime tokens, process roles, or duplicate namespace/source args in `tools/dev`, future `tools/pack`, or packaged launchers.
- Port flags are authoritative inputs: `--daemon-port` and `--web-port`. Internal env vars are `OD_PORT` and `OD_WEB_PORT`; do not introduce `NEXT_PORT`.
+4 -4
View File
@@ -9,13 +9,13 @@
"scripts": {
"build": "node ./esbuild.config.mjs",
"dev": "tsx ./src/index.ts",
"test": "node --import tsx --test src/*.test.ts",
"test": "node --import tsx --test tests/*.test.ts",
"typecheck": "tsc -p tsconfig.json --noEmit"
},
"dependencies": {
"@open-design/platform": "workspace:0.3.0",
"@open-design/sidecar": "workspace:0.3.0",
"@open-design/sidecar-proto": "workspace:0.3.0",
"@open-design/platform": "workspace:*",
"@open-design/sidecar": "workspace:*",
"@open-design/sidecar-proto": "workspace:*",
"cac": "6.7.14"
},
"devDependencies": {
+1 -1
View File
@@ -909,7 +909,7 @@ function addPortOptions(command: ReturnType<typeof cli.command>) {
return command
.option("--daemon-port <port>", "force daemon port; conflict quick-fails")
.option("--web-port <port>", "force web port; conflict quick-fails")
.option("--prod", "use production build (requires pnpm build first)");
.option("--prod", "use production build (requires pnpm --filter @open-design/web build first)");
}
addPortOptions(addSharedOptions(cli.command("start [app]", "Start daemon, web, desktop, or all when app is omitted"))).action(
@@ -5,7 +5,7 @@ import {
appendStartupLogDiagnostics,
createStartupLogDiagnostics,
detectLogDiagnostics,
} from "./diagnostics.js";
} from "../src/diagnostics.js";
describe("tools-dev diagnostics", () => {
it("detects native addon ABI mismatches", () => {
+1 -1
View File
@@ -14,5 +14,5 @@
"target": "ES2024",
"types": ["node"]
},
"include": ["src/**/*.ts", "src/**/*.d.ts", "esbuild.config.mjs"]
"include": ["src/**/*.ts", "src/**/*.d.ts", "tests/**/*.ts", "esbuild.config.mjs"]
}
+4 -4
View File
@@ -10,12 +10,12 @@
"build": "node ./esbuild.config.mjs && tsc -p tsconfig.json --emitDeclarationOnly",
"dev": "tsx ./src/index.ts",
"test": "vitest run",
"typecheck": "tsc -p tsconfig.json --noEmit"
"typecheck": "tsc -p tsconfig.json --noEmit && tsc -p tsconfig.tests.json --noEmit"
},
"dependencies": {
"@open-design/platform": "workspace:0.3.0",
"@open-design/sidecar": "workspace:0.3.0",
"@open-design/sidecar-proto": "workspace:0.3.0",
"@open-design/platform": "workspace:*",
"@open-design/sidecar": "workspace:*",
"@open-design/sidecar-proto": "workspace:*",
"@electron/notarize": "3.1.0",
"cac": "6.7.14",
"electron-builder": "26.8.1"
@@ -1,12 +1,12 @@
import { describe, expect, it } from "vitest";
import type { ToolPackConfig } from "./config.js";
import type { ToolPackConfig } from "../src/config.js";
import {
buildDockerArgs,
matchesAppImageProcess,
renderDesktopTemplate,
sanitizeNamespace,
} from "./linux.js";
} from "../src/linux.js";
function makeConfig(): ToolPackConfig {
return {
@@ -3,7 +3,7 @@ import { mkdtemp, readFile, rm, writeFile, mkdir } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { copyBundledResourceTrees } from "./resources.js";
import { copyBundledResourceTrees } from "../src/resources.js";
describe("copyBundledResourceTrees", () => {
it("includes prompt templates", async () => {
+9
View File
@@ -0,0 +1,9 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"emitDeclarationOnly": false,
"noEmit": true,
"rootDir": "."
},
"include": ["src/**/*.ts", "tests/**/*.ts"]
}