1 #include "clar_libgit2.h"
2 #include "git2/sys/repository.h"
6 #include "patch_parse.h"
7 #include "repository.h"
9 #include "../patch/patch_common.h"
11 static git_repository
*repo
= NULL
;
13 void test_apply_fromfile__initialize(void)
15 repo
= cl_git_sandbox_init("renames");
18 void test_apply_fromfile__cleanup(void)
20 cl_git_sandbox_cleanup();
23 static int apply_patchfile(
28 const char *patchfile
,
29 const char *filename_expected
,
30 unsigned int mode_expected
)
33 git_buf result
= GIT_BUF_INIT
;
34 git_buf patchbuf
= GIT_BUF_INIT
;
39 cl_git_pass(git_patch_from_buffer(&patch
, patchfile
, strlen(patchfile
), NULL
));
41 error
= git_apply__patch(&result
, &filename
, &mode
, old
, old_len
, patch
, NULL
);
44 cl_assert_equal_i(new_len
, result
.size
);
46 cl_assert(memcmp(new, result
.ptr
, new_len
) == 0);
48 cl_assert_equal_s(filename_expected
, filename
);
49 cl_assert_equal_i(mode_expected
, mode
);
53 git_buf_dispose(&result
);
54 git_buf_dispose(&patchbuf
);
55 git_patch_free(patch
);
60 static int validate_and_apply_patchfile(
65 const char *patchfile
,
66 const git_diff_options
*diff_opts
,
67 const char *filename_expected
,
68 unsigned int mode_expected
)
70 git_patch
*patch_fromdiff
;
71 git_buf validated
= GIT_BUF_INIT
;
74 cl_git_pass(git_patch_from_buffers(&patch_fromdiff
,
75 old
, old_len
, "file.txt",
76 new, new_len
, "file.txt",
78 cl_git_pass(git_patch_to_buf(&validated
, patch_fromdiff
));
80 cl_assert_equal_s(patchfile
, validated
.ptr
);
82 error
= apply_patchfile(old
, old_len
, new, new_len
, patchfile
, filename_expected
, mode_expected
);
84 git_buf_dispose(&validated
);
85 git_patch_free(patch_fromdiff
);
90 void test_apply_fromfile__change_middle(void)
92 cl_git_pass(validate_and_apply_patchfile(
93 FILE_ORIGINAL
, strlen(FILE_ORIGINAL
),
94 FILE_CHANGE_MIDDLE
, strlen(FILE_CHANGE_MIDDLE
),
95 PATCH_ORIGINAL_TO_CHANGE_MIDDLE
, NULL
,
96 "file.txt", 0100644));
99 void test_apply_fromfile__change_middle_nocontext(void)
101 git_diff_options diff_opts
= GIT_DIFF_OPTIONS_INIT
;
102 diff_opts
.context_lines
= 0;
104 cl_git_pass(validate_and_apply_patchfile(
105 FILE_ORIGINAL
, strlen(FILE_ORIGINAL
),
106 FILE_CHANGE_MIDDLE
, strlen(FILE_CHANGE_MIDDLE
),
107 PATCH_ORIGINAL_TO_CHANGE_MIDDLE_NOCONTEXT
,
108 &diff_opts
, "file.txt", 0100644));
112 void test_apply_fromfile__change_firstline(void)
114 cl_git_pass(validate_and_apply_patchfile(
115 FILE_ORIGINAL
, strlen(FILE_ORIGINAL
),
116 FILE_CHANGE_FIRSTLINE
, strlen(FILE_CHANGE_FIRSTLINE
),
117 PATCH_ORIGINAL_TO_CHANGE_FIRSTLINE
, NULL
,
118 "file.txt", 0100644));
121 void test_apply_fromfile__lastline(void)
123 cl_git_pass(validate_and_apply_patchfile(
124 FILE_ORIGINAL
, strlen(FILE_ORIGINAL
),
125 FILE_CHANGE_LASTLINE
, strlen(FILE_CHANGE_LASTLINE
),
126 PATCH_ORIGINAL_TO_CHANGE_LASTLINE
, NULL
,
127 "file.txt", 0100644));
130 void test_apply_fromfile__change_middle_shrink(void)
132 cl_git_pass(validate_and_apply_patchfile(
133 FILE_ORIGINAL
, strlen(FILE_ORIGINAL
),
134 FILE_CHANGE_MIDDLE_SHRINK
, strlen(FILE_CHANGE_MIDDLE_SHRINK
),
135 PATCH_ORIGINAL_TO_CHANGE_MIDDLE_SHRINK
, NULL
,
136 "file.txt", 0100644));
139 void test_apply_fromfile__change_middle_shrink_nocontext(void)
141 git_diff_options diff_opts
= GIT_DIFF_OPTIONS_INIT
;
142 diff_opts
.context_lines
= 0;
144 cl_git_pass(validate_and_apply_patchfile(
145 FILE_ORIGINAL
, strlen(FILE_ORIGINAL
),
146 FILE_CHANGE_MIDDLE_SHRINK
, strlen(FILE_CHANGE_MIDDLE_SHRINK
),
147 PATCH_ORIGINAL_TO_MIDDLE_SHRINK_NOCONTEXT
, &diff_opts
,
148 "file.txt", 0100644));
151 void test_apply_fromfile__change_middle_grow(void)
153 cl_git_pass(validate_and_apply_patchfile(
154 FILE_ORIGINAL
, strlen(FILE_ORIGINAL
),
155 FILE_CHANGE_MIDDLE_GROW
, strlen(FILE_CHANGE_MIDDLE_GROW
),
156 PATCH_ORIGINAL_TO_CHANGE_MIDDLE_GROW
, NULL
,
157 "file.txt", 0100644));
160 void test_apply_fromfile__change_middle_grow_nocontext(void)
162 git_diff_options diff_opts
= GIT_DIFF_OPTIONS_INIT
;
163 diff_opts
.context_lines
= 0;
165 cl_git_pass(validate_and_apply_patchfile(
166 FILE_ORIGINAL
, strlen(FILE_ORIGINAL
),
167 FILE_CHANGE_MIDDLE_GROW
, strlen(FILE_CHANGE_MIDDLE_GROW
),
168 PATCH_ORIGINAL_TO_MIDDLE_GROW_NOCONTEXT
, &diff_opts
,
169 "file.txt", 0100644));
172 void test_apply_fromfile__prepend(void)
174 cl_git_pass(validate_and_apply_patchfile(
175 FILE_ORIGINAL
, strlen(FILE_ORIGINAL
),
176 FILE_PREPEND
, strlen(FILE_PREPEND
),
177 PATCH_ORIGINAL_TO_PREPEND
, NULL
, "file.txt", 0100644));
180 void test_apply_fromfile__prepend_nocontext(void)
182 git_diff_options diff_opts
= GIT_DIFF_OPTIONS_INIT
;
183 diff_opts
.context_lines
= 0;
185 cl_git_pass(validate_and_apply_patchfile(
186 FILE_ORIGINAL
, strlen(FILE_ORIGINAL
),
187 FILE_PREPEND
, strlen(FILE_PREPEND
),
188 PATCH_ORIGINAL_TO_PREPEND_NOCONTEXT
, &diff_opts
,
189 "file.txt", 0100644));
192 void test_apply_fromfile__append(void)
194 cl_git_pass(validate_and_apply_patchfile(
195 FILE_ORIGINAL
, strlen(FILE_ORIGINAL
),
196 FILE_APPEND
, strlen(FILE_APPEND
),
197 PATCH_ORIGINAL_TO_APPEND
, NULL
, "file.txt", 0100644));
200 void test_apply_fromfile__append_nocontext(void)
202 git_diff_options diff_opts
= GIT_DIFF_OPTIONS_INIT
;
203 diff_opts
.context_lines
= 0;
205 cl_git_pass(validate_and_apply_patchfile(
206 FILE_ORIGINAL
, strlen(FILE_ORIGINAL
),
207 FILE_APPEND
, strlen(FILE_APPEND
),
208 PATCH_ORIGINAL_TO_APPEND_NOCONTEXT
, &diff_opts
,
209 "file.txt", 0100644));
212 void test_apply_fromfile__prepend_and_append(void)
214 cl_git_pass(validate_and_apply_patchfile(
215 FILE_ORIGINAL
, strlen(FILE_ORIGINAL
),
216 FILE_PREPEND_AND_APPEND
, strlen(FILE_PREPEND_AND_APPEND
),
217 PATCH_ORIGINAL_TO_PREPEND_AND_APPEND
, NULL
,
218 "file.txt", 0100644));
221 void test_apply_fromfile__to_empty_file(void)
223 cl_git_pass(validate_and_apply_patchfile(
224 FILE_ORIGINAL
, strlen(FILE_ORIGINAL
),
226 PATCH_ORIGINAL_TO_EMPTY_FILE
, NULL
, "file.txt", 0100644));
229 void test_apply_fromfile__from_empty_file(void)
231 cl_git_pass(validate_and_apply_patchfile(
233 FILE_ORIGINAL
, strlen(FILE_ORIGINAL
),
234 PATCH_EMPTY_FILE_TO_ORIGINAL
, NULL
, "file.txt", 0100644));
237 void test_apply_fromfile__add(void)
239 cl_git_pass(validate_and_apply_patchfile(
241 FILE_ORIGINAL
, strlen(FILE_ORIGINAL
),
242 PATCH_ADD_ORIGINAL
, NULL
, "file.txt", 0100644));
245 void test_apply_fromfile__delete(void)
247 cl_git_pass(validate_and_apply_patchfile(
248 FILE_ORIGINAL
, strlen(FILE_ORIGINAL
),
250 PATCH_DELETE_ORIGINAL
, NULL
, NULL
, 0));
254 void test_apply_fromfile__rename_exact(void)
256 cl_git_pass(apply_patchfile(
257 FILE_ORIGINAL
, strlen(FILE_ORIGINAL
),
258 FILE_ORIGINAL
, strlen(FILE_ORIGINAL
),
259 PATCH_RENAME_EXACT
, "newfile.txt", 0100644));
262 void test_apply_fromfile__rename_similar(void)
264 cl_git_pass(apply_patchfile(
265 FILE_ORIGINAL
, strlen(FILE_ORIGINAL
),
266 FILE_CHANGE_MIDDLE
, strlen(FILE_CHANGE_MIDDLE
),
267 PATCH_RENAME_SIMILAR
, "newfile.txt", 0100644));
270 void test_apply_fromfile__rename_similar_quotedname(void)
272 cl_git_pass(apply_patchfile(
273 FILE_ORIGINAL
, strlen(FILE_ORIGINAL
),
274 FILE_CHANGE_MIDDLE
, strlen(FILE_CHANGE_MIDDLE
),
275 PATCH_RENAME_SIMILAR_QUOTEDNAME
, "foo\"bar.txt", 0100644));
278 void test_apply_fromfile__modechange(void)
280 cl_git_pass(apply_patchfile(
281 FILE_ORIGINAL
, strlen(FILE_ORIGINAL
),
282 FILE_ORIGINAL
, strlen(FILE_ORIGINAL
),
283 PATCH_MODECHANGE_UNCHANGED
, "file.txt", 0100755));
286 void test_apply_fromfile__modechange_with_modification(void)
288 cl_git_pass(apply_patchfile(
289 FILE_ORIGINAL
, strlen(FILE_ORIGINAL
),
290 FILE_CHANGE_MIDDLE
, strlen(FILE_CHANGE_MIDDLE
),
291 PATCH_MODECHANGE_MODIFIED
, "file.txt", 0100755));
294 void test_apply_fromfile__noisy(void)
296 cl_git_pass(apply_patchfile(
297 FILE_ORIGINAL
, strlen(FILE_ORIGINAL
),
298 FILE_CHANGE_MIDDLE
, strlen(FILE_CHANGE_MIDDLE
),
299 PATCH_NOISY
, "file.txt", 0100644));
302 void test_apply_fromfile__noisy_nocontext(void)
304 cl_git_pass(apply_patchfile(
305 FILE_ORIGINAL
, strlen(FILE_ORIGINAL
),
306 FILE_CHANGE_MIDDLE
, strlen(FILE_CHANGE_MIDDLE
),
307 PATCH_NOISY_NOCONTEXT
, "file.txt", 0100644));
310 void test_apply_fromfile__fail_truncated_1(void)
313 cl_git_fail(git_patch_from_buffer(&patch
, PATCH_TRUNCATED_1
,
314 strlen(PATCH_TRUNCATED_1
), NULL
));
317 void test_apply_fromfile__fail_truncated_2(void)
320 cl_git_fail(git_patch_from_buffer(&patch
, PATCH_TRUNCATED_2
,
321 strlen(PATCH_TRUNCATED_2
), NULL
));
324 void test_apply_fromfile__fail_truncated_3(void)
327 cl_git_fail(git_patch_from_buffer(&patch
, PATCH_TRUNCATED_3
,
328 strlen(PATCH_TRUNCATED_3
), NULL
));
331 void test_apply_fromfile__fail_corrupt_githeader(void)
334 cl_git_fail(git_patch_from_buffer(&patch
, PATCH_CORRUPT_GIT_HEADER
,
335 strlen(PATCH_CORRUPT_GIT_HEADER
), NULL
));
338 void test_apply_fromfile__empty_context(void)
340 cl_git_pass(apply_patchfile(
341 FILE_EMPTY_CONTEXT_ORIGINAL
, strlen(FILE_EMPTY_CONTEXT_ORIGINAL
),
342 FILE_EMPTY_CONTEXT_MODIFIED
, strlen(FILE_EMPTY_CONTEXT_MODIFIED
),
344 "file.txt", 0100644));
347 void test_apply_fromfile__append_no_nl(void)
349 cl_git_pass(validate_and_apply_patchfile(
350 FILE_ORIGINAL
, strlen(FILE_ORIGINAL
),
351 FILE_APPEND_NO_NL
, strlen(FILE_APPEND_NO_NL
),
352 PATCH_APPEND_NO_NL
, NULL
, "file.txt", 0100644));
355 void test_apply_fromfile__fail_missing_new_file(void)
358 cl_git_fail(git_patch_from_buffer(&patch
,
359 PATCH_CORRUPT_MISSING_NEW_FILE
,
360 strlen(PATCH_CORRUPT_MISSING_NEW_FILE
), NULL
));
363 void test_apply_fromfile__fail_missing_old_file(void)
366 cl_git_fail(git_patch_from_buffer(&patch
,
367 PATCH_CORRUPT_MISSING_OLD_FILE
,
368 strlen(PATCH_CORRUPT_MISSING_OLD_FILE
), NULL
));
371 void test_apply_fromfile__fail_no_changes(void)
374 cl_git_fail(git_patch_from_buffer(&patch
,
375 PATCH_CORRUPT_NO_CHANGES
,
376 strlen(PATCH_CORRUPT_NO_CHANGES
), NULL
));
379 void test_apply_fromfile__fail_missing_hunk_header(void)
382 cl_git_fail(git_patch_from_buffer(&patch
,
383 PATCH_CORRUPT_MISSING_HUNK_HEADER
,
384 strlen(PATCH_CORRUPT_MISSING_HUNK_HEADER
), NULL
));
387 void test_apply_fromfile__fail_not_a_patch(void)
390 cl_git_fail(git_patch_from_buffer(&patch
, PATCH_NOT_A_PATCH
,
391 strlen(PATCH_NOT_A_PATCH
), NULL
));
394 void test_apply_fromfile__binary_add(void)
396 cl_git_pass(apply_patchfile(
398 FILE_BINARY_DELTA_MODIFIED
, FILE_BINARY_DELTA_MODIFIED_LEN
,
399 PATCH_BINARY_ADD
, "binary.bin", 0100644));
402 void test_apply_fromfile__binary_change_delta(void)
404 cl_git_pass(apply_patchfile(
405 FILE_BINARY_DELTA_ORIGINAL
, FILE_BINARY_DELTA_ORIGINAL_LEN
,
406 FILE_BINARY_DELTA_MODIFIED
, FILE_BINARY_DELTA_MODIFIED_LEN
,
407 PATCH_BINARY_DELTA
, "binary.bin", 0100644));
410 void test_apply_fromfile__binary_change_literal(void)
412 cl_git_pass(apply_patchfile(
413 FILE_BINARY_LITERAL_ORIGINAL
, FILE_BINARY_LITERAL_ORIGINAL_LEN
,
414 FILE_BINARY_LITERAL_MODIFIED
, FILE_BINARY_LITERAL_MODIFIED_LEN
,
415 PATCH_BINARY_LITERAL
, "binary.bin", 0100644));
418 void test_apply_fromfile__binary_delete(void)
420 cl_git_pass(apply_patchfile(
421 FILE_BINARY_DELTA_MODIFIED
, FILE_BINARY_DELTA_MODIFIED_LEN
,
423 PATCH_BINARY_DELETE
, NULL
, 0));
426 void test_apply_fromfile__binary_change_does_not_apply(void)
428 /* try to apply patch backwards, ensure it does not apply */
429 cl_git_fail(apply_patchfile(
430 FILE_BINARY_DELTA_MODIFIED
, FILE_BINARY_DELTA_MODIFIED_LEN
,
431 FILE_BINARY_DELTA_ORIGINAL
, FILE_BINARY_DELTA_ORIGINAL_LEN
,
432 PATCH_BINARY_DELTA
, "binary.bin", 0100644));
435 void test_apply_fromfile__binary_change_must_be_reversible(void)
437 cl_git_fail(apply_patchfile(
438 FILE_BINARY_DELTA_MODIFIED
, FILE_BINARY_DELTA_MODIFIED_LEN
,
440 PATCH_BINARY_NOT_REVERSIBLE
, NULL
, 0));
443 void test_apply_fromfile__empty_file_not_allowed(void)
447 cl_git_fail(git_patch_from_buffer(&patch
, "", 0, NULL
));
448 cl_git_fail(git_patch_from_buffer(&patch
, NULL
, 0, NULL
));