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

Last change on this file since 1638 was 1638, checked in by pharms, 10 years ago
  • some bugfixes and extensions for these test utils
File size: 18.9 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.util.ArrayList;
20import java.util.HashMap;
21import java.util.Iterator;
22import java.util.LinkedList;
23import java.util.List;
24import java.util.Map;
25import java.util.regex.Matcher;
26import java.util.regex.Pattern;
27
28import de.ugoe.cs.autoquest.eventcore.gui.TextInput;
29import de.ugoe.cs.autoquest.tasktrees.treeifc.DefaultTaskInstanceTraversingVisitor;
30import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTask;
31import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTaskInstance;
32import de.ugoe.cs.autoquest.tasktrees.treeifc.IIteration;
33import de.ugoe.cs.autoquest.tasktrees.treeifc.IOptionalInstance;
34import de.ugoe.cs.autoquest.tasktrees.treeifc.ISelection;
35import de.ugoe.cs.autoquest.tasktrees.treeifc.ISelectionInstance;
36import de.ugoe.cs.autoquest.tasktrees.treeifc.ISequence;
37import de.ugoe.cs.autoquest.tasktrees.treeifc.ITask;
38import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstance;
39import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskInstanceList;
40import de.ugoe.cs.autoquest.tasktrees.treeifc.IUserSession;
41
42/**
43 * TODO comment
44 *
45 * @version $Revision: $ $Date: 01.04.2012$
46 * @author 2012, last modified by $Author: patrick$
47 */
48public class TaskTreeChecker {
49   
50    /** */
51    private static Pattern taskPattern = Pattern.compile("([^{}]+)\\{|\\}");
52   
53    /** */
54    private static Pattern taskDetailsPattern =
55        Pattern.compile("\\s*(\\w*)\\s*([\\w\\(\\)\"]*)\\s*((\\w*)|(\".*\"))?");
56   
57    /** */
58    private boolean doTrace;
59
60    /**
61     *
62     */
63    public TaskTreeChecker() {
64        this(false);
65    }
66
67    /**
68     *
69     */
70    public TaskTreeChecker(boolean doTrace) {
71        this.doTrace = doTrace;
72    }
73
74    /**
75     *
76     */
77    public void assertUserSession(String userSessionSpec, IUserSession session) {
78        if (doTrace) {
79            new TaskTreeEncoder().encode(session, System.err);
80        }
81
82        TaskSpec taskInstanceSpec = null;
83
84        Matcher taskMatcher = taskPattern.matcher(userSessionSpec);
85       
86        Map<String, ITask> tasks = new HashMap<String, ITask>();
87
88        while (taskMatcher.find()) {
89
90            taskInstanceSpec = parseTaskInstance(taskMatcher);
91           
92            if (taskInstanceSpec != null) {
93                assertUserSession(taskInstanceSpec, session, tasks);
94            }
95        }
96    }
97
98    /**
99     *
100     */
101    public void assertTaskInstance(String userSessionSpec, ITaskInstance taskInstance) {
102        if (doTrace) {
103            new TaskTreeEncoder().encode(taskInstance, System.err);
104        }
105
106        TaskSpec taskInstanceSpec = null;
107
108        Matcher taskMatcher = taskPattern.matcher(userSessionSpec);
109       
110        Map<String, ITask> tasks = new HashMap<String, ITask>();
111
112        while (taskMatcher.find()) {
113
114            taskInstanceSpec = parseTaskInstance(taskMatcher);
115           
116            if (taskInstanceSpec != null) {
117                assertTaskInstance(taskInstanceSpec, taskInstance, tasks);
118            }
119        }
120    }
121
122    /**
123     *
124     */
125    public void assertTaskInstanceListsEqual(ITaskInstanceList expected, ITaskInstanceList checked)
126    {
127        if (expected == null) {
128            assertNull("null", checked);
129        }
130        else {
131            assertNotNull(expected.toString(), checked);
132           
133            assertEquals(expected.toString() + ": types do not match",
134                         expected.getClass(), checked.getClass());
135           
136            if ((expected != null) && (expected.size() > 0)) {
137                assertNotNull(expected.toString() + ": children not there", checked);
138                assertEquals(expected.toString() + ": different number of children",
139                             expected.size(), checked.size());
140               
141                Map<ITask, ITask> equalTasksMap = new HashMap<ITask, ITask>();
142                for (int i = 0; i < expected.size(); i++) {
143                    assertTaskInstancesEqual(expected.get(i), checked.get(i), equalTasksMap);
144                }
145            }
146            else {
147                assertTrue(expected.toString() + ": unexpected children",
148                           (checked == null) || (checked.size() == 0));
149            }
150        }
151    }
152
153    /**
154     *
155     */
156    public void assertTaskInstancesEqual(ITaskInstance expected, ITaskInstance checked) {
157        Map<ITask, ITask> equalTasksMap = new HashMap<ITask, ITask>();
158        assertTaskInstancesEqual(expected, checked, equalTasksMap);
159    }
160
161    /**
162     *
163     */
164    public void assertEventTaskInstancesEqual(ITaskInstanceList expected,
165                                              ITaskInstanceList checked)
166    {
167        final List<IEventTaskInstance> expectedEventTaskInstances =
168            new ArrayList<IEventTaskInstance>();
169       
170        final List<IEventTaskInstance> checkedEventTaskInstances =
171                new ArrayList<IEventTaskInstance>();
172           
173        for (ITaskInstance instance : expected) {
174            instance.accept(new DefaultTaskInstanceTraversingVisitor() {
175                @Override
176                public void visit(IEventTaskInstance eventTaskInstance) {
177                    expectedEventTaskInstances.add(eventTaskInstance);
178                }
179            });
180        }
181       
182        for (ITaskInstance instance : checked) {
183            instance.accept(new DefaultTaskInstanceTraversingVisitor() {
184                @Override
185                public void visit(IEventTaskInstance eventTaskInstance) {
186                    checkedEventTaskInstances.add(eventTaskInstance);
187                }
188            });
189        }
190       
191        assertEquals("task instance lists differ in the number of event task instances",
192                     expectedEventTaskInstances.size(), checkedEventTaskInstances.size());
193       
194        for (int i = 0; i < expectedEventTaskInstances.size(); i++) {
195            assertTaskInstancesEqual
196                (expectedEventTaskInstances.get(i), checkedEventTaskInstances.get(i));
197        }
198    }
199
200    /**
201     *
202     */
203    private void assertTaskInstancesEqual(ITaskInstance     expected,
204                                          ITaskInstance     checked,
205                                          Map<ITask, ITask> equalTasksMap)
206    {
207        if (expected == null) {
208            assertNull("null", checked);
209        }
210        else {
211            assertNotNull(expected.toString(), checked);
212           
213            assertEquals(expected.toString() + ": types do not match",
214                         expected.getClass(), checked.getClass());
215           
216            if (equalTasksMap.containsKey(expected.getTask())) {
217                assertEquals(expected.toString() + ": tasks do not match",
218                             checked.getTask(), equalTasksMap.get(expected.getTask()));
219            }
220            else {
221                equalTasksMap.put(expected.getTask(), checked.getTask());
222            }
223           
224            List<ITaskInstance> expectedChildren = getChildren(expected);
225            List<ITaskInstance> checkedChildren = getChildren(checked);
226           
227            if ((expectedChildren != null) && (expectedChildren.size() > 0)) {
228                assertNotNull(expected.toString() + ": children not there", checkedChildren);
229                assertEquals(expected.toString() + ": different number of children",
230                             expectedChildren.size(), checkedChildren.size());
231               
232                if (expected instanceof ISequence) {
233                    for (int i = 0; i < expectedChildren.size(); i++) {
234                        assertTaskInstancesEqual(expectedChildren.get(i), checkedChildren.get(i));
235                    }
236                }
237                else {
238                    for (int i = 0; i < expectedChildren.size(); i++) {
239                        boolean found = false;
240                        for (int j = 0; j < checkedChildren.size(); j++) {
241                            try {
242                                assertTaskInstancesEqual
243                                    (expectedChildren.get(i), checkedChildren.get(j));
244                                found = true;
245                                break;
246                            }
247                            catch (AssertionError e) {
248                                // try next
249                            }
250                        }
251                       
252                        assertTrue("one of the children not found", found);
253                    }
254                }
255            }
256            else {
257                assertTrue(expected.toString() + ": unexpected children",
258                           (checkedChildren == null) || (checkedChildren.size() == 0));
259            }
260        }
261    }
262
263    /**
264     *
265     */
266    private TaskSpec parseTaskInstance(Matcher taskMatcher) {
267        if ("}".equals(taskMatcher.group(1))) {
268            throw new IllegalArgumentException("invalid task specification");
269        }
270       
271        String taskDetails = taskMatcher.group(1);
272       
273        Matcher matcher = taskDetailsPattern.matcher(taskDetails);
274       
275        if (!matcher.find()) {
276            throw new IllegalArgumentException("could not parse task details");
277        }
278
279        TaskSpec task = new TaskSpec();
280        task.type = matcher.group(1);
281       
282        task.name = matcher.group(2);
283        if ((matcher.group(4) != null) && (!"".equals(matcher.group(4).trim()))) {
284            task.name += " " + matcher.group(4).trim();
285        }
286       
287        if ((matcher.group(5) != null) && (!"".equals(matcher.group(5).trim()))) {
288            task.additionalInfo = matcher.group(5).trim();
289        }
290
291        if ("".equals(task.name)) {
292            task.name = null;
293        }
294
295        List<TaskSpec> children = new ArrayList<TaskSpec>();
296        while (taskMatcher.find() && !"}".equals(taskMatcher.group(0))) {
297            children.add(parseTaskInstance(taskMatcher));
298        }
299
300        if (children.size() > 0) {
301            task.children = children.toArray(new TaskSpec[children.size()]);
302        }
303
304        return task;
305    }
306
307    /**
308     * @param task
309     * @param taskMapCopy
310     */
311    private void assertUserSession(TaskSpec           taskSpec,
312                                   IUserSession       session,
313                                   Map<String, ITask> tasks)
314    {
315        if (doTrace) {
316            System.err.println("\ncomparing " + taskSpec.type + " with " + session + "\n");
317        }
318
319        if (!"UserSession".equals(taskSpec.type)) {
320            fail("can not compare a task instance with a user session");
321        }
322       
323        List<ITaskInstance> children = session.getExecutedTasks();
324       
325        if (taskSpec.children.length != children.size()) {
326            fail("number of task instances in task instance list does not match");
327        }
328       
329        for (int i = 0; i < children.size(); i++) {
330            TaskSpec childSpec = taskSpec.children[i];
331            assertTrue(taskSpecEqualsTaskInstance(childSpec, children.get(i), tasks));
332        }
333    }
334
335    /**
336     * @param task
337     * @param taskMapCopy
338     */
339    private void assertTaskInstance(TaskSpec           taskSpec,
340                                    ITaskInstance      taskInstance,
341                                    Map<String, ITask> tasks)
342    {
343        if (doTrace) {
344            System.err.println("\ncomparing " + taskSpec.type + " with " + taskInstance + "\n");
345        }
346
347        if (!"TaskInstances".equals(taskSpec.type)) {
348            fail("can not compare a task instance with a task instance list");
349        }
350       
351        List<ITaskInstance> children = getChildren(taskInstance);
352       
353        if (taskSpec.children.length != children.size()) {
354            fail("number of task instances in task instance list does not match");
355        }
356       
357        for (int i = 0; i < children.size(); i++) {
358            TaskSpec childSpec = taskSpec.children[i];
359            assertTrue(taskSpecEqualsTaskInstance(childSpec, children.get(i), tasks));
360        }
361    }
362
363    /**
364     *
365     */
366    private boolean taskSpecEqualsTaskInstance(TaskSpec           taskSpec,
367                                               ITaskInstance      taskInstance,
368                                               Map<String, ITask> tasks)
369    {
370        if (doTrace) {
371            System.err.println("comparing " + taskSpec.name + " with");
372            new TaskTreeEncoder().encode(taskInstance, System.err);
373        }
374
375        ITask task = taskInstance.getTask();
376       
377        if (("Event".equals(taskSpec.type) && (!(task instanceof IEventTask))) ||
378            ("TextInputEvent".equals(taskSpec.type) &&
379             ((!(taskInstance instanceof IEventTaskInstance)) ||
380              (!(((IEventTaskInstance) taskInstance).getEvent().getType() instanceof TextInput)))) ||
381            ("Sequence".equals(taskSpec.type) && (!(task instanceof ISequence))) ||
382            ("Selection".equals(taskSpec.type) && (!(task instanceof ISelection))) ||
383            ("Iteration".equals(taskSpec.type) && (!(task instanceof IIteration))))
384        {
385            if (doTrace) {
386                System.err.println("task types do not match: " + taskSpec.type + " != " +
387                                   task.getClass().getSimpleName() + "\n");
388            }
389            return false;
390        }
391        else if (!"Event".equals(taskSpec.type) &&
392                 !"TextInputEvent".equals(taskSpec.type) &&
393                 !"Sequence".equals(taskSpec.type) &&
394                 !"Selection".equals(taskSpec.type) &&
395                 !"Iteration".equals(taskSpec.type))
396        {
397            fail("unknown task type " + taskSpec.type + " --> please extend test case");
398        }
399
400        if ("TextInputEvent".equals(taskSpec.type)) {
401            TextInput eventType = (TextInput)
402                ((IEventTaskInstance) taskInstance).getEvent().getType();
403           
404            if ((taskSpec.additionalInfo != null) &&
405                !"".equals(taskSpec.additionalInfo) &&
406                !(taskSpec.additionalInfo.equals(eventType.getEnteredText())))
407            {
408                if (doTrace) {
409                    System.err.println("expected text \"" + taskSpec.additionalInfo +
410                                       "\" is not equal to the text " + "provided by the task \"" +
411                                       eventType.getEnteredText() + "\"\n");
412                }
413                return false;
414            }
415        }
416        else if ((task instanceof IEventTask) &&
417                 (((IEventTaskInstance) taskInstance).getEvent().getType() != null) &&
418                 (!taskSpec.name.equals(((IEventTaskInstance) taskInstance).getEvent().getType().getName())))
419        {
420            // simple event names do not match. But what about the event name in
421            // combination with the additional info
422            String complexName =
423                taskSpec.name +
424                    (!"".equals(taskSpec.additionalInfo) ? " " + taskSpec.additionalInfo : "");
425
426            if (!complexName.equals(((IEventTaskInstance) taskInstance).getEvent().getType().getName())) {
427                if (doTrace) {
428                    System.err.println
429                        ("event names do not match: " + taskSpec.name + " != " +
430                         ((IEventTaskInstance) taskInstance).getEvent().getType().getName() + "\n");
431                }
432                return false;
433            }
434        }
435       
436        // check the task name against the map
437        if (tasks.containsKey(taskSpec.name)) {
438            if (!tasks.get(taskSpec.name).equals(task)) {
439                if (doTrace) {
440                    System.err.println("the task instance is not of the expected task: " +
441                                       taskSpec.name + " != " + task + "\n");
442                }
443                return false;
444            }
445        }
446        else if (tasks.containsValue(task)) {
447            if (doTrace) {
448                System.err.println("the task of the task instance " + taskSpec.name +
449                                   " should be different to another one but it isn't\n");
450            }
451            return false;
452        }
453        else {
454            tasks.put(taskSpec.name, task);
455        }
456
457        List<ITaskInstance> children = getChildren(taskInstance);
458       
459        if (((taskSpec.children == null) && (children.size() > 0)) ||
460            ((taskSpec.children != null) &&
461             (taskSpec.children.length != children.size())))
462        {
463            if (doTrace) {
464                System.err.println
465                    ("numbers of children do not match: " +
466                     (taskSpec.children == null ? "0" : taskSpec.children.length) + " != " +
467                     (children == null ? "0" : children.size()) + "\n");
468            }
469            return false;
470        }
471
472        Iterator<ITaskInstance> childrenIterator = children.iterator();
473        if (taskSpec.children != null) {
474            for (TaskSpec child : taskSpec.children) {
475                if (!taskSpecEqualsTaskInstance(child, childrenIterator.next(), tasks)) {
476                    if (doTrace) {
477                        System.err.println("one of the children does not match\n");
478                    }
479                    return false;
480                }
481            }
482        }
483
484        if (!childrenIterator.hasNext()) {
485            if (doTrace) {
486                System.err.println("nodes match\n");
487            }
488            return true;
489        }
490        else {
491            if (doTrace) {
492                System.err.println("number of children does not match\n");
493            }
494            return false;
495        }
496    }
497   
498    /**
499     * <p>
500     * TODO: comment
501     * </p>
502     *
503     * @param taskInstance
504     * @return
505     */
506    private List<ITaskInstance> getChildren(ITaskInstance taskInstance) {
507        List<ITaskInstance> result = new LinkedList<ITaskInstance>();
508       
509        if (taskInstance instanceof ITaskInstanceList) {
510            for (ITaskInstance child : (ITaskInstanceList) taskInstance) {
511                result.add(child);
512            }
513        }
514        else if (taskInstance instanceof ISelectionInstance) {
515            result.add(((ISelectionInstance) taskInstance).getChild());
516        }
517        else if (taskInstance instanceof IOptionalInstance) {
518            result.add(((IOptionalInstance) taskInstance).getChild());
519        }
520       
521        return result;
522    }
523
524    /**
525     *
526     */
527    private class TaskSpec {
528        public String type;
529        public String name;
530        public String additionalInfo;
531        public TaskSpec[] children;
532    }
533
534}
Note: See TracBrowser for help on using the repository browser.