Skip to content

Commit 7517cd2

Browse files
author
Matt Zanchelli
committed
Add an algorithmically faster variant of XCTAssertUnorderedEqualSequences that works on elements that are Hashable
1 parent 5795324 commit 7517cd2

File tree

1 file changed

+45
-0
lines changed

1 file changed

+45
-0
lines changed

Tests/SwiftAlgorithmsTests/TestUtilities.swift

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,52 @@ func XCTAssertUnorderedEqualSequences<S1: Sequence, S2: Sequence>(
117117
if !s1.isEmpty {
118118
fail("first sequence contains \(s1) missing from second sequence")
119119
}
120+
}
120121

122+
/// Asserts two sequences contain exactly the same elements but not necessarily
123+
/// in the same order.
124+
/// - Complexity: O(*n* + *m*) where *n* is the number of elements in the first
125+
/// sequence and *m* is the number of elements in the second sequence
126+
func XCTAssertUnorderedEqualSequences<S1: Sequence, S2: Sequence>(
127+
_ expression1: @autoclosure () throws -> S1,
128+
_ expression2: @autoclosure () throws -> S2,
129+
_ message: @autoclosure () -> String = "",
130+
file: StaticString = #file, line: UInt = #line
131+
) rethrows where S1.Element: Hashable, S1.Element == S2.Element {
132+
func fail(_ reason: String) {
133+
let message = message()
134+
XCTFail(message.isEmpty ? reason : "\(message) - \(reason)",
135+
file: file, line: line)
136+
}
137+
138+
// Map the elements of the first sequence to the number of times it appeared
139+
// in the sequence
140+
var s1 = [S1.Element: Int](try expression1().lazy.map({
141+
($0, 1)
142+
}), uniquingKeysWith: {
143+
$0 + $1
144+
})
145+
146+
var missing: [S1.Element] = []
147+
for elt in try expression2() {
148+
if let count = s1[elt] {
149+
if count > 1 {
150+
s1[elt] = (count - 1)
151+
} else {
152+
s1[elt] = nil
153+
}
154+
} else {
155+
missing.append(elt)
156+
}
157+
}
158+
159+
if !missing.isEmpty {
160+
fail("first sequence missing '\(missing)' elements from second sequence")
161+
}
162+
163+
if !s1.isEmpty {
164+
fail("second sequence missing one or more occurrences of '\(s1.keys)' elements from first sequence")
165+
}
121166
}
122167

123168
func XCTAssertEqualSequences<S1: Sequence, S2: Sequence>(

0 commit comments

Comments
 (0)