Files
SwiftAudioEx/Example/Tests/AudioPlayerTests.swift
T

230 lines
8.7 KiB
Swift

import Quick
import Nimble
import AVFoundation
@testable import SwiftAudio
class AudioPlayerTests: QuickSpec {
override func spec() {
describe("An AudioPlayer") {
var audioPlayer: AudioPlayer!
beforeEach {
audioPlayer = AudioPlayer()
audioPlayer.bufferDuration = 0.0001
audioPlayer.automaticallyWaitsToMinimizeStalling = false
audioPlayer.volume = 0.0
}
describe("its state", {
it("should be idle", closure: {
expect(audioPlayer.playerState).to(equal(AudioPlayerState.idle))
})
context("when audio item is loaded", {
beforeEach {
try? audioPlayer.load(item: Source.getAudioItem(), playWhenReady: false)
}
it("it should eventually be ready", closure: {
expect(audioPlayer.playerState).toEventually(equal(AudioPlayerState.ready))
})
})
context("when an item is loaded (playWhenReady=true)", {
beforeEach {
try? audioPlayer.load(item: Source.getAudioItem(), playWhenReady: true)
}
it("it should eventually be playing", closure: {
expect(audioPlayer.playerState).toEventually(equal(AudioPlayerState.playing))
})
})
context("when playing an item", {
var holder: AudioPlayerDelegateHolder!
beforeEach {
holder = AudioPlayerDelegateHolder()
audioPlayer.delegate = holder
holder.stateUpdate = { state in
print(state.rawValue)
if state == .ready {
audioPlayer.play()
}
}
try? audioPlayer.load(item: Source.getAudioItem(), playWhenReady: false)
}
it("should eventually be playing", closure: {
expect(audioPlayer.playerState).toEventually(equal(AudioPlayerState.playing))
})
})
context("when pausing an item", {
var holder: AudioPlayerDelegateHolder!
beforeEach {
holder = AudioPlayerDelegateHolder()
audioPlayer.delegate = holder
holder.stateUpdate = { (state) in
if state == .playing {
audioPlayer.pause()
}
}
try? audioPlayer.load(item: Source.getAudioItem(), playWhenReady: true)
}
it("should eventually be paused", closure: {
expect(audioPlayer.playerState).toEventually(equal(AudioPlayerState.paused))
})
})
context("when stopping an item", {
var holder: AudioPlayerDelegateHolder!
beforeEach {
holder = AudioPlayerDelegateHolder()
audioPlayer.delegate = holder
holder.stateUpdate = { (state) in
if state == .playing {
audioPlayer.stop()
}
}
try? audioPlayer.load(item: Source.getAudioItem(), playWhenReady: true)
}
it("should eventually be idle", closure: {
expect(audioPlayer.playerState).toEventually(equal(AudioPlayerState.idle))
})
})
})
describe("its current time", {
it("should be 0", closure: {
expect(audioPlayer.currentTime).to(equal(0))
})
context("when seeking to a time", {
var passed = false
let holder = AudioPlayerDelegateHolder()
let seekTime: TimeInterval = 0.5
beforeEach {
audioPlayer.delegate = holder
holder.seekCompletion = { passed = true }
try? audioPlayer.load(item: Source.getAudioItem(), playWhenReady: false)
audioPlayer.seek(to: seekTime)
}
it("should eventually be equal to the seeked time", closure: {
expect(passed).toEventually(beTrue())
})
})
})
describe("its rate", {
it("should be 0", closure: {
expect(audioPlayer.rate).to(equal(0))
})
context("when playing an item", {
beforeEach {
try? audioPlayer.load(item: Source.getAudioItem(), playWhenReady: true)
}
it("should eventually be 1.0", closure: {
expect(audioPlayer.rate).toEventually(equal(1.0))
})
})
})
describe("its currentItem", {
it("should be nil", closure: {
expect(audioPlayer.currentItem).to(beNil())
})
context("when loading an item", {
beforeEach {
try? audioPlayer.load(item: Source.getAudioItem(), playWhenReady: false)
}
it("should not be nil", closure: {
expect(audioPlayer.currentItem).toNot(beNil())
})
})
context("when setting the timePitchAlgorithm", {
beforeEach {
audioPlayer.audioTimePitchAlgorithm = .timeDomain
}
context("then loading an item", {
beforeEach {
try? audioPlayer.load(item: Source.getAudioItem(), playWhenReady: false)
}
it("should have the applied timePitchAlgorithm", closure: {
expect(audioPlayer.wrapper.currentItem?.audioTimePitchAlgorithm).to(equal(AVAudioTimePitchAlgorithm.timeDomain))
})
})
context("then loading a timepitching item", {
beforeEach {
let item = DefaultAudioItemTimePitching(audioUrl: Source.path, artist: nil, title: nil, albumTitle: nil, sourceType: .file, artwork: nil, audioTimePitchAlgorithm: AVAudioTimePitchAlgorithm.spectral)
try? audioPlayer.load(item: item, playWhenReady: false)
}
it("should have the applied timePitchAlgorithm", closure: {
expect(audioPlayer.wrapper.currentItem?.audioTimePitchAlgorithm).to(equal(AVAudioTimePitchAlgorithm.spectral))
})
})
})
})
}
}
}
class AudioPlayerDelegateHolder: AudioPlayerDelegate {
func audioPlayer(itemPlaybackEndedWithReason reason: PlaybackEndedReason) {
}
var stateUpdate: ((_ state: AudioPlayerState) -> Void)?
var state: AudioPlayerState? {
didSet {
if let state = state {
stateUpdate?(state)
}
}
}
func audioPlayer(playerDidChangeState state: AudioPlayerState) {
self.state = state
}
func audioPlayer(secondsElapsed seconds: Double) {
}
func audioPlayer(failedWithError error: Error?) {
}
var seekCompletion: (() -> Void)?
func audioPlayer(seekTo seconds: Int, didFinish: Bool) {
seekCompletion?()
}
func audioPlayer(didUpdateDuration duration: Double) {
if let state = self.state {
self.stateUpdate?(state)
}
}
}