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

Last change on this file since 1490 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
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;
29import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTask;
[1294]30import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTaskInstance;
[922]31import de.ugoe.cs.autoquest.tasktrees.treeifc.IIteration;
[1294]32import de.ugoe.cs.autoquest.tasktrees.treeifc.IOptionalInstance;
[922]33import de.ugoe.cs.autoquest.tasktrees.treeifc.ISelection;
[1294]34import de.ugoe.cs.autoquest.tasktrees.treeifc.ISelectionInstance;
[922]35import de.ugoe.cs.autoquest.tasktrees.treeifc.ISequence;
[1146]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;
[790]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 =
[977]54        Pattern.compile("\\s*(\\w*)\\s*([\\w\\(\\)\"]*)\\s*((\\w*)|(\".*\"))?");
[790]55   
56    /** */
57    private boolean doTrace;
58
59    /**
[1146]60     *
[790]61     */
62    public TaskTreeChecker() {
63        this(false);
64    }
65
66    /**
[1146]67     *
[790]68     */
69    public TaskTreeChecker(boolean doTrace) {
70        this.doTrace = doTrace;
71    }
72
73    /**
74     *
75     */
[1294]76    public void assertUserSession(String userSessionSpec, IUserSession session) {
[790]77        if (doTrace) {
[1294]78            new TaskTreeEncoder().encode(session, System.err);
[790]79        }
80
[1146]81        TaskSpec taskInstanceSpec = null;
[790]82
[1146]83        Matcher taskMatcher = taskPattern.matcher(userSessionSpec);
84       
85        Map<String, ITask> tasks = new HashMap<String, ITask>();
[790]86
87        while (taskMatcher.find()) {
88
[1146]89            taskInstanceSpec = parseTaskInstance(taskMatcher);
[790]90           
[1146]91            if (taskInstanceSpec != null) {
[1294]92                assertUserSession(taskInstanceSpec, session, tasks);
[790]93            }
94        }
[1146]95    }
[790]96
[1146]97    /**
98     *
99     */
[1294]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     */
[1146]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        }
[790]150    }
151
152    /**
[1123]153     *
154     */
[1146]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    {
[1123]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           
[1146]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            }
[1123]183           
[1294]184            List<ITaskInstance> expectedChildren = getChildren(expected);
185            List<ITaskInstance> checkedChildren = getChildren(checked);
[1146]186           
[1123]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++) {
[1146]194                        assertTaskInstancesEqual(expectedChildren.get(i), checkedChildren.get(i));
[1123]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 {
[1146]202                                assertTaskInstancesEqual
[1123]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    /**
[790]224     *
225     */
[1146]226    private TaskSpec parseTaskInstance(Matcher taskMatcher) {
[790]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))) {
[1146]257            children.add(parseTaskInstance(taskMatcher));
[790]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     */
[1294]271    private void assertUserSession(TaskSpec           taskSpec,
272                                   IUserSession       session,
273                                   Map<String, ITask> tasks)
[790]274    {
[1146]275        if (doTrace) {
[1294]276            System.err.println("\ncomparing " + taskSpec.type + " with " + session + "\n");
[1146]277        }
[790]278
[1294]279        if (!"UserSession".equals(taskSpec.type)) {
[1146]280            fail("can not compare a task instance with a user session");
[790]281        }
[1294]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)) {
[1146]308            fail("can not compare a task instance with a task instance list");
309        }
310       
[1294]311        List<ITaskInstance> children = getChildren(taskInstance);
312       
313        if (taskSpec.children.length != children.size()) {
[1146]314            fail("number of task instances in task instance list does not match");
315        }
316       
[1294]317        for (int i = 0; i < children.size(); i++) {
[1146]318            TaskSpec childSpec = taskSpec.children[i];
[1294]319            assertTrue(taskSpecEqualsTaskInstance(childSpec, children.get(i), tasks));
[1146]320        }
[790]321    }
322
323    /**
324     *
325     */
[1146]326    private boolean taskSpecEqualsTaskInstance(TaskSpec           taskSpec,
327                                               ITaskInstance      taskInstance,
328                                               Map<String, ITask> tasks)
329    {
[790]330        if (doTrace) {
331            System.err.println("comparing " + taskSpec.name + " with");
[1146]332            new TaskTreeEncoder().encode(taskInstance, System.err);
[790]333        }
334
[1146]335        ITask task = taskInstance.getTask();
336       
[790]337        if (("Event".equals(taskSpec.type) && (!(task instanceof IEventTask))) ||
338            ("TextInputEvent".equals(taskSpec.type) &&
[1294]339             ((!(taskInstance instanceof IEventTaskInstance)) ||
340              (!(((IEventTaskInstance) taskInstance).getEvent().getType() instanceof TextInput)))) ||
[790]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 + " != " +
[1146]347                                   task.getClass().getSimpleName() + "\n");
[790]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)) {
[1294]361            TextInput eventType = (TextInput)
362                ((IEventTaskInstance) taskInstance).getEvent().getType();
363           
[790]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        }
[1294]376        else if ((task instanceof IEventTask) &&
377                 (((IEventTaskInstance) taskInstance).getEvent().getType() != null) &&
378                 (!taskSpec.name.equals(((IEventTaskInstance) taskInstance).getEvent().getType().getName())))
[790]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
[1294]386            if (!complexName.equals(((IEventTaskInstance) taskInstance).getEvent().getType().getName())) {
[790]387                if (doTrace) {
[1294]388                    System.err.println
389                        ("event names do not match: " + taskSpec.name + " != " +
390                         ((IEventTaskInstance) taskInstance).getEvent().getType().getName() + "\n");
[790]391                }
392                return false;
393            }
394        }
[1146]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        }
[790]416
[1294]417        List<ITaskInstance> children = getChildren(taskInstance);
418       
419        if (((taskSpec.children == null) && (children.size() > 0)) ||
[1146]420            ((taskSpec.children != null) &&
[1294]421             (taskSpec.children.length != children.size())))
[790]422        {
423            if (doTrace) {
424                System.err.println
425                    ("numbers of children do not match: " +
426                     (taskSpec.children == null ? "0" : taskSpec.children.length) + " != " +
[1294]427                     (children == null ? "0" : children.size()) + "\n");
[790]428            }
429            return false;
430        }
431
[1294]432        Iterator<ITaskInstance> childrenIterator = children.iterator();
[790]433        if (taskSpec.children != null) {
434            for (TaskSpec child : taskSpec.children) {
[1294]435                if (!taskSpecEqualsTaskInstance(child, childrenIterator.next(), tasks)) {
[790]436                    if (doTrace) {
437                        System.err.println("one of the children does not match\n");
438                    }
439                    return false;
440                }
441            }
442        }
443
[1294]444        if (!childrenIterator.hasNext()) {
[790]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    }
[1146]457   
[790]458    /**
[1294]459     * <p>
460     * TODO: comment
461     * </p>
[790]462     *
[1294]463     * @param taskInstance
464     * @return
[790]465     */
[1294]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     */
[790]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.