Files
steipete--codexbar/Tests/CodexBarTests/MenuBarResetTimeDisplayTests.swift
T
2026-07-13 12:22:33 +08:00

366 lines
11 KiB
Swift

import CodexBarCore
import Foundation
import Testing
@testable import CodexBar
struct MenuBarResetTimeDisplayTests {
@Test
func `reset time mode formats the selected window reset`() {
let now = Date(timeIntervalSince1970: 1_800_000_000)
let resetsAt = now.addingTimeInterval(2 * 3600)
let window = RateWindow(
usedPercent: 42,
windowMinutes: 300,
resetsAt: resetsAt,
resetDescription: nil)
let text = MenuBarDisplayText.displayText(
mode: .resetTime,
percentWindow: window,
showUsed: true,
resetTimeDisplayStyle: .absolute,
now: now)
#expect(text == "↻ \(UsageFormatter.resetDescription(from: resetsAt, now: now))")
}
@Test
func `reset time mode uses countdown preference`() {
let now = Date(timeIntervalSince1970: 1_800_000_000)
let resetsAt = now.addingTimeInterval(2 * 3600 + 15 * 60)
let window = RateWindow(
usedPercent: 42,
windowMinutes: 300,
resetsAt: resetsAt,
resetDescription: nil)
let text = MenuBarDisplayText.displayText(
mode: .resetTime,
percentWindow: window,
showUsed: true,
resetTimeDisplayStyle: .countdown,
now: now)
#expect(text == "↻ in 2h 15m")
}
@Test
func `reset time mode falls back to used percent without reset metadata`() {
let window = RateWindow(
usedPercent: 42,
windowMinutes: 300,
resetsAt: nil,
resetDescription: nil)
let text = MenuBarDisplayText.displayText(
mode: .resetTime,
percentWindow: window,
showUsed: true)
#expect(text == "42%")
}
@Test
func `reset time mode uses text reset metadata`() {
let window = RateWindow(
usedPercent: 42,
windowMinutes: 300,
resetsAt: nil,
resetDescription: "in 2h 15m")
let text = MenuBarDisplayText.displayText(
mode: .resetTime,
percentWindow: window,
showUsed: true)
#expect(text == "↻ in 2h 15m")
}
@Test
func `reset time mode surfaces daily reset metadata`() {
let window = RateWindow(
usedPercent: 39,
windowMinutes: 1440,
resetsAt: nil,
resetDescription: "resets daily")
let text = MenuBarDisplayText.displayText(
mode: .resetTime,
percentWindow: window,
showUsed: true)
#expect(text == "↻ resets daily")
}
@Test(arguments: [
"Resets in 2h",
"tomorrow, 3:00 PM",
"next week",
"expires in 4d",
])
func `reset time mode accepts reset timing phrases`(_ description: String) {
let window = RateWindow(
usedPercent: 42,
windowMinutes: 300,
resetsAt: nil,
resetDescription: description)
let text = MenuBarDisplayText.displayText(
mode: .resetTime,
percentWindow: window,
showUsed: true)
#expect(text == "↻ \(description)")
}
@Test(arguments: [
"250/1000 requests",
"160 requests",
"5 hours window",
"$10.00 available",
])
func `reset time mode rejects non-reset provider summaries`(_ description: String) {
let window = RateWindow(
usedPercent: 42,
windowMinutes: 300,
resetsAt: nil,
resetDescription: description)
let text = MenuBarDisplayText.displayText(
mode: .resetTime,
percentWindow: window,
showUsed: true)
#expect(text == "42%")
}
@Test
func `reset time mode falls back to remaining percent without reset metadata`() {
let window = RateWindow(
usedPercent: 42,
windowMinutes: 300,
resetsAt: nil,
resetDescription: nil)
let text = MenuBarDisplayText.displayText(
mode: .resetTime,
percentWindow: window,
showUsed: false)
#expect(text == "58%")
}
@Test(arguments: [MenuBarDisplayMode.percent, .pace, .both])
func `smart reset shows countdown when the quota is exhausted`(_ mode: MenuBarDisplayMode) {
let now = Date(timeIntervalSince1970: 1_800_000_000)
let window = RateWindow(
usedPercent: 100,
windowMinutes: 300,
resetsAt: now.addingTimeInterval(2 * 3600 + 15 * 60),
resetDescription: nil)
let text = MenuBarDisplayText.displayText(
mode: mode,
percentWindow: window,
showUsed: false,
resetTimeDisplayStyle: .countdown,
showsResetTimeWhenExhausted: true,
now: now)
#expect(text == "↻ in 2h 15m")
}
@Test
func `smart reset honors the absolute clock preference`() {
let now = Date(timeIntervalSince1970: 1_800_000_000)
let resetsAt = now.addingTimeInterval(2 * 3600)
let window = RateWindow(
usedPercent: 100,
windowMinutes: 300,
resetsAt: resetsAt,
resetDescription: nil)
let text = MenuBarDisplayText.displayText(
mode: .percent,
percentWindow: window,
showUsed: false,
resetTimeDisplayStyle: .absolute,
showsResetTimeWhenExhausted: true,
now: now)
#expect(text == "↻ \(UsageFormatter.resetDescription(from: resetsAt, now: now))")
}
@Test
func `smart reset leaves a non-exhausted quota untouched`() {
let now = Date(timeIntervalSince1970: 1_800_000_000)
let window = RateWindow(
usedPercent: 42,
windowMinutes: 300,
resetsAt: now.addingTimeInterval(3600),
resetDescription: nil)
let text = MenuBarDisplayText.displayText(
mode: .percent,
percentWindow: window,
showUsed: false,
showsResetTimeWhenExhausted: true,
now: now)
#expect(text == "58%")
}
@Test
func `smart reset disabled keeps the exhausted percent`() {
let window = RateWindow(
usedPercent: 100,
windowMinutes: 300,
resetsAt: Date(timeIntervalSince1970: 1_800_000_000),
resetDescription: nil)
let text = MenuBarDisplayText.displayText(
mode: .percent,
percentWindow: window,
showUsed: false)
#expect(text == "0%")
}
@Test
func `smart reset falls back to percent once the reset has elapsed`() {
let now = Date(timeIntervalSince1970: 1_800_000_000)
// Exhausted window whose reset moment is already in the past (e.g. snapshot lingering at 100%
// before the next provider refresh). Showing "↻ now" here would be stale and could stick.
let window = RateWindow(
usedPercent: 100,
windowMinutes: 300,
resetsAt: now.addingTimeInterval(-60),
resetDescription: nil)
let text = MenuBarDisplayText.displayText(
mode: .percent,
percentWindow: window,
showUsed: false,
resetTimeDisplayStyle: .countdown,
showsResetTimeWhenExhausted: true,
now: now)
#expect(text == "0%")
}
@Test
func `smart reset ignores textual reset metadata without a concrete reset time`() {
// Provider supplies only a textual resetDescription (no resetsAt). The smart option can't hand
// that to the refresh scheduler, so it keeps the percent rather than freezing on "↻ in 2h".
let window = RateWindow(
usedPercent: 100,
windowMinutes: 300,
resetsAt: nil,
resetDescription: "in 2h")
let text = MenuBarDisplayText.displayText(
mode: .percent,
percentWindow: window,
showUsed: false,
showsResetTimeWhenExhausted: true)
#expect(text == "0%")
// Reset-time mode still surfaces the textual metadata (unchanged behavior).
let resetTimeText = MenuBarDisplayText.displayText(
mode: .resetTime,
percentWindow: window,
showUsed: false)
#expect(resetTimeText == "↻ in 2h")
}
@Test
func `smart reset falls back to percent without reset metadata`() {
let window = RateWindow(
usedPercent: 100,
windowMinutes: 300,
resetsAt: nil,
resetDescription: nil)
let text = MenuBarDisplayText.displayText(
mode: .percent,
percentWindow: window,
showUsed: false,
showsResetTimeWhenExhausted: true)
#expect(text == "0%")
}
@Test(arguments: [MenuBarDisplayMode.pace, .both])
func `smart reset keeps exhausted percent when pace exists but reset is unusable`(_ mode: MenuBarDisplayMode) {
let now = Date(timeIntervalSince1970: 1_800_000_000)
let window = RateWindow(
usedPercent: 100,
windowMinutes: 300,
resetsAt: now.addingTimeInterval(-60),
resetDescription: nil)
let pace = UsagePace(
stage: .ahead,
deltaPercent: 12,
expectedUsedPercent: 40,
actualUsedPercent: 52,
etaSeconds: nil,
willLastToReset: true)
let text = MenuBarDisplayText.displayText(
mode: mode,
percentWindow: window,
pace: pace,
showUsed: false,
showsResetTimeWhenExhausted: true,
now: now)
#expect(text == "0%")
}
@Test
func `smart reset does not alter reset time mode`() {
let now = Date(timeIntervalSince1970: 1_800_000_000)
let resetsAt = now.addingTimeInterval(3600)
let window = RateWindow(
usedPercent: 42,
windowMinutes: 300,
resetsAt: resetsAt,
resetDescription: nil)
let text = MenuBarDisplayText.displayText(
mode: .resetTime,
percentWindow: window,
showUsed: false,
resetTimeDisplayStyle: .countdown,
showsResetTimeWhenExhausted: true,
now: now)
#expect(text == "↻ in 1h")
}
@Test
func `smart reset replaces only the exhausted lane in combined text`() {
let now = Date(timeIntervalSince1970: 1_800_000_000)
let session = RateWindow(
usedPercent: 100,
windowMinutes: 300,
resetsAt: now.addingTimeInterval(2 * 3600 + 15 * 60),
resetDescription: nil)
let weekly = RateWindow(
usedPercent: 55,
windowMinutes: 10080,
resetsAt: now.addingTimeInterval(3 * 86400),
resetDescription: nil)
let text = MenuBarDisplayText.combinedSessionWeeklyPercentText(
sessionWindow: session,
weeklyWindow: weekly,
showUsed: false,
resetTimeDisplayStyle: .countdown,
showsResetTimeWhenExhausted: true,
now: now)
#expect(text == "5h ↻ in 2h 15m · W 45%")
}
}