blob: dff915a193940434a4e87a5b28e7caaee3873699 [file] [log] [blame]
/**
* 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());
}
}
}