Skip to content

Commit d5e3e9d

Browse files
authored
Fix for deocding issue when testplan has skipped tests in a swift testing suite (#46)
* testplan codable fix * tests
1 parent 89fe1d4 commit d5e3e9d

File tree

3 files changed

+135
-50
lines changed

3 files changed

+135
-50
lines changed

Sources/TestConfigurator/xctestplanner/Core/Entity/TestPlanModel.swift

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,45 @@ public struct LocationScenario: Codable {
6666

6767
public struct TestTarget: Codable {
6868
public var parallelizable: Bool?
69-
public var skippedTests: [String]?
70-
public var selectedTests: [String]?
69+
public var skippedTests: Tests?
70+
public var selectedTests: Tests?
7171
public var target: Target
7272
public var enabled: Bool?
7373
}
74+
75+
public enum Tests: Codable {
76+
case array([String])
77+
case dictionary(Suites)
78+
79+
public struct Suites: Codable {
80+
let suites: [Suite]
81+
82+
public struct Suite: Codable {
83+
let name: String
84+
}
85+
}
86+
87+
public init(from decoder: Decoder) throws {
88+
let container = try decoder.singleValueContainer()
89+
if let array = try? container.decode([String].self) {
90+
self = .array(array)
91+
return
92+
}
93+
94+
if let dict = try? container.decode(Suites.self) {
95+
self = .dictionary(dict)
96+
return
97+
}
98+
throw DecodingError.dataCorruptedError(in: container, debugDescription: "Invalid type for skippedTests")
99+
}
100+
101+
public func encode(to encoder: Encoder) throws {
102+
var container = encoder.singleValueContainer()
103+
switch self {
104+
case .array(let array):
105+
try container.encode(array)
106+
case .dictionary(let dict):
107+
try container.encode(dict)
108+
}
109+
}
110+
}

Sources/TestConfigurator/xctestplanner/Core/Helper/TestPlanHelper.swift

Lines changed: 0 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -29,54 +29,6 @@ public class TestPlanHelper {
2929
try updatedData.write(to: url)
3030
}
3131

32-
static func updateSkippedTests(testPlan: inout TestPlanModel, tests: [String], override: Bool) {
33-
checkForTestTargets(testPlan: testPlan)
34-
for (index, _) in testPlan.testTargets.enumerated() {
35-
if testPlan.testTargets[index].selectedTests != nil {
36-
testPlan.testTargets[index].selectedTests = nil
37-
}
38-
if override {
39-
Logger.message("Overriding skipped tests in test plan")
40-
testPlan.testTargets[index].skippedTests = tests
41-
} else {
42-
if testPlan.testTargets[index].skippedTests == nil {
43-
testPlan.testTargets[index].skippedTests = []
44-
}
45-
Logger.message("Append given tests to skipped tests in test plan")
46-
testPlan.testTargets[index].skippedTests?.append(contentsOf: tests)
47-
}
48-
}
49-
}
50-
51-
static func updateSelectedTests(testPlan: inout TestPlanModel, with tests: [String], override: Bool) {
52-
checkForTestTargets(testPlan: testPlan)
53-
for (index, _) in testPlan.testTargets.enumerated() {
54-
if testPlan.testTargets[index].skippedTests != nil {
55-
testPlan.testTargets[index].skippedTests = nil
56-
}
57-
if override {
58-
Logger.message("Overriding selected tests in test plan")
59-
testPlan.testTargets[index].selectedTests = tests
60-
} else {
61-
if testPlan.testTargets[index].selectedTests == nil {
62-
testPlan.testTargets[index].selectedTests = []
63-
}
64-
Logger.message("Append given tests to selected tests in test plan")
65-
testPlan.testTargets[index].selectedTests?.append(contentsOf: tests)
66-
}
67-
}
68-
}
69-
70-
static func removeTests(testPlan: inout TestPlanModel, with tests: [String]) {
71-
checkForTestTargets(testPlan: testPlan)
72-
for (index, _) in testPlan.testTargets.enumerated() {
73-
Logger.message("Remove given tests from selected tests in test plan")
74-
for test in tests {
75-
testPlan.testTargets[index].selectedTests?.remove(object: test)
76-
}
77-
}
78-
}
79-
8032
static func updateRerunCount(testPlan: inout TestPlanModel, to count: Int) {
8133
Logger.message("Updating rerun count in test plan to: \(count)")
8234
if testPlan.defaultOptions.testRepetitionMode == nil {
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
@testable import TestConfigurator
2+
import XCTest
3+
4+
class SkippedTestsTests: XCTestCase {
5+
// Sample JSON for skippedTests as an array of strings
6+
let jsonWithArray = """
7+
{
8+
"skippedTests": [
9+
"DigitalRewardsServiceTests",
10+
"LoyaltyCreditCardRewardsPointViewModelTests"
11+
]
12+
}
13+
""".data(using: .utf8)!
14+
15+
// Sample JSON for skippedTests as a dictionary
16+
let jsonWithDictionary = """
17+
{
18+
"skippedTests": {
19+
"suites": [
20+
{
21+
"name": "SparksMissionOfferVisibleTrackingEventTests"
22+
}
23+
]
24+
}
25+
}
26+
""".data(using: .utf8)!
27+
28+
func testDecodeSkippedTestsAsArray() throws {
29+
let decoder = JSONDecoder()
30+
let container = try decoder.decode(SkippedTestsContainer.self, from: jsonWithArray)
31+
32+
if case let .array(skippedTests) = container.skippedTests {
33+
XCTAssertEqual(skippedTests, [
34+
"DigitalRewardsServiceTests",
35+
"LoyaltyCreditCardRewardsPointViewModelTests"
36+
])
37+
} else {
38+
XCTFail("Expected skippedTests to be an array")
39+
}
40+
}
41+
42+
func testDecodeSkippedTestsAsDictionary() throws {
43+
let decoder = JSONDecoder()
44+
let container = try decoder.decode(SkippedTestsContainer.self, from: jsonWithDictionary)
45+
46+
if case let .dictionary(suites) = container.skippedTests {
47+
XCTAssertEqual(suites.suites.count, 1)
48+
XCTAssertEqual(suites.suites[0].name, "SparksMissionOfferVisibleTrackingEventTests")
49+
} else {
50+
XCTFail("Expected skippedTests to be a dictionary")
51+
}
52+
}
53+
54+
func testEncodeSkippedTestsAsArray() throws {
55+
let container = SkippedTestsContainer(
56+
skippedTests: .array([
57+
"DigitalRewardsServiceTests",
58+
"LoyaltyCreditCardRewardsPointViewModelTests"
59+
])
60+
)
61+
62+
let encoder = JSONEncoder()
63+
encoder.outputFormatting = .prettyPrinted
64+
let encodedData = try encoder.encode(container)
65+
let encodedString = String(data: encodedData, encoding: .utf8)
66+
67+
XCTAssertNotNil(encodedString)
68+
XCTAssertTrue(encodedString!.contains("\"skippedTests\" : ["))
69+
XCTAssertTrue(encodedString!.contains("\"DigitalRewardsServiceTests\""))
70+
}
71+
72+
func testEncodeSkippedTestsAsDictionary() throws {
73+
let container = SkippedTestsContainer(
74+
skippedTests: .dictionary(
75+
Tests.Suites(suites: [
76+
Tests.Suites.Suite(name: "SparksMissionOfferVisibleTrackingEventTests")
77+
])
78+
)
79+
)
80+
81+
let encoder = JSONEncoder()
82+
encoder.outputFormatting = .prettyPrinted
83+
let encodedData = try encoder.encode(container)
84+
let encodedString = String(data: encodedData, encoding: .utf8)
85+
86+
XCTAssertNotNil(encodedString)
87+
XCTAssertTrue(encodedString!.contains("\"skippedTests\" : {"))
88+
XCTAssertTrue(encodedString!.contains("\"suites\" : ["))
89+
XCTAssertTrue(encodedString!.contains("\"name\" : \"SparksMissionOfferVisibleTrackingEventTests\""))
90+
}
91+
}
92+
93+
// Container to isolate the "skippedTests" field for testing
94+
struct SkippedTestsContainer: Codable {
95+
let skippedTests: Tests
96+
}

0 commit comments

Comments
 (0)