1 #include "clar_libgit2.h"
2 #include "git2/sys/repository.h"
6 #include "patch_parse.h"
7 #include "repository.h"
10 #include "../patch/patch_common.h"
12 static git_repository
*repo
= NULL
;
14 void test_apply_fromfile__initialize(void)
16 repo
= cl_git_sandbox_init("renames");
19 void test_apply_fromfile__cleanup(void)
21 cl_git_sandbox_cleanup();
24 static int apply_patchfile(
29 const char *patchfile
,
30 const char *filename_expected
,
31 unsigned int mode_expected
)
34 git_buf result
= GIT_BUF_INIT
;
35 git_buf patchbuf
= GIT_BUF_INIT
;
40 cl_git_pass(git_patch_from_buffer(&patch
, patchfile
, strlen(patchfile
), NULL
));
42 error
= git_apply__patch(&result
, &filename
, &mode
, old
, old_len
, patch
, NULL
);
45 cl_assert_equal_i(new_len
, result
.size
);
47 cl_assert(memcmp(new, result
.ptr
, new_len
) == 0);
49 cl_assert_equal_s(filename_expected
, filename
);
50 cl_assert_equal_i(mode_expected
, mode
);
54 git_buf_dispose(&result
);
55 git_buf_dispose(&patchbuf
);
56 git_patch_free(patch
);
61 static int validate_and_apply_patchfile(
66 const char *patchfile
,
67 const git_diff_options
*diff_opts
,
68 const char *filename_expected
,
69 unsigned int mode_expected
)
71 git_patch
*patch_fromdiff
;
72 git_buf validated
= GIT_BUF_INIT
;
75 cl_git_pass(git_patch_from_buffers(&patch_fromdiff
,
76 old
, old_len
, "file.txt",
77 new, new_len
, "file.txt",
79 cl_git_pass(git_patch_to_buf(&validated
, patch_fromdiff
));
81 cl_assert_equal_s(patchfile
, validated
.ptr
);
83 error
= apply_patchfile(old
, old_len
, new, new_len
, patchfile
, filename_expected
, mode_expected
);
85 git_buf_dispose(&validated
);
86 git_patch_free(patch_fromdiff
);
91 void test_apply_fromfile__change_middle(void)
93 cl_git_pass(validate_and_apply_patchfile(
94 FILE_ORIGINAL
, strlen(FILE_ORIGINAL
),
95 FILE_CHANGE_MIDDLE
, strlen(FILE_CHANGE_MIDDLE
),
96 PATCH_ORIGINAL_TO_CHANGE_MIDDLE
, NULL
,
97 "file.txt", 0100644));
100 void test_apply_fromfile__change_middle_nocontext(void)
102 git_diff_options diff_opts
= GIT_DIFF_OPTIONS_INIT
;
103 diff_opts
.context_lines
= 0;
105 cl_git_pass(validate_and_apply_patchfile(
106 FILE_ORIGINAL
, strlen(FILE_ORIGINAL
),
107 FILE_CHANGE_MIDDLE
, strlen(FILE_CHANGE_MIDDLE
),
108 PATCH_ORIGINAL_TO_CHANGE_MIDDLE_NOCONTEXT
,
109 &diff_opts
, "file.txt", 0100644));
113 void test_apply_fromfile__change_firstline(void)
115 cl_git_pass(validate_and_apply_patchfile(
116 FILE_ORIGINAL
, strlen(FILE_ORIGINAL
),
117 FILE_CHANGE_FIRSTLINE
, strlen(FILE_CHANGE_FIRSTLINE
),
118 PATCH_ORIGINAL_TO_CHANGE_FIRSTLINE
, NULL
,
119 "file.txt", 0100644));
122 void test_apply_fromfile__lastline(void)
124 cl_git_pass(validate_and_apply_patchfile(
125 FILE_ORIGINAL
, strlen(FILE_ORIGINAL
),
126 FILE_CHANGE_LASTLINE
, strlen(FILE_CHANGE_LASTLINE
),
127 PATCH_ORIGINAL_TO_CHANGE_LASTLINE
, NULL
,
128 "file.txt", 0100644));
131 void test_apply_fromfile__change_middle_shrink(void)
133 cl_git_pass(validate_and_apply_patchfile(
134 FILE_ORIGINAL
, strlen(FILE_ORIGINAL
),
135 FILE_CHANGE_MIDDLE_SHRINK
, strlen(FILE_CHANGE_MIDDLE_SHRINK
),
136 PATCH_ORIGINAL_TO_CHANGE_MIDDLE_SHRINK
, NULL
,
137 "file.txt", 0100644));
140 void test_apply_fromfile__change_middle_shrink_nocontext(void)
142 git_diff_options diff_opts
= GIT_DIFF_OPTIONS_INIT
;
143 diff_opts
.context_lines
= 0;
145 cl_git_pass(validate_and_apply_patchfile(
146 FILE_ORIGINAL
, strlen(FILE_ORIGINAL
),
147 FILE_CHANGE_MIDDLE_SHRINK
, strlen(FILE_CHANGE_MIDDLE_SHRINK
),
148 PATCH_ORIGINAL_TO_MIDDLE_SHRINK_NOCONTEXT
, &diff_opts
,
149 "file.txt", 0100644));
152 void test_apply_fromfile__change_middle_grow(void)
154 cl_git_pass(validate_and_apply_patchfile(
155 FILE_ORIGINAL
, strlen(FILE_ORIGINAL
),
156 FILE_CHANGE_MIDDLE_GROW
, strlen(FILE_CHANGE_MIDDLE_GROW
),
157 PATCH_ORIGINAL_TO_CHANGE_MIDDLE_GROW
, NULL
,
158 "file.txt", 0100644));
161 void test_apply_fromfile__change_middle_grow_nocontext(void)
163 git_diff_options diff_opts
= GIT_DIFF_OPTIONS_INIT
;
164 diff_opts
.context_lines
= 0;
166 cl_git_pass(validate_and_apply_patchfile(
167 FILE_ORIGINAL
, strlen(FILE_ORIGINAL
),
168 FILE_CHANGE_MIDDLE_GROW
, strlen(FILE_CHANGE_MIDDLE_GROW
),
169 PATCH_ORIGINAL_TO_MIDDLE_GROW_NOCONTEXT
, &diff_opts
,
170 "file.txt", 0100644));
173 void test_apply_fromfile__prepend(void)
175 cl_git_pass(validate_and_apply_patchfile(
176 FILE_ORIGINAL
, strlen(FILE_ORIGINAL
),
177 FILE_PREPEND
, strlen(FILE_PREPEND
),
178 PATCH_ORIGINAL_TO_PREPEND
, NULL
, "file.txt", 0100644));
181 void test_apply_fromfile__prepend_nocontext(void)
183 git_diff_options diff_opts
= GIT_DIFF_OPTIONS_INIT
;
184 diff_opts
.context_lines
= 0;
186 cl_git_pass(validate_and_apply_patchfile(
187 FILE_ORIGINAL
, strlen(FILE_ORIGINAL
),
188 FILE_PREPEND
, strlen(FILE_PREPEND
),
189 PATCH_ORIGINAL_TO_PREPEND_NOCONTEXT
, &diff_opts
,
190 "file.txt", 0100644));
193 void test_apply_fromfile__append(void)
195 cl_git_pass(validate_and_apply_patchfile(
196 FILE_ORIGINAL
, strlen(FILE_ORIGINAL
),
197 FILE_APPEND
, strlen(FILE_APPEND
),
198 PATCH_ORIGINAL_TO_APPEND
, NULL
, "file.txt", 0100644));
201 void test_apply_fromfile__append_nocontext(void)
203 git_diff_options diff_opts
= GIT_DIFF_OPTIONS_INIT
;
204 diff_opts
.context_lines
= 0;
206 cl_git_pass(validate_and_apply_patchfile(
207 FILE_ORIGINAL
, strlen(FILE_ORIGINAL
),
208 FILE_APPEND
, strlen(FILE_APPEND
),
209 PATCH_ORIGINAL_TO_APPEND_NOCONTEXT
, &diff_opts
,
210 "file.txt", 0100644));
213 void test_apply_fromfile__prepend_and_append(void)
215 cl_git_pass(validate_and_apply_patchfile(
216 FILE_ORIGINAL
, strlen(FILE_ORIGINAL
),
217 FILE_PREPEND_AND_APPEND
, strlen(FILE_PREPEND_AND_APPEND
),
218 PATCH_ORIGINAL_TO_PREPEND_AND_APPEND
, NULL
,
219 "file.txt", 0100644));
222 void test_apply_fromfile__to_empty_file(void)
224 cl_git_pass(validate_and_apply_patchfile(
225 FILE_ORIGINAL
, strlen(FILE_ORIGINAL
),
227 PATCH_ORIGINAL_TO_EMPTY_FILE
, NULL
, "file.txt", 0100644));
230 void test_apply_fromfile__from_empty_file(void)
232 cl_git_pass(validate_and_apply_patchfile(
234 FILE_ORIGINAL
, strlen(FILE_ORIGINAL
),
235 PATCH_EMPTY_FILE_TO_ORIGINAL
, NULL
, "file.txt", 0100644));
238 void test_apply_fromfile__add(void)
240 cl_git_pass(validate_and_apply_patchfile(
242 FILE_ORIGINAL
, strlen(FILE_ORIGINAL
),
243 PATCH_ADD_ORIGINAL
, NULL
, "file.txt", 0100644));
246 void test_apply_fromfile__delete(void)
248 cl_git_pass(validate_and_apply_patchfile(
249 FILE_ORIGINAL
, strlen(FILE_ORIGINAL
),
251 PATCH_DELETE_ORIGINAL
, NULL
, NULL
, 0));
255 void test_apply_fromfile__rename_exact(void)
257 cl_git_pass(apply_patchfile(
258 FILE_ORIGINAL
, strlen(FILE_ORIGINAL
),
259 FILE_ORIGINAL
, strlen(FILE_ORIGINAL
),
260 PATCH_RENAME_EXACT
, "newfile.txt", 0100644));
263 void test_apply_fromfile__rename_similar(void)
265 cl_git_pass(apply_patchfile(
266 FILE_ORIGINAL
, strlen(FILE_ORIGINAL
),
267 FILE_CHANGE_MIDDLE
, strlen(FILE_CHANGE_MIDDLE
),
268 PATCH_RENAME_SIMILAR
, "newfile.txt", 0100644));
271 void test_apply_fromfile__rename_similar_quotedname(void)
273 cl_git_pass(apply_patchfile(
274 FILE_ORIGINAL
, strlen(FILE_ORIGINAL
),
275 FILE_CHANGE_MIDDLE
, strlen(FILE_CHANGE_MIDDLE
),
276 PATCH_RENAME_SIMILAR_QUOTEDNAME
, "foo\"bar.txt", 0100644));
279 void test_apply_fromfile__modechange(void)
281 cl_git_pass(apply_patchfile(
282 FILE_ORIGINAL
, strlen(FILE_ORIGINAL
),
283 FILE_ORIGINAL
, strlen(FILE_ORIGINAL
),
284 PATCH_MODECHANGE_UNCHANGED
, "file.txt", 0100755));
287 void test_apply_fromfile__modechange_with_modification(void)
289 cl_git_pass(apply_patchfile(
290 FILE_ORIGINAL
, strlen(FILE_ORIGINAL
),
291 FILE_CHANGE_MIDDLE
, strlen(FILE_CHANGE_MIDDLE
),
292 PATCH_MODECHANGE_MODIFIED
, "file.txt", 0100755));
295 void test_apply_fromfile__noisy(void)
297 cl_git_pass(apply_patchfile(
298 FILE_ORIGINAL
, strlen(FILE_ORIGINAL
),
299 FILE_CHANGE_MIDDLE
, strlen(FILE_CHANGE_MIDDLE
),
300 PATCH_NOISY
, "file.txt", 0100644));
303 void test_apply_fromfile__noisy_nocontext(void)
305 cl_git_pass(apply_patchfile(
306 FILE_ORIGINAL
, strlen(FILE_ORIGINAL
),
307 FILE_CHANGE_MIDDLE
, strlen(FILE_CHANGE_MIDDLE
),
308 PATCH_NOISY_NOCONTEXT
, "file.txt", 0100644));
311 void test_apply_fromfile__fail_truncated_1(void)
314 cl_git_fail(git_patch_from_buffer(&patch
, PATCH_TRUNCATED_1
,
315 strlen(PATCH_TRUNCATED_1
), NULL
));
318 void test_apply_fromfile__fail_truncated_2(void)
321 cl_git_fail(git_patch_from_buffer(&patch
, PATCH_TRUNCATED_2
,
322 strlen(PATCH_TRUNCATED_2
), NULL
));
325 void test_apply_fromfile__fail_truncated_3(void)
328 cl_git_fail(git_patch_from_buffer(&patch
, PATCH_TRUNCATED_3
,
329 strlen(PATCH_TRUNCATED_3
), NULL
));
332 void test_apply_fromfile__fail_corrupt_githeader(void)
335 cl_git_fail(git_patch_from_buffer(&patch
, PATCH_CORRUPT_GIT_HEADER
,
336 strlen(PATCH_CORRUPT_GIT_HEADER
), NULL
));
339 void test_apply_fromfile__empty_context(void)
341 cl_git_pass(apply_patchfile(
342 FILE_EMPTY_CONTEXT_ORIGINAL
, strlen(FILE_EMPTY_CONTEXT_ORIGINAL
),
343 FILE_EMPTY_CONTEXT_MODIFIED
, strlen(FILE_EMPTY_CONTEXT_MODIFIED
),
345 "file.txt", 0100644));
348 void test_apply_fromfile__append_no_nl(void)
350 cl_git_pass(validate_and_apply_patchfile(
351 FILE_ORIGINAL
, strlen(FILE_ORIGINAL
),
352 FILE_APPEND_NO_NL
, strlen(FILE_APPEND_NO_NL
),
353 PATCH_APPEND_NO_NL
, NULL
, "file.txt", 0100644));
356 void test_apply_fromfile__fail_missing_new_file(void)
359 cl_git_fail(git_patch_from_buffer(&patch
,
360 PATCH_CORRUPT_MISSING_NEW_FILE
,
361 strlen(PATCH_CORRUPT_MISSING_NEW_FILE
), NULL
));
364 void test_apply_fromfile__fail_missing_old_file(void)
367 cl_git_fail(git_patch_from_buffer(&patch
,
368 PATCH_CORRUPT_MISSING_OLD_FILE
,
369 strlen(PATCH_CORRUPT_MISSING_OLD_FILE
), NULL
));
372 void test_apply_fromfile__fail_no_changes(void)
375 cl_git_fail(git_patch_from_buffer(&patch
,
376 PATCH_CORRUPT_NO_CHANGES
,
377 strlen(PATCH_CORRUPT_NO_CHANGES
), NULL
));
380 void test_apply_fromfile__fail_missing_hunk_header(void)
383 cl_git_fail(git_patch_from_buffer(&patch
,
384 PATCH_CORRUPT_MISSING_HUNK_HEADER
,
385 strlen(PATCH_CORRUPT_MISSING_HUNK_HEADER
), NULL
));
388 void test_apply_fromfile__fail_not_a_patch(void)
391 cl_git_fail(git_patch_from_buffer(&patch
, PATCH_NOT_A_PATCH
,
392 strlen(PATCH_NOT_A_PATCH
), NULL
));
395 void test_apply_fromfile__binary_add(void)
397 cl_git_pass(apply_patchfile(
399 FILE_BINARY_DELTA_MODIFIED
, FILE_BINARY_DELTA_MODIFIED_LEN
,
400 PATCH_BINARY_ADD
, "binary.bin", 0100644));
403 void test_apply_fromfile__binary_change_delta(void)
405 cl_git_pass(apply_patchfile(
406 FILE_BINARY_DELTA_ORIGINAL
, FILE_BINARY_DELTA_ORIGINAL_LEN
,
407 FILE_BINARY_DELTA_MODIFIED
, FILE_BINARY_DELTA_MODIFIED_LEN
,
408 PATCH_BINARY_DELTA
, "binary.bin", 0100644));
411 void test_apply_fromfile__binary_change_literal(void)
413 cl_git_pass(apply_patchfile(
414 FILE_BINARY_LITERAL_ORIGINAL
, FILE_BINARY_LITERAL_ORIGINAL_LEN
,
415 FILE_BINARY_LITERAL_MODIFIED
, FILE_BINARY_LITERAL_MODIFIED_LEN
,
416 PATCH_BINARY_LITERAL
, "binary.bin", 0100644));
419 void test_apply_fromfile__binary_delete(void)
421 cl_git_pass(apply_patchfile(
422 FILE_BINARY_DELTA_MODIFIED
, FILE_BINARY_DELTA_MODIFIED_LEN
,
424 PATCH_BINARY_DELETE
, NULL
, 0));
427 void test_apply_fromfile__binary_change_does_not_apply(void)
429 /* try to apply patch backwards, ensure it does not apply */
430 cl_git_fail(apply_patchfile(
431 FILE_BINARY_DELTA_MODIFIED
, FILE_BINARY_DELTA_MODIFIED_LEN
,
432 FILE_BINARY_DELTA_ORIGINAL
, FILE_BINARY_DELTA_ORIGINAL_LEN
,
433 PATCH_BINARY_DELTA
, "binary.bin", 0100644));
436 void test_apply_fromfile__binary_change_must_be_reversible(void)
438 cl_git_fail(apply_patchfile(
439 FILE_BINARY_DELTA_MODIFIED
, FILE_BINARY_DELTA_MODIFIED_LEN
,
441 PATCH_BINARY_NOT_REVERSIBLE
, NULL
, 0));
444 void test_apply_fromfile__empty_file_not_allowed(void)
448 cl_git_fail(git_patch_from_buffer(&patch
, "", 0, NULL
));
449 cl_git_fail(git_patch_from_buffer(&patch
, NULL
, 0, NULL
));