xcstrings #10
2
Jenkinsfile
vendored
2
Jenkinsfile
vendored
@ -1,6 +1,6 @@
|
|||||||
library "openiumpipeline"
|
library "openiumpipeline"
|
||||||
|
|
||||||
env.DEVELOPER_DIR="/Applications/Xcode-15.0.1.app/Contents/Developer"
|
env.DEVELOPER_DIR="/Applications/Xcode-15.3.0.app/Contents/Developer"
|
||||||
//env.SIMULATOR_DEVICE_TYPES="iPad--7th-generation-"
|
//env.SIMULATOR_DEVICE_TYPES="iPad--7th-generation-"
|
||||||
env.IS_PACKAGE_SWIFT=1
|
env.IS_PACKAGE_SWIFT=1
|
||||||
env.TARGETS_MACOS=1
|
env.TARGETS_MACOS=1
|
||||||
|
@ -14,8 +14,8 @@
|
|||||||
"kind" : "remoteSourceControl",
|
"kind" : "remoteSourceControl",
|
||||||
"location" : "https://github.com/krzyzanowskim/CryptoSwift.git",
|
"location" : "https://github.com/krzyzanowskim/CryptoSwift.git",
|
||||||
"state" : {
|
"state" : {
|
||||||
"revision" : "db51c407d3be4a051484a141bf0bff36c43d3b1e",
|
"revision" : "c9c3df6ab812de32bae61fc0cd1bf6d45170ebf0",
|
||||||
"version" : "1.8.0"
|
"version" : "1.8.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -9,7 +9,7 @@ import Foundation
|
|||||||
|
|
||||||
enum GenerateError: Error {
|
enum GenerateError: Error {
|
||||||
case fileNotExists(String)
|
case fileNotExists(String)
|
||||||
case invalidConfigurationFile(String)
|
case invalidConfigurationFile(String, String)
|
||||||
case commandError([String], String)
|
case commandError([String], String)
|
||||||
case writeFile(String, String)
|
case writeFile(String, String)
|
||||||
|
|
||||||
@ -18,8 +18,8 @@ enum GenerateError: Error {
|
|||||||
case .fileNotExists(let filename):
|
case .fileNotExists(let filename):
|
||||||
return "error: [\(Generate.toolName)] File \(filename) does not exists"
|
return "error: [\(Generate.toolName)] File \(filename) does not exists"
|
||||||
|
|
||||||
case .invalidConfigurationFile(let filename):
|
case .invalidConfigurationFile(let filename, let underneathErrorDescription):
|
||||||
return "error: [\(Generate.toolName)] File \(filename) is not a valid configuration file"
|
return "error: [\(Generate.toolName)] File \(filename) is not a valid configuration file. Underneath error: \(underneathErrorDescription)"
|
||||||
|
|
||||||
case .commandError(let command, let terminationStatus):
|
case .commandError(let command, let terminationStatus):
|
||||||
let readableCommand = command
|
let readableCommand = command
|
||||||
|
@ -269,6 +269,7 @@ struct StringsConfiguration: Codable, CustomDebugStringConvertible {
|
|||||||
let extensionName: String?
|
let extensionName: String?
|
||||||
let extensionSuffix: String?
|
let extensionSuffix: String?
|
||||||
private let staticMembers: Bool?
|
private let staticMembers: Bool?
|
||||||
|
private let xcStrings: Bool?
|
||||||
|
|
||||||
var staticMembersOptions: Bool {
|
var staticMembersOptions: Bool {
|
||||||
if let staticMembers = staticMembers {
|
if let staticMembers = staticMembers {
|
||||||
@ -277,6 +278,13 @@ struct StringsConfiguration: Codable, CustomDebugStringConvertible {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var xcStringsOptions: Bool {
|
||||||
|
if let xcStrings = xcStrings {
|
||||||
|
return xcStrings
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
internal init(inputFile: String,
|
internal init(inputFile: String,
|
||||||
outputPath: String,
|
outputPath: String,
|
||||||
langs: String,
|
langs: String,
|
||||||
@ -284,7 +292,8 @@ struct StringsConfiguration: Codable, CustomDebugStringConvertible {
|
|||||||
extensionOutputPath: String,
|
extensionOutputPath: String,
|
||||||
extensionName: String?,
|
extensionName: String?,
|
||||||
extensionSuffix: String?,
|
extensionSuffix: String?,
|
||||||
staticMembers: Bool?) {
|
staticMembers: Bool?,
|
||||||
|
xcStrings: Bool?) {
|
||||||
self.inputFile = inputFile
|
self.inputFile = inputFile
|
||||||
self.outputPath = outputPath
|
self.outputPath = outputPath
|
||||||
self.langs = langs
|
self.langs = langs
|
||||||
@ -293,6 +302,7 @@ struct StringsConfiguration: Codable, CustomDebugStringConvertible {
|
|||||||
self.extensionName = extensionName
|
self.extensionName = extensionName
|
||||||
self.extensionSuffix = extensionSuffix
|
self.extensionSuffix = extensionSuffix
|
||||||
self.staticMembers = staticMembers
|
self.staticMembers = staticMembers
|
||||||
|
self.xcStrings = xcStrings
|
||||||
}
|
}
|
||||||
|
|
||||||
var debugDescription: String {
|
var debugDescription: String {
|
||||||
|
@ -16,12 +16,15 @@ class ConfigurationFileParser {
|
|||||||
Generate.exit(withError: error)
|
Generate.exit(withError: error)
|
||||||
}
|
}
|
||||||
|
|
||||||
guard let configuration = try? YAMLDecoder().decode(ConfigurationFile.self, from: data) else {
|
do {
|
||||||
let error = GenerateError.invalidConfigurationFile(configurationFile)
|
return try YAMLDecoder().decode(ConfigurationFile.self, from: data)
|
||||||
|
} catch {
|
||||||
|
let error = GenerateError.invalidConfigurationFile(
|
||||||
|
configurationFile,
|
||||||
|
error.localizedDescription.description
|
||||||
|
)
|
||||||
print(error.description)
|
print(error.description)
|
||||||
Generate.exit(withError: error)
|
Generate.exit(withError: error)
|
||||||
}
|
}
|
||||||
|
|
||||||
return configuration
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,9 @@ extension StringsConfiguration: Runnable {
|
|||||||
"--extension-output-path",
|
"--extension-output-path",
|
||||||
extensionOutputPath.prependIfRelativePath(projectDirectory),
|
extensionOutputPath.prependIfRelativePath(projectDirectory),
|
||||||
"--static-members",
|
"--static-members",
|
||||||
"\(staticMembersOptions)"
|
"\(staticMembersOptions)",
|
||||||
|
"--xc-strings",
|
||||||
|
"\(xcStringsOptions)"
|
||||||
]
|
]
|
||||||
|
|
||||||
if let extensionName = extensionName {
|
if let extensionName = extensionName {
|
||||||
|
@ -18,6 +18,7 @@ class StringsFileGenerator {
|
|||||||
tags: [String],
|
tags: [String],
|
||||||
outputPath: String,
|
outputPath: String,
|
||||||
inputFilenameWithoutExt: String) {
|
inputFilenameWithoutExt: String) {
|
||||||
|
|
||||||
var stringsFilesContent = [String: String]()
|
var stringsFilesContent = [String: String]()
|
||||||
for lang in langs {
|
for lang in langs {
|
||||||
stringsFilesContent[lang] = Self.generateStringsFileContent(lang: lang,
|
stringsFilesContent[lang] = Self.generateStringsFileContent(lang: lang,
|
||||||
@ -42,6 +43,31 @@ class StringsFileGenerator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static func writeXcStringsFiles(sections: [Section],
|
||||||
|
langs: [String],
|
||||||
|
defaultLang: String,
|
||||||
|
tags: [String],
|
||||||
|
outputPath: String,
|
||||||
|
inputFilenameWithoutExt: String) {
|
||||||
|
|
||||||
|
let fileContent: String = Self.generateXcStringsFileContent(
|
||||||
|
langs: langs,
|
||||||
|
defaultLang: defaultLang,
|
||||||
|
tags: tags,
|
||||||
|
sections: sections
|
||||||
|
)
|
||||||
|
|
||||||
|
let stringsFilePath = "\(outputPath)/\(inputFilenameWithoutExt).xcstrings"
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static func generateStringsFileContent(lang: String,
|
static func generateStringsFileContent(lang: String,
|
||||||
defaultLang: String,
|
defaultLang: String,
|
||||||
tags inputTags: [String],
|
tags inputTags: [String],
|
||||||
@ -92,6 +118,117 @@ 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 isNoTranslation = false
|
||||||
|
|
||||||
|
var localizationTab: [XCStringLocalization] = []
|
||||||
|
|
||||||
|
if definition.hasOneOrMoreMatchingTags(inputTags: inputTags) == false {
|
||||||
|
skipDefinition = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if definition.tags.contains(Stringium.noTranslationTag) {
|
||||||
|
isNoTranslation = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if !skipDefinition {
|
||||||
|
if isNoTranslation {
|
||||||
|
// Search for langs in yaml
|
||||||
|
for lang in langs {
|
||||||
|
if let value = definition.translations[defaultLang], !value.isEmpty {
|
||||||
|
let localization = XCStringLocalization(
|
||||||
|
lang: lang,
|
||||||
|
content: XCStringLocalizationLangContent(
|
||||||
|
stringUnit: DefaultStringUnit(state: "translated", value: value)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
localizationTab.append(localization)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Search for langs in twine
|
||||||
|
for (lang, value) in definition.translations where !value.isEmpty {
|
||||||
|
|
||||||
|
let localization = XCStringLocalization(
|
||||||
|
lang: lang,
|
||||||
|
content: XCStringLocalizationLangContent(
|
||||||
|
stringUnit: DefaultStringUnit(state: "translated", value: value)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
localizationTab.append(localization)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let xcStringDefinition = XCStringDefinition(
|
||||||
|
title: definition.name,
|
||||||
|
content: XCStringDefinitionContent(
|
||||||
|
comment: definition.comment,
|
||||||
|
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],
|
||||||
|
@ -84,22 +84,29 @@ class Definition {
|
|||||||
return (inputParameters: inputParameters, translationArguments: translationArguments)
|
return (inputParameters: inputParameters, translationArguments: translationArguments)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func getBaseProperty(lang: String, translation: String, isStatic: Bool) -> String {
|
private func getBaseProperty(lang: String, translation: String, isStatic: Bool, comment: String?) -> String {
|
||||||
"""
|
"""
|
||||||
/// Translation in \(lang) :
|
/// Translation in \(lang) :
|
||||||
/// \(translation)
|
/// \(translation)
|
||||||
|
///
|
||||||
|
/// Comment :
|
||||||
|
/// \(comment?.isEmpty == false ? comment! : "No comment")
|
||||||
\(isStatic ? "static ": "")var \(name): String {
|
\(isStatic ? "static ": "")var \(name): String {
|
||||||
NSLocalizedString("\(name)", tableName: kStringsFileName, bundle: Bundle.main, value: "\(translation)", comment: "")
|
NSLocalizedString("\(name)", tableName: kStringsFileName, bundle: Bundle.main, value: "\(translation)", comment: "\(comment ?? "")")
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private func getBaseMethod(lang: String, translation: String, isStatic: Bool, inputParameters: [String], translationArguments: [String]) -> String {
|
private func getBaseMethod(lang: String, translation: String, isStatic: Bool, inputParameters: [String], translationArguments: [String], comment: String?) -> String {
|
||||||
"""
|
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
/// Translation in \(lang) :
|
/// Translation in \(lang) :
|
||||||
/// \(translation)
|
/// \(translation)
|
||||||
|
///
|
||||||
|
/// Comment :
|
||||||
|
/// \(comment?.isEmpty == false ? comment! : "No comment")
|
||||||
\(isStatic ? "static ": "")func \(name)(\(inputParameters.joined(separator: ", "))) -> String {
|
\(isStatic ? "static ": "")func \(name)(\(inputParameters.joined(separator: ", "))) -> String {
|
||||||
String(format: \(isStatic ? "Self" : "self").\(name), \(translationArguments.joined(separator: ", ")))
|
String(format: \(isStatic ? "Self" : "self").\(name), \(translationArguments.joined(separator: ", ")))
|
||||||
}
|
}
|
||||||
@ -114,7 +121,12 @@ class Definition {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Generate property
|
// Generate property
|
||||||
let property = getBaseProperty(lang: lang, translation: translation, isStatic: false)
|
let property = getBaseProperty(
|
||||||
|
lang: lang,
|
||||||
|
translation: translation,
|
||||||
|
isStatic: false,
|
||||||
|
comment: self.comment
|
||||||
|
)
|
||||||
|
|
||||||
// Generate method
|
// Generate method
|
||||||
var method = ""
|
var method = ""
|
||||||
@ -123,7 +135,8 @@ class Definition {
|
|||||||
translation: translation,
|
translation: translation,
|
||||||
isStatic: false,
|
isStatic: false,
|
||||||
inputParameters: parameters.inputParameters,
|
inputParameters: parameters.inputParameters,
|
||||||
translationArguments: parameters.translationArguments)
|
translationArguments: parameters.translationArguments,
|
||||||
|
comment: self.comment)
|
||||||
}
|
}
|
||||||
|
|
||||||
return property + method
|
return property + method
|
||||||
@ -137,7 +150,12 @@ class Definition {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Generate property
|
// Generate property
|
||||||
let property = getBaseProperty(lang: lang, translation: translation, isStatic: true)
|
let property = getBaseProperty(
|
||||||
|
lang: lang,
|
||||||
|
translation: translation,
|
||||||
|
isStatic: true,
|
||||||
|
comment: self.comment
|
||||||
|
)
|
||||||
|
|
||||||
// Generate method
|
// Generate method
|
||||||
var method = ""
|
var method = ""
|
||||||
@ -146,7 +164,8 @@ class Definition {
|
|||||||
translation: translation,
|
translation: translation,
|
||||||
isStatic: true,
|
isStatic: true,
|
||||||
inputParameters: parameters.inputParameters,
|
inputParameters: parameters.inputParameters,
|
||||||
translationArguments: parameters.translationArguments)
|
translationArguments: parameters.translationArguments,
|
||||||
|
comment: self.comment)
|
||||||
}
|
}
|
||||||
|
|
||||||
return property + method
|
return property + method
|
||||||
@ -164,6 +183,10 @@ class Definition {
|
|||||||
return """
|
return """
|
||||||
/// Translation in \(lang) :
|
/// Translation in \(lang) :
|
||||||
/// \(translation)
|
/// \(translation)
|
||||||
|
///
|
||||||
|
/// Comment :
|
||||||
|
/// \(comment?.isEmpty == false ? comment! : "No comment")
|
||||||
|
|
||||||
var \(name): String {
|
var \(name): String {
|
||||||
"\(translation)"
|
"\(translation)"
|
||||||
}
|
}
|
||||||
@ -180,6 +203,9 @@ class Definition {
|
|||||||
return """
|
return """
|
||||||
/// Translation in \(lang) :
|
/// Translation in \(lang) :
|
||||||
/// \(translation)
|
/// \(translation)
|
||||||
|
///
|
||||||
|
/// Comment :
|
||||||
|
/// \(comment?.isEmpty == false ? comment! : "No comment")
|
||||||
static var \(name): String {
|
static var \(name): String {
|
||||||
"\(translation)"
|
"\(translation)"
|
||||||
}
|
}
|
||||||
|
109
Sources/ResgenSwift/Strings/Model/XcString.swift
Normal file
109
Sources/ResgenSwift/Strings/Model/XcString.swift
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
//
|
||||||
|
// 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static func == (lhs: XCStringDefinitionContainer, rhs: XCStringDefinitionContainer) -> Bool {
|
||||||
|
return lhs.strings.sorted(by: {
|
||||||
|
$0.title < $1.title
|
||||||
|
}) == rhs.strings.sorted(by: { $0.title < $1.title })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct XCStringDefinition: Codable, Equatable {
|
||||||
|
let title: String // json key -> custom encoding methods
|
||||||
|
let content: XCStringDefinitionContent
|
||||||
|
}
|
||||||
|
|
||||||
|
struct XCStringDefinitionContent: Codable, Equatable {
|
||||||
|
let comment: String?
|
||||||
|
let extractionState: String
|
||||||
|
var localizations: XCStringLocalizationContainer
|
||||||
|
|
||||||
|
init(comment: String? = nil, extractionState: String, localizations: XCStringLocalizationContainer) {
|
||||||
|
self.comment = comment
|
||||||
|
self.extractionState = extractionState
|
||||||
|
self.localizations = localizations
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static func == (lhs: XCStringLocalizationContainer, rhs: XCStringLocalizationContainer) -> Bool {
|
||||||
|
return lhs.localizations.count == rhs.localizations.count && lhs.localizations.sorted(by: { $0.lang < $1.lang }) == rhs.localizations.sorted(by: { $0.lang < $1.lang })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
@ -43,12 +43,25 @@ struct Stringium: ParsableCommand {
|
|||||||
let sections = TwineFileParser.parse(options.inputFile)
|
let sections = TwineFileParser.parse(options.inputFile)
|
||||||
|
|
||||||
// Generate strings files
|
// Generate strings files
|
||||||
StringsFileGenerator.writeStringsFiles(sections: sections,
|
print(options.xcStrings)
|
||||||
langs: options.langs,
|
if !options.xcStrings {
|
||||||
defaultLang: options.defaultLang,
|
print("[\(Self.toolName)] Will generate strings")
|
||||||
tags: options.tags,
|
|
||||||
outputPath: options.stringsFileOutputPath,
|
StringsFileGenerator.writeStringsFiles(sections: sections,
|
||||||
inputFilenameWithoutExt: options.inputFilenameWithoutExt)
|
langs: options.langs,
|
||||||
|
defaultLang: options.defaultLang,
|
||||||
|
tags: options.tags,
|
||||||
|
outputPath: options.stringsFileOutputPath,
|
||||||
|
inputFilenameWithoutExt: options.inputFilenameWithoutExt)
|
||||||
|
} else {
|
||||||
|
print("[\(Self.toolName)] Will generate xcStrings")
|
||||||
|
StringsFileGenerator.writeXcStringsFiles(sections: sections,
|
||||||
|
langs: options.langs,
|
||||||
|
defaultLang: options.defaultLang,
|
||||||
|
tags: options.tags,
|
||||||
|
outputPath: options.stringsFileOutputPath,
|
||||||
|
inputFilenameWithoutExt: options.inputFilenameWithoutExt)
|
||||||
|
}
|
||||||
|
|
||||||
// Generate extension
|
// Generate extension
|
||||||
StringsFileGenerator.writeExtensionFiles(sections: sections,
|
StringsFileGenerator.writeExtensionFiles(sections: sections,
|
||||||
|
@ -12,7 +12,7 @@ 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
|
||||||
|
|
||||||
@Argument(help: "Input files where strings ared defined.", transform: { $0.replaceTiltWithHomeDirectoryPath() })
|
@Argument(help: "Input files where strings are defined.", transform: { $0.replaceTiltWithHomeDirectoryPath() })
|
||||||
var inputFile: String
|
var inputFile: String
|
||||||
|
|
||||||
@Option(name: .customLong("output-path"), help: "Path where to strings file.", transform: { $0.replaceTiltWithHomeDirectoryPath() })
|
@Option(name: .customLong("output-path"), help: "Path where to strings file.", transform: { $0.replaceTiltWithHomeDirectoryPath() })
|
||||||
@ -33,6 +33,9 @@ struct StringiumOptions: ParsableArguments {
|
|||||||
@Option(help: "Tell if it will generate static properties or not")
|
@Option(help: "Tell if it will generate static properties or not")
|
||||||
var staticMembers: Bool = false
|
var staticMembers: Bool = false
|
||||||
|
|
||||||
|
@Option(help: "Tell if it will generate xcStrings file or not")
|
||||||
|
var xcStrings: Bool = false
|
||||||
|
|
||||||
@Option(help: "Extension name. If not specified, it will generate an String extension.")
|
@Option(help: "Extension name. If not specified, it will generate an String extension.")
|
||||||
var extensionName: String = Stringium.defaultExtensionName
|
var extensionName: String = Stringium.defaultExtensionName
|
||||||
|
|
||||||
|
@ -91,7 +91,7 @@ final class ParsedColorTests: XCTestCase {
|
|||||||
// When
|
// When
|
||||||
let contentJson = color.contentsJSON()
|
let contentJson = color.contentsJSON()
|
||||||
guard let data = contentJson.data(using: .utf8),
|
guard let data = contentJson.data(using: .utf8),
|
||||||
let parsedJson = try? JSONSerialization.jsonObject(with: data) as? [String: Any] else {
|
let parsedJson = try? JSONSerialization.jsonObject(with: data) as? [String: Any] else {
|
||||||
XCTFail("Cannot convert `contentJSON` string to Data")
|
XCTFail("Cannot convert `contentJSON` string to Data")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -100,6 +100,64 @@ final class DefinitionTests: XCTestCase {
|
|||||||
let expectFr = """
|
let expectFr = """
|
||||||
/// Translation in fr :
|
/// Translation in fr :
|
||||||
/// C'est la traduction francaise
|
/// C'est la traduction francaise
|
||||||
|
///
|
||||||
|
/// Comment :
|
||||||
|
/// This is a comment
|
||||||
|
var definition_name: String {
|
||||||
|
NSLocalizedString("definition_name", tableName: kStringsFileName, bundle: Bundle.main, value: "C'est la traduction francaise", comment: "This is a comment")
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
let expectEn = """
|
||||||
|
/// Translation in en :
|
||||||
|
/// This is the english translation
|
||||||
|
///
|
||||||
|
/// Comment :
|
||||||
|
/// This is a comment
|
||||||
|
var definition_name: String {
|
||||||
|
NSLocalizedString("definition_name", tableName: kStringsFileName, bundle: Bundle.main, value: "This is the english translation", comment: "This is a comment")
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
let expectEnUs = """
|
||||||
|
/// Translation in en-us :
|
||||||
|
/// This is the english us translation
|
||||||
|
///
|
||||||
|
/// Comment :
|
||||||
|
/// This is a comment
|
||||||
|
var definition_name: String {
|
||||||
|
NSLocalizedString("definition_name", tableName: kStringsFileName, bundle: Bundle.main, value: "This is the english us translation", comment: "This is a comment")
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
XCTAssertEqual(propertyFr.adaptForXCTest(), expectFr.adaptForXCTest())
|
||||||
|
XCTAssertEqual(propertyEn.adaptForXCTest(), expectEn.adaptForXCTest())
|
||||||
|
XCTAssertEqual(propertyEnUs.adaptForXCTest(), expectEnUs.adaptForXCTest())
|
||||||
|
}
|
||||||
|
|
||||||
|
func testGeneratedNSLocalizedStringPropertyWithEmptyComment() {
|
||||||
|
// Given
|
||||||
|
let definition = Definition(name: "definition_name")
|
||||||
|
definition.tags = ["ios","iosonly","notranslation"]
|
||||||
|
definition.comment = ""
|
||||||
|
definition.translations = [
|
||||||
|
"fr": "C'est la traduction francaise",
|
||||||
|
"en": "This is the english translation",
|
||||||
|
"en-us": "This is the english us translation"
|
||||||
|
]
|
||||||
|
|
||||||
|
// When
|
||||||
|
let propertyFr = definition.getNSLocalizedStringProperty(forLang: "fr")
|
||||||
|
let propertyEn = definition.getNSLocalizedStringProperty(forLang: "en")
|
||||||
|
let propertyEnUs = definition.getNSLocalizedStringProperty(forLang: "en-us")
|
||||||
|
|
||||||
|
// Expect
|
||||||
|
let expectFr = """
|
||||||
|
/// Translation in fr :
|
||||||
|
/// C'est la traduction francaise
|
||||||
|
///
|
||||||
|
/// Comment :
|
||||||
|
/// No comment
|
||||||
var definition_name: String {
|
var definition_name: String {
|
||||||
NSLocalizedString("definition_name", tableName: kStringsFileName, bundle: Bundle.main, value: "C'est la traduction francaise", comment: "")
|
NSLocalizedString("definition_name", tableName: kStringsFileName, bundle: Bundle.main, value: "C'est la traduction francaise", comment: "")
|
||||||
}
|
}
|
||||||
@ -108,6 +166,9 @@ final class DefinitionTests: XCTestCase {
|
|||||||
let expectEn = """
|
let expectEn = """
|
||||||
/// Translation in en :
|
/// Translation in en :
|
||||||
/// This is the english translation
|
/// This is the english translation
|
||||||
|
///
|
||||||
|
/// Comment :
|
||||||
|
/// No comment
|
||||||
var definition_name: String {
|
var definition_name: String {
|
||||||
NSLocalizedString("definition_name", tableName: kStringsFileName, bundle: Bundle.main, value: "This is the english translation", comment: "")
|
NSLocalizedString("definition_name", tableName: kStringsFileName, bundle: Bundle.main, value: "This is the english translation", comment: "")
|
||||||
}
|
}
|
||||||
@ -116,6 +177,9 @@ final class DefinitionTests: XCTestCase {
|
|||||||
let expectEnUs = """
|
let expectEnUs = """
|
||||||
/// Translation in en-us :
|
/// Translation in en-us :
|
||||||
/// This is the english us translation
|
/// This is the english us translation
|
||||||
|
///
|
||||||
|
/// Comment :
|
||||||
|
/// No comment
|
||||||
var definition_name: String {
|
var definition_name: String {
|
||||||
NSLocalizedString("definition_name", tableName: kStringsFileName, bundle: Bundle.main, value: "This is the english us translation", comment: "")
|
NSLocalizedString("definition_name", tableName: kStringsFileName, bundle: Bundle.main, value: "This is the english us translation", comment: "")
|
||||||
}
|
}
|
||||||
@ -126,6 +190,62 @@ final class DefinitionTests: XCTestCase {
|
|||||||
XCTAssertEqual(propertyEnUs.adaptForXCTest(), expectEnUs.adaptForXCTest())
|
XCTAssertEqual(propertyEnUs.adaptForXCTest(), expectEnUs.adaptForXCTest())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func testGeneratedNSLocalizedStringPropertyWithNoComment() {
|
||||||
|
// Given
|
||||||
|
let definition = Definition(name: "definition_name")
|
||||||
|
definition.tags = ["ios","iosonly","notranslation"]
|
||||||
|
definition.translations = [
|
||||||
|
"fr": "C'est la traduction francaise",
|
||||||
|
"en": "This is the english translation",
|
||||||
|
"en-us": "This is the english us translation"
|
||||||
|
]
|
||||||
|
|
||||||
|
// When
|
||||||
|
let propertyFr = definition.getNSLocalizedStringProperty(forLang: "fr")
|
||||||
|
let propertyEn = definition.getNSLocalizedStringProperty(forLang: "en")
|
||||||
|
let propertyEnUs = definition.getNSLocalizedStringProperty(forLang: "en-us")
|
||||||
|
|
||||||
|
// Expect
|
||||||
|
let expectFr = """
|
||||||
|
/// Translation in fr :
|
||||||
|
/// C'est la traduction francaise
|
||||||
|
///
|
||||||
|
/// Comment :
|
||||||
|
/// No comment
|
||||||
|
var definition_name: String {
|
||||||
|
NSLocalizedString("definition_name", tableName: kStringsFileName, bundle: Bundle.main, value: "C'est la traduction francaise", comment: "")
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
let expectEn = """
|
||||||
|
/// Translation in en :
|
||||||
|
/// This is the english translation
|
||||||
|
///
|
||||||
|
/// Comment :
|
||||||
|
/// No comment
|
||||||
|
var definition_name: String {
|
||||||
|
NSLocalizedString("definition_name", tableName: kStringsFileName, bundle: Bundle.main, value: "This is the english translation", comment: "")
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
let expectEnUs = """
|
||||||
|
/// Translation in en-us :
|
||||||
|
/// This is the english us translation
|
||||||
|
///
|
||||||
|
/// Comment :
|
||||||
|
/// No comment
|
||||||
|
var definition_name: String {
|
||||||
|
NSLocalizedString("definition_name", tableName: kStringsFileName, bundle: Bundle.main, value: "This is the english us translation", comment: "")
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
XCTAssertEqual(propertyFr.adaptForXCTest(), expectFr.adaptForXCTest())
|
||||||
|
XCTAssertEqual(propertyEn.adaptForXCTest(), expectEn.adaptForXCTest())
|
||||||
|
XCTAssertEqual(propertyEnUs.adaptForXCTest(), expectEnUs.adaptForXCTest())
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - getNSLocalizedStringStaticProperty
|
||||||
|
|
||||||
func testGeneratedNSLocalizedStringStaticProperty() {
|
func testGeneratedNSLocalizedStringStaticProperty() {
|
||||||
// Given
|
// Given
|
||||||
let definition = Definition(name: "definition_name")
|
let definition = Definition(name: "definition_name")
|
||||||
@ -146,6 +266,64 @@ final class DefinitionTests: XCTestCase {
|
|||||||
let expectFr = """
|
let expectFr = """
|
||||||
/// Translation in fr :
|
/// Translation in fr :
|
||||||
/// C'est la traduction francaise
|
/// C'est la traduction francaise
|
||||||
|
///
|
||||||
|
/// Comment :
|
||||||
|
/// This is a comment
|
||||||
|
static var definition_name: String {
|
||||||
|
NSLocalizedString("definition_name", tableName: kStringsFileName, bundle: Bundle.main, value: "C'est la traduction francaise", comment: "This is a comment")
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
let expectEn = """
|
||||||
|
/// Translation in en :
|
||||||
|
/// This is the english translation
|
||||||
|
///
|
||||||
|
/// Comment :
|
||||||
|
/// This is a comment
|
||||||
|
static var definition_name: String {
|
||||||
|
NSLocalizedString("definition_name", tableName: kStringsFileName, bundle: Bundle.main, value: "This is the english translation", comment: "This is a comment")
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
let expectEnUs = """
|
||||||
|
/// Translation in en-us :
|
||||||
|
/// This is the english us translation
|
||||||
|
///
|
||||||
|
/// Comment :
|
||||||
|
/// This is a comment
|
||||||
|
static var definition_name: String {
|
||||||
|
NSLocalizedString("definition_name", tableName: kStringsFileName, bundle: Bundle.main, value: "This is the english us translation", comment: "This is a comment")
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
XCTAssertEqual(propertyFr.adaptForXCTest(), expectFr.adaptForXCTest())
|
||||||
|
XCTAssertEqual(propertyEn.adaptForXCTest(), expectEn.adaptForXCTest())
|
||||||
|
XCTAssertEqual(propertyEnUs.adaptForXCTest(), expectEnUs.adaptForXCTest())
|
||||||
|
}
|
||||||
|
|
||||||
|
func testGeneratedNSLocalizedStringStaticPropertyWithEmptyComment() {
|
||||||
|
// Given
|
||||||
|
let definition = Definition(name: "definition_name")
|
||||||
|
definition.tags = ["ios","iosonly","notranslation"]
|
||||||
|
definition.comment = ""
|
||||||
|
definition.translations = [
|
||||||
|
"fr": "C'est la traduction francaise",
|
||||||
|
"en": "This is the english translation",
|
||||||
|
"en-us": "This is the english us translation"
|
||||||
|
]
|
||||||
|
|
||||||
|
// When
|
||||||
|
let propertyFr = definition.getNSLocalizedStringStaticProperty(forLang: "fr")
|
||||||
|
let propertyEn = definition.getNSLocalizedStringStaticProperty(forLang: "en")
|
||||||
|
let propertyEnUs = definition.getNSLocalizedStringStaticProperty(forLang: "en-us")
|
||||||
|
|
||||||
|
// Expect
|
||||||
|
let expectFr = """
|
||||||
|
/// Translation in fr :
|
||||||
|
/// C'est la traduction francaise
|
||||||
|
///
|
||||||
|
/// Comment :
|
||||||
|
/// No comment
|
||||||
static var definition_name: String {
|
static var definition_name: String {
|
||||||
NSLocalizedString("definition_name", tableName: kStringsFileName, bundle: Bundle.main, value: "C'est la traduction francaise", comment: "")
|
NSLocalizedString("definition_name", tableName: kStringsFileName, bundle: Bundle.main, value: "C'est la traduction francaise", comment: "")
|
||||||
}
|
}
|
||||||
@ -154,6 +332,9 @@ final class DefinitionTests: XCTestCase {
|
|||||||
let expectEn = """
|
let expectEn = """
|
||||||
/// Translation in en :
|
/// Translation in en :
|
||||||
/// This is the english translation
|
/// This is the english translation
|
||||||
|
///
|
||||||
|
/// Comment :
|
||||||
|
/// No comment
|
||||||
static var definition_name: String {
|
static var definition_name: String {
|
||||||
NSLocalizedString("definition_name", tableName: kStringsFileName, bundle: Bundle.main, value: "This is the english translation", comment: "")
|
NSLocalizedString("definition_name", tableName: kStringsFileName, bundle: Bundle.main, value: "This is the english translation", comment: "")
|
||||||
}
|
}
|
||||||
@ -162,6 +343,63 @@ final class DefinitionTests: XCTestCase {
|
|||||||
let expectEnUs = """
|
let expectEnUs = """
|
||||||
/// Translation in en-us :
|
/// Translation in en-us :
|
||||||
/// This is the english us translation
|
/// This is the english us translation
|
||||||
|
///
|
||||||
|
/// Comment :
|
||||||
|
/// No comment
|
||||||
|
static var definition_name: String {
|
||||||
|
NSLocalizedString("definition_name", tableName: kStringsFileName, bundle: Bundle.main, value: "This is the english us translation", comment: "")
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
XCTAssertEqual(propertyFr.adaptForXCTest(), expectFr.adaptForXCTest())
|
||||||
|
XCTAssertEqual(propertyEn.adaptForXCTest(), expectEn.adaptForXCTest())
|
||||||
|
XCTAssertEqual(propertyEnUs.adaptForXCTest(), expectEnUs.adaptForXCTest())
|
||||||
|
}
|
||||||
|
|
||||||
|
func testGeneratedNSLocalizedStringStaticPropertyWithNoComment() {
|
||||||
|
// Given
|
||||||
|
let definition = Definition(name: "definition_name")
|
||||||
|
definition.tags = ["ios","iosonly","notranslation"]
|
||||||
|
definition.translations = [
|
||||||
|
"fr": "C'est la traduction francaise",
|
||||||
|
"en": "This is the english translation",
|
||||||
|
"en-us": "This is the english us translation"
|
||||||
|
]
|
||||||
|
|
||||||
|
// When
|
||||||
|
let propertyFr = definition.getNSLocalizedStringStaticProperty(forLang: "fr")
|
||||||
|
let propertyEn = definition.getNSLocalizedStringStaticProperty(forLang: "en")
|
||||||
|
let propertyEnUs = definition.getNSLocalizedStringStaticProperty(forLang: "en-us")
|
||||||
|
|
||||||
|
// Expect
|
||||||
|
let expectFr = """
|
||||||
|
/// Translation in fr :
|
||||||
|
/// C'est la traduction francaise
|
||||||
|
///
|
||||||
|
/// Comment :
|
||||||
|
/// No comment
|
||||||
|
static var definition_name: String {
|
||||||
|
NSLocalizedString("definition_name", tableName: kStringsFileName, bundle: Bundle.main, value: "C'est la traduction francaise", comment: "")
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
let expectEn = """
|
||||||
|
/// Translation in en :
|
||||||
|
/// This is the english translation
|
||||||
|
///
|
||||||
|
/// Comment :
|
||||||
|
/// No comment
|
||||||
|
static var definition_name: String {
|
||||||
|
NSLocalizedString("definition_name", tableName: kStringsFileName, bundle: Bundle.main, value: "This is the english translation", comment: "")
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
let expectEnUs = """
|
||||||
|
/// Translation in en-us :
|
||||||
|
/// This is the english us translation
|
||||||
|
///
|
||||||
|
/// Comment :
|
||||||
|
/// No comment
|
||||||
static var definition_name: String {
|
static var definition_name: String {
|
||||||
NSLocalizedString("definition_name", tableName: kStringsFileName, bundle: Bundle.main, value: "This is the english us translation", comment: "")
|
NSLocalizedString("definition_name", tableName: kStringsFileName, bundle: Bundle.main, value: "This is the english us translation", comment: "")
|
||||||
}
|
}
|
||||||
@ -188,12 +426,18 @@ final class DefinitionTests: XCTestCase {
|
|||||||
let expectFr = """
|
let expectFr = """
|
||||||
/// Translation in fr :
|
/// Translation in fr :
|
||||||
/// Welcome "%@" !
|
/// Welcome "%@" !
|
||||||
|
///
|
||||||
|
/// Comment :
|
||||||
|
/// This is a comment
|
||||||
var definition_name: String {
|
var definition_name: String {
|
||||||
NSLocalizedString("definition_name", tableName: kStringsFileName, bundle: Bundle.main, value: "Welcome \"%@\" !", comment: "")
|
NSLocalizedString("definition_name", tableName: kStringsFileName, bundle: Bundle.main, value: "Welcome \"%@\" !", comment: "This is a comment")
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Translation in fr :
|
/// Translation in fr :
|
||||||
/// Welcome "%@" !
|
/// Welcome "%@" !
|
||||||
|
///
|
||||||
|
/// Comment :
|
||||||
|
/// This is a comment
|
||||||
func definition_name(arg0: String) -> String {
|
func definition_name(arg0: String) -> String {
|
||||||
String(format: self.definition_name, arg0)
|
String(format: self.definition_name, arg0)
|
||||||
}
|
}
|
||||||
@ -218,12 +462,18 @@ final class DefinitionTests: XCTestCase {
|
|||||||
let expectFr = """
|
let expectFr = """
|
||||||
/// Translation in fr :
|
/// Translation in fr :
|
||||||
/// Welcome "%@" ! Your age is %d :) Your weight is %f ;-)
|
/// Welcome "%@" ! Your age is %d :) Your weight is %f ;-)
|
||||||
|
///
|
||||||
|
/// Comment :
|
||||||
|
/// This is a comment
|
||||||
var definition_name: String {
|
var definition_name: String {
|
||||||
NSLocalizedString("definition_name", tableName: kStringsFileName, bundle: Bundle.main, value: "Welcome \"%@\" ! Your age is %d :) Your weight is %f ;-)", comment: "")
|
NSLocalizedString("definition_name", tableName: kStringsFileName, bundle: Bundle.main, value: "Welcome \"%@\" ! Your age is %d :) Your weight is %f ;-)", comment: "This is a comment")
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Translation in fr :
|
/// Translation in fr :
|
||||||
/// Welcome "%@" ! Your age is %d :) Your weight is %f ;-)
|
/// Welcome "%@" ! Your age is %d :) Your weight is %f ;-)
|
||||||
|
///
|
||||||
|
/// Comment :
|
||||||
|
/// This is a comment
|
||||||
func definition_name(arg0: String, arg1: Int, arg2: Double) -> String {
|
func definition_name(arg0: String, arg1: Int, arg2: Double) -> String {
|
||||||
String(format: self.definition_name, arg0, arg1, arg2)
|
String(format: self.definition_name, arg0, arg1, arg2)
|
||||||
}
|
}
|
||||||
@ -249,12 +499,18 @@ final class DefinitionTests: XCTestCase {
|
|||||||
let expectFr = """
|
let expectFr = """
|
||||||
/// Translation in fr :
|
/// Translation in fr :
|
||||||
/// Vous %%: %1$@ %2$@ Age: %3$d
|
/// Vous %%: %1$@ %2$@ Age: %3$d
|
||||||
|
///
|
||||||
|
/// Comment :
|
||||||
|
/// This is a comment
|
||||||
var definition_name: String {
|
var definition_name: String {
|
||||||
NSLocalizedString("definition_name", tableName: kStringsFileName, bundle: Bundle.main, value: "Vous %%: %1$@ %2$@ Age: %3$d", comment: "")
|
NSLocalizedString("definition_name", tableName: kStringsFileName, bundle: Bundle.main, value: "Vous %%: %1$@ %2$@ Age: %3$d", comment: "This is a comment")
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Translation in fr :
|
/// Translation in fr :
|
||||||
/// Vous %%: %1$@ %2$@ Age: %3$d
|
/// Vous %%: %1$@ %2$@ Age: %3$d
|
||||||
|
///
|
||||||
|
/// Comment :
|
||||||
|
/// This is a comment
|
||||||
func definition_name(arg0: String, arg1: String, arg2: Int) -> String {
|
func definition_name(arg0: String, arg1: String, arg2: Int) -> String {
|
||||||
String(format: self.definition_name, arg0, arg1, arg2)
|
String(format: self.definition_name, arg0, arg1, arg2)
|
||||||
}
|
}
|
||||||
@ -263,12 +519,18 @@ final class DefinitionTests: XCTestCase {
|
|||||||
let expectEn = """
|
let expectEn = """
|
||||||
/// Translation in en :
|
/// Translation in en :
|
||||||
/// You %%: %2$@ %1$@ Age: %3$d
|
/// You %%: %2$@ %1$@ Age: %3$d
|
||||||
|
///
|
||||||
|
/// Comment :
|
||||||
|
/// This is a comment
|
||||||
var definition_name: String {
|
var definition_name: String {
|
||||||
NSLocalizedString("definition_name", tableName: kStringsFileName, bundle: Bundle.main, value: "You %%: %2$@ %1$@ Age: %3$d", comment: "")
|
NSLocalizedString("definition_name", tableName: kStringsFileName, bundle: Bundle.main, value: "You %%: %2$@ %1$@ Age: %3$d", comment: "This is a comment")
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Translation in en :
|
/// Translation in en :
|
||||||
/// You %%: %2$@ %1$@ Age: %3$d
|
/// You %%: %2$@ %1$@ Age: %3$d
|
||||||
|
///
|
||||||
|
/// Comment :
|
||||||
|
/// This is a comment
|
||||||
func definition_name(arg0: String, arg1: String, arg2: Int) -> String {
|
func definition_name(arg0: String, arg1: String, arg2: Int) -> String {
|
||||||
String(format: self.definition_name, arg0, arg1, arg2)
|
String(format: self.definition_name, arg0, arg1, arg2)
|
||||||
}
|
}
|
||||||
@ -300,6 +562,9 @@ final class DefinitionTests: XCTestCase {
|
|||||||
let expectFr = """
|
let expectFr = """
|
||||||
/// Translation in fr :
|
/// Translation in fr :
|
||||||
/// C'est la traduction francaise
|
/// C'est la traduction francaise
|
||||||
|
///
|
||||||
|
/// Comment :
|
||||||
|
/// This is a comment
|
||||||
var definition_name: String {
|
var definition_name: String {
|
||||||
"C'est la traduction francaise"
|
"C'est la traduction francaise"
|
||||||
}
|
}
|
||||||
@ -308,6 +573,9 @@ final class DefinitionTests: XCTestCase {
|
|||||||
let expectEn = """
|
let expectEn = """
|
||||||
/// Translation in en :
|
/// Translation in en :
|
||||||
/// This is the english translation
|
/// This is the english translation
|
||||||
|
///
|
||||||
|
/// Comment :
|
||||||
|
/// This is a comment
|
||||||
var definition_name: String {
|
var definition_name: String {
|
||||||
"This is the english translation"
|
"This is the english translation"
|
||||||
}
|
}
|
||||||
@ -316,6 +584,9 @@ final class DefinitionTests: XCTestCase {
|
|||||||
let expectEnUs = """
|
let expectEnUs = """
|
||||||
/// Translation in en-us :
|
/// Translation in en-us :
|
||||||
/// This is the english us translation
|
/// This is the english us translation
|
||||||
|
///
|
||||||
|
/// Comment :
|
||||||
|
/// This is a comment
|
||||||
var definition_name: String {
|
var definition_name: String {
|
||||||
"This is the english us translation"
|
"This is the english us translation"
|
||||||
}
|
}
|
||||||
@ -326,6 +597,117 @@ final class DefinitionTests: XCTestCase {
|
|||||||
XCTAssertEqual(propertyEnUs.adaptForXCTest(), expectEnUs.adaptForXCTest())
|
XCTAssertEqual(propertyEnUs.adaptForXCTest(), expectEnUs.adaptForXCTest())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func testGeneratedRawPropertyWithEmptyComment() {
|
||||||
|
// Given
|
||||||
|
let definition = Definition(name: "definition_name")
|
||||||
|
definition.tags = ["ios","iosonly","notranslation"]
|
||||||
|
definition.comment = ""
|
||||||
|
definition.translations = [
|
||||||
|
"fr": "C'est la traduction francaise",
|
||||||
|
"en": "This is the english translation",
|
||||||
|
"en-us": "This is the english us translation"
|
||||||
|
]
|
||||||
|
|
||||||
|
// When
|
||||||
|
let propertyFr = definition.getProperty(forLang: "fr")
|
||||||
|
let propertyEn = definition.getProperty(forLang: "en")
|
||||||
|
let propertyEnUs = definition.getProperty(forLang: "en-us")
|
||||||
|
|
||||||
|
// Expect
|
||||||
|
let expectFr = """
|
||||||
|
/// Translation in fr :
|
||||||
|
/// C'est la traduction francaise
|
||||||
|
///
|
||||||
|
/// Comment :
|
||||||
|
/// No comment
|
||||||
|
var definition_name: String {
|
||||||
|
"C'est la traduction francaise"
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
let expectEn = """
|
||||||
|
/// Translation in en :
|
||||||
|
/// This is the english translation
|
||||||
|
///
|
||||||
|
/// Comment :
|
||||||
|
/// No comment
|
||||||
|
var definition_name: String {
|
||||||
|
"This is the english translation"
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
let expectEnUs = """
|
||||||
|
/// Translation in en-us :
|
||||||
|
/// This is the english us translation
|
||||||
|
///
|
||||||
|
/// Comment :
|
||||||
|
/// No comment
|
||||||
|
var definition_name: String {
|
||||||
|
"This is the english us translation"
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
XCTAssertEqual(propertyFr.adaptForXCTest(), expectFr.adaptForXCTest())
|
||||||
|
XCTAssertEqual(propertyEn.adaptForXCTest(), expectEn.adaptForXCTest())
|
||||||
|
XCTAssertEqual(propertyEnUs.adaptForXCTest(), expectEnUs.adaptForXCTest())
|
||||||
|
}
|
||||||
|
|
||||||
|
func testGeneratedRawPropertyWithNoComment() {
|
||||||
|
// Given
|
||||||
|
let definition = Definition(name: "definition_name")
|
||||||
|
definition.tags = ["ios","iosonly","notranslation"]
|
||||||
|
definition.translations = [
|
||||||
|
"fr": "C'est la traduction francaise",
|
||||||
|
"en": "This is the english translation",
|
||||||
|
"en-us": "This is the english us translation"
|
||||||
|
]
|
||||||
|
|
||||||
|
// When
|
||||||
|
let propertyFr = definition.getProperty(forLang: "fr")
|
||||||
|
let propertyEn = definition.getProperty(forLang: "en")
|
||||||
|
let propertyEnUs = definition.getProperty(forLang: "en-us")
|
||||||
|
|
||||||
|
// Expect
|
||||||
|
let expectFr = """
|
||||||
|
/// Translation in fr :
|
||||||
|
/// C'est la traduction francaise
|
||||||
|
///
|
||||||
|
/// Comment :
|
||||||
|
/// No comment
|
||||||
|
var definition_name: String {
|
||||||
|
"C'est la traduction francaise"
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
let expectEn = """
|
||||||
|
/// Translation in en :
|
||||||
|
/// This is the english translation
|
||||||
|
///
|
||||||
|
/// Comment :
|
||||||
|
/// No comment
|
||||||
|
var definition_name: String {
|
||||||
|
"This is the english translation"
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
let expectEnUs = """
|
||||||
|
/// Translation in en-us :
|
||||||
|
/// This is the english us translation
|
||||||
|
///
|
||||||
|
/// Comment :
|
||||||
|
/// No comment
|
||||||
|
var definition_name: String {
|
||||||
|
"This is the english us translation"
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
XCTAssertEqual(propertyFr.adaptForXCTest(), expectFr.adaptForXCTest())
|
||||||
|
XCTAssertEqual(propertyEn.adaptForXCTest(), expectEn.adaptForXCTest())
|
||||||
|
XCTAssertEqual(propertyEnUs.adaptForXCTest(), expectEnUs.adaptForXCTest())
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Raw static properties
|
||||||
|
|
||||||
func testGeneratedRawStaticProperty() {
|
func testGeneratedRawStaticProperty() {
|
||||||
// Given
|
// Given
|
||||||
let definition = Definition(name: "definition_name")
|
let definition = Definition(name: "definition_name")
|
||||||
@ -346,6 +728,9 @@ final class DefinitionTests: XCTestCase {
|
|||||||
let expectFr = """
|
let expectFr = """
|
||||||
/// Translation in fr :
|
/// Translation in fr :
|
||||||
/// C'est la traduction francaise
|
/// C'est la traduction francaise
|
||||||
|
///
|
||||||
|
/// Comment :
|
||||||
|
/// This is a comment
|
||||||
static var definition_name: String {
|
static var definition_name: String {
|
||||||
"C'est la traduction francaise"
|
"C'est la traduction francaise"
|
||||||
}
|
}
|
||||||
@ -354,7 +739,10 @@ final class DefinitionTests: XCTestCase {
|
|||||||
let expectEn = """
|
let expectEn = """
|
||||||
/// Translation in en :
|
/// Translation in en :
|
||||||
/// This is the english translation
|
/// This is the english translation
|
||||||
static var definition_name: String {
|
///
|
||||||
|
/// Comment :
|
||||||
|
/// This is a comment
|
||||||
|
static var definition_name: String {
|
||||||
"This is the english translation"
|
"This is the english translation"
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
@ -362,6 +750,118 @@ final class DefinitionTests: XCTestCase {
|
|||||||
let expectEnUs = """
|
let expectEnUs = """
|
||||||
/// Translation in en-us :
|
/// Translation in en-us :
|
||||||
/// This is the english us translation
|
/// This is the english us translation
|
||||||
|
///
|
||||||
|
/// Comment :
|
||||||
|
/// This is a comment
|
||||||
|
static var definition_name: String {
|
||||||
|
"This is the english us translation"
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
XCTAssertEqual(propertyFr.adaptForXCTest(), expectFr.adaptForXCTest())
|
||||||
|
XCTAssertEqual(propertyEn.adaptForXCTest(), expectEn.adaptForXCTest())
|
||||||
|
XCTAssertEqual(propertyEnUs.adaptForXCTest(), expectEnUs.adaptForXCTest())
|
||||||
|
}
|
||||||
|
|
||||||
|
func testGeneratedRawStaticPropertyWithEmptyComment() {
|
||||||
|
// Given
|
||||||
|
let definition = Definition(name: "definition_name")
|
||||||
|
definition.tags = ["ios","iosonly","notranslation"]
|
||||||
|
definition.comment = ""
|
||||||
|
definition.translations = [
|
||||||
|
"fr": "C'est la traduction francaise",
|
||||||
|
"en": "This is the english translation",
|
||||||
|
"en-us": "This is the english us translation"
|
||||||
|
]
|
||||||
|
|
||||||
|
// When
|
||||||
|
let propertyFr = definition.getStaticProperty(forLang: "fr")
|
||||||
|
let propertyEn = definition.getStaticProperty(forLang: "en")
|
||||||
|
let propertyEnUs = definition.getStaticProperty(forLang: "en-us")
|
||||||
|
|
||||||
|
// Expect
|
||||||
|
let expectFr = """
|
||||||
|
/// Translation in fr :
|
||||||
|
/// C'est la traduction francaise
|
||||||
|
///
|
||||||
|
/// Comment :
|
||||||
|
/// No comment
|
||||||
|
static var definition_name: String {
|
||||||
|
"C'est la traduction francaise"
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
let expectEn = """
|
||||||
|
/// Translation in en :
|
||||||
|
/// This is the english translation
|
||||||
|
///
|
||||||
|
/// Comment :
|
||||||
|
/// No comment
|
||||||
|
static var definition_name: String {
|
||||||
|
"This is the english translation"
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
let expectEnUs = """
|
||||||
|
/// Translation in en-us :
|
||||||
|
/// This is the english us translation
|
||||||
|
///
|
||||||
|
/// Comment :
|
||||||
|
/// No comment
|
||||||
|
static var definition_name: String {
|
||||||
|
"This is the english us translation"
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
XCTAssertEqual(propertyFr.adaptForXCTest(), expectFr.adaptForXCTest())
|
||||||
|
XCTAssertEqual(propertyEn.adaptForXCTest(), expectEn.adaptForXCTest())
|
||||||
|
XCTAssertEqual(propertyEnUs.adaptForXCTest(), expectEnUs.adaptForXCTest())
|
||||||
|
}
|
||||||
|
|
||||||
|
func testGeneratedRawStaticPropertyWithNoComment() {
|
||||||
|
// Given
|
||||||
|
let definition = Definition(name: "definition_name")
|
||||||
|
definition.tags = ["ios","iosonly","notranslation"]
|
||||||
|
definition.translations = [
|
||||||
|
"fr": "C'est la traduction francaise",
|
||||||
|
"en": "This is the english translation",
|
||||||
|
"en-us": "This is the english us translation"
|
||||||
|
]
|
||||||
|
|
||||||
|
// When
|
||||||
|
let propertyFr = definition.getStaticProperty(forLang: "fr")
|
||||||
|
let propertyEn = definition.getStaticProperty(forLang: "en")
|
||||||
|
let propertyEnUs = definition.getStaticProperty(forLang: "en-us")
|
||||||
|
|
||||||
|
// Expect
|
||||||
|
let expectFr = """
|
||||||
|
/// Translation in fr :
|
||||||
|
/// C'est la traduction francaise
|
||||||
|
///
|
||||||
|
/// Comment :
|
||||||
|
/// No comment
|
||||||
|
static var definition_name: String {
|
||||||
|
"C'est la traduction francaise"
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
let expectEn = """
|
||||||
|
/// Translation in en :
|
||||||
|
/// This is the english translation
|
||||||
|
///
|
||||||
|
/// Comment :
|
||||||
|
/// No comment
|
||||||
|
static var definition_name: String {
|
||||||
|
"This is the english translation"
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
let expectEnUs = """
|
||||||
|
/// Translation in en-us :
|
||||||
|
/// This is the english us translation
|
||||||
|
///
|
||||||
|
/// Comment :
|
||||||
|
/// No comment
|
||||||
static var definition_name: String {
|
static var definition_name: String {
|
||||||
"This is the english us translation"
|
"This is the english us translation"
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user