blob: 1396a4db200545de124c2b19ad1f3b2cee10a932 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005, 2018 IBM Corporation 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:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.compare.tests;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import org.eclipse.compare.internal.Utilities;
import org.eclipse.compare.internal.core.patch.FilePatch2;
import org.eclipse.compare.internal.core.patch.FileDiffResult;
import org.eclipse.compare.internal.core.patch.Hunk;
import org.eclipse.compare.internal.patch.Patcher;
import org.eclipse.compare.patch.ApplyPatchOperation;
import org.eclipse.compare.patch.IFilePatch;
import org.eclipse.compare.patch.IFilePatchResult;
import org.eclipse.compare.patch.PatchConfiguration;
import org.eclipse.compare.patch.WorkspacePatcherUI;
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.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
public class FileDiffResultTest extends WorkspaceTest {
public FileDiffResultTest() {
super();
}
public FileDiffResultTest(String name) {
super(name);
}
private static final String PATCH_FILE = "patchfile";
private static final String NEW_FILENAME = "newfile";
private static final String NEW_FILE_CONTENT = "Hi There";
private IProgressMonitor nullProgressMonitor = new NullProgressMonitor();
private PatchConfiguration patchConfiguration = new PatchConfiguration();
/**
* Tests applying a patch which creates a new file in a project. The file
* doesn't exist in the project.
*
* @throws CoreException
*/
public void testPatchAddsNewFile() throws CoreException {
IProject project = createProject("FileDiffResultTest",
new String[] { "oldfile" });
try {
// create the patch file
IFile file = project.getFile(PATCH_FILE);
file.create(new ByteArrayInputStream(createPatchAddingFile(project,
NEW_FILENAME, false /* the file doesn't exist */)
.getBytes()), true, null);
assertFalse(project.getFile(NEW_FILENAME).exists());
IFilePatch[] filePatch = ApplyPatchOperation.parsePatch(file);
assertNotNull(filePatch);
assertEquals(1, filePatch.length);
IFilePatchResult filePatchResult = filePatch[0].apply((IStorage)null,
patchConfiguration, nullProgressMonitor);
assertTrue(filePatchResult.hasMatches());
assertEquals(0, filePatchResult.getRejects().length);
assertEquals("", getStringFromStream(filePatchResult
.getOriginalContents()));
assertEquals(NEW_FILE_CONTENT, getStringFromStream(filePatchResult
.getPatchedContents()));
} catch (IOException e) {
fail();
}
}
/**
* Tests applying a patch which creates a new file in a project. The file
* already exists in the project.
*
* @throws CoreException
*/
public void testPatchAddsExistingFileWithSameContents()
throws CoreException {
IProject project = createProject("FileDiffResultTest",
new String[] { NEW_FILENAME });
try {
// create the patch file
IFile file = project.getFile(PATCH_FILE);
file.create(new ByteArrayInputStream(createPatchAddingFile(project,
NEW_FILENAME, true).getBytes()), true, null);
assertTrue(project.getFile(NEW_FILENAME).exists());
IFilePatch[] filePatch = ApplyPatchOperation.parsePatch(file);
assertNotNull(filePatch);
assertEquals(1, filePatch.length);
IFilePatchResult filePatchResult = filePatch[0].apply(project
.getFile(NEW_FILENAME), patchConfiguration,
nullProgressMonitor);
assertFalse(filePatchResult.hasMatches());
assertEquals(1, filePatchResult.getRejects().length);
assertNotNull(filePatchResult.getOriginalContents());
assertNotNull(filePatchResult.getPatchedContents());
assertEquals(new FileInputStream(project.getFile(NEW_FILENAME)
.getLocation().toFile()), filePatchResult
.getOriginalContents());
assertEquals(filePatchResult.getOriginalContents(), filePatchResult
.getPatchedContents());
} catch (IOException e) {
fail();
}
}
/**
* Tests applying a patch which creates a new file in a project. The file
* already exists in the project, but has different contents.
*
* @throws CoreException
*/
public void testPatchAddsExistingFileWithDifferentContents()
throws CoreException {
IProject project = createProject("FileDiffResultTest",
new String[] { NEW_FILENAME });
project.getFile(NEW_FILENAME).setContents(
new ByteArrayInputStream("I'm a different content".getBytes()),
IResource.NONE, null);
try {
// create the patch file
IFile file = project.getFile(PATCH_FILE);
file.create(new ByteArrayInputStream(createPatchAddingFile(project,
NEW_FILENAME, false).getBytes()), true, null);
assertTrue(project.getFile(NEW_FILENAME).exists());
IFilePatch[] filePatch = ApplyPatchOperation.parsePatch(file);
assertNotNull(filePatch);
assertEquals(1, filePatch.length);
IFilePatchResult filePatchResult = filePatch[0].apply(project
.getFile(NEW_FILENAME), patchConfiguration,
nullProgressMonitor);
assertFalse(filePatchResult.hasMatches());
assertEquals(1, filePatchResult.getRejects().length);
assertNotNull(filePatchResult.getOriginalContents());
assertNotNull(filePatchResult.getPatchedContents());
assertEquals(new FileInputStream(project.getFile(NEW_FILENAME)
.getLocation().toFile()), filePatchResult
.getOriginalContents());
assertEquals("I'm a different content",
getStringFromStream(filePatchResult.getOriginalContents()));
assertEquals(filePatchResult.getOriginalContents(), filePatchResult
.getPatchedContents());
} catch (IOException e) {
fail();
}
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=185379
public void testFileDiffResultWithNullPath() {
MyFileDiff myFileDiff = new MyFileDiff();
FileDiffResult fileDiffResult = new FileDiffResult(myFileDiff,
patchConfiguration);
try {
fileDiffResult.calculateFuzz(new ArrayList<>(), nullProgressMonitor);
} catch (NullPointerException e) {
fail();
}
}
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=187365
public void testExcludePartOfNonWorkspacePatch() {
Patcher patcher = new Patcher();
MyFileDiff myFileDiff = new MyFileDiff();
try {
patcher.setEnabled(myFileDiff, false);
} catch (NullPointerException e) {
fail();
}
}
// utility methods
/**
* A mock FileDiff class.
*/
private class MyFileDiff extends FilePatch2 {
protected MyFileDiff() {
super(null, 0, null, 0);
add(Hunk.createHunk(this, new int[] { 0, 0 }, new int[] { 0, 0 },
new ArrayList<>(), false, false, false));
}
}
/**
* @param project
* The project for which the patch is prepared.
* @param filename
* Filename of the file to be added by the patch.
* @param sameContents
* Should the file added by the patch has the same content as the
* existing one. Enter <code>false</code>, if the file doesn't
* exist.
* @return Content of the patch.
* @throws IOException
* @throws CoreException
*/
private String createPatchAddingFile(IProject project, String filename,
boolean sameContents) throws IOException, CoreException {
StringBuffer sb = new StringBuffer();
sb.append(WorkspacePatcherUI.getWorkspacePatchHeader() + "\n");
sb.append(WorkspacePatcherUI.getWorkspacePatchProjectHeader(project)
+ "\n");
sb.append("Index: " + filename + "\n");
sb
.append("===================================================================\n");
sb.append("RCS file: " + filename + "\n");
sb.append("diff -N " + filename + "\n");
sb.append("--- /dev/null 1 Jan 1970 00:00:00 -0000\n");
sb.append("+++ " + filename + " 1 Jan 1970 00:00:00 -0000\n");
sb.append("@@ -0,0 +1,1 @@\n");
if (sameContents) {
sb.append("+" + getStringFromIFile(project.getFile(filename)));
} else {
sb.append("+" + NEW_FILE_CONTENT);
}
return sb.toString();
}
/**
* Return string read from an input stream.
*
* @param in
* Input stream.
* @return String read from the stream.
* @throws IOException
*/
private static String getStringFromStream(InputStream in)
throws IOException {
return Utilities.readString(in, ResourcesPlugin.getEncoding());
}
/**
* Returns content of a file.
*
* @param file
* A file.
* @return Content of the file.
* @throws IOException
* @throws CoreException
*/
private static String getStringFromIFile(IFile file) throws IOException,
CoreException {
return getStringFromStream(new BufferedInputStream(file.getContents()));
}
/**
* Check if two input streams are equal. They can't be null, all bytes need
* to be the same, and they need to have same length.
*
* @param inputStream1
* First stream to check.
* @param inputStream2
* Second stream to check.
* @throws IOException
*/
private static void assertEquals(InputStream inputStream1,
InputStream inputStream2) throws IOException {
assertNotNull(inputStream1);
assertNotNull(inputStream2);
int byte1, byte2;
do {
byte1 = inputStream1.read();
byte2 = inputStream2.read();
// compare every byte of the streams
assertEquals(byte1, byte2);
} while (byte1 != -1 || byte2 != -1);
// the end of the streams should be reached at the same time
assertEquals(-1, byte1);
assertEquals(-1, byte2);
inputStream1.close();
inputStream2.close();
}
}