Skip to content

Commit 5954b71

Browse files
committed
Tests: Migrate 2 suites to Swift Testing
Migrate a few suites to Swift Teting, namely, - SwiftSDKCommandTests - MultiRootSupportTests Depends on: #9012 Relates to: #8997 issue: rdar://157669245
1 parent 52dd688 commit 5954b71

File tree

6 files changed

+370
-220
lines changed

6 files changed

+370
-220
lines changed

Sources/Basics/ArrayHelpers.swift

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,57 @@ public func nextItem<T: Equatable>(in array: [T], after item: T) -> T? {
1717
return nextIndex < array.count ? array[nextIndex] : nil
1818
}
1919
}
20-
return nil // Item not found or it's the last item
20+
return nil // Item not found or it's the last item
21+
}
22+
23+
/// Determines if an array contains all elements of a subset array in any order.
24+
/// - Parameters:
25+
/// - array: The array to search within
26+
/// - subset: The subset array to check for
27+
/// - shouldBeContiguous: if `true`, the subset match must be contiguous sequenence
28+
/// - Returns: `true` if all elements in `subset` are present in `array`, `false` otherwise
29+
public func contains<T: Equatable>(array: [T], subset: [T], shouldBeContiguous: Bool = true) -> Bool {
30+
if shouldBeContiguous {
31+
return containsContiguousSubset(array: array, subset: subset)
32+
} else {
33+
return containsNonContiguousSubset(array: array, subset: subset)
34+
}
35+
}
36+
37+
/// Determines if an array contains all elements of a subset array in any order.
38+
/// - Parameters:
39+
/// - array: The array to search within
40+
/// - subset: The subset array to check for
41+
/// - Returns: `true` if all elements in `subset` are present in `array`, `false` otherwise
42+
internal func containsNonContiguousSubset<T: Equatable>(array: [T], subset: [T]) -> Bool {
43+
for element in subset {
44+
if !array.contains(element) {
45+
return false
46+
}
47+
}
48+
return true
49+
}
50+
51+
/// Determines if an array contains a contiguous subsequence matching the subset array.
52+
/// - Parameters:
53+
/// - array: The array to search within
54+
/// - subset: The contiguous subset array to check for
55+
/// - Returns: `true` if `subset` appears as a contiguous subsequence in `array`, `false` otherwise
56+
internal func containsContiguousSubset<T: Equatable>(array: [T], subset: [T]) -> Bool {
57+
guard !subset.isEmpty else { return true }
58+
guard subset.count <= array.count else { return false }
59+
60+
for startIndex in 0...(array.count - subset.count) {
61+
var matches = true
62+
for (offset, element) in subset.enumerated() {
63+
if array[startIndex + offset] != element {
64+
matches = false
65+
break
66+
}
67+
}
68+
if matches {
69+
return true
70+
}
71+
}
72+
return false
2173
}

Sources/_InternalTestSupport/SwiftTesting+Tags.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,9 @@ extension Tag.Feature.Command {
4141
public enum Package {}
4242
public enum PackageRegistry {}
4343
@Tag public static var Build: Tag
44-
@Tag public static var Test: Tag
4544
@Tag public static var Run: Tag
45+
@Tag public static var Sdk: Tag
46+
@Tag public static var Test: Tag
4647
}
4748

4849
extension Tag.Feature.Command.Package {

Tests/BasicsTests/ArrayHelpersTests.swift

Lines changed: 111 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@
88
See http://swift.org/CONTRIBUTORS.txt for Swift project authors
99
*/
1010

11-
1211
import func Basics.nextItem
12+
@testable import func Basics.containsNonContiguousSubset
13+
@testable import func Basics.containsContiguousSubset
1314
import Testing
1415
@Suite
1516
struct ArrayHelpersTests {
@@ -29,4 +30,113 @@ struct ArrayHelpersTests {
2930
#expect(nextItem(in: [1], after: 1) == nil)
3031
#expect(nextItem(in: [0, 1, 12, 1, 4], after: 1) == 12)
3132
}
33+
34+
@Test(
35+
.tags(
36+
Tag.TestSize.small,
37+
),
38+
)
39+
func containsNonContiguousSubsetReturnsExpectedValue() async throws {
40+
// Empty subset should always return true
41+
#expect(containsNonContiguousSubset(array: [] as [String], subset: []) == true)
42+
#expect(containsNonContiguousSubset(array: [] as [Int], subset: []) == true)
43+
#expect(containsNonContiguousSubset(array: [] as [Bool], subset: []) == true)
44+
#expect(containsNonContiguousSubset(array: [1, 2, 3], subset: []) == true)
45+
46+
// Empty array with non-empty subset should return false
47+
#expect(containsNonContiguousSubset(array: [] as [Int], subset: [1]) == false)
48+
49+
// Single element tests
50+
#expect(containsNonContiguousSubset(array: [1], subset: [1]) == true)
51+
#expect(containsNonContiguousSubset(array: [1], subset: [2]) == false)
52+
53+
// Basic subset tests - all elements present
54+
#expect(containsNonContiguousSubset(array: [1, 2, 3, 4, 5], subset: [1, 3, 5]) == true)
55+
#expect(containsNonContiguousSubset(array: [1, 2, 3, 4, 5], subset: [5, 1, 3]) == true) // Order doesn't matter
56+
#expect(containsNonContiguousSubset(array: [1, 2, 3, 4, 5], subset: [2, 4]) == true)
57+
58+
// Missing elements tests
59+
#expect(containsNonContiguousSubset(array: [1, 2, 3, 4, 5], subset: [1, 6]) == false)
60+
#expect(containsNonContiguousSubset(array: [1, 2, 3, 4, 5], subset: [6, 7, 8]) == false)
61+
62+
// Duplicate elements in subset
63+
#expect(containsNonContiguousSubset(array: [1, 2, 2, 3, 4], subset: [2, 2]) == true)
64+
#expect(containsNonContiguousSubset(array: [1, 2, 3, 4], subset: [2, 2]) == true) // Only one 2 in array, but still contains 2
65+
66+
// String tests
67+
#expect(containsNonContiguousSubset(array: ["a", "b", "c", "d"], subset: ["a", "c"]) == true)
68+
#expect(containsNonContiguousSubset(array: ["a", "b", "c", "d"], subset: ["d", "a"]) == true)
69+
#expect(containsNonContiguousSubset(array: ["a", "b", "c", "d"], subset: ["e"]) == false)
70+
71+
// Subset same size as array
72+
#expect(containsNonContiguousSubset(array: [1, 2, 3], subset: [3, 2, 1]) == true)
73+
#expect(containsNonContiguousSubset(array: [1, 2, 3], subset: [1, 2, 4]) == false)
74+
75+
// Subset larger than array
76+
#expect(containsNonContiguousSubset(array: [1, 2], subset: [1, 2, 3]) == false)
77+
}
78+
79+
@Test(
80+
.tags(
81+
Tag.TestSize.small,
82+
),
83+
)
84+
func containsContiguousSubsetReturnsExpectedValue() async throws {
85+
// Empty subset should always return true
86+
#expect(containsContiguousSubset(array: [] as [String], subset: []) == true)
87+
#expect(containsContiguousSubset(array: [] as [Int], subset: []) == true)
88+
#expect(containsContiguousSubset(array: [] as [Bool], subset: []) == true)
89+
#expect(containsContiguousSubset(array: [1, 2, 3], subset: []) == true)
90+
91+
// Empty array with non-empty subset should return false
92+
#expect(containsContiguousSubset(array: [] as [Int], subset: [1]) == false)
93+
94+
// Single element tests
95+
#expect(containsContiguousSubset(array: [1], subset: [1]) == true)
96+
#expect(containsContiguousSubset(array: [1], subset: [2]) == false)
97+
98+
// Basic contiguous subset tests
99+
#expect(containsContiguousSubset(array: [1, 2, 3, 4, 5], subset: [2, 3, 4]) == true)
100+
#expect(containsContiguousSubset(array: [1, 2, 3, 4, 5], subset: [1, 2]) == true)
101+
#expect(containsContiguousSubset(array: [1, 2, 3, 4, 5], subset: [4, 5]) == true)
102+
#expect(containsContiguousSubset(array: [1, 2, 3, 4, 5], subset: [1, 2, 3, 4, 5]) == true) // Entire array
103+
104+
// Non-contiguous elements should return false
105+
#expect(containsContiguousSubset(array: [1, 2, 3, 4, 5], subset: [1, 3, 5]) == false)
106+
#expect(containsContiguousSubset(array: [1, 2, 3, 4, 5], subset: [2, 4]) == false)
107+
#expect(containsContiguousSubset(array: [1, 2, 3, 4, 5], subset: [1, 3]) == false)
108+
109+
// Wrong order should return false
110+
#expect(containsContiguousSubset(array: [1, 2, 3, 4, 5], subset: [3, 2, 1]) == false)
111+
#expect(containsContiguousSubset(array: [1, 2, 3, 4, 5], subset: [5, 4, 3]) == false)
112+
113+
// Missing elements
114+
#expect(containsContiguousSubset(array: [1, 2, 3, 4, 5], subset: [1, 6]) == false)
115+
#expect(containsContiguousSubset(array: [1, 2, 3, 4, 5], subset: [6, 7]) == false)
116+
117+
// Duplicate elements
118+
#expect(containsContiguousSubset(array: [1, 2, 2, 3, 4], subset: [2, 2, 3]) == true)
119+
#expect(containsContiguousSubset(array: [1, 2, 3, 2, 4], subset: [2, 2]) == false) // 2s are not contiguous
120+
#expect(containsContiguousSubset(array: [1, 1, 2, 3], subset: [1, 1]) == true)
121+
122+
// String tests
123+
#expect(containsContiguousSubset(array: ["a"], subset: ["b", "c"]) == false)
124+
#expect(containsContiguousSubset(array: ["a"], subset: []) == true)
125+
#expect(containsContiguousSubset(array: ["a", "b", "c", "d"], subset: ["b", "c"]) == true)
126+
#expect(containsContiguousSubset(array: ["a", "b", "c", "d"], subset: ["a", "c"]) == false) // Not contiguous
127+
#expect(containsContiguousSubset(array: ["hello", "world", "test"], subset: ["world", "test"]) == true)
128+
129+
// Subset larger than array
130+
#expect(containsContiguousSubset(array: [1, 2], subset: [1, 2, 3]) == false)
131+
132+
// Multiple occurrences - should find first match
133+
#expect(containsContiguousSubset(array: [1, 2, 3, 1, 2, 3], subset: [1, 2]) == true)
134+
#expect(containsContiguousSubset(array: [1, 2, 3, 1, 2, 3], subset: [2, 3]) == true)
135+
136+
// Edge case: subset at the end
137+
#expect(containsContiguousSubset(array: [1, 2, 3, 4], subset: [3, 4]) == true)
138+
139+
// Edge case: subset at the beginning
140+
#expect(containsContiguousSubset(array: [1, 2, 3, 4], subset: [1, 2]) == true)
141+
}
32142
}

Tests/CommandsTests/CommandsTestCase.swift

Lines changed: 0 additions & 54 deletions
This file was deleted.

Tests/CommandsTests/MultiRootSupportTests.swift

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,37 @@
22
//
33
// This source file is part of the Swift open source project
44
//
5-
// Copyright (c) 2014-2024 Apple Inc. and the Swift project authors
5+
// Copyright (c) 2014-2025 Apple Inc. and the Swift project authors
66
// Licensed under Apache License v2.0 with Runtime Library Exception
77
//
88
// See http://swift.org/LICENSE.txt for license information
99
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
1010
//
1111
//===----------------------------------------------------------------------===//
12+
import Foundation
1213

1314
import Basics
1415
import Commands
1516
import _InternalTestSupport
1617
import Workspace
17-
import XCTest
18+
import Testing
1819

19-
final class MultiRootSupportTests: CommandsTestCase {
20-
func testWorkspaceLoader() throws {
20+
@Suite(
21+
.tags(
22+
.TestSize.large,
23+
),
24+
)
25+
struct MultiRootSupportTests {
26+
@Test
27+
func workspaceLoader() throws {
2128
let fs = InMemoryFileSystem(emptyFiles: [
2229
"/tmp/test/dep/Package.swift",
2330
"/tmp/test/local/Package.swift",
2431
])
2532
let path = AbsolutePath("/tmp/test/Workspace.xcworkspace")
26-
try fs.writeFileContents(path.appending("contents.xcworkspacedata"), string:
33+
try fs.writeFileContents(
34+
path.appending("contents.xcworkspacedata"),
35+
string:
2736
"""
2837
<?xml version="1.0" encoding="UTF-8"?>
2938
<Workspace
@@ -41,7 +50,9 @@ final class MultiRootSupportTests: CommandsTestCase {
4150
let observability = ObservabilitySystem.makeForTesting()
4251
let result = try XcodeWorkspaceLoader(fileSystem: fs, observabilityScope: observability.topScope).load(workspace: path)
4352

44-
XCTAssertNoDiagnostics(observability.diagnostics)
45-
XCTAssertEqual(result.map{ $0.pathString }.sorted(), [AbsolutePath("/tmp/test/dep").pathString, AbsolutePath("/tmp/test/local").pathString])
53+
expectNoDiagnostics(observability.diagnostics)
54+
let actual = result.map { $0.pathString }.sorted()
55+
let expected = [AbsolutePath("/tmp/test/dep").pathString, AbsolutePath("/tmp/test/local").pathString]
56+
#expect(actual == expected)
4657
}
4758
}

0 commit comments

Comments
 (0)