test(xcresult): real bundles reproducing dependency misattribution - #1160
Merged
trunk-io[bot] merged 1 commit intoAug 19, 2026
Conversation
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## claude/xcresult-test-frame-attribution #1160 +/- ##
==========================================================================
+ Coverage 80.29% 83.34% +3.05%
==========================================================================
Files 72 72
Lines 16081 16180 +99
==========================================================================
+ Hits 12912 13486 +574
+ Misses 3169 2694 -475 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
dfrankland
force-pushed
the
claude/xcresult-attribution-fixtures
branch
from
August 18, 2026 22:46
bf1f48a to
a3fca84
Compare
The file sources have only synthesized-JSON unit tests behind them, and the one real SnapshotTesting bundle does not reproduce the bug: `assertSnapshot` defaults `filePath` to `#filePath` at the call site, so its `fileName` already points at the test's own source and the fixture passes with or without the fix. `tests/fixture-src/` holds five SwiftPM packages, one per shape, plus the script that captures and checks them. Each bundle is verified to exhibit its shape before it is packaged, since a fixture that stops reproducing keeps passing while guarding nothing. Each test names the `FileSource` it exercises: - `dependency-raises-failure` every source but `TestFrame` is under `SourcePackages/checkouts/` - `in-repo-helper-raises-failure` `TestFrame` versus `RaisedFrom` with nothing to separate them by path - `crash-in-dependency` two tests that never reach their own frame: one `fatalError`s inside the dependency, one is failed by the dependency's `TestScoping` trait after its body returned - `objc-xctest` `TestIdentity::is_named_by` against real `-[Suite testCase]` symbolication - `toplevel-swift-testing` a suiteless `@Test func`, matched by bare name Reverting the fix fails seven of the ten new cases, on exactly the paths it was written to stop reporting. The experimental and legacy cases expect different JUnit, which is the honest result rather than a shared snapshot: only the experimental path reads the failure summary, so it is the only one that can produce a `TestFrame` candidate. Bundles are pruned before packaging. Xcode 26 writes ~95MB of unreferenced dyld shared-cache symbolication data into every result bundle, which would have made these 96MB apiece; `prune-bundle.py` keeps only what the object graph reaches (9-11 objects out of ~1570 files) and regeneration fails if either xcresulttool API we call returns anything different afterwards. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
dfrankland
force-pushed
the
claude/xcresult-attribution-fixtures
branch
from
August 18, 2026 23:32
a3fca84 to
4cff9e3
Compare
|
This pull request was merged into |
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.
Stack 3/3 — depends on #1159.
The file sources have only synthesized-JSON unit tests behind them, and the one real SnapshotTesting bundle does not reproduce the bug:
assertSnapshotdefaultsfilePathto#filePathat the call site, so itsfileNamealready points at the test's own source and the fixture passes with or without the fix.tests/fixture-src/holds five SwiftPM packages, one per shape, plus the script that captures and checks them. Each bundle is verified to exhibit its shape before it is packaged, since a fixture that stops reproducing keeps passing while guarding nothing.Each test names the
FileSourceit exercises:dependency-raises-failureTestFrameis underSourcePackages/checkouts/in-repo-helper-raises-failureTestFrameversusRaisedFromwith nothing to separate them by pathcrash-in-dependencyfatalErrors inside the dependency, one is failed by the dependency'sTestScopingtrait after its body returnedobjc-xctestTestIdentity::is_named_byagainst real-[Suite testCase]symbolicationtoplevel-swift-testing@Test func, matched by bare nameReverting the fix fails seven of the ten new cases, on exactly the paths it was written to stop reporting.
Why the two cases expect different JUnit
Only the experimental path reads the per-test failure summary, and so the call stack, so it is the only one that can produce a
TestFramecandidate. The legacy path seesDocumentLocationalone. Snapshotting a shared expectation would hide that; two expectations state it.Bundle size
Xcode 26 writes ~95MB of unreferenced dyld shared-cache symbolication data into every result bundle, which would have made these 96MB apiece.
prune-bundle.pywalks the object graph from the root and keeps only what it reaches — 9–11 objects out of ~1570 files, 96MB → 84KB — and regeneration fails if eitherxcresulttoolAPI we call returns anything different afterwards. Total added: 168KB.Regenerating
tests/fixture-src/regenerate.sh(macOS + Xcode). See that directory's README for what each bundle must exhibit, and the two things that are easy to get wrong: the dependency has to be a git repository to be checked out intoSourcePackages/checkouts, and absolute paths are baked in at capture time.🤖 Generated with Claude Code