diff --git a/RxSwiftUtilities.xcodeproj/project.pbxproj b/RxSwiftUtilities.xcodeproj/project.pbxproj index b98ecc9..cbd8dc6 100644 --- a/RxSwiftUtilities.xcodeproj/project.pbxproj +++ b/RxSwiftUtilities.xcodeproj/project.pbxproj @@ -38,6 +38,7 @@ 88EB631C216B2D2E00130C74 /* TwoWayBinding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88EB631B216B2D2E00130C74 /* TwoWayBinding.swift */; }; 88EB631F216B2E2500130C74 /* TwoWayBindingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 88EB631D216B2E1C00130C74 /* TwoWayBindingTests.swift */; }; 88EB6322216B43F400130C74 /* RxSwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 888CC1901DE4839900DAE48A /* RxSwift.framework */; }; + C07E4F2C22C1A96F00388DEC /* ActivityIndicatorDriverTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C07E4F2B22C1A96F00388DEC /* ActivityIndicatorDriverTests.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -88,6 +89,7 @@ 88E73C611DE481A100C0D2F6 /* RxSwiftUtilities.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = RxSwiftUtilities.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 88EB631B216B2D2E00130C74 /* TwoWayBinding.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TwoWayBinding.swift; sourceTree = ""; }; 88EB631D216B2E1C00130C74 /* TwoWayBindingTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TwoWayBindingTests.swift; sourceTree = ""; }; + C07E4F2B22C1A96F00388DEC /* ActivityIndicatorDriverTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActivityIndicatorDriverTests.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -200,6 +202,7 @@ children = ( 8803436E1DE397170055DA33 /* ActivityIndicatorTests.swift */, 88EB631D216B2E1C00130C74 /* TwoWayBindingTests.swift */, + C07E4F2B22C1A96F00388DEC /* ActivityIndicatorDriverTests.swift */, 880343331DE315B70055DA33 /* Supporting Files */, ); path = Tests; @@ -505,6 +508,7 @@ developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( + English, en, ); mainGroup = 880342FE1DE303160055DA33; @@ -641,6 +645,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + C07E4F2C22C1A96F00388DEC /* ActivityIndicatorDriverTests.swift in Sources */, 88EB631F216B2E2500130C74 /* TwoWayBindingTests.swift in Sources */, 8803436F1DE397170055DA33 /* ActivityIndicatorTests.swift in Sources */, ); diff --git a/Source/Common/ActivityIndicator.swift b/Source/Common/ActivityIndicator.swift index fddba32..0117c03 100644 --- a/Source/Common/ActivityIndicator.swift +++ b/Source/Common/ActivityIndicator.swift @@ -82,3 +82,11 @@ extension ObservableConvertibleType { return activityIndicator.trackActivityOfObservable(self) } } + +extension SharedSequence { + func trackActivity(_ activityIndicator: ActivityIndicator) -> SharedSequence { + let observable: Observable = self.trackActivity(activityIndicator) + return observable + .asSharedSequence(onErrorDriveWith: SharedSequence.empty()) + } +} diff --git a/Tests/ActivityIndicatorDriverTests.swift b/Tests/ActivityIndicatorDriverTests.swift new file mode 100644 index 0000000..949d4c8 --- /dev/null +++ b/Tests/ActivityIndicatorDriverTests.swift @@ -0,0 +1,109 @@ +// +// ActivityIndicatorDriverTests.swift +// RxSwiftUtilitiesTests iOS +// +// Created by Shawn Simon on 2019-06-24. +// Copyright © 2019 RxSwiftCommunity. All rights reserved. +// + +import XCTest +import RxCocoa +import RxSwift +@testable import RxSwiftUtilities + +extension ActivityIndicatorTests { + + func testEmitsTrueWhenTrackingASingleObservable_asDriver() { + let activityIndicator = ActivityIndicator() + var value = false + let _ = activityIndicator.asObservable() + .subscribe(onNext: { value = $0 }) + let _ = Observable.just(1) + .concat(Observable.never()) + .asDriver(onErrorJustReturn: 1) + .trackActivity(activityIndicator) + .drive() + XCTAssertTrue(value) + } + + func testEmitsFalseWhenFinishedTrackingASingleObservable_asDriver() { + let activityIndicator = ActivityIndicator() + var value = true + let _ = activityIndicator.asObservable() + .subscribe(onNext: { value = $0 }) + let subject = BehaviorSubject(value: 1) + let _ = subject.asDriver(onErrorJustReturn: 1) + .trackActivity(activityIndicator) + .subscribe() + subject.onCompleted() + XCTAssertFalse(value) + } + + func testEmitsTrueWhenTrackingMultipleObservables_asDriver() { + let activityIndicator = ActivityIndicator() + var value = false + let _ = activityIndicator.asObservable() + .subscribe(onNext: { value = $0 }) + let _ = Observable.just(1) + .concat(Observable.never()) + .asDriver(onErrorJustReturn: 1) + .trackActivity(activityIndicator) + .drive() + let _ = Observable.just(2) + .concat(Observable.never()) + .asDriver(onErrorJustReturn: 2) + .trackActivity(activityIndicator) + .drive() + XCTAssertTrue(value) + } + + func testDoesNotEmitFalseWhenFinishedTrackingOnlyOneOfMultipleObservables_asDriver() { + let activityIndicator = ActivityIndicator() + var value = false + let _ = activityIndicator.asObservable() + .subscribe(onNext: { value = $0 }) + let subject1 = BehaviorSubject(value: 1) + let _ = subject1.asDriver(onErrorJustReturn: 1) + .trackActivity(activityIndicator) + .drive() + let subject2 = BehaviorSubject(value: 1) + let _ = subject2.asDriver(onErrorJustReturn: 1) + .trackActivity(activityIndicator) + .drive() + subject1.onCompleted() + XCTAssertTrue(value) + } + + func testEmitsFalseWhenFinishedTrackingMultipleObservables_asDriver() { + let activityIndicator = ActivityIndicator() + var value = true + let _ = activityIndicator.asObservable() + .subscribe(onNext: { value = $0 }) + let subject1 = BehaviorSubject(value: 1) + let _ = subject1.asDriver(onErrorJustReturn: 1) + .trackActivity(activityIndicator) + .drive() + let subject2 = BehaviorSubject(value: 1) + let _ = subject2.asDriver(onErrorJustReturn: 1) + .trackActivity(activityIndicator) + .drive() + subject1.onCompleted() + subject2.onCompleted() + XCTAssertFalse(value) + } + + func testEmitsFalseWhenTrackingObservablesAreDisposed_asDriver() { + let activityIndicator = ActivityIndicator() + var value = true + let _ = activityIndicator.asDriver(onErrorJustReturn: false) + .drive(onNext: { value = $0 }) + let disposable = Observable.just(1) + .concat(Observable.never()) + .asDriver(onErrorJustReturn: 1) + .trackActivity(activityIndicator) + .drive() + disposable.dispose() + XCTAssertFalse(value) + } + +}