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
RevLine 
[927]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
[922]15package de.ugoe.cs.autoquest.tasktrees;
[790]16
[1123]17import static org.junit.Assert.*;
[790]18
19import java.util.ArrayList;
20import java.util.HashMap;
21import java.util.Iterator;
[1294]22import java.util.LinkedList;
[790]23import java.util.List;
24import java.util.Map;
25import java.util.regex.Matcher;
26import java.util.regex.Pattern;
27
[922]28import de.ugoe.cs.autoquest.eventcore.gui.TextInput;
[1638]29import de.ugoe.cs.autoquest.tasktrees.treeifc.DefaultTaskInstanceTraversingVisitor;
[922]30import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTask;
[1294]31import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTaskInstance;
[922]32import de.ugoe.cs.autoquest.tasktrees.treeifc.IIteration;
[1294]33import de.ugoe.cs.autoquest.tasktrees.treeifc.IOptionalInstance;
[922]34import de.ugoe.cs.autoquest.tasktrees.treeifc.ISelection;
[1294]35import de.ugoe.cs.autoquest.tasktrees.treeifc.ISelectionInstance;
[922]36import de.ugoe.cs.autoquest.tasktrees.treeifc.ISequence;
[1146]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;
[790]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 =
[977]55        Pattern.compile("\\s*(\\w*)\\s*([\\w\\(\\)\"]*)\\s*((\\w*)|(\".*\"))?");
[790]56   
57    /** */
58    private boolean doTrace;
59
60    /**
[1146]61     *
[790]62     */
63    public TaskTreeChecker() {
64        this(false);
65    }
66
67    /**
[1146]68     *
[790]69     */
70    public TaskTreeChecker(boolean doTrace) {
71        this.doTrace = doTrace;
72    }
73
74    /**
75     *
76     */
[1294]77    public void assertUserSession(String userSessionSpec, IUserSession session) {
[790]78        if (doTrace) {
[1294]79            new TaskTreeEncoder().encode(session, System.err);
[790]80        }
81
[1146]82        TaskSpec taskInstanceSpec = null;
[790]83
[1146]84        Matcher taskMatcher = taskPattern.matcher(userSessionSpec);
85       
86        Map<String, ITask> tasks = new HashMap<String, ITask>();
[790]87
88        while (taskMatcher.find()) {
89
[1146]90            taskInstanceSpec = parseTaskInstance(taskMatcher);
[790]91           
[1146]92            if (taskInstanceSpec != null) {
[1294]93                assertUserSession(taskInstanceSpec, session, tasks);
[790]94            }
95        }
[1146]96    }
[790]97
[1146]98    /**
99     *
100     */
[1294]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     */
[1146]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        }
[790]151    }
152
153    /**
[1123]154     *
155     */
[1146]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     */
[1638]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     */
[1146]203    private void assertTaskInstancesEqual(ITaskInstance     expected,
204                                          ITaskInstance     checked,
205                                          Map<ITask, ITask> equalTasksMap)
206    {
[1123]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           
[1146]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            }
[1123]223           
[1294]224            List<ITaskInstance> expectedChildren = getChildren(expected);
225            List<ITaskInstance> checkedChildren = getChildren(checked);
[1146]226           
[1123]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++) {
[1146]234                        assertTaskInstancesEqual(expectedChildren.get(i), checkedChildren.get(i));
[1123]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 {
[1146]242                                assertTaskInstancesEqual
[1123]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    /**
[790]264     *
265     */
[1146]266    private TaskSpec parseTaskInstance(Matcher taskMatcher) {
[790]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))) {
[1146]297            children.add(parseTaskInstance(taskMatcher));
[790]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     */
[1294]311    private void assertUserSession(TaskSpec           taskSpec,
312                                   IUserSession       session,
313                                   Map<String, ITask> tasks)
[790]314    {
[1146]315        if (doTrace) {
[1294]316            System.err.println("\ncomparing " + taskSpec.type + " with " + session + "\n");
[1146]317        }
[790]318
[1294]319        if (!"UserSession".equals(taskSpec.type)) {
[1146]320            fail("can not compare a task instance with a user session");
[790]321        }
[1294]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)) {
[1146]348            fail("can not compare a task instance with a task instance list");
349        }
350       
[1294]351        List<ITaskInstance> children = getChildren(taskInstance);
352       
353        if (taskSpec.children.length != children.size()) {
[1146]354            fail("number of task instances in task instance list does not match");
355        }
356       
[1294]357        for (int i = 0; i < children.size(); i++) {
[1146]358            TaskSpec childSpec = taskSpec.children[i];
[1294]359            assertTrue(taskSpecEqualsTaskInstance(childSpec, children.get(i), tasks));
[1146]360        }
[790]361    }
362
363    /**
364     *
365     */
[1146]366    private boolean taskSpecEqualsTaskInstance(TaskSpec           taskSpec,
367                                               ITaskInstance      taskInstance,
368                                               Map<String, ITask> tasks)
369    {
[790]370        if (doTrace) {
371            System.err.println("comparing " + taskSpec.name + " with");
[1146]372            new TaskTreeEncoder().encode(taskInstance, System.err);
[790]373        }
374
[1146]375        ITask task = taskInstance.getTask();
376       
[790]377        if (("Event".equals(taskSpec.type) && (!(task instanceof IEventTask))) ||
378            ("TextInputEvent".equals(taskSpec.type) &&
[1294]379             ((!(taskInstance instanceof IEventTaskInstance)) ||
380              (!(((IEventTaskInstance) taskInstance).getEvent().getType() instanceof TextInput)))) ||
[790]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 + " != " +
[1146]387                                   task.getClass().getSimpleName() + "\n");
[790]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)) {
[1294]401            TextInput eventType = (TextInput)
402                ((IEventTaskInstance) taskInstance).getEvent().getType();
403           
[790]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        }
[1294]416        else if ((task instanceof IEventTask) &&
417                 (((IEventTaskInstance) taskInstance).getEvent().getType() != null) &&
418                 (!taskSpec.name.equals(((IEventTaskInstance) taskInstance).getEvent().getType().getName())))
[790]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
[1294]426            if (!complexName.equals(((IEventTaskInstance) taskInstance).getEvent().getType().getName())) {
[790]427                if (doTrace) {
[1294]428                    System.err.println
429                        ("event names do not match: " + taskSpec.name + " != " +
430                         ((IEventTaskInstance) taskInstance).getEvent().getType().getName() + "\n");
[790]431                }
432                return false;
433            }
434        }
[1146]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        }
[790]456
[1294]457        List<ITaskInstance> children = getChildren(taskInstance);
458       
459        if (((taskSpec.children == null) && (children.size() > 0)) ||
[1146]460            ((taskSpec.children != null) &&
[1294]461             (taskSpec.children.length != children.size())))
[790]462        {
463            if (doTrace) {
464                System.err.println
465                    ("numbers of children do not match: " +
466                     (taskSpec.children == null ? "0" : taskSpec.children.length) + " != " +
[1294]467                     (children == null ? "0" : children.size()) + "\n");
[790]468            }
469            return false;
470        }
471
[1294]472        Iterator<ITaskInstance> childrenIterator = children.iterator();
[790]473        if (taskSpec.children != null) {
474            for (TaskSpec child : taskSpec.children) {
[1294]475                if (!taskSpecEqualsTaskInstance(child, childrenIterator.next(), tasks)) {
[790]476                    if (doTrace) {
477                        System.err.println("one of the children does not match\n");
478                    }
479                    return false;
480                }
481            }
482        }
483
[1294]484        if (!childrenIterator.hasNext()) {
[790]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    }
[1146]497   
[790]498    /**
[1294]499     * <p>
500     * TODO: comment
501     * </p>
[790]502     *
[1294]503     * @param taskInstance
504     * @return
[790]505     */
[1294]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     */
[790]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.