Created
May 2, 2022 17:20
-
-
Save abubakrr/857410a840352e4449907b1ca88ceaba to your computer and use it in GitHub Desktop.
How to unit test localizable strings in Swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import XCTest | |
enum Language: String, Codable { | |
case english = "en" | |
case italian = "it" | |
static let supported: [Language] = [.english, .italian] | |
static let defaultLanguage: Language = .english | |
var displayName: String { | |
switch self { | |
case .english: | |
return "English" | |
case .italian: | |
return "Italiano" | |
} | |
} | |
} | |
final class LocalizationTests: XCTestCase { | |
func test_supportedLanguages_haveNonNilBundle() { | |
for language in Language.supported { | |
XCTAssertNotNil(getBundle(for: language)) | |
} | |
} | |
func test_supportedLanguages_haveNonNilDictionary() { | |
for language in Language.supported { | |
XCTAssertNotNil(getLocalizedDictionary(for: language), "Localizable.strings file not found for \(language.displayName) language") | |
} | |
} | |
func test_translatedWords_basedOnDefaultLocale() { | |
let defaultLanguage = Language.defaultLanguage | |
let defaultLocalizedDictionary = getLocalizedDictionary(for: defaultLanguage)! | |
let supportedLanguagesExceptDefault = Language.supported.filter { $0 != defaultLanguage } | |
for language in supportedLanguagesExceptDefault { | |
let localizedDictionary = getLocalizedDictionary(for: language)! | |
for (key, defaultTranslation) in defaultLocalizedDictionary { | |
if let translation = localizedDictionary[key] { | |
if translation == defaultTranslation { | |
debugPrint("⚠️Warning: '\(key)' has identical translations at \(defaultLanguage.displayName) and \(language.displayName)") | |
} | |
} else { | |
XCTFail("'\(key)' is not translated into \(language.displayName)") | |
} | |
} | |
} | |
} | |
} | |
// MARK: - Helpers | |
extension LocalizationTests { | |
private func getLocalizedDictionary(for language: Language) -> [String: String]? { | |
guard let bundle = getBundle(for: language) else { | |
return nil | |
} | |
return getLocalizableDictionary(from: bundle) | |
} | |
private func getBundle(for language: Language) -> Bundle? { | |
guard let path = Bundle.main.path(forResource: language.rawValue, ofType: "lproj") else { | |
return nil | |
} | |
return Bundle(path: path) | |
} | |
private func getLocalizableDictionary(from bundle: Bundle) -> [String: String]? { | |
guard let path = bundle.path(forResource: "Localizable", ofType: "strings") else { | |
return nil | |
} | |
return NSDictionary(contentsOfFile: path)?.reduce(into: [String: String](), { $0[$1.key as! String] = $1.value as? String}) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment