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);
}
}
}