Skip to content

Instantly share code, notes, and snippets.

@danielt1263
Last active March 14, 2023 12:34
Show Gist options
  • Save danielt1263/19966e573d5381422e454e6944d387c2 to your computer and use it in GitHub Desktop.
Save danielt1263/19966e573d5381422e454e6944d387c2 to your computer and use it in GitHub Desktop.
// uses https://gist.github.com/danielt1263/bd449100764e3166644f7a38bca86c96
import RxSwift
import RxTest
import XCTest
final class ExampleTests: XCTestCase {
func test_merge_second_finishes_faster() {
let scheduler = TestScheduler(initialClock: 0)
let args = scheduler.createObserver(Device.self)
let service = MockService(mock: scheduler.mock(args: args, timelineSelector: { device in
["---|", "--|"][device.id]
}))
let devices = [Device(id: 0), Device(id: 1)]
let result = scheduler.start {
mergeExample(service: service, devices: devices)
}
XCTAssertEqual(args.events, [.next(100, Device(id: 0)), .next(100, Device(id: 1))])
XCTAssertEqual(result.events, [.next(201, Device(id: 1)), .completed(201)])
}
func test_concat_second_finishes_faster() {
let scheduler = TestScheduler(initialClock: 0)
let args = scheduler.createObserver(Device.self)
let service = MockService(mock: scheduler.mock(args: args, timelineSelector: { device in
["---|", "--|"][device.id]
}))
let devices = [Device(id: 0), Device(id: 1)]
let result = scheduler.start {
concatExample(service: service, devices: devices)
}
XCTAssertEqual(args.events, [.next(100, Device(id: 0)), .next(100, Device(id: 1))])
XCTAssertEqual(result.events, [.next(202, Device(id: 0)), .completed(202)])
}
func test_concat_both_error() {
let scheduler = TestScheduler(initialClock: 0)
let args = scheduler.createObserver(Device.self)
let service = MockService(mock: scheduler.mock(args: args, timelineSelector: { device in
["---#", "--#"][device.id]
}))
let devices = [Device(id: 0), Device(id: 1)]
let result = scheduler.start {
concatExample(service: service, devices: devices)
}
XCTAssertEqual(args.events, [.next(100, Device(id: 0)), .next(100, Device(id: 1))])
XCTAssertEqual(result.events, [.error(205, AllFail())])
}
func test_concat_second_errors() {
let scheduler = TestScheduler(initialClock: 0)
let args = scheduler.createObserver(Device.self)
let service = MockService(mock: scheduler.mock(args: args, timelineSelector: { device in
["---|", "--#"][device.id]
}))
let devices = [Device(id: 0), Device(id: 1)]
let result = scheduler.start {
concatExample(service: service, devices: devices)
}
XCTAssertEqual(args.events, [.next(100, Device(id: 0)), .next(100, Device(id: 1))])
XCTAssertEqual(result.events, [.next(202, Device(id: 0)), .completed(202)])
}
func test_concat_first_errors() {
let scheduler = TestScheduler(initialClock: 0)
let args = scheduler.createObserver(Device.self)
let service = MockService(mock: scheduler.mock(args: args, timelineSelector: { device in
["---#", "--|"][device.id]
}))
let devices = [Device(id: 0), Device(id: 1)]
let result = scheduler.start {
concatExample(service: service, devices: devices)
}
XCTAssertEqual(args.events, [.next(100, Device(id: 0)), .next(100, Device(id: 1))])
XCTAssertEqual(result.events, [.next(204, Device(id: 1)), .completed(204)])
}
func test_concat_first_two_error() {
let scheduler = TestScheduler(initialClock: 0)
let args = scheduler.createObserver(Device.self)
let service = MockService(mock: scheduler.mock(args: args, timelineSelector: { device in
["---#", "--#", "--|"][device.id]
}))
let devices = [Device(id: 0), Device(id: 1), Device(id: 2)]
let result = scheduler.start {
concatExample(service: service, devices: devices)
}
XCTAssertEqual(args.events, [.next(100, Device(id: 0)), .next(100, Device(id: 1)), .next(100, Device(id: 2))])
XCTAssertEqual(result.events, [.next(206, Device(id: 2)), .completed(206)])
}
}
struct MockService: Service {
let mock: (Device) -> Observable<String>
func connectTo(device: Device) -> Completable {
mock(device).ignoreElements().asCompletable()
}
}
//--------------------------
protocol Service { func connectTo(device: Device) -> Completable }
struct Device: Equatable { let id: Int }
struct AllFail: Error { }
extension Service {
func connections(devices: [Device]) -> [Observable<Device>] {
devices.map { device in
self.connectTo(device: device)
.andThen(.just(device))
.catch { _ in .empty() }
}
}
}
func mergeExample(service: Service, devices: [Device]) -> Observable<Device> {
Observable.merge(service.connections(devices: devices))
.take(1)
.ifEmpty(switchTo: .error(AllFail()))
}
func concatExample(service: Service, devices: [Device]) -> Observable<Device> {
Observable.concat(service.connections(devices: devices))
.take(1)
.ifEmpty(switchTo: .error(AllFail()))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment