 import Foundation
 import Future
 
-class PromisePerformanceTests: XCTestCase {
-
-    // MARK: - Init
-
-    func testInit() {
+class FutureInitializationTests: XCTestCase {
+
+    func testInitPending() {
         measure {
             for _ in 0..<100_000 {
                 let _ = Future<Int, Void> { _ in

                    Future<Int, Void>(value: 4)]
                )

                future.on(success: { _ in
                    remaining -= 1
                    if remaining == 0 {
                        expecation.fulfill()
                    }
                })
            }
            wait()
        }
    }
}

class FutureOperatorsPerformanceTests: XCTestCase {
    func testMap() {
        let futures = Array(0..<10000).map { _ in
            Future(value: 1)

        }
    }
}

class FutureFlatMapPerformanceTests: XCTestCase {

    func testFlatMapPending() {
        let futures = Array(0..<10000).map { _ in
            Promise<Int, Never>().future
        }

        measure {
            for future in futures {
                let _ = future.flatMap {
                    Future(value: $0)
                }
            }
        }
    }

    func testFlatMapResolvedReturnWithValue() {
        let futures = Array(0..<10000).map { _ in
            Future(value: 1)
        }

        measure {
            for future in futures {
                let _ = future.flatMap {
                    Future(value: $0)
                }
            }
        }
    }

    func testFlatMapResolvedReturnPending() {
        let futures = Array(0..<10000).map { _ in
            Future(value: 1)
        }

        measure {
            for future in futures {
                let _ = future.flatMap { _ in
                    Promise<Int, Never>().future // pending
                }
            }
        }
    }
}

class FutureMiscPerformanceTests: XCTestCase {
    func testObserveOn() {
        let futures = Array(0..<10000).map { _ in
            Future(value: 1)
        }

        let queue = DispatchQueue(label: "testObserveOn")
        measure {
            for future in futures {
                let _ = future.observe(on: queue)
            }
        }
    }
}
