From b143d2379a22ec32935e1ec44d517dd4d1e65086 Mon Sep 17 00:00:00 2001 From: ninarg Date: Thu, 19 Oct 2023 08:51:58 +0200 Subject: [PATCH] Support multiple currencies (#399) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Inject local currency into charcoal --------- Co-authored-by: Nina Røsdal Graneggen --- .../xcshareddata/swiftpm/Package.resolved | 4 +-- .../RangeFilterDemoViewController.swift | 2 +- .../RangeFilterConfigurationExtensions.swift | 2 +- README.md | 2 +- Sources/Charcoal/Charcoal+Currency.swift | 20 +++++++++++++ Sources/Charcoal/Models/FilterUnit.swift | 18 +++++++---- .../Resources/en.lproj/Localizable.strings | 2 -- .../Resources/fi.lproj/Localizable.strings | 2 -- .../Resources/nb.lproj/Localizable.strings | 2 -- .../Charcoal/Models/FilterUnitTests.swift | 30 ++++++++++++++----- .../RangeFilterConfigurationTests.swift | 4 +-- .../RangerFilterConfiguration+Stubs.swift | 2 +- 12 files changed, 64 insertions(+), 26 deletions(-) create mode 100644 Sources/Charcoal/Charcoal+Currency.swift diff --git a/CharcoalDemo/CharcoalDemo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/CharcoalDemo/CharcoalDemo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 2c7618cc..b9870743 100644 --- a/CharcoalDemo/CharcoalDemo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/CharcoalDemo/CharcoalDemo.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -5,8 +5,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/finn-no/FinniversKit.git", "state" : { - "revision" : "ae037d661da2da43a81c3996649c8fbe7d079566", - "version" : "119.0.0" + "revision" : "d11846eca89cf6f50926d5bae7deccbef0a19b99", + "version" : "120.2.0" } }, { diff --git a/CharcoalDemo/CharcoalDemo/Components/RangeFilterDemoViewController.swift b/CharcoalDemo/CharcoalDemo/Components/RangeFilterDemoViewController.swift index 1f2eb88c..49baf794 100644 --- a/CharcoalDemo/CharcoalDemo/Components/RangeFilterDemoViewController.swift +++ b/CharcoalDemo/CharcoalDemo/Components/RangeFilterDemoViewController.swift @@ -14,7 +14,7 @@ final class RangeFilterDemoViewController: DemoViewController { valueKind: .incremented(1000), hasLowerBoundOffset: false, hasUpperBoundOffset: true, - unit: .currency, + unit: .currency(unit: "kr"), usesSmallNumberInputFont: false ) diff --git a/CharcoalDemo/CharcoalDemo/Extensions/RangeFilterConfigurationExtensions.swift b/CharcoalDemo/CharcoalDemo/Extensions/RangeFilterConfigurationExtensions.swift index 78699c92..6da80ac5 100644 --- a/CharcoalDemo/CharcoalDemo/Extensions/RangeFilterConfigurationExtensions.swift +++ b/CharcoalDemo/CharcoalDemo/Extensions/RangeFilterConfigurationExtensions.swift @@ -13,7 +13,7 @@ extension RangeFilterConfiguration { (from: 6000, increment: 1000), ]) - return create(minimumValue: 0, maximumValue: 30000, unit: .currency, increment: increment) + return create(minimumValue: 0, maximumValue: 30000, unit: .currency(unit: "kr"), increment: increment) } static func create(minimumValue: Int = 0, maximumValue: Int = 10, unit: FilterUnit, increment: ValueKind = .incremented(1)) -> RangeFilterConfiguration { diff --git a/README.md b/README.md index 62b26c5d..19517fd8 100644 --- a/README.md +++ b/README.md @@ -92,7 +92,7 @@ let container = FilterContainer( valueKind: .incremented(1000), hasLowerBoundOffset: false, hasUpperBoundOffset: true, - unit: .currency, + unit: .currency(unit: "kr"), usesSmallNumberInputFont: false ) ), diff --git a/Sources/Charcoal/Charcoal+Currency.swift b/Sources/Charcoal/Charcoal+Currency.swift new file mode 100644 index 00000000..20702efa --- /dev/null +++ b/Sources/Charcoal/Charcoal+Currency.swift @@ -0,0 +1,20 @@ +import Foundation + +extension Charcoal { + struct CurrencyConfig { + let localCurrencyLocalized: String + let localCurrencyAccessibleLocalized: String + } + + static private(set) var currencyConfig: CurrencyConfig? + + public static func configure( + localCurrencyLocalized: String, + localCurrencyAccessibleLocalized: String + ) { + self.currencyConfig = .init( + localCurrencyLocalized: localCurrencyLocalized, + localCurrencyAccessibleLocalized: localCurrencyAccessibleLocalized + ) + } +} diff --git a/Sources/Charcoal/Models/FilterUnit.swift b/Sources/Charcoal/Models/FilterUnit.swift index 1e83ef44..1cee3d9a 100644 --- a/Sources/Charcoal/Models/FilterUnit.swift +++ b/Sources/Charcoal/Models/FilterUnit.swift @@ -7,7 +7,7 @@ import Foundation public enum FilterUnit: Equatable { case centimeters case cubicCentimeters - case currency + case currency(unit: String) case feet case horsePower case items @@ -30,8 +30,12 @@ public enum FilterUnit: Equatable { return "unit.centimeters.value".localized() case .cubicCentimeters: return "unit.cubicCentimeters.value".localized() - case .currency: - return "unit.currency.value".localized() + case .currency(let unit): + if let currencyConfig = Charcoal.currencyConfig { + return currencyConfig.localCurrencyLocalized + } else { + return unit + } case .feet: return "unit.feet.value".localized() case .horsePower: @@ -63,8 +67,12 @@ public enum FilterUnit: Equatable { return "unit.centimeters.accessibilityValue".localized() case .cubicCentimeters: return "unit.cubicCentimeters.accessibilityValue".localized() - case .currency: - return "unit.currency.accessibilityValue".localized() + case .currency(let unit): + if let currencyConfig = Charcoal.currencyConfig { + return currencyConfig.localCurrencyAccessibleLocalized + } else { + return unit + } case .feet: return "unit.feet.accessibilityValue".localized() case .horsePower: diff --git a/Sources/Charcoal/Resources/en.lproj/Localizable.strings b/Sources/Charcoal/Resources/en.lproj/Localizable.strings index 248dedf1..de450db7 100644 --- a/Sources/Charcoal/Resources/en.lproj/Localizable.strings +++ b/Sources/Charcoal/Resources/en.lproj/Localizable.strings @@ -34,7 +34,6 @@ "unit.centimeters.value" = "cm"; "unit.cubicCentimeters.value" = "cm3"; -"unit.currency.value" = "kr"; "unit.feet.value" = "feet"; "unit.horsePower.value" = "hp"; "unit.items.value" = "items"; @@ -47,7 +46,6 @@ "unit.centimeters.accessibilityValue" = "centimetre"; "unit.cubicCentimeters.accessibilityValue" = "cubic centimetre"; -"unit.currency.accessibilityValue" = "crowns"; "unit.feet.accessibilityValue" = "feet"; "unit.horsePower.accessibilityValue" = "horsepower"; "unit.items.accessibilityValue" = "items"; diff --git a/Sources/Charcoal/Resources/fi.lproj/Localizable.strings b/Sources/Charcoal/Resources/fi.lproj/Localizable.strings index a26eeb3b..e0b43d6a 100644 --- a/Sources/Charcoal/Resources/fi.lproj/Localizable.strings +++ b/Sources/Charcoal/Resources/fi.lproj/Localizable.strings @@ -34,7 +34,6 @@ "unit.centimeters.value" = "cm"; "unit.cubicCentimeters.value" = "cm³"; -"unit.currency.value" = "€"; "unit.feet.value" = "jalkaa"; "unit.horsePower.value" = "hv"; "unit.items.value" = "kpl"; @@ -47,7 +46,6 @@ "unit.centimeters.accessibilityValue" = "senttimetriä"; "unit.cubicCentimeters.accessibilityValue" = "kuutiosenttimetriä"; -"unit.currency.accessibilityValue" = "euroa"; "unit.feet.accessibilityValue" = "jalkaa"; "unit.horsePower.accessibilityValue" = "hevosvoimaa"; "unit.items.accessibilityValue" = "tuotetta"; diff --git a/Sources/Charcoal/Resources/nb.lproj/Localizable.strings b/Sources/Charcoal/Resources/nb.lproj/Localizable.strings index e5d1908b..fb5b485c 100644 --- a/Sources/Charcoal/Resources/nb.lproj/Localizable.strings +++ b/Sources/Charcoal/Resources/nb.lproj/Localizable.strings @@ -34,7 +34,6 @@ "unit.centimeters.value" = "cm"; "unit.cubicCentimeters.value" = "ccm"; -"unit.currency.value" = "kr"; "unit.feet.value" = "fot"; "unit.horsePower.value" = "hk"; "unit.items.value" = "stk."; @@ -47,7 +46,6 @@ "unit.centimeters.accessibilityValue" = "centimeter"; "unit.cubicCentimeters.accessibilityValue" = "kubikkcentimeter"; -"unit.currency.accessibilityValue" = "kroner"; "unit.feet.accessibilityValue" = "fot"; "unit.horsePower.accessibilityValue" = "hestekrefter"; "unit.items.accessibilityValue" = "stykk"; diff --git a/UnitTests/Charcoal/Models/FilterUnitTests.swift b/UnitTests/Charcoal/Models/FilterUnitTests.swift index a87ff41f..75f161c8 100644 --- a/UnitTests/Charcoal/Models/FilterUnitTests.swift +++ b/UnitTests/Charcoal/Models/FilterUnitTests.swift @@ -12,10 +12,11 @@ final class FilterUnitTests: XCTestCase { shouldFormatWithSeparator: false ) + private let currencyUnit = FilterUnit.currency(unit: "kr") + func testValue() { XCTAssertEqual(FilterUnit.centimeters.value, "unit.centimeters.value".localized()) XCTAssertEqual(FilterUnit.cubicCentimeters.value, "unit.cubicCentimeters.value".localized()) - XCTAssertEqual(FilterUnit.currency.value, "unit.currency.value".localized()) XCTAssertEqual(FilterUnit.feet.value, "unit.feet.value".localized()) XCTAssertEqual(FilterUnit.horsePower.value, "unit.horsePower.value".localized()) XCTAssertEqual(FilterUnit.items.value, "unit.items.value".localized()) @@ -30,7 +31,6 @@ final class FilterUnitTests: XCTestCase { func testAccessibilityValue() { XCTAssertEqual(FilterUnit.centimeters.accessibilityValue, "unit.centimeters.accessibilityValue".localized()) XCTAssertEqual(FilterUnit.cubicCentimeters.accessibilityValue, "unit.cubicCentimeters.accessibilityValue".localized()) - XCTAssertEqual(FilterUnit.currency.accessibilityValue, "unit.currency.accessibilityValue".localized()) XCTAssertEqual(FilterUnit.feet.accessibilityValue, "unit.feet.accessibilityValue".localized()) XCTAssertEqual(FilterUnit.horsePower.accessibilityValue, "unit.horsePower.accessibilityValue".localized()) XCTAssertEqual(FilterUnit.items.accessibilityValue, "unit.items.accessibilityValue".localized()) @@ -45,7 +45,7 @@ final class FilterUnitTests: XCTestCase { func testShouldFormatWithSeparator() { XCTAssertTrue(FilterUnit.centimeters.shouldFormatWithSeparator) XCTAssertTrue(FilterUnit.cubicCentimeters.shouldFormatWithSeparator) - XCTAssertTrue(FilterUnit.currency.shouldFormatWithSeparator) + XCTAssertTrue(currencyUnit.shouldFormatWithSeparator) XCTAssertTrue(FilterUnit.feet.shouldFormatWithSeparator) XCTAssertTrue(FilterUnit.horsePower.shouldFormatWithSeparator) XCTAssertTrue(FilterUnit.items.shouldFormatWithSeparator) @@ -60,7 +60,7 @@ final class FilterUnitTests: XCTestCase { func testLowerBoundText() { XCTAssertEqual(FilterUnit.centimeters.lowerBoundText, "under".localized()) XCTAssertEqual(FilterUnit.cubicCentimeters.lowerBoundText, "under".localized()) - XCTAssertEqual(FilterUnit.currency.lowerBoundText, "under".localized()) + XCTAssertEqual(currencyUnit.lowerBoundText, "under".localized()) XCTAssertEqual(FilterUnit.feet.lowerBoundText, "under".localized()) XCTAssertEqual(FilterUnit.horsePower.lowerBoundText, "under".localized()) XCTAssertEqual(FilterUnit.items.lowerBoundText, "under".localized()) @@ -75,7 +75,7 @@ final class FilterUnitTests: XCTestCase { func testUpperBoundText() { XCTAssertEqual(FilterUnit.centimeters.upperBoundText, "over".localized()) XCTAssertEqual(FilterUnit.cubicCentimeters.upperBoundText, "over".localized()) - XCTAssertEqual(FilterUnit.currency.upperBoundText, "over".localized()) + XCTAssertEqual(currencyUnit.upperBoundText, "over".localized()) XCTAssertEqual(FilterUnit.feet.upperBoundText, "over".localized()) XCTAssertEqual(FilterUnit.horsePower.upperBoundText, "over".localized()) XCTAssertEqual(FilterUnit.items.upperBoundText, "over".localized()) @@ -90,7 +90,7 @@ final class FilterUnitTests: XCTestCase { func testFromValueText() { XCTAssertEqual(FilterUnit.centimeters.fromValueText, "from".localized()) XCTAssertEqual(FilterUnit.cubicCentimeters.fromValueText, "from".localized()) - XCTAssertEqual(FilterUnit.currency.fromValueText, "from".localized()) + XCTAssertEqual(currencyUnit.fromValueText, "from".localized()) XCTAssertEqual(FilterUnit.feet.fromValueText, "from".localized()) XCTAssertEqual(FilterUnit.horsePower.fromValueText, "from".localized()) XCTAssertEqual(FilterUnit.items.fromValueText, "from".localized()) @@ -105,7 +105,7 @@ final class FilterUnitTests: XCTestCase { func testToValueText() { XCTAssertEqual(FilterUnit.centimeters.toValueText, "upTo".localized()) XCTAssertEqual(FilterUnit.cubicCentimeters.toValueText, "upTo".localized()) - XCTAssertEqual(FilterUnit.currency.toValueText, "upTo".localized()) + XCTAssertEqual(currencyUnit.toValueText, "upTo".localized()) XCTAssertEqual(FilterUnit.feet.toValueText, "upTo".localized()) XCTAssertEqual(FilterUnit.horsePower.toValueText, "upTo".localized()) XCTAssertEqual(FilterUnit.items.toValueText, "upTo".localized()) @@ -116,4 +116,20 @@ final class FilterUnitTests: XCTestCase { XCTAssertEqual(FilterUnit.year.toValueText, "before".localized()) XCTAssertEqual(customUnit.toValueText, "upTo".localized()) } + + func testCurrencyConfigurations() { + let unit = "NOK" + let currencyFilter = FilterUnit.currency(unit: unit) + + // Fallback on unit given by backend when not configured with a local currency + XCTAssertEqual(currencyFilter.value, unit) + XCTAssertEqual(currencyFilter.accessibilityValue, unit) + + let localCurrency = "kr" + let localCurrencyAccessible = "kroner" + Charcoal.configure(localCurrencyLocalized: localCurrency, localCurrencyAccessibleLocalized: localCurrencyAccessible) + + XCTAssertEqual(currencyFilter.value, localCurrency) + XCTAssertEqual(currencyFilter.accessibilityValue, localCurrencyAccessible) + } } diff --git a/UnitTests/Charcoal/Models/RangeFilterConfigurationTests.swift b/UnitTests/Charcoal/Models/RangeFilterConfigurationTests.swift index 81ad7886..8e2078a6 100644 --- a/UnitTests/Charcoal/Models/RangeFilterConfigurationTests.swift +++ b/UnitTests/Charcoal/Models/RangeFilterConfigurationTests.swift @@ -97,7 +97,7 @@ final class RangeFilterConfigurationTests: XCTestCase { ), hasLowerBoundOffset: false, hasUpperBoundOffset: true, - unit: .currency, + unit: .currency(unit: "kr"), usesSmallNumberInputFont: false ) @@ -107,7 +107,7 @@ final class RangeFilterConfigurationTests: XCTestCase { XCTAssertTrue(config.hasUpperBoundOffset) XCTAssertEqual(config.values, [0, 50, 100, 150, 200, 300, 400, 500, 1000, 1500, 2000, 3000, 4000]) XCTAssertEqual(config.referenceValues, [0, 400, 4000]) - XCTAssertEqual(config.unit, .currency) + XCTAssertEqual(config.unit, .currency(unit: "kr")) XCTAssertFalse(config.usesSmallNumberInputFont) } diff --git a/UnitTests/Charcoal/Models/RangerFilterConfiguration+Stubs.swift b/UnitTests/Charcoal/Models/RangerFilterConfiguration+Stubs.swift index e27a6d3e..5df6b46c 100644 --- a/UnitTests/Charcoal/Models/RangerFilterConfiguration+Stubs.swift +++ b/UnitTests/Charcoal/Models/RangerFilterConfiguration+Stubs.swift @@ -13,7 +13,7 @@ extension RangeFilterConfiguration { valueKind: .incremented(10), hasLowerBoundOffset: false, hasUpperBoundOffset: false, - unit: .currency, + unit: .currency(unit: "kr"), usesSmallNumberInputFont: false ) }