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

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