source: trunk/autoquest-test-utils/src/main/java/de/ugoe/cs/autoquest/tasktrees/TaskTreeChecker.java @ 1123

Last change on this file since 1123 was 1123, checked in by pharms, 11 years ago
  • improved testing support for task trees
File size: 17.4 KB
Line 
1//   Copyright 2012 Georg-August-Universität Göttingen, Germany
2//
3//   Licensed under the Apache License, Version 2.0 (the "License");
4//   you may not use this file except in compliance with the License.
5//   You may obtain a copy of the License at
6//
7//       http://www.apache.org/licenses/LICENSE-2.0
8//
9//   Unless required by applicable law or agreed to in writing, software
10//   distributed under the License is distributed on an "AS IS" BASIS,
11//   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12//   See the License for the specific language governing permissions and
13//   limitations under the License.
14
15package de.ugoe.cs.autoquest.tasktrees;
16
17import static org.junit.Assert.*;
18
19import java.io.FileNotFoundException;
20import java.io.FileOutputStream;
21import java.io.PrintWriter;
22import java.util.ArrayList;
23import java.util.HashMap;
24import java.util.Iterator;
25import java.util.List;
26import java.util.Map;
27import java.util.regex.Matcher;
28import java.util.regex.Pattern;
29
30import de.ugoe.cs.autoquest.eventcore.gui.TextInput;
31import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTask;
32import de.ugoe.cs.autoquest.tasktrees.treeifc.IIteration;
33import de.ugoe.cs.autoquest.tasktrees.treeifc.ISelection;
34import de.ugoe.cs.autoquest.tasktrees.treeifc.ISequence;
35import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTree;
36import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNode;
37import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNodeInfo;
38
39/**
40 * TODO comment
41 *
42 * @version $Revision: $ $Date: 01.04.2012$
43 * @author 2012, last modified by $Author: patrick$
44 */
45public class TaskTreeChecker {
46   
47    /** */
48    private static Pattern taskPattern = Pattern.compile("([^{}]+)\\{|\\}");
49   
50    /** */
51    private static Pattern taskDetailsPattern =
52        Pattern.compile("\\s*(\\w*)\\s*([\\w\\(\\)\"]*)\\s*((\\w*)|(\".*\"))?");
53   
54    /** */
55    private boolean doTrace;
56
57    /**
58     * TODO: comment
59     *
60     */
61    public TaskTreeChecker() {
62        this(false);
63    }
64
65    /**
66     * TODO: comment
67     *
68     */
69    public TaskTreeChecker(boolean doTrace) {
70        this.doTrace = doTrace;
71    }
72
73    /**
74     *
75     */
76    public void assertTaskTree(String taskTreeSpec, ITaskTree taskTree) {
77        Map<ITaskTreeNode, Integer> taskMapCopy = new HashMap<ITaskTreeNode, Integer>();
78
79        for (Map.Entry<ITaskTreeNode, ITaskTreeNodeInfo> entry : taskTree.getTaskMap().entrySet()) {
80            if (entry.getValue().getNoOfOccurencesInTree() > 0) {
81                taskMapCopy.put(entry.getKey(), entry.getValue().getNoOfOccurencesInTree());
82            }
83            else {
84                taskMapCopy.put(entry.getKey(), 1);
85            }
86        }
87
88        if (doTrace) {
89            dumpTaskMap(taskMapCopy);
90        }
91
92        TaskSpec task = null;
93
94        Matcher taskMatcher = taskPattern.matcher(taskTreeSpec);
95
96        while (taskMatcher.find()) {
97
98            task = parseTask(taskMatcher);
99           
100            if (task != null) {
101                assertTaskAndChildrenInMapAndRemove(task, taskMapCopy);
102            }
103        }
104
105        assertTrue("more tasks in map, than expected", taskMapCopy.isEmpty());
106    }
107
108    /**
109     * <p>
110     * TODO: comment
111     * </p>
112     *
113     * @param oracle
114     * @param result
115     */
116    public void assertTaskNodesEqual(ITaskTreeNode expected, ITaskTreeNode checked) {
117        if (expected == null) {
118            assertNull("null", checked);
119        }
120        else {
121            assertNotNull(expected.toString(), checked);
122           
123            assertEquals(expected.toString() + ": types do not match",
124                         expected.getClass(), checked.getClass());
125            assertEquals(expected.toString() + ": names do not match",
126                         expected.getName(), checked.getName());
127           
128            List<ITaskTreeNode> expectedChildren = expected.getChildren();
129            List<ITaskTreeNode> checkedChildren = checked.getChildren();
130           
131            if ((expectedChildren != null) && (expectedChildren.size() > 0)) {
132                assertNotNull(expected.toString() + ": children not there", checkedChildren);
133                assertEquals(expected.toString() + ": different number of children",
134                             expectedChildren.size(), checkedChildren.size());
135               
136                if (expected instanceof ISequence) {
137                    for (int i = 0; i < expectedChildren.size(); i++) {
138                        assertTaskNodesEqual(expectedChildren.get(i), checkedChildren.get(i));
139                    }
140                }
141                else {
142                    for (int i = 0; i < expectedChildren.size(); i++) {
143                        boolean found = false;
144                        for (int j = 0; j < checkedChildren.size(); j++) {
145                            try {
146                                assertTaskNodesEqual
147                                    (expectedChildren.get(i), checkedChildren.get(j));
148                                found = true;
149                                break;
150                            }
151                            catch (AssertionError e) {
152                                // try next
153                            }
154                        }
155                       
156                        assertTrue("one of the children not found", found);
157                    }
158                }
159            }
160            else {
161                assertTrue(expected.toString() + ": unexpected children",
162                           (checkedChildren == null) || (checkedChildren.size() == 0));
163            }
164        }
165    }
166
167    /**
168     * TODO: comment
169     *
170     * @param taskTree
171     */
172    public void dumpAsCheckString(ITaskTree taskTree) {
173        dumpNodeAsCheckString(taskTree.getRoot(), new int[4], "");
174    }
175
176    /**
177     * TODO: comment
178     *
179     * @param root
180     * @param string
181     */
182    private void dumpNodeAsCheckString(ITaskTreeNode node, int[] typeCounters, String indent) {
183        System.out.print("       \"");
184        System.out.print(indent);
185
186        if (node instanceof ISequence) {
187            System.out.print("Sequence sequence");
188            System.out.print(typeCounters[0]++);
189            System.out.println(" {\" +");
190        }
191        else if (node instanceof IIteration) {
192            System.out.print("Iteration iteration");
193            System.out.print(typeCounters[1]++);
194            System.out.println(" {\" +");
195        }
196        else if (node instanceof ISelection) {
197            System.out.print("Selection selection");
198            System.out.print(typeCounters[2]++);
199            System.out.println(" {\" +");
200        }
201        else if (node instanceof IEventTask) {
202            if (((IEventTask) node).getEventType() instanceof TextInput) {
203                System.out.print("TextInputEvent textInput");
204                System.out.print(typeCounters[3]++);
205                System.out.print(" \"");
206                System.out.print(((TextInput) ((IEventTask) node).getEventType()).getEnteredText());
207                System.out.print("\"");
208            }
209            else {
210                System.out.print("Event ");
211                System.out.print(((IEventTask) node).getEventType().getName());
212            }
213            System.out.print(" {}\" +");
214        }
215        else {
216            fail("unknown type of node in task tree " + node);
217        }
218
219        for (ITaskTreeNode child : node.getChildren()) {
220            dumpNodeAsCheckString(child, typeCounters, indent + "  ");
221        }
222
223        if (!(node instanceof IEventTask)) {
224            System.out.print("       \"");
225            System.out.print(indent);
226            System.out.print("}\" +");
227        }
228
229        System.out.println();
230    }
231
232    /**
233     * TODO: comment
234     *
235     * @param taskTree
236     */
237    public void dumpFullTaskTree(ITaskTree taskTree) throws FileNotFoundException {
238        PrintWriter out = null;
239        try {
240            out = new PrintWriter(new FileOutputStream("taskTree.txt"));
241            dumpFullNode(taskTree.getRoot(), out, "", 0);
242        }
243        finally {
244            if (out != null) {
245                out.close();
246            }
247        }
248
249    }
250
251    /**
252     *
253     */
254    private void dumpFullNode(ITaskTreeNode node, PrintWriter out, String indent, int index) {
255        if (node instanceof ISequence) {
256            if (index > 0) {
257                out.println();
258            }
259            out.print(indent);
260            out.print(node.toString());
261            out.println(" {");
262        }
263        else if (node instanceof IIteration) {
264            if (index > 0) {
265                out.println();
266            }
267            out.print(indent);
268            out.print(node.toString());
269            out.println(" {");
270        }
271        else if (node instanceof ISelection) {
272            if (index > 0) {
273                out.println();
274            }
275            out.print(indent);
276            out.print(node.toString());
277            out.println(" {");
278        }
279        else if (node instanceof IEventTask) {
280            out.print(indent);
281            out.print(((IEventTask) node).getEventType());
282            out.print(" ");
283            out.print(((IEventTask) node).getEventTarget().getStringIdentifier());
284//            if (((IEventTask) node).getEventTarget() instanceof IGUIElement) {
285//              out.print(" ");
286//              out.print(((IGUIElement) ((IEventTask) node).getEventTarget()).getSpecification());
287//            }
288        }
289        else {
290            fail("unknown type of node in task tree " + node);
291        }
292
293        int i = 0;
294        for (ITaskTreeNode child : node.getChildren()) {
295            dumpFullNode(child, out, indent + "  ", i++);
296        }
297
298        if (!(node instanceof IEventTask)) {
299            out.print(indent);
300            out.print("}");
301        }
302
303        out.println();
304    }
305
306    /**
307     *
308     */
309    private TaskSpec parseTask(Matcher taskMatcher) {
310        if ("}".equals(taskMatcher.group(1))) {
311            throw new IllegalArgumentException("invalid task specification");
312        }
313       
314        String taskDetails = taskMatcher.group(1);
315       
316        Matcher matcher = taskDetailsPattern.matcher(taskDetails);
317       
318        if (!matcher.find()) {
319            throw new IllegalArgumentException("could not parse task details");
320        }
321
322        TaskSpec task = new TaskSpec();
323        task.type = matcher.group(1);
324       
325        task.name = matcher.group(2);
326        if ((matcher.group(4) != null) && (!"".equals(matcher.group(4).trim()))) {
327            task.name += " " + matcher.group(4).trim();
328        }
329       
330        if ((matcher.group(5) != null) && (!"".equals(matcher.group(5).trim()))) {
331            task.additionalInfo = matcher.group(5).trim();
332        }
333
334        if ("".equals(task.name)) {
335            task.name = null;
336        }
337
338        List<TaskSpec> children = new ArrayList<TaskSpec>();
339        while (taskMatcher.find() && !"}".equals(taskMatcher.group(0))) {
340            children.add(parseTask(taskMatcher));
341        }
342
343        if (children.size() > 0) {
344            task.children = children.toArray(new TaskSpec[children.size()]);
345        }
346
347        return task;
348    }
349
350    /**
351     * @param task
352     * @param taskMapCopy
353     */
354    private void assertTaskAndChildrenInMapAndRemove(TaskSpec                    task,
355                                                     Map<ITaskTreeNode, Integer> taskMap)
356    {
357        for (Map.Entry<ITaskTreeNode, Integer> entry : taskMap.entrySet()) {
358            if (taskSpecEqualsTask(task, entry.getKey())) {
359                if (task.children != null) {
360                    for (TaskSpec child : task.children) {
361                        assertTaskAndChildrenInMapAndRemove(child, taskMap);
362                    }
363                }
364
365                int count = taskMap.get(entry.getKey());
366                if (count == 1) {
367                    taskMap.remove(entry.getKey());
368                }
369                else {
370                    taskMap.put(entry.getKey(), count - 1);
371                }
372                return;
373            }
374        }
375
376        fail("expected task " + task.type + " " + task.name + " not included in task map");
377    }
378
379    /**
380     *
381     */
382    private boolean taskSpecEqualsTask(TaskSpec taskSpec, ITaskTreeNode task) {
383        if (doTrace) {
384            System.err.println("comparing " + taskSpec.name + " with");
385            dumpTask(task, 0, "");
386        }
387
388        if (("Event".equals(taskSpec.type) && (!(task instanceof IEventTask))) ||
389            ("TextInputEvent".equals(taskSpec.type) &&
390             ((!(task instanceof IEventTask)) ||
391              (!(((IEventTask) task).getEventType() instanceof TextInput)))) ||
392            ("Sequence".equals(taskSpec.type) && (!(task instanceof ISequence))) ||
393            ("Selection".equals(taskSpec.type) && (!(task instanceof ISelection))) ||
394            ("Iteration".equals(taskSpec.type) && (!(task instanceof IIteration))))
395        {
396            if (doTrace) {
397                System.err.println("task types do not match: " + taskSpec.type + " != " +
398                    task.getClass().getSimpleName() + "\n");
399            }
400            return false;
401        }
402        else if (!"Event".equals(taskSpec.type) &&
403                 !"TextInputEvent".equals(taskSpec.type) &&
404                 !"Sequence".equals(taskSpec.type) &&
405                 !"Selection".equals(taskSpec.type) &&
406                 !"Iteration".equals(taskSpec.type))
407        {
408            fail("unknown task type " + taskSpec.type + " --> please extend test case");
409        }
410
411        if ("TextInputEvent".equals(taskSpec.type)) {
412            TextInput eventType = (TextInput) ((IEventTask) task).getEventType();
413            if ((taskSpec.additionalInfo != null) &&
414                !"".equals(taskSpec.additionalInfo) &&
415                !(taskSpec.additionalInfo.equals(eventType.getEnteredText())))
416            {
417                if (doTrace) {
418                    System.err.println("expected text \"" + taskSpec.additionalInfo +
419                                       "\" is not equal to the text " + "provided by the task \"" +
420                                       eventType.getEnteredText() + "\"\n");
421                }
422                return false;
423            }
424        }
425        else if ((task instanceof IEventTask) && (((IEventTask) task).getEventType() != null) &&
426                 (!taskSpec.name.equals(((IEventTask) task).getEventType().getName())))
427        {
428            // simple event names do not match. But what about the event name in
429            // combination with the additional info
430            String complexName =
431                taskSpec.name +
432                    (!"".equals(taskSpec.additionalInfo) ? " " + taskSpec.additionalInfo : "");
433
434            if (!complexName.equals(((IEventTask) task).getEventType().getName())) {
435                if (doTrace) {
436                    System.err.println("event names do not match: " + taskSpec.name + " != " +
437                                       ((IEventTask) task).getEventType().getName() + "\n");
438                }
439                return false;
440            }
441        }
442
443        if (((taskSpec.children == null) && (task.getChildren().size() > 0)) ||
444            ((taskSpec.children != null) && (taskSpec.children.length != task.getChildren().size())))
445        {
446            if (doTrace) {
447                System.err.println
448                    ("numbers of children do not match: " +
449                     (taskSpec.children == null ? "0" : taskSpec.children.length) + " != " +
450                     (task.getChildren() == null ? "0" : task.getChildren().size()) + "\n");
451            }
452            return false;
453        }
454
455        Iterator<ITaskTreeNode> children = task.getChildren().iterator();
456        if (taskSpec.children != null) {
457            for (TaskSpec child : taskSpec.children) {
458                if (!taskSpecEqualsTask(child, children.next())) {
459                    if (doTrace) {
460                        System.err.println("one of the children does not match\n");
461                    }
462                    return false;
463                }
464            }
465        }
466
467        if (!children.hasNext()) {
468            if (doTrace) {
469                System.err.println("nodes match\n");
470            }
471            return true;
472        }
473        else {
474            if (doTrace) {
475                System.err.println("number of children does not match\n");
476            }
477            return false;
478        }
479    }
480
481    /**
482   *
483   */
484    private void dumpTaskMap(Map<ITaskTreeNode, Integer> taskMap) {
485        System.err.println();
486        for (Map.Entry<ITaskTreeNode, Integer> entry : taskMap.entrySet()) {
487            dumpTask(entry.getKey(), entry.getValue(), "");
488            System.err.println();
489        }
490    }
491
492    /**
493     *
494     */
495    private void dumpTask(ITaskTreeNode task, int count, String indent) {
496        System.err.print(indent);
497        System.err.print(task);
498        System.err.print(" ");
499        System.err.print(task.getDescription());
500        System.err.print(" ");
501
502        if (count > 0) {
503            System.err.print("(");
504            System.err.print(count);
505            System.err.print(" occurrences)");
506        }
507
508        System.err.println();
509
510        if ((task.getChildren() != null) && (task.getChildren().size() > 0)) {
511            for (ITaskTreeNode child : task.getChildren()) {
512                dumpTask(child, 0, indent + "  ");
513            }
514        }
515    }
516   
517    /**
518     * TODO comment
519     *
520     * @version $Revision: $ $Date: $
521     * @author 2011, last modified by $Author: $
522     */
523    private class TaskSpec {
524        public String type;
525        public String name;
526        public String additionalInfo;
527        public TaskSpec[] children;
528    }
529
530}
Note: See TracBrowser for help on using the repository browser.