Skip to content

Commit

Permalink
Return 'first' operator
Browse files Browse the repository at this point in the history
  • Loading branch information
Alexey Potemkin authored and freak4pc committed Mar 8, 2019
1 parent 9d80c54 commit eac7083
Show file tree
Hide file tree
Showing 4 changed files with 154 additions and 0 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Expand Up @@ -4,6 +4,8 @@ All notable changes to this project will be documented in this file.
---
## Master

* Returns `first` operator to ObservableType.

## [4.4.1](https://github.com/ReactiveX/RxSwift/releases/tag/4.4.1)

* Adds `takeUntil(_ behavior:predicate:)`.
Expand Down
12 changes: 12 additions & 0 deletions RxSwift/Traits/ObservableType+PrimitiveSequence.swift
Expand Up @@ -18,6 +18,18 @@ extension ObservableType {
public func asSingle() -> Single<E> {
return PrimitiveSequence(raw: AsSingle(source: self.asObservable()))
}

/**
The `first` operator emits only the very first item emitted by this Observable,
or nil if this Observable completes without emitting anything.
- seealso: [single operator on reactivex.io](http://reactivex.io/documentation/operators/first.html)
- returns: An observable sequence that emits a single element or nil if the source observable sequence completes without emitting any items.
*/
public func first() -> Single<E?> {
return PrimitiveSequence(raw: First(source: self.asObservable()))
}

/**
The `asMaybe` operator throws a `RxError.moreThanOneElement`
Expand Down
5 changes: 5 additions & 0 deletions Sources/AllTestz/main.swift
Expand Up @@ -1071,6 +1071,11 @@ final class ObservablePrimitiveSequenceTest_ : ObservablePrimitiveSequenceTest,
("testAsSingle_Error2", ObservablePrimitiveSequenceTest.testAsSingle_Error2),
("testAsSingle_subscribeOnSuccess", ObservablePrimitiveSequenceTest.testAsSingle_subscribeOnSuccess),
("testAsSingle_subscribeOnError", ObservablePrimitiveSequenceTest.testAsSingle_subscribeOnError),
("testFirst_Empty", ObservablePrimitiveSequenceTest.testFirst_Empty),
("testFirst_One", ObservablePrimitiveSequenceTest.testFirst_One),
("testFirst_Many", ObservablePrimitiveSequenceTest.testFirst_Many),
("testFirst_ManyWithoutCompletion", ObservablePrimitiveSequenceTest.testFirst_ManyWithoutCompletion),
("testFirst_Error", ObservablePrimitiveSequenceTest.testFirst_Error),
("testAsMaybe_Empty", ObservablePrimitiveSequenceTest.testAsMaybe_Empty),
("testAsMaybe_One", ObservablePrimitiveSequenceTest.testAsMaybe_One),
("testAsMaybe_Many", ObservablePrimitiveSequenceTest.testAsMaybe_Many),
Expand Down
135 changes: 135 additions & 0 deletions Tests/RxSwiftTests/Observable+PrimitiveSequenceTest.swift
Expand Up @@ -172,6 +172,141 @@ extension ObservablePrimitiveSequenceTest {
#endif
}

extension ObservablePrimitiveSequenceTest {
func testFirst_Empty() {
let scheduler = TestScheduler(initialClock: 0)

let xs = scheduler.createHotObservable([
next(150, 1),
completed(250),
error(260, testError)
])

let res: TestableObserver<Int> = scheduler.start { () -> Observable<Int> in
let single: Single<Int> = xs.first().map { $0 ?? -1 }
return single.asObservable()
}

XCTAssertEqual(res.events, [
next(250, -1),
completed(250)
])

XCTAssertEqual(xs.subscriptions, [
Subscription(200, 250)
])
}

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

let xs = scheduler.createHotObservable([
next(150, 1),
next(210, 2),
completed(250),
error(260, testError)
])

let res = scheduler.start { () -> Observable<Int> in
let single: Single<Int> = xs.first().map { $0 ?? -1 }
return single.asObservable()
}

XCTAssertEqual(res.events, [
next(210, 2),
completed(210)
])

XCTAssertEqual(xs.subscriptions, [
Subscription(200, 210)
])
}

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

let xs = scheduler.createHotObservable([
next(150, 1),
next(210, 2),
next(220, 3),
completed(250),
error(260, testError)
])

let res = scheduler.start { () -> Observable<Int> in
let single: Single<Int> = xs.first().map { $0 ?? -1 }
return single.asObservable()
}

XCTAssertEqual(res.events, [
next(210, 2),
completed(210)
])

XCTAssertEqual(xs.subscriptions, [
Subscription(200, 210)
])
}

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

let xs = scheduler.createHotObservable([
next(150, 1),
next(160, 2),
next(280, 3),
next(250, 4),
next(300, 5)
])

let res = scheduler.start { () -> Observable<Int> in
let single: Single<Int> = xs.first().map { $0 ?? -1 }
return single.asObservable()
}

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

XCTAssertEqual(xs.subscriptions, [
Subscription(200, 250)
])
}

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

let xs = scheduler.createHotObservable([
next(150, 1),
error(210, testError)
])

let res = scheduler.start { () -> Observable<Int> in
let single: Single<Int> = xs.first().map { $0 ?? -1 }
return single.asObservable()
}

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

XCTAssertEqual(xs.subscriptions, [
Subscription(200, 210)
])
}

#if TRACE_RESOURCES
func testFirstReleasesResourcesOnComplete() {
_ = Observable<Int>.just(1).first().subscribe({ _ in })
}

func testFirstReleasesResourcesOnError1() {
_ = Observable<Int>.error(testError).first().subscribe({ _ in })
}
#endif
}

extension ObservablePrimitiveSequenceTest {
func testAsMaybe_Empty() {
let scheduler = TestScheduler(initialClock: 0)
Expand Down

0 comments on commit eac7083

Please sign in to comment.