Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ class PlaylistPlayer(
reject(e)
throw e
})
.then { _ -> reject(CancellationException("PlaylistPlayer halted.")) }
}

private fun playNextFile(preparedPosition: Duration = Duration.ZERO): Promise<PositionedPlayingFile?> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@ import com.lasthopesoftware.bluewater.client.browsing.library.repository.Library
import com.lasthopesoftware.bluewater.client.browsing.library.repository.LibraryNowPlayingValues
import com.lasthopesoftware.promises.extensions.toPromise
import com.namehillsoftware.handoff.promises.Promise
import java.util.concurrent.ConcurrentHashMap

open class FakeLibraryRepository(vararg libraries: Library) : ProvideLibraries, ManageLibraries {
private val sync = Any()

val libraries = libraries.associateBy { l -> l.id }.toMutableMap()
val libraries = ConcurrentHashMap(libraries.associateBy { l -> l.id })

override fun promiseLibrary(libraryId: LibraryId): Promise<Library?> = synchronized(sync) { Promise(libraries[libraryId.id]) }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import com.lasthopesoftware.bluewater.client.playback.engine.preparation.IPlayab
import com.lasthopesoftware.bluewater.client.playback.engine.preparation.PreparedPlaybackQueueResourceManagement
import com.lasthopesoftware.bluewater.client.playback.file.PositionedPlayingFile
import com.lasthopesoftware.bluewater.client.playback.file.error.PlaybackException
import com.lasthopesoftware.bluewater.client.playback.file.fakes.FakeBufferingPlaybackHandler
import com.lasthopesoftware.bluewater.client.playback.file.fakes.FakePreparedPlayableFile
import com.lasthopesoftware.bluewater.client.playback.file.fakes.ResolvablePlaybackHandler
import com.lasthopesoftware.bluewater.client.playback.file.preparation.PlayableFilePreparationSource
Expand All @@ -31,7 +32,7 @@ import org.junit.jupiter.api.Test
private const val libraryId = 362

class `When Playback is Resumed` {
private val expectedPlaybackHandler = ResolvablePlaybackHandler()
private val expectedPlaybackHandler = FakeBufferingPlaybackHandler()

private val mut by lazy {
val fakePlaybackPreparerProvider = mockk<IPlayableFilePreparationSourceProvider> {
Expand All @@ -40,12 +41,12 @@ class `When Playback is Resumed` {

every { promisePreparedPlaybackFile(LibraryId(libraryId), ServiceFile("1"), Duration.ZERO) } returns
FakePreparedPlayableFile(
ResolvablePlaybackHandler().apply { resolve() }
FakeBufferingPlaybackHandler()
).toPromise()

every { promisePreparedPlaybackFile(LibraryId(libraryId), ServiceFile("2"), Duration.ZERO) } returns
FakePreparedPlayableFile(
ResolvablePlaybackHandler().apply { resolve() }
FakeBufferingPlaybackHandler()
).toPromise()

every { promisePreparedPlaybackFile(LibraryId(libraryId), ServiceFile("3"), Duration.ZERO) } returns
Expand All @@ -59,7 +60,7 @@ class `When Playback is Resumed` {
every { promisePreparedPlaybackFile(LibraryId(libraryId), any(), any()) } returns FakePreparedPlayableFile(ResolvablePlaybackHandler()).toPromise()

every { promisePreparedPlaybackFile(LibraryId(libraryId), ServiceFile("3"), Duration.millis(164)) } returns FakePreparedPlayableFile(
expectedPlaybackHandler.apply { resolve() }
expectedPlaybackHandler
).toPromise()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,17 @@ import com.lasthopesoftware.bluewater.client.browsing.library.access.FakePlaybac
import com.lasthopesoftware.bluewater.client.browsing.library.repository.Library
import com.lasthopesoftware.bluewater.client.browsing.library.repository.LibraryId
import com.lasthopesoftware.bluewater.client.connection.selected.GivenANullConnection.AndTheSelectedLibraryChanges.FakeSelectedLibraryProvider
import com.lasthopesoftware.bluewater.client.playback.engine.LinkedOnPlayingFileChangedListener
import com.lasthopesoftware.bluewater.client.playback.engine.PlaybackEngine
import com.lasthopesoftware.bluewater.client.playback.engine.bootstrap.ManagedPlaylistPlayer
import com.lasthopesoftware.bluewater.client.playback.engine.events.OnPlayingFileChanged
import com.lasthopesoftware.bluewater.client.playback.engine.preparation.PreparedPlaybackQueueResourceManagement
import com.lasthopesoftware.bluewater.client.playback.file.PositionedFile
import com.lasthopesoftware.bluewater.client.playback.file.PositionedPlayingFile
import com.lasthopesoftware.bluewater.client.playback.file.fakes.FakePreparedPlayableFile
import com.lasthopesoftware.bluewater.client.playback.file.fakes.ResolvablePlaybackHandler
import com.lasthopesoftware.bluewater.client.playback.file.preparation.queues.CompletingFileQueueProvider
import com.lasthopesoftware.bluewater.client.playback.nowplaying.LockingNowPlayingRepository
import com.lasthopesoftware.bluewater.client.playback.nowplaying.storage.NowPlayingRepository
import com.lasthopesoftware.bluewater.client.playback.volume.PlaylistVolumeManager
import com.lasthopesoftware.bluewater.shared.promises.extensions.DeferredPromise
Expand Down Expand Up @@ -61,10 +64,13 @@ class `When changing tracks many times` {
},
FakePlaybackQueueConfiguration()
)
val repository = NowPlayingRepository(
FakeSelectedLibraryProvider(),
libraryProvider,
val repository = LockingNowPlayingRepository(
NowPlayingRepository(
FakeSelectedLibraryProvider(),
libraryProvider,
)
)
repository.open()
val playbackBootstrapper = ManagedPlaylistPlayer(
PlaylistVolumeManager(1.0f),
preparedPlaybackQueueResourceManagement,
Expand All @@ -79,7 +85,7 @@ class `When changing tracks many times` {
playbackBootstrapper,
playbackBootstrapper,
)
Pair(deferredPlaybackHandlers, playbackEngine)
Triple(deferredPlaybackHandlers, repository, playbackEngine)
}

private var nextSwitchedFile: PositionedFile? = null
Expand All @@ -88,21 +94,28 @@ class `When changing tracks many times` {

@BeforeAll
fun act() {
val (preparedFiles, playbackEngine) = mut
val (preparedFiles, repository, playbackEngine) = mut

val promisedFinalFile = Promise {
playbackEngine
.setOnPlayingFileChanged { _, p ->
startedFiles.add(p?.asPositionedFile())
var onPlayingFileChanged = OnPlayingFileChanged { _, p -> startedFiles.add(p?.asPositionedFile()) }

if (p?.playlistPosition == 4)
it.sendResolution(p)
}
val promisedFirstFile = Promise {
onPlayingFileChanged = LinkedOnPlayingFileChangedListener(onPlayingFileChanged) { _, p ->
if (p?.playlistPosition == 1)
it.sendResolution(p)
}
}

val promisedFinalFile = Promise {
onPlayingFileChanged = LinkedOnPlayingFileChangedListener(onPlayingFileChanged) { _, p ->
if (p?.playlistPosition == 4)
it.sendResolution(p)
}
}

val playlist = preparedFiles.keys.toList()

val promisedStart = playbackEngine
.setOnPlayingFileChanged(onPlayingFileChanged)
.startPlaylist(
LibraryId(libraryId),
playlist,
Expand All @@ -112,6 +125,9 @@ class `When changing tracks many times` {
val (playingPlaybackHandler, resolvablePlaybackHandler) = preparedFiles.getValue(ServiceFile("2"))
resolvablePlaybackHandler.resolve()
promisedStart.toExpiringFuture().get()
promisedFirstFile.toExpiringFuture().get()

repository.close()

val promisedChanges = Promise.whenAll(
playbackEngine.changePosition(0, Duration.ZERO),
Expand All @@ -125,6 +141,8 @@ class `When changing tracks many times` {
val finalPreparableFile = preparedFiles[playlist[4]]
finalPreparableFile?.second?.resolve()

repository.open()

nextSwitchedFile = promisedChanges.toExpiringFuture().get()?.lastOrNull()?.second

// Resolve the first skipped track afterward to ensure a cancellation is tested.
Expand All @@ -140,7 +158,7 @@ class `When changing tracks many times` {

@Test
fun `then the engine is playing`() {
assertThat(mut.second.isPlaying).isTrue
assertThat(mut.third.isPlaying).isTrue
}

@Test
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.lasthopesoftware.bluewater.client.playback.engine

import com.lasthopesoftware.bluewater.client.browsing.library.repository.LibraryId
import com.lasthopesoftware.bluewater.client.playback.engine.events.OnPlayingFileChanged
import com.lasthopesoftware.bluewater.client.playback.file.PositionedPlayingFile

class LinkedOnPlayingFileChangedListener(private val previous: OnPlayingFileChanged, private val next: OnPlayingFileChanged) : OnPlayingFileChanged {
override fun onPlayingFileChanged(libraryId: LibraryId, positionedPlayingFile: PositionedPlayingFile?) {
previous.onPlayingFileChanged(libraryId, positionedPlayingFile)
next.onPlayingFileChanged(libraryId, positionedPlayingFile)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import com.namehillsoftware.handoff.promises.MessengerOperator
import org.joda.time.Duration
import kotlin.coroutines.cancellation.CancellationException

class ResolvablePlaybackHandler : FakeBufferingPlaybackHandler() {
open class ResolvablePlaybackHandler : FakeBufferingPlaybackHandler() {
private var messenger: Messenger<PlayedFile>? = null

private val promise: ProgressedPromise<Duration, PlayedFile> = object : ProgressedPromise<Duration, PlayedFile>(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@ import org.assertj.core.api.Assertions.assertThat
import org.joda.time.Duration
import org.junit.jupiter.api.BeforeAll
import org.junit.jupiter.api.Test
import java.util.concurrent.CancellationException
import java.util.concurrent.ExecutionException
import java.util.concurrent.TimeUnit
import java.util.concurrent.TimeoutException

class `When Halting Playback` {

Expand All @@ -35,7 +36,7 @@ class `When Halting Playback` {
}

private var isCompleted = false
private var exception: Throwable? = null
private var exception: CancellationException? = null

@BeforeAll
fun act() {
Expand All @@ -46,10 +47,8 @@ class `When Halting Playback` {
try {
promisedPlayback.get(3, TimeUnit.SECONDS)
isCompleted = false
} catch (e: TimeoutException) {
// ignore
} catch (e: Throwable) {
exception = e
} catch (e: ExecutionException) {
exception = e.cause as? CancellationException
}
}

Expand All @@ -64,7 +63,7 @@ class `When Halting Playback` {
}

@Test
fun `then the closed resource exception is ignored`() {
assertThat(exception).isNull()
fun `then playback resolves with a cancellation exception`() {
assertThat(exception).isNotNull()
}
}