Tue, 28 Jul 2020 11:53:56 +0200
adds tests for focus events
1 package de.uapcore.sudoku;
4 import org.junit.jupiter.api.AfterEach;
5 import org.junit.jupiter.api.BeforeEach;
6 import org.junit.jupiter.api.Test;
8 import javax.swing.*;
9 import java.awt.*;
10 import java.awt.event.KeyEvent;
11 import java.lang.reflect.InvocationTargetException;
12 import java.util.concurrent.TimeUnit;
14 import static org.junit.jupiter.api.Assertions.*;
16 class SudokuTextFieldTest {
18 private void dispatch(SudokuTextField tf, KeyEvent pressed) {
19 final var released = new KeyEvent(tf, KeyEvent.KEY_RELEASED, pressed.getWhen()+1,
20 pressed.getModifiersEx(), pressed.getKeyCode(), pressed.getKeyChar());
21 final KeyEvent typed;
22 if (pressed.getKeyChar() != KeyEvent.CHAR_UNDEFINED) {
23 typed = new KeyEvent(tf, KeyEvent.KEY_TYPED, pressed.getWhen(),
24 pressed.getModifiersEx(), KeyEvent.VK_UNDEFINED, pressed.getKeyChar());
25 } else {
26 typed = null;
27 }
28 tf.requestFocusInWindow();
29 tf.dispatchEvent(pressed);
30 if (typed != null) {
31 tf.dispatchEvent(typed);
32 }
33 tf.dispatchEvent(released);
34 }
36 private JFrame testFrame;
38 @BeforeEach
39 void createTestFrame() {
40 // we have to use a visible frame for the events to be dispatched
41 testFrame = new JFrame();
42 testFrame.setVisible(true);
43 }
45 @AfterEach
46 void disposeTestFrame() {
47 testFrame.setVisible(false);
48 testFrame.dispose();
49 }
51 private SudokuTextField createTestSubject() {
52 final var tf = new SudokuTextField();
53 testFrame.add(tf);
54 return tf;
55 }
57 @Test
58 void setValue() {
59 // given
60 final var tf = createTestSubject();
61 for (int i = 0 ; i <= 9 ; i++) {
62 // when
63 tf.setValue(i);
64 // then
65 assertEquals(i, tf.getValue());
66 assertEquals(i == 0 ? "" : String.valueOf(i), tf.getText());
67 assertFalse(tf.isModified());
68 }
69 }
71 @Test
72 void setInvalidValue() {
73 // given
74 final var tf = createTestSubject();
75 // when / then
76 assertThrows(IllegalArgumentException.class, () -> tf.setValue(10));
77 assertThrows(IllegalArgumentException.class, () -> tf.setValue(-1));
78 assertFalse(tf.isModified());
79 }
81 @Test
82 void testModifiedByCall() {
83 // given
84 final var tf = createTestSubject();
85 // then initially
86 assertFalse(tf.isModified());
87 // when
88 tf.setModified(true);
89 // then
90 assertTrue(tf.isModified());
91 // when
92 tf.setModified(false);
93 // then
94 assertFalse(tf.isModified());
95 }
97 @Test
98 void testModifiedByKeystroke() throws InvocationTargetException, InterruptedException {
99 // given
100 final var tf = createTestSubject();
101 assertFalse(tf.isModified());
102 final var event = new KeyEvent(tf, KeyEvent.KEY_PRESSED, System.currentTimeMillis(),
103 0, KeyEvent.VK_4, '4');
104 SwingUtilities.invokeAndWait(() -> {
105 // when
106 dispatch(tf, event);
107 // then
108 assertTrue(tf.isModified());
109 });
110 }
112 @Test
113 void testTextChangeByKeystore() throws InvocationTargetException, InterruptedException {
114 // given
115 final var tf = createTestSubject();
116 assertEquals("", tf.getText());
117 final var event = new KeyEvent(tf, KeyEvent.KEY_PRESSED, System.currentTimeMillis(),
118 0, KeyEvent.VK_4, '4');
119 SwingUtilities.invokeAndWait(() -> {
120 // when
121 dispatch(tf, event);
122 // then
123 assertEquals("4", tf.getText());
124 });
125 }
127 @Test
128 void testNumpad() throws InvocationTargetException, InterruptedException {
129 // given
130 final var tf = createTestSubject();
131 assertEquals("", tf.getText());
132 final var event = new KeyEvent(tf, KeyEvent.KEY_PRESSED, System.currentTimeMillis(),
133 0, KeyEvent.VK_NUMPAD4, '4');
134 SwingUtilities.invokeAndWait(() -> {
135 // when
136 dispatch(tf, event);
137 // then
138 assertEquals("4", tf.getText());
139 });
140 }
142 @Test
143 void testTextOverwriteByKeystore() throws InvocationTargetException, InterruptedException {
144 // given
145 final var tf = createTestSubject();
146 tf.setText("6");
147 tf.selectAll();
148 final var event = new KeyEvent(tf, KeyEvent.KEY_PRESSED, System.currentTimeMillis(),
149 0, KeyEvent.VK_4, '4');
150 SwingUtilities.invokeAndWait(() -> {
151 // when
152 dispatch(tf, event);
153 // then
154 assertEquals("4", tf.getText());
155 });
156 }
158 @Test
159 void testNumbersOnly() throws InvocationTargetException, InterruptedException {
160 // given
161 final var tf = createTestSubject();
162 tf.setText("6");
163 tf.selectAll();
164 final var event = new KeyEvent(tf, KeyEvent.KEY_PRESSED, System.currentTimeMillis(),
165 0, KeyEvent.VK_A, 'a');
166 SwingUtilities.invokeAndWait(() -> {
167 // when
168 dispatch(tf, event);
169 // then
170 assertEquals("6", tf.getText());
171 });
172 }
174 @Test
175 void testSingleDigit() throws InvocationTargetException, InterruptedException {
176 // given
177 final var tf = createTestSubject();
178 assertEquals("", tf.getText());
179 final var firstEvent = new KeyEvent(tf, KeyEvent.KEY_PRESSED, System.currentTimeMillis(),
180 0, KeyEvent.VK_A, '4');
181 final var secondEvent = new KeyEvent(tf, KeyEvent.KEY_PRESSED, System.currentTimeMillis(),
182 0, KeyEvent.VK_A, '6');
183 SwingUtilities.invokeAndWait(() -> {
184 // when
185 dispatch(tf, firstEvent);
186 dispatch(tf, secondEvent);
187 // then
188 assertEquals("4", tf.getText());
189 });
190 }
192 @Test
193 void testBackspace() throws InvocationTargetException, InterruptedException {
194 // given
195 final var tf = createTestSubject();
196 assertEquals("", tf.getText());
197 final var typeFour = new KeyEvent(tf, KeyEvent.KEY_PRESSED, System.currentTimeMillis(),
198 0, KeyEvent.VK_A, '4');
199 final var typeBackspace = new KeyEvent(tf, KeyEvent.KEY_PRESSED, System.currentTimeMillis(),
200 0, KeyEvent.VK_BACK_SPACE, KeyEvent.CHAR_UNDEFINED);
201 final var typeSix = new KeyEvent(tf, KeyEvent.KEY_PRESSED, System.currentTimeMillis(),
202 0, KeyEvent.VK_A, '6');
203 SwingUtilities.invokeAndWait(() -> {
204 // when
205 dispatch(tf, typeFour);
206 dispatch(tf, typeBackspace);
207 dispatch(tf, typeSix);
208 // then
209 assertEquals("6", tf.getText());
210 });
211 }
213 @Test
214 void testFocusGained() throws InvocationTargetException, InterruptedException {
215 final var tf = createTestSubject();
216 SwingUtilities.invokeAndWait(() -> {
217 // given
218 tf.setText("5");
219 assertNull(tf.getSelectedText());
220 // when
221 tf.requestFocusInWindow();
222 });
223 // give WM time to deliver the event
224 TimeUnit.MILLISECONDS.sleep(100);
225 // then
226 SwingUtilities.invokeAndWait(() -> assertEquals("5", tf.getSelectedText()));
227 }
229 @Test
230 void testFocusLost() throws InvocationTargetException, InterruptedException {
231 final var tf = createTestSubject();
232 final var focusStealer = new TextField();
233 testFrame.add(focusStealer);
234 SwingUtilities.invokeAndWait(() -> {
235 // given
236 tf.setText("5");
237 tf.selectAll();
238 assertEquals("5", tf.getSelectedText());
239 // when
240 focusStealer.requestFocusInWindow();
241 });
242 // give WM time to deliver the event
243 TimeUnit.MILLISECONDS.sleep(100);
244 // then
245 SwingUtilities.invokeAndWait(() -> assertNull(tf.getSelectedText()));
246 }
247 }