XCResultToolClient and new-format schema structs (#391) - #441
Conversation
Co-Authored-By: Claude Fable 5 <[email protected]>
Narrows the fixture .gitignore patterns to *.xcresult: the bare TestResults* pattern was silently swallowing TestResultsSchema.swift and its tests. Amends the plan doc where implementation corrected it: LegacyCapability lives in XCResultToolClient.swift (Task 6 cannot compile without it and lands before Task 11), and TestNode's nodeType doc now lists the full published TestNodeType enum, with an added test decoding Arguments/Test Value nodes from schema-derived JSON. Co-Authored-By: Claude Fable 5 <[email protected]>
|
Warning Review limit reached
Next review available in: 23 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (6)
Comment |
…t typing (#391, Tasks 8–10) (#447) * test: pin extension-based attachment typing and map public.data on the legacy backend Task 10 of the migration plan. The AttachmentType(filenameExtension:) initializer itself landed with #443; what was missing is the cross-backend agreement pin and one table entry: LegacyResultReader's UTI fallback omitted public.data, so an extensionless public.data attachment degraded .data -> .unknown on the legacy backend only. Co-Authored-By: Claude Fable 5 <[email protected]> * fix: surface XCResultToolError diagnoses through LocalizedError Carried forward from the #441 review: consumers now exist (faults and warnings format these errors), and localizedDescription printed the generic NSError boilerplate rather than the command, exit status, and stderr. Co-Authored-By: Claude Fable 5 <[email protected]> * feat: export attachments through the modern xcresulttool path Task 9 of the migration plan. One `export attachments` call per bundle plus the manifest.json join (activity attachment uuid <-> basename of exportedFileName) replaces the legacy per-payload export and its lock table; only the one-shot export is guarded. Run logs come from `get log --type action` and render from the structured messages, since the new format has no emittedOutput. Committed ahead of Task 8 so each commit builds: the reader's payloadStore property references this type. Co-Authored-By: Claude Fable 5 <[email protected]> * feat: add ModernResultReader for the new xcresulttool format Task 8 of the migration plan. Parity rules carried exactly: statuses map into the neutral enum (Expected Failure still flattens to unknown downstream); multi-repetition status derives from the Repetition children and ignores the parent Test Case's own result (RetryResults reports Passed there for a Failed-then-Passed test); the tree renders flat, without the legacy wrapper groups. Failure text joins the two documents rather than choosing one: measured on Xcode 26.2, every assertion failure appears both as a failure-flagged activity row (positioned and timestamped, but stripped of file:line) and as a Failure Message node (file:line kept, no timestamp). Each message retitles the first unclaimed failure activity whose title is its exact suffix, in document order, nested rows included; unmatched messages (skip reasons, expected-failure notes) append. The plan's original guard kept the activity title instead, which shipped strictly less information than the spec's failureTitlePrefix entry documents — coordinator-approved correction, amended in the plan. A failed activities query records the new .missingActivities fault; fields the format structurally lacks never fault, pinned by a full modern-path render of all three fixtures asserting zero faults. The sample app gains a parameterized @test so Arguments nodes stop being fixture-unexercised; its argument sets merge into one rendered row, moving the TestResults header total from 17 to 18. Co-Authored-By: Claude Fable 5 <[email protected]> * docs: amend plan and spec for Tasks 8-10 as executed The load-bearing correction: failure text is a join of the two documents, not a choice between them. Measured on Xcode 26.2, the activities document carries every assertion failure as a positioned, timestamped, sometimes nested failure row missing only the file:line prefix; the plan's original anti-double-count guard would have dropped the prefixed Failure Message and shipped less than the spec's failureTitlePrefix entry documents. Coordinator-approved retitle-join recorded in both documents. Mechanical notes: Task 9 commits before Task 8 (type dependency), TestRun is nested in TestActivities, the AttachmentType initializer shipped failable in 443, and regenerating fixtures after the sample-app change collapses the plan's 6-of-7 intermediate state. Co-Authored-By: Claude Fable 5 <[email protected]> --------- Co-authored-by: Claude Fable 5 <[email protected]>
Part of #391 (milestone 4.0). Implements migration plan Tasks 6 and 7: the modern-backend subprocess client and the Codable mirrors of the new
xcresulttoolformat. Deliberately independent of the ParsedResult port PR — purely additive, no existing files underClasses/Models/touched, no references toParsedResult/ResultReader.What's here
XCResultToolClient(ResultReading/Modern/XCResultToolClient.swift): runsxcrun xcresulttool, pinning--schema-version 0.1.0on every invocation so an Apple schema revision fails loudly instead of silently mis-decoding. Includes theXCResultToolInvokingseam (Task 8 injects a failing client through it),json<T: Decodable>,run, andlegacyCapability— a three-state probe (available/unavailable/unknown) parsingxcresulttool versionfor the legacy-commands parenthetical.TestResultsSchema(ResultReading/Modern/TestResultsSchema.swift): Decodable structs forget test-results summary|tests|activities, theexport attachmentsmanifest, andget log. Fields optional throughout — xcresulttool omits keys rather than emitting nulls.XCResultToolClientTests(3 tests, realSanityResults.xcresultfixture) andTestResultsSchemaTests(3 tests), including decodingArguments/Test Valuenodes — added from the published schema (get test-results tests --schema), since no fixture produces them yet (design doc answer 6).Deviations from the plan, amended in the plan doc
LegacyCapabilityis defined inXCResultToolClient.swift, not first in Task 11'sResultBackend.swift: Task 6 cannot compile without it and the tasks land as separate PRs. Task 11's snippet now says to reuse it.TestNode'snodeTypedoc lists the full publishedTestNodeTypeenum (verified against schema 0.1.0 on xcresulttool 24514), and Task 7 gained the third test above.Also
.gitignorepatterns (TestResults*→TestResults*.xcresult): the bare pattern was silently swallowingTestResultsSchema.swiftand its test file. Generated fixture bundles remain ignored.Verification
swift test: 39 tests, 0 failures (2 pre-existing skips), on Xcode 26.2 / xcresulttool 24514, schema 0.1.0, fixtures freshly generated via./prepareTestResults.sh.--schema-versionis accepted byget test-results *andexport attachments, and thatnodeIdentifierURLappears in observed output despite being absent from the publishedTestNodeschema.🤖 Generated with Claude Code