Skip to content

Commit 136a5c5

Browse files
committed
Add ExpressionTests
1 parent dad179a commit 136a5c5

File tree

4 files changed

+43
-13
lines changed

4 files changed

+43
-13
lines changed

Sources/SQLite/Typed/Expression.swift

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -64,31 +64,31 @@ public struct Expression<Datatype>: ExpressionType {
6464

6565
}
6666

67-
public protocol Expressible {
67+
public protocol Expressible: CustomStringConvertible {
6868

6969
var expression: Expression<Void> { get }
7070

7171
}
7272

7373
extension Expressible {
74+
public var description: String {
75+
asSQL()
76+
}
7477

7578
// naïve compiler for statements that can’t be bound, e.g., CREATE TABLE
7679
func asSQL() -> String {
7780
let expressed = expression
78-
var idx = 0
79-
return expressed.template.reduce("") { template, character in
80-
let transcoded: String
81+
return expressed.template.reduce(("", 0)) { memo, character in
82+
let (template, index) = memo
8183

8284
if character == "?" {
83-
transcoded = transcode(expressed.bindings[idx])
84-
idx += 1
85+
precondition(index < expressed.bindings.count, "not enough bindings for expression")
86+
return (template + transcode(expressed.bindings[index]), index + 1)
8587
} else {
86-
transcoded = String(character)
88+
return (template + String(character), index)
8789
}
88-
return template + transcoded
89-
}
90+
}.0
9091
}
91-
9292
}
9393

9494
extension ExpressionType {

Tests/SQLiteTests/TestHelpers.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ class SQLiteTestCase: XCTestCase {
1212
trace = [String: Int]()
1313

1414
db.trace { SQL in
15-
print(SQL)
15+
// print("SQL: \(SQL)")
1616
self.trace[SQL, default: 0] += 1
1717
}
1818
}
Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,30 @@
11
import XCTest
2-
import SQLite
2+
@testable import SQLite
33

44
class ExpressionTests: XCTestCase {
5+
6+
func test_asSQL_expression_bindings() {
7+
let expression = Expression<String>("foo ? bar", ["baz"])
8+
XCTAssertEqual(expression.asSQL(), "foo 'baz' bar")
9+
}
10+
11+
func test_asSQL_expression_bindings_quoting() {
12+
let expression = Expression<String>("foo ? bar", ["'baz'"])
13+
XCTAssertEqual(expression.asSQL(), "foo '''baz''' bar")
14+
}
15+
16+
func test_expression_custom_string_convertible() {
17+
let expression = Expression<String>("foo ? bar", ["baz"])
18+
XCTAssertEqual(expression.asSQL(), expression.description)
19+
}
20+
21+
func test_init_literal() {
22+
let expression = Expression<String>(literal: "literal")
23+
XCTAssertEqual(expression.template, "literal")
24+
}
25+
26+
func test_init_identifier() {
27+
let expression = Expression<String>("identifier")
28+
XCTAssertEqual(expression.template, "\"identifier\"")
29+
}
530
}

Tests/SQLiteTests/Typed/QueryIntegrationTests.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,12 @@ class QueryIntegrationTests: SQLiteTestCase {
192192
let query3 = users.select(users[*], Expression<Int>(literal: "1 AS weight")).filter(email == "sally@example.com")
193193
let query4 = users.select(users[*], Expression<Int>(literal: "2 AS weight")).filter(email == "alice@example.com")
194194

195-
print(query3.union(query4).order(Expression<Int>(literal: "weight")).asSQL())
195+
let sql = query3.union(query4).order(Expression<Int>(literal: "weight")).asSQL()
196+
XCTAssertEqual(sql,
197+
"""
198+
SELECT "users".*, 1 AS weight FROM "users" WHERE ("email" = 'sally@example.com') UNION \
199+
SELECT "users".*, 2 AS weight FROM "users" WHERE ("email" = 'alice@example.com') ORDER BY weight
200+
""")
196201

197202
let orderedIDs = try db.prepare(query3.union(query4).order(Expression<Int>(literal: "weight"), email)).map { $0[id] }
198203
XCTAssertEqual(Array(expectedIDs.reversed()), orderedIDs)

0 commit comments

Comments
 (0)