108 lines
5.9 KiB
Swift
108 lines
5.9 KiB
Swift
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
|
|
import Foundation
|
|
import Testing
|
|
import Localization
|
|
|
|
struct AIUsageFormatTests {
|
|
@Test(arguments: [
|
|
(0, "0"), (999, "999"), (1_000, "1K"), (1_234, "1.2K"),
|
|
(100_000, "100K"), (123_456, "123K"), (999_499, "999K"),
|
|
(999_500, "1M"), (1_000_000, "1M"), (1_234_567, "1.2M"),
|
|
(10_000_000, "10M"), (12_345_678, "12M"), (999_499_999, "999M"),
|
|
(999_500_000, "1B"), (1_000_000_000, "1B"), (1_234_567_890, "1.23B"),
|
|
(-1_234, "-1.2K")
|
|
])
|
|
func westernTokens(_ value: Int, _ expected: String) {
|
|
#expect(AIUsageFormat.tokens(value, locale: Locale(identifier: "en_US")) == expected)
|
|
}
|
|
|
|
@Test(arguments: [
|
|
(9_999, "9999"), (10_000, "1万"), (12_345, "1.2万"),
|
|
(99_999_499, "9999.9万"), (99_999_500, "1亿"),
|
|
(100_000_000, "1亿"), (123_456_789, "1.23亿")
|
|
])
|
|
func simplifiedChineseTokens(_ value: Int, _ expected: String) {
|
|
#expect(AIUsageFormat.tokens(value, locale: Locale(identifier: "zh_CN")) == expected)
|
|
}
|
|
|
|
@Test func tokenLocalesAndWesternOverride() {
|
|
#expect(AIUsageFormat.tokens(12_345, locale: Locale(identifier: "zh_Hant_TW")) == "1.2萬")
|
|
#expect(AIUsageFormat.tokens(123_456_789, locale: Locale(identifier: "zh_TW")) == "1.23億")
|
|
#expect(AIUsageFormat.tokens(12_345, westernUnits: true, locale: Locale(identifier: "zh_CN")) == "12.3K")
|
|
#expect(AIUsageFormat.tokens(1_234, locale: Locale(identifier: "de_DE")) == "1,2K")
|
|
#expect(AIUsageFormat.tokens(1_234, locale: Locale(identifier: "ar_SA")) == "١٫٢K")
|
|
#expect(!AIUsageFormat.tokens(Int.min, locale: Locale(identifier: "en_US")).isEmpty)
|
|
#expect(!AIUsageFormat.tokens(Int.max, locale: Locale(identifier: "zh_CN")).isEmpty)
|
|
}
|
|
|
|
@Test func quotaClampsAndInverts() {
|
|
#expect(AIUsageFormat.quotaValue(remainingPercent: -10, showsRemaining: true) == 0)
|
|
#expect(AIUsageFormat.quotaValue(remainingPercent: 110, showsRemaining: true) == 100)
|
|
#expect(AIUsageFormat.quotaValue(remainingPercent: -10, showsRemaining: false) == 100)
|
|
#expect(AIUsageFormat.quotaValue(remainingPercent: 110, showsRemaining: false) == 0)
|
|
#expect(AIUsageFormat.quotaValue(remainingPercent: 75, showsRemaining: false) == 25)
|
|
}
|
|
|
|
@Test(arguments: [Double.nan, Double.infinity, -Double.infinity])
|
|
func unknownQuotaIsNotZero(_ value: Double) {
|
|
#expect(AIUsageFormat.quotaValue(remainingPercent: value, showsRemaining: true) == nil)
|
|
#expect(AIUsageFormat.quotaValue(remainingPercent: value, showsRemaining: false) == nil)
|
|
#expect(AIUsageFormat.quotaPercent(remainingPercent: value, showsRemaining: true,
|
|
locale: Locale(identifier: "en_US")) == "—")
|
|
}
|
|
|
|
@Test func compactQuotaPreservesEndpoints() {
|
|
let locale = Locale(identifier: "en_US")
|
|
#expect(AIUsageFormat.quotaPercent(remainingPercent: 0, showsRemaining: true, locale: locale, compact: true) == "0%")
|
|
#expect(AIUsageFormat.quotaPercent(remainingPercent: 100, showsRemaining: true, locale: locale, compact: true) == "100%")
|
|
#expect(AIUsageFormat.quotaPercent(remainingPercent: 0.4, showsRemaining: true, locale: locale, compact: true) == "<1%")
|
|
#expect(AIUsageFormat.quotaPercent(remainingPercent: 99.6, showsRemaining: true, locale: locale, compact: true) == ">99%")
|
|
#expect(AIUsageFormat.quotaPercent(remainingPercent: 99.6, showsRemaining: false, locale: locale, compact: true) == "<1%")
|
|
#expect(AIUsageFormat.quotaPercent(remainingPercent: 0, showsRemaining: false, locale: locale, compact: true) == "100%")
|
|
#expect(AIUsageFormat.quotaPercent(remainingPercent: 99.6, showsRemaining: true, locale: locale) == "99.6%")
|
|
#expect(AIUsageFormat.quotaPercent(remainingPercent: 99.6, showsRemaining: false, locale: locale) == "0.4%")
|
|
}
|
|
|
|
@Test func percentUsesExplicitLocale() {
|
|
let arabic = AIUsageFormat.quotaPercent(remainingPercent: 12.3, showsRemaining: true, locale: Locale(identifier: "ar_SA"))
|
|
#expect(arabic.contains("١٢٫٣"))
|
|
#expect(arabic.contains("٪"))
|
|
let german = AIUsageFormat.quotaPercent(remainingPercent: 12.3, showsRemaining: true, locale: Locale(identifier: "de_DE"))
|
|
#expect(german.contains("12,3"))
|
|
}
|
|
|
|
@Test(arguments: [(0.0, "$0"), (0.0123, "$0.012"), (1.234, "$1.23"), (100.49, "$100")])
|
|
func dollarsUseMagnitudePrecision(_ value: Double, _ expected: String) {
|
|
#expect(AIUsageFormat.money(usd: value, currency: .usd, usdToCNY: nil,
|
|
locale: Locale(identifier: "en_US")) == expected)
|
|
}
|
|
|
|
@Test func yuanRequiresExchangeRateAndConvertsForDisplay() {
|
|
let usd = 2.0
|
|
let locale = Locale(identifier: "zh_CN")
|
|
#expect(AIUsageFormat.money(usd: usd, currency: .cny, usdToCNY: nil, locale: locale) == nil)
|
|
#expect(AIUsageFormat.money(usd: usd, currency: .cny, usdToCNY: 7.25, locale: locale) == "¥14.5")
|
|
#expect(usd == 2)
|
|
#expect(AIUsageCurrency.usd.currencyCode == "USD")
|
|
#expect(AIUsageCurrency.cny.currencyCode == "CNY")
|
|
}
|
|
|
|
@Test(arguments: [Double.nan, Double.infinity, -Double.infinity, -1])
|
|
func rejectsInvalidMoney(_ value: Double) {
|
|
#expect(AIUsageFormat.money(usd: value, currency: .usd, usdToCNY: nil,
|
|
locale: Locale(identifier: "en_US")) == nil)
|
|
}
|
|
|
|
@Test(arguments: [Double.nan, Double.infinity, -Double.infinity, -1, 0])
|
|
func rejectsInvalidRates(_ rate: Double) {
|
|
#expect(AIUsageFormat.money(usd: 1, currency: .cny, usdToCNY: rate,
|
|
locale: Locale(identifier: "zh_CN")) == nil)
|
|
}
|
|
|
|
@Test func rejectsConversionOverflow() {
|
|
#expect(AIUsageFormat.money(usd: Double.greatestFiniteMagnitude, currency: .cny,
|
|
usdToCNY: 2, locale: Locale(identifier: "zh_CN")) == nil)
|
|
}
|
|
}
|