test: cover what core.ts actually produces - #291
Merged
Merged
Conversation
Every core.ts test asserted the number of pages and nothing else, so 64 of its 193 mutants survived. The tests now check the output itself. - Text extraction joins page items with single spaces. Pinning the start of page one kills the mutants that empty the separator or seed the parts array. - Rendered pages honour the scale, so page one is 595x841 at scale 1 and 1190x1683 at scale 2. The png header carries both numbers. - A pooled canvas has to be resized before another page uses it. The new example-page-sizes.pdf holds two pages of different sizes, so a canvas handed on without a reset produces the wrong dimensions. - A page without text is rendered and handed to the callback as a buffer, a page with text as a string. Nothing covered that split before. - The callback guard rejects a missing callback and a callback that is not a function. - Scale 0.1 and 10 are accepted. Rejecting what lies outside the range never pinned the bounds themselves. core.ts goes from 64.55 to 74.60 and the project from 67.92 to 70.94. Survived mutants in the file drop from 64 to 47. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
l2ysho
force-pushed
the
test/core-mutants
branch
from
August 29, 2026 17:53
fad9903 to
3b47351
Compare
l2ysho
changed the base branch from
test/plimit-concurrency-and-break-threshold
to
main
August 29, 2026 17:53
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.
Third mutant-killing PR from the report at l2ysho.github.io/afpp.
The gap
Every existing core.ts test asserted the page count and stopped:
Nine items came back, so the test passes — whatever is in them. 64 of the 193 mutants survived.
The tests
Text is joined with single spaces. Pinning the start of page one kills the mutants that empty the separator (
parts.join(' ')→parts.join('')) or seed the parts array with junk.Rendered pages honour the scale. Page one is 595x841 at scale 1 and 1190x1683 at scale 2. Both numbers sit in the png IHDR header, so no image library is needed. This kills
getViewport({ scale })→getViewport({}), which silently falls back to scale 1.A pooled canvas is resized before reuse.
test/example-page-sizes.pdfis a hand-written two-page PDF whose pages are 200x100 and 100x300. The first page's canvas goes back to the pool and is handed to the second, so dropping theresetcall produces a page rendered at the wrong size. 682 bytes of plain ASCII.Pages without text are rendered, not emptied. In mixed mode a page with no text items is rasterised and handed to the callback as a Buffer; a text page arrives as a string.
example-img.pdfgives nine buffers,example.pdfnine strings. Nothing covered that split.The callback guard works. A missing callback and a non-function callback both reject.
The scale bounds are accepted, not just their outside rejected. The suite rejected 0, -1, 0.01, 100 and NaN, but never checked that 0.1 and 10 are allowed — so
scale < 0.1could becomescale <= 0.1unnoticed. Folded into the existingscale validationblock.Result
Why I stopped at 47
The rest is not worth a test. Broken down:
page.cleanup(),canvasFactory.destroy()andfinallyblocks. Resource handling with no observable result.Array.from({ length: numPages })withArray.from({}). The array is filled by index afterwards, so it is equivalent.Killing these means exporting internals or asserting on things no caller can see. That trades real test quality for a number.