xcstrings #10
| @@ -1,6 +1,6 @@ | |||||||
| // | // | ||||||
| //  StringsFileGenerator.swift | //  StringsFileGenerator.swift | ||||||
| //   | // | ||||||
| // | // | ||||||
| //  Created by Thibaut Schmitt on 04/01/2022. | //  Created by Thibaut Schmitt on 04/01/2022. | ||||||
| // | // | ||||||
| @@ -9,28 +9,49 @@ import Foundation | |||||||
| import ToolCore | import ToolCore | ||||||
|  |  | ||||||
| class StringsFileGenerator { | class StringsFileGenerator { | ||||||
|      |  | ||||||
|     // MARK: - Strings Files |     // MARK: - Strings Files | ||||||
|      |  | ||||||
|     static func writeStringsFiles(sections: [Section], |     static func writeStringsFiles(sections: [Section], | ||||||
|                                   langs: [String], |                                   langs: [String], | ||||||
|                                   defaultLang: String, |                                   defaultLang: String, | ||||||
|                                   tags: [String], |                                   tags: [String], | ||||||
|                                   outputPath: String, |                                   outputPath: String, | ||||||
|                                   inputFilenameWithoutExt: String) { |                                   inputFilenameWithoutExt: String, | ||||||
|         var stringsFilesContent = [String: String]() |                                   isXcString: Bool = false) { | ||||||
|         for lang in langs { |  | ||||||
|             stringsFilesContent[lang] = Self.generateStringsFileContent(lang: lang, |         if !isXcString { | ||||||
|                                                                         defaultLang: defaultLang, |             var stringsFilesContent = [String: String]() | ||||||
|                                                                         tags: tags, |             for lang in langs { | ||||||
|                                                                         sections: sections) |                 stringsFilesContent[lang] = Self.generateStringsFileContent(lang: lang, | ||||||
|         } |                                                                             defaultLang: defaultLang, | ||||||
|          |                                                                             tags: tags, | ||||||
|         // Write strings file content |                                                                             sections: sections) | ||||||
|         langs.forEach { lang in |             } | ||||||
|             guard let fileContent = stringsFilesContent[lang] else { return } |  | ||||||
|              |             // Write strings file content | ||||||
|             let stringsFilePath = "\(outputPath)/\(lang).lproj/\(inputFilenameWithoutExt).strings" |             langs.forEach { lang in | ||||||
|  |                 guard let fileContent = stringsFilesContent[lang] else { return } | ||||||
|  |  | ||||||
|  |                 let stringsFilePath = "\(outputPath)/\(lang).lproj/\(inputFilenameWithoutExt).strings" | ||||||
|  |                 let stringsFilePathURL = URL(fileURLWithPath: stringsFilePath) | ||||||
|  |                 do { | ||||||
|  |                     try fileContent.write(to: stringsFilePathURL, atomically: false, encoding: .utf8) | ||||||
|  |                 } catch let error { | ||||||
|  |                     let error = StringiumError.writeFile(error.localizedDescription, stringsFilePath) | ||||||
|  |                     print(error.description) | ||||||
|  |                     Stringium.exit(withError: error) | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } else { | ||||||
|  |             let fileContent: String = Self.generateXcStringsFileContent( | ||||||
|  |                 langs: langs, | ||||||
|  |                 defaultLang: defaultLang, | ||||||
|  |                 tags: tags, | ||||||
|  |                 sections: sections | ||||||
|  |             ) | ||||||
|  |  | ||||||
|  |             let stringsFilePath = "\(outputPath)/Localizable.xcstrings" | ||||||
|             let stringsFilePathURL = URL(fileURLWithPath: stringsFilePath) |             let stringsFilePathURL = URL(fileURLWithPath: stringsFilePath) | ||||||
|             do { |             do { | ||||||
|                 try fileContent.write(to: stringsFilePathURL, atomically: false, encoding: .utf8) |                 try fileContent.write(to: stringsFilePathURL, atomically: false, encoding: .utf8) | ||||||
| @@ -41,7 +62,7 @@ class StringsFileGenerator { | |||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|      |  | ||||||
|     static func generateStringsFileContent(lang: String, |     static func generateStringsFileContent(lang: String, | ||||||
|                                            defaultLang: String, |                                            defaultLang: String, | ||||||
|                                            tags inputTags: [String], |                                            tags inputTags: [String], | ||||||
| @@ -53,13 +74,13 @@ class StringsFileGenerator { | |||||||
|          * Language: \(lang) |          * Language: \(lang) | ||||||
|          */\n |          */\n | ||||||
|         """ |         """ | ||||||
|          |  | ||||||
|         sections.forEach { section in |         sections.forEach { section in | ||||||
|             // Check that at least one string will be generated |             // Check that at least one string will be generated | ||||||
|             guard section.hasOneOrMoreMatchingTags(tags: inputTags) else { |             guard section.hasOneOrMoreMatchingTags(tags: inputTags) else { | ||||||
|                 return // Go to next section |                 return // Go to next section | ||||||
|             } |             } | ||||||
|              |  | ||||||
|             stringsFileContent += "\n/********** \(section.name) **********/\n\n" |             stringsFileContent += "\n/********** \(section.name) **********/\n\n" | ||||||
|             section.definitions.forEach { definition in |             section.definitions.forEach { definition in | ||||||
|                 var skipDefinition = false // Set to true if not matching tag |                 var skipDefinition = false // Set to true if not matching tag | ||||||
| @@ -69,16 +90,16 @@ class StringsFileGenerator { | |||||||
|                         skipDefinition = true |                         skipDefinition = true | ||||||
|                         return nil |                         return nil | ||||||
|                     } |                     } | ||||||
|                      |  | ||||||
|                     // If tags contains `noTranslationTag` => get default lang |                     // If tags contains `noTranslationTag` => get default lang | ||||||
|                     if definition.tags.contains(Stringium.noTranslationTag) { |                     if definition.tags.contains(Stringium.noTranslationTag) { | ||||||
|                         return definition.translations[defaultLang] |                         return definition.translations[defaultLang] | ||||||
|                     } |                     } | ||||||
|                      |  | ||||||
|                     // Else: get specific lang |                     // Else: get specific lang | ||||||
|                     return definition.translations[lang] |                     return definition.translations[lang] | ||||||
|                 }() |                 }() | ||||||
|                  |  | ||||||
|                 if let translation = translationOpt { |                 if let translation = translationOpt { | ||||||
|                     stringsFileContent += "\"\(definition.name)\" = \"\(translation)\";\n\n" |                     stringsFileContent += "\"\(definition.name)\" = \"\(translation)\";\n\n" | ||||||
|                 } else if skipDefinition == false { |                 } else if skipDefinition == false { | ||||||
| @@ -88,12 +109,101 @@ class StringsFileGenerator { | |||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|          |  | ||||||
|         return stringsFileContent |         return stringsFileContent | ||||||
|     } |     } | ||||||
|      |  | ||||||
|  |     // MARK: - XcStrings Generation | ||||||
|  |  | ||||||
|  |     static func generateXcStringsFileContent(langs: [String], | ||||||
|  |                                              defaultLang: String, | ||||||
|  |                                              tags inputTags: [String], | ||||||
|  |                                              sections: [Section]) -> String { | ||||||
|  |         let rootObject = generateRootObject(langs: langs, defaultLang: defaultLang, tags: inputTags, sections: sections) | ||||||
|  |         let file = generateXcStringsFileContentFromRootObject(rootObject: rootObject) | ||||||
|  |  | ||||||
|  |         return file | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     static func generateXcStringsFileContentFromRootObject(rootObject: Root) -> String { | ||||||
|  |         do { | ||||||
|  |             let encoder = JSONEncoder() | ||||||
|  |             encoder.outputFormatting = [.prettyPrinted] | ||||||
|  |  | ||||||
|  |             let json = try encoder.encode(rootObject) | ||||||
|  |  | ||||||
|  |             if let jsonString = String(data: json, encoding: .utf8) { | ||||||
|  |                 return jsonString | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |         } catch { | ||||||
|  |             debugPrint("Failed to encode: \(error)") | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         return "" | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     static func generateRootObject(langs: [String], | ||||||
|  |                                    defaultLang: String, | ||||||
|  |                                    tags inputTags: [String], | ||||||
|  |                                    sections: [Section]) -> Root { | ||||||
|  |  | ||||||
|  |         var xcStringDefinitionTab: [XCStringDefinition] = [] | ||||||
|  |  | ||||||
|  |         sections.forEach { section in | ||||||
|  |             // Check that at least one string will be generated | ||||||
|  |             guard section.hasOneOrMoreMatchingTags(tags: inputTags) else { | ||||||
|  |                 return // Go to next section | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             section.definitions.forEach { definition in | ||||||
|  |                 var skipDefinition = false | ||||||
|  |  | ||||||
|  |                 var localizationTab: [XCStringLocalization] = [] | ||||||
|  |  | ||||||
|  |                 if definition.hasOneOrMoreMatchingTags(inputTags: inputTags) == false { | ||||||
|  |                     skipDefinition = true | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |                 if !skipDefinition { | ||||||
|  |  | ||||||
|  |                     for (lang, value) in definition.translations { | ||||||
|  |                         let localization = XCStringLocalization( | ||||||
|  |                             lang: lang, | ||||||
|  |                             content: XCStringLocalizationLangContent( | ||||||
|  |                                 stringUnit: DefaultStringUnit(state: "translated", value: value) | ||||||
|  |                             ) | ||||||
|  |                         ) | ||||||
|  |  | ||||||
|  |                         localizationTab.append(localization) | ||||||
|  |                     } | ||||||
|  |  | ||||||
|  |                     let xcStringDefinition = XCStringDefinition( | ||||||
|  |                         title: definition.name, | ||||||
|  |                         content: XCStringDefinitionContent( | ||||||
|  |                             extractionState: "manual", | ||||||
|  |                             localizations: XCStringLocalizationContainer( | ||||||
|  |                                 localizations: localizationTab | ||||||
|  |                             ) | ||||||
|  |                         ) | ||||||
|  |                     ) | ||||||
|  |  | ||||||
|  |                     xcStringDefinitionTab.append(xcStringDefinition) | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         let xcStringContainer = XCStringDefinitionContainer(strings: xcStringDefinitionTab) | ||||||
|  |          | ||||||
|  |         return Root( | ||||||
|  |             sourceLanguage: defaultLang, | ||||||
|  |             strings: xcStringContainer, | ||||||
|  |             version: "1.0" | ||||||
|  |         ) | ||||||
|  |     } | ||||||
|  |  | ||||||
|     // MARK: - Extension file |     // MARK: - Extension file | ||||||
|      |  | ||||||
|     static func writeExtensionFiles(sections: [Section], |     static func writeExtensionFiles(sections: [Section], | ||||||
|                                     defaultLang lang: String, |                                     defaultLang lang: String, | ||||||
|                                     tags: [String], |                                     tags: [String], | ||||||
| @@ -110,7 +220,7 @@ class StringsFileGenerator { | |||||||
|                                                             inputFilename: inputFilename, |                                                             inputFilename: inputFilename, | ||||||
|                                                             extensionName: extensionName, |                                                             extensionName: extensionName, | ||||||
|                                                             extensionSuffix: extensionSuffix) |                                                             extensionSuffix: extensionSuffix) | ||||||
|          |  | ||||||
|         // Write content |         // Write content | ||||||
|         let extensionFilePathURL = URL(fileURLWithPath: extensionFilePath) |         let extensionFilePathURL = URL(fileURLWithPath: extensionFilePath) | ||||||
|         do { |         do { | ||||||
| @@ -121,9 +231,9 @@ class StringsFileGenerator { | |||||||
|             Stringium.exit(withError: error) |             Stringium.exit(withError: error) | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|      |  | ||||||
|     // MARK: - Extension content |     // MARK: - Extension content | ||||||
|      |  | ||||||
|     static func getExtensionContent(sections: [Section], |     static func getExtensionContent(sections: [Section], | ||||||
|                                     defaultLang lang: String, |                                     defaultLang lang: String, | ||||||
|                                     tags: [String], |                                     tags: [String], | ||||||
| @@ -139,31 +249,31 @@ class StringsFileGenerator { | |||||||
|         ] |         ] | ||||||
|             .joined(separator: "\n") |             .joined(separator: "\n") | ||||||
|     } |     } | ||||||
|      |  | ||||||
|     // MARK: - Extension part |     // MARK: - Extension part | ||||||
|      |  | ||||||
|     private static func getHeader(stringsFilename: String, extensionClassname: String) -> String { |     private static func getHeader(stringsFilename: String, extensionClassname: String) -> String { | ||||||
|         """ |         """ | ||||||
|         // Generated by ResgenSwift.Strings.\(Stringium.toolName) \(ResgenSwiftVersion) |         // Generated by ResgenSwift.Strings.\(Stringium.toolName) \(ResgenSwiftVersion) | ||||||
|          |  | ||||||
|         import UIKit |         import UIKit | ||||||
|          |  | ||||||
|         fileprivate let kStringsFileName = "\(stringsFilename)" |         fileprivate let kStringsFileName = "\(stringsFilename)" | ||||||
|          |  | ||||||
|         extension \(extensionClassname) { |         extension \(extensionClassname) { | ||||||
|         """ |         """ | ||||||
|     } |     } | ||||||
|      |  | ||||||
|     private static func getEnumKey(sections: [Section], tags: [String], extensionClassname: String, extensionSuffix: String) -> String { |     private static func getEnumKey(sections: [Section], tags: [String], extensionClassname: String, extensionSuffix: String) -> String { | ||||||
|         var enumDefinition = "\n    enum Key\(extensionSuffix.uppercasedFirst()): String {\n" |         var enumDefinition = "\n    enum Key\(extensionSuffix.uppercasedFirst()): String {\n" | ||||||
|          |  | ||||||
|         // Enum |         // Enum | ||||||
|         sections.forEach { section in |         sections.forEach { section in | ||||||
|             // Check that at least one string will be generated |             // Check that at least one string will be generated | ||||||
|             guard section.hasOneOrMoreMatchingTags(tags: tags) else { |             guard section.hasOneOrMoreMatchingTags(tags: tags) else { | ||||||
|                 return // Go to next section |                 return // Go to next section | ||||||
|             } |             } | ||||||
|              |  | ||||||
|             section.definitions.forEach { definition in |             section.definitions.forEach { definition in | ||||||
|                 guard definition.hasOneOrMoreMatchingTags(inputTags: tags) == true else { |                 guard definition.hasOneOrMoreMatchingTags(inputTags: tags) == true else { | ||||||
|                     return // Go to next definition |                     return // Go to next definition | ||||||
| @@ -172,7 +282,7 @@ class StringsFileGenerator { | |||||||
|                 enumDefinition += "        case \(definition.name) = \"\(definition.name)\"\n" |                 enumDefinition += "        case \(definition.name) = \"\(definition.name)\"\n" | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|          |  | ||||||
|         // KeyPath accessors |         // KeyPath accessors | ||||||
|         enumDefinition += "\n" |         enumDefinition += "\n" | ||||||
|         enumDefinition += "        var keyPath: KeyPath<\(extensionClassname), String> {\n" |         enumDefinition += "        var keyPath: KeyPath<\(extensionClassname), String> {\n" | ||||||
| @@ -182,7 +292,7 @@ class StringsFileGenerator { | |||||||
|             guard section.hasOneOrMoreMatchingTags(tags: tags) else { |             guard section.hasOneOrMoreMatchingTags(tags: tags) else { | ||||||
|                 return // Go to next section |                 return // Go to next section | ||||||
|             } |             } | ||||||
|              |  | ||||||
|             section.definitions.forEach { definition in |             section.definitions.forEach { definition in | ||||||
|                 guard definition.hasOneOrMoreMatchingTags(inputTags: tags) == true else { |                 guard definition.hasOneOrMoreMatchingTags(inputTags: tags) == true else { | ||||||
|                     return // Go to next definition |                     return // Go to next definition | ||||||
| @@ -194,23 +304,23 @@ class StringsFileGenerator { | |||||||
|         enumDefinition += "            }\n" // Switch |         enumDefinition += "            }\n" // Switch | ||||||
|         enumDefinition += "        }\n" // var keyPath |         enumDefinition += "        }\n" // var keyPath | ||||||
|         enumDefinition += "    }" // Enum |         enumDefinition += "    }" // Enum | ||||||
|          |  | ||||||
|         return enumDefinition |         return enumDefinition | ||||||
|     } |     } | ||||||
|      |  | ||||||
|     private static func getProperties(sections: [Section], defaultLang lang: String, tags: [String], staticVar: Bool) -> String { |     private static func getProperties(sections: [Section], defaultLang lang: String, tags: [String], staticVar: Bool) -> String { | ||||||
|         sections.compactMap { section in |         sections.compactMap { section in | ||||||
|             // Check that at least one string will be generated |             // Check that at least one string will be generated | ||||||
|             guard section.hasOneOrMoreMatchingTags(tags: tags) else { |             guard section.hasOneOrMoreMatchingTags(tags: tags) else { | ||||||
|                 return nil // Go to next section |                 return nil // Go to next section | ||||||
|             } |             } | ||||||
|              |  | ||||||
|             var res = "\n    // MARK: - \(section.name)\n" |             var res = "\n    // MARK: - \(section.name)\n" | ||||||
|             res += section.definitions.compactMap { definition in |             res += section.definitions.compactMap { definition in | ||||||
|                 guard definition.hasOneOrMoreMatchingTags(inputTags: tags) == true else { |                 guard definition.hasOneOrMoreMatchingTags(inputTags: tags) == true else { | ||||||
|                     return nil // Go to next definition |                     return nil // Go to next definition | ||||||
|                 } |                 } | ||||||
|                  |  | ||||||
|                 if staticVar { |                 if staticVar { | ||||||
|                     return "\n\(definition.getNSLocalizedStringStaticProperty(forLang: lang))" |                     return "\n\(definition.getNSLocalizedStringStaticProperty(forLang: lang))" | ||||||
|                 } |                 } | ||||||
| @@ -221,11 +331,11 @@ class StringsFileGenerator { | |||||||
|         } |         } | ||||||
|         .joined(separator: "\n") |         .joined(separator: "\n") | ||||||
|     } |     } | ||||||
|      |  | ||||||
|     private static func getFooter() -> String { |     private static func getFooter() -> String { | ||||||
|         """ |         """ | ||||||
|         } |         } | ||||||
|          |  | ||||||
|         """ |         """ | ||||||
|     } |     } | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										93
									
								
								Sources/ResgenSwift/Strings/Model/XcString.swift
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										93
									
								
								Sources/ResgenSwift/Strings/Model/XcString.swift
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,93 @@ | |||||||
|  | // | ||||||
|  | //  XcString.swift | ||||||
|  | // | ||||||
|  | // | ||||||
|  | //  Created by Quentin Bandera on 12/04/2024. | ||||||
|  | // | ||||||
|  |  | ||||||
|  | import SwiftUI | ||||||
|  |  | ||||||
|  | struct DynamicKey: CodingKey { | ||||||
|  |     var intValue: Int? | ||||||
|  |     init?(intValue: Int) { | ||||||
|  |         self.intValue = intValue | ||||||
|  |         self.stringValue = "\(intValue)" | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     var stringValue: String | ||||||
|  |     init?(stringValue: String) { | ||||||
|  |         self.stringValue = stringValue | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | struct Root: Codable, Equatable { | ||||||
|  |     let sourceLanguage: String | ||||||
|  |     let strings: XCStringDefinitionContainer | ||||||
|  |     let version: String | ||||||
|  | } | ||||||
|  |  | ||||||
|  | struct XCStringDefinitionContainer: Codable, Equatable { | ||||||
|  |     let strings: [XCStringDefinition] | ||||||
|  |  | ||||||
|  |     func encode(to encoder: Encoder) throws { | ||||||
|  |         var container = encoder.container(keyedBy: DynamicKey.self) | ||||||
|  |  | ||||||
|  |         for str in strings { | ||||||
|  |             if let codingKey = DynamicKey(stringValue: str.title) { | ||||||
|  |                 try container.encode(str.content, forKey: codingKey) | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | struct XCStringDefinition: Codable, Equatable { | ||||||
|  |     let title: String // json key -> custom encoding methods | ||||||
|  |     let content: XCStringDefinitionContent | ||||||
|  | } | ||||||
|  |  | ||||||
|  | struct XCStringDefinitionContent: Codable, Equatable { | ||||||
|  |     let extractionState: String | ||||||
|  |     var localizations: XCStringLocalizationContainer | ||||||
|  |  | ||||||
|  | } | ||||||
|  |  | ||||||
|  | struct XCStringLocalizationContainer: Codable, Equatable { | ||||||
|  |     let localizations: [XCStringLocalization] | ||||||
|  |  | ||||||
|  |     func encode(to encoder: Encoder) throws { | ||||||
|  |         var container = encoder.container(keyedBy: DynamicKey.self) | ||||||
|  |  | ||||||
|  |         for loca in localizations { | ||||||
|  |             if let codingKey = DynamicKey(stringValue: loca.lang) { | ||||||
|  |                 try container.encode(loca.content, forKey: codingKey) | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | struct XCStringLocalization: Codable, Equatable { | ||||||
|  |     let lang: String // json key -> custom encoding method | ||||||
|  |     let content: XCStringLocalizationLangContent | ||||||
|  | } | ||||||
|  |  | ||||||
|  | struct XCStringLocalizationLangContent: Codable, Equatable { | ||||||
|  |     let stringUnit: DefaultStringUnit | ||||||
|  | } | ||||||
|  |  | ||||||
|  | //enum VarationOrStringUnit: Encodable { | ||||||
|  | //    case variations([Varation]) | ||||||
|  | //    case stringUnit: (DefaultStringUnit) | ||||||
|  | // | ||||||
|  | //    func encode(to encoder: any Encoder) throws { | ||||||
|  | //        if let varations { | ||||||
|  | // | ||||||
|  | //        } else if let  { | ||||||
|  | // | ||||||
|  | //        } | ||||||
|  | //    } | ||||||
|  | //} | ||||||
|  |  | ||||||
|  | struct DefaultStringUnit: Codable, Equatable { | ||||||
|  |     let state: String | ||||||
|  |     let value: String | ||||||
|  | } | ||||||
| @@ -48,8 +48,9 @@ struct Stringium: ParsableCommand { | |||||||
|                                                defaultLang: options.defaultLang, |                                                defaultLang: options.defaultLang, | ||||||
|                                                tags: options.tags, |                                                tags: options.tags, | ||||||
|                                                outputPath: options.stringsFileOutputPath, |                                                outputPath: options.stringsFileOutputPath, | ||||||
|                                                inputFilenameWithoutExt: options.inputFilenameWithoutExt) |                                                inputFilenameWithoutExt: options.inputFilenameWithoutExt, | ||||||
|          |                                                isXcString: options.isXcstring) | ||||||
|  |  | ||||||
|         // Generate extension |         // Generate extension | ||||||
|         StringsFileGenerator.writeExtensionFiles(sections: sections, |         StringsFileGenerator.writeExtensionFiles(sections: sections, | ||||||
|                                                  defaultLang: options.defaultLang, |                                                  defaultLang: options.defaultLang, | ||||||
|   | |||||||
| @@ -11,7 +11,10 @@ import ArgumentParser | |||||||
| struct StringiumOptions: ParsableArguments { | struct StringiumOptions: ParsableArguments { | ||||||
|     @Flag(name: [.customShort("f"), .customShort("F")], help: "Should force generation") |     @Flag(name: [.customShort("f"), .customShort("F")], help: "Should force generation") | ||||||
|     var forceGeneration = false |     var forceGeneration = false | ||||||
|      |  | ||||||
|  |     @Flag(name: [.customShort("x"), .customLong("xcstrings")], help: "Generate xcstrings catalog") | ||||||
|  |     var isXcstring = false | ||||||
|  |  | ||||||
|     @Argument(help: "Input files where strings ared defined.", transform: { $0.replaceTiltWithHomeDirectoryPath() }) |     @Argument(help: "Input files where strings ared defined.", transform: { $0.replaceTiltWithHomeDirectoryPath() }) | ||||||
|     var inputFile: String |     var inputFile: String | ||||||
|      |      | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| // | // | ||||||
| //  StringsFileGeneratorTests.swift | //  StringsFileGeneratorTests.swift | ||||||
| //   | // | ||||||
| // | // | ||||||
| //  Created by Thibaut Schmitt on 06/09/2022. | //  Created by Thibaut Schmitt on 06/09/2022. | ||||||
| // | // | ||||||
| @@ -12,7 +12,7 @@ import ToolCore | |||||||
| @testable import ResgenSwift | @testable import ResgenSwift | ||||||
|  |  | ||||||
| final class StringsFileGeneratorTests: XCTestCase { | final class StringsFileGeneratorTests: XCTestCase { | ||||||
|      |  | ||||||
|     private func getDefinition(name: String, translations: [String: String], tags: [String], comment: String? = nil) -> Definition { |     private func getDefinition(name: String, translations: [String: String], tags: [String], comment: String? = nil) -> Definition { | ||||||
|         let definition = Definition(name: name) |         let definition = Definition(name: name) | ||||||
|         definition.tags = tags |         definition.tags = tags | ||||||
| @@ -36,7 +36,7 @@ final class StringsFileGeneratorTests: XCTestCase { | |||||||
|                                          "en": "Section One - Definition Two"], |                                          "en": "Section One - Definition Two"], | ||||||
|                           tags: ["ios","iosonly"]) |                           tags: ["ios","iosonly"]) | ||||||
|         ] |         ] | ||||||
|          |  | ||||||
|         let sectionTwo = Section(name: "section_two") |         let sectionTwo = Section(name: "section_two") | ||||||
|         sectionTwo.definitions = [ |         sectionTwo.definitions = [ | ||||||
|             getDefinition(name: "s2_def_one", |             getDefinition(name: "s2_def_one", | ||||||
| @@ -47,7 +47,7 @@ final class StringsFileGeneratorTests: XCTestCase { | |||||||
|                           translations: ["fr": "Section Deux - Definition Deux"], |                           translations: ["fr": "Section Deux - Definition Deux"], | ||||||
|                           tags: ["notranslation"]) |                           tags: ["notranslation"]) | ||||||
|         ] |         ] | ||||||
|          |  | ||||||
|         // When |         // When | ||||||
|         let stringsFileContentFr = StringsFileGenerator.generateStringsFileContent(lang: "fr", |         let stringsFileContentFr = StringsFileGenerator.generateStringsFileContent(lang: "fr", | ||||||
|                                                                                    defaultLang: "fr", |                                                                                    defaultLang: "fr", | ||||||
| @@ -57,7 +57,7 @@ final class StringsFileGeneratorTests: XCTestCase { | |||||||
|                                                                                    defaultLang: "fr", |                                                                                    defaultLang: "fr", | ||||||
|                                                                                    tags: ["ios", "iosonly", "notranslation"], |                                                                                    tags: ["ios", "iosonly", "notranslation"], | ||||||
|                                                                                    sections: [sectionOne, sectionTwo]) |                                                                                    sections: [sectionOne, sectionTwo]) | ||||||
|          |  | ||||||
|         // Expect |         // Expect | ||||||
|         let expectFr = """ |         let expectFr = """ | ||||||
|         /** |         /** | ||||||
| @@ -65,40 +65,40 @@ final class StringsFileGeneratorTests: XCTestCase { | |||||||
|          * Generated by ResgenSwift \(ResgenSwiftVersion) |          * Generated by ResgenSwift \(ResgenSwiftVersion) | ||||||
|          * Language: fr |          * Language: fr | ||||||
|          */ |          */ | ||||||
|          |  | ||||||
|         /********** section_one **********/ |         /********** section_one **********/ | ||||||
|          |  | ||||||
|         "s1_def_one" = "Section Un - Definition Un"; |         "s1_def_one" = "Section Un - Definition Un"; | ||||||
|          |  | ||||||
|         "s1_def_two" = "Section Un - Definition Deux"; |         "s1_def_two" = "Section Un - Definition Deux"; | ||||||
|          |  | ||||||
|         /********** section_two **********/ |         /********** section_two **********/ | ||||||
|          |  | ||||||
|         "s2_def_one" = "Section Deux - Definition Un"; |         "s2_def_one" = "Section Deux - Definition Un"; | ||||||
|  |  | ||||||
|         "s2_def_two" = "Section Deux - Definition Deux"; |         "s2_def_two" = "Section Deux - Definition Deux"; | ||||||
|         """ |         """ | ||||||
|          |  | ||||||
|         let expectEn = """ |         let expectEn = """ | ||||||
|         /** |         /** | ||||||
|          * Apple Strings File |          * Apple Strings File | ||||||
|          * Generated by ResgenSwift \(ResgenSwiftVersion) |          * Generated by ResgenSwift \(ResgenSwiftVersion) | ||||||
|          * Language: en |          * Language: en | ||||||
|          */ |          */ | ||||||
|          |  | ||||||
|         /********** section_one **********/ |         /********** section_one **********/ | ||||||
|          |  | ||||||
|         "s1_def_one" = "Section One - Definition One"; |         "s1_def_one" = "Section One - Definition One"; | ||||||
|          |  | ||||||
|         "s1_def_two" = "Section One - Definition Two"; |         "s1_def_two" = "Section One - Definition Two"; | ||||||
|          |  | ||||||
|         /********** section_two **********/ |         /********** section_two **********/ | ||||||
|          |  | ||||||
|         "s2_def_one" = "Section Two - Definition One"; |         "s2_def_one" = "Section Two - Definition One"; | ||||||
|  |  | ||||||
|         "s2_def_two" = "Section Deux - Definition Deux"; |         "s2_def_two" = "Section Deux - Definition Deux"; | ||||||
|         """ |         """ | ||||||
|          |  | ||||||
|         XCTAssertEqual(stringsFileContentFr.adaptForXCTest(), expectFr.adaptForXCTest()) |         XCTAssertEqual(stringsFileContentFr.adaptForXCTest(), expectFr.adaptForXCTest()) | ||||||
|         XCTAssertEqual(stringsFileContentEn.adaptForXCTest(), expectEn.adaptForXCTest()) |         XCTAssertEqual(stringsFileContentEn.adaptForXCTest(), expectEn.adaptForXCTest()) | ||||||
|     } |     } | ||||||
| @@ -187,6 +187,268 @@ final class StringsFileGeneratorTests: XCTestCase { | |||||||
|         XCTAssertEqual(stringsFileContentEn.adaptForXCTest(), expectEn.adaptForXCTest()) |         XCTAssertEqual(stringsFileContentEn.adaptForXCTest(), expectEn.adaptForXCTest()) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     // MARK: - XcString File Content | ||||||
|  |  | ||||||
|  |     func testGenerateXcStringsRootObject() { | ||||||
|  |         // Given | ||||||
|  |         let sectionOne = Section(name: "section_one") | ||||||
|  |         sectionOne.definitions = [ | ||||||
|  |             getDefinition(name: "s1_def_one", | ||||||
|  |                           translations: ["fr": "Section Un - Definition Un", | ||||||
|  |                                          "en": "Section One - Definition One"], | ||||||
|  |                           tags: ["ios","iosonly"]), | ||||||
|  |             getDefinition(name: "s1_def_two", | ||||||
|  |                           translations: ["fr": "Section Un - Definition Deux", | ||||||
|  |                                          "en": "Section One - Definition Two"], | ||||||
|  |                           tags: ["ios","iosonly"]) | ||||||
|  |         ] | ||||||
|  |  | ||||||
|  |         let sectionTwo = Section(name: "section_two") | ||||||
|  |         sectionTwo.definitions = [ | ||||||
|  |             getDefinition(name: "s2_def_one", | ||||||
|  |                           translations: ["fr": "Section Deux - Definition Un", | ||||||
|  |                                          "en": "Section Two - Definition One"], | ||||||
|  |                           tags: ["ios","iosonly"]), | ||||||
|  |             getDefinition(name: "s2_def_two", | ||||||
|  |                           translations: ["fr": "Section Deux - Definition Deux"], | ||||||
|  |                           tags: ["notranslation"]) | ||||||
|  |         ] | ||||||
|  |  | ||||||
|  |         // When | ||||||
|  |         let rootObject = StringsFileGenerator.generateRootObject( | ||||||
|  |             langs: ["fr", "en"], | ||||||
|  |             defaultLang: "en", | ||||||
|  |             tags: ["ios", "iosonly", "notranslation"], | ||||||
|  |             sections: [sectionOne, sectionTwo] | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  |         //        [[section_one]] | ||||||
|  |         //            [s1_def_one] | ||||||
|  |         //                fr = Section Un - Definition Un | ||||||
|  |         //                en = Section One - Definition One | ||||||
|  |         //                tags = ios,iosonly | ||||||
|  |         //                comments = | ||||||
|  |         //            [s1_def_two] | ||||||
|  |         //                fr = Section Un - Definition Deux | ||||||
|  |         //                en = Section One - Definition Two | ||||||
|  |         //                tags = ios,iosonly | ||||||
|  |         //                comments = | ||||||
|  |         // | ||||||
|  |         //        [[section_two] | ||||||
|  |         //            [s2_def_one] | ||||||
|  |         //                fr = Section Deux - Definition Un | ||||||
|  |         //                en = Section Two - Definition One | ||||||
|  |         //                tags = ios,iosonly | ||||||
|  |         //                comments = | ||||||
|  |         //            [s2_def_two] | ||||||
|  |         //                fr = Section Deux - Definition deux | ||||||
|  |         //                en = Section Two - Definition Two | ||||||
|  |         //                tags = ios,iosonly | ||||||
|  |         //                comments = | ||||||
|  |  | ||||||
|  |         // Expect | ||||||
|  |         let expect = | ||||||
|  |         Root( | ||||||
|  |             sourceLanguage: "en", | ||||||
|  |             strings: XCStringDefinitionContainer( | ||||||
|  |                 strings: [ | ||||||
|  |                     XCStringDefinition( | ||||||
|  |                         title: "s1_def_one", | ||||||
|  |                         content: XCStringDefinitionContent( | ||||||
|  |                             extractionState: "manual", | ||||||
|  |                             localizations: XCStringLocalizationContainer( | ||||||
|  |                                 localizations: [ | ||||||
|  |                                     XCStringLocalization( | ||||||
|  |                                         lang: "en", | ||||||
|  |                                         content: XCStringLocalizationLangContent( | ||||||
|  |                                             stringUnit: DefaultStringUnit( | ||||||
|  |                                                 state: "translated", | ||||||
|  |                                                 value: "Section One - Definition One" | ||||||
|  |                                             ) | ||||||
|  |                                         ) | ||||||
|  |                                     ), | ||||||
|  |                                     XCStringLocalization( | ||||||
|  |                                         lang: "fr", | ||||||
|  |                                         content: XCStringLocalizationLangContent( | ||||||
|  |                                             stringUnit: DefaultStringUnit( | ||||||
|  |                                                 state: "translated", | ||||||
|  |                                                 value: "Section Un - Definition Un" | ||||||
|  |                                             ) | ||||||
|  |                                         ) | ||||||
|  |                                     ) | ||||||
|  |                                 ] | ||||||
|  |                             ) | ||||||
|  |                         ) | ||||||
|  |                     ), | ||||||
|  |                     XCStringDefinition( | ||||||
|  |                         title: "s1_def_two", | ||||||
|  |                         content: XCStringDefinitionContent( | ||||||
|  |                             extractionState: "manual", | ||||||
|  |                             localizations: XCStringLocalizationContainer( | ||||||
|  |                                 localizations: [ | ||||||
|  |                                     XCStringLocalization( | ||||||
|  |                                         lang: "en", | ||||||
|  |                                         content: XCStringLocalizationLangContent( | ||||||
|  |                                             stringUnit: DefaultStringUnit( | ||||||
|  |                                                 state: "translated", | ||||||
|  |                                                 value: "Section One - Definition Two" | ||||||
|  |                                             ) | ||||||
|  |                                         ) | ||||||
|  |                                     ), | ||||||
|  |                                     XCStringLocalization( | ||||||
|  |                                         lang: "fr", | ||||||
|  |                                         content: XCStringLocalizationLangContent( | ||||||
|  |                                             stringUnit: DefaultStringUnit( | ||||||
|  |                                                 state: "translated", | ||||||
|  |                                                 value: "Section Un - Definition Deux" | ||||||
|  |                                             ) | ||||||
|  |                                         ) | ||||||
|  |                                     ) | ||||||
|  |                                 ] | ||||||
|  |                             ) | ||||||
|  |                         ) | ||||||
|  |                     ), | ||||||
|  |                     XCStringDefinition( | ||||||
|  |                         title: "s2_def_one", | ||||||
|  |                         content: XCStringDefinitionContent( | ||||||
|  |                             extractionState: "manual", | ||||||
|  |                             localizations: XCStringLocalizationContainer( | ||||||
|  |                                 localizations: [ | ||||||
|  |                                     XCStringLocalization( | ||||||
|  |                                         lang: "en", | ||||||
|  |                                         content: XCStringLocalizationLangContent( | ||||||
|  |                                             stringUnit: DefaultStringUnit( | ||||||
|  |                                                 state: "translated", | ||||||
|  |                                                 value: "Section Two - Definition One" | ||||||
|  |                                             ) | ||||||
|  |                                         ) | ||||||
|  |                                     ), | ||||||
|  |                                     XCStringLocalization( | ||||||
|  |                                         lang: "fr", | ||||||
|  |                                         content: XCStringLocalizationLangContent( | ||||||
|  |                                             stringUnit: DefaultStringUnit( | ||||||
|  |                                                 state: "translated", | ||||||
|  |                                                 value: "Section Two - Definition Un" | ||||||
|  |                                             ) | ||||||
|  |                                         ) | ||||||
|  |                                     ) | ||||||
|  |                                 ] | ||||||
|  |                             ) | ||||||
|  |                         ) | ||||||
|  |                     ), | ||||||
|  |                     XCStringDefinition( | ||||||
|  |                         title: "s2_def_two", | ||||||
|  |                         content: XCStringDefinitionContent( | ||||||
|  |                             extractionState: "manual", | ||||||
|  |                             localizations: XCStringLocalizationContainer( | ||||||
|  |                                 localizations: [ | ||||||
|  |                                     XCStringLocalization( | ||||||
|  |                                         lang: "en", | ||||||
|  |                                         content: XCStringLocalizationLangContent( | ||||||
|  |                                             stringUnit: DefaultStringUnit( | ||||||
|  |                                                 state: "translated", | ||||||
|  |                                                 value: "Section Two - Definition Two" | ||||||
|  |                                             ) | ||||||
|  |                                         ) | ||||||
|  |                                     ), | ||||||
|  |                                     XCStringLocalization( | ||||||
|  |                                         lang: "fr", | ||||||
|  |                                         content: XCStringLocalizationLangContent( | ||||||
|  |                                             stringUnit: DefaultStringUnit( | ||||||
|  |                                                 state: "translated", | ||||||
|  |                                                 value: "Section Deux - Definition Deux" | ||||||
|  |                                             ) | ||||||
|  |                                         ) | ||||||
|  |                                     ) | ||||||
|  |                                 ] | ||||||
|  |                             ) | ||||||
|  |                         ) | ||||||
|  |                     ) | ||||||
|  |                 ] | ||||||
|  |             ), | ||||||
|  |             version: "1.0" | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  |         //        """ | ||||||
|  |         //        { | ||||||
|  |         //          "sourceLanguage" : "en", | ||||||
|  |         //          "strings" : { | ||||||
|  |         //            "s1_def_one" : { | ||||||
|  |         //              "extractionState" : "manual", | ||||||
|  |         //              "localizations" : { | ||||||
|  |         //                "en" : { | ||||||
|  |         //                  "stringUnit" : { | ||||||
|  |         //                    "state" : "translated", | ||||||
|  |         //                    "value" : "Section One - Definition One" | ||||||
|  |         //                  } | ||||||
|  |         //                }, | ||||||
|  |         //                "fr" : { | ||||||
|  |         //                  "stringUnit" : { | ||||||
|  |         //                    "state" : "translated", | ||||||
|  |         //                    "value" : "Section Un - Definition Un" | ||||||
|  |         //                  } | ||||||
|  |         //                } | ||||||
|  |         //              } | ||||||
|  |         //            }, | ||||||
|  |         //            "s1_def_two" : { | ||||||
|  |         //              "extractionState" : "manual", | ||||||
|  |         //              "localizations" : { | ||||||
|  |         //                "en" : { | ||||||
|  |         //                  "stringUnit" : { | ||||||
|  |         //                    "state" : "translated", | ||||||
|  |         //                    "value" : "Section One - Definition Two" | ||||||
|  |         //                  } | ||||||
|  |         //                }, | ||||||
|  |         //                "fr" : { | ||||||
|  |         //                  "stringUnit" : { | ||||||
|  |         //                    "state" : "translated", | ||||||
|  |         //                    "value" : "Section Un - Definition Deux" | ||||||
|  |         //                  } | ||||||
|  |         //                } | ||||||
|  |         //              } | ||||||
|  |         //            }, | ||||||
|  |         //            "s2_def_one" : { | ||||||
|  |         //              "extractionState" : "manual", | ||||||
|  |         //              "localizations" : { | ||||||
|  |         //                "en" : { | ||||||
|  |         //                  "stringUnit" : { | ||||||
|  |         //                    "state" : "translated", | ||||||
|  |         //                    "value" : "Section Two - Definition One" | ||||||
|  |         //                  } | ||||||
|  |         //                }, | ||||||
|  |         //                "fr" : { | ||||||
|  |         //                  "stringUnit" : { | ||||||
|  |         //                    "state" : "translated", | ||||||
|  |         //                    "value" : "Section Deux - Definition Une" | ||||||
|  |         //                  } | ||||||
|  |         //                } | ||||||
|  |         //              } | ||||||
|  |         //            }, | ||||||
|  |         //            "s2_def_two" : { | ||||||
|  |         //              "extractionState" : "manual", | ||||||
|  |         //              "localizations" : { | ||||||
|  |         //                "en" : { | ||||||
|  |         //                  "stringUnit" : { | ||||||
|  |         //                    "state" : "translated", | ||||||
|  |         //                    "value" : "Section Two - Definition Two" | ||||||
|  |         //                  } | ||||||
|  |         //                }, | ||||||
|  |         //                "fr" : { | ||||||
|  |         //                  "stringUnit" : { | ||||||
|  |         //                    "state" : "translated", | ||||||
|  |         //                    "value" : "Section Deux - Definition Deux" | ||||||
|  |         //                  } | ||||||
|  |         //                } | ||||||
|  |         //              } | ||||||
|  |         //            } | ||||||
|  |         //          }, | ||||||
|  |         //          "version" : "1.0" | ||||||
|  |         //        } | ||||||
|  |         //        """ | ||||||
|  |  | ||||||
|  |         XCTAssertEqual(rootObject, expect) | ||||||
|  |     } | ||||||
|  |  | ||||||
|     // MARK: - Extension Content |     // MARK: - Extension Content | ||||||
|     func testGeneratedExtensionContent() { |     func testGeneratedExtensionContent() { | ||||||
|         // Given |         // Given | ||||||
| @@ -201,7 +463,7 @@ final class StringsFileGeneratorTests: XCTestCase { | |||||||
|                                          "en": "Section One - Definition Two"], |                                          "en": "Section One - Definition Two"], | ||||||
|                           tags: ["ios","iosonly"]) |                           tags: ["ios","iosonly"]) | ||||||
|         ] |         ] | ||||||
|          |  | ||||||
|         let sectionTwo = Section(name: "section_two") |         let sectionTwo = Section(name: "section_two") | ||||||
|         sectionTwo.definitions = [ |         sectionTwo.definitions = [ | ||||||
|             getDefinition(name: "s2_def_one", |             getDefinition(name: "s2_def_one", | ||||||
| @@ -212,7 +474,7 @@ final class StringsFileGeneratorTests: XCTestCase { | |||||||
|                           translations: ["fr": "Section Deux - Definition Deux"], |                           translations: ["fr": "Section Deux - Definition Deux"], | ||||||
|                           tags: ["notranslation"]) |                           tags: ["notranslation"]) | ||||||
|         ] |         ] | ||||||
|          |  | ||||||
|         // When |         // When | ||||||
|         let extensionContent = StringsFileGenerator.getExtensionContent(sections: [sectionOne, sectionTwo], |         let extensionContent = StringsFileGenerator.getExtensionContent(sections: [sectionOne, sectionTwo], | ||||||
|                                                                         defaultLang: "fr", |                                                                         defaultLang: "fr", | ||||||
| @@ -221,23 +483,23 @@ final class StringsFileGeneratorTests: XCTestCase { | |||||||
|                                                                         inputFilename: "myInputFilename", |                                                                         inputFilename: "myInputFilename", | ||||||
|                                                                         extensionName: "GenStrings", |                                                                         extensionName: "GenStrings", | ||||||
|                                                                         extensionSuffix: "strings") |                                                                         extensionSuffix: "strings") | ||||||
|          |  | ||||||
|         // Expect |         // Expect | ||||||
|         let expect = """ |         let expect = """ | ||||||
|         // Generated by ResgenSwift.Strings.Stringium \(ResgenSwiftVersion) |         // Generated by ResgenSwift.Strings.Stringium \(ResgenSwiftVersion) | ||||||
|          |  | ||||||
|         import UIKit |         import UIKit | ||||||
|          |  | ||||||
|         fileprivate let kStringsFileName = "myInputFilename" |         fileprivate let kStringsFileName = "myInputFilename" | ||||||
|          |  | ||||||
|         extension GenStrings { |         extension GenStrings { | ||||||
|          |  | ||||||
|             enum KeyStrings: String { |             enum KeyStrings: String { | ||||||
|                 case s1_def_one = "s1_def_one" |                 case s1_def_one = "s1_def_one" | ||||||
|                 case s1_def_two = "s1_def_two" |                 case s1_def_two = "s1_def_two" | ||||||
|                 case s2_def_one = "s2_def_one" |                 case s2_def_one = "s2_def_one" | ||||||
|                 case s2_def_two = "s2_def_two" |                 case s2_def_two = "s2_def_two" | ||||||
|          |  | ||||||
|                 var keyPath: KeyPath<GenStrings, String> { |                 var keyPath: KeyPath<GenStrings, String> { | ||||||
|                     switch self { |                     switch self { | ||||||
|                     case .s1_def_one: return \\GenStrings.s1_def_one |                     case .s1_def_one: return \\GenStrings.s1_def_one | ||||||
| @@ -247,9 +509,9 @@ final class StringsFileGeneratorTests: XCTestCase { | |||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|          |  | ||||||
|             // MARK: - section_one |             // MARK: - section_one | ||||||
|          |  | ||||||
|             /// Translation in fr : |             /// Translation in fr : | ||||||
|             /// Section Un - Definition Un |             /// Section Un - Definition Un | ||||||
|             /// |             /// | ||||||
| @@ -258,7 +520,7 @@ final class StringsFileGeneratorTests: XCTestCase { | |||||||
|             var s1_def_one: String { |             var s1_def_one: String { | ||||||
|                 NSLocalizedString("s1_def_one", tableName: kStringsFileName, bundle: Bundle.main, value: "Section Un - Definition Un", comment: "") |                 NSLocalizedString("s1_def_one", tableName: kStringsFileName, bundle: Bundle.main, value: "Section Un - Definition Un", comment: "") | ||||||
|             } |             } | ||||||
|          |  | ||||||
|             /// Translation in fr : |             /// Translation in fr : | ||||||
|             /// Section Un - Definition Deux |             /// Section Un - Definition Deux | ||||||
|             /// |             /// | ||||||
| @@ -267,9 +529,9 @@ final class StringsFileGeneratorTests: XCTestCase { | |||||||
|             var s1_def_two: String { |             var s1_def_two: String { | ||||||
|                 NSLocalizedString("s1_def_two", tableName: kStringsFileName, bundle: Bundle.main, value: "Section Un - Definition Deux", comment: "") |                 NSLocalizedString("s1_def_two", tableName: kStringsFileName, bundle: Bundle.main, value: "Section Un - Definition Deux", comment: "") | ||||||
|             } |             } | ||||||
|          |  | ||||||
|             // MARK: - section_two |             // MARK: - section_two | ||||||
|          |  | ||||||
|             /// Translation in fr : |             /// Translation in fr : | ||||||
|             /// Section Deux - Definition Un |             /// Section Deux - Definition Un | ||||||
|             /// |             /// | ||||||
| @@ -278,7 +540,7 @@ final class StringsFileGeneratorTests: XCTestCase { | |||||||
|             var s2_def_one: String { |             var s2_def_one: String { | ||||||
|                 NSLocalizedString("s2_def_one", tableName: kStringsFileName, bundle: Bundle.main, value: "Section Deux - Definition Un", comment: "") |                 NSLocalizedString("s2_def_one", tableName: kStringsFileName, bundle: Bundle.main, value: "Section Deux - Definition Un", comment: "") | ||||||
|             } |             } | ||||||
|          |  | ||||||
|             /// Translation in fr : |             /// Translation in fr : | ||||||
|             /// Section Deux - Definition Deux |             /// Section Deux - Definition Deux | ||||||
|             /// |             /// | ||||||
| @@ -289,7 +551,7 @@ final class StringsFileGeneratorTests: XCTestCase { | |||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         """ |         """ | ||||||
|          |  | ||||||
|         if extensionContent != expect { |         if extensionContent != expect { | ||||||
|             print(prettyFirstDifferenceBetweenStrings(s1: extensionContent, s2: expect)) |             print(prettyFirstDifferenceBetweenStrings(s1: extensionContent, s2: expect)) | ||||||
|         } |         } | ||||||
| @@ -422,7 +684,7 @@ final class StringsFileGeneratorTests: XCTestCase { | |||||||
|                                          "en": "Section One - Definition Two"], |                                          "en": "Section One - Definition Two"], | ||||||
|                           tags: ["ios","iosonly"]) |                           tags: ["ios","iosonly"]) | ||||||
|         ] |         ] | ||||||
|          |  | ||||||
|         let sectionTwo = Section(name: "section_two") |         let sectionTwo = Section(name: "section_two") | ||||||
|         sectionTwo.definitions = [ |         sectionTwo.definitions = [ | ||||||
|             getDefinition(name: "s2_def_one", |             getDefinition(name: "s2_def_one", | ||||||
| @@ -433,7 +695,7 @@ final class StringsFileGeneratorTests: XCTestCase { | |||||||
|                           translations: ["fr": "Section Deux - Definition Deux"], |                           translations: ["fr": "Section Deux - Definition Deux"], | ||||||
|                           tags: ["notranslation"]) |                           tags: ["notranslation"]) | ||||||
|         ] |         ] | ||||||
|          |  | ||||||
|         // When |         // When | ||||||
|         let extensionContent = StringsFileGenerator.getExtensionContent(sections: [sectionOne, sectionTwo], |         let extensionContent = StringsFileGenerator.getExtensionContent(sections: [sectionOne, sectionTwo], | ||||||
|                                                                         defaultLang: "fr", |                                                                         defaultLang: "fr", | ||||||
| @@ -442,23 +704,23 @@ final class StringsFileGeneratorTests: XCTestCase { | |||||||
|                                                                         inputFilename: "myInputFilename", |                                                                         inputFilename: "myInputFilename", | ||||||
|                                                                         extensionName: "GenStrings", |                                                                         extensionName: "GenStrings", | ||||||
|                                                                         extensionSuffix: "strings") |                                                                         extensionSuffix: "strings") | ||||||
|          |  | ||||||
|         // Expect |         // Expect | ||||||
|         let expect = """ |         let expect = """ | ||||||
|         // Generated by ResgenSwift.Strings.Stringium \(ResgenSwiftVersion) |         // Generated by ResgenSwift.Strings.Stringium \(ResgenSwiftVersion) | ||||||
|          |  | ||||||
|         import UIKit |         import UIKit | ||||||
|          |  | ||||||
|         fileprivate let kStringsFileName = "myInputFilename" |         fileprivate let kStringsFileName = "myInputFilename" | ||||||
|          |  | ||||||
|         extension GenStrings { |         extension GenStrings { | ||||||
|          |  | ||||||
|             enum KeyStrings: String { |             enum KeyStrings: String { | ||||||
|                 case s1_def_one = "s1_def_one" |                 case s1_def_one = "s1_def_one" | ||||||
|                 case s1_def_two = "s1_def_two" |                 case s1_def_two = "s1_def_two" | ||||||
|                 case s2_def_one = "s2_def_one" |                 case s2_def_one = "s2_def_one" | ||||||
|                 case s2_def_two = "s2_def_two" |                 case s2_def_two = "s2_def_two" | ||||||
|          |  | ||||||
|                 var keyPath: KeyPath<GenStrings, String> { |                 var keyPath: KeyPath<GenStrings, String> { | ||||||
|                     switch self { |                     switch self { | ||||||
|                     case .s1_def_one: return \\GenStrings.s1_def_one |                     case .s1_def_one: return \\GenStrings.s1_def_one | ||||||
| @@ -468,9 +730,9 @@ final class StringsFileGeneratorTests: XCTestCase { | |||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|          |  | ||||||
|             // MARK: - section_one |             // MARK: - section_one | ||||||
|          |  | ||||||
|             /// Translation in fr : |             /// Translation in fr : | ||||||
|             /// Section Un - Definition Un |             /// Section Un - Definition Un | ||||||
|             /// |             /// | ||||||
| @@ -479,7 +741,7 @@ final class StringsFileGeneratorTests: XCTestCase { | |||||||
|             static var s1_def_one: String { |             static var s1_def_one: String { | ||||||
|                 NSLocalizedString("s1_def_one", tableName: kStringsFileName, bundle: Bundle.main, value: "Section Un - Definition Un", comment: "") |                 NSLocalizedString("s1_def_one", tableName: kStringsFileName, bundle: Bundle.main, value: "Section Un - Definition Un", comment: "") | ||||||
|             } |             } | ||||||
|          |  | ||||||
|             /// Translation in fr : |             /// Translation in fr : | ||||||
|             /// Section Un - Definition Deux |             /// Section Un - Definition Deux | ||||||
|             /// |             /// | ||||||
| @@ -488,9 +750,9 @@ final class StringsFileGeneratorTests: XCTestCase { | |||||||
|             static var s1_def_two: String { |             static var s1_def_two: String { | ||||||
|                 NSLocalizedString("s1_def_two", tableName: kStringsFileName, bundle: Bundle.main, value: "Section Un - Definition Deux", comment: "") |                 NSLocalizedString("s1_def_two", tableName: kStringsFileName, bundle: Bundle.main, value: "Section Un - Definition Deux", comment: "") | ||||||
|             } |             } | ||||||
|          |  | ||||||
|             // MARK: - section_two |             // MARK: - section_two | ||||||
|          |  | ||||||
|             /// Translation in fr : |             /// Translation in fr : | ||||||
|             /// Section Deux - Definition Un |             /// Section Deux - Definition Un | ||||||
|             /// |             /// | ||||||
| @@ -499,7 +761,7 @@ final class StringsFileGeneratorTests: XCTestCase { | |||||||
|             static var s2_def_one: String { |             static var s2_def_one: String { | ||||||
|                 NSLocalizedString("s2_def_one", tableName: kStringsFileName, bundle: Bundle.main, value: "Section Deux - Definition Un", comment: "") |                 NSLocalizedString("s2_def_one", tableName: kStringsFileName, bundle: Bundle.main, value: "Section Deux - Definition Un", comment: "") | ||||||
|             } |             } | ||||||
|          |  | ||||||
|             /// Translation in fr : |             /// Translation in fr : | ||||||
|             /// Section Deux - Definition Deux |             /// Section Deux - Definition Deux | ||||||
|             /// |             /// | ||||||
| @@ -510,7 +772,7 @@ final class StringsFileGeneratorTests: XCTestCase { | |||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         """ |         """ | ||||||
|          |  | ||||||
|         if extensionContent != expect { |         if extensionContent != expect { | ||||||
|             print(prettyFirstDifferenceBetweenStrings(s1: extensionContent, s2: expect)) |             print(prettyFirstDifferenceBetweenStrings(s1: extensionContent, s2: expect)) | ||||||
|         } |         } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user