New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add block/boolean NSPredicates, NSCompoundPredicate, and NSArray predicate method #127
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
// This source file is part of the Swift.org open source project | ||
// | ||
// Copyright (c) 2014 - 2015 Apple Inc. and the Swift project authors | ||
// Licensed under Apache License v2.0 with Runtime Library Exception | ||
// | ||
// See http://swift.org/LICENSE.txt for license information | ||
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors | ||
// | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You should look at another Swift file in this project and add a correct legal notice. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah yeah, missed that, good call. I'll handle that in the morning. Kevin Lundberg
|
||
|
||
#if DEPLOYMENT_RUNTIME_OBJC || os(Linux) | ||
import Foundation | ||
import XCTest | ||
#else | ||
import SwiftFoundation | ||
import SwiftXCTest | ||
#endif | ||
|
||
class TestNSCompoundPredicate: XCTestCase { | ||
|
||
static var allTests: [(String, TestNSCompoundPredicate -> () throws -> Void)] { | ||
return [ | ||
("test_NotPredicate", test_NotPredicate), | ||
("test_AndPredicateWithNoSubpredicates", test_AndPredicateWithNoSubpredicates), | ||
("test_AndPredicateWithOneSubpredicate", test_AndPredicateWithOneSubpredicate), | ||
("test_AndPredicateWithMultipleSubpredicates", test_AndPredicateWithMultipleSubpredicates), | ||
("test_OrPredicateWithNoSubpredicates", test_OrPredicateWithNoSubpredicates), | ||
("test_OrPredicateWithOneSubpredicate", test_OrPredicateWithOneSubpredicate), | ||
("test_OrPredicateWithMultipleSubpredicates", test_OrPredicateWithMultipleSubpredicates), | ||
("test_OrPredicateShortCircuits", test_OrPredicateShortCircuits), | ||
("test_AndPredicateShortCircuits", test_AndPredicateShortCircuits), | ||
] | ||
} | ||
|
||
private func eval(_ predicate: NSPredicate, object: NSObject = NSObject()) -> Bool { | ||
return predicate.evaluateWithObject(object, substitutionVariables: nil) | ||
} | ||
|
||
func test_NotPredicate() { | ||
let notTruePredicate = NSCompoundPredicate(notPredicateWithSubpredicate: NSPredicate(value: true)) | ||
let notFalsePredicate = NSCompoundPredicate(notPredicateWithSubpredicate: NSPredicate(value: false)) | ||
|
||
XCTAssertFalse(eval(notTruePredicate)) | ||
XCTAssertTrue(eval(notFalsePredicate)) | ||
} | ||
|
||
func test_AndPredicateWithNoSubpredicates() { | ||
let predicate = NSCompoundPredicate(andPredicateWithSubpredicates: []) | ||
|
||
XCTAssertTrue(eval(predicate)) | ||
} | ||
|
||
func test_AndPredicateWithOneSubpredicate() { | ||
let truePredicate = NSCompoundPredicate(andPredicateWithSubpredicates: [NSPredicate(value: true)]) | ||
let falsePredicate = NSCompoundPredicate(andPredicateWithSubpredicates: [NSPredicate(value: false)]) | ||
|
||
XCTAssertTrue(eval(truePredicate)) | ||
XCTAssertFalse(eval(falsePredicate)) | ||
} | ||
|
||
func test_AndPredicateWithMultipleSubpredicates() { | ||
let truePredicate = NSCompoundPredicate(andPredicateWithSubpredicates: [NSPredicate(value: true), NSPredicate(value: true)]) | ||
let falsePredicate = NSCompoundPredicate(andPredicateWithSubpredicates: [NSPredicate(value: true), NSPredicate(value: false)]) | ||
|
||
XCTAssertTrue(eval(truePredicate)) | ||
XCTAssertFalse(eval(falsePredicate)) | ||
} | ||
|
||
|
||
func test_OrPredicateWithNoSubpredicates() { | ||
let predicate = NSCompoundPredicate(orPredicateWithSubpredicates: []) | ||
|
||
XCTAssertFalse(eval(predicate)) | ||
} | ||
|
||
func test_OrPredicateWithOneSubpredicate() { | ||
let truePredicate = NSCompoundPredicate(orPredicateWithSubpredicates: [NSPredicate(value: true)]) | ||
let falsePredicate = NSCompoundPredicate(orPredicateWithSubpredicates: [NSPredicate(value: false)]) | ||
|
||
XCTAssertTrue(eval(truePredicate)) | ||
XCTAssertFalse(eval(falsePredicate)) | ||
} | ||
|
||
func test_OrPredicateWithMultipleSubpredicates() { | ||
let truePredicate = NSCompoundPredicate(orPredicateWithSubpredicates: [NSPredicate(value: true), NSPredicate(value: false)]) | ||
let falsePredicate = NSCompoundPredicate(orPredicateWithSubpredicates: [NSPredicate(value: false), NSPredicate(value: false)]) | ||
|
||
XCTAssertTrue(eval(truePredicate)) | ||
XCTAssertFalse(eval(falsePredicate)) | ||
} | ||
|
||
func test_AndPredicateShortCircuits() { | ||
var shortCircuited = true | ||
|
||
let bOK = NSPredicate(value: false) | ||
let bDontEval = NSPredicate(block: { _ in | ||
shortCircuited = false | ||
return true | ||
}) | ||
|
||
let both = NSCompoundPredicate(andPredicateWithSubpredicates: [bOK, bDontEval]) | ||
XCTAssertFalse(eval(both)) | ||
XCTAssertTrue(shortCircuited) | ||
} | ||
|
||
func test_OrPredicateShortCircuits() { | ||
var shortCircuited = true | ||
|
||
let bOK = NSPredicate(value: true) | ||
let bDontEval = NSPredicate(block: { _ in | ||
shortCircuited = false | ||
return true | ||
}) | ||
|
||
let both = NSCompoundPredicate(orPredicateWithSubpredicates: [bOK, bDontEval]) | ||
XCTAssertTrue(eval(both)) | ||
XCTAssertTrue(shortCircuited) | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using
reduce
doesn't maintain the short-circuiting behavior that the ObjC Foundation version exhibits. As a test, the following will not crash, indicating thatNSCompoundPredicate
is short-circuiting predicate evaluation once it knows that it will returnfalse
:There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't see how that's true. I added test cases for both "and" and "or predicates based on your example code here, and I did not get any test failures or crashes. The && and || operators short circuit properly on their own, and I don't see how reduce() could alter that behavior.