-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
/
Copy pathTestHelpers.swift
134 lines (109 loc) · 4.3 KB
/
TestHelpers.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
import XCTest
@testable import SQLite
class SQLiteTestCase: XCTestCase {
private var trace: [String: Int]!
var db: Connection!
let users = Table("users")
override func setUpWithError() throws {
try super.setUpWithError()
db = try Connection()
trace = [String: Int]()
db.trace { SQL in
print(SQL)
self.trace[SQL, default: 0] += 1
}
}
func createUsersTable() throws {
try db.execute("""
CREATE TABLE users (
id INTEGER PRIMARY KEY,
email TEXT NOT NULL UNIQUE,
age INTEGER,
salary REAL,
admin BOOLEAN NOT NULL DEFAULT 0 CHECK (admin IN (0, 1)),
manager_id INTEGER,
created_at DATETIME,
FOREIGN KEY(manager_id) REFERENCES users(id)
)
"""
)
}
func insertUsers(_ names: String...) throws {
try insertUsers(names)
}
func insertUsers(_ names: [String]) throws {
for name in names { try insertUser(name) }
}
@discardableResult func insertUser(_ name: String, age: Int? = nil, admin: Bool = false) throws -> Statement {
try db.run("INSERT INTO \"users\" (email, age, admin) values (?, ?, ?)",
"\(name)@example.com", age?.datatypeValue, admin.datatypeValue)
}
func assertSQL(_ SQL: String, _ executions: Int = 1, _ message: String? = nil, file: StaticString = #file, line: UInt = #line) {
XCTAssertEqual(
executions, trace[SQL] ?? 0,
message ?? SQL,
file: file, line: line
)
}
func assertSQL(_ SQL: String, _ statement: Statement, _ message: String? = nil, file: StaticString = #file, line: UInt = #line) {
try! statement.run()
assertSQL(SQL, 1, message, file: file, line: line)
if let count = trace[SQL] { trace[SQL] = count - 1 }
}
// func AssertSQL(SQL: String, _ query: Query, _ message: String? = nil, file: String = __FILE__, line: UInt = __LINE__) {
// for _ in query {}
// AssertSQL(SQL, 1, message, file: file, line: line)
// if let count = trace[SQL] { trace[SQL] = count - 1 }
// }
func async(expect description: String = "async", timeout: Double = 5, block: (@escaping () -> Void) -> Void) {
let expectation = self.expectation(description: description)
block({ expectation.fulfill() })
waitForExpectations(timeout: timeout, handler: nil)
}
}
let bool = Expression<Bool>("bool")
let boolOptional = Expression<Bool?>("boolOptional")
let data = Expression<Blob>("blob")
let dataOptional = Expression<Blob?>("blobOptional")
let date = Expression<Date>("date")
let dateOptional = Expression<Date?>("dateOptional")
let double = Expression<Double>("double")
let doubleOptional = Expression<Double?>("doubleOptional")
let int = Expression<Int>("int")
let intOptional = Expression<Int?>("intOptional")
let int64 = Expression<Int64>("int64")
let int64Optional = Expression<Int64?>("int64Optional")
let uint32 = Expression<UInt32>("uint32")
let uint32Optional = Expression<UInt32?>("uint32Optional")
let uint64 = Expression<UInt64>("uint64")
let uint64Optional = Expression<UInt64?>("uint64Optional")
let string = Expression<String>("string")
let stringOptional = Expression<String?>("stringOptional")
func assertSQL(_ expression1: @autoclosure () -> String, _ expression2: @autoclosure () -> Expressible,
file: StaticString = #file, line: UInt = #line) {
XCTAssertEqual(expression1(), expression2().asSQL(), file: file, line: line)
}
let table = Table("table")
let qualifiedTable = Table("table", database: "main")
let virtualTable = VirtualTable("virtual_table")
let _view = View("view") // avoid Mac XCTestCase collision
class TestCodable: Codable {
let int: Int
let string: String
let bool: Bool
let float: Float
let double: Double
let date: Date
let optional: String?
let sub: TestCodable?
init(int: Int, string: String, bool: Bool, float: Float, double: Double, date: Date, optional: String?, sub: TestCodable?) {
self.int = int
self.string = string
self.bool = bool
self.float = float
self.double = double
self.date = date
self.optional = optional
self.sub = sub
}
}