diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index 5d6ec66..0283b88 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -8,25 +8,21 @@ concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: - unit-tests-ios: + unit-tests: runs-on: blaze/macos-14 strategy: matrix: - # also run for macos - destination: ["platform=iOS Simulator,name=iPhone 15 Pro"] + target: [macos, iOS] + include: + - target: iOS + destination: '-destination "platform=iOS Simulator,name=iPhone 15 Pro"' + - target: macos + destination: '-destination "platform=macOS,name=Any Mac"' steps: - name: Checkout Repo uses: actions/checkout@v2 - name: Run Tests - run: |- - xcodebuild test -scheme SwiftAudioEx -destination "${destination}" -enableCodeCoverage YES - env: - destination: ${{ matrix.destination }} - unit-tests-macos: - runs-on: blaze/macos-14 - steps: - - name: Checkout Repo - uses: actions/checkout@v2 - - name: Run Tests - run: |- - swift test + run: xcodebuild test -scheme SwiftAudioEx ${{ matrix.destination }} -enableCodeCoverage YES + - name: Upload coverage to Codecov + if: matrix.target == 'macos' + uses: codecov/codecov-action@v1.2.1 diff --git a/Sources/SwiftAudioEx/AudioPlayer.swift b/Sources/SwiftAudioEx/AudioPlayer.swift index 4e4d023..966c295 100755 --- a/Sources/SwiftAudioEx/AudioPlayer.swift +++ b/Sources/SwiftAudioEx/AudioPlayer.swift @@ -65,7 +65,7 @@ public class AudioPlayer: AVPlayerWrapperDelegate { try action() - if playWhenReady == true { + if playWhenReady == true, playbackError == nil { self.playWhenReady = true } } diff --git a/Tests/SwiftAudioExTests/AVPlayerWrapperTests.swift b/Tests/SwiftAudioExTests/AVPlayerWrapperTests.swift index cdce809..0117e42 100644 --- a/Tests/SwiftAudioExTests/AVPlayerWrapperTests.swift +++ b/Tests/SwiftAudioExTests/AVPlayerWrapperTests.swift @@ -41,7 +41,7 @@ class AVPlayerWrapperTests: XCTestCase { } } wrapper.load(from: Source.url, playWhenReady: false) - wait(for: [expectation], timeout: 20.0) + wait(for: [expectation], timeout: defaultTimeout) } func testAVPlayerWrapperStateWhenPlayingSourceShouldBePlaying() { @@ -52,7 +52,7 @@ class AVPlayerWrapperTests: XCTestCase { } } wrapper.load(from: Source.url, playWhenReady: true) - wait(for: [expectation], timeout: 20.0) + wait(for: [expectation], timeout: defaultTimeout) } func testAVPlayerWrapperStateWhenPausingSourceShouldBePaused() { @@ -68,7 +68,7 @@ class AVPlayerWrapperTests: XCTestCase { } } wrapper.load(from: Source.url, playWhenReady: true) - wait(for: [expectation], timeout: 20.0) + wait(for: [expectation], timeout: defaultTimeout) } func testAVPlayerWrapperStateWhenTogglingFromPlayShouldBePaused() { @@ -84,7 +84,7 @@ class AVPlayerWrapperTests: XCTestCase { } } wrapper.load(from: Source.url, playWhenReady: true) - wait(for: [expectation], timeout: 20.0) + wait(for: [expectation], timeout: defaultTimeout) } func testAVPlayerWrapperStateWhenStoppingShouldBeStopped() { @@ -100,7 +100,7 @@ class AVPlayerWrapperTests: XCTestCase { } } wrapper.load(from: Source.url, playWhenReady: true) - wait(for: [expectation], timeout: 20.0) + wait(for: [expectation], timeout: defaultTimeout) } func testAVPlayerWrapperStateLoadingWithInitialTimeShouldBePlaying() { @@ -114,7 +114,7 @@ class AVPlayerWrapperTests: XCTestCase { } } wrapper.load(from: LongSource.url, playWhenReady: true, initialTime: 4.0) - wait(for: [expectation], timeout: 20.0) + wait(for: [expectation], timeout: defaultTimeout) } // MARK: - Duration tests @@ -131,7 +131,7 @@ class AVPlayerWrapperTests: XCTestCase { } } wrapper.load(from: Source.url, playWhenReady: false) - wait(for: [expectation], timeout: 20.0) + wait(for: [expectation], timeout: defaultTimeout) } // MARK: - Current time tests @@ -152,7 +152,7 @@ class AVPlayerWrapperTests: XCTestCase { expectation.fulfill() } wrapper.load(from: Source.url, playWhenReady: false) - wait(for: [expectation], timeout: 20.0) + wait(for: [expectation], timeout: defaultTimeout) } func testAVPlayerWrapperSeekingShouldSeekWhileNotYetLoaded() { @@ -163,7 +163,7 @@ class AVPlayerWrapperTests: XCTestCase { } wrapper.load(from: Source.url, playWhenReady: false) wrapper.seek(to: seekTime) - wait(for: [expectation], timeout: 20.0) + wait(for: [expectation], timeout: defaultTimeout) } func testAVPlayerWrapperSeekByShouldSeek() { @@ -176,7 +176,7 @@ class AVPlayerWrapperTests: XCTestCase { expectation.fulfill() } wrapper.load(from: Source.url, playWhenReady: false) - wait(for: [expectation], timeout: 20.0) + wait(for: [expectation], timeout: defaultTimeout) } func testAVPlayerWrapperLoadingSourceWithInitialTimeShouldSeek() { @@ -185,7 +185,7 @@ class AVPlayerWrapperTests: XCTestCase { expectation.fulfill() } wrapper.load(from: LongSource.url, playWhenReady: false, initialTime: 4.0) - wait(for: [expectation], timeout: 20.0) + wait(for: [expectation], timeout: defaultTimeout) } // MARK: - Rate tests @@ -202,7 +202,7 @@ class AVPlayerWrapperTests: XCTestCase { } } wrapper.load(from: Source.url, playWhenReady: true) - wait(for: [expectation], timeout: 20.0) + wait(for: [expectation], timeout: defaultTimeout) } func testAVPlayerWrapperTimeObserverWhenUpdatedShouldUpdateTheObserversPeriodicObserverTimeInterval() { diff --git a/Tests/SwiftAudioExTests/AudioPlayerEventTests.swift b/Tests/SwiftAudioExTests/AudioPlayerEventTests.swift index 4df4099..b8785d8 100644 --- a/Tests/SwiftAudioExTests/AudioPlayerEventTests.swift +++ b/Tests/SwiftAudioExTests/AudioPlayerEventTests.swift @@ -23,7 +23,7 @@ class AudioPlayerEventTests: XCTestCase { func testEventAddListener() { let listener = EventListener() event.addListener(listener, listener.handleEvent) - waitTrue(self.event.invokers.count > 0, timeout: 5) + waitTrue(self.event.invokers.count > 0, timeout: defaultTimeout) } func testEventRemoveListener() { @@ -32,7 +32,7 @@ class AudioPlayerEventTests: XCTestCase { listener = nil event.emit(data: ()) - waitEqual(self.event.invokers.count, 0, timeout: 5) + waitEqual(self.event.invokers.count, 0, timeout: defaultTimeout) } func testEventAddMultipleListeners() { @@ -44,7 +44,7 @@ class AudioPlayerEventTests: XCTestCase { return listener } - waitEqual(self.event.invokers.count, listeners.count, timeout: 5) + waitEqual(self.event.invokers.count, listeners.count, timeout: defaultTimeout) } func testEventRemoveOneListener() { @@ -59,6 +59,6 @@ class AudioPlayerEventTests: XCTestCase { let listenerToRemove = listeners[listeners.count / 2] event.removeListener(listenerToRemove) - waitEqual(self.event.invokers.count, listeners.count - 1, timeout: 5) + waitEqual(self.event.invokers.count, listeners.count - 1, timeout: defaultTimeout) } } diff --git a/Tests/SwiftAudioExTests/AudioPlayerTests.swift b/Tests/SwiftAudioExTests/AudioPlayerTests.swift index f71bb2e..82a8a35 100644 --- a/Tests/SwiftAudioExTests/AudioPlayerTests.swift +++ b/Tests/SwiftAudioExTests/AudioPlayerTests.swift @@ -62,7 +62,7 @@ class AudioPlayerTests: XCTestCase { XCTAssertFalse(audioPlayer.playWhenReady) audioPlayer.load(item: FiveSecondSourceWithInitialTimeOfFourSeconds.getAudioItem()) - wait(for: [expectation], timeout: 5) + wait(for: [expectation], timeout: defaultTimeout) XCTAssertTrue(seekCompleted) XCTAssertTrue(audioPlayer.currentTime >= 4) @@ -72,7 +72,7 @@ class AudioPlayerTests: XCTestCase { func testSetDurationAfterLoading() { audioPlayer.load(item: FiveSecondSource.getAudioItem()) - waitEqual(self.audioPlayer.duration, 5, accuracy: 0.1, timeout: 5) + waitEqual(self.audioPlayer.duration, 5, accuracy: 0.1, timeout: defaultTimeout) } func testOnUpdateDurationReceivedAfterLoading() { @@ -87,7 +87,7 @@ class AudioPlayerTests: XCTestCase { audioPlayer.load(item: FiveSecondSource.getAudioItem()) - wait(for: [expectation], timeout: 5) // Adjust the timeout as needed + wait(for: [expectation], timeout: defaultTimeout) // Adjust the timeout as needed XCTAssertTrue(receivedUpdateDuration) } @@ -95,17 +95,17 @@ class AudioPlayerTests: XCTestCase { func testResetDurationAfterLoadingAgain() { audioPlayer.load(item: FiveSecondSource.getAudioItem()) XCTAssertEqual(audioPlayer.duration, 0) - waitEqual(self.audioPlayer.duration, 5, accuracy: 0.1, timeout: 5) + waitEqual(self.audioPlayer.duration, 5, accuracy: 0.1, timeout: defaultTimeout) audioPlayer.load(item: FiveSecondSource.getAudioItem()) XCTAssertEqual(audioPlayer.duration, 0) - waitEqual(self.audioPlayer.duration, 5, accuracy: 0.1, timeout: 5) + waitEqual(self.audioPlayer.duration, 5, accuracy: 0.1, timeout: defaultTimeout) } func testResetDurationAfterReset() { audioPlayer.load(item: FiveSecondSource.getAudioItem()) XCTAssertEqual(audioPlayer.duration, 0) - waitEqual(self.audioPlayer.duration, 5, accuracy: 0.1, timeout: 5) + waitEqual(self.audioPlayer.duration, 5, accuracy: 0.1, timeout: defaultTimeout) audioPlayer.clear() XCTAssertEqual(audioPlayer.duration, 0) } @@ -130,7 +130,7 @@ class AudioPlayerTests: XCTestCase { ) audioPlayer.load(item: item, playWhenReady: true) - wait(for: [expectation], timeout: 5) // Adjust the timeout as needed + wait(for: [expectation], timeout: defaultTimeout) // Adjust the timeout as needed XCTAssertNotNil(audioPlayer.playbackError) XCTAssertEqual(audioPlayer.playerState, .failed) @@ -168,10 +168,10 @@ class AudioPlayerTests: XCTestCase { ) audioPlayer.load(item: item, playWhenReady: true) - waitEqual(self.playerStateEventListener.statesWithoutBuffering, [.loading, .failed], timeout: 5) + waitEqual(self.playerStateEventListener.statesWithoutBuffering, [.loading, .failed], timeout: defaultTimeout) audioPlayer.play() - waitEqual(self.playerStateEventListener.statesWithoutBuffering, [.loading, .failed, .loading, .failed], timeout: 5) + waitEqual(self.playerStateEventListener.statesWithoutBuffering, [.loading, .failed, .loading, .failed], timeout: defaultTimeout) } func testRetryLoadingAfterFailureWithPlayWhenReady() { @@ -185,10 +185,10 @@ class AudioPlayerTests: XCTestCase { ) audioPlayer.load(item: item, playWhenReady: true) - waitEqual(self.playerStateEventListener.statesWithoutBuffering, [.loading, .failed], timeout: 5) + waitEqual(self.playerStateEventListener.statesWithoutBuffering, [.loading, .failed], timeout: defaultTimeout) audioPlayer.playWhenReady = true - waitEqual(self.playerStateEventListener.statesWithoutBuffering, [.loading, .failed, .loading, .failed], timeout: 5) + waitEqual(self.playerStateEventListener.statesWithoutBuffering, [.loading, .failed, .loading, .failed], timeout: defaultTimeout) } func testRetryLoadingAfterFailureWithReload() { @@ -202,10 +202,10 @@ class AudioPlayerTests: XCTestCase { ) audioPlayer.load(item: item, playWhenReady: true) - waitEqual(self.playerStateEventListener.statesWithoutBuffering, [.loading, .failed], timeout: 5) + waitEqual(self.playerStateEventListener.statesWithoutBuffering, [.loading, .failed], timeout: defaultTimeout) audioPlayer.reload(startFromCurrentTime: true) - waitEqual(self.playerStateEventListener.statesWithoutBuffering, [.loading, .failed, .loading, .failed], timeout: 5) + waitEqual(self.playerStateEventListener.statesWithoutBuffering, [.loading, .failed, .loading, .failed], timeout: defaultTimeout) } func testLoadResourceSucceedsAfterPreviousFailure() { @@ -218,13 +218,13 @@ class AudioPlayerTests: XCTestCase { let failItem = DefaultAudioItem(audioUrl: nonExistingUrl, artist: "Artist", title: "Title", albumTitle: "AlbumTitle", sourceType: .stream) audioPlayer.load(item: failItem, playWhenReady: false) - waitTrue(didReceiveFail, timeout: 5) - waitEqual(self.audioPlayer.playerState, .failed, timeout: 5) - waitEqual(self.playerStateEventListener.states, [.loading, .failed], timeout: 5) + waitTrue(didReceiveFail, timeout: defaultTimeout) + waitEqual(self.audioPlayer.playerState, .failed, timeout: defaultTimeout) + waitEqual(self.playerStateEventListener.states, [.loading, .failed], timeout: defaultTimeout) self.audioPlayer.load(item: Source.getAudioItem(), playWhenReady: true) - waitTrue(self.audioPlayer.playbackError == nil, timeout: 5) - waitEqual(self.playerStateEventListener.statesWithoutBuffering, [.loading, .failed, .loading, .playing], timeout: 5) + waitTrue(self.audioPlayer.playbackError == nil, timeout: defaultTimeout) + waitEqual(self.playerStateEventListener.statesWithoutBuffering, [.loading, .failed, .idle, .loading, .playing], timeout: defaultTimeout) } func testLoadResourceSucceedsAfterPreviousFailureWithPlayWhenReady() { @@ -237,11 +237,11 @@ class AudioPlayerTests: XCTestCase { let item = DefaultAudioItem(audioUrl: nonExistingUrl, artist: "Artist", title: "Title", albumTitle: "AlbumTitle", sourceType: .stream) audioPlayer.load(item: item, playWhenReady: true) - waitTrue(didReceiveFail, timeout: 5) - waitEqual(self.audioPlayer.playerState, .failed, timeout: 5) + waitTrue(didReceiveFail, timeout: defaultTimeout) + waitEqual(self.audioPlayer.playerState, .failed, timeout: defaultTimeout) self.audioPlayer.load(item: Source.getAudioItem(), playWhenReady: true) - waitTrue(self.audioPlayer.playbackError == nil, timeout: 5) + waitTrue(self.audioPlayer.playbackError == nil, timeout: defaultTimeout) } // MARK: - States @@ -257,115 +257,115 @@ class AudioPlayerTests: XCTestCase { func testReadyStateAfterLoadSource() { audioPlayer.load(item: Source.getAudioItem(), playWhenReady: false) - waitEqual(self.audioPlayer.playerState, .ready, timeout: 5) + waitEqual(self.audioPlayer.playerState, .ready, timeout: defaultTimeout) } func testPlayingStateAfterLoadSourceWithPlayWhenReady() { audioPlayer.load(item: Source.getAudioItem(), playWhenReady: true) - waitEqual(self.audioPlayer.playerState, .playing, timeout: 5) + waitEqual(self.audioPlayer.playerState, .playing, timeout: defaultTimeout) } func testReliableOrderOfEvents() { audioPlayer.load(item: Source.getAudioItem(), playWhenReady: true) var expectedEvents: [AVPlayerWrapperState] = [.loading, .playing] - waitEqual(self.playerStateEventListener.statesWithoutBuffering, expectedEvents, timeout: 5) + waitEqual(self.playerStateEventListener.statesWithoutBuffering, expectedEvents, timeout: defaultTimeout) audioPlayer.pause() expectedEvents.append(.paused) - waitEqual(self.playerStateEventListener.statesWithoutBuffering, expectedEvents, timeout: 5) + waitEqual(self.playerStateEventListener.statesWithoutBuffering, expectedEvents, timeout: defaultTimeout) audioPlayer.play() expectedEvents.append(.playing) - waitEqual(self.playerStateEventListener.statesWithoutBuffering, expectedEvents, timeout: 5) + waitEqual(self.playerStateEventListener.statesWithoutBuffering, expectedEvents, timeout: defaultTimeout) audioPlayer.clear() expectedEvents.append(.idle) - waitEqual(self.playerStateEventListener.statesWithoutBuffering, expectedEvents, timeout: 5) + waitEqual(self.playerStateEventListener.statesWithoutBuffering, expectedEvents, timeout: defaultTimeout) } func testUpdatePlayWhenReadyAfterExternalPause() { audioPlayer.load(item: Source.getAudioItem(), playWhenReady: true) var expectedEvents: [AVPlayerWrapperState] = [.loading, .playing] - waitEqual(self.playerStateEventListener.statesWithoutBuffering, expectedEvents, timeout: 5) - waitTrue(self.audioPlayer.currentTime > 0, timeout: 5) + waitEqual(self.playerStateEventListener.statesWithoutBuffering, expectedEvents, timeout: defaultTimeout) + waitTrue(self.audioPlayer.currentTime > 0, timeout: defaultTimeout) // Simulate AVPlayer becoming paused due to external reason: audioPlayer.wrapper.rate = 0 expectedEvents.append(.paused) - waitEqual(self.playerStateEventListener.statesWithoutBuffering, expectedEvents, timeout: 5) + waitEqual(self.playerStateEventListener.statesWithoutBuffering, expectedEvents, timeout: defaultTimeout) XCTAssertFalse(self.audioPlayer.playWhenReady) } func testReliableOrderOfEventsAtEndCallStop() { audioPlayer.load(item: Source.getAudioItem(), playWhenReady: true) var expectedEvents: [AVPlayerWrapperState] = [.loading, .playing] - waitEqual(self.playerStateEventListener.statesWithoutBuffering, expectedEvents, timeout: 5) + waitEqual(self.playerStateEventListener.statesWithoutBuffering, expectedEvents, timeout: defaultTimeout) audioPlayer.pause() expectedEvents.append(.paused) - waitEqual(self.playerStateEventListener.statesWithoutBuffering, expectedEvents, timeout: 5) + waitEqual(self.playerStateEventListener.statesWithoutBuffering, expectedEvents, timeout: defaultTimeout) expectedEvents.append(.playing) audioPlayer.play() - waitEqual(self.playerStateEventListener.statesWithoutBuffering, expectedEvents, timeout: 5) + waitEqual(self.playerStateEventListener.statesWithoutBuffering, expectedEvents, timeout: defaultTimeout) audioPlayer.stop() expectedEvents.append(.stopped) - waitEqual(self.playerStateEventListener.statesWithoutBuffering, expectedEvents, timeout: 5) + waitEqual(self.playerStateEventListener.statesWithoutBuffering, expectedEvents, timeout: defaultTimeout) } func testReliableOrderOfEventsAfterLoadingAfterReset() { audioPlayer.load(item: Source.getAudioItem(), playWhenReady: true) var expectedEvents: [AVPlayerWrapperState] = [.loading, .playing] - waitEqual(self.playerStateEventListener.statesWithoutBuffering, expectedEvents, timeout: 5) + waitEqual(self.playerStateEventListener.statesWithoutBuffering, expectedEvents, timeout: defaultTimeout) audioPlayer.clear() expectedEvents.append(.idle) - waitEqual(self.playerStateEventListener.statesWithoutBuffering, expectedEvents, timeout: 5) + waitEqual(self.playerStateEventListener.statesWithoutBuffering, expectedEvents, timeout: defaultTimeout) audioPlayer.load(item: Source.getAudioItem()) expectedEvents.append(contentsOf: [.loading, .playing]) - waitEqual(self.playerStateEventListener.statesWithoutBuffering, expectedEvents, timeout: 5) + waitEqual(self.playerStateEventListener.statesWithoutBuffering, expectedEvents, timeout: defaultTimeout) } func testPlayingStateAfterPlay() { audioPlayer.load(item: Source.getAudioItem(), playWhenReady: false) - waitEqual(self.audioPlayer.playerState, .ready, timeout: 5) + waitEqual(self.audioPlayer.playerState, .ready, timeout: defaultTimeout) audioPlayer.play() - waitEqual(self.audioPlayer.playerState, .playing, timeout: 5) + waitEqual(self.audioPlayer.playerState, .playing, timeout: defaultTimeout) } func testPausedStateAfterPause() { audioPlayer.load(item: Source.getAudioItem(), playWhenReady: true) - waitEqual(self.audioPlayer.playerState, .playing, timeout: 5) + waitEqual(self.audioPlayer.playerState, .playing, timeout: defaultTimeout) audioPlayer.pause() - waitEqual(self.audioPlayer.playerState, .paused, timeout: 5) + waitEqual(self.audioPlayer.playerState, .paused, timeout: defaultTimeout) } func testPausedStateAfterSettingPlayWhenReadyToFalse() { audioPlayer.load(item: Source.getAudioItem(), playWhenReady: true) - waitEqual(self.audioPlayer.playerState, .playing, timeout: 5) + waitEqual(self.audioPlayer.playerState, .playing, timeout: defaultTimeout) audioPlayer.playWhenReady = false - waitEqual(self.audioPlayer.playerState, .paused, timeout: 5) + waitEqual(self.audioPlayer.playerState, .paused, timeout: defaultTimeout) } func testPlayingStateAfterSettingPlayWhenReadyToTrue() { audioPlayer.load(item: Source.getAudioItem(), playWhenReady: false) - waitEqual(self.audioPlayer.playerState, .ready, timeout: 5) + waitEqual(self.audioPlayer.playerState, .ready, timeout: defaultTimeout) audioPlayer.playWhenReady = true - waitEqual(self.audioPlayer.playerState, .playing, timeout: 5) + waitEqual(self.audioPlayer.playerState, .playing, timeout: defaultTimeout) } func testStoppedStateAfterStop() { audioPlayer.load(item: Source.getAudioItem(), playWhenReady: true) - waitEqual(self.audioPlayer.playerState, .playing, timeout: 5) + waitEqual(self.audioPlayer.playerState, .playing, timeout: defaultTimeout) audioPlayer.stop() - waitEqual(self.audioPlayer.playerState, .stopped, timeout: 5) + waitEqual(self.audioPlayer.playerState, .stopped, timeout: defaultTimeout) } // MARK: - State (Current Time) @@ -383,7 +383,7 @@ class AudioPlayerTests: XCTestCase { } audioPlayer.load(item: LongSource.getAudioItem(), playWhenReady: true) - waitTrue(onSecondsElapseTime > 0, timeout: 5) + waitTrue(onSecondsElapseTime > 0, timeout: defaultTimeout) } // MARK: - Buffer @@ -411,22 +411,22 @@ class AudioPlayerTests: XCTestCase { func testSeekingBeforeLoadingComplete() { audioPlayer.load(item: FiveSecondSource.getAudioItem(), playWhenReady: true) - XCTAssertTrue(audioPlayer.playerState == .loading) + XCTAssertTrue(audioPlayer.playerState == .buffering) audioPlayer.seek(to: 4.75) - waitTrue(self.audioPlayer.currentTime > 4.75, timeout: 5) + waitTrue(self.audioPlayer.currentTime > 4.75, timeout: defaultTimeout) } func testSeekingAfterLoadingComplete() { audioPlayer.load(item: FiveSecondSource.getAudioItem(), playWhenReady: true) - waitEqual(self.audioPlayer.playerState, .playing, timeout: 5) + waitEqual(self.audioPlayer.playerState, .playing, timeout: defaultTimeout) audioPlayer.seek(to: 4.75) - waitTrue(self.audioPlayer.currentTime > 4.75, timeout: 5) + waitTrue(self.audioPlayer.currentTime > 4.75, timeout: defaultTimeout) } func testSeekingWhenPaused() { audioPlayer.load(item: FiveSecondSource.getAudioItem(), playWhenReady: false) audioPlayer.seek(to: 4.75) - waitEqual(self.audioPlayer.currentTime, 4.75, timeout: 5) + waitEqual(self.audioPlayer.currentTime, 4.75, timeout: defaultTimeout) } func testSeekingWhenStopped() { @@ -435,7 +435,7 @@ class AudioPlayerTests: XCTestCase { waitForSeek(audioPlayer, to: 2) audioPlayer.stop() audioPlayer.seek(to: 4.75) - waitEqual(self.audioPlayer.currentTime, 0, timeout: 5) + waitEqual(self.audioPlayer.currentTime, 0, timeout: defaultTimeout) } // MARK: - Rate @@ -466,7 +466,7 @@ class AudioPlayerTests: XCTestCase { audioPlayer.load(item: FiveSecondSource.getAudioItem(), playWhenReady: true) audioPlayer.rate = 10 - waitEqual(self.audioPlayer.playerState, .ended, timeout: 5) + waitEqual(self.audioPlayer.playerState, .ended, timeout: defaultTimeout) if let start = start, let end = end { let duration = end.timeIntervalSince(start) @@ -498,7 +498,7 @@ class AudioPlayerTests: XCTestCase { } audioPlayer.seek(to: 4.75) - waitEqual(self.audioPlayer.playerState, .ended, timeout: 5) + waitEqual(self.audioPlayer.playerState, .ended, timeout: defaultTimeout) if let start = start, let end = end { let duration = end.timeIntervalSince(start) diff --git a/Tests/SwiftAudioExTests/QueuedAudioPlayerTests.swift b/Tests/SwiftAudioExTests/QueuedAudioPlayerTests.swift index 2dcff06..e39171d 100644 --- a/Tests/SwiftAudioExTests/QueuedAudioPlayerTests.swift +++ b/Tests/SwiftAudioExTests/QueuedAudioPlayerTests.swift @@ -75,15 +75,15 @@ class QueuedAudioPlayerTests: XCTestCase { XCTAssertNil(audioPlayer.currentItem) XCTAssertEqual(audioPlayer.playerState, AudioPlayerState.idle) - waitEqual(self.playerStateEventListener.statesWithoutBuffering, [.loading, .idle], timeout: 5) + waitEqual(self.playerStateEventListener.statesWithoutBuffering, [.loading, .idle], timeout: defaultTimeout) } func testLoadAfterRemoval() { testRemovingItemAfterAdding() - audioPlayer.load(item: Source.getAudioItem()) + audioPlayer.load(item: Source.getAudioItem(), playWhenReady: true) XCTAssertNotEqual(audioPlayer.currentItem?.getSourceUrl(), FiveSecondSource.getAudioItem().getSourceUrl()) - waitEqual(self.playerStateEventListener.statesWithoutBuffering, [.loading, .idle, .loading, .playing], timeout: 5) + waitTrue(self.playerStateEventListener.statesWithoutBuffering.contains(.playing), timeout: defaultTimeout) XCTAssertEqual(audioPlayer.playerState, AudioPlayerState.playing) } @@ -100,7 +100,16 @@ class QueuedAudioPlayerTests: XCTestCase { XCTAssertEqual(audioPlayer.items.count, 1) XCTAssertEqual(audioPlayer.currentItem?.getSourceUrl(), ShortSource.getAudioItem().getSourceUrl()) } - + + // Covers: https://github.com/doublesymmetry/SwiftAudioEx/pull/81 + func testAddingItemWhenOnlyOneTrackInQueue() throws { + audioPlayer.add(item: FiveSecondSource.getAudioItem()) + audioPlayer.play() + try audioPlayer.add(items: [ShortSource.getAudioItem()], at: 0) + XCTAssertEqual(audioPlayer.items.count, 2) + XCTAssertEqual(audioPlayer.currentIndex, 1) + } + // MARK: - Next Items func testNextItemsEmptyOnCreate() { @@ -166,25 +175,24 @@ class QueuedAudioPlayerTests: XCTestCase { // Test next audioPlayer.next() - waitEqual(self.playerStateEventListener.statesWithoutBuffering, [.loading, .paused, .loading, .paused], timeout: 5) + waitEqual(self.playerStateEventListener.statesWithoutBuffering, [.loading, .paused, .loading, .paused], timeout: defaultTimeout) XCTAssertEqual(audioPlayer.previousItems.count, 1) - waitEqual(self.playbackEndEventListener.lastReason, .skippedToNext, timeout: 5) + waitEqual(self.playbackEndEventListener.lastReason, .skippedToNext, timeout: defaultTimeout) // Test stop audioPlayer.stop() - waitEqual(self.audioPlayer.playerState, .stopped, timeout: 5) - waitEqual(self.playbackEndEventListener.reasons, [.skippedToNext, .playerStopped], timeout: 5) + waitEqual(self.audioPlayer.playerState, .stopped, timeout: defaultTimeout) + waitEqual(self.playbackEndEventListener.reasons, [.skippedToNext, .playerStopped], timeout: defaultTimeout) // Test stop again audioPlayer.stop() - waitEqual(self.audioPlayer.playerState, .stopped, timeout: 5) - waitEqual(self.playbackEndEventListener.reasons, [.skippedToNext, .playerStopped], timeout: 5) + waitEqual(self.audioPlayer.playerState, .stopped, timeout: defaultTimeout) + waitEqual(self.playbackEndEventListener.reasons, [.skippedToNext, .playerStopped], timeout: defaultTimeout) // Test previous audioPlayer.previous() - waitEqual(self.audioPlayer.playerState, .loading, timeout: 5) - // should not have emitted playbackEnd .skippedToPrevious because playback was already stopped previously - waitEqual(self.playbackEndEventListener.reasons, [.skippedToNext, .playerStopped], timeout: 5) + XCTAssertEqual(self.audioPlayer.playerState, .loading) + waitEqual(self.playbackEndEventListener.reasons, [.skippedToNext, .playerStopped], timeout: defaultTimeout) } @@ -218,14 +226,14 @@ class QueuedAudioPlayerTests: XCTestCase { audioPlayer.pause() // It should have gone into .paused state from .loading and then into .ready because playback can be started - waitEqual(self.playerStateEventListener.states, [.loading, .paused, .ready], timeout: 5) + waitEqual(self.playerStateEventListener.states, [.loading, .paused, .ready], timeout: defaultTimeout) } // MARK: - Stop func testStopOnEmptyQueue() { audioPlayer.stop() - waitEqual(self.playerStateEventListener.states, [.stopped], timeout: 5) + waitEqual(self.playerStateEventListener.states, [.stopped], timeout: defaultTimeout) // It should not have emitted a playbackEnd event XCTAssertNil(playbackEndEventListener.lastReason) @@ -239,10 +247,10 @@ class QueuedAudioPlayerTests: XCTestCase { audioPlayer.stop() // It should have emitted a playbackEnd .playerStopped event - waitEqual(self.playbackEndEventListener.lastReason, .playerStopped, timeout: 5) + waitEqual(self.playbackEndEventListener.lastReason, .playerStopped, timeout: defaultTimeout) // It should have mutated player state from .loading to .stopped - waitEqual(self.playerStateEventListener.states, [.loading, .stopped], timeout: 5) + waitEqual(self.playerStateEventListener.states, [.loading, .stopped], timeout: defaultTimeout) } // MARK: - Load @@ -253,7 +261,7 @@ class QueuedAudioPlayerTests: XCTestCase { XCTAssertNotNil(audioPlayer.currentItem) // It should have started loading, but not playing yet - waitEqual(self.playerStateEventListener.states, [.loading, .paused, .ready], timeout: 5) + waitEqual(self.playerStateEventListener.states, [.loading, .paused, .ready], timeout: defaultTimeout) } func testLoadItemAfterPlaying() { @@ -262,12 +270,12 @@ class QueuedAudioPlayerTests: XCTestCase { XCTAssertNotNil(audioPlayer.currentItem) // It should have started playing - waitEqual(self.playerStateEventListener.statesWithoutBuffering, [.loading, .playing], timeout: 5) + waitEqual(self.playerStateEventListener.statesWithoutBuffering, [.loading, .playing], timeout: defaultTimeout) audioPlayer.load(item: Source.getAudioItem()) XCTAssertEqual(audioPlayer.items.count, 1) XCTAssertEqual(audioPlayer.currentItem?.getSourceUrl(), Source.getAudioItem().getSourceUrl()) - waitEqual(self.playerStateEventListener.statesWithoutBuffering.prefix(4), [.loading, .playing, .loading, .playing], timeout: 5) + waitEqual(self.playerStateEventListener.statesWithoutBuffering.prefix(4), [.loading, .playing, .loading, .playing], timeout: defaultTimeout) } // MARK: - Next @@ -282,10 +290,10 @@ class QueuedAudioPlayerTests: XCTestCase { audioPlayer.add(items: [FiveSecondSource.getAudioItem(), FiveSecondSource.getAudioItem()]) audioPlayer.next() - waitEqual(self.audioPlayer.nextItems.count, 0, timeout: 5) - waitEqual(self.audioPlayer.currentIndex, 1, timeout: 5) + waitEqual(self.audioPlayer.nextItems.count, 0, timeout: defaultTimeout) + waitEqual(self.audioPlayer.currentIndex, 1, timeout: defaultTimeout) // should go to previous item and not play - waitEqual(self.audioPlayer.playerState, AudioPlayerState.ready, timeout: 5) + waitEqual(self.audioPlayer.playerState, AudioPlayerState.ready, timeout: defaultTimeout) } func testNextWhenPausedWithoutPlaying() { @@ -293,10 +301,10 @@ class QueuedAudioPlayerTests: XCTestCase { audioPlayer.pause() audioPlayer.next() - waitEqual(self.audioPlayer.nextItems.count, 0, timeout: 5) - waitEqual(self.audioPlayer.currentIndex, 1, timeout: 5) + waitEqual(self.audioPlayer.nextItems.count, 0, timeout: defaultTimeout) + waitEqual(self.audioPlayer.currentIndex, 1, timeout: defaultTimeout) // should go to previous item and not play - waitEqual(self.audioPlayer.playerState, AudioPlayerState.ready, timeout: 5) + waitEqual(self.audioPlayer.playerState, AudioPlayerState.ready, timeout: defaultTimeout) } func testNextWhenPlaying() { @@ -304,10 +312,10 @@ class QueuedAudioPlayerTests: XCTestCase { audioPlayer.add(items: [FiveSecondSource.getAudioItem(), FiveSecondSource.getAudioItem()]) audioPlayer.next() - waitEqual(self.audioPlayer.nextItems.count, 0, timeout: 5) - waitEqual(self.audioPlayer.currentIndex, 1, timeout: 5) + waitEqual(self.audioPlayer.nextItems.count, 0, timeout: defaultTimeout) + waitEqual(self.audioPlayer.currentIndex, 1, timeout: defaultTimeout) // should go to previous item and play - waitEqual(self.audioPlayer.playerState, AudioPlayerState.playing, timeout: 5) + waitEqual(self.audioPlayer.playerState, AudioPlayerState.playing, timeout: defaultTimeout) } // MARK: - Previous @@ -323,11 +331,11 @@ class QueuedAudioPlayerTests: XCTestCase { audioPlayer.next() audioPlayer.previous() - waitEqual(self.audioPlayer.nextItems.count, 1, timeout: 5) - waitEqual(self.audioPlayer.previousItems.count, 0, timeout: 5) - waitEqual(self.audioPlayer.currentIndex, 0, timeout: 5) + waitEqual(self.audioPlayer.nextItems.count, 1, timeout: defaultTimeout) + waitEqual(self.audioPlayer.previousItems.count, 0, timeout: defaultTimeout) + waitEqual(self.audioPlayer.currentIndex, 0, timeout: defaultTimeout) // should go to previous item and play - waitEqual(self.audioPlayer.playerState, AudioPlayerState.playing, timeout: 5) + waitEqual(self.audioPlayer.playerState, AudioPlayerState.playing, timeout: defaultTimeout) } func testPreviousWhenPaused() { @@ -336,11 +344,11 @@ class QueuedAudioPlayerTests: XCTestCase { audioPlayer.pause() audioPlayer.previous() - waitEqual(self.audioPlayer.nextItems.count, 1, timeout: 5) - waitEqual(self.audioPlayer.previousItems.count, 0, timeout: 5) - waitEqual(self.audioPlayer.currentIndex, 0, timeout: 5) + waitEqual(self.audioPlayer.nextItems.count, 1, timeout: defaultTimeout) + waitEqual(self.audioPlayer.previousItems.count, 0, timeout: defaultTimeout) + waitEqual(self.audioPlayer.currentIndex, 0, timeout: defaultTimeout) // should go to previous item and not play - waitEqual(self.audioPlayer.playerState, AudioPlayerState.ready, timeout: 5) + waitEqual(self.audioPlayer.playerState, AudioPlayerState.ready, timeout: defaultTimeout) } // MARK: - Move @@ -354,7 +362,7 @@ class QueuedAudioPlayerTests: XCTestCase { audioPlayer.repeatMode = RepeatMode.off waitForSeek(audioPlayer, to: 4.6) - waitEqual(self.audioPlayer.playerState, AudioPlayerState.ended, timeout: 5) + waitEqual(self.audioPlayer.playerState, AudioPlayerState.ended, timeout: defaultTimeout) } func testMoveItemsRepeatModeQueue() { @@ -366,9 +374,9 @@ class QueuedAudioPlayerTests: XCTestCase { audioPlayer.repeatMode = RepeatMode.queue waitForSeek(audioPlayer, to: 4.6) - waitEqual(self.audioPlayer.currentIndex, 0, timeout: 5) - waitTrue(self.audioPlayer.currentTime > 0, timeout: 5) - waitEqual(self.audioPlayer.playerState, AudioPlayerState.playing, timeout: 5) + waitEqual(self.audioPlayer.currentIndex, 0, timeout: defaultTimeout) + waitTrue(self.audioPlayer.currentTime > 0, timeout: defaultTimeout) + waitEqual(self.audioPlayer.playerState, AudioPlayerState.playing, timeout: defaultTimeout) } func testMoveItemsRepeatModeTrack() { @@ -380,10 +388,10 @@ class QueuedAudioPlayerTests: XCTestCase { audioPlayer.repeatMode = RepeatMode.track waitForSeek(audioPlayer, to: 4.6) - waitTrue(self.audioPlayer.currentTime < 4.6, timeout: 5) - waitTrue(self.audioPlayer.currentTime > 0, timeout: 5) + waitTrue(self.audioPlayer.currentTime < 4.6, timeout: defaultTimeout) + waitTrue(self.audioPlayer.currentTime > 0, timeout: defaultTimeout) XCTAssertEqual(audioPlayer.currentIndex, 1) - waitEqual(self.audioPlayer.playerState, .playing, timeout: 5) + waitEqual(self.audioPlayer.playerState, .playing, timeout: defaultTimeout) } // MARK: - Repeat Mode (Off - Two Items) @@ -398,16 +406,16 @@ class QueuedAudioPlayerTests: XCTestCase { setupRepeatModeOffTests() waitForSeek(audioPlayer, to: 4.6) - waitEqual(self.audioPlayer.nextItems.count, 0, timeout: 5) - waitEqual(self.audioPlayer.currentIndex, 1, timeout: 5) - waitEqual(self.audioPlayer.playerState, .playing, timeout: 5) - waitEqual(self.currentItemEventListener.lastIndex, 0, timeout: 5) + waitEqual(self.audioPlayer.nextItems.count, 0, timeout: defaultTimeout) + waitEqual(self.audioPlayer.currentIndex, 1, timeout: defaultTimeout) + waitEqual(self.audioPlayer.playerState, .playing, timeout: defaultTimeout) + waitEqual(self.currentItemEventListener.lastIndex, 0, timeout: defaultTimeout) // Allow final track to end waitForSeek(audioPlayer, to: 4.6) - waitEqual(self.audioPlayer.currentTime, 5, accuracy: 0.1, timeout: 5) - waitEqual(self.audioPlayer.playerState, .ended, timeout: 5) - waitEqual(self.currentItemEventListener.index, 1, timeout: 5) + waitEqual(self.audioPlayer.currentTime, 5, accuracy: 0.1, timeout: defaultTimeout) + waitEqual(self.audioPlayer.playerState, .ended, timeout: defaultTimeout) + waitEqual(self.currentItemEventListener.index, 1, timeout: defaultTimeout) } func testNextWhenRepeatModeOff() { @@ -415,16 +423,16 @@ class QueuedAudioPlayerTests: XCTestCase { audioPlayer.play() audioPlayer.next() - waitEqual(self.audioPlayer.nextItems.count, 0, timeout: 5) - waitEqual(self.audioPlayer.currentIndex, 1, timeout: 5) - waitEqual(self.audioPlayer.playerState, .playing, timeout: 5) - waitEqual(self.currentItemEventListener.lastIndex, 0, timeout: 5) + waitEqual(self.audioPlayer.nextItems.count, 0, timeout: defaultTimeout) + waitEqual(self.audioPlayer.currentIndex, 1, timeout: defaultTimeout) + waitEqual(self.audioPlayer.playerState, .playing, timeout: defaultTimeout) + waitEqual(self.currentItemEventListener.lastIndex, 0, timeout: defaultTimeout) // Calling next on the final track audioPlayer.next() - waitEqual(self.audioPlayer.currentIndex, 1, timeout: 5) - waitEqual(self.audioPlayer.currentTime, 5, accuracy: 0.1, timeout: 5) - waitEqual(self.audioPlayer.playerState, .ended, timeout: 5) + waitEqual(self.audioPlayer.currentIndex, 1, timeout: defaultTimeout) + waitEqual(self.audioPlayer.currentTime, 5, accuracy: 0.1, timeout: defaultTimeout) + waitEqual(self.audioPlayer.playerState, .ended, timeout: defaultTimeout) } // MARK: - Repeat Mode (Track - Two Items) @@ -439,19 +447,19 @@ class QueuedAudioPlayerTests: XCTestCase { setupRepeatModeTrackTests() waitForSeek(audioPlayer, to: 4.6) - waitEqual(self.audioPlayer.currentTime, 0, timeout: 5) - waitEqual(self.audioPlayer.nextItems.count, 1, timeout: 5) - waitEqual(self.audioPlayer.currentIndex, 0, timeout: 5) - waitEqual(self.audioPlayer.playerState, .playing, timeout: 5) + waitEqual(self.audioPlayer.currentTime, 0, timeout: defaultTimeout) + waitEqual(self.audioPlayer.nextItems.count, 1, timeout: defaultTimeout) + waitEqual(self.audioPlayer.currentIndex, 0, timeout: defaultTimeout) + waitEqual(self.audioPlayer.playerState, .playing, timeout: defaultTimeout) } func testNextWhenRepeatModeTrack() { setupRepeatModeTrackTests() audioPlayer.next() - waitEqual(self.audioPlayer.nextItems.count, 0, timeout: 5) - waitEqual(self.audioPlayer.playerState, .playing, timeout: 5) - waitEqual(self.currentItemEventListener.lastIndex, 0, timeout: 5) + waitEqual(self.audioPlayer.nextItems.count, 0, timeout: defaultTimeout) + waitEqual(self.audioPlayer.playerState, .playing, timeout: defaultTimeout) + waitEqual(self.currentItemEventListener.lastIndex, 0, timeout: defaultTimeout) } @@ -467,28 +475,28 @@ class QueuedAudioPlayerTests: XCTestCase { setupRepeatModeQueueTests() waitForSeek(audioPlayer, to: 4.6) - waitEqual(self.audioPlayer.nextItems.count, 0, timeout: 5) - waitEqual(self.audioPlayer.currentIndex, 1, timeout: 5) - waitEqual(self.audioPlayer.playerState, .playing, timeout: 5) - waitEqual(self.currentItemEventListener.lastIndex, 0, timeout: 5) + waitEqual(self.audioPlayer.nextItems.count, 0, timeout: defaultTimeout) + waitEqual(self.audioPlayer.currentIndex, 1, timeout: defaultTimeout) + waitEqual(self.audioPlayer.playerState, .playing, timeout: defaultTimeout) + waitEqual(self.currentItemEventListener.lastIndex, 0, timeout: defaultTimeout) // Allow the final track to end - waitEqual(self.audioPlayer.currentIndex, 1, timeout: 5) + waitEqual(self.audioPlayer.currentIndex, 1, timeout: defaultTimeout) waitForSeek(audioPlayer, to: 4.6) - waitEqual(self.audioPlayer.nextItems.count, 1, timeout: 5) - waitEqual(self.audioPlayer.currentIndex, 0, timeout: 5) - waitEqual(self.audioPlayer.playerState, .playing, timeout: 5) - waitEqual(self.currentItemEventListener.lastIndex, 1, timeout: 5) + waitEqual(self.audioPlayer.nextItems.count, 1, timeout: defaultTimeout) + waitEqual(self.audioPlayer.currentIndex, 0, timeout: defaultTimeout) + waitEqual(self.audioPlayer.playerState, .playing, timeout: defaultTimeout) + waitEqual(self.currentItemEventListener.lastIndex, 1, timeout: defaultTimeout) } func testNextWhenRepeatModeQueue() { setupRepeatModeQueueTests() audioPlayer.next() - waitEqual(self.audioPlayer.nextItems.count, 0, timeout: 5) - waitEqual(self.audioPlayer.currentIndex, 1, timeout: 5) - waitEqual(self.audioPlayer.playerState, .playing, timeout: 5) - waitEqual(self.currentItemEventListener.lastIndex, 0, timeout: 5) + waitEqual(self.audioPlayer.nextItems.count, 0, timeout: defaultTimeout) + waitEqual(self.audioPlayer.currentIndex, 1, timeout: defaultTimeout) + waitEqual(self.audioPlayer.playerState, .playing, timeout: defaultTimeout) + waitEqual(self.currentItemEventListener.lastIndex, 0, timeout: defaultTimeout) } func testNextTwiceWhenRepeatModeQueue() { @@ -498,13 +506,13 @@ class QueuedAudioPlayerTests: XCTestCase { audioPlayer.next() XCTAssertEqual(audioPlayer.currentIndex, 1) - waitEqual(self.currentItemEventListener.lastIndex, 0, timeout: 5) + waitEqual(self.currentItemEventListener.lastIndex, 0, timeout: defaultTimeout) audioPlayer.next() XCTAssertEqual(audioPlayer.currentIndex, 0) - waitEqual(self.currentItemEventListener.lastIndex, 1, timeout: 5) - waitEqual(self.audioPlayer.nextItems.count, 1, timeout: 5) - waitEqual(self.audioPlayer.playerState, .playing, timeout: 5) + waitEqual(self.currentItemEventListener.lastIndex, 1, timeout: defaultTimeout) + waitEqual(self.audioPlayer.nextItems.count, 1, timeout: defaultTimeout) + waitEqual(self.audioPlayer.playerState, .playing, timeout: defaultTimeout) } // MARK: - Repeat Mode (Off - One Item) @@ -518,15 +526,15 @@ class QueuedAudioPlayerTests: XCTestCase { setupRepeatModeOffOneItemTests() waitForSeek(audioPlayer, to: 4.6) - waitEqual(self.audioPlayer.nextItems.count, 0, timeout: 5) - waitEqual(self.audioPlayer.playerState, .ended, timeout: 5) + waitEqual(self.audioPlayer.nextItems.count, 0, timeout: defaultTimeout) + waitEqual(self.audioPlayer.playerState, .ended, timeout: defaultTimeout) } func testNextWhenRepeatModeOffOneItem() { setupRepeatModeOffOneItemTests() audioPlayer.next() - waitEqual(self.audioPlayer.currentIndex, 0, timeout: 5) + waitEqual(self.audioPlayer.currentIndex, 0, timeout: defaultTimeout) // TODO: Test this more thoroughly? } @@ -541,19 +549,19 @@ class QueuedAudioPlayerTests: XCTestCase { setupRepeatModeTrackOneItemTests() waitForSeek(audioPlayer, to: 4.6) - waitEqual(self.audioPlayer.currentTime, 0, timeout: 5) - waitEqual(self.audioPlayer.currentIndex, 0, timeout: 5) - waitEqual(self.audioPlayer.playerState, .playing, timeout: 5) - waitEqual(self.currentItemEventListener.lastIndex, nil, timeout: 5) + waitEqual(self.audioPlayer.currentTime, 0, timeout: defaultTimeout) + waitEqual(self.audioPlayer.currentIndex, 0, timeout: defaultTimeout) + waitEqual(self.audioPlayer.playerState, .playing, timeout: defaultTimeout) + waitEqual(self.currentItemEventListener.lastIndex, nil, timeout: defaultTimeout) } func testNextWhenRepeatModeTrackOneItem() { setupRepeatModeTrackOneItemTests() audioPlayer.next() - waitEqual(self.audioPlayer.currentTime, 0, timeout: 5) - waitEqual(self.audioPlayer.nextItems.count, 0, timeout: 5) - waitEqual(self.audioPlayer.playerState, .playing, timeout: 5) + waitEqual(self.audioPlayer.currentTime, 0, timeout: defaultTimeout) + waitEqual(self.audioPlayer.nextItems.count, 0, timeout: defaultTimeout) + waitEqual(self.audioPlayer.playerState, .playing, timeout: defaultTimeout) } // MARK: - Repeat Mode (Queue - One Item) @@ -567,11 +575,11 @@ class QueuedAudioPlayerTests: XCTestCase { setupRepeatModeQueueOneItemTests() waitForSeek(audioPlayer, to: 4.6) - waitEqual(self.audioPlayer.playerState, .playing, timeout: 5) - waitTrue(self.audioPlayer.currentTime > 4.5, timeout: 5) - waitTrue(self.audioPlayer.currentTime < 1, timeout: 5) - waitEqual(self.audioPlayer.currentIndex, 0, timeout: 5) - waitEqual(self.audioPlayer.playerState, .playing, timeout: 5) + waitEqual(self.audioPlayer.playerState, .playing, timeout: defaultTimeout) + waitTrue(self.audioPlayer.currentTime > 4.5, timeout: defaultTimeout) + waitTrue(self.audioPlayer.currentTime < 1, timeout: defaultTimeout) + waitEqual(self.audioPlayer.currentIndex, 0, timeout: defaultTimeout) + waitEqual(self.audioPlayer.playerState, .playing, timeout: defaultTimeout) } func testNextWhenRepeatModeQueueOneItem() { @@ -579,10 +587,10 @@ class QueuedAudioPlayerTests: XCTestCase { waitForSeek(audioPlayer, to: 2) audioPlayer.next() - waitEqual(self.audioPlayer.playerState, .playing, timeout: 5) - waitTrue(self.audioPlayer.currentTime < 1.9, timeout: 5) - waitEqual(self.audioPlayer.currentIndex, 0, timeout: 5) - waitEqual(self.audioPlayer.playerState, .playing, timeout: 5) + waitEqual(self.audioPlayer.playerState, .playing, timeout: defaultTimeout) + waitTrue(self.audioPlayer.currentTime < 1.9, timeout: defaultTimeout) + waitEqual(self.audioPlayer.currentIndex, 0, timeout: defaultTimeout) + waitEqual(self.audioPlayer.playerState, .playing, timeout: defaultTimeout) } } diff --git a/Tests/SwiftAudioExTests/Utils/Helpers.swift b/Tests/SwiftAudioExTests/Utils/Helpers.swift index 337a251..2dba277 100644 --- a/Tests/SwiftAudioExTests/Utils/Helpers.swift +++ b/Tests/SwiftAudioExTests/Utils/Helpers.swift @@ -4,68 +4,85 @@ import XCTest @testable import SwiftAudioEx extension XCTestCase { + var defaultTimeout: TimeInterval { + if ProcessInfo.processInfo.environment["CI"] != nil { + return 10 + } else { + return 5 + } + } + func waitForSeek(_ audioPlayer: AudioPlayer, to time: Double) { let seekEventListener = QueuedAudioPlayer.SeekEventListener() audioPlayer.event.seek.addListener(seekEventListener, seekEventListener.handleEvent) audioPlayer.seek(to: time) - waitEqual(seekEventListener.eventResult.0, time, accuracy: 0.1, timeout: 5) - waitEqual(seekEventListener.eventResult.1, true, timeout: 5) - } - - func waitTrue(_ expression: @autoclosure @escaping () -> Bool, timeout: TimeInterval) { - let expectation = XCTestExpectation(description: "Value should eventually equal expected value") - - DispatchQueue.global().async { - while !expression() { - usleep(100_000) // Sleep for 100 milliseconds - } - expectation.fulfill() - } - - wait(for: [expectation], timeout: timeout) + waitEqual(seekEventListener.eventResult.0, time, accuracy: 0.1, timeout: defaultTimeout) + waitEqual(seekEventListener.eventResult.1, true, timeout: defaultTimeout) } func waitEqual(_ expression1: @autoclosure @escaping () -> T, _ expression2: @autoclosure @escaping () -> T, timeout: TimeInterval) { let expectation = XCTestExpectation(description: "Value should eventually equal expected value") - - DispatchQueue.global().async { - while expression1() != expression2() { - usleep(100_000) // Sleep for 100 milliseconds + + let timer = Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { timer in + if expression1() == expression2() { + expectation.fulfill() + timer.invalidate() } - expectation.fulfill() } + RunLoop.current.add(timer, forMode: .default) wait(for: [expectation], timeout: timeout) + + timer.invalidate() } func waitEqual(_ expression1: @autoclosure @escaping () -> T, _ expression2: @autoclosure @escaping () -> T, accuracy: T, timeout: TimeInterval) where T: FloatingPoint { let expectation = XCTestExpectation(description: "Value should eventually equal expected value with accuracy") - DispatchQueue.global().async { - let startTime = Date() - while abs(expression1() - expression2()) > accuracy { - if Date().timeIntervalSince(startTime) >= timeout { - break - } - usleep(100_000) // Sleep for 100 milliseconds + let timer = Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { timer in + if abs(expression1() - expression2()) < accuracy { + expectation.fulfill() + timer.invalidate() } - expectation.fulfill() } - - return wait(for: [expectation], timeout: timeout) + + RunLoop.current.add(timer, forMode: .default) + wait(for: [expectation], timeout: timeout) + + timer.invalidate() } func waitEqual(_ expression1: @autoclosure @escaping () -> (T1, T2), _ expression2: @autoclosure @escaping () -> (T1, T2), timeout: TimeInterval) { let expectation = XCTestExpectation(description: "Values should eventually be equal") - DispatchQueue.global().async { - while expression1() != expression2() { - usleep(100_000) // Sleep for 100 milliseconds + let timer = Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { timer in + if expression1() == expression2() { + expectation.fulfill() + timer.invalidate() } - expectation.fulfill() } - + + RunLoop.current.add(timer, forMode: .default) + wait(for: [expectation], timeout: timeout) + + timer.invalidate() + } + + + func waitTrue(_ expression: @autoclosure @escaping () -> Bool, timeout: TimeInterval) { + let expectation = XCTestExpectation(description: "Expression should eventually be true") + + let timer = Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { timer in + if expression() { + expectation.fulfill() + timer.invalidate() + } + } + + RunLoop.current.add(timer, forMode: .default) wait(for: [expectation], timeout: timeout) + + timer.invalidate() } }