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

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