Repository navigation
TypeScript test selection: excluded and JavaScript tests, bare test.ts, Proxy traps, multi-graph --json - #1874
Merged
Conversation
…mports A build config routinely excludes its tests (`exclude: ["test/**", "**/*.spec.ts"]`) and leaves them to the test runner. No config claimed those files and nothing claimed imports them, so they were skipped as NO_PROGRAM_CLAIMS_FILE and every test the change reaches was invisible to test selection, impact and path. An unclaimed file that imports a file of the program now joins it, with the unclaimed files it pulls in, to a fixpoint. A file owned by another config is untouched, and an unclaimed file that imports nothing of the program is still reported as before. Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com>
A JavaScript or TypeScript test written beside the module it tests is often named only for what it is — `src/isToday/test.ts` — or is a package's root `test.js`. Neither the name nor a directory said test, so every test of such a tree was a plain function: the test universe was empty and test selection named none of the tests a change breaks. A file named test, tests, spec or specs is now a test file when it also registers a test (describe / it / test / suite at the start of a line). The name alone is not enough: a library ships `testing/test.ts` with its test utilities, and a vendored `spec.ts` holds a specification's types; both stay code. Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com>
In a repository indexed in several languages the dispatcher asks every graph. When
none answered — path finding no chain (a document with its leads, status 1), or the
same refusal from every graph — --json printed the text answer's per-graph headers
(`══ typescript graph ══`) and each graph's output after them. A machine reader got
nothing it could parse, for an answer that was correct.
--json now prints one document in those cases: the main graph's document with the
other graphs' under other_languages, or one {refusal, language, languages} for a
refusal every graph gave. The exit status is unchanged, and the front door prints a
refusal document as its text.
Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com>
…it imports
A repository written in TypeScript often keeps some of its tests in JavaScript
(`__tests__/base.js` importing `../src/immer`). Those files went to the JavaScript graph,
which has no edge into the TypeScript one, so a change to the source selected none of the
tests that break with it.
A .js / .jsx / .mjs / .cjs file that imports a file of the TypeScript program now joins it,
parsed as JavaScript, the same way an unclaimed TypeScript file does. `require("x")` counts
as an import for that. A JavaScript file that imports nothing of the program is left to the
JavaScript analyzer, and a TypeScript file importing JavaScript still does not pull it in.
Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com>
`new Proxy(target, handler)` and `Proxy.revocable(target, handler)` give the runtime an object whose get / set / has … it calls on every touch of the proxy. No call site names a trap, so what the traps call was reached by nothing: in a Proxy-based library the draft logic was unreachable from every test that creates a draft. The creating site now hands over each trap the handler defines, the way `xs.map(cb)` hands over `cb` (callback_registered). The handler is followed through the holders it is read from — a const, a reassigned let, a parameter it was passed as — to an object literal's methods, or to the methods of the class a `new C()` builds and its bases. Only the ProxyHandler trap names count, and only on an object that reaches a Proxy: an object with a get method handed to any other call is untouched. Co-authored-by: axiomcode-bot[bot] <334110751+axiomcode-bot[bot]@users.noreply.github.com>
swapnilpaliwal-sd
requested review from
JaredHLZhang,
Whua689 and
suyashpaliwal26
as code owners
October 9, 2026 08:51
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Five fixes to TypeScript test selection, impact and path, found by a mutation oracle over 14 open-source TypeScript repositories: break one function, record which test files newly fail, compare each verb's selection with that truth.
Each fix carries a check that is red without it and a control that must not move.
exclude: ["test/**"]) made every test fileNO_PROGRAM_CLAIMS_FILE; on one repository every verb answered nothing. An unclaimed file that imports the program now joins it; one that imports nothing is still reported. Parser check indiscovery-tests.ts.test.tsthat registers a test is a test. Tests written beside their module (src/x/test.ts) were plain functions, so the test universe was empty. The bare name must also register a test (describe/it/test/suite), so a library'stesting/test.tsand a vendoredspec.tsstay code. Casea-file-named-test-is-a-test.--jsonis one document when no language's graph answers. In a repository with several graphs, a path with no chain printed the text answer's per-graph headers under--json: 279 of 1244 answers could not be parsed. Check intests/multi_language.py..jstests importing.tssource lived in the JavaScript graph with no edge into the TypeScript one. Parser check indiscovery-tests.ts.new Proxy(t, h)/Proxy.revocable(t, h): the traps the runtime calls were reached by nothing. Only the ProxyHandler trap names, and only on an object that flows into the handler argument; every edge this adds was audited on six graphs, none on an unrelatedget/set. Caseproxy-handler-traps-are-handed-over.Tests: TypeScript cases 269/269, JavaScript 307/307, Python 306/306; parser
typescript-tests49/49 and discovery checks pass. On this base, 6 checks oftests/multi_language.pyand 1 oftests/surfaces.pyfail with and without these commits.Fixes 1 and 4 change the vendored parser, so they also need to go upstream to the parser repository.