package org.springframework.roo.project; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.mockito.Matchers.any; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import java.io.File; import java.io.IOException; import java.net.URL; import java.util.Arrays; import java.util.Collection; import junit.framework.AssertionFailedError; import org.junit.Before; import org.junit.Test; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.osgi.framework.BundleContext; import org.osgi.service.component.ComponentContext; import org.springframework.roo.file.monitor.FileMonitorService; import org.springframework.roo.metadata.MetadataDependencyRegistry; import org.springframework.roo.metadata.MetadataService; import org.springframework.roo.process.manager.FileManager; import org.springframework.roo.project.maven.Pom; import org.springframework.roo.project.maven.PomFactory; import org.springframework.roo.shell.Shell; import org.springframework.roo.support.osgi.OSGiUtils; import org.springframework.roo.support.util.FileUtils; import org.w3c.dom.Element; /** * Unit test of {@link PomManagementServiceImpl} * * @author Andrew Swan * @since 1.2.0 */ public class PomManagementServiceImplTest { private static final String ROOT_MODULE_NAME = ""; @Mock private FileManager mockFileManager; @Mock private FileMonitorService mockFileMonitorService; @Mock private MetadataDependencyRegistry mockMetadataDependencyRegistry; @Mock private MetadataService mockMetadataService; @Mock private PomFactory mockPomFactory; @Mock private Shell mockShell; // Fixture private PomManagementServiceImpl service; private String getCanonicalPath(final String relativePath) { final String systemDependentPath = relativePath.replace("/", File.separator); final URL resource = getClass().getResource(systemDependentPath); assertNotNull("Can't find '" + systemDependentPath + "' on the classpath of " + getClass().getName(), resource); try { return new File(resource.toURI()).getCanonicalPath(); } catch (final Exception e) { throw new AssertionFailedError(e.getMessage()); } } private Pom getMockPom(final String moduleName, final String canonicalPath) { final Pom mockPom = mock(Pom.class); when(mockPom.getModuleName()).thenReturn(moduleName); when(mockPom.getPath()).thenReturn(canonicalPath); when(mockPomFactory.getInstance(any(Element.class), eq(canonicalPath), eq(moduleName))) .thenReturn(mockPom); return mockPom; } @Before public void setUp() { MockitoAnnotations.initMocks(this); service = new PomManagementServiceImpl(); service.fileManager = mockFileManager; service.fileMonitorService = mockFileMonitorService; service.metadataDependencyRegistry = mockMetadataDependencyRegistry; service.metadataService = mockMetadataService; service.pomFactory = mockPomFactory; service.shell = mockShell; } /** * Sets the working directory for the service under test * * @param relativePath the desired working directory relative to the * "o.s.r.project" package * @throws IOException */ private void setUpWorkingDirectory(final String relativePath) throws IOException { final ComponentContext mockComponentContext = mock(ComponentContext.class); final BundleContext mockBundleContext = mock(BundleContext.class); when(mockComponentContext.getBundleContext()).thenReturn(mockBundleContext); final File workingDirectory = new File("target/test-classes/org/springframework/roo/project", relativePath); when(mockBundleContext.getProperty(OSGiUtils.ROO_WORKING_DIRECTORY_PROPERTY)).thenReturn( workingDirectory.getCanonicalPath()); service.activate(mockComponentContext); } @Test public void testGetPomOfSingleModuleProjectWhenParentHasNoRelativePath() throws Exception { // Set up setUpWorkingDirectory("single"); final String canonicalPath = getCanonicalPath("single/pom.xml"); when(mockFileMonitorService.getDirtyFiles(PomManagementServiceImpl.class.getName())) .thenReturn(Arrays.asList(canonicalPath)); final Pom mockPom = getMockPom(ROOT_MODULE_NAME, canonicalPath); // Invoke final Collection<Pom> poms = service.getPoms(); // Check assertEquals(1, poms.size()); assertEquals(mockPom, poms.iterator().next()); verifyProjectMetadataNotification(ROOT_MODULE_NAME); } @Test public void testGetPomsOfMultiModuleProjectWhenChildIsDirty() throws Exception { // Set up setUpWorkingDirectory("multi"); final String rootPom = FileUtils.getSystemDependentPath("multi", "pom.xml"); final String rootPomCanonicalPath = getCanonicalPath(rootPom); final String childPom = FileUtils.getSystemDependentPath("multi", "foo-child", "pom.xml"); final String childPomCanonicalPath = getCanonicalPath(childPom); final Collection<String> dirtyFiles = Arrays.asList(childPomCanonicalPath); when(mockFileMonitorService.getDirtyFiles(PomManagementServiceImpl.class.getName())) .thenReturn(dirtyFiles); final Pom mockRootPom = getMockPom(ROOT_MODULE_NAME, rootPomCanonicalPath); final String childModuleName = "foo-child"; final Pom mockChildPom = getMockPom(childModuleName, childPomCanonicalPath); when(mockFileManager.getInputStream(rootPomCanonicalPath)).thenReturn( getClass().getResourceAsStream(rootPom)); when(mockFileManager.getInputStream(childPomCanonicalPath)).thenReturn( getClass().getResourceAsStream(childPom)); service.addPom(mockRootPom); // Invoke final Collection<Pom> poms = service.getPoms(); // Check final Collection<Pom> expectedPoms = Arrays.asList(mockRootPom, mockChildPom); assertEquals(expectedPoms.size(), poms.size()); assertTrue(poms.containsAll(expectedPoms)); verifyProjectMetadataNotification(childModuleName); } @Test public void testGetPomsOfMultiModuleProjectWhenParentAndChildAreDirty() throws Exception { // Set up setUpWorkingDirectory("multi"); final String rootPom = "multi/pom.xml"; final String rootPomCanonicalPath = getCanonicalPath(rootPom); final String childPom = "multi/foo-child/pom.xml"; final String childPomCanonicalPath = getCanonicalPath(childPom); final Collection<String> dirtyFiles = Arrays.asList(rootPomCanonicalPath, childPomCanonicalPath); when(mockFileMonitorService.getDirtyFiles(PomManagementServiceImpl.class.getName())) .thenReturn(dirtyFiles); final Pom mockRootPom = getMockPom(ROOT_MODULE_NAME, rootPomCanonicalPath); final String childModuleName = "foo-child"; final Pom mockChildPom = getMockPom(childModuleName, childPomCanonicalPath); when(mockFileManager.getInputStream(rootPomCanonicalPath)).thenReturn( getClass().getResourceAsStream(rootPom)); when(mockFileManager.getInputStream(childPomCanonicalPath)).thenReturn( getClass().getResourceAsStream(childPom)); // Invoke final Collection<Pom> poms = service.getPoms(); // Check final Collection<Pom> expectedPoms = Arrays.asList(mockRootPom, mockChildPom); assertEquals(expectedPoms.size(), poms.size()); assertTrue(poms.containsAll(expectedPoms)); verifyProjectMetadataNotification(ROOT_MODULE_NAME, childModuleName); } @Test public void testGetPomsWhenNoPomsAreDirty() { // Set up final Collection<String> dirtyFiles = Arrays.asList("not-a-pom.txt"); when(mockFileMonitorService.getDirtyFiles(PomManagementServiceImpl.class.getName())) .thenReturn(dirtyFiles); // Invoke final Collection<Pom> poms = service.getPoms(); // Check assertEquals(0, poms.size()); } @Test public void testGetPomsWhenOneEmptyPomIsDirty() throws Exception { // Set up final Collection<String> dirtyFiles = Arrays.asList(getCanonicalPath("empty/pom.xml")); when(mockFileMonitorService.getDirtyFiles(PomManagementServiceImpl.class.getName())) .thenReturn(dirtyFiles); // Invoke final Collection<Pom> poms = service.getPoms(); // Check assertEquals(0, poms.size()); } @Test public void testGetPomsWhenOneNonExistantPomIsDirty() { // Set up final Collection<String> dirtyFiles = Arrays.asList("/users/jbloggs/clinic/pom.xml"); when(mockFileMonitorService.getDirtyFiles(PomManagementServiceImpl.class.getName())) .thenReturn(dirtyFiles); // Invoke final Collection<Pom> poms = service.getPoms(); // Check assertEquals(0, poms.size()); } private void verifyProjectMetadataNotification(final String... moduleNames) { for (final String moduleName : moduleNames) { final String projectMetadataId = ProjectMetadata.getProjectIdentifier(moduleName); verify(mockMetadataService).evictAndGet(projectMetadataId); verify(mockMetadataDependencyRegistry).notifyDownstream(projectMetadataId); } } }