test: cover AIChatViewModel.executeToolUses with injectable registry#1072
Merged
datlechin merged 1 commit intoMay 7, 2026
Merged
Conversation
…njectable registry
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
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.
Summary
Two items from the umbrella followup list, bundled because one obviated the other:
AIChatViewModel.executeToolUsesis the central dispatch helper that mapsToolUseBlock→ToolResultBlockvia the registry. Phase 4 shipped it with zero unit tests. This adds 8 tests covering happy path, parallel ordering, missing tools, throwing tools, isError propagation, mixed cases, input forwarding, and empty input.viewModel.tablescomputed property — same liveSchemaServicesource the popover uses. No code change needed; verified in this PR by reading the current state ofAIChatPanelView.mentionMenu.Refactor for testability
executeToolUsesand the innerrunToolUsepreviously readChatToolRegistry.shareddirectly, which makes test isolation hard (registering a tool in one test pollutes the singleton for others). Added an injectableregistry: ChatToolRegistry?parameter that defaults tonil, falling through to.sharedfor production. Tests pass a freshChatToolRegistry()per test for isolation.Production call site in
runStreamdoesn't change (defaultnilfalls through). The registry parameter is the same shape we used for the parser test refactor in #1071: an injectable seam, defaultnilfor production.Test coverage
dispatchesToRegisteredTool— happy path: registered tool, result matches.resultsAreInInputOrder— parallelwithTaskGroupexecution preserves input order in output.unregisteredToolReturnsError— missing tool name yieldsisError: truewith explanation.throwingToolReturnsError—try await tool.execute(...)failure yieldsisError: truewithError:prefix.toolIsErrorPropagates— a tool's ownChatToolResult(isError: true)flows through.mixedToolsAllReturnResults— array of registered + unregistered tools each gets its own result block.inputForwarded— theToolUseBlock.inputJSONValue reaches the tool'sexecute(input:).emptyInput— empty array returns empty results, doesn't crash.Why these matter
Tool dispatch is the load-bearing path for tool calling. The four most likely regressions from a future refactor:
withTaskGroup, lost order preservation"tool.executeinvocation, isError stops propagating"All four are pinned by these tests.
CHANGELOG
No entry. Tests + non-breaking parameter addition.
Lint
swiftlint lint --strictclean across all 819 files.Test plan
xcodebuild test -only-testing:TableProTests/ExecuteToolUsesTestspasses all 8 tests.list_tables) — production tool dispatch still works.