/* * JBoss, Home of Professional Open Source. * * See the LEGAL.txt file distributed with this work for information regarding copyright ownership and licensing. * * See the AUTHORS.txt file distributed with this work for a full listing of individual contributors. */ package org.teiid.designer.vdb; import static org.hamcrest.core.Is.is; import static org.hamcrest.core.IsNot.not; import static org.junit.Assert.assertThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import static org.teiid.designer.vdb.Vdb.Event.ENTRY_CHECKSUM; import static org.teiid.designer.vdb.Vdb.Event.ENTRY_DESCRIPTION; import static org.teiid.designer.vdb.Vdb.Event.ENTRY_SYNCHRONIZATION; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.File; import java.io.FileInputStream; import java.util.List; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.Path; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.mockito.ArgumentCaptor; import org.teiid.core.designer.EclipseMock; import org.teiid.designer.core.ModelResourceMockFactory; import org.teiid.designer.core.workspace.MockFileBuilder; import org.teiid.designer.vdb.VdbEntry.Synchronization; import org.teiid.designer.vdb.VdbFileEntry.FileEntryType; /** * */ @SuppressWarnings( "javadoc" ) public class VdbFileEntryTest { private EclipseMock eclipseMock; private VdbEntry entry; private Vdb vdb; private VdbTest vdbTest; @Before public void before() throws Exception { vdbTest = new VdbTest(); vdbTest.before(); eclipseMock = vdbTest.getEclipseMock(); vdb = vdbTest.getVdb(); MockFileBuilder fileBuilder = new MockFileBuilder("Test", "txt"); entry = vdb.addEntry(fileBuilder.getPath()); } @After public void afterEach() throws Exception { vdbTest.after(); } private IPath mockPath(String pathName, String pathNameNoExt) { final IPath pathNoExt = mock(Path.class); when(pathNoExt.lastSegment()).thenReturn(pathNameNoExt); final IPath path = mock(Path.class); when(path.lastSegment()).thenReturn(pathName); when(path.removeFileExtension()).thenReturn(pathNoExt); return path; } @Test public void shouldHaveChecksumIfFileInWorkspace() throws Exception { // mock file and contents so that checksum can be computed File tempFile = ModelResourceMockFactory.createTempFile("temp1", "", null, "abcdef"); FileInputStream fileInputStream = new FileInputStream(tempFile); final IPath path = mockPath("test.xsd", "test"); final IFile iFile = mock(IFile.class); when(iFile.getLocation()).thenReturn(path); when(iFile.getLocation().toFile()).thenReturn(tempFile); when(iFile.getContents()).thenReturn(fileInputStream); // put file in workspace final IWorkspaceRoot mockRoot = eclipseMock.workspaceRoot(); // A file entry changes the path according to the file entry type so ensure // our mock path can be found in the workspace when(mockRoot.findMember(path)).thenReturn(iFile); // construct entry so that checksum will be computed VdbFileEntry entry = vdb.addEntry(path); assertThat(entry.getChecksum(), not(is(0L))); fileInputStream.close(); } @Test public void shouldHaveDifferentChecksumIfFileChanges() throws Exception { // mock file and contents so that checksum can be computed File tempFile1 = ModelResourceMockFactory.createTempFile("temp1", "", null, "abcdefxyz"); File tempFile2 = ModelResourceMockFactory.createTempFile("temp2", "", null, "xyz"); FileInputStream fis1 = new FileInputStream(tempFile1); FileInputStream fis2 = new FileInputStream(tempFile2); final IPath path = mockPath("test.xsd", "test"); final IFile iFile = mock(IFile.class); when(iFile.getLocation()).thenReturn(path); when(iFile.getLocation().toFile()).thenReturn(tempFile1, tempFile2); // include values for first call and second call when(iFile.getContents()).thenReturn(fis1, fis2); // put file in workspace final IWorkspaceRoot mockRoot = eclipseMock.workspaceRoot(); // construct entry so that checksum will be computed VdbFileEntry entry = vdb.addEntry(path); // A file entry changes the path according to the file entry type so ensure // our mock path can be found in the workspace when(mockRoot.findMember(path)).thenReturn(iFile); final long originalChecksum = entry.getChecksum(); // will use first value of iFile.getContents() entry.setSynchronization(Synchronization.NotSynchronized); // so that checksum will be recalculated entry.synchronize(); // will use second value of iFile.getContents() // test assertThat(entry.getChecksum(), not(is(originalChecksum))); fis1.close(); fis2.close(); } @Test public void shouldIndicateSynchronizationNotApplicableIfNotInWorkspace() throws Exception { assertThat(entry.getSynchronization(), is(Synchronization.NotApplicable)); } @Test public void shouldNotChangeSynchronizationStateWhenDescriptionIsChanged() { final Synchronization currentState = entry.getSynchronization(); assertThat(entry.getSynchronization(), is(Synchronization.NotApplicable)); // check initial state // change description entry.setDescription("new description"); // test assertThat(entry.getSynchronization(), is(currentState)); } @Test public void shouldNotHaveChecksumIfFileNotInWorkspace() { assertThat(entry.getChecksum(), is(0L)); } @Test public void shouldNotifyAfterChangingEntryDescription() throws Exception { // set an initial description final String oldDescription = "old description"; entry.setDescription(oldDescription); // hookup listener final PropertyChangeListener listener = mock(PropertyChangeListener.class); vdb.addChangeListener(listener); // change description final String newDescription = "new description"; entry.setDescription(newDescription); // tests final ArgumentCaptor<PropertyChangeEvent> arg = ArgumentCaptor.forClass(PropertyChangeEvent.class); verify(listener).propertyChange(arg.capture()); assertThat(arg.getValue().getPropertyName(), is(ENTRY_DESCRIPTION)); assertThat((String)arg.getValue().getOldValue(), is(oldDescription)); assertThat((String)arg.getValue().getNewValue(), is(newDescription)); } @Test public void shouldNotifyAfterChecksumChanges() throws Exception { // change checksum by changing file contents and synchronizing File tempFile1 = ModelResourceMockFactory.createTempFile("temp1", "", null, "abcdef"); File tempFile2 = ModelResourceMockFactory.createTempFile("temp2", "", null, "xyz"); FileInputStream fis1 = new FileInputStream(tempFile1); FileInputStream fis2 = new FileInputStream(tempFile2); final IPath path = mockPath("test.xsd", "test"); final IFile iFile = mock(IFile.class); when(iFile.getLocation()).thenReturn(path); when(iFile.getLocation().toFile()).thenReturn(tempFile1, tempFile2); // include values for first call and second call when(iFile.getContents()).thenReturn(fis1, fis2); // put file in workspace final IWorkspaceRoot mockRoot = eclipseMock.workspaceRoot(); // construct entry so that checksum will be computed VdbFileEntry entry = vdb.addEntry(path); // will have an original checksum based on first value of iFile.getContents() // A file entry changes the path according to the file entry type so ensure // our mock path can be found in the workspace when(mockRoot.findMember(path)).thenReturn(iFile); entry.setSynchronization(Synchronization.NotSynchronized); // so that checksum will be recalculated // add listener final PropertyChangeListener listener = mock(PropertyChangeListener.class); vdb.addChangeListener(listener); // this will cause event to fire entry.synchronize(); // will use second value of iFile.getContents() to compute checksum // tests final ArgumentCaptor<PropertyChangeEvent> arg = ArgumentCaptor.forClass(PropertyChangeEvent.class); verify(listener, times(2)).propertyChange(arg.capture()); // expect 2 events final List<PropertyChangeEvent> values = arg.getAllValues(); assertThat(values.get(0).getPropertyName(), is(ENTRY_CHECKSUM)); assertThat(values.get(1).getPropertyName(), is(ENTRY_SYNCHRONIZATION)); fis1.close(); fis2.close(); } @Test public void shouldNotifyAfterSynchronizationChanges() throws Exception { final PropertyChangeListener listener = mock(PropertyChangeListener.class); vdb.addChangeListener(listener); // change synchronization entry.setSynchronization(Synchronization.Synchronized); // tests final ArgumentCaptor<PropertyChangeEvent> arg = ArgumentCaptor.forClass(PropertyChangeEvent.class); verify(listener).propertyChange(arg.capture()); assertThat(arg.getValue().getPropertyName(), is(ENTRY_SYNCHRONIZATION)); } @Test public void shouldSetDescriptionToNonNullValue() { final String description = "new description"; entry.setDescription(description); // test assertThat(entry.getDescription(), is(description)); } @Test public void shouldSetDescriptionToNullWithEmptyString() { final String description = ""; entry.setDescription(description); // test assertThat(entry.getDescription(), is(description)); } @Test public void shouldVerifyEqualityWhenSamePath() throws Exception { final IPath path = new Path("/my/path/filename"); final VdbFileEntry thisEntry = new VdbFileEntry(vdb, path, FileEntryType.UserFile); final VdbFileEntry thatEntry = new VdbFileEntry(vdb, path, FileEntryType.UserFile); assertThat(thisEntry.equals(thatEntry), is(true)); assertThat(thisEntry.hashCode(), is(thatEntry.hashCode())); } }