add comparison operators for Where.Expression

This commit is contained in:
John Estropia
2019-02-08 17:16:56 +09:00
parent db4426e6b9
commit 635201868a
2 changed files with 154 additions and 24 deletions

View File

@@ -66,14 +66,17 @@ final class WhereTests: XCTestCase {
XCTAssertEqual(
#keyPath(TestEntity1.testToOne.testEntityID),
(\TestEntity1.testToOne ~ \.testEntityID).description,
String(keyPath: \TestEntity1.testToOne ~ \.testEntityID)
)
XCTAssertEqual(
#keyPath(TestEntity1.testToOne.testToOne.testToManyUnordered),
(\TestEntity1.testToOne ~ \.testToOne ~ \.testToManyUnordered).description,
String(keyPath: \TestEntity1.testToOne ~ \.testToOne ~ \.testToManyUnordered)
)
XCTAssertEqual(
#keyPath(TestEntity2.testToOne.testToOne.testToManyOrdered),
(\TestEntity2.testToOne ~ \.testToOne ~ \.testToManyOrdered).description,
String(keyPath: \TestEntity2.testToOne ~ \.testToOne ~ \.testToManyOrdered)
)
}
@@ -81,14 +84,17 @@ final class WhereTests: XCTestCase {
XCTAssertEqual(
"master.pets",
(\Animal.master ~ \.pets).description,
String(keyPath: \Animal.master ~ \.pets)
)
XCTAssertEqual(
"master.pets.species",
(\Animal.master ~ \.pets ~ \.species).description,
String(keyPath: \Animal.master ~ \.pets ~ \.species)
)
XCTAssertEqual(
"master.pets.master",
(\Animal.master ~ \.pets ~ \.master).description,
String(keyPath: \Animal.master ~ \.pets ~ \.master)
)
}
@@ -96,84 +102,99 @@ final class WhereTests: XCTestCase {
XCTAssertEqual(
#keyPath(TestEntity1.testToOne.testToManyUnordered) + ".@count",
(\TestEntity1.testToOne ~ \.testToManyUnordered).count().description
(\TestEntity1.testToOne ~ \.testToManyUnordered).count().description,
String(keyPath: (\TestEntity1.testToOne ~ \.testToManyUnordered).count())
)
XCTAssertEqual(
#keyPath(TestEntity2.testToOne.testToOne.testToManyOrdered) + ".@count",
(\TestEntity2.testToOne ~ \.testToOne ~ \.testToManyOrdered).count().description
(\TestEntity2.testToOne ~ \.testToOne ~ \.testToManyOrdered).count().description,
String(keyPath: (\TestEntity2.testToOne ~ \.testToOne ~ \.testToManyOrdered).count())
)
}
do {
XCTAssertEqual(
"master.pets.@count",
(\Animal.master ~ \.pets).count().description
(\Animal.master ~ \.pets).count().description,
String(keyPath: (\Animal.master ~ \.pets).count())
)
}
do {
XCTAssertEqual(
"ANY " + #keyPath(TestEntity1.testToOne.testToManyUnordered),
(\TestEntity1.testToOne ~ \.testToManyUnordered).any().description
(\TestEntity1.testToOne ~ \.testToManyUnordered).any().description,
String(keyPath: (\TestEntity1.testToOne ~ \.testToManyUnordered).any())
)
XCTAssertEqual(
"ANY " + #keyPath(TestEntity2.testToOne.testToOne.testToManyOrdered),
(\TestEntity2.testToOne ~ \.testToOne ~ \.testToManyOrdered).any().description
(\TestEntity2.testToOne ~ \.testToOne ~ \.testToManyOrdered).any().description,
String(keyPath: (\TestEntity2.testToOne ~ \.testToOne ~ \.testToManyOrdered).any())
)
}
do {
XCTAssertEqual(
"ANY master.pets",
(\Animal.master ~ \.pets).any().description
(\Animal.master ~ \.pets).any().description,
String(keyPath: (\Animal.master ~ \.pets).any())
)
XCTAssertEqual(
"ANY master.pets.species",
(\Animal.master ~ \.pets ~ \.species).any().description
(\Animal.master ~ \.pets ~ \.species).any().description,
String(keyPath: (\Animal.master ~ \.pets ~ \.species).any())
)
}
do {
XCTAssertEqual(
"ALL " + #keyPath(TestEntity1.testToOne.testToManyUnordered),
(\TestEntity1.testToOne ~ \.testToManyUnordered).all().description
(\TestEntity1.testToOne ~ \.testToManyUnordered).all().description,
String(keyPath: (\TestEntity1.testToOne ~ \.testToManyUnordered).all())
)
XCTAssertEqual(
"ALL " + #keyPath(TestEntity2.testToOne.testToOne.testToManyOrdered),
(\TestEntity2.testToOne ~ \.testToOne ~ \.testToManyOrdered).all().description
(\TestEntity2.testToOne ~ \.testToOne ~ \.testToManyOrdered).all().description,
String(keyPath: (\TestEntity2.testToOne ~ \.testToOne ~ \.testToManyOrdered).all())
)
}
do {
XCTAssertEqual(
"ALL master.pets",
(\Animal.master ~ \.pets).all().description
(\Animal.master ~ \.pets).all().description,
String(keyPath: (\Animal.master ~ \.pets).all())
)
XCTAssertEqual(
"ALL master.pets.species",
(\Animal.master ~ \.pets ~ \.species).all().description
(\Animal.master ~ \.pets ~ \.species).all().description,
String(keyPath: (\Animal.master ~ \.pets ~ \.species).all())
)
}
do {
XCTAssertEqual(
"NONE " + #keyPath(TestEntity1.testToOne.testToManyUnordered),
(\TestEntity1.testToOne ~ \.testToManyUnordered).none().description
(\TestEntity1.testToOne ~ \.testToManyUnordered).none().description,
String(keyPath: (\TestEntity1.testToOne ~ \.testToManyUnordered).none())
)
XCTAssertEqual(
"NONE " + #keyPath(TestEntity2.testToOne.testToOne.testToManyOrdered),
(\TestEntity2.testToOne ~ \.testToOne ~ \.testToManyOrdered).none().description
(\TestEntity2.testToOne ~ \.testToOne ~ \.testToManyOrdered).none().description,
String(keyPath: (\TestEntity2.testToOne ~ \.testToOne ~ \.testToManyOrdered).none())
)
}
do {
XCTAssertEqual(
"NONE master.pets",
(\Animal.master ~ \.pets).none().description
(\Animal.master ~ \.pets).none().description,
String(keyPath: (\Animal.master ~ \.pets).none())
)
XCTAssertEqual(
"NONE master.pets.species",
(\Animal.master ~ \.pets ~ \.species).none().description
(\Animal.master ~ \.pets ~ \.species).none().description,
String(keyPath: (\Animal.master ~ \.pets ~ \.species).none())
)
}
}

View File

@@ -91,7 +91,7 @@ extension Where {
}
// MARK: - ~ Operator (Where.Expression Creation Operators)
// MARK: - ~ (Where.Expression Creation Operators)
// MARK: ~ where D: NSManagedObject
@@ -218,6 +218,29 @@ public func ~= <D, T, V: QueryableAttributeType, S: Sequence>(_ sequence: S, _ e
}
// MARK: - Where.Expression where V: QueryableAttributeType & Comparable
public func < <D, T, V: QueryableAttributeType & Comparable>(_ lhs: Where<D>.Expression<T, V>, _ rhs: V) -> Where<D> {
return Where<D>(expression: lhs, function: "<", operand: rhs)
}
public func <= <D, T, V: QueryableAttributeType & Comparable>(_ lhs: Where<D>.Expression<T, V>, _ rhs: V) -> Where<D> {
return Where<D>(expression: lhs, function: "<=", operand: rhs)
}
public func > <D, T, V: QueryableAttributeType & Comparable>(_ lhs: Where<D>.Expression<T, V>, _ rhs: V) -> Where<D> {
return Where<D>(expression: lhs, function: ">", operand: rhs)
}
public func >= <D, T, V: QueryableAttributeType & Comparable>(_ lhs: Where<D>.Expression<T, V>, _ rhs: V) -> Where<D> {
return Where<D>(expression: lhs, function: ">=", operand: rhs)
}
// MARK: - Where.Expression where V: Optional<QueryableAttributeType>
public func == <D, T, V: QueryableAttributeType>(_ lhs: Where<D>.Expression<T, V?>, _ rhs: V) -> Where<D> {
@@ -246,11 +269,44 @@ public func ~= <D, T, V: QueryableAttributeType, S: Sequence>(_ sequence: S, _ e
}
// MARK: - Where.Expression where V: Optional<QueryableAttributeType & Comparable>
public func < <D, T, V: QueryableAttributeType & Comparable>(_ lhs: Where<D>.Expression<T, V?>, _ rhs: V) -> Where<D> {
return Where<D>(expression: lhs, function: "<", operand: rhs)
}
public func <= <D, T, V: QueryableAttributeType & Comparable>(_ lhs: Where<D>.Expression<T, V?>, _ rhs: V?) -> Where<D> {
return Where<D>(expression: lhs, function: "<=", operand: rhs)
}
public func > <D, T, V: QueryableAttributeType & Comparable>(_ lhs: Where<D>.Expression<T, V?>, _ rhs: V) -> Where<D> {
return Where<D>(expression: lhs, function: ">", operand: rhs)
}
public func >= <D, T, V: QueryableAttributeType & Comparable>(_ lhs: Where<D>.Expression<T, V?>, _ rhs: V?) -> Where<D> {
return Where<D>(expression: lhs, function: ">=", operand: rhs)
}
// MARK: - KeyPath where Root: NSManagedObject, Value: AllowedObjectiveCCollectionKeyPathValue
extension KeyPath where Root: NSManagedObject, Value: AllowedObjectiveCCollectionKeyPathValue {
public func count() -> Where<Root>.Expression<Where<Root>.CollectionTarget, Int> {
return .init(self.cs_keyPathString, "@count")
}
}
// MARK: - Where.Expression where D: NSManagedObject, T == Where<D>.CollectionTarget, V: AllowedObjectiveCCollectionKeyPathValue
extension Where.Expression where D: NSManagedObject, T == Where<D>.CollectionTarget, V: AllowedObjectiveCCollectionKeyPathValue {
public func count() -> Where<D>.Expression<Where<D>.CollectionTarget, Int> {
public func count() -> Where<D>.Expression<T, Int> {
return .init(self.cs_keyPathString, "@count")
}
@@ -261,44 +317,97 @@ extension Where.Expression where D: NSManagedObject, T == Where<D>.CollectionTar
extension Where.Expression where D: NSManagedObject, T == Where<D>.CollectionTarget, V: AllowedObjectiveCKeyPathValue {
public func any() -> Where<D>.Expression<Where<D>.CollectionTarget, V> {
public func any() -> Where<D>.Expression<T, V> {
return .init("ANY " + self.cs_keyPathString)
}
public func all() -> Where<D>.Expression<Where<D>.CollectionTarget, V> {
public func all() -> Where<D>.Expression<T, V> {
return .init("ALL " + self.cs_keyPathString)
}
public func none() -> Where<D>.Expression<Where<D>.CollectionTarget, V> {
public func none() -> Where<D>.Expression<T, V> {
return .init("NONE " + self.cs_keyPathString)
}
}
// MARK: - KeyPath where Root: CoreStoreObject, Value: AllowedObjectiveCCollectionKeyPathValue
extension KeyPath where Root: CoreStoreObject, Value: AllowedCoreStoreObjectCollectionKeyPathValue {
public func count() -> Where<Root>.Expression<Where<Root>.CollectionTarget, Int> {
return .init(Root.meta[keyPath: self].cs_keyPathString, "@count")
}
}
// MARK: - Where.Expression where D: CoreStoreObject, T == Where<D>.CollectionTarget
extension Where.Expression where D: CoreStoreObject, T == Where<D>.CollectionTarget {
public func count() -> Where<D>.Expression<Where<D>.CollectionTarget, Int> {
public func count() -> Where<D>.Expression<T, Int> {
return .init(self.cs_keyPathString, "@count")
}
public func any() -> Where<D>.Expression<Where<D>.CollectionTarget, V> {
public func any() -> Where<D>.Expression<T, V> {
return .init("ANY " + self.cs_keyPathString)
}
public func all() -> Where<D>.Expression<Where<D>.CollectionTarget, V> {
public func all() -> Where<D>.Expression<T, V> {
return .init("ALL " + self.cs_keyPathString)
}
public func none() -> Where<D>.Expression<Where<D>.CollectionTarget, V> {
public func none() -> Where<D>.Expression<T, V> {
return .init("NONE " + self.cs_keyPathString)
}
}
// MARK: - Where
extension Where {
// MARK: FilePrivate
fileprivate init<T, V: QueryableAttributeType & Comparable>(expression: Where<D>.Expression<T, V>, function: String, operand: V) {
self.init("\(expression.cs_keyPathString) \(function) %@", operand.cs_toQueryableNativeType())
}
fileprivate init<T, V: QueryableAttributeType & Comparable>(expression: Where<D>.Expression<T, V?>, function: String, operand: V) {
self.init("\(expression.cs_keyPathString) \(function) %@", operand.cs_toQueryableNativeType())
}
fileprivate init<T, V: QueryableAttributeType & Comparable>(expression: Where<D>.Expression<T, V>, function: String, operand: V?) {
if let operand = operand {
self.init("\(expression.cs_keyPathString) \(function) %@", operand.cs_toQueryableNativeType())
}
else {
self.init("\(expression.cs_keyPathString) \(function) nil")
}
}
fileprivate init<T, V: QueryableAttributeType & Comparable>(expression: Where<D>.Expression<T, V?>, function: String, operand: V?) {
if let operand = operand {
self.init("\(expression.cs_keyPathString) \(function) %@", operand.cs_toQueryableNativeType())
}
else {
self.init("\(expression.cs_keyPathString) \(function) nil")
}
}
}