Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions .changeset/6465-stale-typecheck-headers.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
---
---

Comment-only fix: eleven test headers across `@object-ui/app-shell` and
`@object-ui/core` still described a type-checking arrangement that no longer
exists. Two distinct stale claims, both now corrected:

1. **"this package's tests are compiled by nothing."** Both packages graduated
in objectui#4040; each `type-check` script is now
`tsc --noEmit && tsc -p tsconfig.test.json`, and `TEST_DEBT` in
`scripts/check-type-check-coverage.mjs` is literally `{}`.
2. **Present-tense citations of `tsconfig.typetests.json`,** of which zero exist
repo-wide (objectui#4291 retired the last of them). Several headers told the
reader that a listing in such a project is what makes their assertions
load-bearing — a file the reader cannot find.

Both matter beyond tidiness because several of these headers *prescribe*: one
said a `@ts-expect-error` here "would be read by no compiler", another that "a
new type-assertion test file is unchecked until it is added to that include
list". Both instruct the next author away from assertions that are in fact
checked, and away from the config that checks them. That is the same shape
objectui#6426 was filed and fixed for in `@object-ui/plugin-dashboard`.

Where a header is now positive ("this file IS compiled"), the claim was
confirmed for **that file**, not inferred from the package-level coverage
reading: `tsc -p tsconfig.test.json --listFiles` lists all 8 edited app-shell
files (of 4455) and all 4 edited core files (of 634), and both projects exit 0.
Surviving mentions of `TEST_DEBT` and `tsconfig.typetests.json` in these files
are deliberate, and are now past-tense — they record why the header used to say
otherwise.

No behaviour change, no public surface change, no assertion or directive
touched.
23 changes: 15 additions & 8 deletions packages/app-shell/src/__tests__/spec-symbol-parity.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -48,13 +48,20 @@
* 0 — the type half of this "tripwire" was, literally, commentary. Which is the
* same landmine this file's own header cites objectui#3009 for.
*
* They are now compiled by `packages/app-shell/tsconfig.typetests.json`, chained
* from this package's `type-check` script, i.e. run by the CI `Type Check` job.
* That project lists its files EXPLICITLY (app-shell's wider test tree still has
* a pre-existing error backlog, tracked as TEST_DEBT), so **a new
* type-assertion test file is unchecked until it is added to that include
* list** — and `scripts/check-type-check-coverage.mjs` fails if the chaining is
* ever dropped, so the gate cannot go quiet again the way it did here.
* They are now compiled by `packages/app-shell/tsconfig.test.json`, chained from
* this package's `type-check` script (`tsc --noEmit && tsc -p tsconfig.test.json`),
* i.e. run by the CI `Type Check` job. That project takes the whole test tree by
* GLOB — `src/**\/*.test.ts` and `src/**\/*.test.tsx` — so **a new type-assertion
* test file under `src/` is checked from the moment it is written**, with nothing
* to register anywhere.
*
* That last sentence used to say the opposite, and the opposite used to be true:
* a narrow `tsconfig.typetests.json` named its files one at a time while the rest
* of this tree sat in TEST_DEBT, and a file was decoration until someone added it
* to that list. The package graduated in objectui#4040 and the narrow project was
* retired with it (objectui#4291 retired the last of them repo-wide; the debt
* table is now empty). `scripts/check-type-check-coverage.mjs` fails if the
* chaining is ever dropped, so the gate cannot go quiet again the way it did here.
*/

import { describe, it, expect } from 'vitest';
Expand DownExpand Up@@ -294,7 +301,7 @@ describe('re-exported values are the spec binding itself', () => {

/**
* Compile-time assertions. A violation is a `tsc` error, not a runtime failure —
* so it surfaces only under `tsconfig.typetests.json` (see the file header), not
* so it surfaces only under `tsconfig.test.json` (see the file header), not
* under vitest.
*/
type Assert<T extends true> = T;
Expand Down
4 changes: 2 additions & 2 deletions packages/app-shell/src/utils/resolveActionParams.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -386,7 +386,7 @@ describe('resolveActionParams — field-inherited option keys (objectui#3559)',
/**
* A `select` field whose options carry the full declared vocabulary. Authoring
* this literal is itself the type-level half of the fix: this file is compiled
* by `tsconfig.typetests.json`, so a `RuntimeField.options` re-narrowed to
* by `tsconfig.test.json`, so a `RuntimeField.options` re-narrowed to
* `{ label, value }` fails excess-property checking right here rather than
* silently reverting the behaviour below.
*/
Expand DownExpand Up@@ -499,7 +499,7 @@ describe('resolveActionParams — field-inherited option keys (objectui#3559)',

it('keeps `label` and `value` required on a param option (type-level)', () => {
// The catch-all widens the vocabulary; it must not dissolve the two keys
// this layer itself reads. Compiled by `tsconfig.typetests.json`, so these
// this layer itself reads. Compiled by `tsconfig.test.json`, so these
// assertions are checked — a re-widening to `Record< string, unknown >`
// turns the unused suppressions into errors.
const complete: ActionParamOption = { label: 'Standard', value: 'standard', color: 'gray' };
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -17,18 +17,25 @@
*
* ## Why this file exists separately, and why it is listed
*
* The assertions below are its entire point, so it is listed in
* `packages/app-shell/tsconfig.typetests.json`. That listing is the difference
* between a pin and a decoration: the package's build tsconfig excludes
* `**\/*.test.tsx`, and vitest erases types before running, so a
* `@ts-expect-error` written in an ordinary `*.test.tsx` file in this directory
* is read by NO compiler — it neither fails when the error disappears nor when
* the error was never there. This was drafted that way first, and the mutation
* The assertions below are its entire point, and
* `packages/app-shell/tsconfig.test.json` is what makes them a pin rather than a
* decoration: it compiles every `src/**\/*.test.tsx` in the package and is
* chained off the package's `type-check` script. SOME such project is
* load-bearing — the package's build tsconfig excludes `**\/*.test.tsx` and
* vitest erases types before running, so with none of it a `@ts-expect-error`
* would be read by NO compiler, failing neither when the error disappears nor
* when it was never there. This file was drafted that way first and the mutation
* run said so: making naming optional again produced a completely green
* `tsc --noEmit`. That is objectui#3009's failure verbatim (assertions that
* never ran, under a header calling them the real enforcement), and
* `tsconfig.typetests.json`'s own header warns about it — so the type-level
* cases moved here, out of `_shared.labels.test.tsx`, where they are compiled.
* `tsc --noEmit`. That is objectui#3009's failure verbatim — assertions that
* never ran, under a header calling them the real enforcement.
*
* What has changed is the SHAPE of that coverage, and it retires one reason this
* file is separate. A narrow `tsconfig.typetests.json` used to name a handful of
* files one by one, so the type-level cases were moved here, out of
* `_shared.labels.test.tsx`, to sit on that list. Coverage is by glob now and
* BOTH files are compiled (the package graduated in objectui#4040 and the narrow
* project was retired with it), so the separation is a readability preference
* today, not a requirement — a directive in either file is checked.
*
* The runtime `expect` at the bottom is deliberately thin: the DOM consequences
* (which element carries the id, what the accessible name resolves to, that the
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -426,12 +426,17 @@ describe('InspectorComboField — a combo without a visible label is still named

// The type-level half of this contract — that a combo with NO name, or with
// two names, does not compile — is pinned in
// `InspectorComboField.naming.types.test.tsx`, not here. A `@ts-expect-error`
// in this file would be read by no compiler: the package's build tsconfig
// excludes `**/*.test.tsx` and vitest erases types, so it would neither fail
// when the error disappeared nor when it was never there (objectui#3009). That
// sibling file is listed in `tsconfig.typetests.json`, which is what makes its
// directives load-bearing.
// `InspectorComboField.naming.types.test.tsx`, not here. That split is a
// PREFERENCE, not a constraint: do not read it as a rule against writing a
// `@ts-expect-error` in this file. It WAS a constraint when this note was
// written — the package's build tsconfig excludes `**/*.test.tsx` and vitest
// erases types, so a directive here would have failed neither when the error
// disappeared nor when it was never there (objectui#3009).
//
// `tsconfig.test.json` now compiles every `src/**/*.test.tsx` in the package,
// this file and that sibling alike, chained off the package's `type-check`
// script. A directive in either is load-bearing: when the error it expects
// stops happening, `tsc` reports the directive UNUSED (TS2578).
});

/* ───────────────────────── the counter-example holds ─────────────────────── */
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -13,11 +13,16 @@
* DESCRIBE a spec-rejected condition cannot send the next reader down that road
* either — which is only true for as long as somebody checks, hence this file.
*
* The assertions below are the file's entire point, so it is listed in
* `packages/app-shell/tsconfig.typetests.json`. Without that listing they would
* be commentary: the package's build tsconfig excludes `**\/*.test.ts`, and
* vitest erases types before running (objectui#3181 — the same trap
* `src/__tests__/spec-symbol-parity.test.ts` documents in its header). The
* The assertions below are the file's entire point, and what makes them a check
* rather than commentary is `packages/app-shell/tsconfig.test.json`: it compiles
* every `src/**\/*.test.ts` in the package, this file included, and is chained
* off the package's `type-check` script. Without some such project they WOULD be
* commentary — the package's build tsconfig excludes `**\/*.test.ts`, and vitest
* erases types before running (objectui#3181 — the same trap
* `src/__tests__/spec-symbol-parity.test.ts` documents in its header). Coverage
* is by glob, so this file earns it by living under `src/`, not by appearing on
* a list; the narrow `tsconfig.typetests.json` that used to name it was retired
* when the package graduated (objectui#4040). The
* runtime case at the bottom is real too: it walks an envelope through
* `conditionText`, the reader every consumer of this type goes through.
*/
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -21,10 +21,14 @@
* `undefined`) and skipped envelope guards the engine evaluates. The assertions
* below make the local type incapable of describing either error again.
*
* The assertions ARE the file, so it is listed in
* `packages/app-shell/tsconfig.typetests.json`: the package's build tsconfig
* excludes `**\/*.test.ts` and vitest erases types before running
* (objectui#3181), so unlisted they would be commentary, not a check.
* The assertions ARE the file, and `packages/app-shell/tsconfig.test.json` is
* what makes them a check: it compiles every `src/**\/*.test.ts` in the package,
* this file included, chained off the package's `type-check` script. Uncompiled
* they would be commentary — the package's build tsconfig excludes
* `**\/*.test.ts` and vitest erases types before running (objectui#3181).
* Coverage is by glob, not by a listing: the narrow `tsconfig.typetests.json`
* that used to name this file was retired when the package graduated
* (objectui#4040).
*/

import { describe, it, expect } from 'vitest';
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -21,12 +21,19 @@ const run = (nodes: SimNode[], edges: SimEdge[], seed = {}, mocks = {}) => {
* is THE canonical persisted form, and a fixture that spells it by hand could
* drift from what the spec actually emits (objectui#3216).
*
* The `SimEdge` return annotation states the matching type-level claim, but do
* not read it as a proof: `tsc` never sees this file (the package tsconfig
* excludes `**\/*.test.ts`, and app-shell's test tree is still TEST_DEBT), and
* vitest erases types. The enforced version lives next door in
* `flow-sim-edge.types.test.ts`, which IS compiled — `PersistedEdge extends
* SimEdge`.
* The `SimEdge` return annotation states the matching type-level claim, and it
* is checked: `packages/app-shell/tsconfig.test.json` compiles every
* `src/**\/*.test.ts` in the package, this file included, and the package's
* `type-check` script chains it (`tsc --noEmit && tsc -p tsconfig.test.json`),
* which is what CI's Type Check job runs. That was NOT so when this note was
* written — the build tsconfig excludes `**\/*.test.ts`, app-shell's test tree
* was then TEST_DEBT, and vitest erases types, so `tsc` saw nothing here
* (objectui#3181). The package graduated in objectui#4040 and the debt table is
* now empty.
*
* Still read the pin next door in `flow-sim-edge.types.test.ts` as the stronger
* one: `PersistedEdge extends SimEdge` constrains the TYPE, where an annotation
* on this helper only constrains what this helper returns.
*/
const specEdge = (e: Record<string, unknown>): SimEdge => FlowEdgeSchema.parse(e);

Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -18,12 +18,19 @@
* type and the predicate stopped narrowing action dialogs. `ActionParamOption`
* now names the two keys the param layer itself uses and passes the rest through.
*
* Scope of this file, stated honestly: vitest does not typecheck, and this package
* excludes its own test files from `tsc` (TEST_DEBT in
* `scripts/check-type-check-coverage.mjs`), so nothing here can fail because a
* TYPE re-narrowed. The type half is pinned where it is actually compiled — in
* `@object-ui/app-shell`'s `utils/resolveActionParams.test.ts`, which
* `tsconfig.typetests.json` lists. What these cases hold is the behavioural
* Scope of this file, stated honestly: vitest does not typecheck, but this file
* IS compiled — `packages/core/tsconfig.test.json` takes the package's test tree
* by glob and is chained off the package's `type-check` script. That was not so
* when this note was written: `@object-ui/core` was then TEST_DEBT in
* `scripts/check-type-check-coverage.mjs` and nothing here could fail for a type
* reason at all. The package graduated in objectui#4040 and the debt table is now
* empty. Note what still limits the type reach of THIS file specifically: the
* deliberate `as OptionLike[]` seam described below opts its cases out of the
* narrowing check, compiler or no compiler.
*
* So the type half stays pinned where the narrowing actually bites — in
* `@object-ui/app-shell`'s `utils/resolveActionParams.test.ts`, compiled by that
* package's own `tsconfig.test.json`. What these cases hold is the behavioural
* agreement: an option list of the shape a resolved param carries is filtered by
* this package's own predicate reader, per option, on the keys it declares.
*
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -32,16 +32,18 @@
* diagnostics against a control interface carrying nothing but an index
* signature — which is what proves the REJECTIONS come from the promotion and
* not from some unrelated error. This file states the same contract as ordinary
* TypeScript that CI compiles directly (via `tsconfig.typetests.json`), so the
* TypeScript that CI compiles directly (via `tsconfig.test.json`), so the
* pin survives even if the harness's compiler-host plumbing ever breaks, and a
* reader can see the rejected spellings without decoding a test harness.
*
* These assertions are TYPES: this package's own `tsconfig.json` is the BUILD
* config and excludes `src/**` test files, so without the explicit entry in
* `tsconfig.typetests.json` (chained off `type-check`, enforced by
* `scripts/check-type-check-coverage.mjs`) nothing would compile this file and
* every pin below would be decoration — the "declared != enforced" landmine
* objectstack#4115 exists to remove.
* config and excludes `src/**` test files, so without `tsconfig.test.json`
* (which takes the test tree by GLOB, is chained off `type-check`, and is
* enforced by `scripts/check-type-check-coverage.mjs`) nothing would compile this
* file and every pin below would be decoration — the "declared != enforced"
* landmine objectstack#4115 exists to remove. There is no list entry to earn:
* the narrow `tsconfig.typetests.json` that once named this file by hand was
* retired when the package graduated (objectui#4040).
*/

import { describe, it, expect, vi } from 'vitest';
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -133,7 +133,7 @@ const CASES: readonly Case[] = [
// `rejected: true` row here goes red for a reason that has nothing to do with
// `ActionDef`. Measured: green locally after a build, red in CI without one.
//
// `tsconfig.typetests.json` has no such problem — it is a real project in the
// `tsconfig.test.json` has no such problem — it is a real project in the
// dependency graph, so CI's Type Check job builds `@object-ui/types` before
// compiling it, and the `@ts-expect-error` on `{ description: 42 }` there is
// enforced for real. Splitting the two `description` pins out is therefore
Expand Down
Original file line numberDiff line numberDiff line change
Expand Up@@ -20,11 +20,17 @@
* The assertions below are TYPES. `Assert< Equal< Local, Spec > >` is a compile
* error or it is nothing — and this package's own `tsconfig.json` is the BUILD
* config, which excludes every `.test.ts` file under `src` (correctly: a test
* must not emit into `dist`), while `@object-ui/core` is still in
* `scripts/check-type-check-coverage.mjs`'s TEST_DEBT, so no other `tsc`
* invocation reads this tree either. `packages/core/tsconfig.typetests.json`
* lists this file explicitly and is chained off the package's `type-check`
* script; without that project these pins would be the "declared != enforced"
* must not emit into `dist`). What compiles them is
* `packages/core/tsconfig.test.json`, which takes the package's test tree by
* glob — this file included — and is chained off the package's `type-check`
* script (`tsc --noEmit && tsc -p tsconfig.test.json`), the script CI's Type
* Check job runs. That coverage arrived late: `@object-ui/core` sat in
* `scripts/check-type-check-coverage.mjs`'s TEST_DEBT with a narrow
* `tsconfig.typetests.json` naming this file by hand, until the package
* graduated in objectui#4040 and the narrow project was retired with it. The
* debt table is now empty.
*
* Without SOME such project these pins would be the "declared != enforced"
* landmine objectstack#4115 exists to remove, sitting inside a guard for it
* (objectui#3009 found precisely that: reverting a derived alias produced zero
* errors under a header calling the assertions "the real enforcement").
Expand Down
Loading