Skip to content

Commit

Permalink
Escape backslash and double quotes for valid string literal
Browse files Browse the repository at this point in the history
Fixes #19.
  • Loading branch information
Jeehut committed Jul 2, 2016
1 parent ad48fb5 commit 147f97a
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 15 deletions.
17 changes: 16 additions & 1 deletion Sources/Code/StringsFileUpdater.swift
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ public class StringsFileUpdater {

translator.translate(sourceValue, callback: { translatedValue in
if !translatedValue.isEmpty {
updatedTargetTranslations[updatedTargetTranslationIndex] = (key, translatedValue, comment)
updatedTargetTranslations[updatedTargetTranslationIndex] = (key, translatedValue.asStringLiteral, comment)
translatedValuesCount += 1
}

Expand Down Expand Up @@ -405,5 +405,20 @@ extension String {
}
return false
}

/// Unescapes any special characters to make String valid String Literal.
///
/// Source: https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/StringsAndCharacters.html (to be cont.)
/// Continued: #//apple_ref/doc/uid/TP40014097-CH7-ID295
var asStringLiteral: String {
let charactersToEscape = ["\\", "\""] // important: backslash must be first entry
var escapedString = self

charactersToEscape.forEach { character in
escapedString = escapedString.stringByReplacingOccurrencesOfString(character, withString: "\\\(character)")
}

return escapedString
}

}
2 changes: 2 additions & 0 deletions Tests/Assets/StringsFiles/de.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@

/* A string where value only available in English. */
"menu.cars" = "";

"TEST.KEY.UNESCAPED_DOUBLE_QUOTES" = "";
4 changes: 3 additions & 1 deletion Tests/Assets/StringsFiles/en.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,6 @@
"menu.cars" = "Cars";

/* A string where key only available in English. */
"menu.bicycles" = "Bicycles";
"menu.bicycles" = "Bicycles";

"TEST.KEY.UNESCAPED_DOUBLE_QUOTES" = "She said: 'Stop!'";
2 changes: 2 additions & 0 deletions Tests/Assets/StringsFiles/ja.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@

/* A string where value only available in English. */
"menu.cars" = "";

"TEST.KEY.UNESCAPED_DOUBLE_QUOTES" = "";
2 changes: 2 additions & 0 deletions Tests/Assets/StringsFiles/zh-Hans.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@

/* A string where value only available in English. */
"menu.cars" = "";

"TEST.KEY.UNESCAPED_DOUBLE_QUOTES" = "";
42 changes: 29 additions & 13 deletions Tests/Code/StringsFileUpdaterTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -272,26 +272,31 @@ class StringsFileUpdaterTests: XCTestCase {


// test before state (update if failing)
XCTAssertEqual(translations.first!.key, "Test key")
XCTAssertEqual(translations.first!.value, "Test value (\(locale))")
XCTAssertEqual(translations.first!.comment, " A string already localized in all languages. ")
XCTAssertEqual(translations[0].key, "Test key")
XCTAssertEqual(translations[0].value, "Test value (\(locale))")
XCTAssertEqual(translations[0].comment, " A string already localized in all languages. ")

XCTAssertEqual(translations.last!.key, "menu.cars")
XCTAssertEqual(translations.last!.value.utf16.count, 0)
XCTAssertEqual(translations.last!.value, "")
XCTAssertEqual(translations.last!.comment, " A string where value only available in English. ")
XCTAssertEqual(translations[1].key, "menu.cars")
XCTAssertEqual(translations[1].value.utf16.count, 0)
XCTAssertEqual(translations[1].value, "")
XCTAssertEqual(translations[1].comment, " A string where value only available in English. ")

XCTAssertEqual(translations[2].key, "TEST.KEY.UNESCAPED_DOUBLE_QUOTES")
XCTAssertEqual(translations[2].value.utf16.count, 0)
XCTAssertEqual(translations[2].value, "")
XCTAssertEqual(translations[2].comment, nil)


// run tested method
let changedValuesCount = stringsFileUpdater.translateEmptyValues(usingValuesFromStringsFile: sourceStringsFilePath, clientId: id, clientSecret: secret)

translations = stringsFileUpdater.findTranslationsInLines(stringsFileUpdater.linesInFile)

XCTAssertEqual(changedValuesCount, 2)
XCTAssertEqual(changedValuesCount, 3)


// test after state (update if failing)
XCTAssertEqual(translations.count, 3)
XCTAssertEqual(translations.count, 4)

XCTAssertEqual(translations[0].key, "Test key")
XCTAssertEqual(translations[0].value, "Test value (\(locale))")
Expand All @@ -316,6 +321,12 @@ class StringsFileUpdaterTests: XCTestCase {
"ja": "自転車",
"zh-Hans": "自行车"
]

let expectedTranslatedSheSaidStopValues: [String: String] = [
"de": "Sie sagte: \\\"Stop!\\\"", // BartyCrouch is expected to escape double quotes
"ja": "彼女は言った: '停止'!",
"zh-Hans": "她说: '停止' !"
]

// test with create keys options
for locale in ["de", "ja", "zh-Hans"] {
Expand All @@ -339,7 +350,7 @@ class StringsFileUpdaterTests: XCTestCase {


// test before state (update if failing)
XCTAssertEqual(translations.count, 2)
XCTAssertEqual(translations.count, 3)

XCTAssertEqual(translations[0].key, "Test key")
XCTAssertEqual(translations[0].value, "Test value (\(locale))")
Expand All @@ -356,11 +367,11 @@ class StringsFileUpdaterTests: XCTestCase {

translations = stringsFileUpdater.findTranslationsInLines(stringsFileUpdater.linesInFile)

XCTAssertEqual(changedValuesCount, 2)
XCTAssertEqual(changedValuesCount, 3)


// test after state (update if failing)
XCTAssertEqual(translations.count, 3)
XCTAssertEqual(translations.count, 4)

XCTAssertEqual(translations[0].key, "Test key")
XCTAssertEqual(translations[0].value, "Test value (\(locale))")
Expand All @@ -375,7 +386,12 @@ class StringsFileUpdaterTests: XCTestCase {
XCTAssertGreaterThan(translations[2].value.utf16.count, 0)
XCTAssertEqual(translations[2].value, expectedTranslatedBicyclesValues[locale])
XCTAssertEqual(translations[2].comment, " A string where key only available in English. ")


XCTAssertEqual(translations[3].key, "TEST.KEY.UNESCAPED_DOUBLE_QUOTES")
XCTAssertGreaterThan(translations[2].value.utf16.count, 0)
XCTAssertEqual(translations[3].value, expectedTranslatedSheSaidStopValues[locale])
XCTAssertEqual(translations[3].comment, nil)


// cleanup temporary file after testing
do {
Expand Down

0 comments on commit 147f97a

Please sign in to comment.