// This file is autogenerated. Take a look at `Preprocessor` target in RxSwift project 
//
//  Observable+CombineLatestTests+arity.swift
//  Tests
//
//  Created by Krunoslav Zaher on 4/25/15.
//  Copyright © 2015 Krunoslav Zaher. All rights reserved.
//

import XCTest
import RxSwift
import RxTest

// combine latest
extension ObservableCombineLatestTest {


    // 2

    func testCombineLatest_Never2() {
        let factories: [(TestableObservable<Int>, TestableObservable<Int>) -> Observable<Int>] =
            [
                { e0, e1 in
                    Observable.combineLatest(e0, e1) { (_, _) -> Int in
                        return (42)
                    }
                },
                { e0, e1 in
                    Observable.combineLatest(e0, e1).map { (_, _) -> Int in
                        return (42)
                    }
                },
            ]
        for factory in factories {
            let scheduler = TestScheduler(initialClock: 0)


            let e0 = scheduler.createHotObservable([
                .next(150, 1)
            ])

            let e1 = scheduler.createHotObservable([
                .next(150, 1)
            ])


            let res = scheduler.start { () -> Observable<Int> in
                factory(e0, e1)
            }
            
            XCTAssertEqual(res.events, [])
            
            let subscriptions = [Subscription(200, 1000)]
            

            XCTAssertEqual(e0.subscriptions, subscriptions)
            XCTAssertEqual(e1.subscriptions, subscriptions)
        }
    }

    func testCombineLatest_Empty2() {
        let factories: [(TestableObservable<Int>, TestableObservable<Int>) -> Observable<Int>] =
            [
                { e0, e1 in
                    Observable.combineLatest(e0, e1) { (_, _) -> Int in
                        return (42)
                    }
                },
                { e0, e1 in
                    Observable.combineLatest(e0, e1).map { (_, _) -> Int in
                        return (42)
                    }
                },
            ]

        for factory in factories {
            let scheduler = TestScheduler(initialClock: 0)


            let e0 = scheduler.createHotObservable([
                .next(150, 1),
                .completed(210)
            ])

            let e1 = scheduler.createHotObservable([
                .next(150, 1),
                .completed(220)
            ])


            let res = scheduler.start { () -> Observable<Int> in
                factory(e0, e1)
            }

            XCTAssertEqual(res.events, [.completed(220)])


            XCTAssertEqual(e0.subscriptions, [Subscription(200, 210)])

            XCTAssertEqual(e1.subscriptions, [Subscription(200, 220)])

        }
    }

    func testCombineLatest_SelectorThrows2() {
        let scheduler = TestScheduler(initialClock: 0)


        let e0 = scheduler.createHotObservable([
            .next(150, 1),
            .next(210, 1),
            .completed(400)
        ])

        let e1 = scheduler.createHotObservable([
            .next(150, 1),
            .next(220, 2),
            .completed(400)
        ])


        let res = scheduler.start { () -> Observable<Int> in
            Observable.combineLatest(e0, e1) { (_, _) throws -> Int in
                throw testError
            }
        }

        XCTAssertEqual(res.events, [
            .error(220, testError)
        ])


        XCTAssertEqual(e0.subscriptions, [Subscription(200, 220)])

        XCTAssertEqual(e1.subscriptions, [Subscription(200, 220)])

    }

    func testCombineLatest_WillNeverBeAbleToCombine2() {
        let factories: [(TestableObservable<Int>, TestableObservable<Int>) -> Observable<Int>] =
            [
                { e0, e1 in
                    Observable.combineLatest(e0, e1) { (_, _) -> Int in
                        return (42)
                    }
                },
                { e0, e1 in
                    Observable.combineLatest(e0, e1).map { (_, _) -> Int in
                        return (42)
                    }
                },
            ]
        for factory in factories {
            let scheduler = TestScheduler(initialClock: 0)
        

            let e0 = scheduler.createHotObservable([
                .next(150, 1),
                .completed(250)
            ])

            let e1 = scheduler.createHotObservable([
                .next(150, 1),
                .next(500, 2),
                .completed(800)
            ])

            let res = scheduler.start { () -> Observable<Int> in
                factory(e0, e1)
            }

            XCTAssertEqual(res.events, [
                .completed(500)
            ])


            XCTAssertEqual(e0.subscriptions, [Subscription(200, 250)])

            XCTAssertEqual(e1.subscriptions, [Subscription(200, 500)])
        }
    }
    
    func testCombineLatest_Typical2() {
        let factories: [(TestableObservable<Int>, TestableObservable<Int>) -> Observable<Int>] =
            [
                { e0, e1 in
                    Observable.combineLatest(e0, e1) { (e0: Int, e1: Int) -> Int in
                        return (e0 + e1)
                    }
                },
                { e0, e1 in
                    Observable.combineLatest(e0, e1).map { (e0: Int, e1: Int) -> Int in
                        return (e0 + e1)
                    }
                },
            ]
        for factory in factories {
            let scheduler = TestScheduler(initialClock: 0)


            let e0 = scheduler.createHotObservable([
                .next(150, 1),
                .next(210, 1),
                .next(410, 3),
                .completed(800)
            ])

            let e1 = scheduler.createHotObservable([
                .next(150, 1),
                .next(220, 2),
                .next(420, 4),
                .completed(800)
            ])

            let res = scheduler.start { () -> Observable<Int> in
                factory(e0, e1)
            }

            XCTAssertEqual(res.events, [
                
                .next(220, 3),

                .next(410, 5),
                .next(420, 7),
                .completed(800)
                ])


            XCTAssertEqual(e0.subscriptions, [Subscription(200, 800)])

            XCTAssertEqual(e1.subscriptions, [Subscription(200, 800)])

        }
    }




    // 3

    func testCombineLatest_Never3() {
        let factories: [(TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>) -> Observable<Int>] =
            [
                { e0, e1, e2 in
                    Observable.combineLatest(e0, e1, e2) { (_, _, _) -> Int in
                        return (42)
                    }
                },
                { e0, e1, e2 in
                    Observable.combineLatest(e0, e1, e2).map { (_, _, _) -> Int in
                        return (42)
                    }
                },
            ]
        for factory in factories {
            let scheduler = TestScheduler(initialClock: 0)


            let e0 = scheduler.createHotObservable([
                .next(150, 1)
            ])

            let e1 = scheduler.createHotObservable([
                .next(150, 1)
            ])

            let e2 = scheduler.createHotObservable([
                .next(150, 1)
            ])


            let res = scheduler.start { () -> Observable<Int> in
                factory(e0, e1, e2)
            }
            
            XCTAssertEqual(res.events, [])
            
            let subscriptions = [Subscription(200, 1000)]
            

            XCTAssertEqual(e0.subscriptions, subscriptions)
            XCTAssertEqual(e1.subscriptions, subscriptions)
            XCTAssertEqual(e2.subscriptions, subscriptions)
        }
    }

    func testCombineLatest_Empty3() {
        let factories: [(TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>) -> Observable<Int>] =
            [
                { e0, e1, e2 in
                    Observable.combineLatest(e0, e1, e2) { (_, _, _) -> Int in
                        return (42)
                    }
                },
                { e0, e1, e2 in
                    Observable.combineLatest(e0, e1, e2).map { (_, _, _) -> Int in
                        return (42)
                    }
                },
            ]

        for factory in factories {
            let scheduler = TestScheduler(initialClock: 0)


            let e0 = scheduler.createHotObservable([
                .next(150, 1),
                .completed(210)
            ])

            let e1 = scheduler.createHotObservable([
                .next(150, 1),
                .completed(220)
            ])

            let e2 = scheduler.createHotObservable([
                .next(150, 1),
                .completed(230)
            ])


            let res = scheduler.start { () -> Observable<Int> in
                factory(e0, e1, e2)
            }

            XCTAssertEqual(res.events, [.completed(230)])


            XCTAssertEqual(e0.subscriptions, [Subscription(200, 210)])

            XCTAssertEqual(e1.subscriptions, [Subscription(200, 220)])

            XCTAssertEqual(e2.subscriptions, [Subscription(200, 230)])

        }
    }

    func testCombineLatest_SelectorThrows3() {
        let scheduler = TestScheduler(initialClock: 0)


        let e0 = scheduler.createHotObservable([
            .next(150, 1),
            .next(210, 1),
            .completed(400)
        ])

        let e1 = scheduler.createHotObservable([
            .next(150, 1),
            .next(220, 2),
            .completed(400)
        ])

        let e2 = scheduler.createHotObservable([
            .next(150, 1),
            .next(230, 3),
            .completed(400)
        ])


        let res = scheduler.start { () -> Observable<Int> in
            Observable.combineLatest(e0, e1, e2) { (_, _, _) throws -> Int in
                throw testError
            }
        }

        XCTAssertEqual(res.events, [
            .error(230, testError)
        ])


        XCTAssertEqual(e0.subscriptions, [Subscription(200, 230)])

        XCTAssertEqual(e1.subscriptions, [Subscription(200, 230)])

        XCTAssertEqual(e2.subscriptions, [Subscription(200, 230)])

    }

    func testCombineLatest_WillNeverBeAbleToCombine3() {
        let factories: [(TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>) -> Observable<Int>] =
            [
                { e0, e1, e2 in
                    Observable.combineLatest(e0, e1, e2) { (_, _, _) -> Int in
                        return (42)
                    }
                },
                { e0, e1, e2 in
                    Observable.combineLatest(e0, e1, e2).map { (_, _, _) -> Int in
                        return (42)
                    }
                },
            ]
        for factory in factories {
            let scheduler = TestScheduler(initialClock: 0)
        

            let e0 = scheduler.createHotObservable([
                .next(150, 1),
                .completed(250)
            ])

            let e1 = scheduler.createHotObservable([
                .next(150, 1),
                .completed(260)
            ])

            let e2 = scheduler.createHotObservable([
                .next(150, 1),
                .next(500, 2),
                .completed(800)
            ])

            let res = scheduler.start { () -> Observable<Int> in
                factory(e0, e1, e2)
            }

            XCTAssertEqual(res.events, [
                .completed(500)
            ])


            XCTAssertEqual(e0.subscriptions, [Subscription(200, 250)])

            XCTAssertEqual(e1.subscriptions, [Subscription(200, 260)])

            XCTAssertEqual(e2.subscriptions, [Subscription(200, 500)])
        }
    }
    
    func testCombineLatest_Typical3() {
        let factories: [(TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>) -> Observable<Int>] =
            [
                { e0, e1, e2 in
                    Observable.combineLatest(e0, e1, e2) { (e0: Int, e1: Int, e2: Int) -> Int in
                        return (e0 + e1 + e2)
                    }
                },
                { e0, e1, e2 in
                    Observable.combineLatest(e0, e1, e2).map { (e0: Int, e1: Int, e2: Int) -> Int in
                        return (e0 + e1 + e2)
                    }
                },
            ]
        for factory in factories {
            let scheduler = TestScheduler(initialClock: 0)


            let e0 = scheduler.createHotObservable([
                .next(150, 1),
                .next(210, 1),
                .next(410, 4),
                .completed(800)
            ])

            let e1 = scheduler.createHotObservable([
                .next(150, 1),
                .next(220, 2),
                .next(420, 5),
                .completed(800)
            ])

            let e2 = scheduler.createHotObservable([
                .next(150, 1),
                .next(230, 3),
                .next(430, 6),
                .completed(800)
            ])

            let res = scheduler.start { () -> Observable<Int> in
                factory(e0, e1, e2)
            }

            XCTAssertEqual(res.events, [
                
                .next(230, 6),

                .next(410, 9),
                .next(420, 12),
                .next(430, 15),
                .completed(800)
                ])


            XCTAssertEqual(e0.subscriptions, [Subscription(200, 800)])

            XCTAssertEqual(e1.subscriptions, [Subscription(200, 800)])

            XCTAssertEqual(e2.subscriptions, [Subscription(200, 800)])

        }
    }




    // 4

    func testCombineLatest_Never4() {
        let factories: [(TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>) -> Observable<Int>] =
            [
                { e0, e1, e2, e3 in
                    Observable.combineLatest(e0, e1, e2, e3) { (_, _, _, _) -> Int in
                        return (42)
                    }
                },
                { e0, e1, e2, e3 in
                    Observable.combineLatest(e0, e1, e2, e3).map { (_, _, _, _) -> Int in
                        return (42)
                    }
                },
            ]
        for factory in factories {
            let scheduler = TestScheduler(initialClock: 0)


            let e0 = scheduler.createHotObservable([
                .next(150, 1)
            ])

            let e1 = scheduler.createHotObservable([
                .next(150, 1)
            ])

            let e2 = scheduler.createHotObservable([
                .next(150, 1)
            ])

            let e3 = scheduler.createHotObservable([
                .next(150, 1)
            ])


            let res = scheduler.start { () -> Observable<Int> in
                factory(e0, e1, e2, e3)
            }
            
            XCTAssertEqual(res.events, [])
            
            let subscriptions = [Subscription(200, 1000)]
            

            XCTAssertEqual(e0.subscriptions, subscriptions)
            XCTAssertEqual(e1.subscriptions, subscriptions)
            XCTAssertEqual(e2.subscriptions, subscriptions)
            XCTAssertEqual(e3.subscriptions, subscriptions)
        }
    }

    func testCombineLatest_Empty4() {
        let factories: [(TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>) -> Observable<Int>] =
            [
                { e0, e1, e2, e3 in
                    Observable.combineLatest(e0, e1, e2, e3) { (_, _, _, _) -> Int in
                        return (42)
                    }
                },
                { e0, e1, e2, e3 in
                    Observable.combineLatest(e0, e1, e2, e3).map { (_, _, _, _) -> Int in
                        return (42)
                    }
                },
            ]

        for factory in factories {
            let scheduler = TestScheduler(initialClock: 0)


            let e0 = scheduler.createHotObservable([
                .next(150, 1),
                .completed(210)
            ])

            let e1 = scheduler.createHotObservable([
                .next(150, 1),
                .completed(220)
            ])

            let e2 = scheduler.createHotObservable([
                .next(150, 1),
                .completed(230)
            ])

            let e3 = scheduler.createHotObservable([
                .next(150, 1),
                .completed(240)
            ])


            let res = scheduler.start { () -> Observable<Int> in
                factory(e0, e1, e2, e3)
            }

            XCTAssertEqual(res.events, [.completed(240)])


            XCTAssertEqual(e0.subscriptions, [Subscription(200, 210)])

            XCTAssertEqual(e1.subscriptions, [Subscription(200, 220)])

            XCTAssertEqual(e2.subscriptions, [Subscription(200, 230)])

            XCTAssertEqual(e3.subscriptions, [Subscription(200, 240)])

        }
    }

    func testCombineLatest_SelectorThrows4() {
        let scheduler = TestScheduler(initialClock: 0)


        let e0 = scheduler.createHotObservable([
            .next(150, 1),
            .next(210, 1),
            .completed(400)
        ])

        let e1 = scheduler.createHotObservable([
            .next(150, 1),
            .next(220, 2),
            .completed(400)
        ])

        let e2 = scheduler.createHotObservable([
            .next(150, 1),
            .next(230, 3),
            .completed(400)
        ])

        let e3 = scheduler.createHotObservable([
            .next(150, 1),
            .next(240, 4),
            .completed(400)
        ])


        let res = scheduler.start { () -> Observable<Int> in
            Observable.combineLatest(e0, e1, e2, e3) { (_, _, _, _) throws -> Int in
                throw testError
            }
        }

        XCTAssertEqual(res.events, [
            .error(240, testError)
        ])


        XCTAssertEqual(e0.subscriptions, [Subscription(200, 240)])

        XCTAssertEqual(e1.subscriptions, [Subscription(200, 240)])

        XCTAssertEqual(e2.subscriptions, [Subscription(200, 240)])

        XCTAssertEqual(e3.subscriptions, [Subscription(200, 240)])

    }

    func testCombineLatest_WillNeverBeAbleToCombine4() {
        let factories: [(TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>) -> Observable<Int>] =
            [
                { e0, e1, e2, e3 in
                    Observable.combineLatest(e0, e1, e2, e3) { (_, _, _, _) -> Int in
                        return (42)
                    }
                },
                { e0, e1, e2, e3 in
                    Observable.combineLatest(e0, e1, e2, e3).map { (_, _, _, _) -> Int in
                        return (42)
                    }
                },
            ]
        for factory in factories {
            let scheduler = TestScheduler(initialClock: 0)
        

            let e0 = scheduler.createHotObservable([
                .next(150, 1),
                .completed(250)
            ])

            let e1 = scheduler.createHotObservable([
                .next(150, 1),
                .completed(260)
            ])

            let e2 = scheduler.createHotObservable([
                .next(150, 1),
                .completed(270)
            ])

            let e3 = scheduler.createHotObservable([
                .next(150, 1),
                .next(500, 2),
                .completed(800)
            ])

            let res = scheduler.start { () -> Observable<Int> in
                factory(e0, e1, e2, e3)
            }

            XCTAssertEqual(res.events, [
                .completed(500)
            ])


            XCTAssertEqual(e0.subscriptions, [Subscription(200, 250)])

            XCTAssertEqual(e1.subscriptions, [Subscription(200, 260)])

            XCTAssertEqual(e2.subscriptions, [Subscription(200, 270)])

            XCTAssertEqual(e3.subscriptions, [Subscription(200, 500)])
        }
    }
    
    func testCombineLatest_Typical4() {
        let factories: [(TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>) -> Observable<Int>] =
            [
                { e0, e1, e2, e3 in
                    Observable.combineLatest(e0, e1, e2, e3) { (e0: Int, e1: Int, e2: Int, e3: Int) -> Int in
                        return (e0 + e1 + e2 + e3)
                    }
                },
                { e0, e1, e2, e3 in
                    Observable.combineLatest(e0, e1, e2, e3).map { (e0: Int, e1: Int, e2: Int, e3: Int) -> Int in
                        return (e0 + e1 + e2 + e3)
                    }
                },
            ]
        for factory in factories {
            let scheduler = TestScheduler(initialClock: 0)


            let e0 = scheduler.createHotObservable([
                .next(150, 1),
                .next(210, 1),
                .next(410, 5),
                .completed(800)
            ])

            let e1 = scheduler.createHotObservable([
                .next(150, 1),
                .next(220, 2),
                .next(420, 6),
                .completed(800)
            ])

            let e2 = scheduler.createHotObservable([
                .next(150, 1),
                .next(230, 3),
                .next(430, 7),
                .completed(800)
            ])

            let e3 = scheduler.createHotObservable([
                .next(150, 1),
                .next(240, 4),
                .next(440, 8),
                .completed(800)
            ])

            let res = scheduler.start { () -> Observable<Int> in
                factory(e0, e1, e2, e3)
            }

            XCTAssertEqual(res.events, [
                
                .next(240, 10),

                .next(410, 14),
                .next(420, 18),
                .next(430, 22),
                .next(440, 26),
                .completed(800)
                ])


            XCTAssertEqual(e0.subscriptions, [Subscription(200, 800)])

            XCTAssertEqual(e1.subscriptions, [Subscription(200, 800)])

            XCTAssertEqual(e2.subscriptions, [Subscription(200, 800)])

            XCTAssertEqual(e3.subscriptions, [Subscription(200, 800)])

        }
    }




    // 5

    func testCombineLatest_Never5() {
        let factories: [(TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>) -> Observable<Int>] =
            [
                { e0, e1, e2, e3, e4 in
                    Observable.combineLatest(e0, e1, e2, e3, e4) { (_, _, _, _, _) -> Int in
                        return (42)
                    }
                },
                { e0, e1, e2, e3, e4 in
                    Observable.combineLatest(e0, e1, e2, e3, e4).map { (_, _, _, _, _) -> Int in
                        return (42)
                    }
                },
            ]
        for factory in factories {
            let scheduler = TestScheduler(initialClock: 0)


            let e0 = scheduler.createHotObservable([
                .next(150, 1)
            ])

            let e1 = scheduler.createHotObservable([
                .next(150, 1)
            ])

            let e2 = scheduler.createHotObservable([
                .next(150, 1)
            ])

            let e3 = scheduler.createHotObservable([
                .next(150, 1)
            ])

            let e4 = scheduler.createHotObservable([
                .next(150, 1)
            ])


            let res = scheduler.start { () -> Observable<Int> in
                factory(e0, e1, e2, e3, e4)
            }
            
            XCTAssertEqual(res.events, [])
            
            let subscriptions = [Subscription(200, 1000)]
            

            XCTAssertEqual(e0.subscriptions, subscriptions)
            XCTAssertEqual(e1.subscriptions, subscriptions)
            XCTAssertEqual(e2.subscriptions, subscriptions)
            XCTAssertEqual(e3.subscriptions, subscriptions)
            XCTAssertEqual(e4.subscriptions, subscriptions)
        }
    }

    func testCombineLatest_Empty5() {
        let factories: [(TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>) -> Observable<Int>] =
            [
                { e0, e1, e2, e3, e4 in
                    Observable.combineLatest(e0, e1, e2, e3, e4) { (_, _, _, _, _) -> Int in
                        return (42)
                    }
                },
                { e0, e1, e2, e3, e4 in
                    Observable.combineLatest(e0, e1, e2, e3, e4).map { (_, _, _, _, _) -> Int in
                        return (42)
                    }
                },
            ]

        for factory in factories {
            let scheduler = TestScheduler(initialClock: 0)


            let e0 = scheduler.createHotObservable([
                .next(150, 1),
                .completed(210)
            ])

            let e1 = scheduler.createHotObservable([
                .next(150, 1),
                .completed(220)
            ])

            let e2 = scheduler.createHotObservable([
                .next(150, 1),
                .completed(230)
            ])

            let e3 = scheduler.createHotObservable([
                .next(150, 1),
                .completed(240)
            ])

            let e4 = scheduler.createHotObservable([
                .next(150, 1),
                .completed(250)
            ])


            let res = scheduler.start { () -> Observable<Int> in
                factory(e0, e1, e2, e3, e4)
            }

            XCTAssertEqual(res.events, [.completed(250)])


            XCTAssertEqual(e0.subscriptions, [Subscription(200, 210)])

            XCTAssertEqual(e1.subscriptions, [Subscription(200, 220)])

            XCTAssertEqual(e2.subscriptions, [Subscription(200, 230)])

            XCTAssertEqual(e3.subscriptions, [Subscription(200, 240)])

            XCTAssertEqual(e4.subscriptions, [Subscription(200, 250)])

        }
    }

    func testCombineLatest_SelectorThrows5() {
        let scheduler = TestScheduler(initialClock: 0)


        let e0 = scheduler.createHotObservable([
            .next(150, 1),
            .next(210, 1),
            .completed(400)
        ])

        let e1 = scheduler.createHotObservable([
            .next(150, 1),
            .next(220, 2),
            .completed(400)
        ])

        let e2 = scheduler.createHotObservable([
            .next(150, 1),
            .next(230, 3),
            .completed(400)
        ])

        let e3 = scheduler.createHotObservable([
            .next(150, 1),
            .next(240, 4),
            .completed(400)
        ])

        let e4 = scheduler.createHotObservable([
            .next(150, 1),
            .next(250, 5),
            .completed(400)
        ])


        let res = scheduler.start { () -> Observable<Int> in
            Observable.combineLatest(e0, e1, e2, e3, e4) { (_, _, _, _, _) throws -> Int in
                throw testError
            }
        }

        XCTAssertEqual(res.events, [
            .error(250, testError)
        ])


        XCTAssertEqual(e0.subscriptions, [Subscription(200, 250)])

        XCTAssertEqual(e1.subscriptions, [Subscription(200, 250)])

        XCTAssertEqual(e2.subscriptions, [Subscription(200, 250)])

        XCTAssertEqual(e3.subscriptions, [Subscription(200, 250)])

        XCTAssertEqual(e4.subscriptions, [Subscription(200, 250)])

    }

    func testCombineLatest_WillNeverBeAbleToCombine5() {
        let factories: [(TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>) -> Observable<Int>] =
            [
                { e0, e1, e2, e3, e4 in
                    Observable.combineLatest(e0, e1, e2, e3, e4) { (_, _, _, _, _) -> Int in
                        return (42)
                    }
                },
                { e0, e1, e2, e3, e4 in
                    Observable.combineLatest(e0, e1, e2, e3, e4).map { (_, _, _, _, _) -> Int in
                        return (42)
                    }
                },
            ]
        for factory in factories {
            let scheduler = TestScheduler(initialClock: 0)
        

            let e0 = scheduler.createHotObservable([
                .next(150, 1),
                .completed(250)
            ])

            let e1 = scheduler.createHotObservable([
                .next(150, 1),
                .completed(260)
            ])

            let e2 = scheduler.createHotObservable([
                .next(150, 1),
                .completed(270)
            ])

            let e3 = scheduler.createHotObservable([
                .next(150, 1),
                .completed(280)
            ])

            let e4 = scheduler.createHotObservable([
                .next(150, 1),
                .next(500, 2),
                .completed(800)
            ])

            let res = scheduler.start { () -> Observable<Int> in
                factory(e0, e1, e2, e3, e4)
            }

            XCTAssertEqual(res.events, [
                .completed(500)
            ])


            XCTAssertEqual(e0.subscriptions, [Subscription(200, 250)])

            XCTAssertEqual(e1.subscriptions, [Subscription(200, 260)])

            XCTAssertEqual(e2.subscriptions, [Subscription(200, 270)])

            XCTAssertEqual(e3.subscriptions, [Subscription(200, 280)])

            XCTAssertEqual(e4.subscriptions, [Subscription(200, 500)])
        }
    }
    
    func testCombineLatest_Typical5() {
        let factories: [(TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>) -> Observable<Int>] =
            [
                { e0, e1, e2, e3, e4 in
                    Observable.combineLatest(e0, e1, e2, e3, e4) { (e0: Int, e1: Int, e2: Int, e3: Int, e4: Int) -> Int in
                        return (e0 + e1 + e2 + e3 + e4)
                    }
                },
                { e0, e1, e2, e3, e4 in
                    Observable.combineLatest(e0, e1, e2, e3, e4).map { (e0: Int, e1: Int, e2: Int, e3: Int, e4: Int) -> Int in
                        return (e0 + e1 + e2 + e3 + e4)
                    }
                },
            ]
        for factory in factories {
            let scheduler = TestScheduler(initialClock: 0)


            let e0 = scheduler.createHotObservable([
                .next(150, 1),
                .next(210, 1),
                .next(410, 6),
                .completed(800)
            ])

            let e1 = scheduler.createHotObservable([
                .next(150, 1),
                .next(220, 2),
                .next(420, 7),
                .completed(800)
            ])

            let e2 = scheduler.createHotObservable([
                .next(150, 1),
                .next(230, 3),
                .next(430, 8),
                .completed(800)
            ])

            let e3 = scheduler.createHotObservable([
                .next(150, 1),
                .next(240, 4),
                .next(440, 9),
                .completed(800)
            ])

            let e4 = scheduler.createHotObservable([
                .next(150, 1),
                .next(250, 5),
                .next(450, 10),
                .completed(800)
            ])

            let res = scheduler.start { () -> Observable<Int> in
                factory(e0, e1, e2, e3, e4)
            }

            XCTAssertEqual(res.events, [
                
                .next(250, 15),

                .next(410, 20),
                .next(420, 25),
                .next(430, 30),
                .next(440, 35),
                .next(450, 40),
                .completed(800)
                ])


            XCTAssertEqual(e0.subscriptions, [Subscription(200, 800)])

            XCTAssertEqual(e1.subscriptions, [Subscription(200, 800)])

            XCTAssertEqual(e2.subscriptions, [Subscription(200, 800)])

            XCTAssertEqual(e3.subscriptions, [Subscription(200, 800)])

            XCTAssertEqual(e4.subscriptions, [Subscription(200, 800)])

        }
    }




    // 6

    func testCombineLatest_Never6() {
        let factories: [(TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>) -> Observable<Int>] =
            [
                { e0, e1, e2, e3, e4, e5 in
                    Observable.combineLatest(e0, e1, e2, e3, e4, e5) { (_, _, _, _, _, _) -> Int in
                        return (42)
                    }
                },
                { e0, e1, e2, e3, e4, e5 in
                    Observable.combineLatest(e0, e1, e2, e3, e4, e5).map { (_, _, _, _, _, _) -> Int in
                        return (42)
                    }
                },
            ]
        for factory in factories {
            let scheduler = TestScheduler(initialClock: 0)


            let e0 = scheduler.createHotObservable([
                .next(150, 1)
            ])

            let e1 = scheduler.createHotObservable([
                .next(150, 1)
            ])

            let e2 = scheduler.createHotObservable([
                .next(150, 1)
            ])

            let e3 = scheduler.createHotObservable([
                .next(150, 1)
            ])

            let e4 = scheduler.createHotObservable([
                .next(150, 1)
            ])

            let e5 = scheduler.createHotObservable([
                .next(150, 1)
            ])


            let res = scheduler.start { () -> Observable<Int> in
                factory(e0, e1, e2, e3, e4, e5)
            }
            
            XCTAssertEqual(res.events, [])
            
            let subscriptions = [Subscription(200, 1000)]
            

            XCTAssertEqual(e0.subscriptions, subscriptions)
            XCTAssertEqual(e1.subscriptions, subscriptions)
            XCTAssertEqual(e2.subscriptions, subscriptions)
            XCTAssertEqual(e3.subscriptions, subscriptions)
            XCTAssertEqual(e4.subscriptions, subscriptions)
            XCTAssertEqual(e5.subscriptions, subscriptions)
        }
    }

    func testCombineLatest_Empty6() {
        let factories: [(TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>) -> Observable<Int>] =
            [
                { e0, e1, e2, e3, e4, e5 in
                    Observable.combineLatest(e0, e1, e2, e3, e4, e5) { (_, _, _, _, _, _) -> Int in
                        return (42)
                    }
                },
                { e0, e1, e2, e3, e4, e5 in
                    Observable.combineLatest(e0, e1, e2, e3, e4, e5).map { (_, _, _, _, _, _) -> Int in
                        return (42)
                    }
                },
            ]

        for factory in factories {
            let scheduler = TestScheduler(initialClock: 0)


            let e0 = scheduler.createHotObservable([
                .next(150, 1),
                .completed(210)
            ])

            let e1 = scheduler.createHotObservable([
                .next(150, 1),
                .completed(220)
            ])

            let e2 = scheduler.createHotObservable([
                .next(150, 1),
                .completed(230)
            ])

            let e3 = scheduler.createHotObservable([
                .next(150, 1),
                .completed(240)
            ])

            let e4 = scheduler.createHotObservable([
                .next(150, 1),
                .completed(250)
            ])

            let e5 = scheduler.createHotObservable([
                .next(150, 1),
                .completed(260)
            ])


            let res = scheduler.start { () -> Observable<Int> in
                factory(e0, e1, e2, e3, e4, e5)
            }

            XCTAssertEqual(res.events, [.completed(260)])


            XCTAssertEqual(e0.subscriptions, [Subscription(200, 210)])

            XCTAssertEqual(e1.subscriptions, [Subscription(200, 220)])

            XCTAssertEqual(e2.subscriptions, [Subscription(200, 230)])

            XCTAssertEqual(e3.subscriptions, [Subscription(200, 240)])

            XCTAssertEqual(e4.subscriptions, [Subscription(200, 250)])

            XCTAssertEqual(e5.subscriptions, [Subscription(200, 260)])

        }
    }

    func testCombineLatest_SelectorThrows6() {
        let scheduler = TestScheduler(initialClock: 0)


        let e0 = scheduler.createHotObservable([
            .next(150, 1),
            .next(210, 1),
            .completed(400)
        ])

        let e1 = scheduler.createHotObservable([
            .next(150, 1),
            .next(220, 2),
            .completed(400)
        ])

        let e2 = scheduler.createHotObservable([
            .next(150, 1),
            .next(230, 3),
            .completed(400)
        ])

        let e3 = scheduler.createHotObservable([
            .next(150, 1),
            .next(240, 4),
            .completed(400)
        ])

        let e4 = scheduler.createHotObservable([
            .next(150, 1),
            .next(250, 5),
            .completed(400)
        ])

        let e5 = scheduler.createHotObservable([
            .next(150, 1),
            .next(260, 6),
            .completed(400)
        ])


        let res = scheduler.start { () -> Observable<Int> in
            Observable.combineLatest(e0, e1, e2, e3, e4, e5) { (_, _, _, _, _, _) throws -> Int in
                throw testError
            }
        }

        XCTAssertEqual(res.events, [
            .error(260, testError)
        ])


        XCTAssertEqual(e0.subscriptions, [Subscription(200, 260)])

        XCTAssertEqual(e1.subscriptions, [Subscription(200, 260)])

        XCTAssertEqual(e2.subscriptions, [Subscription(200, 260)])

        XCTAssertEqual(e3.subscriptions, [Subscription(200, 260)])

        XCTAssertEqual(e4.subscriptions, [Subscription(200, 260)])

        XCTAssertEqual(e5.subscriptions, [Subscription(200, 260)])

    }

    func testCombineLatest_WillNeverBeAbleToCombine6() {
        let factories: [(TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>) -> Observable<Int>] =
            [
                { e0, e1, e2, e3, e4, e5 in
                    Observable.combineLatest(e0, e1, e2, e3, e4, e5) { (_, _, _, _, _, _) -> Int in
                        return (42)
                    }
                },
                { e0, e1, e2, e3, e4, e5 in
                    Observable.combineLatest(e0, e1, e2, e3, e4, e5).map { (_, _, _, _, _, _) -> Int in
                        return (42)
                    }
                },
            ]
        for factory in factories {
            let scheduler = TestScheduler(initialClock: 0)
        

            let e0 = scheduler.createHotObservable([
                .next(150, 1),
                .completed(250)
            ])

            let e1 = scheduler.createHotObservable([
                .next(150, 1),
                .completed(260)
            ])

            let e2 = scheduler.createHotObservable([
                .next(150, 1),
                .completed(270)
            ])

            let e3 = scheduler.createHotObservable([
                .next(150, 1),
                .completed(280)
            ])

            let e4 = scheduler.createHotObservable([
                .next(150, 1),
                .completed(290)
            ])

            let e5 = scheduler.createHotObservable([
                .next(150, 1),
                .next(500, 2),
                .completed(800)
            ])

            let res = scheduler.start { () -> Observable<Int> in
                factory(e0, e1, e2, e3, e4, e5)
            }

            XCTAssertEqual(res.events, [
                .completed(500)
            ])


            XCTAssertEqual(e0.subscriptions, [Subscription(200, 250)])

            XCTAssertEqual(e1.subscriptions, [Subscription(200, 260)])

            XCTAssertEqual(e2.subscriptions, [Subscription(200, 270)])

            XCTAssertEqual(e3.subscriptions, [Subscription(200, 280)])

            XCTAssertEqual(e4.subscriptions, [Subscription(200, 290)])

            XCTAssertEqual(e5.subscriptions, [Subscription(200, 500)])
        }
    }
    
    func testCombineLatest_Typical6() {
        let factories: [(TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>) -> Observable<Int>] =
            [
                { e0, e1, e2, e3, e4, e5 in
                    Observable.combineLatest(e0, e1, e2, e3, e4, e5) { (e0: Int, e1: Int, e2: Int, e3: Int, e4: Int, e5: Int) -> Int in
                        return (e0 + e1 + e2 + e3 + e4 + e5)
                    }
                },
                { e0, e1, e2, e3, e4, e5 in
                    Observable.combineLatest(e0, e1, e2, e3, e4, e5).map { (e0: Int, e1: Int, e2: Int, e3: Int, e4: Int, e5: Int) -> Int in
                        return (e0 + e1 + e2 + e3 + e4 + e5)
                    }
                },
            ]
        for factory in factories {
            let scheduler = TestScheduler(initialClock: 0)


            let e0 = scheduler.createHotObservable([
                .next(150, 1),
                .next(210, 1),
                .next(410, 7),
                .completed(800)
            ])

            let e1 = scheduler.createHotObservable([
                .next(150, 1),
                .next(220, 2),
                .next(420, 8),
                .completed(800)
            ])

            let e2 = scheduler.createHotObservable([
                .next(150, 1),
                .next(230, 3),
                .next(430, 9),
                .completed(800)
            ])

            let e3 = scheduler.createHotObservable([
                .next(150, 1),
                .next(240, 4),
                .next(440, 10),
                .completed(800)
            ])

            let e4 = scheduler.createHotObservable([
                .next(150, 1),
                .next(250, 5),
                .next(450, 11),
                .completed(800)
            ])

            let e5 = scheduler.createHotObservable([
                .next(150, 1),
                .next(260, 6),
                .next(460, 12),
                .completed(800)
            ])

            let res = scheduler.start { () -> Observable<Int> in
                factory(e0, e1, e2, e3, e4, e5)
            }

            XCTAssertEqual(res.events, [
                
                .next(260, 21),

                .next(410, 27),
                .next(420, 33),
                .next(430, 39),
                .next(440, 45),
                .next(450, 51),
                .next(460, 57),
                .completed(800)
                ])


            XCTAssertEqual(e0.subscriptions, [Subscription(200, 800)])

            XCTAssertEqual(e1.subscriptions, [Subscription(200, 800)])

            XCTAssertEqual(e2.subscriptions, [Subscription(200, 800)])

            XCTAssertEqual(e3.subscriptions, [Subscription(200, 800)])

            XCTAssertEqual(e4.subscriptions, [Subscription(200, 800)])

            XCTAssertEqual(e5.subscriptions, [Subscription(200, 800)])

        }
    }




    // 7

    func testCombineLatest_Never7() {
        let factories: [(TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>) -> Observable<Int>] =
            [
                { e0, e1, e2, e3, e4, e5, e6 in
                    Observable.combineLatest(e0, e1, e2, e3, e4, e5, e6) { (_, _, _, _, _, _, _) -> Int in
                        return (42)
                    }
                },
                { e0, e1, e2, e3, e4, e5, e6 in
                    Observable.combineLatest(e0, e1, e2, e3, e4, e5, e6).map { (_, _, _, _, _, _, _) -> Int in
                        return (42)
                    }
                },
            ]
        for factory in factories {
            let scheduler = TestScheduler(initialClock: 0)


            let e0 = scheduler.createHotObservable([
                .next(150, 1)
            ])

            let e1 = scheduler.createHotObservable([
                .next(150, 1)
            ])

            let e2 = scheduler.createHotObservable([
                .next(150, 1)
            ])

            let e3 = scheduler.createHotObservable([
                .next(150, 1)
            ])

            let e4 = scheduler.createHotObservable([
                .next(150, 1)
            ])

            let e5 = scheduler.createHotObservable([
                .next(150, 1)
            ])

            let e6 = scheduler.createHotObservable([
                .next(150, 1)
            ])


            let res = scheduler.start { () -> Observable<Int> in
                factory(e0, e1, e2, e3, e4, e5, e6)
            }
            
            XCTAssertEqual(res.events, [])
            
            let subscriptions = [Subscription(200, 1000)]
            

            XCTAssertEqual(e0.subscriptions, subscriptions)
            XCTAssertEqual(e1.subscriptions, subscriptions)
            XCTAssertEqual(e2.subscriptions, subscriptions)
            XCTAssertEqual(e3.subscriptions, subscriptions)
            XCTAssertEqual(e4.subscriptions, subscriptions)
            XCTAssertEqual(e5.subscriptions, subscriptions)
            XCTAssertEqual(e6.subscriptions, subscriptions)
        }
    }

    func testCombineLatest_Empty7() {
        let factories: [(TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>) -> Observable<Int>] =
            [
                { e0, e1, e2, e3, e4, e5, e6 in
                    Observable.combineLatest(e0, e1, e2, e3, e4, e5, e6) { (_, _, _, _, _, _, _) -> Int in
                        return (42)
                    }
                },
                { e0, e1, e2, e3, e4, e5, e6 in
                    Observable.combineLatest(e0, e1, e2, e3, e4, e5, e6).map { (_, _, _, _, _, _, _) -> Int in
                        return (42)
                    }
                },
            ]

        for factory in factories {
            let scheduler = TestScheduler(initialClock: 0)


            let e0 = scheduler.createHotObservable([
                .next(150, 1),
                .completed(210)
            ])

            let e1 = scheduler.createHotObservable([
                .next(150, 1),
                .completed(220)
            ])

            let e2 = scheduler.createHotObservable([
                .next(150, 1),
                .completed(230)
            ])

            let e3 = scheduler.createHotObservable([
                .next(150, 1),
                .completed(240)
            ])

            let e4 = scheduler.createHotObservable([
                .next(150, 1),
                .completed(250)
            ])

            let e5 = scheduler.createHotObservable([
                .next(150, 1),
                .completed(260)
            ])

            let e6 = scheduler.createHotObservable([
                .next(150, 1),
                .completed(270)
            ])


            let res = scheduler.start { () -> Observable<Int> in
                factory(e0, e1, e2, e3, e4, e5, e6)
            }

            XCTAssertEqual(res.events, [.completed(270)])


            XCTAssertEqual(e0.subscriptions, [Subscription(200, 210)])

            XCTAssertEqual(e1.subscriptions, [Subscription(200, 220)])

            XCTAssertEqual(e2.subscriptions, [Subscription(200, 230)])

            XCTAssertEqual(e3.subscriptions, [Subscription(200, 240)])

            XCTAssertEqual(e4.subscriptions, [Subscription(200, 250)])

            XCTAssertEqual(e5.subscriptions, [Subscription(200, 260)])

            XCTAssertEqual(e6.subscriptions, [Subscription(200, 270)])

        }
    }

    func testCombineLatest_SelectorThrows7() {
        let scheduler = TestScheduler(initialClock: 0)


        let e0 = scheduler.createHotObservable([
            .next(150, 1),
            .next(210, 1),
            .completed(400)
        ])

        let e1 = scheduler.createHotObservable([
            .next(150, 1),
            .next(220, 2),
            .completed(400)
        ])

        let e2 = scheduler.createHotObservable([
            .next(150, 1),
            .next(230, 3),
            .completed(400)
        ])

        let e3 = scheduler.createHotObservable([
            .next(150, 1),
            .next(240, 4),
            .completed(400)
        ])

        let e4 = scheduler.createHotObservable([
            .next(150, 1),
            .next(250, 5),
            .completed(400)
        ])

        let e5 = scheduler.createHotObservable([
            .next(150, 1),
            .next(260, 6),
            .completed(400)
        ])

        let e6 = scheduler.createHotObservable([
            .next(150, 1),
            .next(270, 7),
            .completed(400)
        ])


        let res = scheduler.start { () -> Observable<Int> in
            Observable.combineLatest(e0, e1, e2, e3, e4, e5, e6) { (_, _, _, _, _, _, _) throws -> Int in
                throw testError
            }
        }

        XCTAssertEqual(res.events, [
            .error(270, testError)
        ])


        XCTAssertEqual(e0.subscriptions, [Subscription(200, 270)])

        XCTAssertEqual(e1.subscriptions, [Subscription(200, 270)])

        XCTAssertEqual(e2.subscriptions, [Subscription(200, 270)])

        XCTAssertEqual(e3.subscriptions, [Subscription(200, 270)])

        XCTAssertEqual(e4.subscriptions, [Subscription(200, 270)])

        XCTAssertEqual(e5.subscriptions, [Subscription(200, 270)])

        XCTAssertEqual(e6.subscriptions, [Subscription(200, 270)])

    }

    func testCombineLatest_WillNeverBeAbleToCombine7() {
        let factories: [(TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>) -> Observable<Int>] =
            [
                { e0, e1, e2, e3, e4, e5, e6 in
                    Observable.combineLatest(e0, e1, e2, e3, e4, e5, e6) { (_, _, _, _, _, _, _) -> Int in
                        return (42)
                    }
                },
                { e0, e1, e2, e3, e4, e5, e6 in
                    Observable.combineLatest(e0, e1, e2, e3, e4, e5, e6).map { (_, _, _, _, _, _, _) -> Int in
                        return (42)
                    }
                },
            ]
        for factory in factories {
            let scheduler = TestScheduler(initialClock: 0)
        

            let e0 = scheduler.createHotObservable([
                .next(150, 1),
                .completed(250)
            ])

            let e1 = scheduler.createHotObservable([
                .next(150, 1),
                .completed(260)
            ])

            let e2 = scheduler.createHotObservable([
                .next(150, 1),
                .completed(270)
            ])

            let e3 = scheduler.createHotObservable([
                .next(150, 1),
                .completed(280)
            ])

            let e4 = scheduler.createHotObservable([
                .next(150, 1),
                .completed(290)
            ])

            let e5 = scheduler.createHotObservable([
                .next(150, 1),
                .completed(300)
            ])

            let e6 = scheduler.createHotObservable([
                .next(150, 1),
                .next(500, 2),
                .completed(800)
            ])

            let res = scheduler.start { () -> Observable<Int> in
                factory(e0, e1, e2, e3, e4, e5, e6)
            }

            XCTAssertEqual(res.events, [
                .completed(500)
            ])


            XCTAssertEqual(e0.subscriptions, [Subscription(200, 250)])

            XCTAssertEqual(e1.subscriptions, [Subscription(200, 260)])

            XCTAssertEqual(e2.subscriptions, [Subscription(200, 270)])

            XCTAssertEqual(e3.subscriptions, [Subscription(200, 280)])

            XCTAssertEqual(e4.subscriptions, [Subscription(200, 290)])

            XCTAssertEqual(e5.subscriptions, [Subscription(200, 300)])

            XCTAssertEqual(e6.subscriptions, [Subscription(200, 500)])
        }
    }
    
    func testCombineLatest_Typical7() {
        let factories: [(TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>) -> Observable<Int>] =
            [
                { e0, e1, e2, e3, e4, e5, e6 in
                    Observable.combineLatest(e0, e1, e2, e3, e4, e5, e6) { (e0: Int, e1: Int, e2: Int, e3: Int, e4: Int, e5: Int, e6: Int) -> Int in
                        return (e0 + e1 + e2 + e3 + e4 + e5 + e6)
                    }
                },
                { e0, e1, e2, e3, e4, e5, e6 in
                    Observable.combineLatest(e0, e1, e2, e3, e4, e5, e6).map { (e0: Int, e1: Int, e2: Int, e3: Int, e4: Int, e5: Int, e6: Int) -> Int in
                        return (e0 + e1 + e2 + e3 + e4 + e5 + e6)
                    }
                },
            ]
        for factory in factories {
            let scheduler = TestScheduler(initialClock: 0)


            let e0 = scheduler.createHotObservable([
                .next(150, 1),
                .next(210, 1),
                .next(410, 8),
                .completed(800)
            ])

            let e1 = scheduler.createHotObservable([
                .next(150, 1),
                .next(220, 2),
                .next(420, 9),
                .completed(800)
            ])

            let e2 = scheduler.createHotObservable([
                .next(150, 1),
                .next(230, 3),
                .next(430, 10),
                .completed(800)
            ])

            let e3 = scheduler.createHotObservable([
                .next(150, 1),
                .next(240, 4),
                .next(440, 11),
                .completed(800)
            ])

            let e4 = scheduler.createHotObservable([
                .next(150, 1),
                .next(250, 5),
                .next(450, 12),
                .completed(800)
            ])

            let e5 = scheduler.createHotObservable([
                .next(150, 1),
                .next(260, 6),
                .next(460, 13),
                .completed(800)
            ])

            let e6 = scheduler.createHotObservable([
                .next(150, 1),
                .next(270, 7),
                .next(470, 14),
                .completed(800)
            ])

            let res = scheduler.start { () -> Observable<Int> in
                factory(e0, e1, e2, e3, e4, e5, e6)
            }

            XCTAssertEqual(res.events, [
                
                .next(270, 28),

                .next(410, 35),
                .next(420, 42),
                .next(430, 49),
                .next(440, 56),
                .next(450, 63),
                .next(460, 70),
                .next(470, 77),
                .completed(800)
                ])


            XCTAssertEqual(e0.subscriptions, [Subscription(200, 800)])

            XCTAssertEqual(e1.subscriptions, [Subscription(200, 800)])

            XCTAssertEqual(e2.subscriptions, [Subscription(200, 800)])

            XCTAssertEqual(e3.subscriptions, [Subscription(200, 800)])

            XCTAssertEqual(e4.subscriptions, [Subscription(200, 800)])

            XCTAssertEqual(e5.subscriptions, [Subscription(200, 800)])

            XCTAssertEqual(e6.subscriptions, [Subscription(200, 800)])

        }
    }




    // 8

    func testCombineLatest_Never8() {
        let factories: [(TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>) -> Observable<Int>] =
            [
                { e0, e1, e2, e3, e4, e5, e6, e7 in
                    Observable.combineLatest(e0, e1, e2, e3, e4, e5, e6, e7) { (_, _, _, _, _, _, _, _) -> Int in
                        return (42)
                    }
                },
                { e0, e1, e2, e3, e4, e5, e6, e7 in
                    Observable.combineLatest(e0, e1, e2, e3, e4, e5, e6, e7).map { (_, _, _, _, _, _, _, _) -> Int in
                        return (42)
                    }
                },
            ]
        for factory in factories {
            let scheduler = TestScheduler(initialClock: 0)


            let e0 = scheduler.createHotObservable([
                .next(150, 1)
            ])

            let e1 = scheduler.createHotObservable([
                .next(150, 1)
            ])

            let e2 = scheduler.createHotObservable([
                .next(150, 1)
            ])

            let e3 = scheduler.createHotObservable([
                .next(150, 1)
            ])

            let e4 = scheduler.createHotObservable([
                .next(150, 1)
            ])

            let e5 = scheduler.createHotObservable([
                .next(150, 1)
            ])

            let e6 = scheduler.createHotObservable([
                .next(150, 1)
            ])

            let e7 = scheduler.createHotObservable([
                .next(150, 1)
            ])


            let res = scheduler.start { () -> Observable<Int> in
                factory(e0, e1, e2, e3, e4, e5, e6, e7)
            }
            
            XCTAssertEqual(res.events, [])
            
            let subscriptions = [Subscription(200, 1000)]
            

            XCTAssertEqual(e0.subscriptions, subscriptions)
            XCTAssertEqual(e1.subscriptions, subscriptions)
            XCTAssertEqual(e2.subscriptions, subscriptions)
            XCTAssertEqual(e3.subscriptions, subscriptions)
            XCTAssertEqual(e4.subscriptions, subscriptions)
            XCTAssertEqual(e5.subscriptions, subscriptions)
            XCTAssertEqual(e6.subscriptions, subscriptions)
            XCTAssertEqual(e7.subscriptions, subscriptions)
        }
    }

    func testCombineLatest_Empty8() {
        let factories: [(TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>) -> Observable<Int>] =
            [
                { e0, e1, e2, e3, e4, e5, e6, e7 in
                    Observable.combineLatest(e0, e1, e2, e3, e4, e5, e6, e7) { (_, _, _, _, _, _, _, _) -> Int in
                        return (42)
                    }
                },
                { e0, e1, e2, e3, e4, e5, e6, e7 in
                    Observable.combineLatest(e0, e1, e2, e3, e4, e5, e6, e7).map { (_, _, _, _, _, _, _, _) -> Int in
                        return (42)
                    }
                },
            ]

        for factory in factories {
            let scheduler = TestScheduler(initialClock: 0)


            let e0 = scheduler.createHotObservable([
                .next(150, 1),
                .completed(210)
            ])

            let e1 = scheduler.createHotObservable([
                .next(150, 1),
                .completed(220)
            ])

            let e2 = scheduler.createHotObservable([
                .next(150, 1),
                .completed(230)
            ])

            let e3 = scheduler.createHotObservable([
                .next(150, 1),
                .completed(240)
            ])

            let e4 = scheduler.createHotObservable([
                .next(150, 1),
                .completed(250)
            ])

            let e5 = scheduler.createHotObservable([
                .next(150, 1),
                .completed(260)
            ])

            let e6 = scheduler.createHotObservable([
                .next(150, 1),
                .completed(270)
            ])

            let e7 = scheduler.createHotObservable([
                .next(150, 1),
                .completed(280)
            ])


            let res = scheduler.start { () -> Observable<Int> in
                factory(e0, e1, e2, e3, e4, e5, e6, e7)
            }

            XCTAssertEqual(res.events, [.completed(280)])


            XCTAssertEqual(e0.subscriptions, [Subscription(200, 210)])

            XCTAssertEqual(e1.subscriptions, [Subscription(200, 220)])

            XCTAssertEqual(e2.subscriptions, [Subscription(200, 230)])

            XCTAssertEqual(e3.subscriptions, [Subscription(200, 240)])

            XCTAssertEqual(e4.subscriptions, [Subscription(200, 250)])

            XCTAssertEqual(e5.subscriptions, [Subscription(200, 260)])

            XCTAssertEqual(e6.subscriptions, [Subscription(200, 270)])

            XCTAssertEqual(e7.subscriptions, [Subscription(200, 280)])

        }
    }

    func testCombineLatest_SelectorThrows8() {
        let scheduler = TestScheduler(initialClock: 0)


        let e0 = scheduler.createHotObservable([
            .next(150, 1),
            .next(210, 1),
            .completed(400)
        ])

        let e1 = scheduler.createHotObservable([
            .next(150, 1),
            .next(220, 2),
            .completed(400)
        ])

        let e2 = scheduler.createHotObservable([
            .next(150, 1),
            .next(230, 3),
            .completed(400)
        ])

        let e3 = scheduler.createHotObservable([
            .next(150, 1),
            .next(240, 4),
            .completed(400)
        ])

        let e4 = scheduler.createHotObservable([
            .next(150, 1),
            .next(250, 5),
            .completed(400)
        ])

        let e5 = scheduler.createHotObservable([
            .next(150, 1),
            .next(260, 6),
            .completed(400)
        ])

        let e6 = scheduler.createHotObservable([
            .next(150, 1),
            .next(270, 7),
            .completed(400)
        ])

        let e7 = scheduler.createHotObservable([
            .next(150, 1),
            .next(280, 8),
            .completed(400)
        ])


        let res = scheduler.start { () -> Observable<Int> in
            Observable.combineLatest(e0, e1, e2, e3, e4, e5, e6, e7) { (_, _, _, _, _, _, _, _) throws -> Int in
                throw testError
            }
        }

        XCTAssertEqual(res.events, [
            .error(280, testError)
        ])


        XCTAssertEqual(e0.subscriptions, [Subscription(200, 280)])

        XCTAssertEqual(e1.subscriptions, [Subscription(200, 280)])

        XCTAssertEqual(e2.subscriptions, [Subscription(200, 280)])

        XCTAssertEqual(e3.subscriptions, [Subscription(200, 280)])

        XCTAssertEqual(e4.subscriptions, [Subscription(200, 280)])

        XCTAssertEqual(e5.subscriptions, [Subscription(200, 280)])

        XCTAssertEqual(e6.subscriptions, [Subscription(200, 280)])

        XCTAssertEqual(e7.subscriptions, [Subscription(200, 280)])

    }

    func testCombineLatest_WillNeverBeAbleToCombine8() {
        let factories: [(TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>) -> Observable<Int>] =
            [
                { e0, e1, e2, e3, e4, e5, e6, e7 in
                    Observable.combineLatest(e0, e1, e2, e3, e4, e5, e6, e7) { (_, _, _, _, _, _, _, _) -> Int in
                        return (42)
                    }
                },
                { e0, e1, e2, e3, e4, e5, e6, e7 in
                    Observable.combineLatest(e0, e1, e2, e3, e4, e5, e6, e7).map { (_, _, _, _, _, _, _, _) -> Int in
                        return (42)
                    }
                },
            ]
        for factory in factories {
            let scheduler = TestScheduler(initialClock: 0)
        

            let e0 = scheduler.createHotObservable([
                .next(150, 1),
                .completed(250)
            ])

            let e1 = scheduler.createHotObservable([
                .next(150, 1),
                .completed(260)
            ])

            let e2 = scheduler.createHotObservable([
                .next(150, 1),
                .completed(270)
            ])

            let e3 = scheduler.createHotObservable([
                .next(150, 1),
                .completed(280)
            ])

            let e4 = scheduler.createHotObservable([
                .next(150, 1),
                .completed(290)
            ])

            let e5 = scheduler.createHotObservable([
                .next(150, 1),
                .completed(300)
            ])

            let e6 = scheduler.createHotObservable([
                .next(150, 1),
                .completed(310)
            ])

            let e7 = scheduler.createHotObservable([
                .next(150, 1),
                .next(500, 2),
                .completed(800)
            ])

            let res = scheduler.start { () -> Observable<Int> in
                factory(e0, e1, e2, e3, e4, e5, e6, e7)
            }

            XCTAssertEqual(res.events, [
                .completed(500)
            ])


            XCTAssertEqual(e0.subscriptions, [Subscription(200, 250)])

            XCTAssertEqual(e1.subscriptions, [Subscription(200, 260)])

            XCTAssertEqual(e2.subscriptions, [Subscription(200, 270)])

            XCTAssertEqual(e3.subscriptions, [Subscription(200, 280)])

            XCTAssertEqual(e4.subscriptions, [Subscription(200, 290)])

            XCTAssertEqual(e5.subscriptions, [Subscription(200, 300)])

            XCTAssertEqual(e6.subscriptions, [Subscription(200, 310)])

            XCTAssertEqual(e7.subscriptions, [Subscription(200, 500)])
        }
    }
    
    func testCombineLatest_Typical8() {
        let factories: [(TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>, TestableObservable<Int>) -> Observable<Int>] =
            [
                { e0, e1, e2, e3, e4, e5, e6, e7 in
                    Observable.combineLatest(e0, e1, e2, e3, e4, e5, e6, e7) { (e0: Int, e1: Int, e2: Int, e3: Int, e4: Int, e5: Int, e6: Int, e7: Int) -> Int in
                        return (e0 + e1 + e2 + e3 + e4 + e5 + e6 + e7)
                    }
                },
                { e0, e1, e2, e3, e4, e5, e6, e7 in
                    Observable.combineLatest(e0, e1, e2, e3, e4, e5, e6, e7).map { (e0: Int, e1: Int, e2: Int, e3: Int, e4: Int, e5: Int, e6: Int, e7: Int) -> Int in
                        return (e0 + e1 + e2 + e3 + e4 + e5 + e6 + e7)
                    }
                },
            ]
        for factory in factories {
            let scheduler = TestScheduler(initialClock: 0)


            let e0 = scheduler.createHotObservable([
                .next(150, 1),
                .next(210, 1),
                .next(410, 9),
                .completed(800)
            ])

            let e1 = scheduler.createHotObservable([
                .next(150, 1),
                .next(220, 2),
                .next(420, 10),
                .completed(800)
            ])

            let e2 = scheduler.createHotObservable([
                .next(150, 1),
                .next(230, 3),
                .next(430, 11),
                .completed(800)
            ])

            let e3 = scheduler.createHotObservable([
                .next(150, 1),
                .next(240, 4),
                .next(440, 12),
                .completed(800)
            ])

            let e4 = scheduler.createHotObservable([
                .next(150, 1),
                .next(250, 5),
                .next(450, 13),
                .completed(800)
            ])

            let e5 = scheduler.createHotObservable([
                .next(150, 1),
                .next(260, 6),
                .next(460, 14),
                .completed(800)
            ])

            let e6 = scheduler.createHotObservable([
                .next(150, 1),
                .next(270, 7),
                .next(470, 15),
                .completed(800)
            ])

            let e7 = scheduler.createHotObservable([
                .next(150, 1),
                .next(280, 8),
                .next(480, 16),
                .completed(800)
            ])

            let res = scheduler.start { () -> Observable<Int> in
                factory(e0, e1, e2, e3, e4, e5, e6, e7)
            }

            XCTAssertEqual(res.events, [
                
                .next(280, 36),

                .next(410, 44),
                .next(420, 52),
                .next(430, 60),
                .next(440, 68),
                .next(450, 76),
                .next(460, 84),
                .next(470, 92),
                .next(480, 100),
                .completed(800)
                ])


            XCTAssertEqual(e0.subscriptions, [Subscription(200, 800)])

            XCTAssertEqual(e1.subscriptions, [Subscription(200, 800)])

            XCTAssertEqual(e2.subscriptions, [Subscription(200, 800)])

            XCTAssertEqual(e3.subscriptions, [Subscription(200, 800)])

            XCTAssertEqual(e4.subscriptions, [Subscription(200, 800)])

            XCTAssertEqual(e5.subscriptions, [Subscription(200, 800)])

            XCTAssertEqual(e6.subscriptions, [Subscription(200, 800)])

            XCTAssertEqual(e7.subscriptions, [Subscription(200, 800)])

        }
    }




}
