diff options
author | Jason Haslam <jason@scitools.com> | 2017-03-30 22:40:47 -0600 |
---|---|---|
committer | Edward Thomson <ethomson@edwardthomson.com> | 2018-11-05 15:53:59 +0000 |
commit | 7263057269ee7131093046205abfcf5938a59ebf (patch) | |
tree | 9353d0829fec545d5d2c9c0d1ff77eca628dc4e1 /tests | |
parent | 52e27b840437d1a374c014a04787d0962f05a4f0 (diff) | |
download | libgit2-7263057269ee7131093046205abfcf5938a59ebf.tar.gz |
patch: add support for partial patch application
Add hunk callback parameter to git_apply__patch to allow hunks to be skipped.
Diffstat (limited to 'tests')
-rw-r--r-- | tests/apply/fromdiff.c | 46 | ||||
-rw-r--r-- | tests/apply/partial.c | 161 | ||||
-rw-r--r-- | tests/patch/patch_common.h | 106 |
3 files changed, 313 insertions, 0 deletions
diff --git a/tests/apply/fromdiff.c b/tests/apply/fromdiff.c index 3b156025e..8a6d8fa0a 100644 --- a/tests/apply/fromdiff.c +++ b/tests/apply/fromdiff.c @@ -150,6 +150,52 @@ void test_apply_fromdiff__prepend_nocontext(void) PATCH_ORIGINAL_TO_PREPEND_NOCONTEXT, &diff_opts)); } +void test_apply_fromdiff__prepend_and_change(void) +{ + cl_git_pass(apply_buf( + FILE_ORIGINAL, "file.txt", + FILE_PREPEND_AND_CHANGE, "file.txt", + PATCH_ORIGINAL_TO_PREPEND_AND_CHANGE, NULL)); +} + +void test_apply_fromdiff__prepend_and_change_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_AND_CHANGE, "file.txt", + PATCH_ORIGINAL_TO_PREPEND_AND_CHANGE_NOCONTEXT, &diff_opts)); +} + +void test_apply_fromdiff__delete_and_change(void) +{ + cl_git_pass(apply_buf( + FILE_ORIGINAL, "file.txt", + FILE_DELETE_AND_CHANGE, "file.txt", + PATCH_ORIGINAL_TO_DELETE_AND_CHANGE, NULL)); +} + +void test_apply_fromdiff__delete_and_change_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_DELETE_AND_CHANGE, "file.txt", + PATCH_ORIGINAL_TO_DELETE_AND_CHANGE_NOCONTEXT, &diff_opts)); +} + +void test_apply_fromdiff__delete_firstline(void) +{ + cl_git_pass(apply_buf( + FILE_ORIGINAL, "file.txt", + FILE_DELETE_FIRSTLINE, "file.txt", + PATCH_ORIGINAL_TO_DELETE_FIRSTLINE, NULL)); +} + void test_apply_fromdiff__append(void) { cl_git_pass(apply_buf( diff --git a/tests/apply/partial.c b/tests/apply/partial.c new file mode 100644 index 000000000..bdbf35a7f --- /dev/null +++ b/tests/apply/partial.c @@ -0,0 +1,161 @@ +#include "clar_libgit2.h" +#include "git2/sys/repository.h" + +#include "apply.h" +#include "repository.h" +#include "buf_text.h" + +#include "../patch/patch_common.h" + +static git_repository *repo = NULL; + +void test_apply_partial__initialize(void) +{ + repo = cl_git_sandbox_init("renames"); +} + +void test_apply_partial__cleanup(void) +{ + cl_git_sandbox_cleanup(); +} + +static int skip_addition( + const git_diff_hunk *hunk, + void *payload) +{ + GIT_UNUSED(payload); + + return (hunk->new_lines > hunk->old_lines) ? 1 : 0; +} + +static int skip_deletion( + const git_diff_hunk *hunk, + void *payload) +{ + GIT_UNUSED(payload); + + return (hunk->new_lines < hunk->old_lines) ? 1 : 0; +} + +static int skip_change( + const git_diff_hunk *hunk, + void *payload) +{ + GIT_UNUSED(payload); + + return (hunk->new_lines == hunk->old_lines) ? 1 : 0; +} + +static int apply_buf( + const char *old, + const char *oldname, + const char *new, + const char *newname, + const char *expected, + const git_diff_options *diff_opts, + git_apply_hunk_cb hunk_cb, + void *payload) +{ + git_patch *patch; + git_buf result = GIT_BUF_INIT; + git_buf patchbuf = GIT_BUF_INIT; + git_apply_options opts = GIT_APPLY_OPTIONS_INIT; + char *filename; + unsigned int mode; + int error; + size_t oldsize = strlen(old); + size_t newsize = strlen(new); + + opts.hunk_cb = hunk_cb; + opts.payload = payload; + + cl_git_pass(git_patch_from_buffers(&patch, old, oldsize, oldname, new, newsize, newname, diff_opts)); + if ((error = git_apply__patch(&result, &filename, &mode, old, oldsize, patch, &opts)) == 0) { + cl_assert_equal_s(expected, result.ptr); + cl_assert_equal_s(newname, 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_partial__prepend_and_change_skip_addition(void) +{ + cl_git_pass(apply_buf( + FILE_ORIGINAL, "file.txt", + FILE_PREPEND_AND_CHANGE, "file.txt", + FILE_ORIGINAL, NULL, skip_addition, NULL)); +} + +void test_apply_partial__prepend_and_change_nocontext_skip_addition(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_AND_CHANGE, "file.txt", + FILE_CHANGE_MIDDLE, &diff_opts, skip_addition, NULL)); +} + +void test_apply_partial__prepend_and_change_skip_change(void) +{ + cl_git_pass(apply_buf( + FILE_ORIGINAL, "file.txt", + FILE_PREPEND_AND_CHANGE, "file.txt", + FILE_PREPEND_AND_CHANGE, NULL, skip_change, NULL)); +} + +void test_apply_partial__prepend_and_change_nocontext_skip_change(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_AND_CHANGE, "file.txt", + FILE_PREPEND, &diff_opts, skip_change, NULL)); +} + +void test_apply_partial__delete_and_change_skip_deletion(void) +{ + cl_git_pass(apply_buf( + FILE_ORIGINAL, "file.txt", + FILE_DELETE_AND_CHANGE, "file.txt", + FILE_ORIGINAL, NULL, skip_deletion, NULL)); +} + +void test_apply_partial__delete_and_change_nocontext_skip_deletion(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_DELETE_AND_CHANGE, "file.txt", + FILE_CHANGE_MIDDLE, &diff_opts, skip_deletion, NULL)); +} + +void test_apply_partial__delete_and_change_skip_change(void) +{ + cl_git_pass(apply_buf( + FILE_ORIGINAL, "file.txt", + FILE_DELETE_AND_CHANGE, "file.txt", + FILE_DELETE_AND_CHANGE, NULL, skip_change, NULL)); +} + +void test_apply_partial__delete_and_change_nocontext_skip_change(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_DELETE_AND_CHANGE, "file.txt", + FILE_DELETE_FIRSTLINE, &diff_opts, skip_change, NULL)); +} diff --git a/tests/patch/patch_common.h b/tests/patch/patch_common.h index e838e6089..3f2668ddc 100644 --- a/tests/patch/patch_common.h +++ b/tests/patch/patch_common.h @@ -220,6 +220,112 @@ "@@ -0,0 +1 @@\n" \ "+insert at front\n" +/* An insertion at the beginning of the file and change in the middle */ + +#define FILE_PREPEND_AND_CHANGE \ + "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_AND_CHANGE \ + "diff --git a/file.txt b/file.txt\n" \ + "index 9432026..f73c8bb 100644\n" \ + "--- a/file.txt\n" \ + "+++ b/file.txt\n" \ + "@@ -1,9 +1,10 @@\n" \ + "+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" \ + "+(THIS line is changed!)\n" \ + " and this\n" \ + " is additional context\n" \ + " below it!\n" + +#define PATCH_ORIGINAL_TO_PREPEND_AND_CHANGE_NOCONTEXT \ + "diff --git a/file.txt b/file.txt\n" \ + "index 9432026..f73c8bb 100644\n" \ + "--- a/file.txt\n" \ + "+++ b/file.txt\n" \ + "@@ -0,0 +1 @@\n" \ + "+insert at front\n" \ + "@@ -6 +7 @@ yes it is!\n" \ + "-(this line is changed)\n" \ + "+(THIS line is changed!)\n" + +/* A deletion at the beginning of the file and a change in the middle */ + +#define FILE_DELETE_AND_CHANGE \ + "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_DELETE_AND_CHANGE \ + "diff --git a/file.txt b/file.txt\n" \ + "index 9432026..1e2dfa6 100644\n" \ + "--- a/file.txt\n" \ + "+++ b/file.txt\n" \ + "@@ -1,9 +1,8 @@\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" \ + "+(THIS line is changed!)\n" \ + " and this\n" \ + " is additional context\n" \ + " below it!\n" + +#define PATCH_ORIGINAL_TO_DELETE_AND_CHANGE_NOCONTEXT \ + "diff --git a/file.txt b/file.txt\n" \ + "index 9432026..1e2dfa6 100644\n" \ + "--- a/file.txt\n" \ + "+++ b/file.txt\n" \ + "@@ -1 +0,0 @@\n" \ + "-hey!\n" \ + "@@ -6 +5 @@ yes it is!\n" \ + "-(this line is changed)\n" \ + "+(THIS line is changed!)\n" + +/* A deletion at the beginning of the file */ + +#define FILE_DELETE_FIRSTLINE \ + "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_DELETE_FIRSTLINE \ + "diff --git a/file.txt b/file.txt\n" \ + "index 9432026..f31fa13 100644\n" \ + "--- a/file.txt\n" \ + "+++ b/file.txt\n" \ + "@@ -1,4 +1,3 @@\n" \ + "-hey!\n" \ + " this is some context!\n" \ + " around some lines\n" \ + " that will change\n" + /* An insertion at the end of the file (and the resultant patch) */ #define FILE_APPEND \ |