diff --git a/CHANGELOG.md b/CHANGELOG.md index ed21872..7051ec6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ ## master ### Added +- Add check for duplicate keys in Spreadsheet ([#38](https://github.com/AckeeCZ/ACKLocalization/pull/38), kudos to @AGr-AlexandrGrigoryev) - Replaces custom solution for getting auth credentials with [google auth library](https://github.com/googleapis/google-auth-library-swift) ([#36](https://github.com/AckeeCZ/ACKLocalization/pull/36), kudos to @babacros) ## 1.5.0 diff --git a/Sources/ACKLocalizationCore/ACKLocalization.swift b/Sources/ACKLocalizationCore/ACKLocalization.swift index 95d3048..45df297 100644 --- a/Sources/ACKLocalizationCore/ACKLocalization.swift +++ b/Sources/ACKLocalizationCore/ACKLocalization.swift @@ -412,12 +412,26 @@ public final class ACKLocalization { /// Actually writes given `rows` to given `file` private func writeRows(_ rows: [LocRow], to file: String) throws { guard rows.count > 0 else { return } - + + try checkDuplicateKeys(form: rows) + try rows.map { $0.localizableRow } .joined(separator: "\n") .write(toFile: file, atomically: true, encoding: .utf8) } - + + /// Check if given `rows` have a duplicated keys + public func checkDuplicateKeys(form rows: [LocRow]) throws { + let keys = rows.map { $0.key } + let uniqueKeys = Set(keys) + + if keys.count != uniqueKeys.count { + let duplicates = Dictionary(grouping: rows, by: \.key) + .filter { $1.count > 1 }.keys + throw LocalizationError(message: "❌ Check your Google Spreadsheet, you have a duplicated keys: \(duplicates)") + } + } + /// Displays error to stdout private func displayError(_ localizationError: LocalizationError) { let message = "❌ " + localizationError.message diff --git a/Tests/ACKLocalizationCoreTests/ACKLocalizationTests.swift b/Tests/ACKLocalizationCoreTests/ACKLocalizationTests.swift index 3764742..33bbe31 100644 --- a/Tests/ACKLocalizationCoreTests/ACKLocalizationTests.swift +++ b/Tests/ACKLocalizationCoreTests/ACKLocalizationTests.swift @@ -2,8 +2,9 @@ import ACKLocalizationCore import XCTest final class ACKLocalizationTests: XCTestCase { + let localization = ACKLocalization() + func test_transform_emptyRow() throws { - let localization = ACKLocalization() let mappedValues = try localization.transformValues( .init( values: [ @@ -21,4 +22,22 @@ final class ACKLocalizationTests: XCTestCase { [LocRow(key: "key", value: "")] ) } + + func testForDuplicateKeys() throws { + let locRow = [ + LocRow(key: "key_1", value: "value1"), + LocRow(key: "key_1", value: "value2"), + LocRow(key: "key_2", value: "value3") + ] + XCTAssertThrowsError(try localization.checkDuplicateKeys(form: locRow)) + } + + func testForUniqueKeys() throws { + let locRow = [ + LocRow(key: "key_1", value: "value1"), + LocRow(key: "key_2", value: "value2"), + LocRow(key: "key_3", value: "value3") + ] + XCTAssertNoThrow(try localization.checkDuplicateKeys(form: locRow)) + } }