Adds `BlockingObservable`.

This commit is contained in:
Krunoslav Zaher 2015-10-19 20:28:49 +02:00
parent c50f5043d5
commit 93e2a927c1
7 changed files with 107 additions and 34 deletions

View File

@ -246,8 +246,8 @@
C8093F4E1B8A732E0088E94D /* NSTextField+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8093ECA1B8A732E0088E94D /* NSTextField+Rx.swift */; };
C8093F4F1B8A732E0088E94D /* RxCocoa.h in Headers */ = {isa = PBXBuildFile; fileRef = C8093ECB1B8A732E0088E94D /* RxCocoa.h */; settings = {ATTRIBUTES = (Public, ); }; };
C8093F501B8A732E0088E94D /* RxCocoa.h in Headers */ = {isa = PBXBuildFile; fileRef = C8093ECB1B8A732E0088E94D /* RxCocoa.h */; settings = {ATTRIBUTES = (Public, ); }; };
C8093F5E1B8A73A20088E94D /* Observable+Blocking.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8093F581B8A73A20088E94D /* Observable+Blocking.swift */; };
C8093F5F1B8A73A20088E94D /* Observable+Blocking.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8093F581B8A73A20088E94D /* Observable+Blocking.swift */; };
C8093F5E1B8A73A20088E94D /* ObservableConvertibleType+Blocking.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8093F581B8A73A20088E94D /* ObservableConvertibleType+Blocking.swift */; };
C8093F5F1B8A73A20088E94D /* ObservableConvertibleType+Blocking.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8093F581B8A73A20088E94D /* ObservableConvertibleType+Blocking.swift */; };
C80D338F1B91EF9E0014629D /* Observable+Bind.swift in Sources */ = {isa = PBXBuildFile; fileRef = C80D338E1B91EF9E0014629D /* Observable+Bind.swift */; };
C80D33901B91EF9E0014629D /* Observable+Bind.swift in Sources */ = {isa = PBXBuildFile; fileRef = C80D338E1B91EF9E0014629D /* Observable+Bind.swift */; };
C80D33981B922FB00014629D /* ControlEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = C80D33931B922FB00014629D /* ControlEvent.swift */; };
@ -328,6 +328,14 @@
C88254341B8A752B00B02D69 /* UITableView+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = C88254121B8A752B00B02D69 /* UITableView+Rx.swift */; };
C88254351B8A752B00B02D69 /* UITextField+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = C88254131B8A752B00B02D69 /* UITextField+Rx.swift */; };
C88254361B8A752B00B02D69 /* UITextView+Rx.swift in Sources */ = {isa = PBXBuildFile; fileRef = C88254141B8A752B00B02D69 /* UITextView+Rx.swift */; };
C8941BDF1BD5695C00A0E874 /* BlockingObservable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8941BDE1BD5695C00A0E874 /* BlockingObservable.swift */; };
C8941BE01BD5695C00A0E874 /* BlockingObservable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8941BDE1BD5695C00A0E874 /* BlockingObservable.swift */; };
C8941BE11BD5695C00A0E874 /* BlockingObservable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8941BDE1BD5695C00A0E874 /* BlockingObservable.swift */; };
C8941BE21BD5695C00A0E874 /* BlockingObservable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8941BDE1BD5695C00A0E874 /* BlockingObservable.swift */; };
C8941BE41BD56B0700A0E874 /* BlockingObservable+Operators.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8941BE31BD56B0700A0E874 /* BlockingObservable+Operators.swift */; };
C8941BE51BD56B0700A0E874 /* BlockingObservable+Operators.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8941BE31BD56B0700A0E874 /* BlockingObservable+Operators.swift */; };
C8941BE61BD56B0700A0E874 /* BlockingObservable+Operators.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8941BE31BD56B0700A0E874 /* BlockingObservable+Operators.swift */; };
C8941BE71BD56B0700A0E874 /* BlockingObservable+Operators.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8941BE31BD56B0700A0E874 /* BlockingObservable+Operators.swift */; };
C89461751BC6C1210055219D /* ObservableConvertibleType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C849BE2A1BAB5D070019AD27 /* ObservableConvertibleType.swift */; };
C89461761BC6C1220055219D /* ObservableConvertibleType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C849BE2A1BAB5D070019AD27 /* ObservableConvertibleType.swift */; };
C89CDB361BCB0DD7002063D9 /* ShareReplay1.swift in Sources */ = {isa = PBXBuildFile; fileRef = C89CDB351BCB0DD7002063D9 /* ShareReplay1.swift */; };
@ -522,7 +530,7 @@
C8F0C0431BBBFBB9001B112F /* _RX.h in Headers */ = {isa = PBXBuildFile; fileRef = C8093E821B8A732E0088E94D /* _RX.h */; settings = {ATTRIBUTES = (Public, ); }; };
C8F0C0441BBBFBB9001B112F /* _RXSwizzling.h in Headers */ = {isa = PBXBuildFile; fileRef = C8093E881B8A732E0088E94D /* _RXSwizzling.h */; settings = {ATTRIBUTES = (Public, ); }; };
C8F0C0451BBBFBB9001B112F /* _RXKVOObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = C8093E861B8A732E0088E94D /* _RXKVOObserver.h */; settings = {ATTRIBUTES = (Public, ); }; };
C8F0C04F1BBBFBCE001B112F /* Observable+Blocking.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8093F581B8A73A20088E94D /* Observable+Blocking.swift */; };
C8F0C04F1BBBFBCE001B112F /* ObservableConvertibleType+Blocking.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8093F581B8A73A20088E94D /* ObservableConvertibleType+Blocking.swift */; };
D203C4F31BB9C4CA00D02D00 /* RxCollectionViewReactiveArrayDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = C88253F11B8A752B00B02D69 /* RxCollectionViewReactiveArrayDataSource.swift */; };
D203C4F41BB9C52400D02D00 /* RxTableViewReactiveArrayDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = C88253F21B8A752B00B02D69 /* RxTableViewReactiveArrayDataSource.swift */; };
D203C4F51BB9C52900D02D00 /* ItemEvents.swift in Sources */ = {isa = PBXBuildFile; fileRef = C88253F41B8A752B00B02D69 /* ItemEvents.swift */; };
@ -698,7 +706,7 @@
D2EBEB421BB9B6DE003A27DC /* ReplaySubject.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8093CC01B8A72BE0088E94D /* ReplaySubject.swift */; };
D2EBEB431BB9B6DE003A27DC /* SubjectType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8093CC11B8A72BE0088E94D /* SubjectType.swift */; };
D2EBEB441BB9B6DE003A27DC /* Variable.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8093CC21B8A72BE0088E94D /* Variable.swift */; };
D2EBEB8A1BB9B9EE003A27DC /* Observable+Blocking.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8093F581B8A73A20088E94D /* Observable+Blocking.swift */; };
D2EBEB8A1BB9B9EE003A27DC /* ObservableConvertibleType+Blocking.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8093F581B8A73A20088E94D /* ObservableConvertibleType+Blocking.swift */; };
D2FC15B31BCB95E5007361FF /* SkipWhile.swift in Sources */ = {isa = PBXBuildFile; fileRef = D22B6D251BC8504A00BCE0AB /* SkipWhile.swift */; };
D2FC15B41BCB95E7007361FF /* SkipWhile.swift in Sources */ = {isa = PBXBuildFile; fileRef = D22B6D251BC8504A00BCE0AB /* SkipWhile.swift */; };
D2FC15B51BCB95E8007361FF /* SkipWhile.swift in Sources */ = {isa = PBXBuildFile; fileRef = D22B6D251BC8504A00BCE0AB /* SkipWhile.swift */; };
@ -897,7 +905,7 @@
C8093EC91B8A732E0088E94D /* NSSlider+Rx.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSSlider+Rx.swift"; sourceTree = "<group>"; };
C8093ECA1B8A732E0088E94D /* NSTextField+Rx.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = "NSTextField+Rx.swift"; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
C8093ECB1B8A732E0088E94D /* RxCocoa.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RxCocoa.h; sourceTree = "<group>"; };
C8093F581B8A73A20088E94D /* Observable+Blocking.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Observable+Blocking.swift"; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
C8093F581B8A73A20088E94D /* ObservableConvertibleType+Blocking.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "ObservableConvertibleType+Blocking.swift"; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
C8093F591B8A73A20088E94D /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
C80D338E1B91EF9E0014629D /* Observable+Bind.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Observable+Bind.swift"; sourceTree = "<group>"; };
C80D33931B922FB00014629D /* ControlEvent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ControlEvent.swift; sourceTree = "<group>"; };
@ -950,6 +958,8 @@
C88254131B8A752B00B02D69 /* UITextField+Rx.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UITextField+Rx.swift"; sourceTree = "<group>"; };
C88254141B8A752B00B02D69 /* UITextView+Rx.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UITextView+Rx.swift"; sourceTree = "<group>"; };
C88BB8711B07E5ED0064D411 /* RxSwift.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = RxSwift.framework; sourceTree = BUILT_PRODUCTS_DIR; };
C8941BDE1BD5695C00A0E874 /* BlockingObservable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BlockingObservable.swift; sourceTree = "<group>"; };
C8941BE31BD56B0700A0E874 /* BlockingObservable+Operators.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "BlockingObservable+Operators.swift"; sourceTree = "<group>"; };
C89CDB351BCB0DD7002063D9 /* ShareReplay1.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = ShareReplay1.swift; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
C8A56AD71AD7424700B4673B /* RxSwift.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = RxSwift.framework; sourceTree = BUILT_PRODUCTS_DIR; };
C8B144FA1BD2D44500267DCE /* ConcurrentMainScheduler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConcurrentMainScheduler.swift; sourceTree = "<group>"; };
@ -1333,7 +1343,9 @@
isa = PBXGroup;
children = (
A111CE961B91C97C00D0DCEE /* Info.plist */,
C8093F581B8A73A20088E94D /* Observable+Blocking.swift */,
C8093F581B8A73A20088E94D /* ObservableConvertibleType+Blocking.swift */,
C8941BDE1BD5695C00A0E874 /* BlockingObservable.swift */,
C8941BE31BD56B0700A0E874 /* BlockingObservable+Operators.swift */,
C8093F591B8A73A20088E94D /* README.md */,
);
path = RxBlocking;
@ -2055,7 +2067,9 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
C8093F5E1B8A73A20088E94D /* Observable+Blocking.swift in Sources */,
C8941BDF1BD5695C00A0E874 /* BlockingObservable.swift in Sources */,
C8941BE41BD56B0700A0E874 /* BlockingObservable+Operators.swift in Sources */,
C8093F5E1B8A73A20088E94D /* ObservableConvertibleType+Blocking.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -2063,7 +2077,9 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
C8093F5F1B8A73A20088E94D /* Observable+Blocking.swift in Sources */,
C8941BE01BD5695C00A0E874 /* BlockingObservable.swift in Sources */,
C8941BE51BD56B0700A0E874 /* BlockingObservable+Operators.swift in Sources */,
C8093F5F1B8A73A20088E94D /* ObservableConvertibleType+Blocking.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -2498,7 +2514,9 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
C8F0C04F1BBBFBCE001B112F /* Observable+Blocking.swift in Sources */,
C8941BE21BD5695C00A0E874 /* BlockingObservable.swift in Sources */,
C8941BE71BD56B0700A0E874 /* BlockingObservable+Operators.swift in Sources */,
C8F0C04F1BBBFBCE001B112F /* ObservableConvertibleType+Blocking.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -2695,7 +2713,9 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
D2EBEB8A1BB9B9EE003A27DC /* Observable+Blocking.swift in Sources */,
C8941BE11BD5695C00A0E874 /* BlockingObservable.swift in Sources */,
C8941BE61BD56B0700A0E874 /* BlockingObservable+Operators.swift in Sources */,
D2EBEB8A1BB9B9EE003A27DC /* ObservableConvertibleType+Blocking.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View File

@ -1,17 +1,17 @@
//
// Observable+Blocking.swift
// RxBlocking
// BlockingObservable+Operators.swift
// Rx
//
// Created by Krunoslav Zaher on 7/12/15.
// Copyright (c) 2015 Krunoslav Zaher. All rights reserved.
// Created by Krunoslav Zaher on 10/19/15.
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
//
import Foundation
#if !RX_NO_MODULE
import RxSwift
import RxSwift
#endif
extension ObservableType {
extension BlockingObservable {
/**
Blocks current thread until sequence terminates.
@ -28,7 +28,7 @@ extension ObservableType {
var ended = false
_ = self.subscribe { e in
_ = self.source.subscribe { e in
switch e {
case .Next(let element):
elements.append(element)
@ -59,7 +59,7 @@ extension ObservableType {
}
}
extension ObservableType {
extension BlockingObservable {
/**
Blocks current thread until sequence produces first element.
@ -78,7 +78,7 @@ extension ObservableType {
let d = SingleAssignmentDisposable()
d.disposable = self.subscribe { e in
d.disposable = self.source.subscribe { e in
switch e {
case .Next(let e):
if element == nil {
@ -112,7 +112,7 @@ extension ObservableType {
}
}
extension ObservableType {
extension BlockingObservable {
/**
Blocks current thread until sequence terminates.
@ -131,7 +131,7 @@ extension ObservableType {
let d = SingleAssignmentDisposable()
d.disposable = self.subscribe { e in
d.disposable = self.source.subscribe { e in
switch e {
case .Next(let e):
element = e

View File

@ -0,0 +1,24 @@
//
// BlockingObservable.swift
// Rx
//
// Created by Krunoslav Zaher on 10/19/15.
// Copyright © 2015 Krunoslav Zaher. All rights reserved.
//
import Foundation
#if !RX_NO_MODULE
import RxSwift
#endif
/**
`BlockingObservable` is a variety of `Observable` that provides blocking operators.
It can be useful for testing and demo purposes, but is generally inappropriate for production applications.
If you think you need to use a `BlockingObservable` this is usually a sign that you should rethink your
design.
*/
public struct BlockingObservable<E> {
let source: Observable<E>
}

View File

@ -0,0 +1,23 @@
//
// Observable+Blocking.swift
// RxBlocking
//
// Created by Krunoslav Zaher on 7/12/15.
// Copyright (c) 2015 Krunoslav Zaher. All rights reserved.
//
import Foundation
#if !RX_NO_MODULE
import RxSwift
#endif
extension ObservableConvertibleType {
/**
Converts an Observable into a `BlockingObservable` (an Observable with blocking operators).
- returns: `BlockingObservable` version of `self`
*/
public func toBlocking() -> BlockingObservable<E> {
return BlockingObservable(source: self.asObservable())
}
}

View File

@ -18,16 +18,16 @@ class ObservableBlockingTest : RxTest {
extension ObservableBlockingTest {
func testToArray_empty() {
XCTAssert(try! (empty() as Observable<Int>).toArray() == [])
XCTAssert(try! (empty() as Observable<Int>).toBlocking().toArray() == [])
}
func testToArray_return() {
XCTAssert(try! just(42).toArray() == [42])
XCTAssert(try! just(42).toBlocking().toArray() == [42])
}
func testToArray_fail() {
do {
try (failWith(testError) as Observable<Int>).toArray()
try (failWith(testError) as Observable<Int>).toBlocking().toArray()
XCTFail("It should fail")
}
catch {
@ -36,7 +36,7 @@ extension ObservableBlockingTest {
}
func testToArray_someData() {
XCTAssert(try! sequenceOf(42, 43, 44, 45).toArray() == [42, 43, 44, 45])
XCTAssert(try! sequenceOf(42, 43, 44, 45).toBlocking().toArray() == [42, 43, 44, 45])
}
func testToArray_withRealScheduler() {
@ -44,6 +44,7 @@ extension ObservableBlockingTest {
let array = try! interval(0.001, scheduler)
.take(10)
.toBlocking()
.toArray()
XCTAssert(array == Array(0..<10))
@ -54,16 +55,16 @@ extension ObservableBlockingTest {
extension ObservableBlockingTest {
func testFirst_empty() {
XCTAssert(try! (empty() as Observable<Int>).first() == nil)
XCTAssert(try! (empty() as Observable<Int>).toBlocking().first() == nil)
}
func testFirst_return() {
XCTAssert(try! just(42).first() == 42)
XCTAssert(try! just(42).toBlocking().first() == 42)
}
func testFirst_fail() {
do {
try (failWith(testError) as Observable<Int>).first()
try (failWith(testError) as Observable<Int>).toBlocking().first()
XCTFail()
}
catch {
@ -72,7 +73,7 @@ extension ObservableBlockingTest {
}
func testFirst_someData() {
XCTAssert(try! sequenceOf(42, 43, 44, 45).first() == 42)
XCTAssert(try! sequenceOf(42, 43, 44, 45).toBlocking().first() == 42)
}
func testFirst_withRealScheduler() {
@ -80,6 +81,7 @@ extension ObservableBlockingTest {
let array = try! interval(0.001, scheduler)
.take(10)
.toBlocking()
.first()
XCTAssert(array == 0)
@ -90,16 +92,16 @@ extension ObservableBlockingTest {
extension ObservableBlockingTest {
func testLast_empty() {
XCTAssert(try! (empty() as Observable<Int>).last() == nil)
XCTAssert(try! (empty() as Observable<Int>).toBlocking().last() == nil)
}
func testLast_return() {
XCTAssert(try! just(42).last() == 42)
XCTAssert(try! just(42).toBlocking().last() == 42)
}
func testLast_fail() {
do {
try (failWith(testError) as Observable<Int>).last()
try (failWith(testError) as Observable<Int>).toBlocking().last()
XCTFail()
}
catch {
@ -108,7 +110,7 @@ extension ObservableBlockingTest {
}
func testLast_someData() {
XCTAssert(try! sequenceOf(42, 43, 44, 45).last() == 45)
XCTAssert(try! sequenceOf(42, 43, 44, 45).toBlocking().last() == 45)
}
func testLast_withRealScheduler() {
@ -116,6 +118,7 @@ extension ObservableBlockingTest {
let array = try! interval(0.001, scheduler)
.take(10)
.toBlocking()
.last()
XCTAssert(array == 9)

View File

@ -370,7 +370,7 @@ class ObservableConcurrentSchedulerConcurrencyTest: ObservableConcurrencyTestBas
scheduler.schedule((), action: concurrent)
try! stop.last()
try! stop.toBlocking().last()
XCTAssertEqual(events, ["Started", "Started", "Ended", "Ended"])
}

View File

@ -264,6 +264,7 @@ extension ObservableTimeTest {
let a = try! [just(0), never()].asObservable().concat()
.throttle(2.0, scheduler)
.toBlocking()
.first()
let end = NSDate()
@ -810,6 +811,7 @@ extension ObservableTimeTest {
let a = try! interval(1, scheduler)
.take(2)
.toBlocking()
.toArray()
let end = NSDate()
@ -1291,6 +1293,7 @@ extension ObservableTimeTest {
let result = try! range(1, 10, backgroundScheduler)
.buffer(timeSpan: 1000, count: 3, scheduler: backgroundScheduler)
.skip(1)
.toBlocking()
.first()
XCTAssertEqual(result!, [4, 5, 6])