Unit tests for MusicManager.java

This commit is contained in:
lieght
2025-10-11 23:08:28 +02:00
parent d958b9730a
commit 73a2fe3da2
2 changed files with 222 additions and 20 deletions

View File

@@ -28,13 +28,10 @@ public class MusicManager<T extends AudioResource> implements org.toop.framework
}
// Used in unit testing
MusicManager(Class<T> type, Dispatcher dispatcher, ResourceManager resourceManager) {
MusicManager(List<T> resources, Dispatcher dispatcher) {
this.dispatcher = dispatcher;
this.resources = new ArrayList<>(resourceManager.getAllOfType((Class<? extends BaseResource>) type)
.stream()
.map(e -> (T) e.getResource())
.toList());
createShuffled();
this.resources = new ArrayList<>(resources);
backgroundMusic.addAll(resources);
}
@Override
@@ -42,7 +39,7 @@ public class MusicManager<T extends AudioResource> implements org.toop.framework
return backgroundMusic;
}
private void addBackgroundMusic(T musicAsset) {
void addBackgroundMusic(T musicAsset) {
backgroundMusic.add(musicAsset);
}
@@ -65,6 +62,20 @@ public class MusicManager<T extends AudioResource> implements org.toop.framework
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() {
if (playingIndex >= backgroundMusic.size()) {
playingIndex = 0;
@@ -80,21 +91,27 @@ public class MusicManager<T extends AudioResource> implements org.toop.framework
dispatcher.run(() -> {
current.play();
current.setOnEnd(() -> {
setTrackRunnable(current);
});
}
private void setTrackRunnable(T track) {
track.setOnEnd(() -> {
playingIndex++;
playCurrentTrack();
});
current.setOnError(() -> {
logger.error("Error playing track: {}", current);
backgroundMusic.remove(current);
track.setOnError(() -> {
logger.error("Error playing track: {}", track);
backgroundMusic.remove(track);
if (!backgroundMusic.isEmpty()) {
playCurrentTrack();
} else {
playing = false;
}
});
});
}
public void stop() {

View File

@@ -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");
}
}
}