package com.projectsacrifice.game; import static org.junit.Assert.assertEquals; 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 CharacterStateIntegrationTest { @Test public void gameViewPublishesMovementAndCommandStates() throws Exception { Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation(); try (ActivityScenario activity = ActivityScenario.launch(MainActivity.class)) { GameView[] view = new GameView[1]; activity.onActivity(current -> view[0] = current.gameViewForAutomation()); instrumentation.runOnMainSync(() -> view[0].startLevelForAutomation(1)); awaitState(instrumentation, view[0], CharacterStateMachine.State.IDLE, 3_000L); instrumentation.runOnMainSync( () -> view[0].setAutomationInput(false, true, false)); awaitState(instrumentation, view[0], CharacterStateMachine.State.RUN, 3_000L); instrumentation.runOnMainSync( () -> view[0].setAutomationInput(true, false, false)); awaitState(instrumentation, view[0], CharacterStateMachine.State.TURN, 3_000L); instrumentation.runOnMainSync( () -> view[0].setAutomationInput(false, true, true)); awaitState(instrumentation, view[0], CharacterStateMachine.State.JUMP, 3_000L); instrumentation.runOnMainSync( () -> view[0].setAutomationInput(false, true, false)); awaitState(instrumentation, view[0], CharacterStateMachine.State.FALL, 3_000L); awaitState(instrumentation, view[0], CharacterStateMachine.State.LAND, 3_000L); instrumentation.runOnMainSync(view[0]::triggerInteractionForAutomation); assertEquals(CharacterStateMachine.State.INTERACT, state(instrumentation, view[0])); instrumentation.runOnMainSync(view[0]::triggerStunForAutomation); assertEquals(CharacterStateMachine.State.STUNNED, state(instrumentation, view[0])); } } private static void awaitState(Instrumentation instrumentation, GameView view, CharacterStateMachine.State expected, long timeoutMillis) throws Exception { long deadline = System.currentTimeMillis() + timeoutMillis; CharacterStateMachine.State current = state(instrumentation, view); while (System.currentTimeMillis() < deadline) { current = state(instrumentation, view); if (current == expected) return; Thread.sleep(24L); } throw new AssertionError("Expected " + expected + " but was " + current); } private static CharacterStateMachine.State state( Instrumentation instrumentation, GameView view) { CharacterStateMachine.State[] result = new CharacterStateMachine.State[1]; instrumentation.runOnMainSync( () -> result[0] = view.characterStateForAutomation()); return result[0]; } }