Skip to content

Commit ac2adb7

Browse files
authored
SWIFT-178 Minor test utils improvements (#272)
1 parent bd4baba commit ac2adb7

File tree

4 files changed

+119
-119
lines changed

4 files changed

+119
-119
lines changed

Sources/MongoSwift/SDAM.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,18 @@ public struct TopologyDescription {
196196
case sharded = "Sharded"
197197
/// A topology whose type is not yet known.
198198
case unknown = "Unknown"
199+
200+
/// Internal initializer used for translating evergreen config and spec test topologies to a `TopologyType`
201+
internal init(from str: String) {
202+
switch str {
203+
case "sharded", "sharded_cluster":
204+
self = .sharded
205+
case "replicaset", "replica_set":
206+
self = .replicaSetWithPrimary
207+
default:
208+
self = .single
209+
}
210+
}
199211
}
200212

201213
/// The type of this topology.

Tests/MongoSwiftTests/CrudTests.swift

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -259,13 +259,6 @@ private class BulkWriteTest: CrudTest {
259259
return BulkWriteOptions(ordered: ordered)
260260
}
261261

262-
private typealias DeleteOneModel = MongoCollection<Document>.DeleteOneModel
263-
private typealias DeleteManyModel = MongoCollection<Document>.DeleteManyModel
264-
private typealias InsertOneModel = MongoCollection<Document>.InsertOneModel
265-
private typealias ReplaceOneModel = MongoCollection<Document>.ReplaceOneModel
266-
private typealias UpdateOneModel = MongoCollection<Document>.UpdateOneModel
267-
private typealias UpdateManyModel = MongoCollection<Document>.UpdateManyModel
268-
269262
private static func parseWriteModel(_ request: Document) throws -> WriteModel {
270263
let name: String = try request.get("name")
271264
let args: Document = try request.get("arguments")

Tests/MongoSwiftTests/MongoClientTests.swift

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ final class MongoClientTests: MongoSwiftTestCase {
3838
}
3939

4040
func testServerVersion() throws {
41-
typealias Version = MongoClient.ServerVersion
41+
typealias Version = ServerVersion
4242

4343
expect(try MongoClient().serverVersion()).toNot(throwError())
4444

@@ -55,36 +55,36 @@ final class MongoClientTests: MongoSwiftTestCase {
5555
expect(try Version("3.6.1.1")).to(equal(three61))
5656

5757
// lt
58-
expect(three6.isLessThan(three6)).to(beFalse())
59-
expect(three6.isLessThan(three61)).to(beTrue())
60-
expect(three61.isLessThan(three6)).to(beFalse())
61-
expect(three61.isLessThan(three7)).to(beTrue())
62-
expect(three7.isLessThan(three6)).to(beFalse())
63-
expect(three7.isLessThan(three61)).to(beFalse())
58+
expect(three6 < three6).to(beFalse())
59+
expect(three6 < three61).to(beTrue())
60+
expect(three61 < three6).to(beFalse())
61+
expect(three61 < three7).to(beTrue())
62+
expect(three7 < three6).to(beFalse())
63+
expect(three7 < three61).to(beFalse())
6464

6565
// lte
66-
expect(three6.isLessThanOrEqualTo(three6)).to(beTrue())
67-
expect(three6.isLessThanOrEqualTo(three61)).to(beTrue())
68-
expect(three61.isLessThanOrEqualTo(three6)).to(beFalse())
69-
expect(three61.isLessThanOrEqualTo(three7)).to(beTrue())
70-
expect(three7.isLessThanOrEqualTo(three6)).to(beFalse())
71-
expect(three7.isLessThanOrEqualTo(three61)).to(beFalse())
66+
expect(three6 <= three6).to(beTrue())
67+
expect(three6 <= three61).to(beTrue())
68+
expect(three61 <= three6).to(beFalse())
69+
expect(three61 <= three7).to(beTrue())
70+
expect(three7 <= three6).to(beFalse())
71+
expect(three7 <= three61).to(beFalse())
7272

7373
// gt
74-
expect(three6.isGreaterThan(three6)).to(beFalse())
75-
expect(three6.isGreaterThan(three61)).to(beFalse())
76-
expect(three61.isGreaterThan(three6)).to(beTrue())
77-
expect(three61.isGreaterThan(three7)).to(beFalse())
78-
expect(three7.isGreaterThan(three6)).to(beTrue())
79-
expect(three7.isGreaterThan(three61)).to(beTrue())
74+
expect(three6 > three6).to(beFalse())
75+
expect(three6 > three61).to(beFalse())
76+
expect(three61 > three6).to(beTrue())
77+
expect(three61 > three7).to(beFalse())
78+
expect(three7 > three6).to(beTrue())
79+
expect(three7 > three61).to(beTrue())
8080

8181
// gte
82-
expect(three6.isGreaterThanOrEqualTo(three6)).to(beTrue())
83-
expect(three6.isGreaterThanOrEqualTo(three61)).to(beFalse())
84-
expect(three61.isGreaterThanOrEqualTo(three6)).to(beTrue())
85-
expect(three61.isGreaterThanOrEqualTo(three7)).to(beFalse())
86-
expect(three7.isGreaterThanOrEqualTo(three6)).to(beTrue())
87-
expect(three7.isGreaterThanOrEqualTo(three61)).to(beTrue())
82+
expect(three6 >= three6).to(beTrue())
83+
expect(three6 >= three61).to(beFalse())
84+
expect(three61 >= three6).to(beTrue())
85+
expect(three61 >= three7).to(beFalse())
86+
expect(three7 >= three6).to(beTrue())
87+
expect(three7 >= three61).to(beTrue())
8888

8989
// invalid strings
9090
expect(try Version("hi")).to(throwError())

Tests/MongoSwiftTests/TestUtils.swift

Lines changed: 82 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,70 @@ import mongoc
44
import Nimble
55
import XCTest
66

7+
typealias DeleteOneModel = MongoCollection<Document>.DeleteOneModel
8+
typealias DeleteManyModel = MongoCollection<Document>.DeleteManyModel
9+
typealias InsertOneModel = MongoCollection<Document>.InsertOneModel
10+
typealias ReplaceOneModel = MongoCollection<Document>.ReplaceOneModel
11+
typealias UpdateOneModel = MongoCollection<Document>.UpdateOneModel
12+
typealias UpdateManyModel = MongoCollection<Document>.UpdateManyModel
13+
14+
/// A struct representing a server version.
15+
internal struct ServerVersion: Comparable, Decodable {
16+
let major: Int
17+
let minor: Int
18+
let patch: Int
19+
20+
/// initialize a server version from a string
21+
init(_ str: String) throws {
22+
let versionComponents = str.split(separator: ".").prefix(3)
23+
guard versionComponents.count >= 2 else {
24+
throw TestError(message: "Expected version string \(str) to have at least two .-separated components")
25+
}
26+
27+
guard let major = Int(versionComponents[0]) else {
28+
throw TestError(message: "Error parsing major version from \(str)")
29+
}
30+
guard let minor = Int(versionComponents[1]) else {
31+
throw TestError(message: "Error parsing minor version from \(str)")
32+
}
33+
34+
var patch = 0
35+
if versionComponents.count == 3 {
36+
// in case there is text at the end, for ex "3.6.0-rc1", stop first time
37+
/// we encounter a non-numeric character.
38+
let numbersOnly = versionComponents[2].prefix { "0123456789".contains($0) }
39+
guard let patchValue = Int(numbersOnly) else {
40+
throw TestError(message: "Error parsing patch version from \(str)")
41+
}
42+
patch = patchValue
43+
}
44+
45+
self.init(major: major, minor: minor, patch: patch)
46+
}
47+
48+
init(from decoder: Decoder) throws {
49+
let str = try decoder.singleValueContainer().decode(String.self)
50+
try self.init(str)
51+
}
52+
53+
// initialize given major, minor, and optional patch
54+
init(major: Int, minor: Int, patch: Int? = nil) {
55+
self.major = major
56+
self.minor = minor
57+
self.patch = patch ?? 0
58+
}
59+
60+
static func < (lhs: ServerVersion, rhs: ServerVersion) -> Bool {
61+
if lhs.major != rhs.major {
62+
return lhs.major < rhs.major
63+
} else if lhs.minor != rhs.minor {
64+
return lhs.minor < rhs.minor
65+
} else {
66+
return lhs.patch < rhs.patch
67+
}
68+
}
69+
}
70+
771
// sourcery: disableTests
872
class MongoSwiftTestCase: XCTestCase {
973
/// Gets the name of the database the test case is running against.
@@ -74,15 +138,7 @@ class MongoSwiftTestCase: XCTestCase {
74138
guard let topology = ProcessInfo.processInfo.environment["MONGODB_TOPOLOGY"] else {
75139
return .single
76140
}
77-
78-
switch topology {
79-
case "sharded_cluster":
80-
return .sharded
81-
case "replica_set":
82-
return .replicaSetWithPrimary
83-
default:
84-
return .single
85-
}
141+
return TopologyDescription.TopologyType(from: topology)
86142
}
87143
}
88144

@@ -98,80 +154,13 @@ extension MongoClient {
98154
return try ServerVersion(versionString)
99155
}
100156

101-
/// A struct representing a server version.
102-
internal struct ServerVersion: Equatable {
103-
let major: Int
104-
let minor: Int
105-
let patch: Int
106-
107-
/// initialize a server version from a string
108-
init(_ str: String) throws {
109-
let versionComponents = str.split(separator: ".").prefix(3)
110-
guard versionComponents.count >= 2 else {
111-
throw TestError(message: "Expected version string \(str) to have at least two .-separated components")
112-
}
113-
114-
guard let major = Int(versionComponents[0]) else {
115-
throw TestError(message: "Error parsing major version from \(str)")
116-
}
117-
guard let minor = Int(versionComponents[1]) else {
118-
throw TestError(message: "Error parsing minor version from \(str)")
119-
}
120-
121-
var patch = 0
122-
if versionComponents.count == 3 {
123-
// in case there is text at the end, for ex "3.6.0-rc1", stop first time
124-
/// we encounter a non-numeric character.
125-
let numbersOnly = versionComponents[2].prefix { "0123456789".contains($0) }
126-
guard let patchValue = Int(numbersOnly) else {
127-
throw TestError(message: "Error parsing patch version from \(str)")
128-
}
129-
patch = patchValue
130-
}
131-
132-
self.init(major: major, minor: minor, patch: patch)
133-
}
134-
135-
// initialize given major, minor, and optional patch
136-
init(major: Int, minor: Int, patch: Int? = nil) {
137-
self.major = major
138-
self.minor = minor
139-
self.patch = patch ?? 0
140-
}
141-
142-
func isLessThan(_ version: ServerVersion) -> Bool {
143-
if self.major == version.major {
144-
if self.minor == version.minor {
145-
// if major & minor equal, just compare patches
146-
return self.patch < version.patch
147-
}
148-
// major equal but minor isn't, so compare minor
149-
return self.minor < version.minor
150-
}
151-
// just compare major versions
152-
return self.major < version.major
153-
}
154-
155-
func isLessThanOrEqualTo(_ version: ServerVersion) -> Bool {
156-
return self == version || self.isLessThan(version)
157-
}
158-
159-
func isGreaterThan(_ version: ServerVersion) -> Bool {
160-
return !self.isLessThanOrEqualTo(version)
161-
}
162-
163-
func isGreaterThanOrEqualTo(_ version: ServerVersion) -> Bool {
164-
return !self.isLessThan(version)
165-
}
166-
}
167-
168157
internal func serverVersionIsInRange(_ min: String?, _ max: String?) throws -> Bool {
169158
let version = try self.serverVersion()
170159

171-
if let min = min, version.isLessThan(try ServerVersion(min)) {
160+
if let min = min, version < (try ServerVersion(min)) {
172161
return false
173162
}
174-
if let max = max, version.isGreaterThan(try ServerVersion(max)) {
163+
if let max = max, version > (try ServerVersion(max)) {
175164
return false
176165
}
177166

@@ -183,6 +172,19 @@ extension MongoClient {
183172
}
184173
}
185174

175+
extension Document {
176+
internal func sortedEquals(_ other: Document) -> Bool {
177+
let keys = self.keys.sorted()
178+
let otherKeys = other.keys.sorted()
179+
180+
// first compare keys, because rearrangeDoc will discard any that don't exist in `expected`
181+
expect(keys).to(equal(otherKeys))
182+
183+
let rearranged = rearrangeDoc(other, toLookLike: self)
184+
return self == rearranged
185+
}
186+
}
187+
186188
/// Cleans and normalizes a given JSON string for comparison purposes
187189
func clean(json: String?) -> String {
188190
guard let str = json else {
@@ -222,7 +224,7 @@ internal func sortedEqual(_ expectedValue: Document?) -> Predicate<Document> {
222224
return Predicate.define("sortedEqual <\(stringify(expectedValue))>") { actualExpression, msg in
223225
let actualValue = try actualExpression.evaluate()
224226

225-
if expectedValue == nil || actualValue == nil {
227+
guard let expected = expectedValue, let actual = actualValue else {
226228
if expectedValue == nil && actualValue != nil {
227229
return PredicateResult(
228230
status: .fail,
@@ -232,14 +234,7 @@ internal func sortedEqual(_ expectedValue: Document?) -> Predicate<Document> {
232234
return PredicateResult(status: .fail, message: msg)
233235
}
234236

235-
let expectedKeys = expectedValue?.keys.sorted()
236-
let actualKeys = actualValue?.keys.sorted()
237-
238-
// first compare keys, because rearrangeDoc will discard any that don't exist in `expected`
239-
expect(expectedKeys).to(equal(actualKeys))
240-
241-
let rearranged = rearrangeDoc(actualValue!, toLookLike: expectedValue!)
242-
let matches = expectedValue == rearranged
237+
let matches = expected.sortedEquals(actual)
243238
return PredicateResult(status: PredicateStatus(bool: matches), message: msg)
244239
}
245240
}

0 commit comments

Comments
 (0)