mirror of
https://github.com/2OOP/pism.git
synced 2026-02-04 10:54:51 +00:00
Unit tests for MusicManager.java
This commit is contained in:
@@ -28,13 +28,10 @@ public class MusicManager<T extends AudioResource> implements org.toop.framework
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Used in unit testing
|
// Used in unit testing
|
||||||
MusicManager(Class<T> type, Dispatcher dispatcher, ResourceManager resourceManager) {
|
MusicManager(List<T> resources, Dispatcher dispatcher) {
|
||||||
this.dispatcher = dispatcher;
|
this.dispatcher = dispatcher;
|
||||||
this.resources = new ArrayList<>(resourceManager.getAllOfType((Class<? extends BaseResource>) type)
|
this.resources = new ArrayList<>(resources);
|
||||||
.stream()
|
backgroundMusic.addAll(resources);
|
||||||
.map(e -> (T) e.getResource())
|
|
||||||
.toList());
|
|
||||||
createShuffled();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -42,7 +39,7 @@ public class MusicManager<T extends AudioResource> implements org.toop.framework
|
|||||||
return backgroundMusic;
|
return backgroundMusic;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addBackgroundMusic(T musicAsset) {
|
void addBackgroundMusic(T musicAsset) {
|
||||||
backgroundMusic.add(musicAsset);
|
backgroundMusic.add(musicAsset);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,6 +62,20 @@ public class MusicManager<T extends AudioResource> implements org.toop.framework
|
|||||||
playCurrentTrack();
|
playCurrentTrack();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Used in testing
|
||||||
|
void play(int index) {
|
||||||
|
if (playing) {
|
||||||
|
logger.warn("MusicManager is already playing.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (backgroundMusic.isEmpty()) return;
|
||||||
|
|
||||||
|
playingIndex = index;
|
||||||
|
playing = true;
|
||||||
|
playCurrentTrack();
|
||||||
|
}
|
||||||
|
|
||||||
private void playCurrentTrack() {
|
private void playCurrentTrack() {
|
||||||
if (playingIndex >= backgroundMusic.size()) {
|
if (playingIndex >= backgroundMusic.size()) {
|
||||||
playingIndex = 0;
|
playingIndex = 0;
|
||||||
@@ -80,21 +91,27 @@ public class MusicManager<T extends AudioResource> implements org.toop.framework
|
|||||||
dispatcher.run(() -> {
|
dispatcher.run(() -> {
|
||||||
current.play();
|
current.play();
|
||||||
|
|
||||||
current.setOnEnd(() -> {
|
setTrackRunnable(current);
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setTrackRunnable(T track) {
|
||||||
|
track.setOnEnd(() -> {
|
||||||
playingIndex++;
|
playingIndex++;
|
||||||
playCurrentTrack();
|
playCurrentTrack();
|
||||||
});
|
});
|
||||||
|
|
||||||
current.setOnError(() -> {
|
track.setOnError(() -> {
|
||||||
logger.error("Error playing track: {}", current);
|
logger.error("Error playing track: {}", track);
|
||||||
backgroundMusic.remove(current);
|
backgroundMusic.remove(track);
|
||||||
|
|
||||||
if (!backgroundMusic.isEmpty()) {
|
if (!backgroundMusic.isEmpty()) {
|
||||||
playCurrentTrack();
|
playCurrentTrack();
|
||||||
} else {
|
} else {
|
||||||
playing = false;
|
playing = false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void stop() {
|
public void stop() {
|
||||||
|
|||||||
@@ -0,0 +1,185 @@
|
|||||||
|
package org.toop.framework.audio;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.toop.framework.audio.interfaces.Dispatcher;
|
||||||
|
import org.toop.framework.resource.resources.BaseResource;
|
||||||
|
import org.toop.framework.resource.types.AudioResource;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
|
class MockAudioResource extends BaseResource implements AudioResource {
|
||||||
|
boolean played = false;
|
||||||
|
boolean stopped = false;
|
||||||
|
Runnable onEnd;
|
||||||
|
Runnable onError;
|
||||||
|
|
||||||
|
public MockAudioResource(String name) {
|
||||||
|
super(new File(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void triggerError() {
|
||||||
|
if (onError != null) {
|
||||||
|
onError.run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void triggerEnd() {
|
||||||
|
if (onEnd != null) {
|
||||||
|
onEnd.run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void play() {
|
||||||
|
played = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void stop() {
|
||||||
|
stopped = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setOnEnd(Runnable callback) {
|
||||||
|
onEnd = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setOnError(Runnable callback) {
|
||||||
|
onError = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateVolume(double volume) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class MusicManagerTest {
|
||||||
|
|
||||||
|
private Dispatcher dispatcher;
|
||||||
|
private MockAudioResource track1;
|
||||||
|
private MockAudioResource track2;
|
||||||
|
private MockAudioResource track3;
|
||||||
|
private MusicManager<MockAudioResource> manager;
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void setUp() {
|
||||||
|
dispatcher = Runnable::run;
|
||||||
|
|
||||||
|
track1 = new MockAudioResource("track1");
|
||||||
|
track2 = new MockAudioResource("track2");
|
||||||
|
track3 = new MockAudioResource("track3");
|
||||||
|
|
||||||
|
List<MockAudioResource> resources = List.of(track1, track2, track3);
|
||||||
|
|
||||||
|
manager = new MusicManager<>(resources, dispatcher);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testPlaySingleTrack() {
|
||||||
|
manager.play();
|
||||||
|
assertTrue(track1.played || track2.played || track3.played,
|
||||||
|
"At least one track should have played");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testPlayMultipleTimesDoesNotRestart() {
|
||||||
|
manager.play();
|
||||||
|
track1.played = false;
|
||||||
|
manager.play();
|
||||||
|
assertFalse(track1.played, "Second play call should not restart tracks");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testStopStopsAllTracks() {
|
||||||
|
manager.play();
|
||||||
|
manager.stop();
|
||||||
|
assertTrue(track1.stopped && track2.stopped && track3.stopped,
|
||||||
|
"All tracks should be stopped");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testAutoAdvanceTracks() {
|
||||||
|
track1.played = false;
|
||||||
|
track2.played = false;
|
||||||
|
track3.played = false;
|
||||||
|
|
||||||
|
manager.play();
|
||||||
|
track1.triggerEnd();
|
||||||
|
track2.triggerEnd();
|
||||||
|
|
||||||
|
assertTrue(track1.played, "Track1 should play, played %s instead");
|
||||||
|
assertTrue(track2.played, "Track2 should play after track1 ends");
|
||||||
|
assertTrue(track3.played, "Track3 should play after track2 ends");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testTrackErrorRemovesTrackAndPlaysNext() {
|
||||||
|
manager.play();
|
||||||
|
track1.triggerError();
|
||||||
|
|
||||||
|
assertFalse(manager.getActiveAudio().contains(track1),
|
||||||
|
"Track1 should be removed after error");
|
||||||
|
assertTrue(track2.played, "Track2 should play after track1 error");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testPlayWithEmptyPlaylistDoesNothing() {
|
||||||
|
manager.getActiveAudio().clear();
|
||||||
|
manager.play();
|
||||||
|
assertFalse(track1.played || track2.played || track3.played,
|
||||||
|
"No tracks should play if playlist is empty");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testMultiplePlayStopSequences() {
|
||||||
|
manager.play();
|
||||||
|
manager.stop();
|
||||||
|
manager.play();
|
||||||
|
assertTrue(track1.played || track2.played || track3.played,
|
||||||
|
"Tracks should play again after stopping");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testPlayingIndexWrapsAround() {
|
||||||
|
track1.played = false;
|
||||||
|
track2.played = false;
|
||||||
|
track3.played = false;
|
||||||
|
|
||||||
|
manager.play();
|
||||||
|
track1.triggerEnd();
|
||||||
|
track2.triggerEnd();
|
||||||
|
track3.triggerEnd();
|
||||||
|
|
||||||
|
assertTrue(track1.played, "Track1 should play again after loop");
|
||||||
|
assertTrue(track2.played, "Track2 should play");
|
||||||
|
assertTrue(track3.played, "Track3 should play");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test for many tracks playing sequentially one after another
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
void testSequentialMultipleTracks() {
|
||||||
|
List<MockAudioResource> manyTracks = new ArrayList<>();
|
||||||
|
for (int i = 1; i <= 1_000; i++) {
|
||||||
|
manyTracks.add(new MockAudioResource("track" + i));
|
||||||
|
}
|
||||||
|
|
||||||
|
MusicManager<MockAudioResource> multiManager = new MusicManager<>(manyTracks, dispatcher);
|
||||||
|
|
||||||
|
for (int i = 0; i < manyTracks.size() - 1; i++) {
|
||||||
|
multiManager.play();
|
||||||
|
manyTracks.get(i).triggerEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < manyTracks.size(); i++) {
|
||||||
|
assertTrue(manyTracks.get(i).played, "Track " + (i + 1) + " should have played sequentially");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user