Skip to content

[TST-E4] test: fourteen Vcs and Worktrees declared-error doors become table rows; two enum duplicates go - #467

Merged
Blind-Striker merged 2 commits into
masterfrom
test/tst-e4a-p05a-door-rows
Oct 17, 2026
Merged

Blind-Striker merged 2 commits into
masterfrom
test/tst-e4a-p05a-door-rows

Conversation

@Blind-Striker

@Blind-Striker Blind-Striker commented Oct 17, 2026 •

Copy link
Copy Markdown
Collaborator

📝 Description

What does this PR do?
It is TST-E4a's P05a: fourteen more declared-error door methods become rows of the door table (Vcs 8, Worktrees 6), and the two genuine enum duplicates L1 and L2 are deleted in favour of their named survivors. Each converted method proved only "door D answers declared status S with error type T" on one spine.

  • Each becomes a row that runs on both spines. On the throwing spine it asserts OpenCodeApiException, the exact status and the exact type. On the NoThrow spine it asserts IsError, the exact status and the exact type. The one-way guard checks every row against its declaration in the pinned spec/openapi.json.
  • The rows live in their slices. Vcs/VcsDeclaredErrors.cs is new, with a 67-line Rows(). The Worktrees rows are appended to Worktrees/WorktreesDeclaredErrors.cs, whose existing field and case stay byte-identical. DeclaredErrorTests.EveryDoor() appends the Vcs slice.
  • Each distinct door is one shared field. A door is its five parts, and those include the lambda's arguments. The two deleted GetDiffAsync methods call it with Mode = VcsMode.Branch and Mode = VcsMode.Working, so they are two fields, GetDiffBranchDoor and GetDiffWorkingDoor. No argument is normalized. The worktree.create:401 row reuses the existing CreateWorktreeDoor, because the deleted method's CreateRequest() has the same two values.
  • L1 and L2 (OpenCodeJsonContextTests) are deleted with named survivors in ExtensibleEnumContractTests:
    • L1's survivor is Deserialize_Should_Refuse_A_Token_That_Is_Not_A_String. Its numeric fixture case expects a JsonException.
    • L2's survivor is Deserialize_Should_Read_A_Pinned_Value_As_Its_Static_Property. It reads the same known fixture and expects Modified, plus IsKnown.
  • Every other method in the touched classes is byte-identical. That includes the kept 400 Worktree methods, which assert Data, and Vcs's 501 initialization test.
  • The clone baseline drops 15 fingerprints, and the tests ceiling falls to 5.5%. The regeneration is deletions only (+0 / −15). Tests go from 586 clones (4.98%) to 571 (4.87%), with 0 new clones.

Net line delta: +184 / −198 = −14 in Sdk test code. Over the whole PR it is +189 / −218, including the baseline and the ceiling.

🔄 Type of Change

  • 🧪 Test improvements

🎯 Protocol & API Surface

  • No change to the public API surface
  • Nothing under external/, spec/ or src/ was touched

🧪 Testing

Test mapping (mechanical: e4_test_map.py over git diff 67b45833 5e006ecf, the worker's commit; the conversion commit here has identical files)

File Base test method At head Target
tests/OpenCode.Sdk.Tests/Serialization/OpenCodeJsonContextTests.cs Deserialize_Should_Reject_A_Numeric_String_Enum_Value survivor Deserialize_Should_Refuse_A_Token_That_Is_Not_A_String
tests/OpenCode.Sdk.Tests/Serialization/OpenCodeJsonContextTests.cs Deserialize_Should_Map_A_Known_String_Enum_Wire_Value survivor Deserialize_Should_Read_A_Pinned_Value_As_Its_Static_Property
tests/OpenCode.Sdk.Tests/Vcs/VcsClientContractTests.cs GetStatusAsync_Should_Throw_The_Declared_400_Error row vcs.status:400:InvalidRequestError
tests/OpenCode.Sdk.Tests/Vcs/VcsClientContractTests.cs GetStatusAsync_Should_Return_The_401_Error_On_The_NoThrow_Spine row vcs.status:401:UnauthorizedError
tests/OpenCode.Sdk.Tests/Vcs/VcsClientContractTests.cs ListBranchesAsync_Should_Throw_The_Declared_400_Error row vcs.branch.list:400:InvalidRequestError
tests/OpenCode.Sdk.Tests/Vcs/VcsClientContractTests.cs ListBranchesAsync_Should_Return_The_401_Error_On_The_NoThrow_Spine row vcs.branch.list:401:UnauthorizedError
tests/OpenCode.Sdk.Tests/Vcs/VcsClientContractTests.cs GetBaseAsync_Should_Throw_The_Declared_503_Error row vcs.base:503:ServiceUnavailableError
tests/OpenCode.Sdk.Tests/Vcs/VcsClientContractTests.cs GetBaseAsync_Should_Return_The_401_Error_On_The_NoThrow_Spine row vcs.base:401:UnauthorizedError
tests/OpenCode.Sdk.Tests/Vcs/VcsClientContractTests.cs GetDiffAsync_Should_Throw_The_Declared_503_Error row vcs.diff:503:ServiceUnavailableError
tests/OpenCode.Sdk.Tests/Vcs/VcsClientContractTests.cs GetDiffAsync_Should_Return_The_401_Error_On_The_NoThrow_Spine row vcs.diff:401:UnauthorizedError
tests/OpenCode.Sdk.Tests/Worktrees/WorktreesClientContractTests.cs CreateWorktreeAsync_Should_Return_The_401_Error_On_The_NoThrow_Spine row worktree.create:401:UnauthorizedError
tests/OpenCode.Sdk.Tests/Worktrees/WorktreesClientContractTests.cs RemoveWorktreeAsync_Should_Return_The_401_Error_On_The_NoThrow_Spine row worktree.remove:401:UnauthorizedError
tests/OpenCode.Sdk.Tests/Worktrees/WorktreesClientContractTests.cs RefreshWorktreesAsync_Should_Throw_The_Declared_400_Worktree_Error row worktree.refresh:400:WorktreeError
tests/OpenCode.Sdk.Tests/Worktrees/WorktreesClientContractTests.cs RefreshWorktreesAsync_Should_Return_The_401_Error_On_The_NoThrow_Spine row worktree.refresh:401:UnauthorizedError
tests/OpenCode.Sdk.Tests/Worktrees/WorktreesClientContractTests.cs ListWorktreesAsync_Should_Throw_The_Declared_400_Error row worktree.list:400:InvalidRequestError
tests/OpenCode.Sdk.Tests/Worktrees/WorktreesClientContractTests.cs ListWorktreesAsync_Should_Return_The_401_Error_On_The_NoThrow_Spine row worktree.list:401:UnauthorizedError

Unmapped: 0

File Assert.That at base at head delta
tests/OpenCode.Sdk.Tests/Common/Errors/DeclaredErrorTests.cs 12 12 +0
tests/OpenCode.Sdk.Tests/Serialization/OpenCodeJsonContextTests.cs 174 172 -2
tests/OpenCode.Sdk.Tests/Vcs/VcsClientContractTests.cs 69 45 -24
tests/OpenCode.Sdk.Tests/Vcs/VcsDeclaredErrors.cs 0 0 +0
tests/OpenCode.Sdk.Tests/Worktrees/WorktreesClientContractTests.cs 65 47 -18
tests/OpenCode.Sdk.Tests/Worktrees/WorktreesDeclaredErrors.cs 0 0 +0

The negative deltas are the deleted methods' assertions. The rows assert the same status and exact type on both spines, and the L survivors assert at least what L1 and L2 did.

Equivalence and row mutants (scratch only; restored from saved bytes; net10.0, analyzers on)

Mutant File:line Base (old method) Head (survivor)
Remove the 400 tag src/OpenCode.Sdk/Vcs/Internal/VcsStatusResponseAdapter.cs:9 GetStatusAsync_Should_Throw_The_Declared_400_Error red vcs.status:400:InvalidRequestError red on both spines
Remove the WorktreeError tag src/OpenCode.Sdk/Worktrees/Internal/WorktreeRefreshResponseAdapter.cs:9 RefreshWorktreesAsync_Should_Throw_The_Declared_400_Worktree_Error red worktree.refresh:400:WorktreeError red on both spines
Accept a numeric enum token src/OpenCode.Sdk/Vcs/Internal/FileDiffInfoStatusJsonConverter.cs:15 L1 red Deserialize_Should_Refuse_A_Token_That_Is_Not_A_String (numeric case) red
Read "modified" as "added" same converter, :20–21 L2 red Deserialize_Should_Read_A_Pinned_Value_As_Its_Static_Property red
Wrong expected CLR type Vcs/VcsDeclaredErrors.cs:53 n/a vcs.status:400 red on both spines
Pointer at another operation Vcs/VcsDeclaredErrors.cs:54 n/a the provenance guard red

Review

  • Second-family review (Sol, requirements and diff only): no findings.
    • It compared each of the 14 deleted methods with its row: SDK call, arguments, canned status and body.
    • It checked every operationId, method, path, status, _tag and pointer against spec/openapi.json.
    • All 9 door labels match the invoked client and member, and Branch and Working stay distinct.
    • It confirmed both L survivors.
  • Coordinator read: no findings. The Create and Remove 401 rows reproduce the CreateRequest() and RemoveRequest() values exactly, including Force = false.

Local check (Windows, on master df25ea5, which carries #465's 2.0.32 spec)

  • slopwatch: 0 issues. dotnet build -c Release: 0 warnings, 0 errors. dotnet format whitespace and style: clean.
  • Sdk.Tests [(Category!=ServiceElection)&(Category!=NativeAot)]: net10.0 2905 / 2905, net472 2910 / 2910 passed. The guard passes against the new pin.
  • Tools.Tests [Category!=NativeAot]: 2086 / 2086 passed, after the ceiling change.
  • verify-clones: passed. Tests: 571 clones, 4.87%, 0 new.

View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.

@Blind-Striker
Blind-Striker added this pull request to the merge queue Oct 17, 2026
Merged via the queue into master with commit a323b4d Oct 17, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant