980 lines · 39.0 KB · Swift
RawDownload
import Foundationimport Testing@testable import CodexBarCore@testable import CodexBarWidget struct CodexBarWidgetProviderTests {    @Test    func `usage display follows remaining and used preference`() {        #expect(WidgetUsageDisplay.percent(fromRemaining: 48, showUsed: false) == 48)        #expect(WidgetUsageDisplay.percent(fromRemaining: 48, showUsed: true) == 52)        #expect(WidgetUsageDisplay.percent(fromRemaining: nil, showUsed: true) == nil)    }     @Test    func `small widget falls back to local cost when quota rows are unavailable`() {        let tokenUsage = WidgetSnapshot.TokenUsageSummary(            sessionCostUSD: 1.25,            sessionTokens: 4200,            last30DaysCostUSD: 12.50,            last30DaysTokens: 42000,            currencyCode: "USD",            sessionLabel: "Today",            last30DaysLabel: "30d")        let entry = WidgetSnapshot.ProviderEntry(            provider: .claude,            updatedAt: Date(),            primary: nil,            secondary: nil,            tertiary: nil,            usageRows: [],            creditsRemaining: nil,            codeReviewRemainingPercent: nil,            tokenUsage: tokenUsage,            dailyUsage: [])        let windowedEntry = WidgetSnapshot.ProviderEntry(            provider: .claude,            updatedAt: Date(),            primary: RateWindow(usedPercent: 25, windowMinutes: 300, resetsAt: nil, resetDescription: nil),            secondary: nil,            tertiary: nil,            usageRows: nil,            creditsRemaining: nil,            codeReviewRemainingPercent: nil,            tokenUsage: tokenUsage,            dailyUsage: [])         #expect(WidgetUsageRow.compactTokenUsage(for: entry)?.sessionTokens == 4200)        #expect(WidgetUsageRow.compactTokenUsage(for: windowedEntry) == nil)    }     @Test    func `small widget limits custom usage rows`() {        let entry = WidgetSnapshot.ProviderEntry(            provider: .antigravity,            updatedAt: Date(),            primary: nil,            secondary: nil,            tertiary: nil,            usageRows: [                WidgetSnapshot.WidgetUsageRowSnapshot(id: "one", title: "One", percentLeft: 90),                WidgetSnapshot.WidgetUsageRowSnapshot(id: "two", title: "Two", percentLeft: 80),                WidgetSnapshot.WidgetUsageRowSnapshot(id: "three", title: "Three", percentLeft: 70),                WidgetSnapshot.WidgetUsageRowSnapshot(id: "four", title: "Four", percentLeft: 60),            ],            creditsRemaining: nil,            codeReviewRemainingPercent: nil,            tokenUsage: nil,            dailyUsage: [])         #expect(WidgetUsageRow.rows(for: entry, limit: 2).map(\.id) == ["one", "two"])        #expect(WidgetUsageRow.rows(for: entry).count == 4)    }     @Test    func `small antigravity widget keeps one row per quota family`() {        let entry = WidgetSnapshot.ProviderEntry(            provider: .antigravity,            updatedAt: Date(),            primary: nil,            secondary: nil,            tertiary: nil,            usageRows: [                WidgetSnapshot.WidgetUsageRowSnapshot(                    id: "antigravity-quota-summary-gemini-session",                    title: "Gemini Models Five Hour Limit",                    percentLeft: 80),                WidgetSnapshot.WidgetUsageRowSnapshot(                    id: "antigravity-quota-summary-gemini-weekly",                    title: "Gemini Models Weekly Limit",                    percentLeft: 20),                WidgetSnapshot.WidgetUsageRowSnapshot(                    id: "antigravity-quota-summary-third-party-session",                    title: "Claude and GPT models Five Hour Limit",                    percentLeft: 5),                WidgetSnapshot.WidgetUsageRowSnapshot(                    id: "antigravity-quota-summary-third-party-weekly",                    title: "Claude and GPT models Weekly Limit",                    percentLeft: 60),            ],            creditsRemaining: nil,            codeReviewRemainingPercent: nil,            tokenUsage: nil,            dailyUsage: [])         let rows = WidgetUsageRow.rows(for: entry, limit: 2)         #expect(rows.map(\.title) == ["Gemini Models Weekly Limit", "Claude and GPT models Five Hour Limit"])        #expect(rows.compactMap(\.percentLeft) == [20, 5])        #expect(WidgetUsageRow.smallWidgetRowLimit(for: entry) == 2)        #expect(WidgetUsageRow.mediumWidgetRowLimit(for: entry) == 3)        let mediumRows = WidgetUsageRow.rows(            for: entry,            limit: WidgetUsageRow.mediumWidgetRowLimit(for: entry))        #expect(mediumRows.map(\.title) == [            "Gemini Models Weekly Limit",            "Claude and GPT models Five Hour Limit",            "Claude and GPT models Weekly Limit",        ])    }     @Test    func `small antigravity widget keeps claude gpt family when fallback rows are more constrained`() {        let entry = WidgetSnapshot.ProviderEntry(            provider: .antigravity,            updatedAt: Date(),            primary: nil,            secondary: nil,            tertiary: nil,            usageRows: [                WidgetSnapshot.WidgetUsageRowSnapshot(                    id: "antigravity-quota-summary-gemini-5h",                    title: "Gemini Models Five Hour Limit",                    percentLeft: 40),                WidgetSnapshot.WidgetUsageRowSnapshot(                    id: "antigravity-quota-summary-gemini-weekly",                    title: "Gemini Models Weekly Limit",                    percentLeft: 70),                WidgetSnapshot.WidgetUsageRowSnapshot(                    id: "antigravity-quota-summary-3p-5h",                    title: "Claude and GPT models Five Hour Limit",                    percentLeft: 60),                WidgetSnapshot.WidgetUsageRowSnapshot(                    id: "antigravity-quota-summary-other-5h",                    title: "Other Five Hour Limit",                    percentLeft: 1),            ],            creditsRemaining: nil,            codeReviewRemainingPercent: nil,            tokenUsage: nil,            dailyUsage: [])         let rows = WidgetUsageRow.rows(for: entry, limit: 2)         #expect(rows.map(\.id) == [            "antigravity-quota-summary-gemini-5h",            "antigravity-quota-summary-3p-5h",        ])    }     @Test    func `small widget preserves tertiary rows for other providers`() {        let entry = WidgetSnapshot.ProviderEntry(            provider: .cursor,            updatedAt: Date(),            primary: nil,            secondary: nil,            tertiary: nil,            usageRows: [                WidgetSnapshot.WidgetUsageRowSnapshot(id: "one", title: "One", percentLeft: 90),                WidgetSnapshot.WidgetUsageRowSnapshot(id: "two", title: "Two", percentLeft: 80),                WidgetSnapshot.WidgetUsageRowSnapshot(id: "three", title: "Three", percentLeft: 70),            ],            creditsRemaining: nil,            codeReviewRemainingPercent: nil,            tokenUsage: nil,            dailyUsage: [])         let limit = WidgetUsageRow.smallWidgetRowLimit(for: entry)         #expect(limit == nil)        #expect(WidgetUsageRow.rows(for: entry, limit: limit).map(\.id) == ["one", "two", "three"])    }     @Test    func `small antigravity widget prefers known quota rows`() {        let entry = WidgetSnapshot.ProviderEntry(            provider: .antigravity,            updatedAt: Date(),            primary: nil,            secondary: nil,            tertiary: nil,            usageRows: [                WidgetSnapshot.WidgetUsageRowSnapshot(                    id: "antigravity-quota-summary-gemini-session",                    title: "Gemini Models Five Hour Limit",                    percentLeft: nil),                WidgetSnapshot.WidgetUsageRowSnapshot(                    id: "antigravity-quota-summary-gemini-weekly",                    title: "Gemini Models Weekly Limit",                    percentLeft: 100),                WidgetSnapshot.WidgetUsageRowSnapshot(                    id: "antigravity-quota-summary-third-party-session",                    title: "Claude and GPT models Five Hour Limit",                    percentLeft: 80),            ],            creditsRemaining: nil,            codeReviewRemainingPercent: nil,            tokenUsage: nil,            dailyUsage: [])         let rows = WidgetUsageRow.rows(for: entry, limit: 2)         #expect(rows.map(\.title) == ["Gemini Models Weekly Limit", "Claude and GPT models Five Hour Limit"])    }     @Test    func `small antigravity widget keeps nonstandard quota groups visible`() {        let entry = WidgetSnapshot.ProviderEntry(            provider: .antigravity,            updatedAt: Date(),            primary: nil,            secondary: nil,            tertiary: nil,            usageRows: [                WidgetSnapshot.WidgetUsageRowSnapshot(                    id: "antigravity-quota-summary-other-session",                    title: "Other Session",                    percentLeft: 70),                WidgetSnapshot.WidgetUsageRowSnapshot(                    id: "antigravity-quota-summary-other-weekly",                    title: "Other Weekly",                    percentLeft: 40),            ],            creditsRemaining: nil,            codeReviewRemainingPercent: nil,            tokenUsage: nil,            dailyUsage: [])         let rows = WidgetUsageRow.rows(for: entry, limit: 2)         #expect(rows.map(\.title) == ["Other Weekly", "Other Session"])    }     @Test    func `provider choice supports alibaba`() {        #expect(ProviderChoice(provider: .alibaba) == .alibaba)        #expect(ProviderChoice.alibaba.provider == .alibaba)    }     @Test    func `provider choice supports alibaba token plan`() {        #expect(ProviderChoice(provider: .alibabatokenplan) == .alibabatokenplan)        #expect(ProviderChoice.alibabatokenplan.provider == .alibabatokenplan)    }     @Test    func `provider choice supports opencode go`() {        #expect(ProviderChoice(provider: .opencodego) == .opencodego)        #expect(ProviderChoice.opencodego.provider == .opencodego)    }     @Test    func `provider choice supports devin`() {        #expect(ProviderChoice(provider: .devin) == .devin)        #expect(ProviderChoice.devin.provider == .devin)    }     @Test    func `widget entry carries devin overage balance through providerCost`() {        let entry = WidgetSnapshot.ProviderEntry(            provider: .devin,            updatedAt: Date(timeIntervalSince1970: 1_700_000_000),            primary: nil,            secondary: nil,            tertiary: nil,            creditsRemaining: nil,            codeReviewRemainingPercent: nil,            tokenUsage: nil,            dailyUsage: [],            providerCost: ProviderCostSnapshot(                used: 48.0,                limit: 0,                currencyCode: "USD",                period: "Extra usage balance",                updatedAt: Date(timeIntervalSince1970: 1_700_000_000)))        let encoded = try? JSONEncoder().encode(entry)        #expect(encoded != nil)        let decoded = encoded.flatMap { try? JSONDecoder().decode(WidgetSnapshot.ProviderEntry.self, from: $0) }        #expect(decoded?.providerCost?.period == "Extra usage balance")        #expect(decoded?.providerCost?.used == 48.0)        #expect(decoded?.providerCost?.limit == 0)        #expect(decoded?.provider == .devin)    }     @Test    func `widget balance formatter renders devin extra usage balance`() {        let entry = WidgetSnapshot.ProviderEntry(            provider: .devin,            updatedAt: Date(timeIntervalSince1970: 1_700_000_000),            primary: nil,            secondary: nil,            tertiary: nil,            creditsRemaining: nil,            codeReviewRemainingPercent: nil,            tokenUsage: nil,            dailyUsage: [],            providerCost: ProviderCostSnapshot(                used: 48.0,                limit: 0,                currencyCode: "USD",                period: "Extra usage balance",                updatedAt: Date(timeIntervalSince1970: 1_700_000_000)))        let line = WidgetBalanceFormatter.extraUsageBalance(for: entry)        #expect(line?.title == "Extra usage")        #expect(line?.value.hasPrefix("Balance: ") == true)        #expect(line?.value.contains("48") == true)    }     @Test    func `compact credits render Devin extra usage balance`() {        let entry = WidgetSnapshot.ProviderEntry(            provider: .devin,            updatedAt: Date(timeIntervalSince1970: 1_700_000_000),            primary: nil,            secondary: nil,            tertiary: nil,            creditsRemaining: nil,            codeReviewRemainingPercent: nil,            tokenUsage: nil,            dailyUsage: [],            providerCost: ProviderCostSnapshot(                used: 48.0,                limit: 0,                currencyCode: "USD",                period: "Extra usage balance",                updatedAt: Date(timeIntervalSince1970: 1_700_000_000)))         let display = CompactMetricFormatter.display(for: entry, metric: .credits)         #expect(display.value.contains("48"))        #expect(display.label == "Extra usage balance")        #expect(display.detail == nil)    }     @Test    func `widget balance formatter does not leak another provider balance`() {        let entry = WidgetSnapshot.ProviderEntry(            provider: .factory,            updatedAt: Date(timeIntervalSince1970: 1_700_000_000),            primary: nil,            secondary: nil,            tertiary: nil,            creditsRemaining: nil,            codeReviewRemainingPercent: nil,            tokenUsage: nil,            dailyUsage: [],            providerCost: ProviderCostSnapshot(                used: 12.0,                limit: 100.0,                currencyCode: "USD",                period: "Extra usage balance",                updatedAt: Date(timeIntervalSince1970: 1_700_000_000)))        #expect(WidgetBalanceFormatter.extraUsageBalance(for: entry) == nil)    }     @Test    func `provider choice supports Mistral`() {        #expect(ProviderChoice(provider: .mistral) == .mistral)        #expect(ProviderChoice.mistral.provider == .mistral)    }     @Test    func `provider choice supports Kimi`() {        #expect(ProviderChoice(provider: .kimi) == .kimi)        #expect(ProviderChoice.kimi.provider == .kimi)    }     @Test    func `compact Kimi widgets keep established row fit while large widgets show all quotas`() {        let now = Date(timeIntervalSince1970: 1_700_000_000)        let entry = WidgetSnapshot.ProviderEntry(            provider: .kimi,            updatedAt: now,            primary: RateWindow(usedPercent: 25, windowMinutes: nil, resetsAt: nil, resetDescription: nil),            secondary: RateWindow(usedPercent: 50, windowMinutes: 300, resetsAt: nil, resetDescription: nil),            tertiary: nil,            usageRows: [                WidgetSnapshot.WidgetUsageRowSnapshot(id: "primary", title: "Weekly", percentLeft: 75),                WidgetSnapshot.WidgetUsageRowSnapshot(id: "secondary", title: "Rate Limit", percentLeft: 50),                WidgetSnapshot.WidgetUsageRowSnapshot(id: "kimi-monthly", title: "Monthly", percentLeft: 25),                WidgetSnapshot.WidgetUsageRowSnapshot(id: "kimi-code-7d", title: "Code 7-day", percentLeft: 90),            ],            creditsRemaining: nil,            codeReviewRemainingPercent: nil,            tokenUsage: nil,            dailyUsage: [])         let smallRows = WidgetUsageRow.rows(            for: entry,            limit: WidgetUsageRow.smallWidgetRowLimit(for: entry))        let mediumRows = WidgetUsageRow.rows(            for: entry,            limit: WidgetUsageRow.mediumWidgetRowLimit(for: entry))        let largeRows = WidgetUsageRow.rows(for: entry)         #expect(WidgetUsageRow.smallWidgetRowLimit(for: entry) == 3)        #expect(WidgetUsageRow.mediumWidgetRowLimit(for: entry) == 3)        #expect(smallRows.map(\.id) == ["primary", "secondary", "kimi-monthly"])        #expect(mediumRows == smallRows)        #expect(largeRows.map(\.id) == ["primary", "secondary", "kimi-monthly", "kimi-code-7d"])    }     @Test    func `provider choice excludes unsupported Chutes widgets`() {        #expect(ProviderChoice(provider: .chutes) == nil)        #expect(ProviderChoice(provider: .sub2api) == nil)    }     @Test    func `supported providers fall back to codex when snapshot is empty`() {        let snapshot = WidgetSnapshot(entries: [], enabledProviders: [], generatedAt: Date())         #expect(CodexBarSwitcherTimelineProvider.supportedProviders(from: snapshot) == [.codex])    }     @Test    func `supported providers keep alibaba when it is the only enabled provider`() {        let now = Date(timeIntervalSince1970: 1_700_000_000)        let entry = WidgetSnapshot.ProviderEntry(            provider: .alibaba,            updatedAt: now,            primary: nil,            secondary: nil,            tertiary: nil,            creditsRemaining: nil,            codeReviewRemainingPercent: nil,            tokenUsage: nil,            dailyUsage: [])        let snapshot = WidgetSnapshot(entries: [entry], enabledProviders: [.alibaba], generatedAt: now)         #expect(CodexBarSwitcherTimelineProvider.supportedProviders(from: snapshot) == [.alibaba])    }     @Test    func `supported providers keep alibaba token plan when it is the only enabled provider`() {        let now = Date(timeIntervalSince1970: 1_700_000_000)        let entry = WidgetSnapshot.ProviderEntry(            provider: .alibabatokenplan,            updatedAt: now,            primary: nil,            secondary: nil,            tertiary: nil,            creditsRemaining: nil,            codeReviewRemainingPercent: nil,            tokenUsage: nil,            dailyUsage: [])        let snapshot = WidgetSnapshot(entries: [entry], enabledProviders: [.alibabatokenplan], generatedAt: now)         #expect(CodexBarSwitcherTimelineProvider.supportedProviders(from: snapshot) == [.alibabatokenplan])    }     @Test    func `supported providers keep Mistral when it is the only enabled provider`() {        let now = Date(timeIntervalSince1970: 1_700_000_000)        let entry = WidgetSnapshot.ProviderEntry(            provider: .mistral,            updatedAt: now,            primary: nil,            secondary: nil,            tertiary: nil,            creditsRemaining: nil,            codeReviewRemainingPercent: nil,            tokenUsage: nil,            dailyUsage: [])        let snapshot = WidgetSnapshot(entries: [entry], enabledProviders: [.mistral], generatedAt: now)         #expect(CodexBarSwitcherTimelineProvider.supportedProviders(from: snapshot) == [.mistral])    }     @Test    func `supported providers keep Kimi when it is the only enabled provider`() {        let now = Date(timeIntervalSince1970: 1_700_000_000)        let entry = WidgetSnapshot.ProviderEntry(            provider: .kimi,            updatedAt: now,            primary: RateWindow(usedPercent: 25, windowMinutes: nil, resetsAt: nil, resetDescription: nil),            secondary: RateWindow(usedPercent: 50, windowMinutes: 300, resetsAt: nil, resetDescription: nil),            tertiary: nil,            creditsRemaining: nil,            codeReviewRemainingPercent: nil,            tokenUsage: nil,            dailyUsage: [])        let snapshot = WidgetSnapshot(entries: [entry], enabledProviders: [.kimi], generatedAt: now)         #expect(CodexBarSwitcherTimelineProvider.supportedProviders(from: snapshot) == [.kimi])    }     @Test    func `codex weekly only widget rows omit session`() {        let now = Date(timeIntervalSince1970: 1_700_000_000)

Lines 1–500 of 980.