66 new tests across 8 files (93 total in the suite now):
- GitSyncServiceTests: convertToSSH/injectCredentials/sanitizeFilename/
detectSecretsInText, including a below-threshold false-positive check
on the secret regex.
- ChatViewModelPureLogicTests: detectGoodbyePhrase, inferProvider,
calculateCost -- including the cache-read (0.1x) / cache-write (1.25x)
pricing multipliers, which is real billing-affecting logic.
- EmbeddingServiceTests / ContextSelectionServiceTests: embedding
(de)serialization round-trip, importance-score weighting, and the
token-estimate fallback (content.count / 4) when no real count exists.
- OpenRouterProviderTests / OllamaProviderTests / OpenAIProviderTests /
AnthropicProviderTests: request-building (attachments, online mode,
cache_control breakpoints, o1/o3 temperature omission, tool schema
conversion) and response-parsing (text, tool_use blocks, empty-choices
fallback behavior) for all four providers, with no network involved.
Also marks calculateCost/inferProvider/detectGoodbyePhrase (ChatViewModel)
and serializeEmbedding/deserializeEmbedding (EmbeddingService) as
`nonisolated` -- discovered via the actual test failures, not
speculation: the project's `SWIFT_DEFAULT_ACTOR_ISOLATION = MainActor`
setting isolates the classes that carry an explicit `@MainActor`
(ChatViewModel), so calling their static members from a plain
synchronous @Test needs the pure ones marked `nonisolated`. Matches
the existing convention already used elsewhere in EmbeddingService
(cosineSimilarity was already nonisolated before this change).
Phase 2 of the test-suite rollout plan (peaceful-baking-kurzweil).
27 tests across 4 files, all targeting code that was already testable
the moment the target existed -- no visibility bumps, no refactors:
- GitignoreParserTests: MCPService.GitignoreParser's glob-to-regex
matching (wildcards, **, directory anchors, negation, comments).
- OpenRouterModelsTests: the string-vs-content-block-array decoders
on both the request side (APIMessage.MessageContent/ContentItem)
and response side (Choice.MessageContent, StreamChoice.Delta),
including image extraction from content blocks.
- AIProviderTests: ChatResponse/Usage decoding, with an explicit
regression guard that Usage.rawCostUSD always decodes to nil (it's
only ever set programmatically, never from API JSON).
- MessageCodableTests: confirms Message's transient fields
(isStreaming, isStarred, generatedImages, toolCalls,
thinkingContent) don't survive an encode/decode round-trip, and
documents that its custom == deliberately ignores role/timestamp/
attachments/modelId -- a real but non-obvious behavior worth
locking in with a test.
Removed the placeholder oAITests.swift example test now that there's
real coverage. Phase 1 of the test-suite rollout plan
(peaceful-baking-kurzweil).
The old Tests/oAITests/oAITests.swift + root Package.swift/Sources/
were a swift package init stub that @testable imported a fake empty
oAI module, completely disconnected from the real ~31K-line app
(built only via oAI.xcodeproj). Running `swift test` there would
have silently "passed" while testing nothing.
oAITests is a proper Unit Testing Bundle target added via Xcode's
target editor, wired into the app's scheme (TestAction references
oAITests.xctest). Verified with `xcodebuild test` before and after
removing the dead scaffold.
First phase of the test-suite rollout plan (peaceful-baking-kurzweil).