package de.ugoe.cs.autoquest.tasktrees; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.PrintWriter; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; import de.ugoe.cs.autoquest.eventcore.gui.TextInput; import de.ugoe.cs.autoquest.tasktrees.treeifc.IEventTask; import de.ugoe.cs.autoquest.tasktrees.treeifc.IIteration; import de.ugoe.cs.autoquest.tasktrees.treeifc.ISelection; import de.ugoe.cs.autoquest.tasktrees.treeifc.ISequence; import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTree; import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNode; import de.ugoe.cs.autoquest.tasktrees.treeifc.ITaskTreeNodeInfo; /** * TODO comment * * @version $Revision: $ $Date: 01.04.2012$ * @author 2012, last modified by $Author: patrick$ */ public class TaskTreeChecker { /** */ private static Pattern taskPattern = Pattern.compile("([^{}]+)\\{|\\}"); /** */ private static Pattern taskDetailsPattern = Pattern.compile("\\s*(\\w*)\\s*(\\w*)\\s*((\\w*)|(\".*\"))?"); /** */ private boolean doTrace; /** * TODO: comment * */ public TaskTreeChecker() { this(false); } /** * TODO: comment * */ public TaskTreeChecker(boolean doTrace) { this.doTrace = doTrace; } /** * */ public void assertTaskTree(String taskTreeSpec, ITaskTree taskTree) { Map taskMapCopy = new HashMap(); for (Map.Entry entry : taskTree.getTaskMap().entrySet()) { if (entry.getValue().getNoOfOccurencesInTree() > 0) { taskMapCopy.put(entry.getKey(), entry.getValue().getNoOfOccurencesInTree()); } else { taskMapCopy.put(entry.getKey(), 1); } } if (doTrace) { dumpTaskMap(taskMapCopy); } TaskSpec task = null; Matcher taskMatcher = taskPattern.matcher(taskTreeSpec); while (taskMatcher.find()) { task = parseTask(taskMatcher); if (task != null) { assertTaskAndChildrenInMapAndRemove(task, taskMapCopy); } } assertTrue("more tasks in map, than expected", taskMapCopy.isEmpty()); } /** * TODO: comment * * @param taskTree */ public void dumpAsCheckString(ITaskTree taskTree) { dumpNodeAsCheckString(taskTree.getRoot(), new int[4], ""); } /** * TODO: comment * * @param root * @param string */ private void dumpNodeAsCheckString(ITaskTreeNode node, int[] typeCounters, String indent) { System.out.print(" \""); System.out.print(indent); if (node instanceof ISequence) { System.out.print("Sequence sequence"); System.out.print(typeCounters[0]++); System.out.println(" {\" +"); } else if (node instanceof IIteration) { System.out.print("Iteration iteration"); System.out.print(typeCounters[1]++); System.out.println(" {\" +"); } else if (node instanceof ISelection) { System.out.print("Selection selection"); System.out.print(typeCounters[2]++); System.out.println(" {\" +"); } else if (node instanceof IEventTask) { if (((IEventTask) node).getEventType() instanceof TextInput) { System.out.print("TextInputEvent textInput"); System.out.print(typeCounters[3]++); System.out.print(" \""); System.out.print(((TextInput) ((IEventTask) node).getEventType()).getEnteredText()); System.out.print("\""); } else { System.out.print("Event "); System.out.print(((IEventTask) node).getEventType().getName()); } System.out.print(" {}\" +"); } else { fail("unknown type of node in task tree " + node); } for (ITaskTreeNode child : node.getChildren()) { dumpNodeAsCheckString(child, typeCounters, indent + " "); } if (!(node instanceof IEventTask)) { System.out.print(" \""); System.out.print(indent); System.out.print("}\" +"); } System.out.println(); } /** * TODO: comment * * @param taskTree */ public void dumpFullTaskTree(ITaskTree taskTree) throws FileNotFoundException { PrintWriter out = null; try { out = new PrintWriter(new FileOutputStream("taskTree.txt")); dumpFullNode(taskTree.getRoot(), out, "", 0); } finally { if (out != null) { out.close(); } } } /** * */ private void dumpFullNode(ITaskTreeNode node, PrintWriter out, String indent, int index) { if (node instanceof ISequence) { if (index > 0) { out.println(); } out.print(indent); out.println("Sequence {"); } else if (node instanceof IIteration) { if (index > 0) { out.println(); } out.print(indent); out.println("Iteration {"); } else if (node instanceof ISelection) { if (index > 0) { out.println(); } out.print(indent); out.println("Selection {"); } else if (node instanceof IEventTask) { out.print(indent); out.print(((IEventTask) node).getEventType().getName()); out.print(" "); out.print(((IEventTask) node).getEventTarget()); // if (((IEventTask) node).getEventTarget() instanceof IGUIElement) { // out.print(" "); // out.print(((IGUIElement) ((IEventTask) node).getEventTarget()).getSpecification()); // } } else { fail("unknown type of node in task tree " + node); } int i = 0; for (ITaskTreeNode child : node.getChildren()) { dumpFullNode(child, out, indent + " ", i++); } if (!(node instanceof IEventTask)) { out.print(indent); out.print("}"); } out.println(); } /** * */ private TaskSpec parseTask(Matcher taskMatcher) { if ("}".equals(taskMatcher.group(1))) { throw new IllegalArgumentException("invalid task specification"); } String taskDetails = taskMatcher.group(1); Matcher matcher = taskDetailsPattern.matcher(taskDetails); if (!matcher.find()) { throw new IllegalArgumentException("could not parse task details"); } TaskSpec task = new TaskSpec(); task.type = matcher.group(1); task.name = matcher.group(2); if ((matcher.group(4) != null) && (!"".equals(matcher.group(4).trim()))) { task.name += " " + matcher.group(4).trim(); } if ((matcher.group(5) != null) && (!"".equals(matcher.group(5).trim()))) { task.additionalInfo = matcher.group(5).trim(); } if ("".equals(task.name)) { task.name = null; } List children = new ArrayList(); while (taskMatcher.find() && !"}".equals(taskMatcher.group(0))) { children.add(parseTask(taskMatcher)); } if (children.size() > 0) { task.children = children.toArray(new TaskSpec[children.size()]); } return task; } /** * @param task * @param taskMapCopy */ private void assertTaskAndChildrenInMapAndRemove(TaskSpec task, Map taskMap) { for (Map.Entry entry : taskMap.entrySet()) { if (taskSpecEqualsTask(task, entry.getKey())) { if (task.children != null) { for (TaskSpec child : task.children) { assertTaskAndChildrenInMapAndRemove(child, taskMap); } } int count = taskMap.get(entry.getKey()); if (count == 1) { taskMap.remove(entry.getKey()); } else { taskMap.put(entry.getKey(), count - 1); } return; } } fail("expected task " + task.type + " " + task.name + " not included in task map"); } /** * */ private boolean taskSpecEqualsTask(TaskSpec taskSpec, ITaskTreeNode task) { if (doTrace) { System.err.println("comparing " + taskSpec.name + " with"); dumpTask(task, 0, ""); } if (("Event".equals(taskSpec.type) && (!(task instanceof IEventTask))) || ("TextInputEvent".equals(taskSpec.type) && ((!(task instanceof IEventTask)) || (!(((IEventTask) task).getEventType() instanceof TextInput)))) || ("Sequence".equals(taskSpec.type) && (!(task instanceof ISequence))) || ("Selection".equals(taskSpec.type) && (!(task instanceof ISelection))) || ("Iteration".equals(taskSpec.type) && (!(task instanceof IIteration)))) { if (doTrace) { System.err.println("task types do not match: " + taskSpec.type + " != " + task.getClass().getSimpleName() + "\n"); } return false; } else if (!"Event".equals(taskSpec.type) && !"TextInputEvent".equals(taskSpec.type) && !"Sequence".equals(taskSpec.type) && !"Selection".equals(taskSpec.type) && !"Iteration".equals(taskSpec.type)) { fail("unknown task type " + taskSpec.type + " --> please extend test case"); } if ("TextInputEvent".equals(taskSpec.type)) { TextInput eventType = (TextInput) ((IEventTask) task).getEventType(); if ((taskSpec.additionalInfo != null) && !"".equals(taskSpec.additionalInfo) && !(taskSpec.additionalInfo.equals(eventType.getEnteredText()))) { if (doTrace) { System.err.println("expected text \"" + taskSpec.additionalInfo + "\" is not equal to the text " + "provided by the task \"" + eventType.getEnteredText() + "\"\n"); } return false; } } else if ((task instanceof IEventTask) && (((IEventTask) task).getEventType() != null) && (!taskSpec.name.equals(((IEventTask) task).getEventType().getName()))) { // simple event names do not match. But what about the event name in // combination with the additional info String complexName = taskSpec.name + (!"".equals(taskSpec.additionalInfo) ? " " + taskSpec.additionalInfo : ""); if (!complexName.equals(((IEventTask) task).getEventType().getName())) { if (doTrace) { System.err.println("event names do not match: " + taskSpec.name + " != " + ((IEventTask) task).getEventType().getName() + "\n"); } return false; } } if (((taskSpec.children == null) && (task.getChildren().size() > 0)) || ((taskSpec.children != null) && (taskSpec.children.length != task.getChildren().size()))) { if (doTrace) { System.err.println ("numbers of children do not match: " + (taskSpec.children == null ? "0" : taskSpec.children.length) + " != " + (task.getChildren() == null ? "0" : task.getChildren().size()) + "\n"); } return false; } Iterator children = task.getChildren().iterator(); if (taskSpec.children != null) { for (TaskSpec child : taskSpec.children) { if (!taskSpecEqualsTask(child, children.next())) { if (doTrace) { System.err.println("one of the children does not match\n"); } return false; } } } if (!children.hasNext()) { if (doTrace) { System.err.println("nodes match\n"); } return true; } else { if (doTrace) { System.err.println("number of children does not match\n"); } return false; } } /** * */ private void dumpTaskMap(Map taskMap) { System.err.println(); for (Map.Entry entry : taskMap.entrySet()) { dumpTask(entry.getKey(), entry.getValue(), ""); System.err.println(); } } /** * */ private void dumpTask(ITaskTreeNode task, int count, String indent) { System.err.print(indent); System.err.print(task); System.err.print(" "); System.err.print(task.getDescription()); System.err.print(" "); if (count > 0) { System.err.print("("); System.err.print(count); System.err.print(" occurrences)"); } System.err.println(); if ((task.getChildren() != null) && (task.getChildren().size() > 0)) { for (ITaskTreeNode child : task.getChildren()) { dumpTask(child, 0, indent + " "); } } } /** * TODO comment * * @version $Revision: $ $Date: $ * @author 2011, last modified by $Author: $ */ private class TaskSpec { public String type; public String name; public String additionalInfo; public TaskSpec[] children; } }