Skip to content

Commit 6bf768e

Browse files
authored
Merge pull request vkuttyp#5 from FoxClock/TestOptimisation
Test optimisation
2 parents f0e46de + 9867dba commit 6bf768e

1 file changed

Lines changed: 64 additions & 56 deletions

File tree

Tests/SQLClientSwiftTests/SQLClientSwiftTests.swift

Lines changed: 64 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -3,182 +3,190 @@
33
// Set environment variables: HOST, USERNAME, PASSWORD, DATABASE (optional)
44

55
import XCTest
6+
67
@testable import SQLClientSwift
78

89
final class SQLClientSwiftTests: XCTestCase {
910

1011
private func env(_ key: String) -> String { ProcessInfo.processInfo.environment[key] ?? "" }
11-
private var host: String { env("HOST") }
12+
private var host: String { env("HOST") }
1213
private var username: String { env("USERNAME") }
1314
private var password: String { env("PASSWORD") }
1415
private var database: String { env("DATABASE") }
1516
private var canConnect: Bool { !host.isEmpty && !username.isEmpty && !password.isEmpty }
17+
private var client: SQLClient! // global client
1618

1719
private func makeClient() async throws -> SQLClient {
20+
let c = SQLClient()
21+
try await c.connect(
22+
server: host, username: username, password: password,
23+
database: database.isEmpty ? nil : database)
24+
return c
25+
}
26+
27+
/// Called before each XCTest method is run. Able to throw errors on setup.
28+
/// Centralises boilerplate setup making
29+
override func setUp() async throws {
30+
try super.setUpWithError()
1831
guard canConnect else {
1932
throw XCTSkip("Set HOST, USERNAME, PASSWORD environment variables to run tests.")
2033
}
21-
let client = SQLClient()
22-
try await client.connect(server: host, username: username, password: password,
23-
database: database.isEmpty ? nil : database)
24-
return client
34+
client = try await makeClient()
35+
36+
}
37+
38+
/// Called after each XCTest method is run. Able to throw errors on cleanup.
39+
/// Ensures cleanup from each test is completed after the test is run. Before
40+
/// the next test is run.
41+
override func tearDown() async throws {
42+
guard client != nil else { return }
43+
try await client.disconnect()
44+
try await super.tearDown()
2545
}
2646

2747
func testConnect() async throws {
28-
let client = try await makeClient()
29-
let connected = await client.isConnected
48+
// Use a local client, as the global client is already connected
49+
let localClient = SQLClient()
50+
try await localClient.connect(
51+
server: host, username: username, password: password,
52+
database: database.isEmpty ? nil : database)
53+
54+
let connected = await localClient.isConnected
3055
XCTAssertTrue(connected)
31-
await client.disconnect()
32-
let isConnected = await client.isConnected
56+
57+
await localClient.disconnect()
58+
let isConnected = await localClient.isConnected
3359
XCTAssertFalse(isConnected)
3460
}
3561

3662
func testDoubleConnectThrows() async throws {
37-
let client = try await makeClient()
38-
defer { Task { await client.disconnect() } }
63+
// Use a local client as the global client is already connected
64+
let localClient = SQLClient()
65+
try await localClient.connect(
66+
server: host, username: username, password: password,
67+
database: database.isEmpty ? nil : database)
68+
// Defer is used here as race condition on cleanup is inconsequential
69+
defer { Task { await localClient.disconnect() } }
70+
3971
do {
40-
try await client.connect(server: host, username: username, password: password)
72+
try await localClient.connect(server: host, username: username, password: password)
4173
XCTFail("Expected alreadyConnected")
42-
} catch SQLClientError.alreadyConnected { }
74+
} catch SQLClientError.alreadyConnected {}
4375
}
4476

4577
func testSelectScalar() async throws {
46-
let client = try await makeClient()
47-
defer { Task { await client.disconnect() } }
4878
let rows = try await client.query("SELECT 42 AS Answer")
4979
XCTAssertEqual(rows.count, 1)
5080
XCTAssertEqual(rows[0].int("Answer"), 42)
5181
}
5282

5383
func testSelectNull() async throws {
54-
let client = try await makeClient()
55-
defer { Task { await client.disconnect() } }
5684
let rows = try await client.query("SELECT NULL AS Val")
5785
XCTAssertTrue(rows[0].isNull("Val"))
5886
}
5987

6088
func testSelectString() async throws {
61-
let client = try await makeClient()
62-
defer { Task { await client.disconnect() } }
6389
let rows = try await client.query("SELECT 'Hello' AS Msg")
6490
XCTAssertEqual(rows[0].string("Msg"), "Hello")
6591
}
6692

6793
func testSelectFloat() async throws {
68-
let client = try await makeClient()
69-
defer { Task { await client.disconnect() } }
7094
let rows = try await client.query("SELECT CAST(3.14 AS FLOAT) AS Pi")
7195
XCTAssertEqual(rows[0].double("Pi") ?? 0, 3.14, accuracy: 0.001)
7296
}
7397

7498
func testSelectBit() async throws {
75-
let client = try await makeClient()
76-
defer { Task { await client.disconnect() } }
7799
let rows = try await client.query("SELECT CAST(1 AS BIT) AS Flag")
78100
XCTAssertEqual(rows[0].bool("Flag"), true)
79101
}
80102

81103
func testSelectDateTime() async throws {
82-
let client = try await makeClient()
83-
defer { Task { await client.disconnect() } }
84104
let rows = try await client.query("SELECT GETDATE() AS Now")
85105
XCTAssertNotNil(rows[0].date("Now"))
86106
}
87107

88108
func testMultipleRows() async throws {
89-
let client = try await makeClient()
90-
defer { Task { await client.disconnect() } }
91109
let rows = try await client.query("SELECT 1 AS n UNION ALL SELECT 2 UNION ALL SELECT 3")
92110
XCTAssertEqual(rows.count, 3)
93111
XCTAssertEqual(rows.map { $0.int("n") }, [1, 2, 3])
94112
}
95113

96114
func testMultipleResultSets() async throws {
97-
let client = try await makeClient()
98-
defer { Task { await client.disconnect() } }
99115
let result = try await client.execute("SELECT 1 AS A; SELECT 2 AS B;")
100116
XCTAssertEqual(result.tables.count, 2)
101117
XCTAssertEqual(result.tables[0][0].int("A"), 1)
102118
XCTAssertEqual(result.tables[1][0].int("B"), 2)
103119
}
104120

105121
func testRowsAffected() async throws {
106-
let client = try await makeClient()
107-
defer { Task { await client.disconnect() } }
108-
try await client.run("""
109-
IF OBJECT_ID('tempdb..#T') IS NOT NULL DROP TABLE #T;
110-
CREATE TABLE #T (id INT);
111-
INSERT INTO #T VALUES (1),(2),(3);
112-
""")
122+
try await client.run(
123+
"""
124+
IF OBJECT_ID('tempdb..#T') IS NOT NULL DROP TABLE #T;
125+
CREATE TABLE #T (id INT);
126+
INSERT INTO #T VALUES (1),(2),(3);
127+
""")
113128
let affected = try await client.run("UPDATE #T SET id = id + 10")
114129
XCTAssertEqual(affected, 3)
115130
try await client.run("DROP TABLE #T")
116131
}
117132

118133
func testParameterisedQuery() async throws {
119-
let client = try await makeClient()
120-
defer { Task { await client.disconnect() } }
121134
let rows = try await client.execute("SELECT ? AS Name", parameters: ["O'Brien"])
122135
XCTAssertEqual(rows.rows[0].string("Name"), "O'Brien")
123136
}
124137

125138
func testNullParameter() async throws {
126-
let client = try await makeClient()
127-
defer { Task { await client.disconnect() } }
128139
let rows = try await client.execute("SELECT ? AS Val", parameters: [nil])
129140
XCTAssertTrue(rows.rows[0].isNull("Val"))
130141
}
131142

132143
func testParameterCountMismatch() async throws {
133-
let client = try await makeClient()
134144
defer { Task { await client.disconnect() } }
135145
do {
136146
_ = try await client.execute("SELECT ? AS A", parameters: [1, 2])
137147
XCTFail("Expected parameterCountMismatch")
138-
} catch SQLClientError.parameterCountMismatch { }
148+
} catch SQLClientError.parameterCountMismatch {}
139149
}
140150

141151
func testDecodableStruct() async throws {
142-
let client = try await makeClient()
143-
defer { Task { await client.disconnect() } }
144-
struct Point: Decodable { let x: Int; let y: Int }
152+
struct Point: Decodable {
153+
let x: Int
154+
let y: Int
155+
}
145156
let points: [Point] = try await client.query("SELECT 10 AS x, 20 AS y")
146157
XCTAssertEqual(points[0].x, 10)
147158
XCTAssertEqual(points[0].y, 20)
148159
}
149160

150161
func testDecodableSnakeCase() async throws {
151-
let client = try await makeClient()
152-
defer { Task { await client.disconnect() } }
153-
struct Item: Decodable { let itemId: Int; let itemName: String }
162+
struct Item: Decodable {
163+
let itemId: Int
164+
let itemName: String
165+
}
154166
let items: [Item] = try await client.query("SELECT 7 AS item_id, 'Widget' AS item_name")
155-
XCTAssertEqual(items[0].itemId, 7)
167+
XCTAssertEqual(items[0].itemId, 7)
156168
XCTAssertEqual(items[0].itemName, "Widget")
157169
}
158170

159171
func testBadSQLThrows() async throws {
160-
let client = try await makeClient()
161-
defer { Task { await client.disconnect() } }
162172
do {
163173
_ = try await client.execute("THIS IS NOT VALID SQL")
164174
XCTFail("Expected executionFailed")
165-
} catch SQLClientError.executionFailed { }
175+
} catch SQLClientError.executionFailed {}
166176
}
167177

168178
func testEmptySQLThrows() async throws {
169-
let client = try await makeClient()
170-
defer { Task { await client.disconnect() } }
171179
do {
172180
_ = try await client.execute(" ")
173181
XCTFail("Expected noCommandText")
174-
} catch SQLClientError.noCommandText { }
182+
} catch SQLClientError.noCommandText {}
175183
}
176184

177185
func testQueryBeforeConnectThrows() async throws {
178186
let client = SQLClient()
179187
do {
180188
_ = try await client.query("SELECT 1")
181189
XCTFail("Expected notConnected")
182-
} catch SQLClientError.notConnected { }
190+
} catch SQLClientError.notConnected {}
183191
}
184192
}

0 commit comments

Comments
 (0)