Skip to content

Commit ea84651

Browse files
committed
test(type-check): 12 packages type-check their tests, and the gap is now declared (objectstack#4118)
A package tsconfig excludes test files — correctly, it is the BUILD config and they would emit into `dist`. The hole is that no other `tsc` invocation read them either, so for most packages nothing compiled a test at all. objectui#3009 found what that costs: `spec-derived-unions.test.ts` had built its whole contract on `satisfies` checks that never ran, under a header calling them "the real enforcement". Reverting a derived alias produced zero errors. Tests are where agents encode their understanding of a contract. Unchecked, a wrong understanding accumulates silently and then reads as evidence. Wires up every package measured at zero code-tier errors — 12, not the 8 the issue estimated. The extra four fell out of a better config template: `plugin-calendar` and `plugin-kanban` needed only the jest-dom matcher types, `providers` was already clean, and `sdui-parser`'s 50 TS2304s were env globals exactly as the issue suspected, not real errors. Wiring `sdui-parser` up surfaced a real bug: `render.test.tsx` imports `@object-ui/core` and `@object-ui/react` with neither declared in its package.json. Both were phantom — resolved only through the ROOT tsconfig's `paths` alias and vitest, never as a dependency a consumer would get. Declared as devDependencies, which is also what makes the `paths: {}` in the new config meaningful: with the alias in place an undeclared workspace import still compiles. Every `tsconfig.test.json` follows objectui#3009's template — `noEmit`, `composite: false`, `paths: {}` to kill the TS6059 source-leak noise, and `lib` / `types` only where the tests actually need them (`mobile` reads `Array.prototype.at`, so ES2022; `plugin-report` pulls in a source file that reads `process.env`, so `node`). The guard grows a second half so this cannot silently regress. A package with test files either compiles them or carries a TEST_DEBT entry with a MEASURED count — re-measured against current main, not copied from the issue's table: 240 code-tier errors across 15 packages. It also fails on a `tsconfig.test.json` that nothing runs, which is the objectui#3009 shape itself: a file that looks like enforcement while no compiler reads it. Discrimination proof — three ways it fails, run before landing: 1. unchaining plugin-tree's config: "has a tsconfig.test.json that its type-check script never runs … the exact shape of objectui#3009" 2. deleting the `permissions` TEST_DEBT entry: "has 3 test files that no `tsc` invocation reads" 3. a package listed in both DEBT and TEST_DEBT is rejected as one gap counted twice (this is how `layout` was caught during the sweep) Refs objectstack#4118, objectui#3009, objectstack#4074, #2911, #2901 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Rvv6qysks2dRLaGfpTdgEy
1 parent 0c2ec44 commit ea84651

26 files changed

Lines changed: 449 additions & 18 deletions

packages/mobile/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
"build": "tsc",
3131
"clean": "rm -rf dist",
3232
"test": "vitest run",
33-
"type-check": "tsc --noEmit",
33+
"type-check": "tsc --noEmit && tsc -p tsconfig.test.json",
3434
"lint": "eslint ."
3535
},
3636
"peerDependencies": {

packages/mobile/tsconfig.test.json

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
// Type-checks this package's TESTS, which `tsconfig.json` excludes.
3+
// See `packages/types/tsconfig.test.json` for why that exclusion was a hole:
4+
// the build correctly keeps tests out of `dist`, but nothing else compiled
5+
// them, so a test could assert a contract the compiler never checked.
6+
"extends": "../../tsconfig.json",
7+
"compilerOptions": {
8+
"noEmit": true,
9+
// The package build is `composite` + `declaration`; this project emits
10+
// nothing, so it must not inherit those.
11+
"composite": false,
12+
// `gesture-spec-parity.test.tsx` reads `mock.calls.at(-1)`. ES2022 is the
13+
// floor for `Array.prototype.at` — the root config's ES2020 is what the
14+
// SOURCE targets, and a test is free to need more than the shipped bundle.
15+
"lib": ["ES2022", "DOM", "DOM.Iterable"],
16+
// Drop the root tsconfig's source-tree `paths` so `@object-ui/*` and
17+
// `@objectstack/spec` resolve through the workspace dependency's built
18+
// `.d.ts` instead of pulling sibling sources in as program inputs (TS6059).
19+
"paths": {}
20+
},
21+
"include": ["src/**/*.test.ts", "src/**/*.test.tsx"]
22+
}

packages/plugin-calendar/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
"build": "vite build",
2828
"test": "vitest run",
2929
"test:watch": "vitest",
30-
"type-check": "tsc --noEmit",
30+
"type-check": "tsc --noEmit && tsc -p tsconfig.test.json",
3131
"lint": "eslint ."
3232
},
3333
"dependencies": {
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{
2+
// Type-checks this package's TESTS, which `tsconfig.json` excludes.
3+
// See `packages/types/tsconfig.test.json` for why that exclusion was a hole:
4+
// the build correctly keeps tests out of `dist`, but nothing else compiled
5+
// them, so a test could assert a contract the compiler never checked.
6+
"extends": "../../tsconfig.json",
7+
"compilerOptions": {
8+
"noEmit": true,
9+
// The package build emits `dist`; this project emits nothing, so it must
10+
// not inherit `composite` / `declaration` from the build config.
11+
"composite": false,
12+
// The `toBeInTheDocument` / `toHaveTextContent` matchers these tests use are
13+
// a global augmentation, not an import, and `@testing-library/jest-dom` does
14+
// not live under `@types/` — so it is never picked up automatically and has
15+
// to be named here. Naming `types` at all switches off automatic `@types/*`
16+
// inclusion, which is fine: nothing in these tests touches Node globals.
17+
"types": ["@testing-library/jest-dom"],
18+
// Drop the root tsconfig's source-tree `paths` so `@object-ui/*` and
19+
// `@objectstack/spec` resolve through the workspace dependency's built
20+
// `.d.ts` instead of pulling sibling sources in as program inputs (TS6059).
21+
"paths": {}
22+
},
23+
"include": ["src/**/*.test.ts", "src/**/*.test.tsx"]
24+
}

packages/plugin-designer/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
"build": "vite build",
2525
"clean": "rm -rf dist",
2626
"test": "vitest run",
27-
"type-check": "tsc --noEmit",
27+
"type-check": "tsc --noEmit && tsc -p tsconfig.test.json",
2828
"lint": "eslint ."
2929
},
3030
"peerDependencies": {
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
// Type-checks this package's TESTS, which `tsconfig.json` excludes.
3+
// See `packages/types/tsconfig.test.json` for why that exclusion was a hole:
4+
// the build correctly keeps tests out of `dist`, but nothing else compiled
5+
// them, so a test could assert a contract the compiler never checked.
6+
"extends": "../../tsconfig.json",
7+
"compilerOptions": {
8+
"noEmit": true,
9+
// The package build emits `dist`; this project emits nothing, so it must
10+
// not inherit `composite` / `declaration` from the build config.
11+
"composite": false,
12+
// Drop the root tsconfig's source-tree `paths` so `@object-ui/*` and
13+
// `@objectstack/spec` resolve through the workspace dependency's built
14+
// `.d.ts` instead of pulling sibling sources in as program inputs (TS6059).
15+
"paths": {}
16+
},
17+
"include": ["src/**/*.test.ts", "src/**/*.test.tsx"]
18+
}

packages/plugin-kanban/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
"build": "vite build",
2828
"test": "vitest run",
2929
"test:watch": "vitest",
30-
"type-check": "tsc --noEmit",
30+
"type-check": "tsc --noEmit && tsc -p tsconfig.test.json",
3131
"lint": "eslint ."
3232
},
3333
"dependencies": {
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{
2+
// Type-checks this package's TESTS, which `tsconfig.json` excludes.
3+
// See `packages/types/tsconfig.test.json` for why that exclusion was a hole:
4+
// the build correctly keeps tests out of `dist`, but nothing else compiled
5+
// them, so a test could assert a contract the compiler never checked.
6+
"extends": "../../tsconfig.json",
7+
"compilerOptions": {
8+
"noEmit": true,
9+
// The package build emits `dist`; this project emits nothing, so it must
10+
// not inherit `composite` / `declaration` from the build config.
11+
"composite": false,
12+
// The `toBeInTheDocument` / `toHaveTextContent` matchers these tests use are
13+
// a global augmentation, not an import, and `@testing-library/jest-dom` does
14+
// not live under `@types/` — so it is never picked up automatically and has
15+
// to be named here. Naming `types` at all switches off automatic `@types/*`
16+
// inclusion, which is fine: nothing in these tests touches Node globals.
17+
"types": ["@testing-library/jest-dom"],
18+
// Drop the root tsconfig's source-tree `paths` so `@object-ui/*` and
19+
// `@objectstack/spec` resolve through the workspace dependency's built
20+
// `.d.ts` instead of pulling sibling sources in as program inputs (TS6059).
21+
"paths": {}
22+
},
23+
"include": ["src/**/*.test.ts", "src/**/*.test.tsx"]
24+
}

packages/plugin-markdown/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
"build": "vite build",
2828
"test": "vitest run",
2929
"test:watch": "vitest",
30-
"type-check": "tsc --noEmit",
30+
"type-check": "tsc --noEmit && tsc -p tsconfig.test.json",
3131
"lint": "eslint ."
3232
},
3333
"dependencies": {
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
// Type-checks this package's TESTS, which `tsconfig.json` excludes.
3+
// See `packages/types/tsconfig.test.json` for why that exclusion was a hole:
4+
// the build correctly keeps tests out of `dist`, but nothing else compiled
5+
// them, so a test could assert a contract the compiler never checked.
6+
"extends": "../../tsconfig.json",
7+
"compilerOptions": {
8+
"noEmit": true,
9+
// The package build emits `dist`; this project emits nothing, so it must
10+
// not inherit `composite` / `declaration` from the build config.
11+
"composite": false,
12+
// Drop the root tsconfig's source-tree `paths` so `@object-ui/*` and
13+
// `@objectstack/spec` resolve through the workspace dependency's built
14+
// `.d.ts` instead of pulling sibling sources in as program inputs (TS6059).
15+
"paths": {}
16+
},
17+
"include": ["src/**/*.test.ts", "src/**/*.test.tsx"]
18+
}

0 commit comments

Comments
 (0)