]>
Commit | Line | Data |
---|---|---|
d34f6826 ET |
1 | #include "clar_libgit2.h" |
2 | #include "git2/sys/repository.h" | |
3 | ||
4 | #include "apply.h" | |
5 | #include "repository.h" | |
6 | #include "buf_text.h" | |
7 | ||
8bca8b9e | 8 | #include "../patch/patch_common.h" |
d34f6826 ET |
9 | |
10 | static git_repository *repo = NULL; | |
11 | ||
12 | void test_apply_fromfile__initialize(void) | |
13 | { | |
14 | repo = cl_git_sandbox_init("renames"); | |
15 | } | |
16 | ||
17 | void test_apply_fromfile__cleanup(void) | |
18 | { | |
19 | cl_git_sandbox_cleanup(); | |
20 | } | |
21 | ||
22 | static int apply_patchfile( | |
23 | const char *old, | |
5d17d726 | 24 | size_t old_len, |
d34f6826 | 25 | const char *new, |
5d17d726 | 26 | size_t new_len, |
d34f6826 ET |
27 | const char *patchfile, |
28 | const char *filename_expected, | |
29 | unsigned int mode_expected) | |
30 | { | |
31 | git_patch *patch; | |
32 | git_buf result = GIT_BUF_INIT; | |
33 | git_buf patchbuf = GIT_BUF_INIT; | |
34 | char *filename; | |
35 | unsigned int mode; | |
36 | int error; | |
37 | ||
38 | cl_git_pass(git_patch_from_patchfile(&patch, patchfile, strlen(patchfile))); | |
39 | ||
5d17d726 | 40 | error = git_apply__patch(&result, &filename, &mode, old, old_len, patch); |
d34f6826 ET |
41 | |
42 | if (error == 0) { | |
5d17d726 ET |
43 | cl_assert_equal_i(new_len, result.size); |
44 | cl_assert(memcmp(new, result.ptr, new_len) == 0); | |
d34f6826 ET |
45 | |
46 | cl_assert_equal_s(filename_expected, filename); | |
47 | cl_assert_equal_i(mode_expected, mode); | |
48 | } | |
49 | ||
50 | git__free(filename); | |
51 | git_buf_free(&result); | |
52 | git_buf_free(&patchbuf); | |
53 | git_patch_free(patch); | |
54 | ||
55 | return error; | |
56 | } | |
57 | ||
58 | static int validate_and_apply_patchfile( | |
59 | const char *old, | |
5d17d726 | 60 | size_t old_len, |
d34f6826 | 61 | const char *new, |
5d17d726 | 62 | size_t new_len, |
d34f6826 ET |
63 | const char *patchfile, |
64 | const git_diff_options *diff_opts, | |
65 | const char *filename_expected, | |
66 | unsigned int mode_expected) | |
67 | { | |
68 | git_patch *patch_fromdiff; | |
69 | git_buf validated = GIT_BUF_INIT; | |
70 | int error; | |
71 | ||
72 | cl_git_pass(git_patch_from_buffers(&patch_fromdiff, | |
5d17d726 ET |
73 | old, old_len, "file.txt", |
74 | new, new_len, "file.txt", | |
d34f6826 ET |
75 | diff_opts)); |
76 | cl_git_pass(git_patch_to_buf(&validated, patch_fromdiff)); | |
77 | ||
78 | cl_assert_equal_s(patchfile, validated.ptr); | |
79 | ||
5d17d726 | 80 | error = apply_patchfile(old, old_len, new, new_len, patchfile, filename_expected, mode_expected); |
d34f6826 ET |
81 | |
82 | git_buf_free(&validated); | |
83 | git_patch_free(patch_fromdiff); | |
84 | ||
85 | return error; | |
86 | } | |
87 | ||
88 | void test_apply_fromfile__change_middle(void) | |
89 | { | |
5d17d726 ET |
90 | cl_git_pass(validate_and_apply_patchfile( |
91 | FILE_ORIGINAL, strlen(FILE_ORIGINAL), | |
92 | FILE_CHANGE_MIDDLE, strlen(FILE_CHANGE_MIDDLE), | |
93 | PATCH_ORIGINAL_TO_CHANGE_MIDDLE, NULL, | |
d34f6826 ET |
94 | "b/file.txt", 0100644)); |
95 | } | |
96 | ||
97 | void test_apply_fromfile__change_middle_nocontext(void) | |
98 | { | |
99 | git_diff_options diff_opts = GIT_DIFF_OPTIONS_INIT; | |
100 | diff_opts.context_lines = 0; | |
101 | ||
5d17d726 ET |
102 | cl_git_pass(validate_and_apply_patchfile( |
103 | FILE_ORIGINAL, strlen(FILE_ORIGINAL), | |
104 | FILE_CHANGE_MIDDLE, strlen(FILE_CHANGE_MIDDLE), | |
105 | PATCH_ORIGINAL_TO_CHANGE_MIDDLE_NOCONTEXT, | |
d34f6826 ET |
106 | &diff_opts, "b/file.txt", 0100644)); |
107 | } | |
108 | ||
804d5fe9 | 109 | |
d34f6826 ET |
110 | void test_apply_fromfile__change_firstline(void) |
111 | { | |
5d17d726 ET |
112 | cl_git_pass(validate_and_apply_patchfile( |
113 | FILE_ORIGINAL, strlen(FILE_ORIGINAL), | |
114 | FILE_CHANGE_FIRSTLINE, strlen(FILE_CHANGE_FIRSTLINE), | |
115 | PATCH_ORIGINAL_TO_CHANGE_FIRSTLINE, NULL, | |
d34f6826 ET |
116 | "b/file.txt", 0100644)); |
117 | } | |
118 | ||
119 | void test_apply_fromfile__lastline(void) | |
120 | { | |
5d17d726 ET |
121 | cl_git_pass(validate_and_apply_patchfile( |
122 | FILE_ORIGINAL, strlen(FILE_ORIGINAL), | |
123 | FILE_CHANGE_LASTLINE, strlen(FILE_CHANGE_LASTLINE), | |
124 | PATCH_ORIGINAL_TO_CHANGE_LASTLINE, NULL, | |
d34f6826 ET |
125 | "b/file.txt", 0100644)); |
126 | } | |
127 | ||
128 | void test_apply_fromfile__prepend(void) | |
129 | { | |
5d17d726 ET |
130 | cl_git_pass(validate_and_apply_patchfile( |
131 | FILE_ORIGINAL, strlen(FILE_ORIGINAL), | |
132 | FILE_PREPEND, strlen(FILE_PREPEND), | |
d34f6826 ET |
133 | PATCH_ORIGINAL_TO_PREPEND, NULL, "b/file.txt", 0100644)); |
134 | } | |
135 | ||
136 | void test_apply_fromfile__prepend_nocontext(void) | |
137 | { | |
138 | git_diff_options diff_opts = GIT_DIFF_OPTIONS_INIT; | |
139 | diff_opts.context_lines = 0; | |
140 | ||
5d17d726 ET |
141 | cl_git_pass(validate_and_apply_patchfile( |
142 | FILE_ORIGINAL, strlen(FILE_ORIGINAL), | |
143 | FILE_PREPEND, strlen(FILE_PREPEND), | |
d34f6826 ET |
144 | PATCH_ORIGINAL_TO_PREPEND_NOCONTEXT, &diff_opts, |
145 | "b/file.txt", 0100644)); | |
146 | } | |
147 | ||
148 | void test_apply_fromfile__append(void) | |
149 | { | |
5d17d726 ET |
150 | cl_git_pass(validate_and_apply_patchfile( |
151 | FILE_ORIGINAL, strlen(FILE_ORIGINAL), | |
152 | FILE_APPEND, strlen(FILE_APPEND), | |
d34f6826 ET |
153 | PATCH_ORIGINAL_TO_APPEND, NULL, "b/file.txt", 0100644)); |
154 | } | |
155 | ||
156 | void test_apply_fromfile__append_nocontext(void) | |
157 | { | |
158 | git_diff_options diff_opts = GIT_DIFF_OPTIONS_INIT; | |
159 | diff_opts.context_lines = 0; | |
160 | ||
5d17d726 ET |
161 | cl_git_pass(validate_and_apply_patchfile( |
162 | FILE_ORIGINAL, strlen(FILE_ORIGINAL), | |
163 | FILE_APPEND, strlen(FILE_APPEND), | |
d34f6826 ET |
164 | PATCH_ORIGINAL_TO_APPEND_NOCONTEXT, &diff_opts, |
165 | "b/file.txt", 0100644)); | |
166 | } | |
167 | ||
168 | void test_apply_fromfile__prepend_and_append(void) | |
169 | { | |
5d17d726 ET |
170 | cl_git_pass(validate_and_apply_patchfile( |
171 | FILE_ORIGINAL, strlen(FILE_ORIGINAL), | |
172 | FILE_PREPEND_AND_APPEND, strlen(FILE_PREPEND_AND_APPEND), | |
173 | PATCH_ORIGINAL_TO_PREPEND_AND_APPEND, NULL, | |
d34f6826 ET |
174 | "b/file.txt", 0100644)); |
175 | } | |
176 | ||
177 | void test_apply_fromfile__to_empty_file(void) | |
178 | { | |
5d17d726 ET |
179 | cl_git_pass(validate_and_apply_patchfile( |
180 | FILE_ORIGINAL, strlen(FILE_ORIGINAL), | |
181 | "", 0, | |
d34f6826 ET |
182 | PATCH_ORIGINAL_TO_EMPTY_FILE, NULL, "b/file.txt", 0100644)); |
183 | } | |
184 | ||
185 | void test_apply_fromfile__from_empty_file(void) | |
186 | { | |
5d17d726 ET |
187 | cl_git_pass(validate_and_apply_patchfile( |
188 | "", 0, | |
189 | FILE_ORIGINAL, strlen(FILE_ORIGINAL), | |
d34f6826 ET |
190 | PATCH_EMPTY_FILE_TO_ORIGINAL, NULL, "b/file.txt", 0100644)); |
191 | } | |
192 | ||
193 | void test_apply_fromfile__add(void) | |
194 | { | |
5d17d726 ET |
195 | cl_git_pass(validate_and_apply_patchfile( |
196 | NULL, 0, | |
197 | FILE_ORIGINAL, strlen(FILE_ORIGINAL), | |
d34f6826 ET |
198 | PATCH_ADD_ORIGINAL, NULL, "b/file.txt", 0100644)); |
199 | } | |
200 | ||
201 | void test_apply_fromfile__delete(void) | |
202 | { | |
5d17d726 ET |
203 | cl_git_pass(validate_and_apply_patchfile( |
204 | FILE_ORIGINAL, strlen(FILE_ORIGINAL), | |
205 | NULL, 0, | |
d34f6826 ET |
206 | PATCH_DELETE_ORIGINAL, NULL, NULL, 0)); |
207 | } | |
208 | ||
209 | ||
210 | void test_apply_fromfile__rename_exact(void) | |
211 | { | |
5d17d726 ET |
212 | cl_git_pass(apply_patchfile( |
213 | FILE_ORIGINAL, strlen(FILE_ORIGINAL), | |
214 | FILE_ORIGINAL, strlen(FILE_ORIGINAL), | |
d34f6826 ET |
215 | PATCH_RENAME_EXACT, "b/newfile.txt", 0100644)); |
216 | } | |
217 | ||
218 | void test_apply_fromfile__rename_similar(void) | |
219 | { | |
5d17d726 ET |
220 | cl_git_pass(apply_patchfile( |
221 | FILE_ORIGINAL, strlen(FILE_ORIGINAL), | |
222 | FILE_CHANGE_MIDDLE, strlen(FILE_CHANGE_MIDDLE), | |
d34f6826 ET |
223 | PATCH_RENAME_SIMILAR, "b/newfile.txt", 0100644)); |
224 | } | |
225 | ||
226 | void test_apply_fromfile__rename_similar_quotedname(void) | |
227 | { | |
5d17d726 ET |
228 | cl_git_pass(apply_patchfile( |
229 | FILE_ORIGINAL, strlen(FILE_ORIGINAL), | |
230 | FILE_CHANGE_MIDDLE, strlen(FILE_CHANGE_MIDDLE), | |
d34f6826 ET |
231 | PATCH_RENAME_SIMILAR_QUOTEDNAME, "b/foo\"bar.txt", 0100644)); |
232 | } | |
233 | ||
234 | void test_apply_fromfile__modechange(void) | |
235 | { | |
5d17d726 ET |
236 | cl_git_pass(apply_patchfile( |
237 | FILE_ORIGINAL, strlen(FILE_ORIGINAL), | |
238 | FILE_ORIGINAL, strlen(FILE_ORIGINAL), | |
d34f6826 ET |
239 | PATCH_MODECHANGE_UNCHANGED, "b/file.txt", 0100755)); |
240 | } | |
241 | ||
242 | void test_apply_fromfile__modechange_with_modification(void) | |
243 | { | |
5d17d726 ET |
244 | cl_git_pass(apply_patchfile( |
245 | FILE_ORIGINAL, strlen(FILE_ORIGINAL), | |
246 | FILE_CHANGE_MIDDLE, strlen(FILE_CHANGE_MIDDLE), | |
d34f6826 ET |
247 | PATCH_MODECHANGE_MODIFIED, "b/file.txt", 0100755)); |
248 | } | |
249 | ||
250 | void test_apply_fromfile__noisy(void) | |
251 | { | |
5d17d726 ET |
252 | cl_git_pass(apply_patchfile( |
253 | FILE_ORIGINAL, strlen(FILE_ORIGINAL), | |
254 | FILE_CHANGE_MIDDLE, strlen(FILE_CHANGE_MIDDLE), | |
d34f6826 ET |
255 | PATCH_NOISY, "b/file.txt", 0100644)); |
256 | } | |
257 | ||
258 | void test_apply_fromfile__noisy_nocontext(void) | |
259 | { | |
5d17d726 ET |
260 | cl_git_pass(apply_patchfile( |
261 | FILE_ORIGINAL, strlen(FILE_ORIGINAL), | |
262 | FILE_CHANGE_MIDDLE, strlen(FILE_CHANGE_MIDDLE), | |
d34f6826 ET |
263 | PATCH_NOISY_NOCONTEXT, "b/file.txt", 0100644)); |
264 | } | |
265 | ||
266 | void test_apply_fromfile__fail_truncated_1(void) | |
267 | { | |
268 | git_patch *patch; | |
269 | cl_git_fail(git_patch_from_patchfile(&patch, PATCH_TRUNCATED_1, | |
270 | strlen(PATCH_TRUNCATED_1))); | |
271 | } | |
272 | ||
273 | void test_apply_fromfile__fail_truncated_2(void) | |
274 | { | |
275 | git_patch *patch; | |
276 | cl_git_fail(git_patch_from_patchfile(&patch, PATCH_TRUNCATED_2, | |
277 | strlen(PATCH_TRUNCATED_2))); | |
278 | } | |
279 | ||
280 | void test_apply_fromfile__fail_truncated_3(void) | |
281 | { | |
282 | git_patch *patch; | |
283 | cl_git_fail(git_patch_from_patchfile(&patch, PATCH_TRUNCATED_3, | |
284 | strlen(PATCH_TRUNCATED_3))); | |
285 | } | |
286 | ||
287 | void test_apply_fromfile__fail_corrupt_githeader(void) | |
288 | { | |
289 | git_patch *patch; | |
290 | cl_git_fail(git_patch_from_patchfile(&patch, PATCH_CORRUPT_GIT_HEADER, | |
291 | strlen(PATCH_CORRUPT_GIT_HEADER))); | |
292 | } | |
293 | ||
294 | void test_apply_fromfile__empty_context(void) | |
295 | { | |
5d17d726 ET |
296 | cl_git_pass(apply_patchfile( |
297 | FILE_EMPTY_CONTEXT_ORIGINAL, strlen(FILE_EMPTY_CONTEXT_ORIGINAL), | |
298 | FILE_EMPTY_CONTEXT_MODIFIED, strlen(FILE_EMPTY_CONTEXT_MODIFIED), | |
299 | PATCH_EMPTY_CONTEXT, | |
d34f6826 ET |
300 | "b/file.txt", 0100644)); |
301 | } | |
302 | ||
303 | void test_apply_fromfile__append_no_nl(void) | |
304 | { | |
305 | cl_git_pass(validate_and_apply_patchfile( | |
5d17d726 ET |
306 | FILE_ORIGINAL, strlen(FILE_ORIGINAL), |
307 | FILE_APPEND_NO_NL, strlen(FILE_APPEND_NO_NL), | |
308 | PATCH_APPEND_NO_NL, NULL, "b/file.txt", 0100644)); | |
d34f6826 ET |
309 | } |
310 | ||
311 | void test_apply_fromfile__fail_missing_new_file(void) | |
312 | { | |
313 | git_patch *patch; | |
314 | cl_git_fail(git_patch_from_patchfile(&patch, | |
315 | PATCH_CORRUPT_MISSING_NEW_FILE, | |
316 | strlen(PATCH_CORRUPT_MISSING_NEW_FILE))); | |
317 | } | |
318 | ||
319 | void test_apply_fromfile__fail_missing_old_file(void) | |
320 | { | |
321 | git_patch *patch; | |
322 | cl_git_fail(git_patch_from_patchfile(&patch, | |
323 | PATCH_CORRUPT_MISSING_OLD_FILE, | |
324 | strlen(PATCH_CORRUPT_MISSING_OLD_FILE))); | |
325 | } | |
326 | ||
327 | void test_apply_fromfile__fail_no_changes(void) | |
328 | { | |
329 | git_patch *patch; | |
330 | cl_git_fail(git_patch_from_patchfile(&patch, | |
331 | PATCH_CORRUPT_NO_CHANGES, | |
332 | strlen(PATCH_CORRUPT_NO_CHANGES))); | |
333 | } | |
334 | ||
335 | void test_apply_fromfile__fail_missing_hunk_header(void) | |
336 | { | |
337 | git_patch *patch; | |
338 | cl_git_fail(git_patch_from_patchfile(&patch, | |
339 | PATCH_CORRUPT_MISSING_HUNK_HEADER, | |
340 | strlen(PATCH_CORRUPT_MISSING_HUNK_HEADER))); | |
341 | } | |
342 | ||
343 | void test_apply_fromfile__fail_not_a_patch(void) | |
344 | { | |
345 | git_patch *patch; | |
346 | cl_git_fail(git_patch_from_patchfile(&patch, PATCH_NOT_A_PATCH, | |
347 | strlen(PATCH_NOT_A_PATCH))); | |
348 | } | |
3149ff6f | 349 | |
5d17d726 | 350 | void test_apply_fromfile__binary_add(void) |
3149ff6f | 351 | { |
5d17d726 ET |
352 | cl_git_pass(apply_patchfile( |
353 | NULL, 0, | |
354 | FILE_BINARY_DELTA_MODIFIED, FILE_BINARY_DELTA_MODIFIED_LEN, | |
355 | PATCH_BINARY_ADD, "b/binary.bin", 0100644)); | |
356 | } | |
3149ff6f | 357 | |
5d17d726 ET |
358 | void test_apply_fromfile__binary_change_delta(void) |
359 | { | |
360 | cl_git_pass(apply_patchfile( | |
361 | FILE_BINARY_DELTA_ORIGINAL, FILE_BINARY_DELTA_ORIGINAL_LEN, | |
362 | FILE_BINARY_DELTA_MODIFIED, FILE_BINARY_DELTA_MODIFIED_LEN, | |
363 | PATCH_BINARY_DELTA, "b/binary.bin", 0100644)); | |
364 | } | |
3149ff6f | 365 | |
5d17d726 ET |
366 | void test_apply_fromfile__binary_change_literal(void) |
367 | { | |
368 | cl_git_pass(apply_patchfile( | |
369 | FILE_BINARY_LITERAL_ORIGINAL, FILE_BINARY_LITERAL_ORIGINAL_LEN, | |
370 | FILE_BINARY_LITERAL_MODIFIED, FILE_BINARY_LITERAL_MODIFIED_LEN, | |
371 | PATCH_BINARY_LITERAL, "b/binary.bin", 0100644)); | |
372 | } | |
3149ff6f | 373 | |
5d17d726 ET |
374 | void test_apply_fromfile__binary_delete(void) |
375 | { | |
376 | cl_git_pass(apply_patchfile( | |
377 | FILE_BINARY_DELTA_MODIFIED, FILE_BINARY_DELTA_MODIFIED_LEN, | |
378 | NULL, 0, | |
379 | PATCH_BINARY_DELETE, NULL, 0)); | |
380 | } | |
3149ff6f | 381 | |
5d17d726 ET |
382 | void test_apply_fromfile__binary_change_does_not_apply(void) |
383 | { | |
384 | /* try to apply patch backwards, ensure it does not apply */ | |
385 | cl_git_fail(apply_patchfile( | |
386 | FILE_BINARY_DELTA_MODIFIED, FILE_BINARY_DELTA_MODIFIED_LEN, | |
387 | FILE_BINARY_DELTA_ORIGINAL, FILE_BINARY_DELTA_ORIGINAL_LEN, | |
388 | PATCH_BINARY_DELTA, "b/binary.bin", 0100644)); | |
389 | } | |
3149ff6f | 390 | |
5d17d726 ET |
391 | void test_apply_fromfile__binary_change_must_be_reversible(void) |
392 | { | |
393 | cl_git_fail(apply_patchfile( | |
394 | FILE_BINARY_DELTA_MODIFIED, FILE_BINARY_DELTA_MODIFIED_LEN, | |
395 | NULL, 0, | |
396 | PATCH_BINARY_NOT_REVERSIBLE, NULL, 0)); | |
3149ff6f | 397 | } |
8d2eef27 ET |
398 | |
399 | void test_apply_fromfile__empty_file_not_allowed(void) | |
400 | { | |
401 | git_patch *patch; | |
402 | ||
403 | cl_git_fail(git_patch_from_patchfile(&patch, "", 0)); | |
404 | cl_git_fail(git_patch_from_patchfile(&patch, NULL, 0)); | |
405 | } |