/******************************************************************************* * Copyright (c) 2015 EclipseSource Muenchen GmbH 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: * Stefan Dirix - initial API and implementation *******************************************************************************/ package org.eclipse.emf.compare.diagram.papyrus.tests.saveparameter; import static org.junit.Assert.assertTrue; import com.google.common.base.Charsets; import com.google.common.io.Files; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; import org.eclipse.core.resources.IFile; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.FileLocator; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Platform; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.compare.ide.ui.internal.logical.ComparisonScopeBuilder; import org.eclipse.emf.compare.ide.ui.logical.SynchronizationModel; import org.eclipse.emf.compare.ide.ui.tests.workspace.TestProject; import org.eclipse.emf.compare.ide.utils.StorageTraversal; import org.eclipse.emf.compare.scope.IComparisonScope; import org.eclipse.emf.compare.uml2.ide.tests.util.ProfileTestUtil; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.ecore.resource.ResourceSet; import org.eclipse.emf.ecore.resource.URIConverter; import org.eclipse.emf.ecore.resource.impl.ExtensibleURIConverterImpl; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.osgi.framework.Bundle; /** * This class tests the SaveParameterHook integration in EMF Compare by using the EMF Compare comparison * process to save and compare test models. * * @author Stefan Dirix <sdirix@eclipsesource.com> */ @SuppressWarnings("restriction") public class SaveParameterHookIntegrationTest { /** * The bundle which contains this test. */ private static final String TEST_BUNDLE = "org.eclipse.emf.compare.diagram.papyrus.tests"; /** * The path within this bundle to reach the data for this test. */ private static final String BASE_PATH = "src/org/eclipse/emf/compare/diagram/papyrus/tests/saveparameter/data/"; /** * The name of the temporary project created to test the saving behavior of EMF Compare. */ private static final String TEST_PROJECT_NAME = "SaveParameterTestProject"; /** * The temporary project containing the original and modified files. */ private TestProject project; /** * Tests if EMF Compare introduces binary changes when saving model files after the comparing process. * * @throws Exception * If the files can not be copied or compared. */ @Test public void testSaveParametersIntegrationA1() throws Exception { final String localContainer = "a1/"; final List<String> fileNames = Arrays.asList(new String[] {"model.uml", "model.notation" }); assertNoChangeViaSave(localContainer, fileNames); } /** * Tests if EMF Compare introduces binary changes when saving model files after the comparing process. * * @throws Exception * If the files can not be copied or compared. */ @Test public void testSaveParametersIntegrationA2() throws Exception { final String localContainer = "a2/"; final List<String> fileNames = Arrays .asList(new String[] {"model.di", "model.uml", "model.notation" }); assertNoChangeViaSave(localContainer, fileNames); } /** * Copies the files specified in {@code fileNames} twice into the temporary project. One set of files is * then re-saved after the default comparing process of EMF Compare and binary compared to the original * set of files to determine if EMF Compare introduced any changes. * * @param localContainer * The container containing the files specified in {@code fileNames}. The container is relative * to {@link #BASE_PATH}. * @param fileNames * The files to copy, save and compare which are located in the {@code localContainer}. * @throws Exception * * @throws Exception If the files can not be copied or compared. */ private void assertNoChangeViaSave(final String localContainer, final Collection<String> fileNames) throws Exception { final Bundle bundle = Platform.getBundle(TEST_BUNDLE); final List<IFile> originalFiles = new ArrayList<IFile>(fileNames.size()); final List<IFile> saveFiles = new ArrayList<IFile>(fileNames.size()); final List<String> platformURIStrings = new ArrayList<String>(fileNames.size()); // copy files twice for (String fileName : fileNames) { final String path = BASE_PATH + localContainer + fileName; final URI fileURI = getFileUri(bundle.getEntry(path)); final IFile originalFile = project.createFile("original/" + fileName, getInputStream(fileURI)); final IFile saveFile = project.createFile("save/" + fileName, getInputStream(fileURI)); originalFiles.add(originalFile); saveFiles.add(saveFile); platformURIStrings.add("platform:/resource/" + TEST_PROJECT_NAME + "/save/" + fileName); } // build comparison scope which uses the internal resource sets of EMF Compare final StorageTraversal traversal = ProfileTestUtil .createStorageTraversal(platformURIStrings.toArray(new String[0])); final SynchronizationModel syncModel = new SynchronizationModel(traversal, traversal, null); final IComparisonScope scope = ComparisonScopeBuilder.create(syncModel, new NullProgressMonitor()); // save all resources touched by EMF Compare final ResourceSet resourceSet = (ResourceSet)scope.getLeft(); for (Resource resource : resourceSet.getResources()) { resource.save(null); } // check if all files are still identical for (int i = 0; i < fileNames.size(); i++) { final IFile originalFile = originalFiles.get(i); final IFile saveFile = saveFiles.get(i); assertTrue(compareTextContent(originalFile, saveFile)); } } /** * Compares the textual content of both files. The content is only compared after removing all * "carriage return" characters to allow the test to work properly independent of the given environment. * * @param fileA * One of the files for the comparison. * @param fileB * One of the files for the comparison. * @return {@code true} if both files have the same textual content, {@code false} otherwise. * @throws IOException * When there is an error reading one of the files. */ private boolean compareTextContent(IFile fileA, IFile fileB) throws IOException { final String textFileA = removeCRCharacters(getText(fileA)); final String textFileB = removeCRCharacters(getText(fileB)); return textFileA.equals(textFileB); } /** * Returns a {@link String} with the same content but all "carriage return" characters removed. * * @param text * The {@link String} from which all CR characters shall be removed. * @return The given {@code text} without CR characters. */ private String removeCRCharacters(String text) { return text.replaceAll("\\r", ""); } /** * Reads and returns the content of the given {@link IFile} assuming it is a text file. * * @param iFile * The text file which shall be read. * @return The content of the given {@link IFile}. * @throws IOException * When there is an error reading the file. */ private String getText(IFile iFile) throws IOException { final File file = iFile.getLocation().toFile(); return Files.toString(file, Charsets.UTF_8); } /** * Returns the {@link InputStream} for a given {@link URI}. * * @param uri * The {@link URI} for which the {@link InputStream} is to be determined. * @return The {@link InputStream} for the given {@link URI}. * @throws IOException * If there is a problem obtaining an open input stream. */ private InputStream getInputStream(final URI uri) throws IOException { final URIConverter converter = new ExtensibleURIConverterImpl(); return converter.createInputStream(uri); } /** * Returns the {@link URI} for a given {@link URL}. * * @param fileUrl * The {@link URL} for which the {@link URI} is to be determined. * @return The {@link URI} for the given {@link URL}. * @throws IOException * If an error occurs during the conversion. */ private URI getFileUri(final URL fileUrl) throws IOException { final URL fileLocation = FileLocator.toFileURL(fileUrl); return URI.createFileURI(fileLocation.getPath()); } /** * Initializes the temporary test project. * * @throws CoreException * If an error occurs when (re-)creating the temporary test project. */ @Before public void setupProject() throws CoreException { project = new TestProject(TEST_PROJECT_NAME); } /** * Disposes the temporary test project. * * @throws CoreException * If an error occurs when disposing the temporary test project. * @throws IOException * If an error occurs when disposing the temporary test project. */ @After public void disposeProject() throws CoreException, IOException { project.dispose(); } }