package com.projectsacrifice.game; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import android.app.Instrumentation; import androidx.test.core.app.ActivityScenario; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.platform.app.InstrumentationRegistry; import org.junit.Test; import org.junit.runner.RunWith; @RunWith(AndroidJUnit4.class) public final class GameRestartTest { @Test public void restartClearsBodiesSignalsTimerAndHeldInput() throws Exception { try (ActivityScenario activity = ActivityScenario.launch(MainActivity.class)) { Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation(); GameView[] view = new GameView[1]; activity.onActivity(current -> view[0] = current.gameViewForAutomation()); instrumentation.runOnMainSync(() -> { view[0].startLevelForAutomation(10); view[0].setAutomationInput(false, true, false); }); await(instrumentation, view[0], 4_000L, snapshot -> snapshot.deaths() == 1 && snapshot.corpseCount() == 1); instrumentation.runOnMainSync( () -> view[0].setAutomationInput(false, false, false)); await(instrumentation, view[0], 5_000L, GameView.AutomationSnapshot::firstMovingPlatformPowered); instrumentation.runOnMainSync(() -> { view[0].setAutomationInput(false, true, true); view[0].restartLevelForAutomation(); }); GameView.AutomationSnapshot restarted = snapshot(instrumentation, view[0]); assertEquals(10, restarted.levelNumber()); assertTrue(restarted.playerAlive()); assertEquals(0, restarted.deaths()); assertEquals(0, restarted.corpseCount()); assertFalse(restarted.firstMovingPlatformPowered()); assertFalse(restarted.inputActive()); assertTrue("Restarted timer must begin near zero: " + restarted.elapsedMilliseconds(), restarted.elapsedMilliseconds() < 200L); assertTrue("Restarted player must be at the level spawn: x=" + restarted.playerX(), restarted.playerX() >= 125f && restarted.playerX() <= 135f); assertEquals(790f, restarted.firstMovingPlatformY(), 0.5f); } } private static GameView.AutomationSnapshot await( Instrumentation instrumentation, GameView view, long timeoutMillis, LevelPlaytestBot.SnapshotCondition condition ) throws Exception { long deadline = System.currentTimeMillis() + timeoutMillis; GameView.AutomationSnapshot current = snapshot(instrumentation, view); while (System.currentTimeMillis() < deadline) { current = snapshot(instrumentation, view); if (condition.reached(current)) return current; Thread.sleep(32L); } throw new AssertionError("Restart setup timed out; level=" + current.levelNumber() + ", x=" + current.playerX() + ", deaths=" + current.deaths() + ", corpses=" + current.corpseCount()); } private static GameView.AutomationSnapshot snapshot( Instrumentation instrumentation, GameView view ) { GameView.AutomationSnapshot[] value = new GameView.AutomationSnapshot[1]; instrumentation.runOnMainSync(() -> value[0] = view.automationSnapshot()); return value[0]; } }