summaryrefslogtreecommitdiff
path: root/tests/apply
diff options
context:
space:
mode:
authorEdward Thomson <ethomson@microsoft.com>2014-04-01 23:58:59 -0700
committerEdward Thomson <ethomson@github.com>2016-05-26 11:36:11 -0500
commit7cb904ba4443c22ff5396769b7d07a7f329c0102 (patch)
tree30b2a54983d04ff8b6e55c6c9ff735aad2b9d58b /tests/apply
parent784bb30300eadfa47c9d5632f9b1a111e36bcbbd (diff)
downloadlibgit2-7cb904ba4443c22ff5396769b7d07a7f329c0102.tar.gz
Introduce git_apply_patch
The beginnings of patch application from an existing (diff-created) git_patch object: applies the hunks of a git_patch to a buffer.
Diffstat (limited to 'tests/apply')
-rw-r--r--tests/apply/apply_common.h286
-rw-r--r--tests/apply/fromdiff.c176
2 files changed, 462 insertions, 0 deletions
diff --git a/tests/apply/apply_common.h b/tests/apply/apply_common.h
new file mode 100644
index 000000000..8226cc1da
--- /dev/null
+++ b/tests/apply/apply_common.h
@@ -0,0 +1,286 @@
+/* The original file contents */
+
+#define FILE_ORIGINAL \
+ "hey!\n" \
+ "this is some context!\n" \
+ "around some lines\n" \
+ "that will change\n" \
+ "yes it is!\n" \
+ "(this line is changed)\n" \
+ "and this\n" \
+ "is additional context\n" \
+ "below it!\n"
+
+/* A change in the middle of the file (and the resultant patch) */
+
+#define FILE_CHANGE_MIDDLE \
+ "hey!\n" \
+ "this is some context!\n" \
+ "around some lines\n" \
+ "that will change\n" \
+ "yes it is!\n" \
+ "(THIS line is changed!)\n" \
+ "and this\n" \
+ "is additional context\n" \
+ "below it!\n"
+
+#define PATCH_ORIGINAL_TO_CHANGE_MIDDLE \
+ "diff --git a/file.txt b/file.txt\n" \
+ "index 9432026..cd8fd12 100644\n" \
+ "--- a/file.txt\n" \
+ "+++ b/file.txt\n" \
+ "@@ -3,7 +3,7 @@ this is some context!\n" \
+ " around some lines\n" \
+ " that will change\n" \
+ " yes it is!\n" \
+ "-(this line is changed)\n" \
+ "+(THIS line is changed!)\n" \
+ " and this\n" \
+ " is additional context\n" \
+ " below it!\n"
+
+#define PATCH_ORIGINAL_TO_CHANGE_MIDDLE_NOCONTEXT \
+ "diff --git a/file.txt b/file.txt\n" \
+ "index 9432026..cd8fd12 100644\n" \
+ "--- a/file.txt\n" \
+ "+++ b/file.txt\n" \
+ "@@ -6 +6 @@ yes it is!\n" \
+ "-(this line is changed)\n" \
+ "+(THIS line is changed!)\n"
+
+/* A change of the first line (and the resultant patch) */
+
+#define FILE_CHANGE_FIRSTLINE \
+ "hey, change in head!\n" \
+ "this is some context!\n" \
+ "around some lines\n" \
+ "that will change\n" \
+ "yes it is!\n" \
+ "(this line is changed)\n" \
+ "and this\n" \
+ "is additional context\n" \
+ "below it!\n"
+
+#define PATCH_ORIGINAL_TO_CHANGE_FIRSTLINE \
+ "diff --git a/file.txt b/file.txt\n" \
+ "index 9432026..c81df1d 100644\n" \
+ "--- a/file.txt\n" \
+ "+++ b/file.txt\n" \
+ "@@ -1,4 +1,4 @@\n" \
+ "-hey!\n" \
+ "+hey, change in head!\n" \
+ " this is some context!\n" \
+ " around some lines\n" \
+ " that will change\n"
+
+/* A change of the last line (and the resultant patch) */
+
+#define FILE_CHANGE_LASTLINE \
+ "hey!\n" \
+ "this is some context!\n" \
+ "around some lines\n" \
+ "that will change\n" \
+ "yes it is!\n" \
+ "(this line is changed)\n" \
+ "and this\n" \
+ "is additional context\n" \
+ "change to the last line.\n"
+
+#define PATCH_ORIGINAL_TO_CHANGE_LASTLINE \
+ "diff --git a/file.txt b/file.txt\n" \
+ "index 9432026..f70db1c 100644\n" \
+ "--- a/file.txt\n" \
+ "+++ b/file.txt\n" \
+ "@@ -6,4 +6,4 @@ yes it is!\n" \
+ " (this line is changed)\n" \
+ " and this\n" \
+ " is additional context\n" \
+ "-below it!\n" \
+ "+change to the last line.\n"
+
+/* An insertion at the beginning of the file (and the resultant patch) */
+
+#define FILE_PREPEND \
+ "insert at front\n" \
+ "hey!\n" \
+ "this is some context!\n" \
+ "around some lines\n" \
+ "that will change\n" \
+ "yes it is!\n" \
+ "(this line is changed)\n" \
+ "and this\n" \
+ "is additional context\n" \
+ "below it!\n"
+
+#define PATCH_ORIGINAL_TO_PREPEND \
+ "diff --git a/file.txt b/file.txt\n" \
+ "index 9432026..0f39b9a 100644\n" \
+ "--- a/file.txt\n" \
+ "+++ b/file.txt\n" \
+ "@@ -1,3 +1,4 @@\n" \
+ "+insert at front\n" \
+ " hey!\n" \
+ " this is some context!\n" \
+ " around some lines\n"
+
+#define PATCH_ORIGINAL_TO_PREPEND_NOCONTEXT \
+ "diff --git a/file.txt b/file.txt\n" \
+ "index 9432026..0f39b9a 100644\n" \
+ "--- a/file.txt\n" \
+ "+++ b/file.txt\n" \
+ "@@ -0,0 +1 @@\n" \
+ "+insert at front\n"
+
+/* An insertion at the end of the file (and the resultant patch) */
+
+#define FILE_APPEND \
+ "hey!\n" \
+ "this is some context!\n" \
+ "around some lines\n" \
+ "that will change\n" \
+ "yes it is!\n" \
+ "(this line is changed)\n" \
+ "and this\n" \
+ "is additional context\n" \
+ "below it!\n" \
+ "insert at end\n"
+
+#define PATCH_ORIGINAL_TO_APPEND \
+ "diff --git a/file.txt b/file.txt\n" \
+ "index 9432026..72788bb 100644\n" \
+ "--- a/file.txt\n" \
+ "+++ b/file.txt\n" \
+ "@@ -7,3 +7,4 @@ yes it is!\n" \
+ " and this\n" \
+ " is additional context\n" \
+ " below it!\n" \
+ "+insert at end\n"
+
+#define PATCH_ORIGINAL_TO_APPEND_NOCONTEXT \
+ "diff --git a/file.txt b/file.txt\n" \
+ "index 9432026..72788bb 100644\n" \
+ "--- a/file.txt\n" \
+ "+++ b/file.txt\n" \
+ "@@ -9,0 +10 @@ below it!\n" \
+ "+insert at end\n"
+
+/* An insertion at the beginning and end of file (and the resultant patch) */
+
+#define FILE_PREPEND_AND_APPEND \
+ "first and\n" \
+ "this is some context!\n" \
+ "around some lines\n" \
+ "that will change\n" \
+ "yes it is!\n" \
+ "(this line is changed)\n" \
+ "and this\n" \
+ "is additional context\n" \
+ "last lines\n"
+
+#define PATCH_ORIGINAL_TO_PREPEND_AND_APPEND \
+ "diff --git a/file.txt b/file.txt\n" \
+ "index 9432026..f282430 100644\n" \
+ "--- a/file.txt\n" \
+ "+++ b/file.txt\n" \
+ "@@ -1,4 +1,4 @@\n" \
+ "-hey!\n" \
+ "+first and\n" \
+ " this is some context!\n" \
+ " around some lines\n" \
+ " that will change\n" \
+ "@@ -6,4 +6,4 @@ yes it is!\n" \
+ " (this line is changed)\n" \
+ " and this\n" \
+ " is additional context\n" \
+ "-below it!\n" \
+ "+last lines\n"
+
+#define PATCH_ORIGINAL_TO_EMPTY_FILE \
+ "diff --git a/file.txt b/file.txt\n" \
+ "index 9432026..e69de29 100644\n" \
+ "--- a/file.txt\n" \
+ "+++ b/file.txt\n" \
+ "@@ -1,9 +0,0 @@\n" \
+ "-hey!\n" \
+ "-this is some context!\n" \
+ "-around some lines\n" \
+ "-that will change\n" \
+ "-yes it is!\n" \
+ "-(this line is changed)\n" \
+ "-and this\n" \
+ "-is additional context\n" \
+ "-below it!\n"
+
+#define PATCH_EMPTY_FILE_TO_ORIGINAL \
+ "diff --git a/file.txt b/file.txt\n" \
+ "index e69de29..9432026 100644\n" \
+ "--- a/file.txt\n" \
+ "+++ b/file.txt\n" \
+ "@@ -0,0 +1,9 @@\n" \
+ "+hey!\n" \
+ "+this is some context!\n" \
+ "+around some lines\n" \
+ "+that will change\n" \
+ "+yes it is!\n" \
+ "+(this line is changed)\n" \
+ "+and this\n" \
+ "+is additional context\n" \
+ "+below it!\n"
+
+#define PATCH_ADD_ORIGINAL \
+ "diff --git a/file.txt b/file.txt\n" \
+ "new file mode 100644\n" \
+ "index 0000000..9432026\n" \
+ "--- /dev/null\n" \
+ "+++ b/file.txt\n" \
+ "@@ -0,0 +1,9 @@\n" \
+ "+hey!\n" \
+ "+this is some context!\n" \
+ "+around some lines\n" \
+ "+that will change\n" \
+ "+yes it is!\n" \
+ "+(this line is changed)\n" \
+ "+and this\n" \
+ "+is additional context\n" \
+ "+below it!\n"
+
+#define PATCH_DELETE_ORIGINAL \
+ "diff --git a/file.txt b/file.txt\n" \
+ "deleted file mode 100644\n" \
+ "index 9432026..0000000\n" \
+ "--- a/file.txt\n" \
+ "+++ /dev/null\n" \
+ "@@ -1,9 +0,0 @@\n" \
+ "-hey!\n" \
+ "-this is some context!\n" \
+ "-around some lines\n" \
+ "-that will change\n" \
+ "-yes it is!\n" \
+ "-(this line is changed)\n" \
+ "-and this\n" \
+ "-is additional context\n" \
+ "-below it!\n"
+
+#define PATCH_RENAME_EXACT \
+ "diff --git a/file.txt b/newfile.txt\n" \
+ "similarity index 100%\n" \
+ "rename from file.txt\n" \
+ "rename to newfile.txt\n"
+
+#define PATCH_RENAME_SIMILAR \
+ "diff --git a/file.txt b/newfile.txt\n" \
+ "similarity index 77%\n" \
+ "rename from file.txt\n" \
+ "rename to newfile.txt\n" \
+ "index 9432026..cd8fd12 100644\n" \
+ "--- a/file.txt\n" \
+ "+++ b/newfile.txt\n" \
+ "@@ -3,7 +3,7 @@ this is some context!\n" \
+ " around some lines\n" \
+ " that will change\n" \
+ " yes it is!\n" \
+ "-(this line is changed)\n" \
+ "+(THIS line is changed!)\n" \
+ " and this\n" \
+ " is additional context\n" \
+ " below it!\n"
diff --git a/tests/apply/fromdiff.c b/tests/apply/fromdiff.c
new file mode 100644
index 000000000..64ed9de79
--- /dev/null
+++ b/tests/apply/fromdiff.c
@@ -0,0 +1,176 @@
+#include "clar_libgit2.h"
+#include "git2/sys/repository.h"
+
+#include "apply.h"
+#include "repository.h"
+#include "buf_text.h"
+
+#include "apply_common.h"
+
+static git_repository *repo = NULL;
+
+void test_apply_fromdiff__initialize(void)
+{
+ repo = cl_git_sandbox_init("renames");
+}
+
+void test_apply_fromdiff__cleanup(void)
+{
+ cl_git_sandbox_cleanup();
+}
+
+static int apply_buf(
+ const char *old,
+ const char *oldname,
+ const char *new,
+ const char *newname,
+ const char *patch_expected,
+ const git_diff_options *diff_opts)
+{
+ git_patch *patch;
+ git_buf result = GIT_BUF_INIT;
+ git_buf patchbuf = GIT_BUF_INIT;
+ char *filename;
+ unsigned int mode;
+ int error;
+
+ cl_git_pass(git_patch_from_buffers(&patch,
+ old, old ? strlen(old) : 0, oldname,
+ new, new ? strlen(new) : 0, newname,
+ diff_opts));
+ cl_git_pass(git_patch_to_buf(&patchbuf, patch));
+
+ cl_assert_equal_s(patch_expected, patchbuf.ptr);
+
+ error = git_apply__patch(&result, &filename, &mode, old, old ? strlen(old) : 0, patch);
+
+ if (error == 0 && new == NULL) {
+ cl_assert_equal_i(0, result.size);
+ cl_assert_equal_p(NULL, filename);
+ cl_assert_equal_i(0, mode);
+ } else {
+ cl_assert_equal_s(new, result.ptr);
+ cl_assert_equal_s("file.txt", filename);
+ cl_assert_equal_i(0100644, mode);
+ }
+
+ git__free(filename);
+ git_buf_free(&result);
+ git_buf_free(&patchbuf);
+ git_patch_free(patch);
+
+ return error;
+}
+
+void test_apply_fromdiff__change_middle(void)
+{
+ cl_git_pass(apply_buf(
+ FILE_ORIGINAL, "file.txt",
+ FILE_CHANGE_MIDDLE, "file.txt",
+ PATCH_ORIGINAL_TO_CHANGE_MIDDLE, NULL));
+}
+
+void test_apply_fromdiff__change_middle_nocontext(void)
+{
+ git_diff_options diff_opts = GIT_DIFF_OPTIONS_INIT;
+ diff_opts.context_lines = 0;
+
+ cl_git_pass(apply_buf(
+ FILE_ORIGINAL, "file.txt",
+ FILE_CHANGE_MIDDLE, "file.txt",
+ PATCH_ORIGINAL_TO_CHANGE_MIDDLE_NOCONTEXT, &diff_opts));
+}
+
+void test_apply_fromdiff__change_firstline(void)
+{
+ cl_git_pass(apply_buf(
+ FILE_ORIGINAL, "file.txt",
+ FILE_CHANGE_FIRSTLINE, "file.txt",
+ PATCH_ORIGINAL_TO_CHANGE_FIRSTLINE, NULL));
+}
+
+void test_apply_fromdiff__lastline(void)
+{
+ cl_git_pass(apply_buf(
+ FILE_ORIGINAL, "file.txt",
+ FILE_CHANGE_LASTLINE, "file.txt",
+ PATCH_ORIGINAL_TO_CHANGE_LASTLINE, NULL));
+}
+
+void test_apply_fromdiff__prepend(void)
+{
+ cl_git_pass(apply_buf(
+ FILE_ORIGINAL, "file.txt",
+ FILE_PREPEND, "file.txt",
+ PATCH_ORIGINAL_TO_PREPEND, NULL));
+}
+
+void test_apply_fromdiff__prepend_nocontext(void)
+{
+ git_diff_options diff_opts = GIT_DIFF_OPTIONS_INIT;
+ diff_opts.context_lines = 0;
+
+ cl_git_pass(apply_buf(
+ FILE_ORIGINAL, "file.txt",
+ FILE_PREPEND, "file.txt",
+ PATCH_ORIGINAL_TO_PREPEND_NOCONTEXT, &diff_opts));
+}
+
+void test_apply_fromdiff__append(void)
+{
+ cl_git_pass(apply_buf(
+ FILE_ORIGINAL, "file.txt",
+ FILE_APPEND, "file.txt",
+ PATCH_ORIGINAL_TO_APPEND, NULL));
+}
+
+void test_apply_fromdiff__append_nocontext(void)
+{
+ git_diff_options diff_opts = GIT_DIFF_OPTIONS_INIT;
+ diff_opts.context_lines = 0;
+
+ cl_git_pass(apply_buf(
+ FILE_ORIGINAL, "file.txt",
+ FILE_APPEND, "file.txt",
+ PATCH_ORIGINAL_TO_APPEND_NOCONTEXT, &diff_opts));
+}
+
+void test_apply_fromdiff__prepend_and_append(void)
+{
+ cl_git_pass(apply_buf(
+ FILE_ORIGINAL, "file.txt",
+ FILE_PREPEND_AND_APPEND, "file.txt",
+ PATCH_ORIGINAL_TO_PREPEND_AND_APPEND, NULL));
+}
+
+void test_apply_fromdiff__to_empty_file(void)
+{
+ cl_git_pass(apply_buf(
+ FILE_ORIGINAL, "file.txt",
+ "", NULL,
+ PATCH_ORIGINAL_TO_EMPTY_FILE, NULL));
+}
+
+void test_apply_fromdiff__from_empty_file(void)
+{
+ cl_git_pass(apply_buf(
+ "", NULL,
+ FILE_ORIGINAL, "file.txt",
+ PATCH_EMPTY_FILE_TO_ORIGINAL, NULL));
+}
+
+void test_apply_fromdiff__add(void)
+{
+ cl_git_pass(apply_buf(
+ NULL, NULL,
+ FILE_ORIGINAL, "file.txt",
+ PATCH_ADD_ORIGINAL, NULL));
+}
+
+void test_apply_fromdiff__delete(void)
+{
+ cl_git_pass(apply_buf(
+ FILE_ORIGINAL, "file.txt",
+ NULL, NULL,
+ PATCH_DELETE_ORIGINAL, NULL));
+}