From 03539ef9c440c1a715013405463010234cb0137a Mon Sep 17 00:00:00 2001 From: sam woolf Date: Mon, 13 Jan 2025 14:42:27 +0000 Subject: [PATCH 1/2] testplan codable fix --- .../Core/Entity/TestPlanModel.swift | 41 +++++++++++++++- .../Core/Helper/TestPlanHelper.swift | 48 ------------------- 2 files changed, 39 insertions(+), 50 deletions(-) diff --git a/Sources/TestConfigurator/xctestplanner/Core/Entity/TestPlanModel.swift b/Sources/TestConfigurator/xctestplanner/Core/Entity/TestPlanModel.swift index 97ad7da..8cc33db 100644 --- a/Sources/TestConfigurator/xctestplanner/Core/Entity/TestPlanModel.swift +++ b/Sources/TestConfigurator/xctestplanner/Core/Entity/TestPlanModel.swift @@ -66,8 +66,45 @@ public struct LocationScenario: Codable { public struct TestTarget: Codable { public var parallelizable: Bool? - public var skippedTests: [String]? - public var selectedTests: [String]? + public var skippedTests: Tests? + public var selectedTests: Tests? public var target: Target public var enabled: Bool? } + +public enum Tests: Codable { + case array([String]) + case dictionary(Suites) + + public struct Suites: Codable { + let suites: [Suite] + + public struct Suite: Codable { + let name: String + } + } + + public init(from decoder: Decoder) throws { + let container = try decoder.singleValueContainer() + if let array = try? container.decode([String].self) { + self = .array(array) + return + } + + if let dict = try? container.decode(Suites.self) { + self = .dictionary(dict) + return + } + throw DecodingError.dataCorruptedError(in: container, debugDescription: "Invalid type for skippedTests") + } + + public func encode(to encoder: Encoder) throws { + var container = encoder.singleValueContainer() + switch self { + case .array(let array): + try container.encode(array) + case .dictionary(let dict): + try container.encode(dict) + } + } +} diff --git a/Sources/TestConfigurator/xctestplanner/Core/Helper/TestPlanHelper.swift b/Sources/TestConfigurator/xctestplanner/Core/Helper/TestPlanHelper.swift index eca4efd..fb9be9f 100644 --- a/Sources/TestConfigurator/xctestplanner/Core/Helper/TestPlanHelper.swift +++ b/Sources/TestConfigurator/xctestplanner/Core/Helper/TestPlanHelper.swift @@ -29,54 +29,6 @@ public class TestPlanHelper { try updatedData.write(to: url) } - static func updateSkippedTests(testPlan: inout TestPlanModel, tests: [String], override: Bool) { - checkForTestTargets(testPlan: testPlan) - for (index, _) in testPlan.testTargets.enumerated() { - if testPlan.testTargets[index].selectedTests != nil { - testPlan.testTargets[index].selectedTests = nil - } - if override { - Logger.message("Overriding skipped tests in test plan") - testPlan.testTargets[index].skippedTests = tests - } else { - if testPlan.testTargets[index].skippedTests == nil { - testPlan.testTargets[index].skippedTests = [] - } - Logger.message("Append given tests to skipped tests in test plan") - testPlan.testTargets[index].skippedTests?.append(contentsOf: tests) - } - } - } - - static func updateSelectedTests(testPlan: inout TestPlanModel, with tests: [String], override: Bool) { - checkForTestTargets(testPlan: testPlan) - for (index, _) in testPlan.testTargets.enumerated() { - if testPlan.testTargets[index].skippedTests != nil { - testPlan.testTargets[index].skippedTests = nil - } - if override { - Logger.message("Overriding selected tests in test plan") - testPlan.testTargets[index].selectedTests = tests - } else { - if testPlan.testTargets[index].selectedTests == nil { - testPlan.testTargets[index].selectedTests = [] - } - Logger.message("Append given tests to selected tests in test plan") - testPlan.testTargets[index].selectedTests?.append(contentsOf: tests) - } - } - } - - static func removeTests(testPlan: inout TestPlanModel, with tests: [String]) { - checkForTestTargets(testPlan: testPlan) - for (index, _) in testPlan.testTargets.enumerated() { - Logger.message("Remove given tests from selected tests in test plan") - for test in tests { - testPlan.testTargets[index].selectedTests?.remove(object: test) - } - } - } - static func updateRerunCount(testPlan: inout TestPlanModel, to count: Int) { Logger.message("Updating rerun count in test plan to: \(count)") if testPlan.defaultOptions.testRepetitionMode == nil { From 8edadbe8a830762dfe7ffcd7bf4d9ee5b46af6a0 Mon Sep 17 00:00:00 2001 From: sam woolf Date: Mon, 13 Jan 2025 14:58:50 +0000 Subject: [PATCH 2/2] tests --- .../TestPlanCodableTests.swift | 96 +++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 Tests/SelectiveTestingTests/TestPlanCodableTests.swift diff --git a/Tests/SelectiveTestingTests/TestPlanCodableTests.swift b/Tests/SelectiveTestingTests/TestPlanCodableTests.swift new file mode 100644 index 0000000..495ffc5 --- /dev/null +++ b/Tests/SelectiveTestingTests/TestPlanCodableTests.swift @@ -0,0 +1,96 @@ +@testable import TestConfigurator +import XCTest + +class SkippedTestsTests: XCTestCase { + // Sample JSON for skippedTests as an array of strings + let jsonWithArray = """ + { + "skippedTests": [ + "DigitalRewardsServiceTests", + "LoyaltyCreditCardRewardsPointViewModelTests" + ] + } + """.data(using: .utf8)! + + // Sample JSON for skippedTests as a dictionary + let jsonWithDictionary = """ + { + "skippedTests": { + "suites": [ + { + "name": "SparksMissionOfferVisibleTrackingEventTests" + } + ] + } + } + """.data(using: .utf8)! + + func testDecodeSkippedTestsAsArray() throws { + let decoder = JSONDecoder() + let container = try decoder.decode(SkippedTestsContainer.self, from: jsonWithArray) + + if case let .array(skippedTests) = container.skippedTests { + XCTAssertEqual(skippedTests, [ + "DigitalRewardsServiceTests", + "LoyaltyCreditCardRewardsPointViewModelTests" + ]) + } else { + XCTFail("Expected skippedTests to be an array") + } + } + + func testDecodeSkippedTestsAsDictionary() throws { + let decoder = JSONDecoder() + let container = try decoder.decode(SkippedTestsContainer.self, from: jsonWithDictionary) + + if case let .dictionary(suites) = container.skippedTests { + XCTAssertEqual(suites.suites.count, 1) + XCTAssertEqual(suites.suites[0].name, "SparksMissionOfferVisibleTrackingEventTests") + } else { + XCTFail("Expected skippedTests to be a dictionary") + } + } + + func testEncodeSkippedTestsAsArray() throws { + let container = SkippedTestsContainer( + skippedTests: .array([ + "DigitalRewardsServiceTests", + "LoyaltyCreditCardRewardsPointViewModelTests" + ]) + ) + + let encoder = JSONEncoder() + encoder.outputFormatting = .prettyPrinted + let encodedData = try encoder.encode(container) + let encodedString = String(data: encodedData, encoding: .utf8) + + XCTAssertNotNil(encodedString) + XCTAssertTrue(encodedString!.contains("\"skippedTests\" : [")) + XCTAssertTrue(encodedString!.contains("\"DigitalRewardsServiceTests\"")) + } + + func testEncodeSkippedTestsAsDictionary() throws { + let container = SkippedTestsContainer( + skippedTests: .dictionary( + Tests.Suites(suites: [ + Tests.Suites.Suite(name: "SparksMissionOfferVisibleTrackingEventTests") + ]) + ) + ) + + let encoder = JSONEncoder() + encoder.outputFormatting = .prettyPrinted + let encodedData = try encoder.encode(container) + let encodedString = String(data: encodedData, encoding: .utf8) + + XCTAssertNotNil(encodedString) + XCTAssertTrue(encodedString!.contains("\"skippedTests\" : {")) + XCTAssertTrue(encodedString!.contains("\"suites\" : [")) + XCTAssertTrue(encodedString!.contains("\"name\" : \"SparksMissionOfferVisibleTrackingEventTests\"")) + } +} + +// Container to isolate the "skippedTests" field for testing +struct SkippedTestsContainer: Codable { + let skippedTests: Tests +}