Files
hyungi_document_server/Tests/DSKitTests/RouterFallbackTests.swift
T
Hyungi 52aa99ec8e merge: integrate AIFabric (S2) into S3 app — unified package
- Resolve Package.swift add/add: one manifest, single AIFabric target (Sources/AI compiled once;
  no duplicate-symbol risk) + DSKit/AppFeature/DSApp + AITests + DSKitTests, AIFabric library product kept.
- import AI -> import AIFabric across AppFeature + RouterFallbackTests (S2 renamed module).
- AppModel.askMeta qualified DSKit.AskResponse (AIFabric also defines an AskResponse for RemoteDS).

swift build + swift test green (71 tests: S2 AITests + S3 DSKitTests). Frozen AIProvider interface intact.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-05 06:41:30 +09:00

43 lines
1.8 KiB
Swift

import XCTest
import AIFabric
/// Gate 4 (AI flow): proves the S2 AIRouter produces a VISIBLE routingNote on a rule-based fallback,
/// and that an explicit-provider-unavailable pick throws (no silent fallback). Sources/AI is consumed
/// read-only; these tests never modify it.
final class RouterFallbackTests: XCTestCase {
func testRuleFallbackIsVisible() async throws {
let router = AIRouter(providers: [
.onDevice: MockAIProvider(id: .onDevice, available: false),
.localMLX: MockAIProvider(id: .localMLX, available: true),
])
let resp = try await router.route(AICompletionRequest(task: .quickSummarize, prompt: "x"))
XCTAssertEqual(resp.providerUsed, .localMLX)
XCTAssertEqual(resp.routingNote, "fallback from onDevice → localMLX")
}
func testExplicitUnavailableThrowsNoFallback() async throws {
let router = AIRouter(providers: [
.onDevice: MockAIProvider(id: .onDevice, available: false),
.localMLX: MockAIProvider(id: .localMLX, available: true),
])
do {
_ = try await router.route(
AICompletionRequest(task: .quickSummarize, prompt: "x", explicitProvider: .onDevice)
)
XCTFail("expected explicitProviderUnavailable")
} catch let error as AIRoutingError {
guard case .explicitProviderUnavailable = error else {
return XCTFail("wrong error: \(error)")
}
}
}
func testCorpusAskRoutesRemoteWithCitation() async throws {
let router = AIRouter(providers: [.remoteDS: MockAIProvider(id: .remoteDS)])
let resp = try await router.route(AICompletionRequest(task: .corpusAsk, prompt: "q"))
XCTAssertEqual(resp.providerUsed, .remoteDS)
XCTAssertEqual(resp.citations.count, 1)
}
}