Skip to content

Commit

Permalink
Expose StringCatalog target as a library (#48)
Browse files Browse the repository at this point in the history
* Make StringCatalog initializers public

* Expose StringCatalog as a linkable library

* Add StringCatalog test

* Ensure parser can be used externally

* Address PR comments

* Update tests.yml
  • Loading branch information
tricky-vrc authored Apr 3, 2024
1 parent 05bb5f4 commit ddbda75
Show file tree
Hide file tree
Showing 11 changed files with 188 additions and 2 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,4 +38,4 @@ jobs:
- name: Checkout Repo
uses: actions/checkout@v3
- name: Run Tests
run: xcodebuild clean test -scheme XCStringsTool -destination platform=macOS
run: xcodebuild clean test -scheme XCStringsTool-Package -destination platform=macOS
13 changes: 12 additions & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ let package = Package(
],
products: [
.executable(name: "xcstrings-tool", targets: ["xcstrings-tool"]),
.plugin(name: "XCStringsToolPlugin", targets: ["XCStringsToolPlugin"])
.plugin(name: "XCStringsToolPlugin", targets: ["XCStringsToolPlugin"]),
.library(name: "StringCatalog", targets: ["StringCatalog"])
],
dependencies: [
.package(url: "https://github.com/apple/swift-argument-parser.git", from: "1.2.3"),
Expand Down Expand Up @@ -110,6 +111,16 @@ let package = Package(
swiftSettings: [
.define("XCSTRINGS_TOOL_ACCESS_LEVEL_PUBLIC")
]
),

.testTarget(
name: "StringCatalogTests",
dependencies: [
.target(name: "StringCatalog")
],
resources: [
.copy("__Fixtures__")
]
)
]
)
Expand Down
6 changes: 6 additions & 0 deletions Sources/StringCatalog/StringCatalog.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ public struct StringCatalog: Codable {
public var sourceLanguage: StringLanguage
public var strings: [String: StringEntry]
public var version: String // TODO: Use a Version type?

public init(sourceLanguage: StringLanguage, strings: [String : StringEntry], version: String) {
self.sourceLanguage = sourceLanguage
self.strings = strings
self.version = version
}
}

// MARK: - Init
Expand Down
6 changes: 6 additions & 0 deletions Sources/StringCatalog/Types/StringEntry.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,10 @@ public struct StringEntry: Codable {
public var comment: String?
public var extractionState: StringExtractionState?
public var localizations: Localizations?

public init(comment: String? = nil, extractionState: StringExtractionState? = nil, localizations: Localizations? = nil) {
self.comment = comment
self.extractionState = extractionState
self.localizations = localizations
}
}
6 changes: 6 additions & 0 deletions Sources/StringCatalog/Types/StringLocalization.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,10 @@ public struct StringLocalization: Codable {
public var stringUnit: StringUnit?
public var substitutions: [String: StringSubstitution]?
public var variations: StringVariations?

public init(stringUnit: StringUnit? = nil, substitutions: [String : StringSubstitution]? = nil, variations: StringVariations? = nil) {
self.stringUnit = stringUnit
self.substitutions = substitutions
self.variations = variations
}
}
6 changes: 6 additions & 0 deletions Sources/StringCatalog/Types/StringSubstitution.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,10 @@ public struct StringSubstitution: Codable {
public let argNum: Int
public let formatSpecifier: String
public let variations: StringVariations?

public init(argNum: Int, formatSpecifier: String, variations: StringVariations?) {
self.argNum = argNum
self.formatSpecifier = formatSpecifier
self.variations = variations
}
}
5 changes: 5 additions & 0 deletions Sources/StringCatalog/Types/StringUnit.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,9 @@ import Foundation
public struct StringUnit: Codable {
public var state: StringUnitState
public var value: String

public init(state: StringUnitState, value: String) {
self.state = state
self.value = value
}
}
4 changes: 4 additions & 0 deletions Sources/StringCatalog/Types/StringVariation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,8 @@ import Foundation

public struct StringVariation: Codable {
public var stringUnit: StringUnit

public init(stringUnit: StringUnit) {
self.stringUnit = stringUnit
}
}
5 changes: 5 additions & 0 deletions Sources/StringCatalog/Types/StringVariations.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@ import Foundation
public struct StringVariations: Codable {
public let device: DictionaryWrapper<DeviceKey, StringVariation>?
public let plural: DictionaryWrapper<PluralKey, StringVariation>?

public init(device: DictionaryWrapper<DeviceKey, StringVariation>?, plural: DictionaryWrapper<PluralKey, StringVariation>?) {
self.device = device
self.plural = plural
}
}

extension StringVariations {
Expand Down
27 changes: 27 additions & 0 deletions Tests/StringCatalogTests/StringCatalogTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import Foundation
import XCTest
import StringCatalog

class StringCatalogTests: XCTestCase {
func testCreateCatalog() {
let stringUnit = StringUnit(state: .translated, value: "Example value")
let variations = StringVariations(device: [.iPad: StringVariation(stringUnit: stringUnit)], plural: [:])
let substitutions = ["substitution": StringSubstitution(argNum: 0, formatSpecifier: "%lld", variations: variations)]
let localization = StringLocalization(stringUnit: stringUnit, substitutions: substitutions, variations: variations)
let entry = StringEntry(comment: "A comment", extractionState: "manual", localizations: [ "en": localization ])
_ = StringCatalog(sourceLanguage: "en", strings: ["ExampleKey": entry], version: "1.0")
}

func testParseCatalog() throws {
let fixtureUrl = try fixture(named: "Localizable")
let catalog = try StringCatalog(contentsOf: fixtureUrl)
print(String(describing: catalog))
}

func fixture(named name: String) throws -> URL {
let bundle = Bundle.module
return try XCTUnwrap(
bundle.url(forResource: name, withExtension: "xcstrings", subdirectory: "__Fixtures__")
)
}
}
110 changes: 110 additions & 0 deletions Tests/StringCatalogTests/__Fixtures__/Localizable.xcstrings
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
{
"sourceLanguage" : "en",
"strings" : {
"Empty" : {
"extractionState" : "manual"
},
"Empty.Comment" : {
"comment" : "Value is empty but there is a comment",
"extractionState" : "manual"
},
"Key" : {
"comment" : "This is a comment",
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Default Value"
}
}
}
},
"myDeviceVariant" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"variations" : {
"device" : {
"ipad" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "macOS Original"
}
},
"mac" : {
"stringUnit" : {
"state" : "translated",
"value" : "macOS Original"
}
},
"other" : {
"stringUnit" : {
"state" : "translated",
"value" : "Multiplatform Original"
}
}
}
}
}
}
},
"myPlural" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"variations" : {
"plural" : {
"one" : {
"stringUnit" : {
"state" : "translated",
"value" : "I have %lld plural"
}
},
"other" : {
"stringUnit" : {
"state" : "translated",
"value" : "I have %lld plurals"
}
}
}
}
}
}
},
"mySubstitute" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "%lld: People liked %#@count@ posts"
},
"substitutions" : {
"count" : {
"argNum" : 2,
"formatSpecifier" : "lld",
"variations" : {
"plural" : {
"one" : {
"stringUnit" : {
"state" : "translated",
"value" : "%arg"
}
},
"other" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "%arg"
}
}
}
}
}
}
}
}
}
},
"version" : "1.0"
}

0 comments on commit ddbda75

Please sign in to comment.