Imported from HahyeonJeon/gobbi (
.gobbi/projects/gobbi/skills/typescript/typescript-testing/SKILL.md). Install upstream withnpx skills add HahyeonJeon/gobbi --skill typescript-testing. Copyright stays with the author.
TypeScript Testing
TypeScript Testing verifies runtime behavior and compile-time requirements without treating one evidence layer as a substitute for another. Use it when creating or reviewing runtime tests, type-level or negative tests, declaration and package checks, command behavior, or executable examples.
typescript-packaging alone creates package archives; review-only mode keeps the subject unchanged.
Principles
Test with the layer that can disprove the claim
Runtime behavior needs an execution result; a type relationship needs a compiler result; a package compatibility statement needs a consumer result against the installed archive.
Make failures discriminating
A useful test fails for the defect it names and stays green under unrelated refactoring.
Control nondeterminism at named dependencies
Time, randomness, scheduling, I/O, processes, and external services need explicit controllable adapters.
Keep teaching executable
Documented examples are code and require a named compiler version and exact compiler options with explicit limits.
Rules
- MUST classify the work as author mode or review-only mode, then select runtime, type-level, negative, declaration, package, and example checks from the claims being made. Review-only mode changes no reviewed file and stops after Step 1.4; author mode continues into Phase 2.
- NEVER use an ordinary type assertion such as
value as Typeor<Type>valueinside a test as proof that the asserted type is true.as constis a const assertion that may construct precise test input, but it does not itself prove a tested type relationship. - MUST prove every expected-error or negative test rejects the intended misuse. For directive-based tests, removing the directive must produce the intended diagnostic, and moving it to valid code must produce an unused-directive failure.
- MUST test public declarations and resolution from an isolated consumer project rather than only inside the source project.
- MUST control time, randomness, scheduling, I/O, and named-runtime state when deterministic observation is required.
- NEVER build, pack, create, or recreate a package archive in this operation. Receive the exact identified
archive and applicable isolated consumer setup from
typescript-packaging, and never treat a source-checkout test as proof of that archive's behavior.
Procedure
Phase 1 — Plan the verification
1.1 Enumerate claims
- List caller-visible behaviors, failure paths, cleanup obligations, type relationships, rejected programs, public declarations, package resolution paths, command distribution and invocation paths, and taught examples.
- Record every TypeScript compiler version claimed for package consumers or taught examples.
- Map each claim to the layer capable of disproving it.
- Classify the work as author mode or review-only mode. Use review-only mode whenever edits are not authorized.
- Select every applicable project kind: web application, command-line application, library, SDK, desktop application, or a literal fallback.
1.2 Design discriminating cases
- Ensure every applicable ordinary, limit, failure, cancellation, and adversarial case for the tested claims is included.
- Define what mutation or controlled defect would make each test fail.
- Avoid assertions tied only to implementation order or private structure unless that structure is an explicit requirement.
1.3 Establish controllable dependencies
- Identify time, randomness, network, filesystem, process, event, and scheduler dependencies.
- In author mode, use project-standard fakes or injected adapters while preserving the behavior under test. In review-only mode, inspect how existing tests control those dependencies without adding an adapter or fake.
- Record unavoidable nondeterminism and the repeated or statistical result that bounds it.
1.4 Run review-only mode
- Continue through this step only in review-only mode. Inspect the existing runtime, type-level, negative, declaration, package, command, and example checks that apply to the recorded claims.
- Run only authorized existing checks. To challenge a test's failure power, introduce or simulate the named defect only inside an authorized disposable boundary, such as the smallest required fixture copied into a named temporary directory. When reproduction would require an unauthorized external or irreversible effect, record that exact blocked effect and classify failure-power evidence as unavailable.
- For package validation, inspect only existing declarations and generated package output. Inspect or install
only the exact package archive that
typescript-packagingidentifies as having existed before the review, and install it only into the isolated disposable consumer setup that operation supplies when command authority permits. - Return command results, findings, and limitations without changing a reviewed file, creating build output, creating an archive, installing persistently, updating documentation or release notes, or publishing. Stop before Phase 2; any required mutation of reviewed files or new output requires author mode.
Phase 2 — Build runtime tests
Continue into Phase 2 only in author mode.
2.1 Test observable behavior
- Reach the unit through its public API, command, or user-visible interface.
- Assert outputs, state transitions, emitted events, side effects, and failures that consumers observe.
- Verify cleanup after success, failure, cancellation, and early exit when resources are involved.
2.2 Exercise async behavior
- Control completion order and test overlapping operations with inverted results.
- Distinguish cancellation from stale-result suppression and assert the intended one.
- Observe every rejection so the test cannot pass with background failures.
2.3 Verify the failure power
- Introduce or simulate the named defect only inside the authorized author-mode affected set or an authorized disposable boundary, and confirm the test fails for the expected reason.
- When reproduction would require an unauthorized external or irreversible effect, record that exact blocked effect and classify failure-power evidence as unavailable instead of crossing the boundary. Keep that result open and do not enter the remaining mutation-specific path for that test.
- Restore the accepted implementation and run the focused test again.
- If the test stays green under the defect or stays red after restoration, return to Phase 1.2 for the case design or the owning Phase 2 step for the runtime test.
- Reject snapshots or broad assertions that pass under the defect.
Phase 3 — Build type and declaration tests
3.1 Add positive type cases
- Compile representative valid uses through the public API.
- Assert inferred or declared relationships with type-level helpers that fail on mismatch.
- Keep runtime assertions separate from compile-time claims.
3.2 Add negative type cases
- Compile intentionally invalid uses with the project's expected-error mechanism.
- Confirm removing the expectation produces the intended diagnostic and that an unused expectation fails.
- If either mutation does not discriminate the intended misuse, return to Phase 1.2 or revise the negative case in this step before continuing.
- Keep diagnostic-sensitive tests narrow enough to reject the targeted misuse rather than any arbitrary error.
3.3 Test declarations, packages, and commands
- Emit or obtain the public declarations and type-check isolated consumer fixtures.
- Receive the exact identified package archive and applicable isolated consumer setup from
typescript-packaging. Do not independently build, pack, create, or recreate the archive. - Install that exact archive into the supplied consumer setup, then exercise its documented entry points and resolution modes and own the behavior, type, and declaration assertions against it.
- For every command supplied through a package archive, capture command-name resolution in the isolated consumer. Prove that it selects the executable created by that archive installation.
- Invoke the installed command and assert the arguments, standard streams, exit status, signals, and failure text required by the supplied command specification.
- Compare declarations or exported APIs when compatibility is a stated requirement.
Phase 4 — Verify examples and the suite
4.1 Verify documented examples
- Extract every fenced
tsexample the documentation presents as valid or intentionally rejected. - Compile each self-contained example exactly as displayed with every compiler version claimed for it. For an
@ts-expect-errorexample, also prove that removing or moving the directive produces the intended diagnostic or an unused-directive failure under each version. - Record every compiler version, option set, and result. State that these checks prove only those examples under those versions and options; they do not prove every named runtime, project
tsconfig.json, or installed package path.
4.2 Run the verification ladder
- Run focused runtime and type checks, then the broader test, declaration, build, and package checks that apply.
- Ensure zero discovered tests or examples fails closed when discovery is part of the claim.
- Review output from the final-tree run for skipped, quarantined, flaky, or unexpectedly absent cases.
- When a check fails, return to Phase 1 for a claim or case-design mismatch, Phase 2 for a runtime-test defect, or Phase 3 for a type, declaration, package, or command-test defect.
- After repair, re-run the failed check and every affected downstream check from the final tree.
- When repair is unauthorized or outside scope, stop with the failed claim and command evidence. A check that ran and failed is not an unavailable-check limitation.
4.3 Verify each selected project kind
- For a web application, test affected browser and server behavior at the layer that exposes it and smoke-test the production build in the named runtime.
- For a command-line application, use the isolated consumer entry prepared by the applicable delivery owner
and invoke its consumer command. Use
typescript-packagingfor every command name or entry supplied throughpackage.jsonbin, a package script, or a workspace package link. Usetypescript-cli-deliverywhen the consumer receives the command without installing a package archive, including a standalone executable or archive, a script copied or linked directly to an install target, a workspace or repository revision plus command, or another direct non-archive method whose unit, method, and consumer command are recorded by name. A package-backed workspace command delivered directly loads both owners. A genuine hybrid distributes the same command through both methods, loads both, and keeps separate artifact identities and consumer entries. Prove the invoked executable is the recorded output rather than an unrelated command already onPATH. Verify the command specification, including failure and signal paths that apply. - For a library, use an isolated representative consumer through the recorded distribution method. Install the
exact package archive and isolated consumer setup supplied by
typescript-packagingwhen the library is distributed as a package; otherwise use the recorded workspace, project-reference, source, or other consumer path. Type-check every supported import, inspect declarations that path exposes, and run every runtime entry where runtime code exists. - For an SDK, verify external payload parsing, documented client calls, public types, failures, cancellation, and supported consumer compiler configurations.
- For a desktop application, test main, preload, renderer, and typed IPC behavior separately where present, then exercise the packaged application path required by the Electron and desktop skills.
- For a fallback project kind, test every named runtime, generated output, and direct consumer recorded by
typescript-development.
4.4 Review traceability
- Map every claim to at least one current test and every test to a named requirement.
- Record unavailable runtimes, tools, or package modes as limitations.
- When this test change is evaluated, the test checklist, project-kind checklist, and every checklist provided by
an active
typescriptsibling supply the applicable conditions; the general Evaluation operation resolves them and issues any verdict.
References
- Test checklist supplies reusable unchecked scenarios and atomic conditions for test design and evidence.
- Project-kind checklist supplies reusable unchecked scenarios and atomic conditions for web, CLI, library, SDK, desktop, and fallback verification.