diff --git a/Sources/VoidBar/Services/Translator.swift b/Sources/VoidBar/Services/Translator.swift index bb63ded..d3000db 100644 --- a/Sources/VoidBar/Services/Translator.swift +++ b/Sources/VoidBar/Services/Translator.swift @@ -8,7 +8,7 @@ import Translation /// holding the result. `TranslatePane` supplies the session. @MainActor final class Translator: ObservableObject { - static let russian = Locale.Language(identifier: "ru") + static let ukrainian = Locale.Language(identifier: "uk") static let english = Locale.Language(identifier: "en") /// Both ends are always named. Leaving the source to the framework looks @@ -40,7 +40,7 @@ final class Translator: ObservableObject { var trimmed: String { input.trimmingCharacters(in: .whitespacesAndNewlines) } var route: Route { Self.route(for: trimmed) } - /// Russian goes out to English, everything else comes in to Russian. + /// Ukrainian goes out to English, everything else comes in to Ukrainian. /// /// Decided by script rather than by language detection: a single word is /// far too short to identify reliably, and "привет" comes back as Bulgarian @@ -48,8 +48,8 @@ final class Translator: ObservableObject { static func route(for text: String) -> Route { let cyrillic = text.unicodeScalars.contains { (0x0400...0x04FF).contains($0.value) } return cyrillic - ? Route(source: russian, target: english) - : Route(source: english, target: russian) + ? Route(source: ukrainian, target: english) + : Route(source: english, target: ukrainian) } func retry() { @@ -108,7 +108,7 @@ final class Translator: ObservableObject { pasteboard.setString(output, forType: .string) } - /// "Русский", "English" — for the column headers. Named in the language the + /// "Українська", "English" — for the column headers. Named in the language the /// panel itself is in, not in the system's: those two can differ, and a /// column headed in one language above a button worded in another reads as /// a mistake. @@ -120,7 +120,7 @@ final class Translator: ObservableObject { return name.prefix(1).uppercased() + name.dropFirst() } - /// Short code for the header badge — "EN → RU" reads at a glance where a + /// Short code for the header badge — "EN → UK" reads at a glance where a /// spelled-out name would not fit in the strip. static func code(_ language: Locale.Language) -> String { language.languageCode?.identifier.uppercased() ?? "?" diff --git a/Tests/VoidBarTests/TranslatorTests.swift b/Tests/VoidBarTests/TranslatorTests.swift new file mode 100644 index 0000000..9e62b65 --- /dev/null +++ b/Tests/VoidBarTests/TranslatorTests.swift @@ -0,0 +1,19 @@ +import XCTest +@testable import VoidBar + +@MainActor +final class TranslatorTests: XCTestCase { + func testEnglishRoutesToUkrainian() { + let route = Translator.route(for: "Hello, world") + + XCTAssertEqual(route.source.languageCode?.identifier, "en") + XCTAssertEqual(route.target.languageCode?.identifier, "uk") + } + + func testUkrainianRoutesToEnglish() { + let route = Translator.route(for: "Привіт, світе") + + XCTAssertEqual(route.source.languageCode?.identifier, "uk") + XCTAssertEqual(route.target.languageCode?.identifier, "en") + } +} diff --git a/docs/assets/hover-demo.gif b/docs/assets/hover-demo.gif index 563095b..133f92f 100644 Binary files a/docs/assets/hover-demo.gif and b/docs/assets/hover-demo.gif differ