/* * Copyright (c) 2006, 2010 Borland Software Corporation and others * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Dmitry Stadnik (Borland) - initial API and implementation * Artem Tikhomirov (Borland) - tests for Ant build */ package org.eclipse.gmf.tests.gen; import java.io.File; import java.net.URL; import java.util.Arrays; import java.util.Collections; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.SortedSet; import java.util.TreeSet; import java.util.regex.Pattern; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathExpression; import javax.xml.xpath.XPathFactory; import org.eclipse.ant.core.AntRunner; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.FileLocator; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Platform; import org.eclipse.gmf.codegen.gmfgen.CreateShortcutAction; import org.eclipse.gmf.codegen.gmfgen.CustomParser; import org.eclipse.gmf.codegen.gmfgen.DynamicModelAccess; import org.eclipse.gmf.codegen.gmfgen.GMFGenFactory; import org.eclipse.gmf.codegen.gmfgen.GenCommandAction; import org.eclipse.gmf.codegen.gmfgen.GenContextMenu; import org.eclipse.gmf.codegen.gmfgen.GenCustomAction; import org.eclipse.gmf.codegen.gmfgen.GenCustomPreferencePage; import org.eclipse.gmf.codegen.gmfgen.GenDiagram; import org.eclipse.gmf.codegen.gmfgen.GenEditorGenerator; import org.eclipse.gmf.codegen.gmfgen.GenGroupMarker; import org.eclipse.gmf.codegen.gmfgen.GenMenuManager; import org.eclipse.gmf.codegen.gmfgen.GenPlugin; import org.eclipse.gmf.codegen.gmfgen.GenPreference; import org.eclipse.gmf.codegen.gmfgen.GenStandardPreferencePage; import org.eclipse.gmf.codegen.gmfgen.LoadResourceAction; import org.eclipse.gmf.codegen.gmfgen.StandardPreferencePages; import org.eclipse.gmf.internal.bridge.genmodel.InnerClassViewmapProducer; import org.eclipse.gmf.mappings.AuditContainer; import org.eclipse.gmf.mappings.AuditRule; import org.eclipse.gmf.mappings.Constraint; import org.eclipse.gmf.mappings.DiagramElementTarget; import org.eclipse.gmf.mappings.DomainElementTarget; import org.eclipse.gmf.mappings.GMFMapFactory; import org.eclipse.gmf.mappings.Mapping; import org.eclipse.gmf.mappings.MetricContainer; import org.eclipse.gmf.mappings.MetricRule; import org.eclipse.gmf.mappings.Severity; import org.eclipse.gmf.tests.setup.DiaGenSource; import org.eclipse.gmf.tests.setup.RuntimeBasedGeneratorConfiguration; import org.eclipse.gmf.tests.setup.annotated.GenASetup; import org.eclipse.jdt.core.Flags; import org.eclipse.jdt.core.ICompilationUnit; import org.eclipse.jdt.core.IField; import org.eclipse.jdt.core.IMethod; import org.eclipse.jdt.core.IType; import org.eclipse.jdt.core.JavaCore; import org.eclipse.jface.preference.IPreferenceStore; import org.w3c.dom.Document; import org.w3c.dom.NodeList; import org.xml.sax.InputSource; /** * @author dstadnik */ public class RuntimeCompilationTest extends CompilationTest { public RuntimeCompilationTest(String name) { this(name, new RuntimeBasedGeneratorConfiguration()); } public RuntimeCompilationTest(String name, RuntimeBasedGeneratorConfiguration genConfig) { super(name, genConfig, new InnerClassViewmapProducer()); } /** * Pure design diagrams are not supported in lite version. */ public void testCompilePureDesignDiagram() throws Exception { myMapSource.detachFromDomainModel(); DiaGenSource gmfGenSource = createLibraryGen(false); gmfGenSource.getGenDiagram().getEditorGen().setPackageNamePrefix("org.eclipse.gmf.examples.library.diagram"); //$NON-NLS-1$ generateAndCompile(gmfGenSource); } public void testCompileDynamicDomainModel() throws Exception { DiaGenSource s = createLibraryGen(false); final GenEditorGenerator editorGen = s.getGenDiagram().getEditorGen(); assertNull("prereq", editorGen.getModelAccess()); DynamicModelAccess dma = GMFGenFactory.eINSTANCE.createDynamicModelAccess(); editorGen.setModelAccess(dma); generateAndCompile(s, new GenDiagramMutator("dynmodel") { @Override public void doMutation(GenDiagram d) { final DynamicModelAccess modelAccess = d.getEditorGen().getModelAccess(); modelAccess.setClassName("NonDefaultDynamicAccessorName"); } @Override public void undoMutation(GenDiagram d) { final DynamicModelAccess modelAccess = d.getEditorGen().getModelAccess(); modelAccess.setClassName(null); } }); } public void testPreferencePages() throws Exception { DiaGenSource s = createLibraryGen(false); final GenDiagram gd = s.getGenDiagram(); // Part 1: compile all standard GenStandardPreferencePage[] p = new GenStandardPreferencePage[StandardPreferencePages.values().length]; assertTrue("sanity", p.length > 5); for (int i = 0; i < p.length; i++) { p[i] = GMFGenFactory.eINSTANCE.createGenStandardPreferencePage(); p[i].setClassName("Page" + i); p[i].setKind(StandardPreferencePages.values()[i]); if (i > 0) { p[i - 1].getChildren().add(p[i]); } } gd.getPreferencePages().clear(); gd.getPreferencePages().add(p[0]); generateAndCompile(s); GenPlugin gp = gd.getEditorGen().getPlugin(); IProject generatedProject = ResourcesPlugin.getWorkspace().getRoot().getProject(gp.getID()); IFile generatedManifest = generatedProject.getFile("plugin.xml"); assertTrue(generatedManifest.exists()); XPathFactory xf = XPathFactory.newInstance(); XPathExpression xe = xf.newXPath().compile("/plugin/extension[@point = 'org.eclipse.ui.preferencePages']/page"); NodeList result = (NodeList) xe.evaluate(new InputSource(generatedManifest.getContents()), XPathConstants.NODESET); assertEquals(p.length, result.getLength()); // // Part 2: generateBoilerplate and subset of pages gp.setID(gp.getID() + ".boilerplateprefpage"); gd.getPreferencePages().clear(); GenCustomPreferencePage cp1 = GMFGenFactory.eINSTANCE.createGenCustomPreferencePage(); cp1.setQualifiedClassName(gd.getPreferencesPackageName() + ".CustomPageNoCodeGenerated"); cp1.setGenerateBoilerplate(false); GenCustomPreferencePage cp2 = GMFGenFactory.eINSTANCE.createGenCustomPreferencePage(); cp2.setQualifiedClassName(gd.getPreferencesPackageName() + ".CustomPageWithBoilerplateCode"); cp2.setGenerateBoilerplate(true); GenStandardPreferencePage onePage = GMFGenFactory.eINSTANCE.createGenStandardPreferencePage(); onePage.setKind(StandardPreferencePages.CONNECTIONS_LITERAL); onePage.getChildren().add(cp1); onePage.getChildren().add(cp2); gd.getPreferencePages().add(onePage); generateAndCompile(s); generatedProject = ResourcesPlugin.getWorkspace().getRoot().getProject(gp.getID()); generatedManifest = generatedProject.getFile("plugin.xml"); assertTrue(generatedManifest.exists()); // check all three have been registered result = (NodeList) xe.evaluate(new InputSource(generatedManifest.getContents()), XPathConstants.NODESET); assertEquals(3, result.getLength()); HashSet<String> names = new HashSet<String>(); names.add(onePage.getQualifiedClassName()); names.add(cp1.getQualifiedClassName()); names.add(cp2.getQualifiedClassName()); assertTrue("sanity", names.size() == 3); for (int i = 0; i < result.getLength(); i++) { String className = result.item(i).getAttributes().getNamedItem("class").getNodeValue(); assertTrue(className, names.remove(className)); } assertTrue(names.isEmpty()); // check real files IFile file_sp = generatedProject.getFile("/src/" + onePage.getQualifiedClassName().replace('.', '/') + ".java"); IFile file_cp1 = generatedProject.getFile("/src/" + cp1.getQualifiedClassName().replace('.', '/') + ".java"); IFile file_cp2 = generatedProject.getFile("/src/" + cp2.getQualifiedClassName().replace('.', '/') + ".java"); assertTrue(file_sp.exists()); assertTrue(file_cp2.exists()); assertFalse(file_cp1.exists()); } public void testCustomActions() throws Exception { DiaGenSource s = createLibraryGen(false); final GenEditorGenerator editorGen = s.getGenDiagram().getEditorGen(); GenContextMenu menu = GMFGenFactory.eINSTANCE.createGenContextMenu(); GenCustomAction a1 = GMFGenFactory.eINSTANCE.createGenCustomAction(); GenCustomAction a2 = GMFGenFactory.eINSTANCE.createGenCustomAction(); GenCustomAction a3 = GMFGenFactory.eINSTANCE.createGenCustomAction(); a1.setGenerateBoilerplate(false); a2.setGenerateBoilerplate(true); a3.setGenerateBoilerplate(true); a1.setQualifiedClassName("org.sample.actions.Action1"); a2.setQualifiedClassName("org.sample.actions.Action2"); a3.setQualifiedClassName("org.sample.actions.Action3"); a1.setName("testaction-1"); a2.setName("testaction-2"); a3.setName("testaction-3"); GenMenuManager subMenu = GMFGenFactory.eINSTANCE.createGenMenuManager(); subMenu.setID("org.sample.submenu"); GenGroupMarker gm = GMFGenFactory.eINSTANCE.createGenGroupMarker(); gm.setGroupName("group.name"); GenCommandAction cmdAction = GMFGenFactory.eINSTANCE.createGenCommandAction(); cmdAction.setCommandIdentifier("org.sample.command"); subMenu.getItems().add(a3); subMenu.getItems().add(gm); subMenu.getItems().add(cmdAction); menu.getItems().add(a1); menu.getItems().add(GMFGenFactory.eINSTANCE.createGenSeparator()); menu.getItems().add(a2); menu.getItems().add(subMenu); editorGen.getContextMenus().clear(); // make sure there's no other (default) menus editorGen.getContextMenus().add(menu); // generateAndCompile(s); // IProject generatedProject = ResourcesPlugin.getWorkspace().getRoot().getProject(editorGen.getPlugin().getID()); IFile generatedManifest = generatedProject.getFile("plugin.xml"); assertTrue(generatedManifest.exists()); DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder(); Document parsedManifest = db.parse(new InputSource(generatedManifest.getContents())); XPath xf = XPathFactory.newInstance().newXPath(); XPathExpression xe = xf.compile("/plugin/extension[@point = 'org.eclipse.ui.menus']/menuContribution"); NodeList result = (NodeList) xe.evaluate(parsedManifest, XPathConstants.NODESET); assertEquals(2, result.getLength()); // one contribution to global context menu and another for submenu String l1 = result.item(0).getAttributes().getNamedItem("locationURI").getNodeValue(); String l2 = result.item(1).getAttributes().getNamedItem("locationURI").getNodeValue(); assertEquals(l1, "popup:org.eclipse.gmf.runtime.diagram.ui.DiagramEditorContextMenu"); assertEquals(l2, "popup:" + subMenu.getID()); // xe = xf.compile("/plugin/extension[@point = 'org.eclipse.ui.menus']/menuContribution/menu"); result = (NodeList) xe.evaluate(parsedManifest, XPathConstants.NODESET); assertEquals(1, result.getLength()); String menuIdAttr = result.item(0).getAttributes().getNamedItem("id").getNodeValue(); assertEquals(subMenu.getID(), menuIdAttr); // xe = xf.compile("/plugin/extension[@point = 'org.eclipse.ui.menus']/menuContribution/command"); result = (NodeList) xe.evaluate(parsedManifest, XPathConstants.NODESET); assertEquals(4, result.getLength()); // FIXME assert command contribution goes into correct locationURI // xe = xf.compile("/plugin/extension[@point = 'org.eclipse.ui.menus']/menuContribution/separator"); result = (NodeList) xe.evaluate(parsedManifest, XPathConstants.NODESET); assertEquals(2, result.getLength()); // xe = xf.compile("/plugin/extension[@point = 'org.eclipse.ui.commands']/command[starts-with(@name,'testaction-')]"); result = (NodeList) xe.evaluate(parsedManifest, XPathConstants.NODESET); assertEquals(3, result.getLength()); // xe = xf.compile("/plugin/extension[@point = 'org.eclipse.ui.handlers']/handler"); result = (NodeList) xe.evaluate(parsedManifest, XPathConstants.NODESET); assertEquals(3, result.getLength()); String h1 = result.item(0).getAttributes().getNamedItem("class").getNodeValue(); String h2 = result.item(1).getAttributes().getNamedItem("class").getNodeValue(); String h3 = result.item(2).getAttributes().getNamedItem("class").getNodeValue(); assertEquals(a1.getQualifiedClassName(), h1); assertEquals(a2.getQualifiedClassName(), h2); assertEquals(a3.getQualifiedClassName(), h3); // check real files for handlers IFile file_a1 = generatedProject.getFile("/src/" + a1.getQualifiedClassName().replace('.', '/') + ".java"); IFile file_a2 = generatedProject.getFile("/src/" + a2.getQualifiedClassName().replace('.', '/') + ".java"); IFile file_a3 = generatedProject.getFile("/src/" + a3.getQualifiedClassName().replace('.', '/') + ".java"); assertFalse(file_a1.exists()); assertTrue(file_a2.exists()); assertTrue(file_a3.exists()); } // CreateShortcut, LoadResource, InitDiagramFileAction public void testPredefinedActions() throws Exception { DiaGenSource s1 = createLibraryGen(false); final GenEditorGenerator editorGen = s1.getGenDiagram().getEditorGen(); GenContextMenu menu = GMFGenFactory.eINSTANCE.createGenContextMenu(); menu.getContext().add(s1.getGenDiagram()); final CreateShortcutAction createShortcutAction = GMFGenFactory.eINSTANCE.createCreateShortcutAction(); final LoadResourceAction loadResourceAction = GMFGenFactory.eINSTANCE.createLoadResourceAction(); menu.getItems().add(createShortcutAction); menu.getItems().add(loadResourceAction); editorGen.getContextMenus().clear(); // make sure there's no other (default) menus editorGen.getContextMenus().add(menu); editorGen.getDiagram().getContainsShortcutsTo().add("ecore"); assertTrue("sanity", editorGen.getDiagram().generateCreateShortcutAction()); // generateAndCompile(s1); // IProject generatedProject = ResourcesPlugin.getWorkspace().getRoot().getProject(editorGen.getPlugin().getID()); IFile generatedManifest = generatedProject.getFile("plugin.xml"); assertTrue(generatedManifest.exists()); DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder(); Document parsedManifest = db.parse(new InputSource(generatedManifest.getContents())); XPath xf = XPathFactory.newInstance().newXPath(); XPathExpression xe = xf.compile("/plugin/extension[@point = 'org.eclipse.ui.menus']/menuContribution/command"); NodeList result = (NodeList) xe.evaluate(parsedManifest, XPathConstants.NODESET); assertEquals(2, result.getLength()); xe = xf.compile("/plugin/extension[@point = 'org.eclipse.ui.commands']/command"); result = (NodeList) xe.evaluate(parsedManifest, XPathConstants.NODESET); assertTrue(result.getLength() > 2); HashSet<String> allCommands = new HashSet<String>(); for (int i = result.getLength() - 1; i >= 0; i--) { allCommands.add(result.item(i).getAttributes().getNamedItem("defaultHandler").getNodeValue()); } assertTrue(allCommands.contains(createShortcutAction.getQualifiedClassName())); assertTrue(allCommands.contains(loadResourceAction.getQualifiedClassName())); IFile file1 = generatedProject.getFile("/src/" + createShortcutAction.getQualifiedClassName().replace('.', '/') + ".java"); IFile file2 = generatedProject.getFile("/src/" + loadResourceAction.getQualifiedClassName().replace('.', '/') + ".java"); assertTrue(file1.exists()); assertTrue(file2.exists()); // // DiaGenSource s2 = createLibraryGen(true); // fail("TODO"); } public void testCustomPreferences() throws Exception { DiaGenSource s = createLibraryGen(false); final GenDiagram gd = s.getGenDiagram(); GenCustomPreferencePage pp = GMFGenFactory.eINSTANCE.createGenCustomPreferencePage(); if (gd.getPreferencePages().isEmpty()) { gd.getPreferencePages().add(pp); } else { gd.getPreferencePages().get(0).getChildren().add(pp); } pp.setGenerateBoilerplate(true); pp.setName("Page Name"); pp.setQualifiedClassName(gd.getEditorGen().getEditor().getPackageName() + ".CustomPreferencePage"); GenPreference p1 = GMFGenFactory.eINSTANCE.createGenPreference(); p1.setName("PREF_XXX_ONE"); p1.setDefaultValue("\"XXX_ONE_DEFAULT\""); GenPreference p2 = GMFGenFactory.eINSTANCE.createGenPreference(); p2.setName("NO_PREFIX_XXX_TWO"); p2.setKey("KEY.XXX.TWO"); pp.getPreferences().add(p1); pp.getPreferences().add(p2); // generateAndCompile(s); // IProject generatedProject = ResourcesPlugin.getWorkspace().getRoot().getProject(gd.getEditorGen().getPlugin().getID()); IFile file_pp = generatedProject.getFile("/src/" + pp.getQualifiedClassName().replace('.', '/') + ".java"); assertTrue(file_pp.exists()); ICompilationUnit cuPage = (ICompilationUnit) JavaCore.create(file_pp); assertNotNull(cuPage); IType mainClass = cuPage.getTypes()[0]; assertNotNull(mainClass); assertEquals(2, mainClass.getFields().length); final IField p1field = mainClass.getField(p1.getName()); final IField p2field = mainClass.getField(p2.getName()); assertTrue(Flags.isPublic(p1field.getFlags())); assertTrue(Flags.isStatic(p1field.getFlags())); assertTrue(Flags.isPublic(p2field.getFlags())); assertTrue(Flags.isStatic(p2field.getFlags())); assertEquals('"' + p1.getKey() + '"', p1field.getConstant()); assertEquals('"' + p2.getKey() + '"', p2field.getConstant()); IMethod initMethod = mainClass.getMethod("initDefaults", new String[] { "Q" + IPreferenceStore.class.getSimpleName() + ";" }); assertNotNull(initMethod); String methodText = initMethod.getSource(); assertTrue(methodText.indexOf(p1.getName()) != -1); assertTrue(methodText.indexOf(p1.getDefaultValue()) != -1); assertTrue(methodText.indexOf(p2.getName()) == -1); } // check CustomParser#isGenerateBoilerplate == true emits java class public void testCustomParsers() throws Exception { DiaGenSource s = createLibraryGen(false); final GenEditorGenerator gd = s.getGenDiagram().getEditorGen(); CustomParser cp1 = GMFGenFactory.eINSTANCE.createCustomParser(); cp1.setQualifiedName(gd.getLabelParsers().getImplPackageName() + "CustomParserOne"); CustomParser cp2 = GMFGenFactory.eINSTANCE.createCustomParser(); cp2.setQualifiedName(gd.getLabelParsers().getImplPackageName() + "CustomParserTwo"); cp2.setGenerateBoilerplate(true); gd.getLabelParsers().getImplementations().add(cp1); gd.getLabelParsers().getImplementations().add(cp2); // generateAndCompile(s); // IProject generatedProject = ResourcesPlugin.getWorkspace().getRoot().getProject(gd.getPlugin().getID()); IFile file_cp1 = generatedProject.getFile("/src/" + cp1.getQualifiedName().replace('.', '/') + ".java"); IFile file_cp2 = generatedProject.getFile("/src/" + cp2.getQualifiedName().replace('.', '/') + ".java"); assertFalse(file_cp1.exists()); assertTrue(file_cp2.exists()); } public void _testAntScriptEmitsSameStructure() throws Exception { Mapping mapping = myMapSource.getMapping(); // // metrics MetricContainer mc = GMFMapFactory.eINSTANCE.createMetricContainer(); MetricRule mr = GMFMapFactory.eINSTANCE.createMetricRule(); mr.setKey("metric.rule1"); //$NON-NLS-1$ // Note: use characters that need to be escaped in java source string literals mr.setName("Name of " + mr.getKey()); //$NON-NLS-1$ mr.setDescription("Description of " + mr.getKey()); //$NON-NLS-1$ mr.setRule(GMFMapFactory.eINSTANCE.createValueExpression()); mr.getRule().setBody("'aaa'.size() + 2"); mr.setLowLimit(new Double(2)); mr.setHighLimit(new Double(6)); DiagramElementTarget diagramElementTarget = GMFMapFactory.eINSTANCE.createDiagramElementTarget(); diagramElementTarget.setElement(mapping.getNodes().get(0).getChild()); mr.setTarget(diagramElementTarget); mc.getMetrics().add(mr); mapping.setMetrics(mc); // // audits AuditContainer ac = GMFMapFactory.eINSTANCE.createAuditContainer(); ac.setId("ac1"); //$NON-NLS-1$ ac.setName(ac.getId()); AuditRule ar = GMFMapFactory.eINSTANCE.createAuditRule(); String ar_id = "audit.rule1"; ar.setId(ar_id); ar.setName("Name of " + ar_id); //$NON-NLS-1$ ar.setMessage("Violation of " + ar_id); //$NON-NLS-1$ ar.setDescription("Description of " + ar_id); //$NON-NLS-1$ DomainElementTarget classLibrary = GMFMapFactory.eINSTANCE.createDomainElementTarget(); classLibrary.setElement(mapping.getDiagram().getDomainMetaElement()); ar.setTarget(classLibrary); Constraint rule = GMFMapFactory.eINSTANCE.createConstraint(); // body is not essential, just to look nice rule.setBody("Library.allInstances()->size() > 0"); //$NON-NLS-1$ ar.setRule(rule); ar.setSeverity(Severity.ERROR_LITERAL); ar.setUseInLiveMode(true); ac.getAudits().add(ar); mapping.setAudits(ac); DiaGenSource s = new GenASetup(mapping, myViewmapProducer, false); // // validation s.getGenDiagram().setValidationEnabled(true); // although presence of audits effectively does the same // // shortcuts s.getGenDiagram().getContainsShortcutsTo().add("ecore"); s.getGenDiagram().getShortcutsProvidedFor().add("ecore"); s.getGenDiagram().eResource().save(null); testAntScriptEmitsSameStructure(s); } public void _testAntScriptEmitsSameStructure_rcp() throws Exception { testAntScriptEmitsSameStructure(createLibraryGen(true)); } private void testAntScriptEmitsSameStructure(DiaGenSource s) throws Exception { System.out.println(s.getGenDiagram().eResource().getURI().toString()); URL scriptLocation = FileLocator.find(Platform.getBundle("org.eclipse.gmf.xpand.ant"), new Path("/examples/gmfgen-run.xml"), null); assertNotNull(scriptLocation); AntRunner r = new AntRunner(); r.setBuildFileLocation(FileLocator.toFileURL(scriptLocation).getFile()); File antOutputRoot = File.createTempFile("aaa", ""); antOutputRoot.delete(); antOutputRoot = new File(antOutputRoot.getParentFile(), antOutputRoot.getName()); antOutputRoot.mkdir(); r.setArguments("-Dinput-gmfgen-model-uri=" + s.getGenDiagram().eResource().getURI().toString() + "#/ -DoutputRoot=" + antOutputRoot.getAbsolutePath()); r.run(new NullProgressMonitor()); // FileCollector antResult = new FileCollector(); FileCollector javaResult = new FileCollector(); final String[] filters = { ".*\\.java$", ".*\\.properties$", "MANIFEST\\.MF$", "plugin\\.xml$", "\\.options$", ".*\\.gif$" }; antResult.addNameFilter(filters); javaResult.addNameFilter(filters); // System.out.println(antOutputRoot); TreeSet<String> antResultFileNames = new TreeSet<String>(); for (File f : antResult.collect(antOutputRoot)) { antResultFileNames.add(f.getPath().substring(antOutputRoot.getPath().length())); } generateAndCompile(s, (GenDiagramMutator[]) null); // IProject generatedProject = ResourcesPlugin.getWorkspace().getRoot().getProject(s.getGenDiagram().getEditorGen().getPlugin().getID()); File javaOutputRoot = ResourcesPlugin.getWorkspace().getRoot().getLocation().toFile(); javaResult.collect(generatedProject.getLocation().toFile()); boolean missingFiles = false, excessiveFiles = false; for (File f : javaResult.getResult()) { String javaResultFile = f.getPath().substring(javaOutputRoot.getPath().length()); if (!antResultFileNames.remove(javaResultFile)) { missingFiles = true; System.err.println("Missing file: " + javaResultFile); } } for (String a : antResultFileNames) { excessiveFiles = true; System.out.println("Excessive file generated by ANT: " + a); } assertFalse("Few files are not generated by Ant codegen script", missingFiles); // TODO provide list of missing files as part of the message assertFalse("Ant codegen script produces excessive files", excessiveFiles); // TODO list of files in the message } static class FileCollector { private final TreeSet<File> myResult; private boolean myIsRecursive = true; private final List<Pattern> myFilters = new LinkedList<Pattern>(); public FileCollector() { myResult = new TreeSet<File>(); } public void addNameFilter(String... nameFilter) { for (String f : nameFilter) { myFilters.add(Pattern.compile(f)); } } public void setRecursive(boolean recurseIntoSubfolders) { myIsRecursive = recurseIntoSubfolders; } public SortedSet<File> getResult() { return Collections.unmodifiableSortedSet(myResult); } public SortedSet<File> collect(File dir) { if (!dir.isDirectory()) { throw new IllegalArgumentException(); } LinkedList<File> queue = new LinkedList<File>(Arrays.asList(dir.listFiles())); while (!queue.isEmpty()) { File f = queue.removeFirst(); if (f.isDirectory() && myIsRecursive) { queue.addAll(Arrays.asList(f.listFiles())); continue; } if (f.isFile()) { if (myFilters.isEmpty()) { myResult.add(f); continue; } else { for (Pattern p : myFilters) { if (p.matcher(f.getName()).matches()) { myResult.add(f); break; // continue outer cycle } } } } } return getResult(); } } }