// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2016 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 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)
    }
}
