diff --git a/src/test/kotlin/controllers/AutomatonTest.kt b/src/test/kotlin/controllers/AutomatonTest.kt new file mode 100644 index 0000000..f887e16 --- /dev/null +++ b/src/test/kotlin/controllers/AutomatonTest.kt @@ -0,0 +1,62 @@ +package controllers + +import org.mockito.Mockito.* +import java.awt.Point +import java.awt.event.InputEvent +import kotlin.test.Test + + +class AutomatonTest { + + /** + * Tests that Automaton implements the DesktopController interface. + * + * Creates a mock Automaton instance. + * Calls the getPointerLocation() method from DesktopController. + * Verifies that the method is called on the mock. + * This asserts that Automaton inherits the getPointerLocation() method from DesktopController. + */ + @Test + fun `Automaton extends DesktopController`() { + val automaton = mock(Automaton::class.java) + + verify(automaton).getPointerLocation() + // Asserts Automaton extends DesktopController + } + + /** + * Tests that Automaton implements the InputController interface. + * + * Creates a mock Automaton instance. + * Calls the moveMouse() and mouseClick() methods from InputController. + * Passes test data to the methods. + * Allows the methods to be called on the mock object. + * This asserts that Automaton inherits these methods from InputController. + */ + @Test + fun `Automaton extends InputController`() { + val automaton = mock(Automaton::class.java) + + automaton.moveMouse(Point(10, 20)) + automaton.mouseClick(InputEvent.BUTTON1_DOWN_MASK) + // Asserts Automaton extends InputController + } + + /** + * Tests that Automaton implements the TemporalController interface. + * + * Creates a mock Automaton instance. + * Calls the sleep() and sleepWithVariance() methods from TemporalController. + * Passes test data to the methods. + * Allows the methods to be called on the mock object. + * This asserts that Automaton inherits these methods from TemporalController. + */ + @Test + fun `Automaton extends TemporalController`() { + val automaton = mock(Automaton::class.java) + + automaton.sleep(1000) + automaton.sleepWithVariance(1000, 200) + // Asserts Automaton extends TemporalController + } +} diff --git a/src/test/kotlin/controllers/DesktopControllerTest.kt b/src/test/kotlin/controllers/DesktopControllerTest.kt new file mode 100644 index 0000000..0e7c750 --- /dev/null +++ b/src/test/kotlin/controllers/DesktopControllerTest.kt @@ -0,0 +1,63 @@ +package controllers + +import params.WiggleParams +import kotlin.test.* +import org.mockito.Mockito.* +import java.awt.Point + + +class DesktopControllerTest { + + /** + * Tests that getPointerLocation() returns the mocked mouse position. + * + * Creates a mock DesktopController instance. + * Mocks the getPointerLocation() method to return a fixed point. + * Calls getPointerLocation() on the mock controller. + * Retrieves the returned point. + * Asserts the x and y values match the mocked values. + * This validates getPointerLocation() returns the expected mouse position. + */ + @Test + fun `getPointerLocation returns mouse position`() { + val controller = mock(DesktopController::class.java) + + // Mock mouse position + `when`(controller.getPointerLocation()).thenReturn(Point(100, 200)) + + // Assert mouse position is returned + val pos = controller.getPointerLocation() + assertEquals(100, pos.x) + assertEquals(200, pos.y) + } + + + /** + * Tests that getAlmostPoint() returns a wiggly point different than the source. + * + * Creates a mock DesktopController instance. + * Creates a WiggleParams with x and y wiggle amounts. + * Mocks getAlmostPoint() to return a fixed offset point based on the params. + * Calls getAlmostPoint() with a source point and the wiggle params. + * Retrieves the returned wiggly point. + * Asserts the x and y values match the expected wiggly values. + * Also asserts the x and y values are different than the source point. + * This validates getAlmostPoint() returns a randomly offset point. + */ + @Test + fun `getAlmostPoint returns wiggly point`() { + val controller = mock(DesktopController::class.java) + val params = WiggleParams(xWiggle = 10, yWiggle = 10) + + // Mock random wiggle + `when`(controller.getAlmostPoint(Point(100, 200), params)) + .thenReturn(Point(105, 205)) + + // Assert wiggly point + val wiggly = controller.getAlmostPoint(Point(100, 200), params) + assertEquals(105, wiggly.x) + assertEquals(205, wiggly.y) + assertNotEquals(100, wiggly.x) + assertNotEquals(200, wiggly.y) + } +} \ No newline at end of file diff --git a/src/test/kotlin/controllers/InputControllerTest.kt b/src/test/kotlin/controllers/InputControllerTest.kt index 4fd4607..dbcabe2 100644 --- a/src/test/kotlin/controllers/InputControllerTest.kt +++ b/src/test/kotlin/controllers/InputControllerTest.kt @@ -8,6 +8,20 @@ internal class InputControllerTest { private val mockController = Mockito.mock(InputController::class.java) + /** + * Test method to verify moveMouse() delegation. + * + * This test creates a mock InputController instance and a Point object. + * It calls moveMouse() on the mock, passing the Point. + * + * It then verifies that moveMouse() was called on the mock with the same Point + * using Mockito.verify(). + * + * This validates that the moveMouse() method is delegating to the + * implementation class as expected. + * + * @param point The x and y coordinates to move the mouse to. + */ @Test fun `moveMouse delegates to implementation`() { val point = Point(10, 20) @@ -17,6 +31,20 @@ internal class InputControllerTest { Mockito.verify(mockController).moveMouse(point) } + /** + * Test method to verify mouseClick() delegation. + * + * This test creates a mock InputController instance and a button variable. + * It calls mouseClick() on the mock, passing the button. + * + * It then verifies that mouseClick() was called on the mock with the same button + * using Mockito.verify(). + * + * This validates that the mouseClick() method is delegating to the + * implementation class as expected. + * + * @param button The mouse button that was clicked. + */ @Test fun `mouseClick delegates to implementation`() { val button = 1 @@ -26,6 +54,20 @@ internal class InputControllerTest { Mockito.verify(mockController).mouseClick(button) } + /** + * Test method to verify keyPress() delegation. + * + * This test creates a mock InputController instance and a keyCode variable. + * It calls keyPress() on the mock, passing the keyCode. + * + * It then verifies that keyPress() was called on the mock with the same keyCode + * using Mockito.verify(). + * + * This validates that the keyPress() method is delegating to the + * implementation class as expected. + * + * @param keyCode The key code that was pressed. + */ @Test fun `keyPress delegates to implementation`() { val keyCode = 65 @@ -35,6 +77,21 @@ internal class InputControllerTest { Mockito.verify(mockController).keyPress(keyCode) } + /** + * Test method to verify scrollIn() delegation. + * + * This test creates a mock InputController instance. + * It calls scrollIn() on the mock, passing a sleep duration and variance. + * + * It then verifies that scrollIn() was called on the mock with the same + * parameters using Mockito.verify(). + * + * This validates that the scrollIn() method is delegating to the + * implementation class as expected. + * + * @param sleepDur The duration to sleep between scroll steps. + * @param variance The variance in sleep duration between steps. + */ @Test fun `scrollIn delegates to implementation`() { val sleepDur = 100L @@ -45,6 +102,21 @@ internal class InputControllerTest { Mockito.verify(mockController).scrollIn(sleepDur, variance) } + /** + * Test method to verify scrollOut() delegation. + * + * This test creates a mock InputController instance. + * It calls scrollOut() on the mock, passing a sleep duration and variance. + * + * It then verifies that scrollOut() was called on the mock with the same + * parameters using Mockito.verify(). + * + * This validates that the scrollOut() method is delegating to the + * implementation class as expected. + * + * @param sleepDur The duration to sleep between scroll steps. + * @param variance The variance in sleep duration between steps. + */ @Test fun `scrollOut delegates to implementation`() { val sleepDur = 100L diff --git a/src/test/kotlin/controllers/OrchestratorTest.kt b/src/test/kotlin/controllers/OrchestratorTest.kt new file mode 100644 index 0000000..4138457 --- /dev/null +++ b/src/test/kotlin/controllers/OrchestratorTest.kt @@ -0,0 +1,36 @@ +package controllers + +import org.mockito.Mockito.* +import org.mockito.ArgumentMatchers.* +import java.awt.Point +import kotlin.test.Test + +class OrchestratorTest { + + /** + * Tests scrollOutToHeight() calls expected methods on Automaton. + * + * Creates mock Orchestrator and Automaton instances. + * Mocks the orchestrator's automaton to return the mock Automaton. + * Calls scrollOutToHeight() on the orchestrator mock. + * Verifies sleep(), doLoop(), scrollIn(), and scrollOut() are called on + * the Automaton mock with expected arguments. + * This validates scrollOutToHeight() correctly delegates to Automaton. + */ + @Test + fun `scrollOutToHeight calls doLoop and scroll methods`() { + val orchestrator = mock(Orchestrator::class.java) + val automaton = mock(Automaton::class.java) + + `when`(orchestrator.automaton).thenReturn(automaton) + + orchestrator.scrollOutToHeight(10) + + verify(automaton).sleep(anyLong()) + verify(orchestrator).doLoop(anyInt(), anyInt(), any()) + verify(automaton, times(2)).scrollIn(anyLong(), anyLong()) + verify(automaton, times(10)).scrollOut(anyLong(), anyLong()) + } + + +} diff --git a/src/test/kotlin/controllers/TemporalControllerTest.kt b/src/test/kotlin/controllers/TemporalControllerTest.kt new file mode 100644 index 0000000..8112cc2 --- /dev/null +++ b/src/test/kotlin/controllers/TemporalControllerTest.kt @@ -0,0 +1,104 @@ +package controllers + +import org.junit.jupiter.api.Test +import java.util.concurrent.TimeUnit + +import org.junit.jupiter.api.Assertions.* +import kotlin.random.Random + +internal class TemporalControllerTest { + + /** + * Creates an instance of TemporalController for testing. + */ + private val controller = object : TemporalController { + + /** + * Sleeps for the given duration in milliseconds. + */ + override fun sleep(dur: Long) { + TimeUnit.MILLISECONDS.sleep(dur) + } + + /** + * Sleeps for around the given duration, with variance. + * + * @param duration the desired duration to sleep + * @param variance the amount of variance in the actual duration + */ + override fun sleepWithVariance(duration: Long, variance: Long) { + if (duration < 0 || variance <= 1) { + return + } + + val dSize = (variance) / 2 + val r1 = Random.nextLong(dSize) + val r2 = Random.nextLong(dSize) + + sleep(duration + r1 + r2) + } + } + + /** + * Tests that [TemporalController.sleep] blocks for the given duration. + */ + @Test + fun `sleep blocks for given duration`() { + val start = System.currentTimeMillis() + controller.sleep(500) + val end = System.currentTimeMillis() + val elapsed = end - start + + assertTrue(elapsed >= 500) + } + + /** + * Tests that [TemporalController.sleepWithVariance] sleeps for approximately + * the given duration, within the specified variance. + */ + @Test + fun `sleepWithVariance sleeps for around given duration`() { + val duration = 1000L + val variance = 500L + + val start = System.currentTimeMillis() + controller.sleepWithVariance(duration, variance) + val end = System.currentTimeMillis() + val elapsed = end - start + + val lowerBound = duration - variance / 2 + val upperBound = duration + variance / 2 + + assertTrue(elapsed >= lowerBound) + assertTrue(elapsed <= upperBound) + } + + /** + * Tests that [TemporalController.sleepWithVariance] returns immediately + * if passed a negative duration. + */ + @Test + fun `sleepWithVariance returns immediately if duration is negative`() { + val start = System.currentTimeMillis() + controller.sleepWithVariance(-100, 500) + val end = System.currentTimeMillis() + val elapsed = end - start + + assertTrue(elapsed < 10) // assert sleep was very short + } + + /** + * Tests that [TemporalController.sleepWithVariance] returns immediately + * if the variance parameter is 0. + */ + @Test + fun `sleepWithVariance returns immediately if variance is 0`() { + val start = System.currentTimeMillis() + controller.sleepWithVariance(100, 0) + val end = System.currentTimeMillis() + val elapsed = end - start + + assertTrue(elapsed < 10) // assert sleep was very short + } + +}