[470268] Add test classes for RenameDetector and SimilarityComputer

Bug: 470268
Change-Id: I7b4cbbe4fb154cfd357fb6ec4725d3972f7da907
Signed-off-by: Michael Borkowski <mborkowski@eclipsesource.com>
diff --git a/plugins/org.eclipse.emf.compare.ide.ui.tests/src/org/eclipse/emf/compare/ide/ui/tests/logical/resolver/RenameDetectorTest.java b/plugins/org.eclipse.emf.compare.ide.ui.tests/src/org/eclipse/emf/compare/ide/ui/tests/logical/resolver/RenameDetectorTest.java
new file mode 100644
index 0000000..a9247a0
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.ide.ui.tests/src/org/eclipse/emf/compare/ide/ui/tests/logical/resolver/RenameDetectorTest.java
@@ -0,0 +1,374 @@
+/*******************************************************************************
+ * Copyright (c) 2015 EclipseSource GmbH.
+ * 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:
+ *     Michael Borkowski - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.emf.compare.ide.ui.tests.logical.resolver;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IStorage;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.emf.compare.ide.ui.internal.logical.RenameDetector;
+import org.eclipse.emf.compare.ide.ui.logical.IStorageProvider;
+import org.eclipse.emf.compare.ide.ui.logical.IStorageProviderAccessor;
+import org.eclipse.emf.compare.ide.ui.logical.IStorageProviderAccessor.DiffSide;
+import org.eclipse.team.core.diff.IDiff;
+import org.eclipse.team.core.diff.ITwoWayDiff;
+import org.eclipse.team.core.diff.provider.ThreeWayDiff;
+import org.eclipse.team.core.subscribers.Subscriber;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+
+@SuppressWarnings({"nls", "boxing" })
+public class RenameDetectorTest {
+
+	RenameDetector sut;
+
+	Subscriber subscriber;
+
+	IStorageProviderAccessor accessor;
+
+	IProject root;
+
+	Map<IFile, String> contentsOrigin = new HashMap<IFile, String>();
+
+	Map<IFile, String> contentsSource = new HashMap<IFile, String>();
+
+	Map<IFile, String> contentsRemote = new HashMap<IFile, String>();
+
+	@Before
+	public void setUp() {
+		subscriber = mock(Subscriber.class);
+		accessor = mock(IStorageProviderAccessor.class);
+		sut = new RenameDetector(subscriber, accessor);
+
+		root = mock(IProject.class);
+		when(subscriber.roots()).thenReturn(new IResource[] {root });
+	}
+
+	@Test
+	public void testNoChange() throws CoreException, UnsupportedEncodingException {
+		IFile fileA = mock(IFile.class);
+		IFile fileB = mock(IFile.class);
+
+		contentsOrigin.put(fileA, SimilarityComputerTest.PREFIX + "contents\nbla\n");
+		contentsSource.put(fileA, SimilarityComputerTest.PREFIX + "contents\nbla\n");
+		contentsRemote.put(fileA, SimilarityComputerTest.PREFIX + "contents\nbla\n");
+
+		contentsOrigin.put(fileB, SimilarityComputerTest.PREFIX2 + "contents2\nbla\n");
+		contentsSource.put(fileB, SimilarityComputerTest.PREFIX2 + "contents2\nbla\n");
+		contentsRemote.put(fileB, SimilarityComputerTest.PREFIX2 + "contents2\nbla\n");
+
+		processContents();
+
+		assertFalse(sut.getFileAfterRename(fileA, DiffSide.SOURCE).isPresent());
+		assertFalse(sut.getFileAfterRename(fileA, DiffSide.REMOTE).isPresent());
+		assertFalse(sut.getFileBeforeRename(fileA, DiffSide.SOURCE).isPresent());
+		assertFalse(sut.getFileBeforeRename(fileA, DiffSide.REMOTE).isPresent());
+
+		assertFalse(sut.getFileAfterRename(fileB, DiffSide.SOURCE).isPresent());
+		assertFalse(sut.getFileAfterRename(fileB, DiffSide.REMOTE).isPresent());
+		assertFalse(sut.getFileBeforeRename(fileB, DiffSide.SOURCE).isPresent());
+		assertFalse(sut.getFileBeforeRename(fileB, DiffSide.REMOTE).isPresent());
+	}
+
+	@Test
+	public void testRenameSourceNoChange() throws CoreException, UnsupportedEncodingException {
+		IFile fileA = mock(IFile.class);
+		IFile fileB = mock(IFile.class);
+		IFile fileB2 = mock(IFile.class);
+
+		contentsOrigin.put(fileA, SimilarityComputerTest.PREFIX + "contents\nbla\n");
+		contentsSource.put(fileA, SimilarityComputerTest.PREFIX + "contents\nbla\n");
+		contentsRemote.put(fileA, SimilarityComputerTest.PREFIX + "contents\nbla\n");
+
+		contentsOrigin.put(fileB, SimilarityComputerTest.PREFIX2 + "contents2\nbla\n");
+		contentsSource.put(fileB2, SimilarityComputerTest.PREFIX2 + "contents2\nbla\n");
+		contentsRemote.put(fileB, SimilarityComputerTest.PREFIX2 + "contents2\nbla\n");
+
+		processContents();
+
+		assertFalse(sut.getFileAfterRename(fileA, DiffSide.SOURCE).isPresent());
+		assertFalse(sut.getFileAfterRename(fileA, DiffSide.REMOTE).isPresent());
+		assertFalse(sut.getFileBeforeRename(fileA, DiffSide.SOURCE).isPresent());
+		assertFalse(sut.getFileBeforeRename(fileA, DiffSide.REMOTE).isPresent());
+
+		assertTrue(sut.getFileAfterRename(fileB, DiffSide.SOURCE).isPresent());
+		assertFalse(sut.getFileAfterRename(fileB, DiffSide.REMOTE).isPresent());
+		assertFalse(sut.getFileBeforeRename(fileB, DiffSide.SOURCE).isPresent());
+		assertFalse(sut.getFileBeforeRename(fileB, DiffSide.REMOTE).isPresent());
+
+		assertFalse(sut.getFileAfterRename(fileB2, DiffSide.SOURCE).isPresent());
+		assertFalse(sut.getFileAfterRename(fileB2, DiffSide.REMOTE).isPresent());
+		assertTrue(sut.getFileBeforeRename(fileB2, DiffSide.SOURCE).isPresent());
+		assertFalse(sut.getFileBeforeRename(fileB2, DiffSide.REMOTE).isPresent());
+
+		assertSame(fileB2, sut.getFileAfterRename(fileB, DiffSide.SOURCE).get());
+		assertSame(fileB, sut.getFileBeforeRename(fileB2, DiffSide.SOURCE).get());
+	}
+
+	@Test
+	public void testRenameRemoteNoChange() throws CoreException, UnsupportedEncodingException {
+		IFile fileA = mock(IFile.class);
+		IFile fileB = mock(IFile.class);
+		IFile fileB2 = mock(IFile.class);
+
+		contentsOrigin.put(fileA, SimilarityComputerTest.PREFIX + "contents\nbla\n");
+		contentsSource.put(fileA, SimilarityComputerTest.PREFIX + "contents\nbla\n");
+		contentsRemote.put(fileA, SimilarityComputerTest.PREFIX + "contents\nbla\n");
+
+		contentsOrigin.put(fileB, SimilarityComputerTest.PREFIX2 + "contents2\nbla\n");
+		contentsSource.put(fileB, SimilarityComputerTest.PREFIX2 + "contents2\nbla\n");
+		contentsRemote.put(fileB2, SimilarityComputerTest.PREFIX2 + "contents2\nbla\n");
+
+		processContents();
+
+		assertFalse(sut.getFileAfterRename(fileA, DiffSide.SOURCE).isPresent());
+		assertFalse(sut.getFileAfterRename(fileA, DiffSide.REMOTE).isPresent());
+		assertFalse(sut.getFileBeforeRename(fileA, DiffSide.SOURCE).isPresent());
+		assertFalse(sut.getFileBeforeRename(fileA, DiffSide.REMOTE).isPresent());
+
+		assertFalse(sut.getFileAfterRename(fileB, DiffSide.SOURCE).isPresent());
+		assertTrue(sut.getFileAfterRename(fileB, DiffSide.REMOTE).isPresent());
+		assertFalse(sut.getFileBeforeRename(fileB, DiffSide.SOURCE).isPresent());
+		assertFalse(sut.getFileBeforeRename(fileB, DiffSide.REMOTE).isPresent());
+
+		assertFalse(sut.getFileAfterRename(fileB2, DiffSide.SOURCE).isPresent());
+		assertFalse(sut.getFileAfterRename(fileB2, DiffSide.REMOTE).isPresent());
+		assertFalse(sut.getFileBeforeRename(fileB2, DiffSide.SOURCE).isPresent());
+		assertTrue(sut.getFileBeforeRename(fileB2, DiffSide.REMOTE).isPresent());
+
+		assertSame(fileB2, sut.getFileAfterRename(fileB, DiffSide.REMOTE).get());
+		assertSame(fileB, sut.getFileBeforeRename(fileB2, DiffSide.REMOTE).get());
+	}
+
+	@Test
+	public void testRenameSourceSlightChange() throws CoreException, UnsupportedEncodingException {
+		IFile fileA = mock(IFile.class);
+		IFile fileB = mock(IFile.class);
+		IFile fileB2 = mock(IFile.class);
+
+		contentsOrigin.put(fileA, SimilarityComputerTest.PREFIX + "contents\nbla\n");
+		contentsSource.put(fileA, SimilarityComputerTest.PREFIX + "contents\nbla\n");
+		contentsRemote.put(fileA, SimilarityComputerTest.PREFIX + "contents\nbla\n");
+
+		contentsOrigin.put(fileB, SimilarityComputerTest.PREFIX2 + "contents2\nbla\n");
+		contentsSource.put(fileB2, SimilarityComputerTest.PREFIX2 + "contents2, slight change\nbla\n");
+		contentsRemote.put(fileB, SimilarityComputerTest.PREFIX2 + "contents2\nbla\n");
+
+		processContents();
+
+		assertFalse(sut.getFileAfterRename(fileA, DiffSide.SOURCE).isPresent());
+		assertFalse(sut.getFileAfterRename(fileA, DiffSide.REMOTE).isPresent());
+		assertFalse(sut.getFileBeforeRename(fileA, DiffSide.SOURCE).isPresent());
+		assertFalse(sut.getFileBeforeRename(fileA, DiffSide.REMOTE).isPresent());
+
+		assertTrue(sut.getFileAfterRename(fileB, DiffSide.SOURCE).isPresent());
+		assertFalse(sut.getFileAfterRename(fileB, DiffSide.REMOTE).isPresent());
+		assertFalse(sut.getFileBeforeRename(fileB, DiffSide.SOURCE).isPresent());
+		assertFalse(sut.getFileBeforeRename(fileB, DiffSide.REMOTE).isPresent());
+
+		assertFalse(sut.getFileAfterRename(fileB2, DiffSide.SOURCE).isPresent());
+		assertFalse(sut.getFileAfterRename(fileB2, DiffSide.REMOTE).isPresent());
+		assertTrue(sut.getFileBeforeRename(fileB2, DiffSide.SOURCE).isPresent());
+		assertFalse(sut.getFileBeforeRename(fileB2, DiffSide.REMOTE).isPresent());
+
+		assertSame(fileB2, sut.getFileAfterRename(fileB, DiffSide.SOURCE).get());
+		assertSame(fileB, sut.getFileBeforeRename(fileB2, DiffSide.SOURCE).get());
+	}
+
+	@Test
+	public void testRenameRemoteSlightChange() throws CoreException, UnsupportedEncodingException {
+		IFile fileA = mock(IFile.class);
+		IFile fileB = mock(IFile.class);
+		IFile fileB2 = mock(IFile.class);
+
+		contentsOrigin.put(fileA, SimilarityComputerTest.PREFIX + "contents\nbla\n");
+		contentsSource.put(fileA, SimilarityComputerTest.PREFIX + "contents\nbla\n");
+		contentsRemote.put(fileA, SimilarityComputerTest.PREFIX + "contents\nbla\n");
+
+		contentsOrigin.put(fileB, SimilarityComputerTest.PREFIX2 + "contents2\nbla\n");
+		contentsSource.put(fileB, SimilarityComputerTest.PREFIX2 + "contents2\nbla\n");
+		contentsRemote.put(fileB2, SimilarityComputerTest.PREFIX2 + "contents2, slight change\nbla\n");
+
+		processContents();
+
+		assertFalse(sut.getFileAfterRename(fileA, DiffSide.SOURCE).isPresent());
+		assertFalse(sut.getFileAfterRename(fileA, DiffSide.REMOTE).isPresent());
+		assertFalse(sut.getFileBeforeRename(fileA, DiffSide.SOURCE).isPresent());
+		assertFalse(sut.getFileBeforeRename(fileA, DiffSide.REMOTE).isPresent());
+
+		assertFalse(sut.getFileAfterRename(fileB, DiffSide.SOURCE).isPresent());
+		assertTrue(sut.getFileAfterRename(fileB, DiffSide.REMOTE).isPresent());
+		assertFalse(sut.getFileBeforeRename(fileB, DiffSide.SOURCE).isPresent());
+		assertFalse(sut.getFileBeforeRename(fileB, DiffSide.REMOTE).isPresent());
+
+		assertFalse(sut.getFileAfterRename(fileB2, DiffSide.SOURCE).isPresent());
+		assertFalse(sut.getFileAfterRename(fileB2, DiffSide.REMOTE).isPresent());
+		assertFalse(sut.getFileBeforeRename(fileB2, DiffSide.SOURCE).isPresent());
+		assertTrue(sut.getFileBeforeRename(fileB2, DiffSide.REMOTE).isPresent());
+
+		assertSame(fileB2, sut.getFileAfterRename(fileB, DiffSide.REMOTE).get());
+		assertSame(fileB, sut.getFileBeforeRename(fileB2, DiffSide.REMOTE).get());
+	}
+
+	@Test
+	public void testRenameSourceBigChange() throws CoreException, UnsupportedEncodingException {
+		IFile fileA = mock(IFile.class);
+		IFile fileB = mock(IFile.class);
+		IFile fileB2 = mock(IFile.class);
+
+		contentsOrigin.put(fileA, SimilarityComputerTest.PREFIX + "contents\nbla\n");
+		contentsSource.put(fileA, SimilarityComputerTest.PREFIX + "contents\nbla\n");
+		contentsRemote.put(fileA, SimilarityComputerTest.PREFIX + "contents\nbla\n");
+
+		contentsOrigin.put(fileB, SimilarityComputerTest.PREFIX2 + "contents2\nbla\n");
+		contentsSource.put(fileB2, SimilarityComputerTest.PREFIX + "contents2, slight change\nbla\n");
+		contentsRemote.put(fileB, SimilarityComputerTest.PREFIX2 + "contents2\nbla\n");
+
+		processContents();
+
+		assertFalse(sut.getFileAfterRename(fileA, DiffSide.SOURCE).isPresent());
+		assertFalse(sut.getFileAfterRename(fileA, DiffSide.REMOTE).isPresent());
+		assertFalse(sut.getFileBeforeRename(fileA, DiffSide.SOURCE).isPresent());
+		assertFalse(sut.getFileBeforeRename(fileA, DiffSide.REMOTE).isPresent());
+
+		assertFalse(sut.getFileAfterRename(fileB, DiffSide.SOURCE).isPresent());
+		assertFalse(sut.getFileAfterRename(fileB, DiffSide.REMOTE).isPresent());
+		assertFalse(sut.getFileBeforeRename(fileB, DiffSide.SOURCE).isPresent());
+		assertFalse(sut.getFileBeforeRename(fileB, DiffSide.REMOTE).isPresent());
+
+		assertFalse(sut.getFileAfterRename(fileB2, DiffSide.SOURCE).isPresent());
+		assertFalse(sut.getFileAfterRename(fileB2, DiffSide.REMOTE).isPresent());
+		assertFalse(sut.getFileBeforeRename(fileB2, DiffSide.SOURCE).isPresent());
+		assertFalse(sut.getFileBeforeRename(fileB2, DiffSide.REMOTE).isPresent());
+	}
+
+	@Test
+	public void testRenameRemoteBigChange() throws CoreException, UnsupportedEncodingException {
+		IFile fileA = mock(IFile.class);
+		IFile fileB = mock(IFile.class);
+		IFile fileB2 = mock(IFile.class);
+
+		contentsOrigin.put(fileA, SimilarityComputerTest.PREFIX + "contents\nbla\n");
+		contentsSource.put(fileA, SimilarityComputerTest.PREFIX + "contents\nbla\n");
+		contentsRemote.put(fileA, SimilarityComputerTest.PREFIX + "contents\nbla\n");
+
+		contentsOrigin.put(fileB, SimilarityComputerTest.PREFIX2 + "contents2\nbla\n");
+		contentsSource.put(fileB, SimilarityComputerTest.PREFIX2 + "contents2\nbla\n");
+		contentsRemote.put(fileB2, SimilarityComputerTest.PREFIX + "contents2, slight change\nbla\n");
+
+		processContents();
+
+		assertFalse(sut.getFileAfterRename(fileA, DiffSide.SOURCE).isPresent());
+		assertFalse(sut.getFileAfterRename(fileA, DiffSide.REMOTE).isPresent());
+		assertFalse(sut.getFileBeforeRename(fileA, DiffSide.SOURCE).isPresent());
+		assertFalse(sut.getFileBeforeRename(fileA, DiffSide.REMOTE).isPresent());
+
+		assertFalse(sut.getFileAfterRename(fileB, DiffSide.SOURCE).isPresent());
+		assertFalse(sut.getFileAfterRename(fileB, DiffSide.REMOTE).isPresent());
+		assertFalse(sut.getFileBeforeRename(fileB, DiffSide.SOURCE).isPresent());
+		assertFalse(sut.getFileBeforeRename(fileB, DiffSide.REMOTE).isPresent());
+
+		assertFalse(sut.getFileAfterRename(fileB2, DiffSide.SOURCE).isPresent());
+		assertFalse(sut.getFileAfterRename(fileB2, DiffSide.REMOTE).isPresent());
+		assertFalse(sut.getFileBeforeRename(fileB2, DiffSide.SOURCE).isPresent());
+		assertFalse(sut.getFileBeforeRename(fileB2, DiffSide.REMOTE).isPresent());
+	}
+
+	private void processContents() throws CoreException, UnsupportedEncodingException {
+		Set<IFile> files = new HashSet<IFile>();
+		files.addAll(contentsOrigin.keySet());
+		files.addAll(contentsSource.keySet());
+		files.addAll(contentsRemote.keySet());
+
+		for (IFile file : files) {
+			String originContent = contentsOrigin.get(file);
+			String remoteContent = contentsRemote.get(file);
+			String sourceContent = contentsSource.get(file);
+
+			int remoteDiffKind = diffKind(originContent, remoteContent);
+			int sourceDiffKind = diffKind(originContent, sourceContent);
+
+			ThreeWayDiff threeWayDiff = mock(ThreeWayDiff.class);
+
+			ITwoWayDiff remoteDiff = mock(ITwoWayDiff.class);
+			ITwoWayDiff sourceDiff = mock(ITwoWayDiff.class);
+
+			when(remoteDiff.getKind()).thenReturn(remoteDiffKind);
+			when(sourceDiff.getKind()).thenReturn(sourceDiffKind);
+			when(threeWayDiff.getLocalChange()).thenReturn(sourceDiff);
+			when(threeWayDiff.getRemoteChange()).thenReturn(remoteDiff);
+
+			when(subscriber.getDiff(file)).thenReturn(threeWayDiff);
+
+			IStorageProvider originProvider = mock(IStorageProvider.class);
+			IStorageProvider remoteProvider = mock(IStorageProvider.class);
+			IStorageProvider sourceProvider = mock(IStorageProvider.class);
+
+			IStorage originStorage = mock(IStorage.class);
+			IStorage remoteStorage = mock(IStorage.class);
+			IStorage sourceStorage = mock(IStorage.class);
+
+			when(originProvider.getStorage(any(IProgressMonitor.class))).thenReturn(originStorage);
+			when(remoteProvider.getStorage(any(IProgressMonitor.class))).thenReturn(remoteStorage);
+			when(sourceProvider.getStorage(any(IProgressMonitor.class))).thenReturn(sourceStorage);
+
+			when(originStorage.getContents()).then(openInputStream(originContent));
+			when(remoteStorage.getContents()).then(openInputStream(remoteContent));
+			when(sourceStorage.getContents()).then(openInputStream(sourceContent));
+
+			when(accessor.getStorageProvider(file, DiffSide.ORIGIN)).thenReturn(originProvider);
+			when(accessor.getStorageProvider(file, DiffSide.REMOTE)).thenReturn(remoteProvider);
+			when(accessor.getStorageProvider(file, DiffSide.SOURCE)).thenReturn(sourceProvider);
+
+		}
+		when(subscriber.members(root)).thenReturn(files.toArray(new IFile[0]));
+	}
+
+	private Answer<?> openInputStream(String content) throws UnsupportedEncodingException {
+		final byte[] bytes = content == null ? null : content.getBytes("UTF-8");
+		return new Answer<InputStream>() {
+			public InputStream answer(InvocationOnMock invocation) throws Throwable {
+				return bytes == null ? null : new ByteArrayInputStream(bytes);
+			}
+		};
+	}
+
+	private int diffKind(String originContent, String branchContent) {
+		if (originContent == null && branchContent == null) {
+			return IDiff.NO_CHANGE;
+		} else if (originContent == null) {
+			return IDiff.ADD;
+		} else if (branchContent == null) {
+			return IDiff.REMOVE;
+		} else {
+			return IDiff.CHANGE;
+		}
+	}
+}
diff --git a/plugins/org.eclipse.emf.compare.ide.ui.tests/src/org/eclipse/emf/compare/ide/ui/tests/logical/resolver/SimilarityComputerTest.java b/plugins/org.eclipse.emf.compare.ide.ui.tests/src/org/eclipse/emf/compare/ide/ui/tests/logical/resolver/SimilarityComputerTest.java
new file mode 100644
index 0000000..5c52edb
--- /dev/null
+++ b/plugins/org.eclipse.emf.compare.ide.ui.tests/src/org/eclipse/emf/compare/ide/ui/tests/logical/resolver/SimilarityComputerTest.java
@@ -0,0 +1,98 @@
+package org.eclipse.emf.compare.ide.ui.tests.logical.resolver;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.eclipse.emf.compare.ide.ui.internal.logical.SimilarityComputer;
+import org.junit.Test;
+
+public class SimilarityComputerTest {
+
+	private static final String LIPSUM1 = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. In imperdiet risus eu hendrerit facilisis. Nullam at blandit elit."; //$NON-NLS-1$
+
+	private static final String LIPSUM2 = "Aenean fermentum turpis sit amet auctor pretium. Maecenas dignissim nisi mi, eu fermentum eros lobortis et. Quisque rutrum neque nec."; //$NON-NLS-1$
+
+	public static final String PREFIX;
+
+	public static final String PREFIX2;
+
+	static {
+		StringBuilder prefixBuilder = new StringBuilder();
+		while (prefixBuilder.length() < SimilarityComputer.MINIMUM_LENGTH) {
+			prefixBuilder.append(LIPSUM1);
+			prefixBuilder.append('\n');
+		}
+		PREFIX = prefixBuilder.toString();
+
+		prefixBuilder = new StringBuilder();
+		while (prefixBuilder.length() < SimilarityComputer.MINIMUM_LENGTH) {
+			prefixBuilder.append(LIPSUM2);
+			prefixBuilder.append('\n');
+		}
+		PREFIX2 = prefixBuilder.toString();
+	}
+
+	@Test
+	public void testIdentical() throws IOException {
+		String a = PREFIX;
+		String b = PREFIX;
+
+		assertTrue(SimilarityComputer.isSimilar(stream(a), stream(b)));
+	}
+
+	@Test
+	public void testMinorAddition() throws IOException {
+		String a = PREFIX;
+		String b = PREFIX + "another line\n"; //$NON-NLS-1$
+
+		assertTrue(SimilarityComputer.isSimilar(stream(a), stream(b)));
+	}
+
+	@Test
+	public void testMinorDeletion() throws IOException {
+		String a = PREFIX + "old line\n"; //$NON-NLS-1$
+		String b = PREFIX;
+
+		assertTrue(SimilarityComputer.isSimilar(stream(a), stream(b)));
+	}
+
+	@Test
+	public void testMinorChange() throws IOException {
+		String a = PREFIX + "old line\n"; //$NON-NLS-1$
+		String b = PREFIX + "new line\n"; //$NON-NLS-1$
+
+		assertTrue(SimilarityComputer.isSimilar(stream(a), stream(b)));
+	}
+
+	@Test
+	public void testMajorChange() throws IOException {
+		String a = PREFIX + "old line\n"; //$NON-NLS-1$
+		String b;
+
+		StringBuilder bBuilder = new StringBuilder();
+		while (bBuilder.length() < a.length()) {
+			bBuilder.append(LIPSUM2);
+			bBuilder.append('\n');
+		}
+		b = bBuilder.toString();
+
+		assertFalse(SimilarityComputer.isSimilar(stream(a), stream(b)));
+	}
+
+	@Test
+	public void testTooShort() throws IOException {
+		String a = LIPSUM1 + '\n' + LIPSUM2;
+		String b = a;
+
+		assertFalse(SimilarityComputer.isSimilar(stream(a), stream(b)));
+	}
+
+	private InputStream stream(String string) throws IOException {
+		return new ByteArrayInputStream(string.getBytes("UTF-8")); //$NON-NLS-1$
+	}
+
+}
diff --git a/plugins/org.eclipse.emf.compare.ide.ui.tests/src/org/eclipse/emf/compare/ide/ui/tests/suite/AllTests.java b/plugins/org.eclipse.emf.compare.ide.ui.tests/src/org/eclipse/emf/compare/ide/ui/tests/suite/AllTests.java
index 9bcfdc9..68cb930 100644
--- a/plugins/org.eclipse.emf.compare.ide.ui.tests/src/org/eclipse/emf/compare/ide/ui/tests/suite/AllTests.java
+++ b/plugins/org.eclipse.emf.compare.ide.ui.tests/src/org/eclipse/emf/compare/ide/ui/tests/suite/AllTests.java
@@ -25,9 +25,11 @@
 import org.eclipse.emf.compare.ide.ui.tests.logical.resolver.GraphResolutionTest;
 import org.eclipse.emf.compare.ide.ui.tests.logical.resolver.LocalMonitoredProxyCreationListenerTest;
 import org.eclipse.emf.compare.ide.ui.tests.logical.resolver.RemoteMonitoredProxyCreationListenerTest;
+import org.eclipse.emf.compare.ide.ui.tests.logical.resolver.RenameDetectorTest;
 import org.eclipse.emf.compare.ide.ui.tests.logical.resolver.ResolutionEventsTest;
 import org.eclipse.emf.compare.ide.ui.tests.logical.resolver.ResourceComputationSchedulerTest;
 import org.eclipse.emf.compare.ide.ui.tests.logical.resolver.ResourceComputationSchedulerWithEventBusTest;
+import org.eclipse.emf.compare.ide.ui.tests.logical.resolver.SimilarityComputerTest;
 import org.eclipse.emf.compare.ide.ui.tests.logical.resolver.ThreadedModelResolverGraphTest;
 import org.eclipse.emf.compare.ide.ui.tests.logical.resolver.ThreadedModelResolverWithCustomDependencyProviderTest;
 import org.eclipse.emf.compare.ide.ui.tests.structuremergeviewer.NavigatableTest;
@@ -53,7 +55,8 @@
 		ThreadedModelResolverGraphTest.class, ThreadedModelResolverWithCustomDependencyProviderTest.class,
 		DependencyGraphUpdaterTest.class, GraphResolutionTest.class, EMFModelProviderTest.class,
 		MergeAllCommandTests.class, LocalMonitoredProxyCreationListenerTest.class,
-		RemoteMonitoredProxyCreationListenerTest.class, MergeNonConflictingRunnableTest.class })
+		RemoteMonitoredProxyCreationListenerTest.class, MergeNonConflictingRunnableTest.class,
+		RenameDetectorTest.class, SimilarityComputerTest.class })
 public class AllTests {
 	/**
 	 * Launches the test with the given arguments.