/******************************************************************************* * Copyright (c) 2012 VMWare, Inc. * 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: * VMWare, Inc. - initial API and implementation *******************************************************************************/ package org.grails.ide.eclipse.ui.test; import java.util.ArrayList; import java.util.List; import org.codehaus.groovy.eclipse.dsl.DSLPreferences; import org.codehaus.groovy.eclipse.dsl.GroovyDSLCoreActivator; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFolder; import org.eclipse.jdt.core.IPackageFragmentRoot; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.swt.graphics.Image; import org.eclipse.swtbot.swt.finder.finders.UIThreadRunnable; import org.eclipse.swtbot.swt.finder.results.VoidResult; import org.eclipse.swtbot.swt.finder.widgets.SWTBotTreeItem; import org.grails.ide.eclipse.explorer.elements.GrailsClasspathContainersFolder; import org.grails.ide.eclipse.explorer.elements.GrailsPluginFolder; import org.grails.ide.eclipse.explorer.types.GrailsContainerType; import org.grails.ide.eclipse.explorer.types.GrailsContainerTypeManager; import org.springsource.ide.eclipse.commons.frameworks.test.util.SWTBotConditions; import org.springsource.ide.eclipse.commons.frameworks.test.util.SWTBotUtils; /** * @author Nieraj Singh * @author Kris De Volder * @created Jul 8, 2010 */ public class GrailsExplorerTests extends GrailsProjectHarness { @Override public void setupClass() throws Exception { // turn off Greclipse AUTO_ADD_DSL_SUPPORT: it breaks this test by // adding another node to the view, at a time which is unpredictable // (background job running // concurrently with this test). IPreferenceStore groovyPrefs = GroovyDSLCoreActivator.getDefault().getPreferenceStore(); groovyPrefs.setValue(DSLPreferences.AUTO_ADD_DSL_SUPPORT, false); super.setupClass(); } /** * The expected content of a grails Project, listed in the order that they * must appear */ private static final GrailsExplorerElementMatcher[] GRAILS_EXPLORER_CONTENT = new GrailsExplorerElementMatcher[] { getGrailsElementMatcher(GrailsContainerType.DOMAIN, true, IPackageFragmentRoot.class), getGrailsElementMatcher(GrailsContainerType.CONTROLLERS, true, IPackageFragmentRoot.class), getGrailsElementMatcher(GrailsContainerType.VIEWS, true, IFolder.class), getGrailsElementMatcher(GrailsContainerType.TAGLIB, true, IPackageFragmentRoot.class), getGrailsElementMatcher(GrailsContainerType.SERVICES, true, IPackageFragmentRoot.class), getGrailsElementMatcher(GrailsContainerType.UTILS, true, IPackageFragmentRoot.class), getGrailsElementMatcher(GrailsContainerType.SCRIPTS, true, IFolder.class), getGrailsElementMatcher(GrailsContainerType.I18N, true, IFolder.class), getGrailsElementMatcher(GrailsContainerType.CONF, true, IPackageFragmentRoot.class), getGrailsElementMatcher("src/java", true, IPackageFragmentRoot.class), getGrailsElementMatcher("src/groovy", true, IPackageFragmentRoot.class), getGrailsElementMatcher("test/unit", true, IPackageFragmentRoot.class), getGrailsElementMatcher("test/integration", true, IPackageFragmentRoot.class), getGrailsElementMatcher(GrailsContainerType.PLUGINS, true, GrailsPluginFolder.class), getGrailsElementMatcher(GrailsContainerType.CLASSPATH_CONTAINERS, true, GrailsClasspathContainersFolder.class), getGrailsElementMatcher("application.properties", true, IFile.class), getGrailsElementMatcher("grails-app", true, IFolder.class), getGrailsElementMatcher("lib", true, IFolder.class), getGrailsElementMatcher("target", true, IFolder.class), getGrailsElementMatcher("web-app", true, IFolder.class), }; protected List<GrailsExplorerElementMatcher> getExpectedProjectExplorerElementsInOrder() { List<GrailsExplorerElementMatcher> vals = new ArrayList<GrailsExplorerElementMatcher>( GRAILS_EXPLORER_CONTENT.length); for (GrailsExplorerElementMatcher label : GRAILS_EXPLORER_CONTENT) { vals.add(label); } return vals; } protected Image getGrailsTypeImage(final GrailsContainerType type) { final Image[] result = new Image[1]; UIThreadRunnable.syncExec(bot.getDisplay(), new VoidResult() { public void run() { result[0] = GrailsContainerTypeManager.getInstance().getIcon(type); } }); return result[0]; } protected Image getActualImage(final SWTBotTreeItem item) { final Image[] result = new Image[1]; UIThreadRunnable.syncExec(bot.getDisplay(), new VoidResult() { public void run() { result[0] = item.widget.getImage(); } }); return result[0]; } protected void disposeImage(final Image image) { UIThreadRunnable.syncExec(bot.getDisplay(), new VoidResult() { public void run() { image.dispose(); } }); } protected boolean compareImages(Image image1, Image image2) { byte[] data1 = image1.getImageData().data; byte[] data2 = image2.getImageData().data; if (data1.length != data2.length) { return false; } for (int i = 0; i < data1.length; i++) { if (data1[i] != data2[i]) { return false; } } return true; } protected static class GrailsExplorerElementMatcher { private boolean matchExactly = false; private GrailsContainerType type; private final String label; private final Class<?> actualType; public Class<?> getActualType() { return actualType; } public GrailsExplorerElementMatcher(String label, boolean matchExactly, Class<?> actualType) { this.matchExactly = matchExactly; this.label = label; this.actualType = actualType; } public GrailsExplorerElementMatcher(GrailsContainerType type, boolean matchExactly, Class<?> actualType) { this(type.getStructureType().getDisplayName(), matchExactly, actualType); this.type = type; } public boolean matchesLabel(String toCompare) { if (matchExactly) { return label.equals(toCompare); } else { return toCompare.length() > label.length() ? toCompare.startsWith(label) : label.startsWith(toCompare); } } public String getLabel() { return label; } public boolean isGrailsReimaged() { return type != null; } public GrailsContainerType getGrailsType() { return type; } } @Override protected void waitForProjectBuild(String projectName) throws Exception { super.waitForProjectBuild(projectName); // In addition, wait for markers to disappear, for the icon tests SWTBotConditions.waitForProjectErrorMarkersCleared(bot, getTestProject().getName()); } protected static GrailsExplorerElementMatcher getGrailsElementMatcher(String label, boolean matchExactly, Class<?> actualType) { return new GrailsExplorerElementMatcher(label, matchExactly, actualType); } protected static GrailsExplorerElementMatcher getGrailsElementMatcher(GrailsContainerType type, boolean matchExactly, Class<?> actualType) { return new GrailsExplorerElementMatcher(type, matchExactly, actualType); } // // ------------> TESTS <------------- // public void testProjectExplorerContentSize() throws Exception { SWTBotTreeItem[] actualProjectItems = getExpandedProjectTreeNode().getItems(); List<GrailsExplorerElementMatcher> expected = getExpectedProjectExplorerElementsInOrder(); assertEquals(expected.size(), actualProjectItems.length); } public void testProjectExplorerContentLabel() throws Exception { SWTBotTreeItem[] actualProjectItems = getExpandedProjectTreeNode().getItems(); List<GrailsExplorerElementMatcher> expected = getExpectedProjectExplorerElementsInOrder(); int i = 0; for (GrailsExplorerElementMatcher expectedElement : expected) { SWTBotTreeItem actualItem = actualProjectItems[i++]; String actualLabel = actualItem.getText(); boolean matches = expectedElement.matchesLabel(actualLabel); print(expectedElement.getLabel() + " MATCHES: " + matches + " " + actualLabel); assertTrue(expectedElement.getLabel() + " does NOT match: " + actualLabel, matches); } } public void testProjectExplorerContentIcon() throws Exception { SWTBotTreeItem[] actualProjectItems = getExpandedProjectTreeNode().getItems(); List<GrailsExplorerElementMatcher> expected = getExpectedProjectExplorerElementsInOrder(); int i = 0; for (GrailsExplorerElementMatcher expectedElement : expected) { SWTBotTreeItem actualItem = actualProjectItems[i++]; String actualLabel = actualItem.getText(); boolean matches = expectedElement.matchesLabel(actualLabel); print(expectedElement.getLabel() + " MATCHES: " + matches + " " + actualLabel); if (!matches) { SWTBotUtils.screenshot("icon_test_label_matching_" + expectedElement.getLabel()); } assertTrue(matches); // Check the image for the Grails reimaged folders and logical // folders if (expectedElement.isGrailsReimaged()) { GrailsContainerType type = expectedElement.getGrailsType(); Image expectedImage = getGrailsTypeImage(type); Image actualImage = getActualImage(actualItem); boolean areEqual = compareImages(expectedImage, actualImage); print("Is expected Grails folder icon equal to actual for: " + expectedElement.getLabel() + " --> " + areEqual); if (!areEqual) { SWTBotUtils.screenshot("icon_test_icon_matching_" + expectedElement.getLabel()); } assertTrue(areEqual); disposeImage(expectedImage); } } } public void testProjectExplorerContentType() throws Exception { SWTBotTreeItem[] actualProjectItems = getExpandedProjectTreeNode().getItems(); List<GrailsExplorerElementMatcher> expected = getExpectedProjectExplorerElementsInOrder(); int i = 0; for (SWTBotTreeItem item : actualProjectItems) { item = actualProjectItems[i]; Object actualItem = getTreeItemObject(item); assertNotNull(actualItem); print("Expected type: " + expected.get(i).getActualType() + ". Actual type: " + actualItem.getClass()); assertTrue(expected.get(i).getActualType().isInstance(actualItem)); i++; } } }