118 lines · 4.5 KB · Swift
RawDownload
import Foundationimport Testing@testable import CodexBarCore struct ClaudeSourcePlannerTests {    @Test    func `app auto plan preserves ordered steps and reasons`() {        let plan = ClaudeSourcePlanner.resolve(input: ClaudeSourcePlanningInput(            runtime: .app,            selectedDataSource: .auto,            webExtrasEnabled: false,            hasWebSession: true,            hasCLI: true,            hasOAuthCredentials: true))         #expect(plan.orderedSteps.map(\.dataSource) == [.oauth, .cli, .web])        #expect(plan.orderedSteps.map(\.inclusionReason) == [            .appAutoPreferredOAuth,            .appAutoFallbackCLI,            .appAutoFallbackWeb,        ])        #expect(plan.availableSteps.map(\.dataSource) == [.oauth, .cli, .web])        #expect(plan.preferredStep?.dataSource == .oauth)    }     @Test    func `CLI auto plan preserves ordered steps and reasons`() {        let plan = ClaudeSourcePlanner.resolve(input: ClaudeSourcePlanningInput(            runtime: .cli,            selectedDataSource: .auto,            webExtrasEnabled: false,            hasWebSession: true,            hasCLI: true,            hasOAuthCredentials: false))         #expect(plan.orderedSteps.map(\.dataSource) == [.web, .cli])        #expect(plan.orderedSteps.map(\.inclusionReason) == [            .cliAutoPreferredWeb,            .cliAutoFallbackCLI,        ])        #expect(plan.preferredStep?.dataSource == .web)    }     @Test    func `explicit mode plan is single step`() {        let plan = ClaudeSourcePlanner.resolve(input: ClaudeSourcePlanningInput(            runtime: .app,            selectedDataSource: .cli,            webExtrasEnabled: true,            hasWebSession: false,            hasCLI: true,            hasOAuthCredentials: false))         #expect(plan.orderedSteps.count == 1)        #expect(plan.orderedSteps.first?.dataSource == .cli)        #expect(plan.orderedSteps.first?.inclusionReason == .explicitSourceSelection)        #expect(plan.compatibilityStrategy == ClaudeUsageStrategy(dataSource: .cli, useWebExtras: true))    }     @Test    func `app auto CLI fallback reports web extras like runtime`() {        let plan = ClaudeSourcePlanner.resolve(input: ClaudeSourcePlanningInput(            runtime: .app,            selectedDataSource: .auto,            webExtrasEnabled: true,            hasWebSession: false,            hasCLI: true,            hasOAuthCredentials: false))         #expect(plan.preferredStep?.dataSource == .cli)        #expect(plan.compatibilityStrategy == ClaudeUsageStrategy(dataSource: .cli, useWebExtras: true))    }     @Test    func `no source planner output is deterministic`() {        let input = ClaudeSourcePlanningInput(            runtime: .app,            selectedDataSource: .auto,            webExtrasEnabled: false,            hasWebSession: false,            hasCLI: false,            hasOAuthCredentials: false)        let plan = ClaudeSourcePlanner.resolve(input: input)         #expect(plan.orderedSteps.map(\.dataSource) == [.oauth, .cli, .web])        #expect(plan.availableSteps.isEmpty)        #expect(plan.isNoSourceAvailable)        #expect(plan.preferredStep == nil)        #expect(plan.executionSteps.isEmpty)        #expect(plan.debugLines() == [            "planner_order=oauth→cli→web",            "planner_selected=none",            "planner_no_source=true",            "planner_step.oauth=unavailable reason=app-auto-preferred-oauth",            "planner_step.cli=unavailable reason=app-auto-fallback-cli",            "planner_step.web=unavailable reason=app-auto-fallback-web",        ])    }     @Test    func `CLI resolver falls back to PATH when Claude CLI path override is invalid`() throws {        let tempDir = FileManager.default.temporaryDirectory            .appendingPathComponent(UUID().uuidString, isDirectory: true)        try FileManager.default.createDirectory(at: tempDir, withIntermediateDirectories: true)        let binaryURL = tempDir.appendingPathComponent("claude")        try Data("#!/bin/sh\nexit 0\n".utf8).write(to: binaryURL)        try FileManager.default.setAttributes([.posixPermissions: 0o755], ofItemAtPath: binaryURL.path)         let resolved = ClaudeCLIResolver.resolvedBinaryPath(            environment: [                "CLAUDE_CLI_PATH": "/definitely/missing/claude",                "PATH": tempDir.path,            ],            loginPATH: nil)         #expect(resolved == binaryURL.path)    }}