Skip to content

Start implementing NSPredicate #131

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

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Foundation.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

/* Begin PBXBuildFile section */
22B9C1E11C165D7A00DECFF9 /* TestNSDate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22B9C1E01C165D7A00DECFF9 /* TestNSDate.swift */; };
265706D21C1B404300D31C07 /* TestNSPredicate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 265706D11C1B404300D31C07 /* TestNSPredicate.swift */; };
4AE109271C17CCBF007367B5 /* TestNSIndexPath.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4AE109261C17CCBF007367B5 /* TestNSIndexPath.swift */; };
4DC1D0801C12EEEF00B5948A /* TestNSPipe.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4DC1D07F1C12EEEF00B5948A /* TestNSPipe.swift */; };
525AECED1BF2C9C500D15BB0 /* TestNSFileManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 525AECEB1BF2C96400D15BB0 /* TestNSFileManager.swift */; };
Expand Down Expand Up @@ -332,6 +333,7 @@

/* Begin PBXFileReference section */
22B9C1E01C165D7A00DECFF9 /* TestNSDate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestNSDate.swift; sourceTree = "<group>"; };
265706D11C1B404300D31C07 /* TestNSPredicate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestNSPredicate.swift; sourceTree = "<group>"; };
4AE109261C17CCBF007367B5 /* TestNSIndexPath.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestNSIndexPath.swift; sourceTree = "<group>"; };
4DC1D07F1C12EEEF00B5948A /* TestNSPipe.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestNSPipe.swift; sourceTree = "<group>"; };
522C253A1BF16E1600804FC6 /* FoundationErrors.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FoundationErrors.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1068,6 +1070,7 @@
83712C8D1C1684900049AD49 /* TestNSURLRequest.swift */,
7A7D6FBA1C16439400957E2E /* TestNSURLResponse.swift */,
A5A34B551C18C85D00FD972B /* TestNSByteCountFormatter.swift */,
265706D11C1B404300D31C07 /* TestNSPredicate.swift */,
);
name = Tests;
sourceTree = "<group>";
Expand Down Expand Up @@ -1761,6 +1764,7 @@
files = (
525AECED1BF2C9C500D15BB0 /* TestNSFileManager.swift in Sources */,
5B915F0F1C1A320E00BE40C5 /* TestNSJSONSerialization.swift in Sources */,
265706D21C1B404300D31C07 /* TestNSPredicate.swift in Sources */,
EA66F6501BF1619600136161 /* TestNSNumber.swift in Sources */,
844DC3331C17584F005611F9 /* TestNSScanner.swift in Sources */,
E876A73E1C1180E000F279EC /* TestNSRange.swift in Sources */,
Expand Down
95 changes: 79 additions & 16 deletions Foundation/NSPredicate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,51 +27,114 @@ public class NSPredicate : NSObject, NSSecureCoding, NSCopying {
public func copyWithZone(zone: NSZone) -> AnyObject {
NSUnimplemented()
}


internal let _evaluator : PredicateEvaluator
internal let _bindings : [String:AnyObject]?

internal init(evaluator : PredicateEvaluator, bindings : [String:AnyObject]? = nil ) {
_evaluator = evaluator
_bindings = bindings
}

// Parse predicateFormat and return an appropriate predicate
public init(format predicateFormat: String, argumentArray arguments: [AnyObject]?) { NSUnimplemented() }

public init?(fromMetadataQueryString queryString: String) { NSUnimplemented() }

// return predicates that always evaluate to true/false
public convenience init(value: Bool) {
self.init(evaluator: ConstantEvaluator(value: value))
}

public init(value: Bool) { NSUnimplemented() } // return predicates that always evaluate to true/false

public init(block: (AnyObject, [String : AnyObject]?) -> Bool) { NSUnimplemented() }
public convenience init(block: (AnyObject, [String : AnyObject]?) -> Bool) {
self.init(evaluator: BlockEvaluator(block: block))
}

public var predicateFormat: String { NSUnimplemented() } // returns the format string of the predicate

public func predicateWithSubstitutionVariables(variables: [String : AnyObject]) -> Self { NSUnimplemented() } // substitute constant values for variables

public func evaluateWithObject(object: AnyObject?) -> Bool { NSUnimplemented() } // evaluate a predicate against a single object

public func evaluateWithObject(object: AnyObject?, substitutionVariables bindings: [String : AnyObject]?) -> Bool { NSUnimplemented() } // single pass evaluation substituting variables from the bindings dictionary for any variable expressions encountered

// evaluate a predicate against a single object
public func evaluateWithObject(object: AnyObject?) -> Bool {
return _evaluator.evaluate(object, bindings: _bindings)
}

// single pass evaluation substituting variables from the bindings dictionary for any variable expressions encountered
public func evaluateWithObject(object: AnyObject?, substitutionVariables bindings: [String : AnyObject]?) -> Bool {
return _evaluator.evaluate(object, bindings: bindings)
}

public func allowEvaluation() { NSUnimplemented() } // Force a predicate which was securely decoded to allow evaluation
}

internal protocol PredicateEvaluator {
func evaluate(object : AnyObject?, bindings : [String:AnyObject]?) -> Bool
}

private struct BlockEvaluator : PredicateEvaluator {
let block : (AnyObject, [String:AnyObject]?) -> Bool

func evaluate(object: AnyObject?, bindings: [String : AnyObject]?) -> Bool {
return block(object!, bindings)
}
}

private struct ConstantEvaluator : PredicateEvaluator {
let value : Bool

func evaluate(object: AnyObject?, bindings: [String : AnyObject]?) -> Bool {
return value
}
}

extension NSArray {
public func filteredArrayUsingPredicate(predicate: NSPredicate) -> [AnyObject] { NSUnimplemented() } // evaluate a predicate against an array of objects and return a filtered array
// evaluate a predicate against an array of objects and return a filtered array
public func filteredArrayUsingPredicate(predicate: NSPredicate) -> [AnyObject] {
return filter(predicate.evaluateWithObject)
}
}

extension NSMutableArray {
public func filterUsingPredicate(predicate: NSPredicate) { NSUnimplemented() } // evaluate a predicate against an array of objects and filter the mutable array directly
// evaluate a predicate against an array of objects and filter the mutable array directly
public func filterUsingPredicate(predicate: NSPredicate) {
let indexes = indexesOfObjectsPassingTest {
object, index, stop in
return !predicate.evaluateWithObject(object)
}
removeObjectsAtIndexes(indexes)
}
}

extension NSSet {
public func filteredSetUsingPredicate(predicate: NSPredicate) -> Set<NSObject> { NSUnimplemented() } // evaluate a predicate against a set of objects and return a filtered set
// evaluate a predicate against a set of objects and return a filtered set
public func filteredSetUsingPredicate(predicate: NSPredicate) -> Set<NSObject> {
return Set(_storage.filter(predicate.evaluateWithObject))
}
}

extension NSMutableSet {
public func filterUsingPredicate(predicate: NSPredicate) { NSUnimplemented() } // evaluate a predicate against a set of objects and filter the mutable set directly
// evaluate a predicate against a set of objects and filter the mutable set directly
public func filterUsingPredicate(predicate: NSPredicate) {
setSet(filteredSetUsingPredicate(predicate))
}
}

extension NSOrderedSet {

public func filteredOrderedSetUsingPredicate(p: NSPredicate) -> NSOrderedSet { NSUnimplemented() } // evaluate a predicate against an ordered set of objects and return a filtered ordered set
// evaluate a predicate against an ordered set of objects and return a filtered ordered set
public func filteredOrderedSetUsingPredicate(p: NSPredicate) -> NSOrderedSet {
return NSOrderedSet(array: array.filter(p.evaluateWithObject))
}
}

extension NSMutableOrderedSet {

public func filterUsingPredicate(p: NSPredicate) { NSUnimplemented() } // evaluate a predicate against an ordered set of objects and filter the mutable ordered set directly
// evaluate a predicate against an ordered set of objects and filter the mutable ordered set directly
public func filterUsingPredicate(p: NSPredicate) {
let indexes = indexesOfObjectsPassingTest( {
object, index, stop in
return !p.evaluateWithObject(object)
})
removeObjectsAtIndexes(indexes)
}
}


50 changes: 50 additions & 0 deletions TestFoundation/TestNSPredicate.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// 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
//



#if DEPLOYMENT_RUNTIME_OBJC || os(Linux)
import Foundation
import XCTest
#else
import SwiftFoundation
import SwiftXCTest
#endif



class TestNSPredicate : XCTestCase {

var allTests : [(String, () -> ())] {
return [
("test_constantPredicate", test_constantPredicate),
("test_blockPredicate", test_blockPredicate),
]
}

func test_constantPredicate() {
XCTAssert(NSPredicate(value: true).evaluateWithObject( self ) == true)
XCTAssert(NSPredicate(value: false).evaluateWithObject( self ) == false)
}

func test_blockPredicate() {
var called = false
let block : (AnyObject, [String:AnyObject]?) -> Bool = {[unowned self] object, bindings in
XCTAssert(object === self)
XCTAssertNil(bindings)

called = true
return true
}

XCTAssert(NSPredicate(block: block).evaluateWithObject( self ) == true)
XCTAssert(called)
}

}
1 change: 1 addition & 0 deletions TestFoundation/main.swift
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,5 @@ XCTMain([
TestNSByteCountFormatter(),
TestNSURLResponse(),
TestNSNotificationCenter(),
TestNSPredicate(),
])