From b0b7f43985ba3740a6d2c26846cdba6de05df98d Mon Sep 17 00:00:00 2001 From: Richard Piazza Date: Sun, 22 Mar 2026 12:36:18 -0500 Subject: [PATCH 1/3] Converted Localizer Tests to SwiftTesting --- .../TranslationCatalogIO/KeyHierarchy.swift | 2 +- .../LocalizerTests/CoreDataExportTests.swift | 147 ------------- ...teProjectTests.swift => DeleteTests.swift} | 50 ++--- Tests/LocalizerTests/ExportTests.swift | 203 ++++++++++++++++++ .../FilesystemExportTests.swift | 147 ------------- Tests/LocalizerTests/HelpTests.swift | 8 +- ...temImportTests.swift => ImportTests.swift} | 17 +- Tests/LocalizerTests/PreviewTests.swift | 13 +- Tests/LocalizerTests/SQLiteExportTests.swift | 145 ------------- ...logSyntaxTests.swift => SyntaxTests.swift} | 18 +- .../TestCases/LocalizerTestCase.swift | 22 -- 11 files changed, 257 insertions(+), 515 deletions(-) delete mode 100644 Tests/LocalizerTests/CoreDataExportTests.swift rename Tests/LocalizerTests/{CatalogDeleteProjectTests.swift => DeleteTests.swift} (76%) create mode 100644 Tests/LocalizerTests/ExportTests.swift delete mode 100644 Tests/LocalizerTests/FilesystemExportTests.swift rename Tests/LocalizerTests/{FilesystemImportTests.swift => ImportTests.swift} (90%) delete mode 100644 Tests/LocalizerTests/SQLiteExportTests.swift rename Tests/LocalizerTests/{CatalogSyntaxTests.swift => SyntaxTests.swift} (85%) delete mode 100644 Tests/LocalizerTests/TestCases/LocalizerTestCase.swift diff --git a/Sources/TranslationCatalogIO/KeyHierarchy.swift b/Sources/TranslationCatalogIO/KeyHierarchy.swift index 3c79cf8..34612c8 100644 --- a/Sources/TranslationCatalogIO/KeyHierarchy.swift +++ b/Sources/TranslationCatalogIO/KeyHierarchy.swift @@ -18,7 +18,7 @@ public struct KeyHierarchy { ] static let reservedVariableTokens: [String] = [ - "any", +// "any", // Not Necessary to reserve when used as enum case "continue", "for", "in", diff --git a/Tests/LocalizerTests/CoreDataExportTests.swift b/Tests/LocalizerTests/CoreDataExportTests.swift deleted file mode 100644 index f1bb72c..0000000 --- a/Tests/LocalizerTests/CoreDataExportTests.swift +++ /dev/null @@ -1,147 +0,0 @@ -#if canImport(CoreData) -import XCTest - -final class CoreDataExportTests: LocalizerTestCase { - - override var resource: TestResource { - .file( - Bundle.module.url(forResource: "test_multi_language_core_data_v3", withExtension: "sqlite") - ) - } - - func testAppleStringsEnglish() throws { - let output = try process.runOutputting(with: [ - "catalog", "export", "apple-strings", "en", "--storage", "core-data", "--path", url.path(), - ]) - - XCTAssertEqual(output, """ - "APPLICATION_NAME" = "Lingua"; - "GREETING" = "Hello World!"; - "HIDDEN_MESSAGE" = ""; - "PLATFORM_ANDROID" = "Android"; - "PLATFORM_APPLE" = "Apple"; - "PLATFORM_WEB" = "Web"; - - """) - } - - func testAppleStringsSpanish() throws { - let output = try process.runOutputting(with: [ - "catalog", "export", "apple-strings", "es", "--storage", "core-data", "--path", url.path(), - ]) - - XCTAssertEqual(output, """ - "APPLICATION_NAME" = "Lingua"; - "GREETING" = "Hola Mundo!"; - "HIDDEN_MESSAGE" = "solo en español"; - "PLATFORM_ANDROID" = "Android"; - "PLATFORM_APPLE" = "Apple"; - "PLATFORM_WEB" = "Web"; - - """) - } - - func testAndroidXMLEnglish() throws { - let output = try process.runOutputting(with: [ - "catalog", "export", "android-xml", "en", "--storage", "core-data", "--path", url.path(), - ]) - - XCTAssertEqual(output, """ - - - Lingua - Hello World! - - Android - Apple - Web - - - """) - } - - func testAndroidXMLSpanish() throws { - let output = try process.runOutputting(with: [ - "catalog", "export", "android-xml", "es", "--storage", "core-data", "--path", url.path(), - ]) - - XCTAssertEqual(output, """ - - - Hola Mundo! - solo en español - - - """) - } - - func testAndroidXMLSpanishWithFallback() throws { - let output = try process.runOutputting(with: [ - "catalog", "export", "android-xml", "es", "--fallback", "--storage", "core-data", "--path", url.path(), - ]) - - XCTAssertEqual(output, """ - - - Lingua - Hola Mundo! - solo en español - Android - Apple - Web - - - """) - } - - func testJSONEnglish() throws { - let output = try process.runOutputting(with: [ - "catalog", "export", "json", "en", "--storage", "core-data", "--path", url.path(), - ]) - - XCTAssertEqual(output, """ - { - "APPLICATION_NAME" : "Lingua", - "GREETING" : "Hello World!", - "HIDDEN_MESSAGE" : "", - "PLATFORM_ANDROID" : "Android", - "PLATFORM_APPLE" : "Apple", - "PLATFORM_WEB" : "Web" - } - - """) - } - - func testJSONSpanish() throws { - let output = try process.runOutputting(with: [ - "catalog", "export", "json", "es", "--storage", "core-data", "--path", url.path(), - ]) - - XCTAssertEqual(output, """ - { - "GREETING" : "Hola Mundo!", - "HIDDEN_MESSAGE" : "solo en español" - } - - """) - } - - func testJSONSpanishWithFallback() throws { - let output = try process.runOutputting(with: [ - "catalog", "export", "json", "es", "--storage", "core-data", "--fallback", "--path", url.path(), - ]) - - XCTAssertEqual(output, """ - { - "APPLICATION_NAME" : "Lingua", - "GREETING" : "Hola Mundo!", - "HIDDEN_MESSAGE" : "solo en español", - "PLATFORM_ANDROID" : "Android", - "PLATFORM_APPLE" : "Apple", - "PLATFORM_WEB" : "Web" - } - - """) - } -} -#endif diff --git a/Tests/LocalizerTests/CatalogDeleteProjectTests.swift b/Tests/LocalizerTests/DeleteTests.swift similarity index 76% rename from Tests/LocalizerTests/CatalogDeleteProjectTests.swift rename to Tests/LocalizerTests/DeleteTests.swift index 179fe90..ccbafb7 100644 --- a/Tests/LocalizerTests/CatalogDeleteProjectTests.swift +++ b/Tests/LocalizerTests/DeleteTests.swift @@ -1,16 +1,16 @@ -import TranslationCatalogSQLite -import XCTest +import Foundation +import Testing -final class CatalogDeleteProjectTests: XCTestCase { +struct DeleteTests { - func testNoParameters() throws { + @Test func noParameters() throws { let process = LocalizerProcess() let (terminationStatus, _, error) = try process.runReporting(with: [ "catalog", "delete", "project", ]) - XCTAssertNotEqual(terminationStatus, 0) - XCTAssertEqual(error, """ + #expect(terminationStatus != 0) + #expect(error == """ Error: Missing expected argument '' Help: Unique ID of the Project. Usage: localizer catalog delete project [--storage ] [--path ] [--verbose] @@ -21,29 +21,29 @@ final class CatalogDeleteProjectTests: XCTestCase { try process.recycle() } - func testHelp() throws { + @Test func help() throws { let process = LocalizerProcess() let (terminationStatus, output, _) = try process.runReporting(with: [ "catalog", "delete", "project", "--help", ]) - XCTAssertEqual(terminationStatus, 0) - XCTAssertTrue(output.contains("OVERVIEW: Delete a Project from the catalog.")) - XCTAssertTrue(output.contains("USAGE: localizer catalog delete project [--storage ] [--path ] [--verbose]")) - XCTAssertTrue(output.contains("ARGUMENTS:")) - XCTAssertTrue(output.contains("OPTIONS:")) + #expect(terminationStatus == 0) + #expect(output.contains("OVERVIEW: Delete a Project from the catalog.")) + #expect(output.contains("USAGE: localizer catalog delete project [--storage ] [--path ] [--verbose]")) + #expect(output.contains("ARGUMENTS:")) + #expect(output.contains("OPTIONS:")) try process.recycle() } - func testInvalidProjectID() throws { + @Test func invalidProjectID() throws { let process = LocalizerProcess() let (terminationStatus, _, error) = try process.runReporting(with: [ "catalog", "delete", "project", "123ABC", "--path", process.url.path(), ]) - XCTAssertNotEqual(terminationStatus, 0) - XCTAssertEqual(error, """ + #expect(terminationStatus != 0) + #expect(error == """ Error: The value '123ABC' is invalid for '' Help: Unique ID of the Project. Usage: localizer catalog delete project [--storage ] [--path ] [--verbose] @@ -54,14 +54,14 @@ final class CatalogDeleteProjectTests: XCTestCase { try process.recycle() } - func testUnknownProjectID() throws { + @Test func unknownProjectID() throws { let process = LocalizerProcess() let (terminationStatus, _, error) = try process.runReporting(with: [ "catalog", "delete", "project", "399150E5-6709-4CA8-AE54-C665EC3D1916", "--path", process.url.lastPathComponent, ]) - XCTAssertNotEqual(terminationStatus, 0) - XCTAssertEqual(error, """ + #expect(terminationStatus != 0) + #expect(error == """ Error: Unknown Project '399150E5-6709-4CA8-AE54-C665EC3D1916'. Usage: project [--storage ] [--path ] [--verbose] See 'project --help' for more information. @@ -71,14 +71,14 @@ final class CatalogDeleteProjectTests: XCTestCase { try process.recycle() } - func testUnknownProjectIDDebug() throws { + @Test func unknownProjectIDDebug() throws { let process = LocalizerProcess() let (terminationStatus, output, error) = try process.runReporting(with: [ "catalog", "delete", "project", "399150E5-6709-4CA8-AE54-C665EC3D1916", "--path", process.url.lastPathComponent, "--verbose", ]) - XCTAssertNotEqual(terminationStatus, 0) - XCTAssertEqual(output, """ + #expect(terminationStatus != 0) + #expect(output == """ ======SQL====== SELECT id, uuid, name FROM project @@ -88,7 +88,7 @@ final class CatalogDeleteProjectTests: XCTestCase { """) - XCTAssertEqual(error, """ + #expect(error == """ Error: Unknown Project '399150E5-6709-4CA8-AE54-C665EC3D1916'. Usage: project [--storage ] [--path ] [--verbose] See 'project --help' for more information. @@ -98,15 +98,15 @@ final class CatalogDeleteProjectTests: XCTestCase { try process.recycle() } - func testKnownProjectId() throws { + @Test func knownProjectIdVerbose() throws { let resource: TestResource = .file(Bundle.module.url(forResource: "test_single_project_entity_v5", withExtension: "sqlite")) let process = try LocalizerProcess(copying: resource) let (terminationStatus, output, _) = try process.runReporting(with: [ "catalog", "delete", "project", "82362D51-8C80-4328-BADD-BBE2EA08889F", "--path", process.url.path(), "--verbose", ]) - XCTAssertEqual(terminationStatus, 0) - XCTAssertEqual(output, """ + #expect(terminationStatus == 0) + #expect(output == """ ======SQL====== SELECT id, uuid, name FROM project diff --git a/Tests/LocalizerTests/ExportTests.swift b/Tests/LocalizerTests/ExportTests.swift new file mode 100644 index 0000000..b57caf3 --- /dev/null +++ b/Tests/LocalizerTests/ExportTests.swift @@ -0,0 +1,203 @@ +import Foundation +import Testing +@testable import localizer + +struct ExportTests { + + private static var resources: [(TestResource, Catalog.Storage)] { + get { + var resources: [(TestResource, Catalog.Storage)] = [ + ( + .file( + Bundle.module.url(forResource: "test_multi_language_v5", withExtension: "sqlite") + ), + .sqlite + ), + ( + .directory( + Bundle.module.resourceURL? + .appending(path: "StructuredResources", directoryHint: .isDirectory) + .appending(path: "MultiLanguageCatalog", directoryHint: .isDirectory) + ), + .filesystem + ), + ] + #if canImport(CoreData) && os(macOS) + resources.append( + ( + .file( + Bundle.module.url(forResource: "test_multi_language_core_data_v3", withExtension: "sqlite") + ), + .coreData + ), + ) + #endif + return resources + } + } + + @Test(arguments: Self.resources) + func appleStringsEnglish(resource: (TestResource, Catalog.Storage)) throws { + let process = try LocalizerProcess(copying: resource.0) + let output = try process.runOutputting(with: [ + "catalog", "export", "apple-strings", "en", "--storage", resource.1.rawValue, "--path", process.url.path(), + ]) + + #expect(output == """ + "APPLICATION_NAME" = "Lingua"; + "GREETING" = "Hello World!"; + "HIDDEN_MESSAGE" = ""; + "PLATFORM_ANDROID" = "Android"; + "PLATFORM_APPLE" = "Apple"; + "PLATFORM_WEB" = "Web"; + + """) + + try process.recycle() + } + + @Test(arguments: Self.resources) + func appleStringsSpanish(resource: (TestResource, Catalog.Storage)) throws { + let process = try LocalizerProcess(copying: resource.0) + let output = try process.runOutputting(with: [ + "catalog", "export", "apple-strings", "es", "--storage", resource.1.rawValue, "--path", process.url.path(), + ]) + + #expect(output == """ + "APPLICATION_NAME" = "Lingua"; + "GREETING" = "Hola Mundo!"; + "HIDDEN_MESSAGE" = "solo en español"; + "PLATFORM_ANDROID" = "Android"; + "PLATFORM_APPLE" = "Apple"; + "PLATFORM_WEB" = "Web"; + + """) + + try process.recycle() + } + + @Test(arguments: Self.resources) + func androidXMLEnglish(resource: (TestResource, Catalog.Storage)) throws { + let process = try LocalizerProcess(copying: resource.0) + let output = try process.runOutputting(with: [ + "catalog", "export", "android-xml", "en", "--storage", resource.1.rawValue, "--path", process.url.path(), + ]) + + #expect(output == """ + + + Lingua + Hello World! + + Android + Apple + Web + + + """) + + try process.recycle() + } + + @Test(arguments: Self.resources) + func androidXMLSpanish(resource: (TestResource, Catalog.Storage)) throws { + let process = try LocalizerProcess(copying: resource.0) + let output = try process.runOutputting(with: [ + "catalog", "export", "android-xml", "es", "--storage", resource.1.rawValue, "--path", process.url.path(), + ]) + + #expect(output == """ + + + Hola Mundo! + solo en español + + + """) + } + + @Test(arguments: Self.resources) + func androidXMLSpanishWithFallback(resource: (TestResource, Catalog.Storage)) throws { + let process = try LocalizerProcess(copying: resource.0) + let output = try process.runOutputting(with: [ + "catalog", "export", "android-xml", "es", "--storage", resource.1.rawValue, "--fallback", "--path", process.url.path(), + ]) + + #expect(output == """ + + + Lingua + Hola Mundo! + solo en español + Android + Apple + Web + + + """) + + try process.recycle() + } + + @Test(arguments: Self.resources) + func jsonEnglish(resource: (TestResource, Catalog.Storage)) throws { + let process = try LocalizerProcess(copying: resource.0) + let output = try process.runOutputting(with: [ + "catalog", "export", "json", "en", "--storage", resource.1.rawValue, "--path", process.url.path(), + ]) + + #expect(output == """ + { + "APPLICATION_NAME" : "Lingua", + "GREETING" : "Hello World!", + "HIDDEN_MESSAGE" : "", + "PLATFORM_ANDROID" : "Android", + "PLATFORM_APPLE" : "Apple", + "PLATFORM_WEB" : "Web" + } + + """) + + try process.recycle() + } + + @Test(arguments: Self.resources) + func jsonSpanish(resource: (TestResource, Catalog.Storage)) throws { + let process = try LocalizerProcess(copying: resource.0) + let output = try process.runOutputting(with: [ + "catalog", "export", "json", "es", "--storage", resource.1.rawValue, "--path", process.url.path(), + ]) + + #expect(output == """ + { + "GREETING" : "Hola Mundo!", + "HIDDEN_MESSAGE" : "solo en español" + } + + """) + + try process.recycle() + } + + @Test(arguments: Self.resources) + func jsonSpanishWithFallback(resource: (TestResource, Catalog.Storage)) throws { + let process = try LocalizerProcess(copying: resource.0) + let output = try process.runOutputting(with: [ + "catalog", "export", "json", "es", "--fallback", "--storage", resource.1.rawValue, "--path", process.url.path(), + ]) + + #expect(output == """ + { + "APPLICATION_NAME" : "Lingua", + "GREETING" : "Hola Mundo!", + "HIDDEN_MESSAGE" : "solo en español", + "PLATFORM_ANDROID" : "Android", + "PLATFORM_APPLE" : "Apple", + "PLATFORM_WEB" : "Web" + } + + """) + + try process.recycle() + } +} diff --git a/Tests/LocalizerTests/FilesystemExportTests.swift b/Tests/LocalizerTests/FilesystemExportTests.swift deleted file mode 100644 index 1dfec73..0000000 --- a/Tests/LocalizerTests/FilesystemExportTests.swift +++ /dev/null @@ -1,147 +0,0 @@ -import XCTest - -final class FilesystemExportTests: LocalizerTestCase { - - override var resource: TestResource { - .directory( - Bundle.module.resourceURL? - .appending(path: "StructuredResources", directoryHint: .isDirectory) - .appending(path: "MultiLanguageCatalog", directoryHint: .isDirectory) - ) - } - - func testAppleStringsEnglish() throws { - let output = try process.runOutputting(with: [ - "catalog", "export", "apple", "en", "--storage", "filesystem", "--path", directory.path(), - ]) - - XCTAssertEqual(output, """ - "APPLICATION_NAME" = "Lingua"; - "GREETING" = "Hello World!"; - "HIDDEN_MESSAGE" = ""; - "PLATFORM_ANDROID" = "Android"; - "PLATFORM_APPLE" = "Apple"; - "PLATFORM_WEB" = "Web"; - - """) - } - - func testAppleStringsSpanish() throws { - let output = try process.runOutputting(with: [ - "catalog", "export", "apple", "es", "--storage", "filesystem", "--path", directory.path(), - ]) - - XCTAssertEqual(output, """ - "APPLICATION_NAME" = "Lingua"; - "GREETING" = "Hola Mundo!"; - "HIDDEN_MESSAGE" = "solo en español"; - "PLATFORM_ANDROID" = "Android"; - "PLATFORM_APPLE" = "Apple"; - "PLATFORM_WEB" = "Web"; - - """) - } - - func testAndroidXMLEnglish() throws { - let output = try process.runOutputting(with: [ - "catalog", "export", "android", "en", "--storage", "filesystem", "--path", directory.path(), - ]) - - XCTAssertEqual(output, """ - - - Lingua - Hello World! - - Android - Apple - Web - - - """) - } - - func testAndroidXMLSpanish() throws { - let output = try process.runOutputting(with: [ - "catalog", "export", "android", "es", "--storage", "filesystem", "--path", directory.path(), - ]) - - XCTAssertEqual(output, """ - - - Hola Mundo! - solo en español - - - """) - } - - func testAndroidXMLSpanishWithFallback() throws { - let output = try process.runOutputting(with: [ - "catalog", "export", "android", "es", "--fallback", "--storage", "filesystem", "--path", directory.path(), - ]) - - XCTAssertEqual(output, """ - - - Lingua - Hola Mundo! - solo en español - Android - Apple - Web - - - """) - } - - func testJSONEnglish() throws { - let output = try process.runOutputting(with: [ - "catalog", "export", "json", "en", "--storage", "filesystem", "--path", directory.path(), - ]) - - XCTAssertEqual(output, """ - { - "APPLICATION_NAME" : "Lingua", - "GREETING" : "Hello World!", - "HIDDEN_MESSAGE" : "", - "PLATFORM_ANDROID" : "Android", - "PLATFORM_APPLE" : "Apple", - "PLATFORM_WEB" : "Web" - } - - """) - } - - func testJSONSpanish() throws { - let output = try process.runOutputting(with: [ - "catalog", "export", "json", "es", "--storage", "filesystem", "--path", directory.path(), - ]) - - XCTAssertEqual(output, """ - { - "GREETING" : "Hola Mundo!", - "HIDDEN_MESSAGE" : "solo en español" - } - - """) - } - - func testJSONSpanishWithFallback() throws { - let output = try process.runOutputting(with: [ - "catalog", "export", "json", "es", "--fallback", "--storage", "filesystem", "--path", directory.path(), - ]) - - XCTAssertEqual(output, """ - { - "APPLICATION_NAME" : "Lingua", - "GREETING" : "Hola Mundo!", - "HIDDEN_MESSAGE" : "solo en español", - "PLATFORM_ANDROID" : "Android", - "PLATFORM_APPLE" : "Apple", - "PLATFORM_WEB" : "Web" - } - - """) - } -} diff --git a/Tests/LocalizerTests/HelpTests.swift b/Tests/LocalizerTests/HelpTests.swift index d9e888b..46f0791 100644 --- a/Tests/LocalizerTests/HelpTests.swift +++ b/Tests/LocalizerTests/HelpTests.swift @@ -1,12 +1,12 @@ -import XCTest +import Testing -final class HelpTests: XCTestCase { +struct HelpTests { - func testNoArguments() throws { + @Test func noArguments() throws { let process = LocalizerProcess() let output = try process.runOutputting() - XCTAssertEqual(output, """ + #expect(output == """ OVERVIEW: Utility for interacting with Android 'strings.xml', Apple 'Localizable.strings', and Web '*.json' localization files. diff --git a/Tests/LocalizerTests/FilesystemImportTests.swift b/Tests/LocalizerTests/ImportTests.swift similarity index 90% rename from Tests/LocalizerTests/FilesystemImportTests.swift rename to Tests/LocalizerTests/ImportTests.swift index dabe2fa..a059f7b 100644 --- a/Tests/LocalizerTests/FilesystemImportTests.swift +++ b/Tests/LocalizerTests/ImportTests.swift @@ -1,9 +1,10 @@ -import XCTest +import Foundation +import Testing -final class FilesystemImportTests: XCTestCase { +struct ImportTests { /// Assert that repeated imports of the same file produce the expected results - func testDoubleImport() throws { + @Test func doubleImport() throws { let resource: TestResource = .file( Bundle.module.url(forResource: "Import1", withExtension: "strings") ) @@ -12,7 +13,7 @@ final class FilesystemImportTests: XCTestCase { "catalog", "import", "en", process.url.path(), "--format", "apple", "--storage", "filesystem", "--path", process.directory.path(), ]) - XCTAssertEqual(output, """ + #expect(output == """ Expression Created 'FIRST_NAME' Expression Created 'LAST_NAME' Expression Created 'TITLE' @@ -27,7 +28,7 @@ final class FilesystemImportTests: XCTestCase { "catalog", "import", "en", process.url.path(), "--format", "apple", "--storage", "filesystem", "--path", process.directory.path(), ]) - XCTAssertEqual(output, """ + #expect(output == """ Expression Exists with Key \'FIRST_NAME\' Expression Exists with Key \'LAST_NAME\' Expression Exists with Key \'TITLE\' @@ -38,7 +39,7 @@ final class FilesystemImportTests: XCTestCase { } /// Assert that repeated imports of the same file (that has changes) produce the expected results - func testRepeatImport() throws { + @Test func repeatImport() throws { var resource: TestResource = .file( Bundle.module.url(forResource: "Import1", withExtension: "strings") ) @@ -47,7 +48,7 @@ final class FilesystemImportTests: XCTestCase { "catalog", "import", "en", process.url.path(), "--format", "apple", "--storage", "filesystem", "--path", process.directory.path(), ]) - XCTAssertEqual(output, """ + #expect(output == """ Expression Created 'FIRST_NAME' Expression Created 'LAST_NAME' Expression Created 'TITLE' @@ -65,7 +66,7 @@ final class FilesystemImportTests: XCTestCase { "catalog", "import", "en", process.url.path(), "--format", "apple", "--storage", "filesystem", "--path", process.directory.path(), ]) - XCTAssertEqual(output, """ + #expect(output == """ Expression Created 'FAMILY_NAME' Expression Created 'GIVEN_NAME' Expression Exists with Key 'TITLE' diff --git a/Tests/LocalizerTests/PreviewTests.swift b/Tests/LocalizerTests/PreviewTests.swift index 40b4074..be5ad1d 100644 --- a/Tests/LocalizerTests/PreviewTests.swift +++ b/Tests/LocalizerTests/PreviewTests.swift @@ -1,15 +1,16 @@ -import XCTest +import Foundation +import Testing -final class LocalizerPreviewTests: XCTestCase { +struct LocalizerPreviewTests { - func testPreviewAndroid() throws { + @Test func previewAndroidXML() throws { let resource: TestResource = .file(Bundle.module.url(forResource: "Strings", withExtension: "xml")) let process = try LocalizerProcess(copying: resource) let output = try process.runOutputting(with: [ "preview", "android", process.url.path(), ]) - XCTAssertEqual(output, """ + #expect(output == """ APP_NAME = Localizer NAVIGATION_TITLE = Welcome PERFORM_ACTION = Make It Go! @@ -19,14 +20,14 @@ final class LocalizerPreviewTests: XCTestCase { try process.recycle() } - func testPreviewApple() throws { + @Test func previewAppleStrings() throws { let resource: TestResource = .file(Bundle.module.url(forResource: "Localizable", withExtension: "strings")) let process = try LocalizerProcess(copying: resource) let output = try process.runOutputting(with: [ "preview", "apple-strings", process.url.path(), ]) - XCTAssertEqual(output, """ + #expect(output == """ APP_NAME = Localizer NAVIGATION_TITLE = Welcome PERFORM_ACTION = Make It Go! diff --git a/Tests/LocalizerTests/SQLiteExportTests.swift b/Tests/LocalizerTests/SQLiteExportTests.swift deleted file mode 100644 index 48bd9d4..0000000 --- a/Tests/LocalizerTests/SQLiteExportTests.swift +++ /dev/null @@ -1,145 +0,0 @@ -import XCTest - -final class SQLiteExportTests: LocalizerTestCase { - - override var resource: TestResource { - .file( - Bundle.module.url(forResource: "test_multi_language_v5", withExtension: "sqlite") - ) - } - - func testAppleStringsEnglish() throws { - let output = try process.runOutputting(with: [ - "catalog", "export", "apple-strings", "en", "--path", url.path(), - ]) - - XCTAssertEqual(output, """ - "APPLICATION_NAME" = "Lingua"; - "GREETING" = "Hello World!"; - "HIDDEN_MESSAGE" = ""; - "PLATFORM_ANDROID" = "Android"; - "PLATFORM_APPLE" = "Apple"; - "PLATFORM_WEB" = "Web"; - - """) - } - - func testAppleStringsSpanish() throws { - let output = try process.runOutputting(with: [ - "catalog", "export", "apple-strings", "es", "--path", url.path(), - ]) - - XCTAssertEqual(output, """ - "APPLICATION_NAME" = "Lingua"; - "GREETING" = "Hola Mundo!"; - "HIDDEN_MESSAGE" = "solo en español"; - "PLATFORM_ANDROID" = "Android"; - "PLATFORM_APPLE" = "Apple"; - "PLATFORM_WEB" = "Web"; - - """) - } - - func testAndroidXMLEnglish() throws { - let output = try process.runOutputting(with: [ - "catalog", "export", "android-xml", "en", "--path", url.path(), - ]) - - XCTAssertEqual(output, """ - - - Lingua - Hello World! - - Android - Apple - Web - - - """) - } - - func testAndroidXMLSpanish() throws { - let output = try process.runOutputting(with: [ - "catalog", "export", "android-xml", "es", "--path", url.path(), - ]) - - XCTAssertEqual(output, """ - - - Hola Mundo! - solo en español - - - """) - } - - func testAndroidXMLSpanishWithFallback() throws { - let output = try process.runOutputting(with: [ - "catalog", "export", "android-xml", "es", "--fallback", "--path", url.path(), - ]) - - XCTAssertEqual(output, """ - - - Lingua - Hola Mundo! - solo en español - Android - Apple - Web - - - """) - } - - func testJSONEnglish() throws { - let output = try process.runOutputting(with: [ - "catalog", "export", "json", "en", "--path", url.path(), - ]) - - XCTAssertEqual(output, """ - { - "APPLICATION_NAME" : "Lingua", - "GREETING" : "Hello World!", - "HIDDEN_MESSAGE" : "", - "PLATFORM_ANDROID" : "Android", - "PLATFORM_APPLE" : "Apple", - "PLATFORM_WEB" : "Web" - } - - """) - } - - func testJSONSpanish() throws { - let output = try process.runOutputting(with: [ - "catalog", "export", "json", "es", "--path", url.path(), - ]) - - XCTAssertEqual(output, """ - { - "GREETING" : "Hola Mundo!", - "HIDDEN_MESSAGE" : "solo en español" - } - - """) - } - - func testJSONSpanishWithFallback() throws { - let output = try process.runOutputting(with: [ - "catalog", "export", "json", "es", "--fallback", "--path", url.path(), - ]) - - XCTAssertEqual(output, """ - { - "APPLICATION_NAME" : "Lingua", - "GREETING" : "Hola Mundo!", - "HIDDEN_MESSAGE" : "solo en español", - "PLATFORM_ANDROID" : "Android", - "PLATFORM_APPLE" : "Apple", - "PLATFORM_WEB" : "Web" - } - - """) - } -} diff --git a/Tests/LocalizerTests/CatalogSyntaxTests.swift b/Tests/LocalizerTests/SyntaxTests.swift similarity index 85% rename from Tests/LocalizerTests/CatalogSyntaxTests.swift rename to Tests/LocalizerTests/SyntaxTests.swift index 096297d..90e1ece 100644 --- a/Tests/LocalizerTests/CatalogSyntaxTests.swift +++ b/Tests/LocalizerTests/SyntaxTests.swift @@ -1,22 +1,20 @@ -import XCTest +import Foundation +import Testing -final class CatalogSyntaxTests: LocalizerTestCase { +struct SyntaxTests { - override var resource: TestResource { - .directory( + @Test func syntax() throws { + let resource: TestResource = .directory( Bundle.module.resourceURL? .appending(path: "StructuredResources", directoryHint: .isDirectory) .appending(path: "MultiLanguageCatalog", directoryHint: .isDirectory) ) - } - - func testSyntax() throws { - let process = LocalizerProcess() + let process = try LocalizerProcess(copying: resource) let output = try process.runOutputting(with: [ - "catalog", "syntax", "--storage", "filesystem", "--path", directory.path(), + "catalog", "syntax", "--storage", "filesystem", "--path", process.directory.path(), ]) - XCTAssertEqual(output, """ + #expect(output == """ import LocaleSupport enum LocalizedStrings: String, LocalizedStringConvertible { diff --git a/Tests/LocalizerTests/TestCases/LocalizerTestCase.swift b/Tests/LocalizerTests/TestCases/LocalizerTestCase.swift deleted file mode 100644 index 1a71c3b..0000000 --- a/Tests/LocalizerTests/TestCases/LocalizerTestCase.swift +++ /dev/null @@ -1,22 +0,0 @@ -import XCTest - -class LocalizerTestCase: XCTestCase { - - var process: LocalizerProcess! - var resource: TestResource { .file(nil) } - - var url: URL { process.url } - var directory: URL { process.directory } - - override func setUpWithError() throws { - try super.setUpWithError() - process = try LocalizerProcess(copying: resource) - } - - override func tearDownWithError() throws { - if process != nil { - try process.recycle() - } - try super.tearDownWithError() - } -} From 8061675e59719818e1abc43da0ca51cdd170db9d Mon Sep 17 00:00:00 2001 From: Richard Piazza Date: Sun, 22 Mar 2026 12:38:04 -0500 Subject: [PATCH 2/3] Syntax Updates --- Tests/LocalizerTests/ExportTests.swift | 64 +++++++++++++------------- 1 file changed, 31 insertions(+), 33 deletions(-) diff --git a/Tests/LocalizerTests/ExportTests.swift b/Tests/LocalizerTests/ExportTests.swift index b57caf3..01b6a53 100644 --- a/Tests/LocalizerTests/ExportTests.swift +++ b/Tests/LocalizerTests/ExportTests.swift @@ -1,39 +1,37 @@ import Foundation -import Testing @testable import localizer +import Testing struct ExportTests { private static var resources: [(TestResource, Catalog.Storage)] { - get { - var resources: [(TestResource, Catalog.Storage)] = [ - ( - .file( - Bundle.module.url(forResource: "test_multi_language_v5", withExtension: "sqlite") - ), - .sqlite + var resources: [(TestResource, Catalog.Storage)] = [ + ( + .file( + Bundle.module.url(forResource: "test_multi_language_v5", withExtension: "sqlite") ), - ( - .directory( - Bundle.module.resourceURL? - .appending(path: "StructuredResources", directoryHint: .isDirectory) - .appending(path: "MultiLanguageCatalog", directoryHint: .isDirectory) - ), - .filesystem + .sqlite + ), + ( + .directory( + Bundle.module.resourceURL? + .appending(path: "StructuredResources", directoryHint: .isDirectory) + .appending(path: "MultiLanguageCatalog", directoryHint: .isDirectory) ), - ] - #if canImport(CoreData) && os(macOS) - resources.append( - ( - .file( - Bundle.module.url(forResource: "test_multi_language_core_data_v3", withExtension: "sqlite") - ), - .coreData + .filesystem + ), + ] + #if canImport(CoreData) && os(macOS) + resources.append( + ( + .file( + Bundle.module.url(forResource: "test_multi_language_core_data_v3", withExtension: "sqlite") ), + .coreData ) - #endif - return resources - } + ) + #endif + return resources } @Test(arguments: Self.resources) @@ -52,7 +50,7 @@ struct ExportTests { "PLATFORM_WEB" = "Web"; """) - + try process.recycle() } @@ -72,7 +70,7 @@ struct ExportTests { "PLATFORM_WEB" = "Web"; """) - + try process.recycle() } @@ -95,7 +93,7 @@ struct ExportTests { """) - + try process.recycle() } @@ -135,7 +133,7 @@ struct ExportTests { """) - + try process.recycle() } @@ -157,7 +155,7 @@ struct ExportTests { } """) - + try process.recycle() } @@ -175,7 +173,7 @@ struct ExportTests { } """) - + try process.recycle() } @@ -197,7 +195,7 @@ struct ExportTests { } """) - + try process.recycle() } } From d1f4f82fd8756724b77cb00546635daadb417b75 Mon Sep 17 00:00:00 2001 From: Richard Piazza Date: Sun, 22 Mar 2026 12:48:26 -0500 Subject: [PATCH 3/3] Correct product directory lookup --- Tests/LocalizerTests/ExportTests.swift | 2 ++ Tests/LocalizerTests/Models/LocalizerProcess.swift | 2 +- Tests/LocalizerTests/SyntaxTests.swift | 2 ++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Tests/LocalizerTests/ExportTests.swift b/Tests/LocalizerTests/ExportTests.swift index 01b6a53..e75568e 100644 --- a/Tests/LocalizerTests/ExportTests.swift +++ b/Tests/LocalizerTests/ExportTests.swift @@ -112,6 +112,8 @@ struct ExportTests { """) + + try process.recycle() } @Test(arguments: Self.resources) diff --git a/Tests/LocalizerTests/Models/LocalizerProcess.swift b/Tests/LocalizerTests/Models/LocalizerProcess.swift index c6eee4d..9cb5a1d 100644 --- a/Tests/LocalizerTests/Models/LocalizerProcess.swift +++ b/Tests/LocalizerTests/Models/LocalizerProcess.swift @@ -41,7 +41,7 @@ class LocalizerProcess { /// Returns path to the built products directory. private var productsDirectory: URL { #if os(macOS) - for bundle in Bundle.allBundles where bundle.bundlePath.hasSuffix(".xctest") { + for bundle in Bundle.allBundles where bundle.bundlePath.contains("LocalizerTests") { return bundle.bundleURL.deletingLastPathComponent() } fatalError("couldn't find the products directory") diff --git a/Tests/LocalizerTests/SyntaxTests.swift b/Tests/LocalizerTests/SyntaxTests.swift index 90e1ece..d2e62fe 100644 --- a/Tests/LocalizerTests/SyntaxTests.swift +++ b/Tests/LocalizerTests/SyntaxTests.swift @@ -54,5 +54,7 @@ struct SyntaxTests { } """) + + try process.recycle() } }