]> git.proxmox.com Git - libgit2.git/blob - tests/apply/fromfile.c
apply: move patch data to patch_common.h
[libgit2.git] / tests / apply / fromfile.c
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
8 #include "../patch/patch_common.h"
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,
24 size_t old_len,
25 const char *new,
26 size_t new_len,
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
40 error = git_apply__patch(&result, &filename, &mode, old, old_len, patch);
41
42 if (error == 0) {
43 cl_assert_equal_i(new_len, result.size);
44 cl_assert(memcmp(new, result.ptr, new_len) == 0);
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,
60 size_t old_len,
61 const char *new,
62 size_t new_len,
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,
73 old, old_len, "file.txt",
74 new, new_len, "file.txt",
75 diff_opts));
76 cl_git_pass(git_patch_to_buf(&validated, patch_fromdiff));
77
78 cl_assert_equal_s(patchfile, validated.ptr);
79
80 error = apply_patchfile(old, old_len, new, new_len, patchfile, filename_expected, mode_expected);
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 {
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,
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
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,
106 &diff_opts, "b/file.txt", 0100644));
107 }
108
109
110 void test_apply_fromfile__change_firstline(void)
111 {
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,
116 "b/file.txt", 0100644));
117 }
118
119 void test_apply_fromfile__lastline(void)
120 {
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,
125 "b/file.txt", 0100644));
126 }
127
128 void test_apply_fromfile__prepend(void)
129 {
130 cl_git_pass(validate_and_apply_patchfile(
131 FILE_ORIGINAL, strlen(FILE_ORIGINAL),
132 FILE_PREPEND, strlen(FILE_PREPEND),
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
141 cl_git_pass(validate_and_apply_patchfile(
142 FILE_ORIGINAL, strlen(FILE_ORIGINAL),
143 FILE_PREPEND, strlen(FILE_PREPEND),
144 PATCH_ORIGINAL_TO_PREPEND_NOCONTEXT, &diff_opts,
145 "b/file.txt", 0100644));
146 }
147
148 void test_apply_fromfile__append(void)
149 {
150 cl_git_pass(validate_and_apply_patchfile(
151 FILE_ORIGINAL, strlen(FILE_ORIGINAL),
152 FILE_APPEND, strlen(FILE_APPEND),
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
161 cl_git_pass(validate_and_apply_patchfile(
162 FILE_ORIGINAL, strlen(FILE_ORIGINAL),
163 FILE_APPEND, strlen(FILE_APPEND),
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 {
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,
174 "b/file.txt", 0100644));
175 }
176
177 void test_apply_fromfile__to_empty_file(void)
178 {
179 cl_git_pass(validate_and_apply_patchfile(
180 FILE_ORIGINAL, strlen(FILE_ORIGINAL),
181 "", 0,
182 PATCH_ORIGINAL_TO_EMPTY_FILE, NULL, "b/file.txt", 0100644));
183 }
184
185 void test_apply_fromfile__from_empty_file(void)
186 {
187 cl_git_pass(validate_and_apply_patchfile(
188 "", 0,
189 FILE_ORIGINAL, strlen(FILE_ORIGINAL),
190 PATCH_EMPTY_FILE_TO_ORIGINAL, NULL, "b/file.txt", 0100644));
191 }
192
193 void test_apply_fromfile__add(void)
194 {
195 cl_git_pass(validate_and_apply_patchfile(
196 NULL, 0,
197 FILE_ORIGINAL, strlen(FILE_ORIGINAL),
198 PATCH_ADD_ORIGINAL, NULL, "b/file.txt", 0100644));
199 }
200
201 void test_apply_fromfile__delete(void)
202 {
203 cl_git_pass(validate_and_apply_patchfile(
204 FILE_ORIGINAL, strlen(FILE_ORIGINAL),
205 NULL, 0,
206 PATCH_DELETE_ORIGINAL, NULL, NULL, 0));
207 }
208
209
210 void test_apply_fromfile__rename_exact(void)
211 {
212 cl_git_pass(apply_patchfile(
213 FILE_ORIGINAL, strlen(FILE_ORIGINAL),
214 FILE_ORIGINAL, strlen(FILE_ORIGINAL),
215 PATCH_RENAME_EXACT, "b/newfile.txt", 0100644));
216 }
217
218 void test_apply_fromfile__rename_similar(void)
219 {
220 cl_git_pass(apply_patchfile(
221 FILE_ORIGINAL, strlen(FILE_ORIGINAL),
222 FILE_CHANGE_MIDDLE, strlen(FILE_CHANGE_MIDDLE),
223 PATCH_RENAME_SIMILAR, "b/newfile.txt", 0100644));
224 }
225
226 void test_apply_fromfile__rename_similar_quotedname(void)
227 {
228 cl_git_pass(apply_patchfile(
229 FILE_ORIGINAL, strlen(FILE_ORIGINAL),
230 FILE_CHANGE_MIDDLE, strlen(FILE_CHANGE_MIDDLE),
231 PATCH_RENAME_SIMILAR_QUOTEDNAME, "b/foo\"bar.txt", 0100644));
232 }
233
234 void test_apply_fromfile__modechange(void)
235 {
236 cl_git_pass(apply_patchfile(
237 FILE_ORIGINAL, strlen(FILE_ORIGINAL),
238 FILE_ORIGINAL, strlen(FILE_ORIGINAL),
239 PATCH_MODECHANGE_UNCHANGED, "b/file.txt", 0100755));
240 }
241
242 void test_apply_fromfile__modechange_with_modification(void)
243 {
244 cl_git_pass(apply_patchfile(
245 FILE_ORIGINAL, strlen(FILE_ORIGINAL),
246 FILE_CHANGE_MIDDLE, strlen(FILE_CHANGE_MIDDLE),
247 PATCH_MODECHANGE_MODIFIED, "b/file.txt", 0100755));
248 }
249
250 void test_apply_fromfile__noisy(void)
251 {
252 cl_git_pass(apply_patchfile(
253 FILE_ORIGINAL, strlen(FILE_ORIGINAL),
254 FILE_CHANGE_MIDDLE, strlen(FILE_CHANGE_MIDDLE),
255 PATCH_NOISY, "b/file.txt", 0100644));
256 }
257
258 void test_apply_fromfile__noisy_nocontext(void)
259 {
260 cl_git_pass(apply_patchfile(
261 FILE_ORIGINAL, strlen(FILE_ORIGINAL),
262 FILE_CHANGE_MIDDLE, strlen(FILE_CHANGE_MIDDLE),
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 {
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,
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(
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));
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 }
349
350 void test_apply_fromfile__binary_add(void)
351 {
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 }
357
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 }
365
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 }
373
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 }
381
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 }
390
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));
397 }
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 }