Skip to content

Commit

Permalink
added test cases for count and or/and groups and fixed the previous i…
Browse files Browse the repository at this point in the history
…mplementation. Avoid inserting an empty filter before all queries.
  • Loading branch information
fedefrappi committed Jan 3, 2017
1 parent a614353 commit 31afa0b
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 19 deletions.
21 changes: 12 additions & 9 deletions Sources/Filter+MongoKitten.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import MongoKitten
import Fluent

extension Fluent.Filter {
public func makeMKQuery() -> MongoKitten.Query {
public func makeMKQuery() throws -> MongoKitten.Query {
let query: MongoKitten.Query

switch self.method {
Expand Down Expand Up @@ -51,14 +51,17 @@ extension Fluent.Filter {
query = MKQuery(aqt: .and(ands))
}
case .group(let relation, let filters):
query = filters.map {
$0.makeMKQuery()
}.reduce(Query([:]), { lhs, rhs in
switch relation {
case .and: return lhs && rhs
case .or: return lhs || rhs
}
})
if filters.count >= 2 {
let queries = try filters.map {
try $0.makeMKQuery()
}
switch relation {
case .and: return queries.dropFirst().reduce(queries[0], &&)
case .or: return queries.dropFirst().reduce(queries[0], ||)
}
} else {
fatalError("Filter group must have at least 2 filters")
}
}

return query
Expand Down
2 changes: 1 addition & 1 deletion Sources/MongoDriver.swift
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public class MongoDriver: Fluent.Driver {
return Node.null
}
case .count:
return try count(query).node
return try count(query).makeNode()
}
}

Expand Down
18 changes: 10 additions & 8 deletions Sources/Query+MongoKitten.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@ extension Fluent.Query {
if unions.count != 0 {
fatalError("[Mongo] Unions not yet supported. Use nesting instead.")
}

let query = filters.map {
$0.makeMKQuery()
}.reduce(Query([:]), { lhs, rhs in
return lhs && rhs
})

return query

switch filters.count {
case 0: return Query([:])
case 1: return try filters[0].makeMKQuery()
default:
let queries = try filters.map {
try $0.makeMKQuery()
}
return queries.dropFirst().reduce(queries[0], &&)
}
}
}
61 changes: 60 additions & 1 deletion Tests/FluentMongoTests/DriverTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@ class DriverTests: XCTestCase {
("testDeleteLimit0Implicit", testDeleteLimit0Implicit),
("testDeleteLimit0Explicit", testDeleteLimit0Explicit),
("testDeleteLimit1", testDeleteLimit1),
("testDeleteLimitInvalid", testDeleteLimitInvalid)
("testDeleteLimitInvalid", testDeleteLimitInvalid),
("testCount", testCount),
("testGroupOr", testGroupOr),
("testGroupAnd", testGroupAnd),
]
}

Expand Down Expand Up @@ -221,4 +224,60 @@ class DriverTests: XCTestCase {
// this should fail
}
}

func testCount() throws {
// Insert dummy users Vapor0, Vapor1, Vapor0, ..., Vapor1
for i in (0..<10) {
_ = createUser(suffix: "\(i%2)")
}
let count = try User.query().count()
XCTAssertEqual(10, count)
}

func testGroupOr() throws {
// Insert dummy users Vapor0, Vapor1, ...
for i in (0..<10) {
_ = createUser(suffix: "\(i)")
}

let query = try User.query().or({ query in
try query.filter("name", "Vapor3")
try query.filter("name", "Vapor4")
try query.filter("name", "Vapor5")
try query.filter("name", "Vapor6")
try query.filter("name", "Vapor7")
})
query.limit = Limit(count: 3, offset: 1)
let result = try query.all()
XCTAssertEqual(["Vapor4", "Vapor5", "Vapor6"], result.map { $0.name })
}

func testGroupAnd() throws {
// Insert dummy users Vapor0, Vapor1, ...
for i in (0..<10) {
var user = createUser(suffix: "\(i)")
if i%2 == 0 {
user.email = "[email protected]"
try user.save()
}
}

let query = try User.query()
.or{ query in
try query.filter("name", "Vapor1")
try query.and{ query in
try query.filter("name", "Vapor2")
try query.filter("email", "[email protected]")
}
try query.and{ query in
try query.filter("name", "Vapor3")
try query.filter("email", "[email protected]")
}
try query.filter("name", "Vapor4")
try query.filter("name", "Vapor5")
}
query.limit = Limit(count: 2, offset: 1)
let result = try query.all()
XCTAssertEqual(["Vapor2", "Vapor4"], result.map { $0.name })
}
}

0 comments on commit 31afa0b

Please sign in to comment.