/** * Copyright (c) 2012, 2013 Obeo. * 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: * Obeo - initial API and implementation */ package org.eclipse.emf.compare.tests; import static org.junit.Assert.assertSame; import com.google.common.collect.Iterables; import com.google.common.collect.Sets; import java.util.Iterator; import java.util.List; import java.util.Set; import org.eclipse.emf.common.util.BasicMonitor; import org.eclipse.emf.compare.Comparison; import org.eclipse.emf.compare.Diff; import org.eclipse.emf.compare.DifferenceState; import org.eclipse.emf.compare.EMFCompare; import org.eclipse.emf.compare.ReferenceChange; import org.eclipse.emf.compare.match.eobject.URIDistance; import org.eclipse.emf.compare.merge.BatchMerger; import org.eclipse.emf.compare.merge.IBatchMerger; import org.eclipse.emf.compare.merge.IMerger; import org.eclipse.emf.compare.scope.DefaultComparisonScope; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EReference; import org.eclipse.emf.ecore.EcorePackage; import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.emf.emfstore.fuzzy.Annotations.Data; import org.eclipse.emf.emfstore.fuzzy.Annotations.DataProvider; import org.eclipse.emf.emfstore.fuzzy.Annotations.Util; import org.eclipse.emf.emfstore.fuzzy.FuzzyRunner; import org.eclipse.emf.emfstore.fuzzy.emf.EMFDataProvider; import org.eclipse.emf.emfstore.fuzzy.emf.MutateUtil; import org.eclipse.emf.emfstore.modelmutator.api.ModelMutatorConfiguration; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; /** * A brute force test using fuzzy testing. * * @author <a href="mailto:cedric.brun@obeo.fr">Cedric Brun</a> */ @RunWith(FuzzyRunner.class) @DataProvider(EMFDataProvider.class) @SuppressWarnings("nls") public class FuzzyTest { @Data private EObject root; @Util private MutateUtil util; private IMerger.Registry mergerRegistry = IMerger.RegistryImpl.createStandaloneInstance(); /** * Test to check if the {@link FuzzyRunner} is working. */ @Test public void detectingNoDifferenceOnACopy() { Assert.assertNotNull(root); EObject backup = EcoreUtil.copy(root); Comparison result = EMFCompare.builder().build() .compare(new DefaultComparisonScope(root, backup, null)); Assert.assertEquals(0, result.getDifferences().size()); } /** * Test to check if the {@link FuzzyRunner} is working. */ @Test public void copyAllRightToLeft() { Assert.assertNotNull(root); removeAllDuplicateCrossReferencesFrom(root); EObject backup = EcoreUtil.copy(root); util.mutate(createConfig()); EObject mutated = EcoreUtil.copy(root); removeAllDuplicateCrossReferencesFrom(root); Comparison result = EMFCompare.builder().build() .compare(new DefaultComparisonScope(root, backup, null)); int nbDiffs = result.getDifferences().size(); final IBatchMerger merger = new BatchMerger(mergerRegistry); merger.copyAllRightToLeft(result.getDifferences(), new BasicMonitor()); for (Diff delta : result.getDifferences()) { assertSame(delta.getState(), DifferenceState.MERGED); } Comparison valid = EMFCompare.builder().build() .compare(new DefaultComparisonScope(root, backup, null)); List<Diff> differences = valid.getDifferences(); Set<String> urisToDebug = Sets.newLinkedHashSet(); for (ReferenceChange diff : Iterables.filter(differences, ReferenceChange.class)) { if (diff.getMatch().getRight() != null) { urisToDebug.add(new URIDistance().apply(diff.getMatch().getRight()).toString()); } } if (urisToDebug.size() > 0) { /* * restart */ root = EcoreUtil.copy(mutated); result = EMFCompare.builder().build().compare(new DefaultComparisonScope(root, backup, null)); for (Diff diff : result.getDifferences()) { if (diff.getMatch().getRight() != null) { String uri = new URIDistance().apply(diff.getMatch().getRight()).toString(); if (urisToDebug.contains(uri)) { final IMerger diffMerger = mergerRegistry.getHighestRankingMerger(diff); diffMerger.copyRightToLeft(diff, new BasicMonitor()); } } } } Assert.assertEquals("We still have differences after merging all of them (had " + nbDiffs + " to merge in the beginning)", 0, differences.size()); } /** * Test to check if the {@link FuzzyRunner} is working. */ @Test public void copyAllLeftToRight() { Assert.assertNotNull(root); removeAllDuplicateCrossReferencesFrom(root); EObject backup = EcoreUtil.copy(root); util.mutate(createConfig()); removeAllDuplicateCrossReferencesFrom(root); Comparison result = EMFCompare.builder().build() .compare(new DefaultComparisonScope(root, backup, null)); int nbDiffs = result.getDifferences().size(); final IBatchMerger merger = new BatchMerger(mergerRegistry); merger.copyAllLeftToRight(result.getDifferences(), new BasicMonitor()); Comparison valid = EMFCompare.builder().build() .compare(new DefaultComparisonScope(root, backup, null)); List<Diff> differences = valid.getDifferences(); Assert.assertEquals("We still have differences after merging all of them (had " + nbDiffs + " to merge in the beginning)", 0, differences.size()); } private ModelMutatorConfiguration createConfig() { ModelMutatorConfiguration conf = new ModelMutatorConfiguration(EcorePackage.eINSTANCE, root, 1L); conf.setMaxDeleteCount(0); return conf; } private static void removeAllDuplicateCrossReferencesFrom(EObject contentRoot) { for (EReference reference : contentRoot.eClass().getEAllReferences()) { if (!reference.isContainment() && !reference.isDerived() && reference.isMany()) { @SuppressWarnings("unchecked") final Iterator<EObject> crossReferences = ((List<EObject>)contentRoot.eGet(reference)) .iterator(); final Set<EObject> noDupes = Sets.newHashSet(); while (crossReferences.hasNext()) { if (!noDupes.add(crossReferences.next())) { crossReferences.remove(); } } } } final Iterator<EObject> contentIterator = contentRoot.eContents().iterator(); while (contentIterator.hasNext()) { removeAllDuplicateCrossReferencesFrom(contentIterator.next()); } } }