             let people = $.join(names, separator: " from ")
             return "Hello \(people)"
             }, "Ankur", "Swift")
-        XCTAssert($.times(3, function: fun) as String[] == ["Hello Ankur from Swift", "Hello Ankur from Swift", "Hello Ankur from Swift"], "Call a function 3 times")
+        XCTAssertEqualObjects($.times(3, function: fun) as String[], ["Hello Ankur from Swift", "Hello Ankur from Swift", "Hello Ankur from Swift"], "Call a function 3 times")
     }
 
     func testAfter() {

        for elem in saves {
            asyncSave(completeCallback)
        }
        XCTAssert(isDone, "Should be done")
    }

    func testSlice() {
        var res = $.slice([1,2,3,4,5], start: 0, end: 2)
        XCTAssert(res == [1, 2], "Slice subarray 0..2")
        
        res = $.slice([1,2,3,4,5], start: 0)
        XCTAssert(res == [1, 2, 3, 4, 5], "Slice at 0 is whole array")
        
        res = $.slice([1,2,3,4,5], start: 3)
        XCTAssert(res == [4, 5], "Slice with start goes till end")
        
        res = $.slice([1,2,3,4,5], start: 8)
        XCTAssert(res == [], "Slice out of bounds is empty")
        
        res = $.slice([1,2,3,4,5], start: 8, end: 10)
        XCTAssert(res == [], "Slice out of bounds is empty")
        
        res = $.slice([1,2,3,4,5], start: 8 , end: 2)
        XCTAssert(res == [], "Slice with end < start is empty")
        
        res = $.slice([1,2,3,4,5], start: 3, end: 3)
        XCTAssert(res == [], "Slice at x and x is empty")
        
        res = $.slice([1,2,3,4,5], start: 2, end: 5)
        XCTAssert(res == [3,4,5], "Slice at x and x is subarray")
        
    }
    
    /// Helper function for testing partition, Swift cannot compare nested arrays.
    func compareNestedArray(first: Array<Array<Int>>, with second: Array<Array<Int>>) -> Bool {
        if first.count != second.count { return false }
        for i in 0..first.count {
            if first[i] != second[i] { return false }
        }
        return true
    }

    func testPartition() {
        var array = [1, 2, 3, 4, 5]

        XCTAssert(compareNestedArray($.partition(array, n: 2), with: [[1, 2], [3, 4]]), "Partition uses n for step if not supplied.")
        XCTAssert(compareNestedArray($.partition(array, n: 2, step: 1), with: [[1, 2], [2, 3], [3, 4], [4, 5]]), "Partition allows specifying a custom step.")
        XCTAssert(compareNestedArray($.partition(array, n: 2, step: 1, pad: nil), with: [[1, 2], [2, 3], [3, 4], [4, 5], [5]]), "Partition with nil pad allows the last partition to be less than n length")
        XCTAssert(compareNestedArray($.partition(array, n: 4, step: 1, pad: nil), with: [[1, 2, 3, 4], [2, 3, 4, 5], [3, 4, 5]]), "Partition with nil pad stops at the first partition less than n length.")
        XCTAssert(compareNestedArray($.partition(array, n: 2, step: 1, pad: [6,7,8]), with: [[1, 2], [2, 3], [3, 4], [4, 5], [5, 6]]), "Partition pads the last partition to the right length.")
        XCTAssert(compareNestedArray($.partition(array, n: 4, step: 3, pad: [6]), with: [[1, 2, 3, 4], [4, 5, 6]]), "Partition doesn't add more elements than pad has.")
        XCTAssert(compareNestedArray($.partition([1, 2, 3, 4, 5], n: 2, pad: [6]), with: [[1, 2], [3, 4], [5, 6]]), "Partition with pad and no step uses n as step.")
        XCTAssert(compareNestedArray($.partition([1, 2, 3, 4, 5, 6], n: 2, step: 4), with: [[1, 2], [5, 6]]), "Partition step length works.")
        XCTAssert(compareNestedArray($.partition(array, n: 10), with: [[]]), "Partition without pad returns [[]] if n is longer than array.")
    }
    
    func testPartitionAll() {
        var array = [1, 2, 3, 4, 5]

        XCTAssert(compareNestedArray($.partitionAll(array, n: 2, step: 1), with: [[1, 2], [2, 3], [3, 4], [4, 5], [5]]), "PartitionAll includes partitions less than n.")
        XCTAssert(compareNestedArray($.partitionAll(array, n: 2), with: [[1, 2], [3, 4], [5]]), "PartitionAll uses n as the step when not supplied.")
        XCTAssert(compareNestedArray($.partitionAll(array, n:4, step: 1), with: [[1, 2, 3, 4], [2, 3, 4, 5], [3, 4, 5], [4, 5], [5]]), "PartitionAll does not stop at the first partition less than n length.")
    }
    
    func testPartitionBy() {
        XCTAssert(compareNestedArray($.partitionBy([1, 2, 3, 4, 5]) { $0 > 10 }, with: [[1, 2, 3, 4, 5]]), "PartitionBy doesn't try to split unnecessarily.")
        XCTAssert(compareNestedArray($.partitionBy([1, 2, 4, 3, 5, 6]) { $0 % 2 == 0 }, with: [[1], [2, 4], [3, 5], [6]]), "PartitionBy splits appropriately on Bool.")
        XCTAssert(compareNestedArray($.partitionBy([1, 7, 3, 6, 10, 12]) { $0 % 3 }, with: [[1, 7], [3, 6], [10], [12]]), "PartitionBy can split on functions other than Bool.")
    }
    
    func testMap() {
        let result = $.map([1, 2, 3, 4, 5]) { $0 * 2 }
        XCTAssert(result == [2, 4, 6, 8, 10], "Map function should double values in the array")
    }

    func testReduce() {
        XCTAssert($.reduce([1, 2, 3, 4, 5], initial: 0) { $0 + $1 } == 15, "Reduce function should sum elements in the array")
    }

    
}

    }

    func testSample() {
        let arr = [2, 1, 2, 3, 4]
        XCTAssertTrue($.contains(arr, value: $.sample(arr)), "Returns sample which is an element from the array")
    }

    func testPluck() {
        let arr = [["age": 20], ["age": 30], ["age": 40]]
        XCTAssertEqualObjects($.pluck(arr, value: "age"), [20, 30, 40], "Returns values from the object where they key is the value")
    }

    func testFrequencies() {
        XCTAssertEqualObjects($.frequencies(["a", "a", "b", "c", "a", "b"]), ["a": 3, "b": 2, "c": 1], "Returns correct frequency dictionary")
        XCTAssertEqualObjects($.frequencies([1,2,3,4,5]) { $0 % 2 == 0 }, [false: 3, true: 2], "Returns correct frequency dictionary from cond")
    }

    func testKeys() {
        let dict = ["Dog": 1, "Cat": 2]
        XCTAssertEqualObjects($.keys(dict), ["Dog", "Cat"], "Returns correct array with keys")
    }

    func testValues() {
        let dict = ["Dog": 1, "Cat": 2]
        XCTAssertEqualObjects($.values(dict), [1, 2], "Returns correct array with values")
    }
    
    func testMerge() {
        let dict  = ["Dog": 1, "Cat": 2]
        let dict2 = ["Cow": 3]
        let dict3 = ["Sheep": 4]
        XCTAssertEqualObjects($.merge(dictionaries: dict, dict2, dict3), ["Dog": 1, "Cat": 2, "Cow": 3, "Sheep": 4], "Returns correct merged dictionary")

        let arr  = [1, 5]
        let arr2 = [2, 4]
        let arr3 = [5, 6]
        XCTAssertEqualObjects($.merge(arrays: arr, arr2, arr3), [1, 5, 2, 4, 5, 6], "Returns correct merged array")
    }

    func testPick() {
        let dict = ["Dog": 1, "Cat": 2, "Cow": 3]
        XCTAssertEqualObjects($.pick(dict, keys: "Dog", "Cow"), ["Dog": 1, "Cow": 3], "Returns correct picked dictionary")
    }

    func testOmit() {
        let dict = ["Dog": 1, "Cat": 2, "Cow": 3]
        XCTAssertEqualObjects($.omit(dict, keys: "Dog"), ["Cat": 2, "Cow": 3], "Returns correct omited dictionary")
    }

    func testTap() {
        var beatle = CarExample(name: "Fusca")
        $.tap(beatle, {$0.name = "Beatle"}).color = "Blue"

        XCTAssertEqualObjects(beatle.name, "Beatle", "Set the car name")
        XCTAssertEqualObjects(beatle.color, "Blue", "Set the car color")
    }

    func testChaining() {
        var chain = $(array: [1, 2, 3])
        XCTAssertEqual(chain.first() as Int, 1, "Returns first element which ends the chain")

        chain = $(array: [[1, 2], 3, [[4], 5]])
        XCTAssertEqualObjects(chain.flatten().initial(2).value() as Int[], [1, 2, 3], "Returns flatten array from chaining")

        chain = $(array: [[1, 2], 3, [[4], 5]])
        XCTAssertEqual(chain.initial().flatten().first() as Int, 1, "Returns flatten array from chaining")

        chain = $(array: [[1, 2], 3, [[4], 5]])
        XCTAssertEqualObjects(chain.flatten().map({ (elem) in elem as Int * 10 }).value() as Int[], [10, 20, 30, 40, 50], "Returns mapped values")

        XCTAssertEqual(chain.first() as Int, 10, "Returns first element from mapped value")

        var elements: Int[] = []
        chain.each { elements += $0 as Int }
        XCTAssertEqualObjects(elements as Int[], [10, 20, 30, 40, 50], "Goes through each element in the array")

        XCTAssertTrue(chain.all { ( $0 as Int) < 100 }, "All elements are less than 100")
        XCTAssertFalse(chain.all { ($0 as Int) < 40 }, "All elements are not less than 40")
        XCTAssertTrue(chain.any { ($0 as Int) < 40 }, "At least one element is less than 40")

        elements = []
        chain.slice(0, end: 3).each({ elements += $0 as Int})
        XCTAssertEqualObjects(elements as Int[], [10, 20, 30], "Chained seld")

    }

    func testPartial() {
        let partialFunc = $.partial({(T...) in T[0] + " " + T[1] + " from " + T[2] }, "Hello")
        XCTAssertEqual(partialFunc("World", "Swift"), "Hello World from Swift", "Returns curry function that is evaluated")
    }

    func testBind() {
        let helloWorldFunc = $.bind({(T...) in T[0] + " " + T[1] + " from " + T[2] }, "Hello", "World", "Swift")
        XCTAssertEqual(helloWorldFunc(), "Hello World from Swift", "Returns curry function that is evaluated")
    }

    func testTimes() {
