universe@13: package de.uapcore.sudoku; universe@13: universe@13: universe@13: import org.junit.jupiter.api.AfterEach; universe@13: import org.junit.jupiter.api.BeforeEach; universe@13: import org.junit.jupiter.api.Test; universe@13: universe@13: import javax.swing.*; universe@13: import java.awt.event.KeyEvent; universe@13: import java.lang.reflect.InvocationTargetException; universe@13: universe@13: import static org.junit.jupiter.api.Assertions.*; universe@13: universe@13: class SudokuTextFieldTest { universe@13: universe@13: private void dispatch(SudokuTextField tf, KeyEvent pressed) { universe@13: final var released = new KeyEvent(tf, KeyEvent.KEY_RELEASED, pressed.getWhen()+1, universe@13: pressed.getModifiersEx(), pressed.getKeyCode(), pressed.getKeyChar()); universe@13: final KeyEvent typed; universe@13: if (pressed.getKeyChar() != KeyEvent.CHAR_UNDEFINED) { universe@13: typed = new KeyEvent(tf, KeyEvent.KEY_TYPED, pressed.getWhen(), universe@13: pressed.getModifiersEx(), KeyEvent.VK_UNDEFINED, pressed.getKeyChar()); universe@13: } else { universe@13: typed = null; universe@13: } universe@13: tf.requestFocusInWindow(); universe@13: tf.dispatchEvent(pressed); universe@13: if (typed != null) { universe@13: tf.dispatchEvent(typed); universe@13: } universe@13: tf.dispatchEvent(released); universe@13: } universe@13: universe@13: private JFrame testFrame; universe@13: universe@13: @BeforeEach universe@13: void createTestFrame() { universe@13: // we have to use a visible frame for the events to be dispatched universe@13: testFrame = new JFrame(); universe@13: testFrame.setVisible(true); universe@13: } universe@13: universe@13: @AfterEach universe@13: void disposeTestFrame() { universe@13: testFrame.dispose(); universe@13: } universe@13: universe@13: private SudokuTextField createTestSubject() { universe@13: final var tf = new SudokuTextField(); universe@13: testFrame.add(tf); universe@13: return tf; universe@13: } universe@13: universe@13: @Test universe@13: void getValue() { universe@13: universe@13: } universe@13: universe@13: @Test universe@13: void setValue() { universe@13: // given universe@13: final var tf = createTestSubject(); universe@13: for (int i = 0 ; i <= 9 ; i++) { universe@13: // when universe@13: tf.setValue(i); universe@13: // then universe@13: assertEquals(i, tf.getValue()); universe@13: assertEquals(i == 0 ? "" : String.valueOf(i), tf.getText()); universe@13: assertFalse(tf.isModified()); universe@13: } universe@13: } universe@13: universe@13: @Test universe@13: void setInvalidValue() { universe@13: // given universe@13: final var tf = createTestSubject(); universe@13: // when / then universe@13: assertThrows(IllegalArgumentException.class, () -> tf.setValue(10)); universe@13: assertThrows(IllegalArgumentException.class, () -> tf.setValue(-1)); universe@13: assertFalse(tf.isModified()); universe@13: } universe@13: universe@13: @Test universe@13: void testModifiedByCall() { universe@13: // given universe@13: final var tf = createTestSubject(); universe@13: // then initially universe@13: assertFalse(tf.isModified()); universe@13: // when universe@13: tf.setModified(true); universe@13: // then universe@13: assertTrue(tf.isModified()); universe@13: // when universe@13: tf.setModified(false); universe@13: // then universe@13: assertFalse(tf.isModified()); universe@13: } universe@13: universe@13: @Test universe@13: void testModifiedByKeystroke() throws InvocationTargetException, InterruptedException { universe@13: // given universe@13: final var tf = createTestSubject(); universe@13: assertFalse(tf.isModified()); universe@13: final var event = new KeyEvent(tf, KeyEvent.KEY_PRESSED, System.currentTimeMillis(), universe@13: 0, KeyEvent.VK_4, '4'); universe@13: SwingUtilities.invokeAndWait(() -> { universe@13: // when universe@13: dispatch(tf, event); universe@13: // then universe@13: assertTrue(tf.isModified()); universe@13: }); universe@13: } universe@13: universe@13: @Test universe@13: void testTextChangeByKeystore() throws InvocationTargetException, InterruptedException { universe@13: // given universe@13: final var tf = createTestSubject(); universe@13: assertEquals("", tf.getText()); universe@13: final var event = new KeyEvent(tf, KeyEvent.KEY_PRESSED, System.currentTimeMillis(), universe@13: 0, KeyEvent.VK_4, '4'); universe@13: SwingUtilities.invokeAndWait(() -> { universe@13: // when universe@13: dispatch(tf, event); universe@13: // then universe@13: assertEquals("4", tf.getText()); universe@13: }); universe@13: } universe@13: universe@13: @Test universe@16: void testNumpad() throws InvocationTargetException, InterruptedException { universe@16: // given universe@16: final var tf = createTestSubject(); universe@16: assertEquals("", tf.getText()); universe@16: final var event = new KeyEvent(tf, KeyEvent.KEY_PRESSED, System.currentTimeMillis(), universe@16: 0, KeyEvent.VK_NUMPAD4, '4'); universe@16: SwingUtilities.invokeAndWait(() -> { universe@16: // when universe@16: dispatch(tf, event); universe@16: // then universe@16: assertEquals("4", tf.getText()); universe@16: }); universe@16: } universe@16: universe@16: @Test universe@13: void testTextOverwriteByKeystore() throws InvocationTargetException, InterruptedException { universe@13: // given universe@13: final var tf = createTestSubject(); universe@13: tf.setText("6"); universe@13: tf.selectAll(); universe@13: final var event = new KeyEvent(tf, KeyEvent.KEY_PRESSED, System.currentTimeMillis(), universe@13: 0, KeyEvent.VK_4, '4'); universe@13: SwingUtilities.invokeAndWait(() -> { universe@13: // when universe@13: dispatch(tf, event); universe@13: // then universe@13: assertEquals("4", tf.getText()); universe@13: }); universe@13: } universe@13: universe@13: @Test universe@13: void testNumbersOnly() throws InvocationTargetException, InterruptedException { universe@13: // given universe@13: final var tf = createTestSubject(); universe@13: tf.setText("6"); universe@13: tf.selectAll(); universe@13: final var event = new KeyEvent(tf, KeyEvent.KEY_PRESSED, System.currentTimeMillis(), universe@13: 0, KeyEvent.VK_A, 'a'); universe@13: SwingUtilities.invokeAndWait(() -> { universe@13: // when universe@13: dispatch(tf, event); universe@13: // then universe@13: assertEquals("6", tf.getText()); universe@13: }); universe@13: } universe@13: universe@13: @Test universe@13: void testSingleDigit() throws InvocationTargetException, InterruptedException { universe@13: // given universe@13: final var tf = createTestSubject(); universe@13: assertEquals("", tf.getText()); universe@13: final var firstEvent = new KeyEvent(tf, KeyEvent.KEY_PRESSED, System.currentTimeMillis(), universe@13: 0, KeyEvent.VK_A, '4'); universe@13: final var secondEvent = new KeyEvent(tf, KeyEvent.KEY_PRESSED, System.currentTimeMillis(), universe@13: 0, KeyEvent.VK_A, '6'); universe@13: SwingUtilities.invokeAndWait(() -> { universe@13: // when universe@13: dispatch(tf, firstEvent); universe@13: dispatch(tf, secondEvent); universe@13: // then universe@13: assertEquals("4", tf.getText()); universe@13: }); universe@13: } universe@13: universe@13: @Test universe@13: void testBackspace() throws InvocationTargetException, InterruptedException { universe@13: // given universe@13: final var tf = createTestSubject(); universe@13: assertEquals("", tf.getText()); universe@13: final var typeFour = new KeyEvent(tf, KeyEvent.KEY_PRESSED, System.currentTimeMillis(), universe@13: 0, KeyEvent.VK_A, '4'); universe@13: final var typeBackspace = new KeyEvent(tf, KeyEvent.KEY_PRESSED, System.currentTimeMillis(), universe@13: 0, KeyEvent.VK_BACK_SPACE, KeyEvent.CHAR_UNDEFINED); universe@13: final var typeSix = new KeyEvent(tf, KeyEvent.KEY_PRESSED, System.currentTimeMillis(), universe@13: 0, KeyEvent.VK_A, '6'); universe@13: SwingUtilities.invokeAndWait(() -> { universe@13: // when universe@13: dispatch(tf, typeFour); universe@13: dispatch(tf, typeBackspace); universe@13: dispatch(tf, typeSix); universe@13: // then universe@13: assertEquals("6", tf.getText()); universe@13: }); universe@13: } universe@13: }