Skip to content

Package: SWTTestUtil$Counter

SWTTestUtil$Counter

nameinstructionbranchcomplexitylinemethod
inc()
M: 0 C: 7
100%
M: 0 C: 0
100%
M: 0 C: 1
100%
M: 0 C: 2
100%
M: 0 C: 1
100%

Coverage

1: /*******************************************************************************
2: * Copyright (c) 2011-2014 EclipseSource Muenchen GmbH and others.
3: *
4: * All rights reserved. This program and the accompanying materials
5: * are made available under the terms of the Eclipse Public License 2.0
6: * which accompanies this distribution, and is available at
7: * https://www.eclipse.org/legal/epl-2.0/
8: *
9: * SPDX-License-Identifier: EPL-2.0
10: *
11: * Contributors:
12: * jfaltermeier - initial API and implementation
13: ******************************************************************************/
14: package org.eclipse.emf.ecp.view.test.common.swt.spi;
15:
16: import static org.junit.Assert.fail;
17:
18: import java.util.NoSuchElementException;
19:
20: import org.eclipse.emfforms.spi.swt.core.SWTDataElementIdHelper;
21: import org.eclipse.swt.SWT;
22: import org.eclipse.swt.custom.StackLayout;
23: import org.eclipse.swt.widgets.Button;
24: import org.eclipse.swt.widgets.Composite;
25: import org.eclipse.swt.widgets.Control;
26: import org.eclipse.swt.widgets.Display;
27: import org.eclipse.swt.widgets.Event;
28: import org.eclipse.swt.widgets.Layout;
29: import org.eclipse.swt.widgets.Table;
30: import org.eclipse.swt.widgets.TableItem;
31: import org.eclipse.swt.widgets.Text;
32: import org.eclipse.swt.widgets.Tree;
33: import org.eclipse.swt.widgets.TreeItem;
34: import org.eclipse.swt.widgets.Widget;
35:
36: /**
37: * Util class for SWT Tests.
38: *
39: * @author jfaltermeier
40: *
41: */
42: public final class SWTTestUtil {
43:
44:         private SWTTestUtil() {
45:                 // util
46:         }
47:
48:         /**
49:          * <p>
50:          * Iterates over the hierarchy of the given {@link Control} and looks for a {@link Composite} with a
51:          * {@link StackLayout}. The index specifies which composite with a stack layout should be returned.
52:          * </p>
53:          * <p>
54:          * This method uses a depth-first-search.
55:          * </p>
56:          *
57:          * @param control the parent control
58:          * @param index the index of the layout
59:          * @return the layout
60:          * @throws NoSuchElementException if no layout with the index can be found
61:          */
62:         public static StackLayout findStackLayout(Control control, int index) throws NoSuchElementException {
63:                 final Control result = find(control, index, new Counter(), new ControlTest() {
64:                         @Override
65:                         public boolean testCondition(Control control) {
66:                                 if (!Composite.class.isInstance(control)) {
67:                                         return false;
68:                                 }
69:                                 final Composite composite = Composite.class.cast(control);
70:                                 final Layout layout = composite.getLayout();
71:                                 if (layout == null) {
72:                                         return false;
73:                                 }
74:                                 if (StackLayout.class != layout.getClass()) {
75:                                         return false;
76:                                 }
77:                                 return true;
78:                         }
79:                 });
80:                 if (result == null) {
81:                         throw new NoSuchElementException("No composite with stack layout and index " + index + " found."); //$NON-NLS-1$//$NON-NLS-2$
82:                 }
83:                 final Composite composite = (Composite) result;
84:                 return (StackLayout) composite.getLayout();
85:         }
86:
87:         /**
88:          * <p>
89:          * Iterates over the hierarchy of the given {@link Control} and looks for a control of the given class. The index
90:          * specifies which control should be returned.
91:          * </p>
92:          * <p>
93:          * This method uses a depth-first-search.
94:          * </p>
95:          *
96:          * @param control the parent control
97:          * @param index the index of the control to find
98:          * @param <T> the type of the control to find
99:          * @param clazz the class of the control to find
100:          * @return the control
101:          * @throws NoSuchElementException if no control with the index can be found
102:          */
103:         public static <T extends Control> T findControl(Control control, int index, final Class<T> clazz)
104:                 throws NoSuchElementException {
105:                 final Control result = find(control, index, new Counter(), new ControlTest() {
106:                         @Override
107:                         public boolean testCondition(Control control) {
108:                                 if (control.getClass() != clazz) {
109:                                         return false;
110:                                 }
111:                                 return true;
112:                         }
113:                 });
114:                 if (result == null) {
115:                         throw new NoSuchElementException("No control of type " + clazz.getName() + " with index " + index //$NON-NLS-1$ //$NON-NLS-2$
116:                                 + " found."); //$NON-NLS-1$
117:                 }
118:                 return clazz.cast(result);
119:         }
120:
121:         private static Control find(Control control, int index, Counter found, ControlTest test) {
122:                 final boolean success = test.testCondition(control);
123:                 if (success) {
124:                         found.inc();
125:                 }
126:                 if (index + 1 == found.count) {
127:                         return control;
128:                 }
129:                 if (!Composite.class.isInstance(control)) {
130:                         return null;
131:                 }
132:                 final Composite composite = Composite.class.cast(control);
133:                 for (final Control child : composite.getChildren()) {
134:                         final Control childResult = find(child, index, found, test);
135:                         if (childResult != null) {
136:                                 return childResult;
137:                         }
138:                 }
139:                 return null;
140:         }
141:
142:         /**
143:          * Retrieves an element in the specified control by its unique Id, as defined in {@link SWTDataElementIdHelper}.
144:          *
145:          * @param control the parent control where the search control should be found.
146:          * @param id the unique ID of the element to find
147:          * @param clazz the class of control to find
148:          * @param <T> the type of Control to find
149:          * @return a optional referencing the control or an empty one if none was found.
150:          */
151:         public static <T extends Control> T findControlById(Control control, final String id, final Class<T> clazz) {
152:                 // only get the first index, assuming id is unique
153:                 final Control result = find(control, 0, new Counter(), new ControlTest() {
154:                         @Override
155:                         public boolean testCondition(Control control) {
156:                                 if (control.getClass() != clazz) {
157:                                         return false;
158:                                 }
159:
160:                                 final Object elementID = control.getData(SWTDataElementIdHelper.ELEMENT_ID_KEY);
161:                                 if (elementID != null && id.equals(elementID)) {
162:                                         return true;
163:                                 }
164:
165:                                 return false;
166:                         }
167:                 });
168:                 return clazz.cast(result);
169:         }
170:
171:         /**
172:          * Waits for the ui thread to complete its work. Fails a testcase after 5 seconds.
173:          */
174:         public static void waitForUIThread() {
175:                 final long maxTime = System.currentTimeMillis() + 5000;
176:                 while (Display.getDefault().readAndDispatch()) {
177:                         if (System.currentTimeMillis() > maxTime) {
178:                                 fail("Timeout");
179:                         }
180:                 }
181:         }
182:
183:         /**
184:          * Simulates a click on the given {@link Button}.
185:          *
186:          * @param button the button to press
187:          */
188:         public static void clickButton(Button button) {
189:                 selectWidget(button);
190:         }
191:
192:         /**
193:          * Selects the given widget.
194:          *
195:          * @param widget the control to select.
196:          */
197:         public static void selectWidget(Widget widget) {
198:                 widget.notifyListeners(SWT.Selection, new Event());
199:         }
200:
201:         /**
202:          * Simulates a key down and key up event on the given {@link Control}.
203:          *
204:          * @param control the control
205:          * @param keyCode the key code
206:          */
207:         public static void pressAndReleaseKey(Control control, int keyCode) {
208:                 pressAndReleaseKey(control, 0, keyCode);
209:         }
210:
211:         /**
212:          * Simulates a key down and key up event on the given {@link Control}.
213:          *
214:          * @param control the control
215:          * @param stateMask the state of the keyboard modifier keys (e.g. M1/ctrl)
216:          * @param keyCode the key code
217:          */
218:         public static void pressAndReleaseKey(Control control, int stateMask, int keyCode) {
219:                 final Event eventDown = new Event();
220:                 eventDown.stateMask = stateMask;
221:                 eventDown.keyCode = keyCode;
222:                 control.notifyListeners(SWT.KeyDown, eventDown);
223:                 final Event eventUp = new Event();
224:                 eventUp.keyCode = keyCode;
225:                 control.notifyListeners(SWT.KeyUp, eventDown);
226:         }
227:
228:         /**
229:          * Sets the given string on the {@link Text} and simulates a focus out event.
230:          *
231:          * @param text the text
232:          * @param string the string to enter in the text
233:          */
234:         public static void typeAndFocusOut(Text text, String string) {
235:                 text.setText(string);
236:                 text.notifyListeners(SWT.FocusOut, new Event());
237:         }
238:
239:         /**
240:          * Selects the index in the given tree and notifies the tree's listeners (e.g. a corresponding tree viewer) about
241:          * the selection.
242:          *
243:          * @param tree The tree to select an element in
244:          * @param index The index of the element to select
245:          * @return the selected {@link TreeItem}
246:          */
247:         public static TreeItem selectTreeItem(Tree tree, int index) {
248:                 final TreeItem result = tree.getItem(index);
249:                 selectTreeItem(result);
250:                 return result;
251:         }
252:
253:         /**
254:          * Selects the given {@link TreeItem} in its parent {@link Tree} and notifies the tree's listeners.
255:          *
256:          * @param treeItem The {@link TreeItem} to select
257:          */
258:         public static void selectTreeItem(TreeItem treeItem) {
259:                 final Tree tree = treeItem.getParent();
260:                 tree.setSelection(treeItem);
261:                 final Event event = new Event();
262:                 event.type = SWT.Selection;
263:                 event.widget = tree;
264:                 event.item = treeItem;
265:                 tree.notifyListeners(SWT.Selection, event);
266:         }
267:
268:         /**
269:          * Selects the index in the given table and notifies the table's listeners (e.g. a corresponding table viewer) about
270:          * the selection.
271:          *
272:          * @param table The table to select an element in
273:          * @param index The index of the element to select
274:          * @return the selected {@link TableItem}
275:          */
276:         public static TableItem selectTableItem(Table table, int index) {
277:                 table.setSelection(index);
278:                 final Event event = new Event();
279:                 event.type = SWT.Selection;
280:                 event.widget = table;
281:                 final TableItem result = table.getItem(index);
282:                 event.item = result;
283:                 table.notifyListeners(SWT.Selection, event);
284:                 return result;
285:         }
286:
287:         /**
288:          * Interface for a tester used by the {@link SWTTestUtil#find(Control, int, Counter, ControlTest)} method.
289:          *
290:          * @author jfaltermeier
291:          *
292:          */
293:         private interface ControlTest {
294:
295:                 /**
296:                  * Tests a condition on the given control.
297:                  *
298:                  * @param control the control to test
299:                  * @return <code>true</code> if condition fulfilled, <code>false</code> otherwise
300:                  */
301:                 boolean testCondition(Control control);
302:         }
303:
304:         /**
305:          * Simple counter class.
306:          *
307:          * @author jfaltermeier
308:          *
309:          */
310:         private static class Counter {
311:                 private int count;
312:
313:                 /**
314:                  * Increases the counter.
315:                  */
316:                 public void inc() {
317:                         count = count + 1;
318:                 }
319:         }
320: }