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))
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user