Files
Jander_Semester2/Semesterprojekt/src/test/java/thb/jeanluc/adventure/AppQuitTest.java
Jean-Luc Makiola d0966c3ce4 fix(menu): main-menu Quit now closes the GUI instead of revealing the game
App.run ended its menu loop on Quit and just returned. The console exits then,
but in the GUI run() is on a daemon worker while the Swing JFrame stays
displayable on the EDT, keeping the JVM alive — and the dismissed menu overlay
just revealed the running game underneath ("back into the game"). EXIT_ON_CLOSE
only fires for the native window X, not a programmatic quit.

Add a GameIO.shutdown() teardown hook (default no-op) and call it after the menu
loop ends. SwingIO overrides it to stop music, dispose the window, and exit the
JVM, mirroring EXIT_ON_CLOSE; console keeps the no-op. Extract an injectable
App.run overload and add AppQuitTest asserting the Quit path invokes shutdown().

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-02 09:39:05 +02:00

53 lines
1.7 KiB
Java

package thb.jeanluc.adventure;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;
import thb.jeanluc.adventure.io.TestIO;
import thb.jeanluc.adventure.save.SaveService;
import thb.jeanluc.adventure.save.SettingsStore;
import java.nio.file.Path;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Regression test for the main-menu Quit: choosing Quit must end the menu loop
* AND tell the frontend to tear down. Previously {@code run} just returned,
* which exits the console but left the Swing window open (the menu overlay
* closed and the game reappeared underneath). We assert the frontend-agnostic
* contract: the Quit path invokes {@link thb.jeanluc.adventure.io.GameIO#shutdown()}.
*/
class AppQuitTest {
/** Fake IO that always picks the last menu option (Quit) and records shutdown. */
private static final class QuitIO extends TestIO {
boolean shutdownCalled;
int chooseCalls;
@Override
public int choose(String title, List<String> options) {
chooseCalls++;
return options.size() - 1; // Quit is the last main-menu option
}
@Override
public void shutdown() {
shutdownCalled = true;
}
}
@Test
void choosingQuit_tearsDownTheFrontend(@TempDir Path tmp) {
QuitIO io = new QuitIO();
SaveService saves = new SaveService(tmp.resolve("saves"));
SettingsStore settings = new SettingsStore(tmp.resolve("settings.json"));
App.run(io, saves, settings);
assertThat(io.shutdownCalled).isTrue();
assertThat(io.chooseCalls).isEqualTo(1); // straight to Quit, no game started
assertThat(io.allOutput()).contains("Farewell.");
}
}