From cd2aca90e0290db44e02368ecf7291be307f7ef4 Mon Sep 17 00:00:00 2001 From: Tomasz Szulc Date: Fri, 31 Jul 2015 15:17:36 +0200 Subject: [PATCH] Add tests for LoadedTranslationsProcessor --- Swifternalization.xcodeproj/project.pbxproj | 50 ++++--- Swifternalization/JSONFileLoader.swift | 36 ++++- Swifternalization/LengthVariationType.swift | 4 +- .../LoadedTranslationsProcessor.swift | 26 ++-- .../SharedExpressionLoader.swift | 13 +- Swifternalization/TranslationsLoader.swift | 48 ++++--- SwifternalizationTests/ExpressionJSONs.swift | 28 ++++ .../JSONFileLoaderTests.swift | 36 ++++- .../LoadedTranslationsProcessorTests.swift | 125 ++++++++++++++++++ .../SharedExpressionsLoaderTests.swift | 16 +-- .../SharedExpressionsProcessorTests.swift | 13 +- SwifternalizationTests/TranslationJSONs.swift | 56 ++++++++ .../TranslationsLoaderTests.swift | 16 +-- 13 files changed, 356 insertions(+), 111 deletions(-) create mode 100644 SwifternalizationTests/ExpressionJSONs.swift create mode 100644 SwifternalizationTests/LoadedTranslationsProcessorTests.swift create mode 100644 SwifternalizationTests/TranslationJSONs.swift diff --git a/Swifternalization.xcodeproj/project.pbxproj b/Swifternalization.xcodeproj/project.pbxproj index 0049185..4271158 100644 --- a/Swifternalization.xcodeproj/project.pbxproj +++ b/Swifternalization.xcodeproj/project.pbxproj @@ -76,9 +76,12 @@ 6D62834B1B3F622A00E65FCD /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 6D6283491B3F622A00E65FCD /* Localizable.strings */; }; 6D62834E1B3F628000E65FCD /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 6D62834D1B3F628000E65FCD /* Main.storyboard */; }; 6D6283501B3F62B100E65FCD /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 6D62834F1B3F62B100E65FCD /* LaunchScreen.xib */; }; + 6D62F9FC1B6B808400596A7C /* ExpressionJSONs.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D62F9FB1B6B808400596A7C /* ExpressionJSONs.swift */; }; + 6D62F9FE1B6B824300596A7C /* TranslationJSONs.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D62F9FD1B6B824300596A7C /* TranslationJSONs.swift */; }; 6D6464821B40106C00C46C6D /* LocalizableFilesLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D6464811B40106C00C46C6D /* LocalizableFilesLoader.swift */; }; 6D6464841B40146100C46C6D /* KeyValueType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D6464831B40146100C46C6D /* KeyValueType.swift */; }; 6D6464851B40146600C46C6D /* KeyValueType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D6464831B40146100C46C6D /* KeyValueType.swift */; }; + 6D75E6D41B6B6CFE00B370DC /* LoadedTranslationsProcessorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D75E6D31B6B6CFE00B370DC /* LoadedTranslationsProcessorTests.swift */; }; 6DB3CC751B5EBDA600A1220F /* CountryCode.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DB3CC651B5EBDA600A1220F /* CountryCode.swift */; }; 6DB3CC761B5EBDA600A1220F /* ExpressionType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DB3CC661B5EBDA600A1220F /* ExpressionType.swift */; }; 6DB3CC771B5EBDA600A1220F /* SharedExpressionLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DB3CC671B5EBDA600A1220F /* SharedExpressionLoader.swift */; }; @@ -176,8 +179,11 @@ 6D62834C1B3F623200E65FCD /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/Localizable.strings; sourceTree = ""; }; 6D62834D1B3F628000E65FCD /* Main.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Main.storyboard; sourceTree = ""; }; 6D62834F1B3F62B100E65FCD /* LaunchScreen.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = LaunchScreen.xib; sourceTree = ""; }; + 6D62F9FB1B6B808400596A7C /* ExpressionJSONs.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ExpressionJSONs.swift; sourceTree = ""; }; + 6D62F9FD1B6B824300596A7C /* TranslationJSONs.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TranslationJSONs.swift; sourceTree = ""; }; 6D6464811B40106C00C46C6D /* LocalizableFilesLoader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LocalizableFilesLoader.swift; sourceTree = ""; }; 6D6464831B40146100C46C6D /* KeyValueType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KeyValueType.swift; sourceTree = ""; }; + 6D75E6D31B6B6CFE00B370DC /* LoadedTranslationsProcessorTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoadedTranslationsProcessorTests.swift; sourceTree = ""; }; 6DB3CC651B5EBDA600A1220F /* CountryCode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CountryCode.swift; sourceTree = ""; }; 6DB3CC661B5EBDA600A1220F /* ExpressionType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ExpressionType.swift; sourceTree = ""; }; 6DB3CC671B5EBDA600A1220F /* SharedExpressionLoader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SharedExpressionLoader.swift; sourceTree = ""; }; @@ -233,8 +239,10 @@ 6D140F451B56D04300359143 /* Helpers */ = { isa = PBXGroup; children = ( - 6D140F431B56D03D00359143 /* RandomNumbers.swift */, + 6D62F9FB1B6B808400596A7C /* ExpressionJSONs.swift */, 6DD3B94A1B5ED65A00C79EAC /* NSBundle+TestExtension.swift */, + 6D140F431B56D03D00359143 /* RandomNumbers.swift */, + 6D62F9FD1B6B824300596A7C /* TranslationJSONs.swift */, ); name = Helpers; sourceTree = ""; @@ -288,7 +296,6 @@ 6DB3CC8E1B5EC27600A1220F /* Enums */, 6DB3CC8D1B5EC1FF00A1220F /* Matchers and Parsers */, 6DB3CC8A1B5EC19400A1220F /* Protocols */, - 6DB3CC8B1B5EC1A400A1220F /* Typealiases */, 6D6282911B3F04C800E65FCD /* Expression.swift */, 6D6464811B40106C00C46C6D /* LocalizableFilesLoader.swift */, 6D6282991B3F17CA00E65FCD /* Regex.swift */, @@ -313,9 +320,8 @@ 6D5004571B3EF91600A54B36 /* SwifternalizationTests */ = { isa = PBXGroup; children = ( + 6D75E6D21B6B6CBC00B370DC /* Next */, 6D140F451B56D04300359143 /* Helpers */, - 6DD3B93F1B5ED37A00C79EAC /* Loaders */, - 6D5BA6021B6537BE000D7E49 /* Processors */, 6D6282971B3F13C300E65FCD /* ExpressionTests.swift */, 6D6282BE1B3F42CA00E65FCD /* InequalityExpressionMatcherTests.swift */, 6D6282A81B3F25DC00E65FCD /* InequalityExpressionParserTests.swift */, @@ -345,14 +351,6 @@ name = "Supporting Files"; sourceTree = ""; }; - 6D5BA6021B6537BE000D7E49 /* Processors */ = { - isa = PBXGroup; - children = ( - 6D5BA6031B6537D5000D7E49 /* SharedExpressionsProcessorTests.swift */, - ); - name = Processors; - sourceTree = ""; - }; 6D6283261B3F613D00E65FCD /* DemoOrdering */ = { isa = PBXGroup; children = ( @@ -384,19 +382,24 @@ name = Resources; sourceTree = ""; }; - 6DB3CC8A1B5EC19400A1220F /* Protocols */ = { + 6D75E6D21B6B6CBC00B370DC /* Next */ = { isa = PBXGroup; children = ( - 6D6464831B40146100C46C6D /* KeyValueType.swift */, + 6DD3B9401B5ED38B00C79EAC /* JSONFileLoaderTests.swift */, + 6D75E6D31B6B6CFE00B370DC /* LoadedTranslationsProcessorTests.swift */, + 6DD3B9431B5ED55500C79EAC /* SharedExpressionsLoaderTests.swift */, + 6D5BA6031B6537D5000D7E49 /* SharedExpressionsProcessorTests.swift */, + 6D5BA5EF1B651796000D7E49 /* TranslationsLoaderTests.swift */, ); - name = Protocols; + name = Next; sourceTree = ""; }; - 6DB3CC8B1B5EC1A400A1220F /* Typealiases */ = { + 6DB3CC8A1B5EC19400A1220F /* Protocols */ = { isa = PBXGroup; children = ( + 6D6464831B40146100C46C6D /* KeyValueType.swift */, ); - name = Typealiases; + name = Protocols; sourceTree = ""; }; 6DB3CC8D1B5EC1FF00A1220F /* Matchers and Parsers */ = { @@ -444,16 +447,6 @@ name = "Localizable Files"; sourceTree = ""; }; - 6DD3B93F1B5ED37A00C79EAC /* Loaders */ = { - isa = PBXGroup; - children = ( - 6DD3B9401B5ED38B00C79EAC /* JSONFileLoaderTests.swift */, - 6DD3B9431B5ED55500C79EAC /* SharedExpressionsLoaderTests.swift */, - 6D5BA5EF1B651796000D7E49 /* TranslationsLoaderTests.swift */, - ); - name = Loaders; - sourceTree = ""; - }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ @@ -653,6 +646,7 @@ 6DD3B9451B5ED58A00C79EAC /* SharedExpressionLoader.swift in Sources */, 6D6282981B3F13C300E65FCD /* ExpressionTests.swift in Sources */, 6DBB6C661B40369A002F39A3 /* SharedExpressionsConfigurator.swift in Sources */, + 6D75E6D41B6B6CFE00B370DC /* LoadedTranslationsProcessorTests.swift in Sources */, 6D50045B1B3EF91600A54B36 /* SwifternalizationTests.swift in Sources */, 6D6282A61B3F25B900E65FCD /* InequalityExpressionParser.swift in Sources */, 6D6282B81B3F3E2200E65FCD /* InequalitySign.swift in Sources */, @@ -668,6 +662,7 @@ 6D5BA6011B65271A000D7E49 /* SharedExpression.swift in Sources */, 6D4C4EC51B6AD01300B7839A /* LoadedTranslationsProcessor.swift in Sources */, 6DBB6C6A1B40412D002F39A3 /* InternalPattern.swift in Sources */, + 6D62F9FC1B6B808400596A7C /* ExpressionJSONs.swift in Sources */, 6D4C4EB91B6AB6EF00B7839A /* LoadedTranslationType.swift in Sources */, 6DD3B9411B5ED38B00C79EAC /* JSONFileLoaderTests.swift in Sources */, 6D4C4EB01B6AA54800B7839A /* LoadedTranslation.swift in Sources */, @@ -697,6 +692,7 @@ 6D5BA5F11B6517A6000D7E49 /* TranslationsLoader.swift in Sources */, 6D6282BB1B3F41DB00E65FCD /* InequalityExtendedExpressionMatcher.swift in Sources */, 6DBB6C511B401B7C002F39A3 /* LocalizableFilesLoader.swift in Sources */, + 6D62F9FE1B6B824300596A7C /* TranslationJSONs.swift in Sources */, 6DBB6C6C1B40431D002F39A3 /* LocalizableFilesLoaderTests.swift in Sources */, 6DBB6C961B4076E8002F39A3 /* SharedBaseExpressionTests.swift in Sources */, 6D62829B1B3F17FE00E65FCD /* Regex.swift in Sources */, diff --git a/Swifternalization/JSONFileLoader.swift b/Swifternalization/JSONFileLoader.swift index b879214..c310847 100644 --- a/Swifternalization/JSONFileLoader.swift +++ b/Swifternalization/JSONFileLoader.swift @@ -1,10 +1,36 @@ import Foundation +/** +Represents json content. +*/ +typealias JSONDictionary = Dictionary + /** Simple JSON loader. */ -class JSONFileLoader { - typealias JSONDictionary = Dictionary +final class JSONFileLoader { + + /** + Loads translations dict for specified language. + + :param: countryCode A country code. + :param: bundle A bundle when file is located. + :returns: Returns json of file or nil if cannot load a file. + */ + class func loadTranslations(countryCode: CountryCode, bundle: NSBundle = NSBundle.mainBundle()) -> JSONDictionary? { + return self.load(countryCode, bundle: bundle) + } + + /** + Loads expressions dict for specified language. + + :param: countryCode A country code. + :param: bundle A bundle when file is located. + :returns: dictionary with expressions or nil. + */ + class func loadExpressions(countryCode: CountryCode, bundle: NSBundle = NSBundle.mainBundle()) -> Dictionary? { + return self.load("expressions", bundle: bundle)?[countryCode] as? Dictionary + } /** Loads content of a file with specified name, type and bundle. @@ -14,7 +40,7 @@ class JSONFileLoader { :param: bundle A bundle when file is located. :returns: JSON or nil. */ - final class func load(fileName: String, bundle: NSBundle = NSBundle.mainBundle()) -> JSONDictionary? { + private class func load(fileName: String, bundle: NSBundle = NSBundle.mainBundle()) -> JSONDictionary? { if let fileURL = bundle.URLForResource(fileName, withExtension: "json") { return load(fileURL) } @@ -33,9 +59,9 @@ class JSONFileLoader { var error: NSError? if let dictionary = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.allZeros, error: &error) as? JSONDictionary { return dictionary - } else { - print("Cannot parse JSON. It might be broken.") } + print("Cannot parse JSON. It might be broken.") + return nil } print("Cannot load content of file.") return nil diff --git a/Swifternalization/LengthVariationType.swift b/Swifternalization/LengthVariationType.swift index ffd3ffc..14bc186 100644 --- a/Swifternalization/LengthVariationType.swift +++ b/Swifternalization/LengthVariationType.swift @@ -1,6 +1,8 @@ import Foundation -/// Represents length variation. +/** +Represents length variation. +*/ protocol LengthVariationType { /// Length of a screen. var length: Int {get} diff --git a/Swifternalization/LoadedTranslationsProcessor.swift b/Swifternalization/LoadedTranslationsProcessor.swift index fb2b555..3d632f1 100644 --- a/Swifternalization/LoadedTranslationsProcessor.swift +++ b/Swifternalization/LoadedTranslationsProcessor.swift @@ -27,7 +27,7 @@ class LoadedTranslationsProcessor { expressions as well as built-in ones. Translations are processed in shared expressions processor. */ - class func processTrnslations(baseTranslations: [LoadedTranslation], preferedLanguageTranslations: [LoadedTranslation], sharedExpressions: [SharedExpression]) -> [TranslationType] { + class func processTranslations(baseTranslations: [LoadedTranslation], preferedLanguageTranslations: [LoadedTranslation], sharedExpressions: [SharedExpression]) -> [TranslationType] { // Find those base translations that are not contained in prefered // language translations. @@ -74,19 +74,23 @@ class LoadedTranslationsProcessor { case .WithExpressionsAndLengthVariations: // The most advanced translation type. It contains expressions - // that contain length variations. THe job done here is similar - // to the one in .WithExpressions and .WithLengthVariations - // cases. key is filtered in shared expressions to get one of - // shared expressions and then method builds array of variations. + // that contain length variations or just simple expressions. + // THe job done here is similar to the one in .WithExpressions + // and .WithLengthVariations cases. key is filtered in shared + // expressions to get one of shared expressions and then method + // builds array of variations. var expressions = [ExpressionType]() - for (key, value) in $0.content as! Dictionary> { + for (key, value) in $0.content { let pattern = sharedExpressions.filter({$0.identifier == key}).first?.pattern ?? key - - var lengthVariations = [LengthVariation]() - for (lvKey, lvValue) in value as Dictionary { - lengthVariations.append(LengthVariation(length: self.parseNumberFromLengthVariation(lvKey), value: lvValue)) + if value is Dictionary { + var lengthVariations = [LengthVariation]() + for (lvKey, lvValue) in value as! Dictionary { + lengthVariations.append(LengthVariation(length: self.parseNumberFromLengthVariation(lvKey), value: lvValue)) + } + expressions.append(LengthVariationExpression(pattern: pattern, variations: lengthVariations)) + } else if value is String { + expressions.append(SimpleExpression(pattern:pattern, localizedValue: value as! String)) } - expressions.append(LengthVariationExpression(pattern: pattern, variations: lengthVariations)) } return TranslationWithExpressions(key: $0.key, expressions: expressions) } diff --git a/Swifternalization/SharedExpressionLoader.swift b/Swifternalization/SharedExpressionLoader.swift index d248a49..4ff9216 100644 --- a/Swifternalization/SharedExpressionLoader.swift +++ b/Swifternalization/SharedExpressionLoader.swift @@ -3,7 +3,7 @@ import Foundation /** Used to load content from `expressions.json` file for specified language. */ -final class SharedExpressionsLoader: JSONFileLoader { +final class SharedExpressionsLoader { /** Loads expressions for specified language. @@ -11,15 +11,10 @@ final class SharedExpressionsLoader: JSONFileLoader { :param: countryCode A country code :returns: array of loaded expressions. */ - class func loadExpressions(countryCode: CountryCode, bundle: NSBundle) -> [SharedExpression] { + class func loadExpressions(json: Dictionary) -> [SharedExpression] { var expressions = [SharedExpression]() - if let json = self.load("expressions", bundle: bundle), - let expressionsDict = json[countryCode] as? Dictionary { - for (identifier, pattern) in expressionsDict { - expressions.append(SharedExpression(identifier: identifier, pattern: pattern)) - } - } else { - println("expressions.json file structure is incorrect.") + for (identifier, pattern) in json { + expressions.append(SharedExpression(identifier: identifier, pattern: pattern)) } return expressions } diff --git a/Swifternalization/TranslationsLoader.swift b/Swifternalization/TranslationsLoader.swift index f7f2e58..a68fd34 100644 --- a/Swifternalization/TranslationsLoader.swift +++ b/Swifternalization/TranslationsLoader.swift @@ -1,30 +1,28 @@ import Foundation /** -Class that loads translations from a file. +Class that gets dictionary of translations and turn it into `LoadedTranslation`s. */ -final class TranslationsLoader: JSONFileLoader { +final class TranslationsLoader { /** - Loads content from file with name equal to passed country code in a bundle. + Converts dictionary into array of `LoadedTranslation`s. - :params: countryCode A country code. - :params: bundle A bundle when file is placed. - :returns: `LoadedTranslation` objects from specified file. + :params: dictionary A dictionary with content of file which contains + translations. + :returns: Array of `LoadedTranslation` objects from specified file. */ - class func loadTranslations(countryCode: CountryCode, bundle: NSBundle = NSBundle.mainBundle()) -> [LoadedTranslation] { + class func loadTranslations(json: Dictionary) -> [LoadedTranslation] { var loadedTranslations = [LoadedTranslation]() - if let json = self.load(countryCode, bundle: bundle) { - for (key, value) in json { - if value is String { - loadedTranslations.append(LoadedTranslation(type: .Simple, key: key, content: [key: value])) + for (key, value) in json { + if value is String { + loadedTranslations.append(LoadedTranslation(type: .Simple, key: key, content: [key: value])) + } else { + let dictionary = value as! JSONDictionary + if let type = detectElementType(dictionary) { + loadedTranslations.append(LoadedTranslation(type: type, key: key, content: dictionary)) } else { - let dictionary = value as! JSONDictionary - if let type = detectElementType(dictionary) { - loadedTranslations.append(LoadedTranslation(type: type, key: key, content: dictionary)) - } else { - println("Translation type is not supported for: \(dictionary)") - } + println("Translation type is not supported for: \(dictionary)") } } } @@ -42,10 +40,22 @@ final class TranslationsLoader: JSONFileLoader { typealias DictWithStrings = Dictionary typealias DictWithDicts = Dictionary - if element is DictWithStrings, let key = element.keys.first { + var dicts = 0 + var strings = 0 + + for (key, value) in element { + if value is String { + strings++ + } else if value is Dictionary { + dicts++ + } + } + + if strings > 0 && dicts == 0 { + let key = element.keys.first! let toIndex = advance(key.startIndex, 1) return key.substringToIndex(toIndex) == "@" ? .WithLengthVariations : .WithExpressions - } else if element is DictWithDicts { + } else if strings >= 0 && dicts > 0 { return .WithExpressionsAndLengthVariations } diff --git a/SwifternalizationTests/ExpressionJSONs.swift b/SwifternalizationTests/ExpressionJSONs.swift new file mode 100644 index 0000000..926945c --- /dev/null +++ b/SwifternalizationTests/ExpressionJSONs.swift @@ -0,0 +1,28 @@ +// +// ExpressionJSONs.swift +// Swifternalization +// +// Created by Tomasz Szulc on 31/07/15. +// Copyright (c) 2015 Tomasz Szulc. All rights reserved. +// + +import Foundation + +class ExpressionJSONs { + + class func base() -> Dictionary { + return [ + "key1": "val1", + "key2": "val2", + "key3": "val3" + ] + } + + class func en() -> Dictionary { + return [ + "key3": "val3", + "key4": "val4", + "key5": "val5" + ] + } +} \ No newline at end of file diff --git a/SwifternalizationTests/JSONFileLoaderTests.swift b/SwifternalizationTests/JSONFileLoaderTests.swift index 0d308ba..fbd61b9 100644 --- a/SwifternalizationTests/JSONFileLoaderTests.swift +++ b/SwifternalizationTests/JSONFileLoaderTests.swift @@ -10,14 +10,38 @@ import UIKit import XCTest class JSONFileLoaderTests: XCTestCase { + + // Expressions + func loadExpressions(cc: CountryCode) -> Dictionary? { + return JSONFileLoader.loadExpressions(cc, bundle: NSBundle.testBundle()) + } + + func testShouldLoadBaseExpressions() { + XCTAssertNotNil(loadExpressions("base"), "") + } + + func testShouldLoadPLExpressions() { + XCTAssertNotNil(loadExpressions("pl"), "") + } + + func testShouldNotLoadDEExpressions() { + XCTAssertNil(loadExpressions("de"), "") + } + + // Translations + func loadTranslations(cc: CountryCode) -> JSONDictionary? { + return JSONFileLoader.loadTranslations(cc, bundle: NSBundle.testBundle()) + } - func testJSONShouldBeLoaded() { - let content = JSONFileLoader.load("base", bundle: NSBundle.testBundle()) - XCTAssertNotNil(content!, "") + func testShouldLoadBaseTranslations() { + XCTAssertNotNil(loadTranslations("base"), "") + } + + func testShouldLoadPLTranslations() { + XCTAssertNotNil(loadTranslations("pl"), "") } - func testFileShouldNotBeLoaded() { - let content = JSONFileLoader.load("not-existing", bundle: NSBundle.testBundle()) - XCTAssertNil(content, "") + func testShouldNotLoadDETranslations() { + XCTAssertNil(loadTranslations("de"), "") } } diff --git a/SwifternalizationTests/LoadedTranslationsProcessorTests.swift b/SwifternalizationTests/LoadedTranslationsProcessorTests.swift new file mode 100644 index 0000000..84e4fe9 --- /dev/null +++ b/SwifternalizationTests/LoadedTranslationsProcessorTests.swift @@ -0,0 +1,125 @@ +// +// LoadedTranslationsProcessorTests.swift +// Swifternalization +// +// Created by Tomasz Szulc on 31/07/15. +// Copyright (c) 2015 Tomasz Szulc. All rights reserved. +// + +import UIKit +import XCTest + +class LoadedTranslationsProcessorTests: XCTestCase { + + private func _baseExpressions() -> Dictionary { + return [ + "e1": "ie:x=1", + "e2": "ie:x=2" + ] + } + + private func _enExpressions() -> Dictionary { + return [ + "e1": "ie:x=1", + "e2": "ie:x=2", + "e3": "ie:x=3", + "e4": "ie:x=4" + ] + } + + private func _baseTranslations() -> Dictionary { + return [ + "k1": "v1", + "k2": "v2", + "k3": "v3", + "k4": "v4" + ] + } + + private func _enTranslations() -> Dictionary { + return [ + "k1": "v1", + "k2": [ + "@100": "v2-1", + "@200": "v2-2" + ], + "k3": [ + "e1": "v3-1", + "e2": "v3-2" + ], + "k4": [ + "e3": [ + "@100": "v4-1", + "@200": "v4-2" + ], + + "e4": [ + "@100": "v4-3", + "@300": "v4-4" + ], + + "e2": "v4-5" + ] + ] + } + + func testShouldProcessTranslations() { + let baseExpressions = SharedExpressionsLoader.loadExpressions(_baseExpressions()) + let enExpressions = SharedExpressionsLoader.loadExpressions(_enExpressions()) + let expressions = SharedExpressionsProcessor.processSharedExpression("en", preferedLanguageExpressions: enExpressions, baseLanguageExpressions: baseExpressions) + + let baseTranslations = TranslationsLoader.loadTranslations(_baseTranslations()) + let enTranslations = TranslationsLoader.loadTranslations(_enTranslations()) + var translations = LoadedTranslationsProcessor.processTranslations(baseTranslations, preferedLanguageTranslations: enTranslations, sharedExpressions: expressions) + + translations.sort({$0.key < $1.key}) + + XCTAssertEqual(translations.count, 4, "") + + /** + Check if there is k1 translation + */ + XCTAssertEqual(translations[0].key, "k1", "") + + /** + Check content of k2 translation + */ + let k2Translation = translations[1] as! TranslationWithExpressions + XCTAssertEqual(k2Translation.key, "k2", "") + XCTAssertEqual(k2Translation.expressions.count, 1, "") + let k2Expression = k2Translation.expressions[0] as! LengthVariationExpression + XCTAssertEqual(k2Expression.variations.count, 2, "") + + /** + Check content of k3 translation + */ + let k3Translation = translations[2] as! TranslationWithExpressions + XCTAssertEqual(k3Translation.key, "k3", "") + XCTAssertEqual(k3Translation.expressions.count, 2, "") + + // Get patterns of expressions + var k3ExpressionPatterns: [String] = k3Translation.expressions.map({ $0.pattern }) + k3ExpressionPatterns.sort({$0 < $1}) + + var k3ExpressionsToMatch: [String] = [_enExpressions()["e1"]!, _enExpressions()["e2"]!] + k3ExpressionsToMatch.sort({$0 < $1}) + + XCTAssertEqual(k3ExpressionPatterns, k3ExpressionsToMatch, "") + + /** + Check content of k4 translation + */ + let k4Translation = translations[3] as! TranslationWithExpressions + XCTAssertEqual(k4Translation.key, "k4", "") + XCTAssertEqual(k4Translation.expressions.count, 3, "") + + // Get patterns of expressions + var k4ExpressionPatterns: [String] = k4Translation.expressions.map({ $0.pattern }) + k4ExpressionPatterns.sort({$0 < $1}) + + var k4ExpressionsToMatch: [String] = [_enExpressions()["e2"]!, _enExpressions()["e3"]!, _enExpressions()["e4"]!] + k4ExpressionsToMatch.sort({$0 < $1}) + + XCTAssertEqual(k4ExpressionPatterns, k4ExpressionsToMatch, "") + } +} diff --git a/SwifternalizationTests/SharedExpressionsLoaderTests.swift b/SwifternalizationTests/SharedExpressionsLoaderTests.swift index 80e06cb..91ddaea 100644 --- a/SwifternalizationTests/SharedExpressionsLoaderTests.swift +++ b/SwifternalizationTests/SharedExpressionsLoaderTests.swift @@ -11,18 +11,8 @@ import XCTest class SharedExpressionsLoaderTests: XCTestCase { - func testShouldLoadBase() { - let content = SharedExpressionsLoader.loadExpressions("base", bundle: NSBundle.testBundle()) - XCTAssertTrue(content.count > 0, "") - } - - func testShouldLoadPL() { - let content = SharedExpressionsLoader.loadExpressions("pl", bundle: NSBundle.testBundle()) - XCTAssertTrue(content.count > 0, "") - } - - func testShouldNotLoadDE() { - let content = SharedExpressionsLoader.loadExpressions("de", bundle: NSBundle.testBundle()) - XCTAssertFalse(content.count > 0, "") + func testShouldLoadExpressions() { + let expressions = SharedExpressionsLoader.loadExpressions(ExpressionJSONs.base()) + XCTAssertEqual(expressions.count, 3, "") } } diff --git a/SwifternalizationTests/SharedExpressionsProcessorTests.swift b/SwifternalizationTests/SharedExpressionsProcessorTests.swift index 90e96ea..4793c09 100644 --- a/SwifternalizationTests/SharedExpressionsProcessorTests.swift +++ b/SwifternalizationTests/SharedExpressionsProcessorTests.swift @@ -10,13 +10,12 @@ import Foundation import XCTest class SharedExpressionsProcessorTests: XCTestCase { - - func testThatAllExpressionsShouldBeLoadedCorreclty() { - let baseExpressions = SharedExpressionsLoader.loadExpressions("base", bundle: NSBundle.testBundle()) - let preferedExpressions = SharedExpressionsLoader.loadExpressions("pl", bundle: NSBundle.testBundle()) - - let sharedExpressions = SharedExpressionsProcessor.processSharedExpression("pl", preferedLanguageExpressions: preferedExpressions, baseLanguageExpressions: baseExpressions) + + func testShouldProcessExpressions() { + let base = SharedExpressionsLoader.loadExpressions(ExpressionJSONs.base()) + let en = SharedExpressionsLoader.loadExpressions(ExpressionJSONs.en()) - XCTAssertEqual(sharedExpressions.count, 8, "") + let shared = SharedExpressionsProcessor.processSharedExpression("en", preferedLanguageExpressions: base, baseLanguageExpressions: en) + XCTAssertEqual(shared.count, 9, "") } } diff --git a/SwifternalizationTests/TranslationJSONs.swift b/SwifternalizationTests/TranslationJSONs.swift new file mode 100644 index 0000000..3ce4744 --- /dev/null +++ b/SwifternalizationTests/TranslationJSONs.swift @@ -0,0 +1,56 @@ +// +// TranslationJSONs.swift +// Swifternalization +// +// Created by Tomasz Szulc on 31/07/15. +// Copyright (c) 2015 Tomasz Szulc. All rights reserved. +// + +import Foundation + +class TranslationJSONs { + + class func base() -> Dictionary { + return [ + "key-1": "value-1", + "key-2": [ + "@100": "value-2-1", + "@200": "value-2-2", + "@300": "value-2-3" + ], + "key-3": [ + "key-3-1": [ + "@100": "value-3-1-1", + "@200": "value-3-1-2" + ], + + "key-3-2": [ + "@100": "value-3-2-1", + "@200": "value-3-2-2" + ] + ] + ] + } + + class func en() -> Dictionary { + return [ + "key-1": "en-value-1", + "key-2": [ + "@100": "en-value-2-1", + "@200": "en-value-2-2", + "@300": "en-value-2-3" + ], + "key-4": [ + "key-4-1": [ + "@100": "value-4-1-1", + "@200": "value-$-1-2" + ], + + "key-4-2": [ + "@100": "value-4-2-1", + "@200": "value-4-2-2" + ] + ] + ] + } +} \ No newline at end of file diff --git a/SwifternalizationTests/TranslationsLoaderTests.swift b/SwifternalizationTests/TranslationsLoaderTests.swift index e15dc4c..b1114f3 100644 --- a/SwifternalizationTests/TranslationsLoaderTests.swift +++ b/SwifternalizationTests/TranslationsLoaderTests.swift @@ -11,18 +11,8 @@ import XCTest class TranslationsLoaderTests: XCTestCase { - func testShouldLoadBase() { - let content = TranslationsLoader.loadTranslations("pl", bundle: NSBundle.testBundle()) - XCTAssertTrue(content.count > 0, "") - } - - func testShouldLoadPL() { - let content = TranslationsLoader.loadTranslations("base", bundle: NSBundle.testBundle()) - XCTAssertTrue(content.count > 0, "") - } - - func testShouldNotLoadDE() { - let content = TranslationsLoader.loadTranslations("de", bundle: NSBundle.testBundle()) - XCTAssertFalse(content.count > 0, "") + func testShouldLoadTranslations() { + let translations = TranslationsLoader.loadTranslations(TranslationJSONs.base()) + XCTAssertEqual(translations.count, 3, "") } }