]> git.proxmox.com Git - libgit2.git/blame - tests/diff/blob.c
New upstream version 1.4.3+dfsg.1
[libgit2.git] / tests / diff / blob.c
CommitLineData
3a437590
RB
1#include "clar_libgit2.h"
2#include "diff_helpers.h"
3
eae0bfdc
PP
4#define BLOB_DIFF \
5 "diff --git a/file b/file\n" \
6 "index 45141a7..4d713dc 100644\n" \
7 "--- a/file\n" \
8 "+++ b/file\n" \
9 "@@ -1 +1,6 @@\n" \
10 " Hello from the root\n" \
11 "+\n" \
12 "+Some additional lines\n" \
13 "+\n" \
14 "+Down here below\n" \
15 "+\n"
16
3a437590 17static git_repository *g_repo = NULL;
1956693f 18static diff_expects expected;
4f806761 19static git_diff_options opts;
28ef7f9b 20static git_blob *d, *alien;
3a437590 21
74ded024
RB
22static void quick_diff_blob_to_str(
23 const git_blob *blob, const char *blob_path,
24 const char *str, size_t len, const char *str_path)
25{
26 memset(&expected, 0, sizeof(expected));
27
28 if (str && !len)
29 len = strlen(str);
30
31 cl_git_pass(git_diff_blob_to_buffer(
32 blob, blob_path, str, len, str_path,
8147b1af 33 &opts, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &expected));
74ded024
RB
34}
35
3a437590
RB
36void test_diff_blob__initialize(void)
37{
28ef7f9b 38 git_oid oid;
4f806761 39
854eccbb 40 g_repo = cl_git_sandbox_init("attr");
4f806761 41
22a2d3d5 42 cl_git_pass(git_diff_options_init(&opts, GIT_DIFF_OPTIONS_VERSION));
4f806761 43 opts.context_lines = 1;
4f806761 44
1956693f 45 memset(&expected, 0, sizeof(expected));
4f806761 46
47 /* tests/resources/attr/root_test4.txt */
29f9186d 48 cl_git_pass(git_oid_fromstrn(&oid, "a0f7217a", 8));
13e5e344 49 cl_git_pass(git_blob_lookup_prefix(&d, g_repo, &oid, 8));
28ef7f9b 50
51 /* alien.png */
52 cl_git_pass(git_oid_fromstrn(&oid, "edf3dcee", 8));
13e5e344 53 cl_git_pass(git_blob_lookup_prefix(&alien, g_repo, &oid, 8));
3a437590
RB
54}
55
56void test_diff_blob__cleanup(void)
57{
4f806761 58 git_blob_free(d);
9094d30b
SC
59 d = NULL;
60
28ef7f9b 61 git_blob_free(alien);
9094d30b 62 alien = NULL;
4f806761 63
854eccbb 64 cl_git_sandbox_cleanup();
3a437590
RB
65}
66
6789b7a7
RB
67static void assert_one_modified(
68 int hunks, int lines, int ctxt, int adds, int dels, diff_expects *exp)
69{
70 cl_assert_equal_i(1, exp->files);
71 cl_assert_equal_i(1, exp->file_status[GIT_DELTA_MODIFIED]);
72 cl_assert_equal_i(0, exp->files_binary);
73
74 cl_assert_equal_i(hunks, exp->hunks);
75 cl_assert_equal_i(lines, exp->lines);
76 cl_assert_equal_i(ctxt, exp->line_ctxt);
77 cl_assert_equal_i(adds, exp->line_adds);
78 cl_assert_equal_i(dels, exp->line_dels);
79}
80
eae0bfdc
PP
81void test_diff_blob__patch_with_freed_blobs(void)
82{
83 git_oid a_oid, b_oid;
84 git_blob *a, *b;
85 git_patch *p;
86 git_buf buf = GIT_BUF_INIT;
87
88 /* tests/resources/attr/root_test1 */
89 cl_git_pass(git_oid_fromstrn(&a_oid, "45141a79", 8));
90 cl_git_pass(git_blob_lookup_prefix(&a, g_repo, &a_oid, 4));
91 /* tests/resources/attr/root_test2 */
92 cl_git_pass(git_oid_fromstrn(&b_oid, "4d713dc4", 8));
93 cl_git_pass(git_blob_lookup_prefix(&b, g_repo, &b_oid, 4));
94
95 cl_git_pass(git_patch_from_blobs(&p, a, NULL, b, NULL, NULL));
96
97 git_blob_free(a);
98 git_blob_free(b);
99
100 cl_git_pass(git_patch_to_buf(&buf, p));
101 cl_assert_equal_s(buf.ptr, BLOB_DIFF);
102
103 git_patch_free(p);
ac3d33df 104 git_buf_dispose(&buf);
eae0bfdc
PP
105}
106
245c5eae 107void test_diff_blob__can_compare_text_blobs(void)
3a437590 108{
4f806761 109 git_blob *a, *b, *c;
110 git_oid a_oid, b_oid, c_oid;
3a437590
RB
111
112 /* tests/resources/attr/root_test1 */
113 cl_git_pass(git_oid_fromstrn(&a_oid, "45141a79", 8));
114 cl_git_pass(git_blob_lookup_prefix(&a, g_repo, &a_oid, 4));
115
116 /* tests/resources/attr/root_test2 */
117 cl_git_pass(git_oid_fromstrn(&b_oid, "4d713dc4", 8));
118 cl_git_pass(git_blob_lookup_prefix(&b, g_repo, &b_oid, 4));
119
120 /* tests/resources/attr/root_test3 */
121 cl_git_pass(git_oid_fromstrn(&c_oid, "c96bbb2c2557a832", 16));
13e5e344 122 cl_git_pass(git_blob_lookup_prefix(&c, g_repo, &c_oid, 16));
3a437590 123
3a437590
RB
124 /* Doing the equivalent of a `git diff -U1` on these files */
125
29f9186d 126 /* diff on tests/resources/attr/root_test1 */
6789b7a7 127 memset(&expected, 0, sizeof(expected));
3a437590 128 cl_git_pass(git_diff_blobs(
74ded024 129 a, NULL, b, NULL, &opts,
8147b1af 130 diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &expected));
6789b7a7 131 assert_one_modified(1, 6, 1, 5, 0, &expected);
28ef7f9b 132
6789b7a7
RB
133 /* same diff but use direct buffers */
134 memset(&expected, 0, sizeof(expected));
135 cl_git_pass(git_diff_buffers(
136 git_blob_rawcontent(a), (size_t)git_blob_rawsize(a), NULL,
137 git_blob_rawcontent(b), (size_t)git_blob_rawsize(b), NULL, &opts,
8147b1af 138 diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &expected));
6789b7a7 139 assert_one_modified(1, 6, 1, 5, 0, &expected);
3a437590 140
29f9186d 141 /* diff on tests/resources/attr/root_test2 */
1956693f 142 memset(&expected, 0, sizeof(expected));
3a437590 143 cl_git_pass(git_diff_blobs(
74ded024 144 b, NULL, c, NULL, &opts,
8147b1af 145 diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &expected));
6789b7a7 146 assert_one_modified(1, 15, 3, 9, 3, &expected);
3a437590 147
29f9186d 148 /* diff on tests/resources/attr/root_test3 */
1956693f 149 memset(&expected, 0, sizeof(expected));
3a437590 150 cl_git_pass(git_diff_blobs(
74ded024 151 a, NULL, c, NULL, &opts,
8147b1af 152 diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &expected));
6789b7a7 153 assert_one_modified(1, 13, 0, 12, 1, &expected);
3a437590 154
1956693f 155 memset(&expected, 0, sizeof(expected));
3a437590 156 cl_git_pass(git_diff_blobs(
74ded024 157 c, NULL, d, NULL, &opts,
8147b1af 158 diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &expected));
6789b7a7 159 assert_one_modified(2, 14, 4, 6, 4, &expected);
3a437590
RB
160
161 git_blob_free(a);
162 git_blob_free(b);
163 git_blob_free(c);
3a437590
RB
164}
165
6789b7a7
RB
166static void assert_patch_matches_blobs(
167 git_patch *p, git_blob *a, git_blob *b,
168 int hunks, int l0, int l1, int ctxt, int adds, int dels)
169{
170 const git_diff_delta *delta;
171 size_t tc, ta, td;
172
173 cl_assert(p != NULL);
174
175 delta = git_patch_get_delta(p);
176 cl_assert(delta != NULL);
177
178 cl_assert_equal_i(GIT_DELTA_MODIFIED, delta->status);
0cee70eb 179 cl_assert_equal_oid(git_blob_id(a), &delta->old_file.id);
6789b7a7 180 cl_assert_equal_sz(git_blob_rawsize(a), delta->old_file.size);
0cee70eb 181 cl_assert_equal_oid(git_blob_id(b), &delta->new_file.id);
6789b7a7
RB
182 cl_assert_equal_sz(git_blob_rawsize(b), delta->new_file.size);
183
184 cl_assert_equal_i(hunks, (int)git_patch_num_hunks(p));
185
186 if (hunks > 0)
187 cl_assert_equal_i(l0, git_patch_num_lines_in_hunk(p, 0));
188 if (hunks > 1)
189 cl_assert_equal_i(l1, git_patch_num_lines_in_hunk(p, 1));
190
191 cl_git_pass(git_patch_line_stats(&tc, &ta, &td, p));
192 cl_assert_equal_i(ctxt, (int)tc);
193 cl_assert_equal_i(adds, (int)ta);
194 cl_assert_equal_i(dels, (int)td);
195}
196
f9c824c5
RB
197void test_diff_blob__can_compare_text_blobs_with_patch(void)
198{
199 git_blob *a, *b, *c;
200 git_oid a_oid, b_oid, c_oid;
3ff1d123 201 git_patch *p;
f9c824c5
RB
202
203 /* tests/resources/attr/root_test1 */
204 cl_git_pass(git_oid_fromstrn(&a_oid, "45141a79", 8));
13e5e344 205 cl_git_pass(git_blob_lookup_prefix(&a, g_repo, &a_oid, 8));
f9c824c5
RB
206
207 /* tests/resources/attr/root_test2 */
208 cl_git_pass(git_oid_fromstrn(&b_oid, "4d713dc4", 8));
13e5e344 209 cl_git_pass(git_blob_lookup_prefix(&b, g_repo, &b_oid, 8));
f9c824c5
RB
210
211 /* tests/resources/attr/root_test3 */
212 cl_git_pass(git_oid_fromstrn(&c_oid, "c96bbb2c2557a832", 16));
13e5e344 213 cl_git_pass(git_blob_lookup_prefix(&c, g_repo, &c_oid, 16));
f9c824c5
RB
214
215 /* Doing the equivalent of a `git diff -U1` on these files */
216
217 /* diff on tests/resources/attr/root_test1 */
3ff1d123 218 cl_git_pass(git_patch_from_blobs(&p, a, NULL, b, NULL, &opts));
6789b7a7 219 assert_patch_matches_blobs(p, a, b, 1, 6, 0, 1, 5, 0);
3ff1d123 220 git_patch_free(p);
f9c824c5
RB
221
222 /* diff on tests/resources/attr/root_test2 */
3ff1d123 223 cl_git_pass(git_patch_from_blobs(&p, b, NULL, c, NULL, &opts));
6789b7a7 224 assert_patch_matches_blobs(p, b, c, 1, 15, 0, 3, 9, 3);
3ff1d123 225 git_patch_free(p);
f9c824c5
RB
226
227 /* diff on tests/resources/attr/root_test3 */
3ff1d123 228 cl_git_pass(git_patch_from_blobs(&p, a, NULL, c, NULL, &opts));
6789b7a7 229 assert_patch_matches_blobs(p, a, c, 1, 13, 0, 0, 12, 1);
3ff1d123 230 git_patch_free(p);
f9c824c5
RB
231
232 /* one more */
3ff1d123 233 cl_git_pass(git_patch_from_blobs(&p, c, NULL, d, NULL, &opts));
6789b7a7 234 assert_patch_matches_blobs(p, c, d, 2, 5, 9, 4, 6, 4);
3ff1d123 235 git_patch_free(p);
f9c824c5
RB
236
237 git_blob_free(a);
238 git_blob_free(b);
239 git_blob_free(c);
240}
241
4f806761 242void test_diff_blob__can_compare_against_null_blobs(void)
243{
244 git_blob *e = NULL;
245
246 cl_git_pass(git_diff_blobs(
74ded024 247 d, NULL, e, NULL, &opts,
8147b1af 248 diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &expected));
28ef7f9b 249
f335ecd6 250 cl_assert_equal_i(1, expected.files);
b4f5bb07
RB
251 cl_assert_equal_i(1, expected.file_status[GIT_DELTA_DELETED]);
252 cl_assert_equal_i(0, expected.files_binary);
4f806761 253
f335ecd6
RB
254 cl_assert_equal_i(1, expected.hunks);
255 cl_assert_equal_i(14, expected.hunk_old_lines);
256 cl_assert_equal_i(14, expected.lines);
257 cl_assert_equal_i(14, expected.line_dels);
4f806761 258
259 opts.flags |= GIT_DIFF_REVERSE;
1956693f 260 memset(&expected, 0, sizeof(expected));
4f806761 261
262 cl_git_pass(git_diff_blobs(
74ded024 263 d, NULL, e, NULL, &opts,
8147b1af 264 diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &expected));
28ef7f9b 265
f335ecd6 266 cl_assert_equal_i(1, expected.files);
b4f5bb07
RB
267 cl_assert_equal_i(1, expected.file_status[GIT_DELTA_ADDED]);
268 cl_assert_equal_i(0, expected.files_binary);
4f806761 269
f335ecd6
RB
270 cl_assert_equal_i(1, expected.hunks);
271 cl_assert_equal_i(14, expected.hunk_new_lines);
272 cl_assert_equal_i(14, expected.lines);
273 cl_assert_equal_i(14, expected.line_adds);
28ef7f9b 274
275 opts.flags ^= GIT_DIFF_REVERSE;
1956693f 276 memset(&expected, 0, sizeof(expected));
28ef7f9b 277
278 cl_git_pass(git_diff_blobs(
74ded024 279 alien, NULL, NULL, NULL, &opts,
8147b1af 280 diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &expected));
28ef7f9b 281
f335ecd6 282 cl_assert_equal_i(1, expected.files);
b4f5bb07
RB
283 cl_assert_equal_i(1, expected.files_binary);
284 cl_assert_equal_i(1, expected.file_status[GIT_DELTA_DELETED]);
f335ecd6
RB
285 cl_assert_equal_i(0, expected.hunks);
286 cl_assert_equal_i(0, expected.lines);
28ef7f9b 287
1956693f 288 memset(&expected, 0, sizeof(expected));
28ef7f9b 289
290 cl_git_pass(git_diff_blobs(
74ded024 291 NULL, NULL, alien, NULL, &opts,
8147b1af 292 diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &expected));
28ef7f9b 293
f335ecd6 294 cl_assert_equal_i(1, expected.files);
b4f5bb07
RB
295 cl_assert_equal_i(1, expected.files_binary);
296 cl_assert_equal_i(1, expected.file_status[GIT_DELTA_ADDED]);
f335ecd6
RB
297 cl_assert_equal_i(0, expected.hunks);
298 cl_assert_equal_i(0, expected.lines);
28ef7f9b 299}
300
f9c824c5
RB
301void test_diff_blob__can_compare_against_null_blobs_with_patch(void)
302{
303 git_blob *e = NULL;
3ff1d123 304 git_patch *p;
74ded024 305 const git_diff_delta *delta;
3b5f7954
RB
306 const git_diff_line *line;
307 int l, max_l;
f9c824c5 308
3ff1d123 309 cl_git_pass(git_patch_from_blobs(&p, d, NULL, e, NULL, &opts));
f9c824c5
RB
310
311 cl_assert(p != NULL);
74ded024 312
10672e3e 313 delta = git_patch_get_delta(p);
74ded024
RB
314 cl_assert(delta != NULL);
315 cl_assert_equal_i(GIT_DELTA_DELETED, delta->status);
0cee70eb 316 cl_assert_equal_oid(git_blob_id(d), &delta->old_file.id);
74ded024 317 cl_assert_equal_sz(git_blob_rawsize(d), delta->old_file.size);
22a2d3d5 318 cl_assert(git_oid_is_zero(&delta->new_file.id));
74ded024
RB
319 cl_assert_equal_sz(0, delta->new_file.size);
320
3ff1d123
RB
321 cl_assert_equal_i(1, (int)git_patch_num_hunks(p));
322 cl_assert_equal_i(14, git_patch_num_lines_in_hunk(p, 0));
f9c824c5 323
3b5f7954
RB
324 max_l = git_patch_num_lines_in_hunk(p, 0);
325 for (l = 0; l < max_l; ++l) {
326 cl_git_pass(git_patch_get_line_in_hunk(&line, p, 0, l));
327 cl_assert_equal_i(GIT_DIFF_LINE_DELETION, (int)line->origin);
f9c824c5
RB
328 }
329
3ff1d123 330 git_patch_free(p);
f9c824c5
RB
331
332 opts.flags |= GIT_DIFF_REVERSE;
333
3ff1d123 334 cl_git_pass(git_patch_from_blobs(&p, d, NULL, e, NULL, &opts));
f9c824c5
RB
335
336 cl_assert(p != NULL);
74ded024 337
10672e3e 338 delta = git_patch_get_delta(p);
74ded024
RB
339 cl_assert(delta != NULL);
340 cl_assert_equal_i(GIT_DELTA_ADDED, delta->status);
22a2d3d5 341 cl_assert(git_oid_is_zero(&delta->old_file.id));
74ded024 342 cl_assert_equal_sz(0, delta->old_file.size);
0cee70eb 343 cl_assert_equal_oid(git_blob_id(d), &delta->new_file.id);
74ded024
RB
344 cl_assert_equal_sz(git_blob_rawsize(d), delta->new_file.size);
345
3ff1d123
RB
346 cl_assert_equal_i(1, (int)git_patch_num_hunks(p));
347 cl_assert_equal_i(14, git_patch_num_lines_in_hunk(p, 0));
f9c824c5 348
3b5f7954
RB
349 max_l = git_patch_num_lines_in_hunk(p, 0);
350 for (l = 0; l < max_l; ++l) {
351 cl_git_pass(git_patch_get_line_in_hunk(&line, p, 0, l));
352 cl_assert_equal_i(GIT_DIFF_LINE_ADDITION, (int)line->origin);
f9c824c5
RB
353 }
354
3ff1d123 355 git_patch_free(p);
f9c824c5
RB
356
357 opts.flags ^= GIT_DIFF_REVERSE;
358
3ff1d123 359 cl_git_pass(git_patch_from_blobs(&p, alien, NULL, NULL, NULL, &opts));
f9c824c5
RB
360
361 cl_assert(p != NULL);
74ded024 362
10672e3e 363 delta = git_patch_get_delta(p);
74ded024
RB
364 cl_assert(delta != NULL);
365 cl_assert_equal_i(GIT_DELTA_DELETED, delta->status);
366 cl_assert((delta->flags & GIT_DIFF_FLAG_BINARY) != 0);
367
3ff1d123 368 cl_assert_equal_i(0, (int)git_patch_num_hunks(p));
f9c824c5 369
3ff1d123 370 git_patch_free(p);
f9c824c5 371
3ff1d123 372 cl_git_pass(git_patch_from_blobs(&p, NULL, NULL, alien, NULL, &opts));
f9c824c5
RB
373
374 cl_assert(p != NULL);
74ded024 375
10672e3e 376 delta = git_patch_get_delta(p);
74ded024
RB
377 cl_assert(delta != NULL);
378 cl_assert_equal_i(GIT_DELTA_ADDED, delta->status);
379 cl_assert((delta->flags & GIT_DIFF_FLAG_BINARY) != 0);
380
3ff1d123 381 cl_assert_equal_i(0, (int)git_patch_num_hunks(p));
f9c824c5 382
3ff1d123 383 git_patch_free(p);
f9c824c5
RB
384}
385
b4f5bb07 386static void assert_identical_blobs_comparison(diff_expects *expected)
9a29f8d5 387{
b4f5bb07
RB
388 cl_assert_equal_i(1, expected->files);
389 cl_assert_equal_i(1, expected->file_status[GIT_DELTA_UNMODIFIED]);
390 cl_assert_equal_i(0, expected->hunks);
391 cl_assert_equal_i(0, expected->lines);
9a29f8d5 392}
393
394void test_diff_blob__can_compare_identical_blobs(void)
395{
74ded024
RB
396 opts.flags |= GIT_DIFF_INCLUDE_UNMODIFIED;
397
9a29f8d5 398 cl_git_pass(git_diff_blobs(
74ded024 399 d, NULL, d, NULL, &opts,
8147b1af 400 diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &expected));
9a29f8d5 401
b4f5bb07 402 assert_identical_blobs_comparison(&expected);
74ded024 403 cl_assert_equal_i(0, expected.files_binary);
9a29f8d5 404
1956693f 405 memset(&expected, 0, sizeof(expected));
9a29f8d5 406 cl_git_pass(git_diff_blobs(
74ded024 407 NULL, NULL, NULL, NULL, &opts,
8147b1af 408 diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &expected));
9a29f8d5 409
74ded024 410 assert_identical_blobs_comparison(&expected);
b4f5bb07 411 cl_assert_equal_i(0, expected.files_binary);
9a29f8d5 412
1956693f 413 memset(&expected, 0, sizeof(expected));
9a29f8d5 414 cl_git_pass(git_diff_blobs(
74ded024 415 alien, NULL, alien, NULL, &opts,
8147b1af 416 diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &expected));
9a29f8d5 417
b4f5bb07 418 assert_identical_blobs_comparison(&expected);
74ded024 419 cl_assert(expected.files_binary > 0);
9a29f8d5 420}
421
f9c824c5
RB
422void test_diff_blob__can_compare_identical_blobs_with_patch(void)
423{
3ff1d123 424 git_patch *p;
74ded024 425 const git_diff_delta *delta;
f9c824c5 426
3ff1d123 427 cl_git_pass(git_patch_from_blobs(&p, d, NULL, d, NULL, &opts));
f9c824c5 428 cl_assert(p != NULL);
74ded024 429
10672e3e 430 delta = git_patch_get_delta(p);
74ded024
RB
431 cl_assert(delta != NULL);
432 cl_assert_equal_i(GIT_DELTA_UNMODIFIED, delta->status);
433 cl_assert_equal_sz(delta->old_file.size, git_blob_rawsize(d));
0cee70eb 434 cl_assert_equal_oid(git_blob_id(d), &delta->old_file.id);
74ded024 435 cl_assert_equal_sz(delta->new_file.size, git_blob_rawsize(d));
0cee70eb 436 cl_assert_equal_oid(git_blob_id(d), &delta->new_file.id);
74ded024 437
3ff1d123
RB
438 cl_assert_equal_i(0, (int)git_patch_num_hunks(p));
439 git_patch_free(p);
f9c824c5 440
3ff1d123 441 cl_git_pass(git_patch_from_blobs(&p, NULL, NULL, NULL, NULL, &opts));
f9c824c5 442 cl_assert(p != NULL);
74ded024 443
10672e3e 444 delta = git_patch_get_delta(p);
74ded024
RB
445 cl_assert(delta != NULL);
446 cl_assert_equal_i(GIT_DELTA_UNMODIFIED, delta->status);
447 cl_assert_equal_sz(0, delta->old_file.size);
22a2d3d5 448 cl_assert(git_oid_is_zero(&delta->old_file.id));
74ded024 449 cl_assert_equal_sz(0, delta->new_file.size);
22a2d3d5 450 cl_assert(git_oid_is_zero(&delta->new_file.id));
74ded024 451
3ff1d123
RB
452 cl_assert_equal_i(0, (int)git_patch_num_hunks(p));
453 git_patch_free(p);
f9c824c5 454
3ff1d123 455 cl_git_pass(git_patch_from_blobs(&p, alien, NULL, alien, NULL, &opts));
f9c824c5 456 cl_assert(p != NULL);
10672e3e 457 cl_assert_equal_i(GIT_DELTA_UNMODIFIED, git_patch_get_delta(p)->status);
3ff1d123
RB
458 cl_assert_equal_i(0, (int)git_patch_num_hunks(p));
459 git_patch_free(p);
f9c824c5
RB
460}
461
b4f5bb07 462static void assert_binary_blobs_comparison(diff_expects *expected)
28ef7f9b 463{
b4f5bb07 464 cl_assert(expected->files_binary > 0);
28ef7f9b 465
b4f5bb07
RB
466 cl_assert_equal_i(1, expected->files);
467 cl_assert_equal_i(1, expected->file_status[GIT_DELTA_MODIFIED]);
468 cl_assert_equal_i(0, expected->hunks);
469 cl_assert_equal_i(0, expected->lines);
28ef7f9b 470}
471
472void test_diff_blob__can_compare_two_binary_blobs(void)
473{
474 git_blob *heart;
475 git_oid h_oid;
476
477 /* heart.png */
478 cl_git_pass(git_oid_fromstrn(&h_oid, "de863bff", 8));
13e5e344 479 cl_git_pass(git_blob_lookup_prefix(&heart, g_repo, &h_oid, 8));
28ef7f9b 480
481 cl_git_pass(git_diff_blobs(
74ded024 482 alien, NULL, heart, NULL, &opts,
8147b1af 483 diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &expected));
28ef7f9b 484
b4f5bb07 485 assert_binary_blobs_comparison(&expected);
28ef7f9b 486
1956693f 487 memset(&expected, 0, sizeof(expected));
28ef7f9b 488
489 cl_git_pass(git_diff_blobs(
74ded024 490 heart, NULL, alien, NULL, &opts,
8147b1af 491 diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &expected));
28ef7f9b 492
b4f5bb07 493 assert_binary_blobs_comparison(&expected);
28ef7f9b 494
495 git_blob_free(heart);
496}
497
498void test_diff_blob__can_compare_a_binary_blob_and_a_text_blob(void)
499{
500 cl_git_pass(git_diff_blobs(
74ded024 501 alien, NULL, d, NULL, &opts,
8147b1af 502 diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &expected));
28ef7f9b 503
b4f5bb07 504 assert_binary_blobs_comparison(&expected);
28ef7f9b 505
1956693f 506 memset(&expected, 0, sizeof(expected));
28ef7f9b 507
508 cl_git_pass(git_diff_blobs(
74ded024 509 d, NULL, alien, NULL, &opts,
8147b1af 510 diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &expected));
28ef7f9b 511
b4f5bb07 512 assert_binary_blobs_comparison(&expected);
4f806761 513}
29f9186d 514
515/*
516 * $ git diff fe773770 a0f7217
517 * diff --git a/fe773770 b/a0f7217
518 * index fe77377..a0f7217 100644
519 * --- a/fe773770
520 * +++ b/a0f7217
521 * @@ -1,6 +1,6 @@
522 * Here is some stuff at the start
22a2d3d5 523 *
29f9186d 524 * -This should go in one hunk
525 * +This should go in one hunk (first)
22a2d3d5 526 *
29f9186d 527 * Some additional lines
22a2d3d5 528 *
29f9186d 529 * @@ -8,7 +8,7 @@ Down here below the other lines
22a2d3d5 530 *
29f9186d 531 * With even more at the end
22a2d3d5 532 *
29f9186d 533 * -Followed by a second hunk of stuff
534 * +Followed by a second hunk of stuff (second)
22a2d3d5 535 *
29f9186d 536 * That happens down here
537 */
538void test_diff_blob__comparing_two_text_blobs_honors_interhunkcontext(void)
539{
540 git_blob *old_d;
541 git_oid old_d_oid;
542
543 opts.context_lines = 3;
544
545 /* tests/resources/attr/root_test1 from commit f5b0af1 */
546 cl_git_pass(git_oid_fromstrn(&old_d_oid, "fe773770", 8));
13e5e344 547 cl_git_pass(git_blob_lookup_prefix(&old_d, g_repo, &old_d_oid, 8));
29f9186d 548
549 /* Test with default inter-hunk-context (not set) => default is 0 */
550 cl_git_pass(git_diff_blobs(
74ded024 551 old_d, NULL, d, NULL, &opts,
8147b1af 552 diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &expected));
29f9186d 553
f335ecd6 554 cl_assert_equal_i(2, expected.hunks);
29f9186d 555
556 /* Test with inter-hunk-context explicitly set to 0 */
557 opts.interhunk_lines = 0;
558 memset(&expected, 0, sizeof(expected));
559 cl_git_pass(git_diff_blobs(
74ded024 560 old_d, NULL, d, NULL, &opts,
8147b1af 561 diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &expected));
29f9186d 562
f335ecd6 563 cl_assert_equal_i(2, expected.hunks);
29f9186d 564
565 /* Test with inter-hunk-context explicitly set to 1 */
566 opts.interhunk_lines = 1;
567 memset(&expected, 0, sizeof(expected));
568 cl_git_pass(git_diff_blobs(
74ded024 569 old_d, NULL, d, NULL, &opts,
8147b1af 570 diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &expected));
29f9186d 571
f335ecd6 572 cl_assert_equal_i(1, expected.hunks);
29f9186d 573
574 git_blob_free(old_d);
575}
2f8d30be
BS
576
577void test_diff_blob__checks_options_version_too_low(void)
578{
579 const git_error *err;
580
581 opts.version = 0;
582 cl_git_fail(git_diff_blobs(
74ded024 583 d, NULL, alien, NULL, &opts,
8147b1af 584 diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &expected));
ac3d33df
JK
585 err = git_error_last();
586 cl_assert_equal_i(GIT_ERROR_INVALID, err->klass);
2f8d30be
BS
587}
588
589void test_diff_blob__checks_options_version_too_high(void)
590{
591 const git_error *err;
592
593 opts.version = 1024;
594 cl_git_fail(git_diff_blobs(
74ded024 595 d, NULL, alien, NULL, &opts,
8147b1af 596 diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &expected));
ac3d33df
JK
597 err = git_error_last();
598 cl_assert_equal_i(GIT_ERROR_INVALID, err->klass);
2f8d30be 599}
a3337f10 600
601void test_diff_blob__can_correctly_detect_a_binary_blob_as_binary(void)
602{
603 /* alien.png */
604 cl_assert_equal_i(true, git_blob_is_binary(alien));
605}
606
e579e0f7
MB
607void test_diff_blob__can_correctly_detect_binary_blob_data_as_binary(void)
608{
609 /* alien.png */
610 const char *content = git_blob_rawcontent(alien);
611 size_t len = (size_t)git_blob_rawsize(alien);
612 cl_assert_equal_i(true, git_blob_data_is_binary(content, len));
613}
614
a3337f10 615void test_diff_blob__can_correctly_detect_a_textual_blob_as_non_binary(void)
616{
617 /* tests/resources/attr/root_test4.txt */
618 cl_assert_equal_i(false, git_blob_is_binary(d));
619}
f2b7f7a6 620
e579e0f7
MB
621void test_diff_blob__can_correctly_detect_textual_blob_data_as_non_binary(void)
622{
623 /* tests/resources/attr/root_test4.txt */
624 const char *content = git_blob_rawcontent(d);
625 size_t len = (size_t)git_blob_rawsize(d);
626 cl_assert_equal_i(false, git_blob_data_is_binary(content, len));
627}
628
f2b7f7a6
RB
629/*
630 * git_diff_blob_to_buffer tests
631 */
632
c2c0874d
RB
633static void assert_changed_single_one_line_file(
634 diff_expects *expected, git_delta_t mod)
635{
636 cl_assert_equal_i(1, expected->files);
637 cl_assert_equal_i(1, expected->file_status[mod]);
638 cl_assert_equal_i(1, expected->hunks);
639 cl_assert_equal_i(1, expected->lines);
640
641 if (mod == GIT_DELTA_ADDED)
642 cl_assert_equal_i(1, expected->line_adds);
643 else if (mod == GIT_DELTA_DELETED)
644 cl_assert_equal_i(1, expected->line_dels);
645}
646
f2b7f7a6
RB
647void test_diff_blob__can_compare_blob_to_buffer(void)
648{
649 git_blob *a;
650 git_oid a_oid;
651 const char *a_content = "Hello from the root\n";
652 const char *b_content = "Hello from the root\n\nSome additional lines\n\nDown here below\n\n";
653
654 /* tests/resources/attr/root_test1 */
655 cl_git_pass(git_oid_fromstrn(&a_oid, "45141a79", 8));
13e5e344 656 cl_git_pass(git_blob_lookup_prefix(&a, g_repo, &a_oid, 8));
f2b7f7a6
RB
657
658 /* diff from blob a to content of b */
74ded024 659 quick_diff_blob_to_str(a, NULL, b_content, 0, NULL);
6789b7a7 660 assert_one_modified(1, 6, 1, 5, 0, &expected);
f2b7f7a6
RB
661
662 /* diff from blob a to content of a */
74ded024
RB
663 opts.flags |= GIT_DIFF_INCLUDE_UNMODIFIED;
664 quick_diff_blob_to_str(a, NULL, a_content, 0, NULL);
f2b7f7a6
RB
665 assert_identical_blobs_comparison(&expected);
666
960a04dd 667 /* diff from NULL blob to content of a */
f2b7f7a6 668 memset(&expected, 0, sizeof(expected));
74ded024 669 quick_diff_blob_to_str(NULL, NULL, a_content, 0, NULL);
c2c0874d 670 assert_changed_single_one_line_file(&expected, GIT_DELTA_ADDED);
f2b7f7a6
RB
671
672 /* diff from blob a to NULL buffer */
673 memset(&expected, 0, sizeof(expected));
74ded024 674 quick_diff_blob_to_str(a, NULL, NULL, 0, NULL);
c2c0874d 675 assert_changed_single_one_line_file(&expected, GIT_DELTA_DELETED);
f2b7f7a6
RB
676
677 /* diff with reverse */
678 opts.flags ^= GIT_DIFF_REVERSE;
679
680 memset(&expected, 0, sizeof(expected));
74ded024 681 quick_diff_blob_to_str(a, NULL, NULL, 0, NULL);
c2c0874d 682 assert_changed_single_one_line_file(&expected, GIT_DELTA_ADDED);
f2b7f7a6
RB
683
684 git_blob_free(a);
685}
c2c0874d 686
f9c824c5
RB
687void test_diff_blob__can_compare_blob_to_buffer_with_patch(void)
688{
3ff1d123 689 git_patch *p;
f9c824c5
RB
690 git_blob *a;
691 git_oid a_oid;
692 const char *a_content = "Hello from the root\n";
693 const char *b_content = "Hello from the root\n\nSome additional lines\n\nDown here below\n\n";
694 size_t tc, ta, td;
695
696 /* tests/resources/attr/root_test1 */
697 cl_git_pass(git_oid_fromstrn(&a_oid, "45141a79", 8));
13e5e344 698 cl_git_pass(git_blob_lookup_prefix(&a, g_repo, &a_oid, 8));
f9c824c5
RB
699
700 /* diff from blob a to content of b */
3ff1d123 701 cl_git_pass(git_patch_from_blob_and_buffer(
74ded024 702 &p, a, NULL, b_content, strlen(b_content), NULL, &opts));
f9c824c5
RB
703
704 cl_assert(p != NULL);
10672e3e 705 cl_assert_equal_i(GIT_DELTA_MODIFIED, git_patch_get_delta(p)->status);
3ff1d123
RB
706 cl_assert_equal_i(1, (int)git_patch_num_hunks(p));
707 cl_assert_equal_i(6, git_patch_num_lines_in_hunk(p, 0));
f9c824c5 708
3ff1d123 709 cl_git_pass(git_patch_line_stats(&tc, &ta, &td, p));
f9c824c5
RB
710 cl_assert_equal_i(1, (int)tc);
711 cl_assert_equal_i(5, (int)ta);
712 cl_assert_equal_i(0, (int)td);
713
3ff1d123 714 git_patch_free(p);
f9c824c5
RB
715
716 /* diff from blob a to content of a */
74ded024 717 opts.flags |= GIT_DIFF_INCLUDE_UNMODIFIED;
3ff1d123 718 cl_git_pass(git_patch_from_blob_and_buffer(
74ded024 719 &p, a, NULL, a_content, strlen(a_content), NULL, &opts));
f9c824c5 720 cl_assert(p != NULL);
10672e3e 721 cl_assert_equal_i(GIT_DELTA_UNMODIFIED, git_patch_get_delta(p)->status);
3ff1d123
RB
722 cl_assert_equal_i(0, (int)git_patch_num_hunks(p));
723 git_patch_free(p);
f9c824c5
RB
724
725 /* diff from NULL blob to content of a */
3ff1d123 726 cl_git_pass(git_patch_from_blob_and_buffer(
74ded024 727 &p, NULL, NULL, a_content, strlen(a_content), NULL, &opts));
f9c824c5 728 cl_assert(p != NULL);
10672e3e 729 cl_assert_equal_i(GIT_DELTA_ADDED, git_patch_get_delta(p)->status);
3ff1d123
RB
730 cl_assert_equal_i(1, (int)git_patch_num_hunks(p));
731 cl_assert_equal_i(1, git_patch_num_lines_in_hunk(p, 0));
732 git_patch_free(p);
f9c824c5
RB
733
734 /* diff from blob a to NULL buffer */
3ff1d123 735 cl_git_pass(git_patch_from_blob_and_buffer(
74ded024 736 &p, a, NULL, NULL, 0, NULL, &opts));
f9c824c5 737 cl_assert(p != NULL);
10672e3e 738 cl_assert_equal_i(GIT_DELTA_DELETED, git_patch_get_delta(p)->status);
3ff1d123
RB
739 cl_assert_equal_i(1, (int)git_patch_num_hunks(p));
740 cl_assert_equal_i(1, git_patch_num_lines_in_hunk(p, 0));
741 git_patch_free(p);
f9c824c5
RB
742
743 /* diff with reverse */
744 opts.flags ^= GIT_DIFF_REVERSE;
745
3ff1d123 746 cl_git_pass(git_patch_from_blob_and_buffer(
74ded024 747 &p, a, NULL, NULL, 0, NULL, &opts));
f9c824c5 748 cl_assert(p != NULL);
10672e3e 749 cl_assert_equal_i(GIT_DELTA_ADDED, git_patch_get_delta(p)->status);
3ff1d123
RB
750 cl_assert_equal_i(1, (int)git_patch_num_hunks(p));
751 cl_assert_equal_i(1, git_patch_num_lines_in_hunk(p, 0));
752 git_patch_free(p);
f9c824c5
RB
753
754 git_blob_free(a);
755}
c2c0874d
RB
756
757static void assert_one_modified_with_lines(diff_expects *expected, int lines)
758{
759 cl_assert_equal_i(1, expected->files);
760 cl_assert_equal_i(1, expected->file_status[GIT_DELTA_MODIFIED]);
761 cl_assert_equal_i(0, expected->files_binary);
762 cl_assert_equal_i(lines, expected->lines);
763}
764
765void test_diff_blob__binary_data_comparisons(void)
766{
767 git_blob *bin, *nonbin;
768 git_oid oid;
769 const char *nonbin_content = "Hello from the root\n";
770 size_t nonbin_len = 20;
771 const char *bin_content = "0123456789\n\x01\x02\x03\x04\x05\x06\x07\x08\x09\x00\n0123456789\n";
772 size_t bin_len = 33;
773
74ded024
RB
774 opts.flags |= GIT_DIFF_INCLUDE_UNMODIFIED;
775
c2c0874d 776 cl_git_pass(git_oid_fromstrn(&oid, "45141a79", 8));
13e5e344 777 cl_git_pass(git_blob_lookup_prefix(&nonbin, g_repo, &oid, 8));
c2c0874d
RB
778
779 cl_git_pass(git_oid_fromstrn(&oid, "b435cd56", 8));
13e5e344 780 cl_git_pass(git_blob_lookup_prefix(&bin, g_repo, &oid, 8));
c2c0874d
RB
781
782 /* non-binary to reference content */
783
74ded024 784 quick_diff_blob_to_str(nonbin, NULL, nonbin_content, nonbin_len, NULL);
c2c0874d
RB
785 assert_identical_blobs_comparison(&expected);
786 cl_assert_equal_i(0, expected.files_binary);
787
788 /* binary to reference content */
789
74ded024 790 quick_diff_blob_to_str(bin, NULL, bin_content, bin_len, NULL);
c2c0874d
RB
791 assert_identical_blobs_comparison(&expected);
792
793 cl_assert_equal_i(1, expected.files_binary);
794
795 /* non-binary to binary content */
796
74ded024 797 quick_diff_blob_to_str(nonbin, NULL, bin_content, bin_len, NULL);
c2c0874d
RB
798 assert_binary_blobs_comparison(&expected);
799
800 /* binary to non-binary content */
801
74ded024 802 quick_diff_blob_to_str(bin, NULL, nonbin_content, nonbin_len, NULL);
c2c0874d
RB
803 assert_binary_blobs_comparison(&expected);
804
805 /* non-binary to binary blob */
806
807 memset(&expected, 0, sizeof(expected));
808 cl_git_pass(git_diff_blobs(
74ded024 809 bin, NULL, nonbin, NULL, &opts,
8147b1af 810 diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &expected));
c2c0874d
RB
811 assert_binary_blobs_comparison(&expected);
812
813 /*
814 * repeat with FORCE_TEXT
815 */
816
817 opts.flags |= GIT_DIFF_FORCE_TEXT;
818
74ded024 819 quick_diff_blob_to_str(bin, NULL, bin_content, bin_len, NULL);
c2c0874d
RB
820 assert_identical_blobs_comparison(&expected);
821
74ded024 822 quick_diff_blob_to_str(nonbin, NULL, bin_content, bin_len, NULL);
c2c0874d
RB
823 assert_one_modified_with_lines(&expected, 4);
824
74ded024 825 quick_diff_blob_to_str(bin, NULL, nonbin_content, nonbin_len, NULL);
c2c0874d
RB
826 assert_one_modified_with_lines(&expected, 4);
827
828 memset(&expected, 0, sizeof(expected));
829 cl_git_pass(git_diff_blobs(
74ded024 830 bin, NULL, nonbin, NULL, &opts,
8147b1af 831 diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &expected));
c2c0874d
RB
832 assert_one_modified_with_lines(&expected, 4);
833
834 /* cleanup */
835 git_blob_free(bin);
836 git_blob_free(nonbin);
837}
74ded024
RB
838
839void test_diff_blob__using_path_and_attributes(void)
840{
841 git_config *cfg;
842 git_blob *bin, *nonbin;
843 git_oid oid;
844 const char *nonbin_content = "Hello from the root\n";
845 const char *bin_content =
846 "0123456789\n\x01\x02\x03\x04\x05\x06\x07\x08\x09\x00\n0123456789\n";
847 size_t bin_len = 33;
848 const char *changed;
3ff1d123 849 git_patch *p;
c05cd792 850 git_buf buf = GIT_BUF_INIT;
74ded024
RB
851
852 /* set up custom diff drivers and 'diff' attribute mappings for them */
853
854 cl_git_pass(git_repository_config(&cfg, g_repo));
855 cl_git_pass(git_config_set_bool(cfg, "diff.iam_binary.binary", 1));
856 cl_git_pass(git_config_set_bool(cfg, "diff.iam_text.binary", 0));
857 cl_git_pass(git_config_set_string(
5d82c0df 858 cfg, "diff.iam_alphactx.xfuncname", "^[A-Za-z].*$"));
74ded024
RB
859 cl_git_pass(git_config_set_bool(cfg, "diff.iam_textalpha.binary", 0));
860 cl_git_pass(git_config_set_string(
5d82c0df 861 cfg, "diff.iam_textalpha.xfuncname", "^[A-Za-z].*$"));
74ded024 862 cl_git_pass(git_config_set_string(
5d82c0df 863 cfg, "diff.iam_numctx.funcname", "^[0-9][0-9]*"));
74ded024
RB
864 cl_git_pass(git_config_set_bool(cfg, "diff.iam_textnum.binary", 0));
865 cl_git_pass(git_config_set_string(
5d82c0df 866 cfg, "diff.iam_textnum.funcname", "^[0-9][0-9]*"));
74ded024
RB
867 git_config_free(cfg);
868
869 cl_git_append2file(
870 "attr/.gitattributes",
871 "\n\n# test_diff_blob__using_path_and_attributes extra\n\n"
872 "*.binary diff=iam_binary\n"
873 "*.textary diff=iam_text\n"
874 "*.alphary diff=iam_alphactx\n"
875 "*.textalphary diff=iam_textalpha\n"
876 "*.textnumary diff=iam_textnum\n"
877 "*.numary diff=iam_numctx\n\n");
878
879 opts.context_lines = 0;
880 opts.flags |= GIT_DIFF_INCLUDE_UNMODIFIED;
881
882 cl_git_pass(git_oid_fromstrn(&oid, "45141a79", 8));
13e5e344 883 cl_git_pass(git_blob_lookup_prefix(&nonbin, g_repo, &oid, 8));
74ded024
RB
884 /* 20b: "Hello from the root\n" */
885
886 cl_git_pass(git_oid_fromstrn(&oid, "b435cd56", 8));
13e5e344 887 cl_git_pass(git_blob_lookup_prefix(&bin, g_repo, &oid, 8));
74ded024
RB
888 /* 33b: "0123456789\n\x01\x02\x03\x04\x05\x06\x07\x08\x09\n0123456789\n" */
889
890 /* non-binary to reference content */
891
892 quick_diff_blob_to_str(nonbin, NULL, nonbin_content, 0, NULL);
893 assert_identical_blobs_comparison(&expected);
894 cl_assert_equal_i(0, expected.files_binary);
895
896 /* binary to reference content */
897
898 quick_diff_blob_to_str(bin, NULL, bin_content, bin_len, NULL);
899 assert_identical_blobs_comparison(&expected);
900 cl_assert_equal_i(1, expected.files_binary);
901
902 /* add some text */
903
904 changed = "Hello from the root\nMore lines\nAnd more\nGo here\n";
905
906 quick_diff_blob_to_str(nonbin, NULL, changed, 0, NULL);
6789b7a7 907 assert_one_modified(1, 3, 0, 3, 0, &expected);
74ded024
RB
908
909 quick_diff_blob_to_str(nonbin, "foo/bar.binary", changed, 0, NULL);
910 cl_assert_equal_i(1, expected.files);
911 cl_assert_equal_i(1, expected.file_status[GIT_DELTA_MODIFIED]);
912 cl_assert_equal_i(1, expected.files_binary);
913 cl_assert_equal_i(0, expected.hunks);
914 cl_assert_equal_i(0, expected.lines);
74ded024
RB
915
916 quick_diff_blob_to_str(nonbin, "foo/bar.textary", changed, 0, NULL);
6789b7a7 917 assert_one_modified(1, 3, 0, 3, 0, &expected);
74ded024
RB
918
919 quick_diff_blob_to_str(nonbin, "foo/bar.alphary", changed, 0, NULL);
6789b7a7 920 assert_one_modified(1, 3, 0, 3, 0, &expected);
74ded024 921
3ff1d123 922 cl_git_pass(git_patch_from_blob_and_buffer(
74ded024 923 &p, nonbin, "zzz.normal", changed, strlen(changed), NULL, &opts));
c05cd792 924 cl_git_pass(git_patch_to_buf(&buf, p));
74ded024
RB
925 cl_assert_equal_s(
926 "diff --git a/zzz.normal b/zzz.normal\n"
927 "index 45141a7..75b0dbb 100644\n"
928 "--- a/zzz.normal\n"
929 "+++ b/zzz.normal\n"
930 "@@ -1,0 +2,3 @@ Hello from the root\n"
931 "+More lines\n"
932 "+And more\n"
c05cd792 933 "+Go here\n", buf.ptr);
e579e0f7 934 git_buf_dispose(&buf);
3ff1d123 935 git_patch_free(p);
74ded024 936
3ff1d123 937 cl_git_pass(git_patch_from_blob_and_buffer(
74ded024 938 &p, nonbin, "zzz.binary", changed, strlen(changed), NULL, &opts));
c05cd792 939 cl_git_pass(git_patch_to_buf(&buf, p));
74ded024
RB
940 cl_assert_equal_s(
941 "diff --git a/zzz.binary b/zzz.binary\n"
942 "index 45141a7..75b0dbb 100644\n"
c05cd792 943 "Binary files a/zzz.binary and b/zzz.binary differ\n", buf.ptr);
e579e0f7 944 git_buf_dispose(&buf);
3ff1d123 945 git_patch_free(p);
74ded024 946
3ff1d123 947 cl_git_pass(git_patch_from_blob_and_buffer(
74ded024 948 &p, nonbin, "zzz.alphary", changed, strlen(changed), NULL, &opts));
c05cd792 949 cl_git_pass(git_patch_to_buf(&buf, p));
74ded024
RB
950 cl_assert_equal_s(
951 "diff --git a/zzz.alphary b/zzz.alphary\n"
952 "index 45141a7..75b0dbb 100644\n"
953 "--- a/zzz.alphary\n"
954 "+++ b/zzz.alphary\n"
955 "@@ -1,0 +2,3 @@ Hello from the root\n"
956 "+More lines\n"
957 "+And more\n"
c05cd792 958 "+Go here\n", buf.ptr);
e579e0f7 959 git_buf_dispose(&buf);
3ff1d123 960 git_patch_free(p);
74ded024 961
3ff1d123 962 cl_git_pass(git_patch_from_blob_and_buffer(
74ded024 963 &p, nonbin, "zzz.numary", changed, strlen(changed), NULL, &opts));
c05cd792 964 cl_git_pass(git_patch_to_buf(&buf, p));
74ded024
RB
965 cl_assert_equal_s(
966 "diff --git a/zzz.numary b/zzz.numary\n"
967 "index 45141a7..75b0dbb 100644\n"
968 "--- a/zzz.numary\n"
969 "+++ b/zzz.numary\n"
970 "@@ -1,0 +2,3 @@\n"
971 "+More lines\n"
972 "+And more\n"
c05cd792 973 "+Go here\n", buf.ptr);
e579e0f7 974 git_buf_dispose(&buf);
3ff1d123 975 git_patch_free(p);
74ded024
RB
976
977 /* "0123456789\n\x01\x02\x03\x04\x05\x06\x07\x08\x09\x00\n0123456789\n"
978 * 33 bytes
979 */
980
981 changed = "0123456789\n\x01\x02\x03\x04\x05\x06\x07\x08\x09\x00\nreplace a line\n";
982
3ff1d123 983 cl_git_pass(git_patch_from_blob_and_buffer(
74ded024 984 &p, bin, "zzz.normal", changed, 37, NULL, &opts));
c05cd792 985 cl_git_pass(git_patch_to_buf(&buf, p));
74ded024
RB
986 cl_assert_equal_s(
987 "diff --git a/zzz.normal b/zzz.normal\n"
988 "index b435cd5..1604519 100644\n"
c05cd792 989 "Binary files a/zzz.normal and b/zzz.normal differ\n", buf.ptr);
e579e0f7 990 git_buf_dispose(&buf);
3ff1d123 991 git_patch_free(p);
74ded024 992
3ff1d123 993 cl_git_pass(git_patch_from_blob_and_buffer(
74ded024 994 &p, bin, "zzz.textary", changed, 37, NULL, &opts));
c05cd792 995 cl_git_pass(git_patch_to_buf(&buf, p));
74ded024
RB
996 cl_assert_equal_s(
997 "diff --git a/zzz.textary b/zzz.textary\n"
998 "index b435cd5..1604519 100644\n"
999 "--- a/zzz.textary\n"
1000 "+++ b/zzz.textary\n"
1001 "@@ -3 +3 @@\n"
1002 "-0123456789\n"
c05cd792 1003 "+replace a line\n", buf.ptr);
e579e0f7 1004 git_buf_dispose(&buf);
3ff1d123 1005 git_patch_free(p);
74ded024 1006
3ff1d123 1007 cl_git_pass(git_patch_from_blob_and_buffer(
74ded024 1008 &p, bin, "zzz.textalphary", changed, 37, NULL, &opts));
c05cd792 1009 cl_git_pass(git_patch_to_buf(&buf, p));
74ded024
RB
1010 cl_assert_equal_s(
1011 "diff --git a/zzz.textalphary b/zzz.textalphary\n"
1012 "index b435cd5..1604519 100644\n"
1013 "--- a/zzz.textalphary\n"
1014 "+++ b/zzz.textalphary\n"
1015 "@@ -3 +3 @@\n"
1016 "-0123456789\n"
c05cd792 1017 "+replace a line\n", buf.ptr);
e579e0f7 1018 git_buf_dispose(&buf);
3ff1d123 1019 git_patch_free(p);
74ded024 1020
3ff1d123 1021 cl_git_pass(git_patch_from_blob_and_buffer(
74ded024 1022 &p, bin, "zzz.textnumary", changed, 37, NULL, &opts));
c05cd792 1023 cl_git_pass(git_patch_to_buf(&buf, p));
74ded024
RB
1024 cl_assert_equal_s(
1025 "diff --git a/zzz.textnumary b/zzz.textnumary\n"
1026 "index b435cd5..1604519 100644\n"
1027 "--- a/zzz.textnumary\n"
1028 "+++ b/zzz.textnumary\n"
1029 "@@ -3 +3 @@ 0123456789\n"
1030 "-0123456789\n"
c05cd792 1031 "+replace a line\n", buf.ptr);
e579e0f7 1032 git_buf_dispose(&buf);
3ff1d123 1033 git_patch_free(p);
74ded024 1034
ac3d33df 1035 git_buf_dispose(&buf);
74ded024
RB
1036 git_blob_free(nonbin);
1037 git_blob_free(bin);
1038}
6789b7a7
RB
1039
1040void test_diff_blob__can_compare_buffer_to_buffer(void)
1041{
1042 const char *a = "a\nb\nc\nd\ne\nf\ng\nh\ni\nj\n";
1043 const char *b = "a\nB\nc\nd\nE\nF\nh\nj\nk\n";
1044
1045 opts.interhunk_lines = 0;
1046 opts.context_lines = 0;
1047
1048 memset(&expected, 0, sizeof(expected));
1049
1050 cl_git_pass(git_diff_buffers(
8147b1af
ET
1051 a, strlen(a), NULL, b, strlen(b), NULL, &opts,
1052 diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &expected));
6789b7a7
RB
1053 assert_one_modified(4, 9, 0, 4, 5, &expected);
1054
1055 opts.flags ^= GIT_DIFF_REVERSE;
1056
1057 memset(&expected, 0, sizeof(expected));
1058
1059 cl_git_pass(git_diff_buffers(
8147b1af
ET
1060 a, strlen(a), NULL, b, strlen(b), NULL, &opts,
1061 diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, &expected));
6789b7a7
RB
1062 assert_one_modified(4, 9, 0, 5, 4, &expected);
1063}