]> git.proxmox.com Git - libgit2.git/blame - tests/core/buffer.c
New upstream version 1.3.0+dfsg.1
[libgit2.git] / tests / core / buffer.c
CommitLineData
3fd1520c 1#include "clar_libgit2.h"
8c74d22e 2#include "buffer.h"
737b5051 3#include "git2/sys/hashsig.h"
22a2d3d5 4#include "futils.h"
8c74d22e
RB
5
6#define TESTSTR "Have you seen that? Have you seeeen that??"
7const char *test_string = TESTSTR;
8const char *test_string_x2 = TESTSTR TESTSTR;
9
8c74d22e
RB
10#define TESTSTR_4096 REP1024("1234")
11#define TESTSTR_8192 REP1024("12341234")
12const char *test_4096 = TESTSTR_4096;
13const char *test_8192 = TESTSTR_8192;
14
15/* test basic data concatenation */
16void test_core_buffer__0(void)
17{
18 git_buf buf = GIT_BUF_INIT;
19
20 cl_assert(buf.size == 0);
21
22 git_buf_puts(&buf, test_string);
23 cl_assert(git_buf_oom(&buf) == 0);
1a6e8f8a 24 cl_assert_equal_s(test_string, git_buf_cstr(&buf));
8c74d22e
RB
25
26 git_buf_puts(&buf, test_string);
27 cl_assert(git_buf_oom(&buf) == 0);
1a6e8f8a 28 cl_assert_equal_s(test_string_x2, git_buf_cstr(&buf));
8c74d22e 29
ac3d33df 30 git_buf_dispose(&buf);
8c74d22e
RB
31}
32
33/* test git_buf_printf */
34void test_core_buffer__1(void)
35{
36 git_buf buf = GIT_BUF_INIT;
37
38 git_buf_printf(&buf, "%s %s %d ", "shoop", "da", 23);
39 cl_assert(git_buf_oom(&buf) == 0);
1a6e8f8a 40 cl_assert_equal_s("shoop da 23 ", git_buf_cstr(&buf));
8c74d22e
RB
41
42 git_buf_printf(&buf, "%s %d", "woop", 42);
43 cl_assert(git_buf_oom(&buf) == 0);
1a6e8f8a 44 cl_assert_equal_s("shoop da 23 woop 42", git_buf_cstr(&buf));
8c74d22e 45
ac3d33df 46 git_buf_dispose(&buf);
8c74d22e
RB
47}
48
49/* more thorough test of concatenation options */
50void test_core_buffer__2(void)
51{
52 git_buf buf = GIT_BUF_INIT;
53 int i;
97769280 54 char data[128];
8c74d22e
RB
55
56 cl_assert(buf.size == 0);
57
58 /* this must be safe to do */
ac3d33df 59 git_buf_dispose(&buf);
8c74d22e
RB
60 cl_assert(buf.size == 0);
61 cl_assert(buf.asize == 0);
62
63 /* empty buffer should be empty string */
1a6e8f8a 64 cl_assert_equal_s("", git_buf_cstr(&buf));
8c74d22e 65 cl_assert(buf.size == 0);
c63728cd 66 /* cl_assert(buf.asize == 0); -- should not assume what git_buf does */
8c74d22e
RB
67
68 /* free should set us back to the beginning */
ac3d33df 69 git_buf_dispose(&buf);
8c74d22e
RB
70 cl_assert(buf.size == 0);
71 cl_assert(buf.asize == 0);
72
73 /* add letter */
74 git_buf_putc(&buf, '+');
75 cl_assert(git_buf_oom(&buf) == 0);
1a6e8f8a 76 cl_assert_equal_s("+", git_buf_cstr(&buf));
8c74d22e
RB
77
78 /* add letter again */
79 git_buf_putc(&buf, '+');
80 cl_assert(git_buf_oom(&buf) == 0);
1a6e8f8a 81 cl_assert_equal_s("++", git_buf_cstr(&buf));
8c74d22e
RB
82
83 /* let's try that a few times */
84 for (i = 0; i < 16; ++i) {
85 git_buf_putc(&buf, '+');
86 cl_assert(git_buf_oom(&buf) == 0);
87 }
1a6e8f8a 88 cl_assert_equal_s("++++++++++++++++++", git_buf_cstr(&buf));
8c74d22e 89
ac3d33df 90 git_buf_dispose(&buf);
8c74d22e
RB
91
92 /* add data */
93 git_buf_put(&buf, "xo", 2);
94 cl_assert(git_buf_oom(&buf) == 0);
1a6e8f8a 95 cl_assert_equal_s("xo", git_buf_cstr(&buf));
8c74d22e
RB
96
97 /* add letter again */
98 git_buf_put(&buf, "xo", 2);
99 cl_assert(git_buf_oom(&buf) == 0);
1a6e8f8a 100 cl_assert_equal_s("xoxo", git_buf_cstr(&buf));
8c74d22e
RB
101
102 /* let's try that a few times */
103 for (i = 0; i < 16; ++i) {
104 git_buf_put(&buf, "xo", 2);
105 cl_assert(git_buf_oom(&buf) == 0);
106 }
1a6e8f8a 107 cl_assert_equal_s("xoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxo",
8c74d22e
RB
108 git_buf_cstr(&buf));
109
ac3d33df 110 git_buf_dispose(&buf);
8c74d22e
RB
111
112 /* set to string */
113 git_buf_sets(&buf, test_string);
114 cl_assert(git_buf_oom(&buf) == 0);
1a6e8f8a 115 cl_assert_equal_s(test_string, git_buf_cstr(&buf));
8c74d22e
RB
116
117 /* append string */
118 git_buf_puts(&buf, test_string);
119 cl_assert(git_buf_oom(&buf) == 0);
1a6e8f8a 120 cl_assert_equal_s(test_string_x2, git_buf_cstr(&buf));
8c74d22e
RB
121
122 /* set to string again (should overwrite - not append) */
123 git_buf_sets(&buf, test_string);
124 cl_assert(git_buf_oom(&buf) == 0);
1a6e8f8a 125 cl_assert_equal_s(test_string, git_buf_cstr(&buf));
8c74d22e
RB
126
127 /* test clear */
128 git_buf_clear(&buf);
1a6e8f8a 129 cl_assert_equal_s("", git_buf_cstr(&buf));
8c74d22e 130
ac3d33df 131 git_buf_dispose(&buf);
7df41387
RB
132
133 /* test extracting data into buffer */
134 git_buf_puts(&buf, REP4("0123456789"));
135 cl_assert(git_buf_oom(&buf) == 0);
136
97769280 137 git_buf_copy_cstr(data, sizeof(data), &buf);
1a6e8f8a 138 cl_assert_equal_s(REP4("0123456789"), data);
7df41387 139 git_buf_copy_cstr(data, 11, &buf);
1a6e8f8a 140 cl_assert_equal_s("0123456789", data);
7df41387 141 git_buf_copy_cstr(data, 3, &buf);
1a6e8f8a 142 cl_assert_equal_s("01", data);
7df41387 143 git_buf_copy_cstr(data, 1, &buf);
1a6e8f8a 144 cl_assert_equal_s("", data);
7df41387 145
97769280 146 git_buf_copy_cstr(data, sizeof(data), &buf);
1a6e8f8a 147 cl_assert_equal_s(REP4("0123456789"), data);
97769280
RB
148
149 git_buf_sets(&buf, REP256("x"));
150 git_buf_copy_cstr(data, sizeof(data), &buf);
151 /* since sizeof(data) == 128, only 127 bytes should be copied */
1a6e8f8a 152 cl_assert_equal_s(REP4(REP16("x")) REP16("x") REP16("x")
97769280 153 REP16("x") "xxxxxxxxxxxxxxx", data);
7df41387 154
ac3d33df 155 git_buf_dispose(&buf);
7df41387 156
97769280 157 git_buf_copy_cstr(data, sizeof(data), &buf);
1a6e8f8a 158 cl_assert_equal_s("", data);
8c74d22e
RB
159}
160
161/* let's do some tests with larger buffers to push our limits */
162void test_core_buffer__3(void)
163{
164 git_buf buf = GIT_BUF_INIT;
165
166 /* set to string */
167 git_buf_set(&buf, test_4096, 4096);
168 cl_assert(git_buf_oom(&buf) == 0);
1a6e8f8a 169 cl_assert_equal_s(test_4096, git_buf_cstr(&buf));
8c74d22e
RB
170
171 /* append string */
172 git_buf_puts(&buf, test_4096);
173 cl_assert(git_buf_oom(&buf) == 0);
1a6e8f8a 174 cl_assert_equal_s(test_8192, git_buf_cstr(&buf));
8c74d22e
RB
175
176 /* set to string again (should overwrite - not append) */
177 git_buf_set(&buf, test_4096, 4096);
178 cl_assert(git_buf_oom(&buf) == 0);
1a6e8f8a 179 cl_assert_equal_s(test_4096, git_buf_cstr(&buf));
8c74d22e 180
ac3d33df 181 git_buf_dispose(&buf);
8c74d22e
RB
182}
183
184/* let's try some producer/consumer tests */
185void test_core_buffer__4(void)
186{
187 git_buf buf = GIT_BUF_INIT;
188 int i;
189
190 for (i = 0; i < 10; ++i) {
191 git_buf_puts(&buf, "1234"); /* add 4 */
192 cl_assert(git_buf_oom(&buf) == 0);
193 git_buf_consume(&buf, buf.ptr + 2); /* eat the first two */
194 cl_assert(strlen(git_buf_cstr(&buf)) == (size_t)((i + 1) * 2));
195 }
196 /* we have appended 1234 10x and removed the first 20 letters */
1a6e8f8a 197 cl_assert_equal_s("12341234123412341234", git_buf_cstr(&buf));
8c74d22e
RB
198
199 git_buf_consume(&buf, NULL);
1a6e8f8a 200 cl_assert_equal_s("12341234123412341234", git_buf_cstr(&buf));
8c74d22e
RB
201
202 git_buf_consume(&buf, "invalid pointer");
1a6e8f8a 203 cl_assert_equal_s("12341234123412341234", git_buf_cstr(&buf));
8c74d22e
RB
204
205 git_buf_consume(&buf, buf.ptr);
1a6e8f8a 206 cl_assert_equal_s("12341234123412341234", git_buf_cstr(&buf));
8c74d22e
RB
207
208 git_buf_consume(&buf, buf.ptr + 1);
1a6e8f8a 209 cl_assert_equal_s("2341234123412341234", git_buf_cstr(&buf));
8c74d22e
RB
210
211 git_buf_consume(&buf, buf.ptr + buf.size);
1a6e8f8a 212 cl_assert_equal_s("", git_buf_cstr(&buf));
8c74d22e 213
ac3d33df 214 git_buf_dispose(&buf);
8c74d22e
RB
215}
216
217
218static void
219check_buf_append(
220 const char* data_a,
221 const char* data_b,
222 const char* expected_data,
13224ea4
VM
223 size_t expected_size,
224 size_t expected_asize)
8c74d22e
RB
225{
226 git_buf tgt = GIT_BUF_INIT;
227
228 git_buf_sets(&tgt, data_a);
229 cl_assert(git_buf_oom(&tgt) == 0);
230 git_buf_puts(&tgt, data_b);
231 cl_assert(git_buf_oom(&tgt) == 0);
1a6e8f8a 232 cl_assert_equal_s(expected_data, git_buf_cstr(&tgt));
22a2d3d5 233 cl_assert_equal_i(tgt.size, expected_size);
8c74d22e 234 if (expected_asize > 0)
22a2d3d5 235 cl_assert_equal_i(tgt.asize, expected_asize);
8c74d22e 236
ac3d33df 237 git_buf_dispose(&tgt);
8c74d22e
RB
238}
239
240static void
241check_buf_append_abc(
242 const char* buf_a,
243 const char* buf_b,
244 const char* buf_c,
245 const char* expected_ab,
246 const char* expected_abc,
247 const char* expected_abca,
248 const char* expected_abcab,
249 const char* expected_abcabc)
250{
251 git_buf buf = GIT_BUF_INIT;
252
253 git_buf_sets(&buf, buf_a);
254 cl_assert(git_buf_oom(&buf) == 0);
1a6e8f8a 255 cl_assert_equal_s(buf_a, git_buf_cstr(&buf));
8c74d22e
RB
256
257 git_buf_puts(&buf, buf_b);
258 cl_assert(git_buf_oom(&buf) == 0);
1a6e8f8a 259 cl_assert_equal_s(expected_ab, git_buf_cstr(&buf));
8c74d22e
RB
260
261 git_buf_puts(&buf, buf_c);
262 cl_assert(git_buf_oom(&buf) == 0);
1a6e8f8a 263 cl_assert_equal_s(expected_abc, git_buf_cstr(&buf));
8c74d22e
RB
264
265 git_buf_puts(&buf, buf_a);
266 cl_assert(git_buf_oom(&buf) == 0);
1a6e8f8a 267 cl_assert_equal_s(expected_abca, git_buf_cstr(&buf));
8c74d22e
RB
268
269 git_buf_puts(&buf, buf_b);
270 cl_assert(git_buf_oom(&buf) == 0);
1a6e8f8a 271 cl_assert_equal_s(expected_abcab, git_buf_cstr(&buf));
8c74d22e
RB
272
273 git_buf_puts(&buf, buf_c);
274 cl_assert(git_buf_oom(&buf) == 0);
1a6e8f8a 275 cl_assert_equal_s(expected_abcabc, git_buf_cstr(&buf));
8c74d22e 276
ac3d33df 277 git_buf_dispose(&buf);
8c74d22e
RB
278}
279
280/* more variations on append tests */
281void test_core_buffer__5(void)
282{
92e0b679
VM
283 check_buf_append("", "", "", 0, 0);
284 check_buf_append("a", "", "a", 1, 0);
679b69c4 285 check_buf_append("", "a", "a", 1, 8);
8c74d22e 286 check_buf_append("", "a", "a", 1, 8);
8c74d22e
RB
287 check_buf_append("a", "b", "ab", 2, 8);
288 check_buf_append("", "abcdefgh", "abcdefgh", 8, 16);
289 check_buf_append("abcdefgh", "", "abcdefgh", 8, 16);
290
291 /* buffer with starting asize will grow to:
292 * 1 -> 2, 2 -> 3, 3 -> 5, 4 -> 6, 5 -> 8, 6 -> 9,
293 * 7 -> 11, 8 -> 12, 9 -> 14, 10 -> 15, 11 -> 17, 12 -> 18,
294 * 13 -> 20, 14 -> 21, 15 -> 23, 16 -> 24, 17 -> 26, 18 -> 27,
295 * 19 -> 29, 20 -> 30, 21 -> 32, 22 -> 33, 23 -> 35, 24 -> 36,
296 * ...
297 * follow sequence until value > target size,
298 * then round up to nearest multiple of 8.
299 */
300
301 check_buf_append("abcdefgh", "/", "abcdefgh/", 9, 16);
c63728cd 302 check_buf_append("abcdefgh", "ijklmno", "abcdefghijklmno", 15, 16);
8c74d22e
RB
303 check_buf_append("abcdefgh", "ijklmnop", "abcdefghijklmnop", 16, 24);
304 check_buf_append("0123456789", "0123456789",
305 "01234567890123456789", 20, 24);
306 check_buf_append(REP16("x"), REP16("o"),
307 REP16("x") REP16("o"), 32, 40);
308
c63728cd 309 check_buf_append(test_4096, "", test_4096, 4096, 4104);
22a2d3d5 310 check_buf_append(test_4096, test_4096, test_8192, 8192, 8200);
8c74d22e
RB
311
312 /* check sequences of appends */
313 check_buf_append_abc("a", "b", "c",
314 "ab", "abc", "abca", "abcab", "abcabc");
315 check_buf_append_abc("a1", "b2", "c3",
316 "a1b2", "a1b2c3", "a1b2c3a1",
317 "a1b2c3a1b2", "a1b2c3a1b2c3");
318 check_buf_append_abc("a1/", "b2/", "c3/",
319 "a1/b2/", "a1/b2/c3/", "a1/b2/c3/a1/",
320 "a1/b2/c3/a1/b2/", "a1/b2/c3/a1/b2/c3/");
321}
322
323/* test swap */
324void test_core_buffer__6(void)
325{
326 git_buf a = GIT_BUF_INIT;
327 git_buf b = GIT_BUF_INIT;
328
329 git_buf_sets(&a, "foo");
330 cl_assert(git_buf_oom(&a) == 0);
331 git_buf_sets(&b, "bar");
332 cl_assert(git_buf_oom(&b) == 0);
333
1a6e8f8a
RB
334 cl_assert_equal_s("foo", git_buf_cstr(&a));
335 cl_assert_equal_s("bar", git_buf_cstr(&b));
8c74d22e
RB
336
337 git_buf_swap(&a, &b);
338
1a6e8f8a
RB
339 cl_assert_equal_s("bar", git_buf_cstr(&a));
340 cl_assert_equal_s("foo", git_buf_cstr(&b));
8c74d22e 341
ac3d33df
JK
342 git_buf_dispose(&a);
343 git_buf_dispose(&b);
8c74d22e
RB
344}
345
346
97769280 347/* test detach/attach data */
8c74d22e
RB
348void test_core_buffer__7(void)
349{
97769280 350 const char *fun = "This is fun";
8c74d22e
RB
351 git_buf a = GIT_BUF_INIT;
352 char *b = NULL;
353
354 git_buf_sets(&a, "foo");
355 cl_assert(git_buf_oom(&a) == 0);
1a6e8f8a 356 cl_assert_equal_s("foo", git_buf_cstr(&a));
8c74d22e 357
97769280 358 b = git_buf_detach(&a);
8c74d22e 359
1a6e8f8a
RB
360 cl_assert_equal_s("foo", b);
361 cl_assert_equal_s("", a.ptr);
8c74d22e
RB
362 git__free(b);
363
97769280 364 b = git_buf_detach(&a);
8c74d22e 365
1a6e8f8a
RB
366 cl_assert_equal_s(NULL, b);
367 cl_assert_equal_s("", a.ptr);
8c74d22e 368
ac3d33df 369 git_buf_dispose(&a);
97769280
RB
370
371 b = git__strdup(fun);
372 git_buf_attach(&a, b, 0);
373
1a6e8f8a 374 cl_assert_equal_s(fun, a.ptr);
13224ea4
VM
375 cl_assert(a.size == strlen(fun));
376 cl_assert(a.asize == strlen(fun) + 1);
97769280 377
ac3d33df 378 git_buf_dispose(&a);
97769280
RB
379
380 b = git__strdup(fun);
381 git_buf_attach(&a, b, strlen(fun) + 1);
382
1a6e8f8a 383 cl_assert_equal_s(fun, a.ptr);
13224ea4
VM
384 cl_assert(a.size == strlen(fun));
385 cl_assert(a.asize == strlen(fun) + 1);
97769280 386
ac3d33df 387 git_buf_dispose(&a);
8c74d22e
RB
388}
389
390
391static void
3aa294fd
RB
392check_joinbuf_2(
393 const char *a,
394 const char *b,
395 const char *expected)
396{
397 char sep = '/';
398 git_buf buf = GIT_BUF_INIT;
399
3aa294fd
RB
400 git_buf_join(&buf, sep, a, b);
401 cl_assert(git_buf_oom(&buf) == 0);
1a6e8f8a 402 cl_assert_equal_s(expected, git_buf_cstr(&buf));
ac3d33df 403 git_buf_dispose(&buf);
3aa294fd
RB
404}
405
abdaf936
PR
406static void
407check_joinbuf_overlapped(
408 const char *oldval,
409 int ofs_a,
410 const char *b,
411 const char *expected)
412{
413 char sep = '/';
414 git_buf buf = GIT_BUF_INIT;
415
416 git_buf_sets(&buf, oldval);
417 git_buf_join(&buf, sep, buf.ptr + ofs_a, b);
418 cl_assert(git_buf_oom(&buf) == 0);
419 cl_assert_equal_s(expected, git_buf_cstr(&buf));
ac3d33df 420 git_buf_dispose(&buf);
abdaf936
PR
421}
422
3aa294fd
RB
423static void
424check_joinbuf_n_2(
8c74d22e
RB
425 const char *a,
426 const char *b,
427 const char *expected)
428{
429 char sep = '/';
430 git_buf buf = GIT_BUF_INIT;
431
432 git_buf_sets(&buf, a);
433 cl_assert(git_buf_oom(&buf) == 0);
434
3aa294fd 435 git_buf_join_n(&buf, sep, 1, b);
8c74d22e 436 cl_assert(git_buf_oom(&buf) == 0);
1a6e8f8a 437 cl_assert_equal_s(expected, git_buf_cstr(&buf));
8c74d22e 438
ac3d33df 439 git_buf_dispose(&buf);
8c74d22e
RB
440}
441
442static void
3aa294fd 443check_joinbuf_n_4(
8c74d22e
RB
444 const char *a,
445 const char *b,
446 const char *c,
447 const char *d,
448 const char *expected)
449{
450 char sep = ';';
451 git_buf buf = GIT_BUF_INIT;
3aa294fd 452 git_buf_join_n(&buf, sep, 4, a, b, c, d);
8c74d22e 453 cl_assert(git_buf_oom(&buf) == 0);
1a6e8f8a 454 cl_assert_equal_s(expected, git_buf_cstr(&buf));
ac3d33df 455 git_buf_dispose(&buf);
8c74d22e
RB
456}
457
458/* test join */
459void test_core_buffer__8(void)
460{
461 git_buf a = GIT_BUF_INIT;
462
3aa294fd 463 git_buf_join_n(&a, '/', 1, "foo");
8c74d22e 464 cl_assert(git_buf_oom(&a) == 0);
1a6e8f8a 465 cl_assert_equal_s("foo", git_buf_cstr(&a));
8c74d22e 466
3aa294fd 467 git_buf_join_n(&a, '/', 1, "bar");
8c74d22e 468 cl_assert(git_buf_oom(&a) == 0);
1a6e8f8a 469 cl_assert_equal_s("foo/bar", git_buf_cstr(&a));
8c74d22e 470
3aa294fd 471 git_buf_join_n(&a, '/', 1, "baz");
8c74d22e 472 cl_assert(git_buf_oom(&a) == 0);
1a6e8f8a 473 cl_assert_equal_s("foo/bar/baz", git_buf_cstr(&a));
8c74d22e 474
ac3d33df 475 git_buf_dispose(&a);
8c74d22e 476
17c92bea
RB
477 check_joinbuf_2(NULL, "", "");
478 check_joinbuf_2(NULL, "a", "a");
479 check_joinbuf_2(NULL, "/a", "/a");
3aa294fd
RB
480 check_joinbuf_2("", "", "");
481 check_joinbuf_2("", "a", "a");
482 check_joinbuf_2("", "/a", "/a");
483 check_joinbuf_2("a", "", "a/");
484 check_joinbuf_2("a", "/", "a/");
485 check_joinbuf_2("a", "b", "a/b");
486 check_joinbuf_2("/", "a", "/a");
487 check_joinbuf_2("/", "", "/");
488 check_joinbuf_2("/a", "/b", "/a/b");
489 check_joinbuf_2("/a", "/b/", "/a/b/");
490 check_joinbuf_2("/a/", "b/", "/a/b/");
491 check_joinbuf_2("/a/", "/b/", "/a/b/");
492 check_joinbuf_2("/a/", "//b/", "/a/b/");
493 check_joinbuf_2("/abcd", "/defg", "/abcd/defg");
494 check_joinbuf_2("/abcd", "/defg/", "/abcd/defg/");
495 check_joinbuf_2("/abcd/", "defg/", "/abcd/defg/");
496 check_joinbuf_2("/abcd/", "/defg/", "/abcd/defg/");
497
abdaf936
PR
498 check_joinbuf_overlapped("abcd", 0, "efg", "abcd/efg");
499 check_joinbuf_overlapped("abcd", 1, "efg", "bcd/efg");
500 check_joinbuf_overlapped("abcd", 2, "efg", "cd/efg");
501 check_joinbuf_overlapped("abcd", 3, "efg", "d/efg");
502 check_joinbuf_overlapped("abcd", 4, "efg", "efg");
503 check_joinbuf_overlapped("abc/", 2, "efg", "c/efg");
504 check_joinbuf_overlapped("abc/", 3, "efg", "/efg");
505 check_joinbuf_overlapped("abc/", 4, "efg", "efg");
506 check_joinbuf_overlapped("abcd", 3, "", "d/");
507 check_joinbuf_overlapped("abcd", 4, "", "");
508 check_joinbuf_overlapped("abc/", 2, "", "c/");
509 check_joinbuf_overlapped("abc/", 3, "", "/");
510 check_joinbuf_overlapped("abc/", 4, "", "");
511
3aa294fd
RB
512 check_joinbuf_n_2("", "", "");
513 check_joinbuf_n_2("", "a", "a");
514 check_joinbuf_n_2("", "/a", "/a");
515 check_joinbuf_n_2("a", "", "a/");
516 check_joinbuf_n_2("a", "/", "a/");
517 check_joinbuf_n_2("a", "b", "a/b");
518 check_joinbuf_n_2("/", "a", "/a");
519 check_joinbuf_n_2("/", "", "/");
520 check_joinbuf_n_2("/a", "/b", "/a/b");
521 check_joinbuf_n_2("/a", "/b/", "/a/b/");
522 check_joinbuf_n_2("/a/", "b/", "/a/b/");
523 check_joinbuf_n_2("/a/", "/b/", "/a/b/");
524 check_joinbuf_n_2("/abcd", "/defg", "/abcd/defg");
525 check_joinbuf_n_2("/abcd", "/defg/", "/abcd/defg/");
526 check_joinbuf_n_2("/abcd/", "defg/", "/abcd/defg/");
527 check_joinbuf_n_2("/abcd/", "/defg/", "/abcd/defg/");
528
529 check_joinbuf_n_4("", "", "", "", "");
530 check_joinbuf_n_4("", "a", "", "", "a;");
531 check_joinbuf_n_4("a", "", "", "", "a;");
532 check_joinbuf_n_4("", "", "", "a", "a");
533 check_joinbuf_n_4("a", "b", "", ";c;d;", "a;b;c;d;");
534 check_joinbuf_n_4("a", "b", "", ";c;d", "a;b;c;d");
535 check_joinbuf_n_4("abcd", "efgh", "ijkl", "mnop", "abcd;efgh;ijkl;mnop");
536 check_joinbuf_n_4("abcd;", "efgh;", "ijkl;", "mnop;", "abcd;efgh;ijkl;mnop;");
537 check_joinbuf_n_4(";abcd;", ";efgh;", ";ijkl;", ";mnop;", ";abcd;efgh;ijkl;mnop;");
8c74d22e
RB
538}
539
969d588d
RB
540void test_core_buffer__9(void)
541{
542 git_buf buf = GIT_BUF_INIT;
543
544 /* just some exhaustive tests of various separator placement */
545 char *a[] = { "", "-", "a-", "-a", "-a-" };
546 char *b[] = { "", "-", "b-", "-b", "-b-" };
547 char sep[] = { 0, '-', '/' };
548 char *expect_null[] = { "", "-", "a-", "-a", "-a-",
549 "-", "--", "a--", "-a-", "-a--",
550 "b-", "-b-", "a-b-", "-ab-", "-a-b-",
551 "-b", "--b", "a--b", "-a-b", "-a--b",
552 "-b-", "--b-", "a--b-", "-a-b-", "-a--b-" };
553 char *expect_dash[] = { "", "-", "a-", "-a-", "-a-",
554 "-", "-", "a-", "-a-", "-a-",
555 "b-", "-b-", "a-b-", "-a-b-", "-a-b-",
556 "-b", "-b", "a-b", "-a-b", "-a-b",
557 "-b-", "-b-", "a-b-", "-a-b-", "-a-b-" };
558 char *expect_slas[] = { "", "-/", "a-/", "-a/", "-a-/",
559 "-", "-/-", "a-/-", "-a/-", "-a-/-",
560 "b-", "-/b-", "a-/b-", "-a/b-", "-a-/b-",
561 "-b", "-/-b", "a-/-b", "-a/-b", "-a-/-b",
562 "-b-", "-/-b-", "a-/-b-", "-a/-b-", "-a-/-b-" };
563 char **expect_values[] = { expect_null, expect_dash, expect_slas };
564 char separator, **expect;
565 unsigned int s, i, j;
566
567 for (s = 0; s < sizeof(sep) / sizeof(char); ++s) {
568 separator = sep[s];
569 expect = expect_values[s];
570
571 for (j = 0; j < sizeof(b) / sizeof(char*); ++j) {
572 for (i = 0; i < sizeof(a) / sizeof(char*); ++i) {
573 git_buf_join(&buf, separator, a[i], b[j]);
1a6e8f8a 574 cl_assert_equal_s(*expect, buf.ptr);
969d588d
RB
575 expect++;
576 }
577 }
578 }
579
ac3d33df 580 git_buf_dispose(&buf);
969d588d 581}
a4c291ef
RB
582
583void test_core_buffer__10(void)
584{
585 git_buf a = GIT_BUF_INIT;
586
587 cl_git_pass(git_buf_join_n(&a, '/', 1, "test"));
1a6e8f8a 588 cl_assert_equal_s(a.ptr, "test");
a4c291ef 589 cl_git_pass(git_buf_join_n(&a, '/', 1, "string"));
1a6e8f8a 590 cl_assert_equal_s(a.ptr, "test/string");
a4c291ef
RB
591 git_buf_clear(&a);
592 cl_git_pass(git_buf_join_n(&a, '/', 3, "test", "string", "join"));
1a6e8f8a 593 cl_assert_equal_s(a.ptr, "test/string/join");
a4c291ef 594 cl_git_pass(git_buf_join_n(&a, '/', 2, a.ptr, "more"));
1a6e8f8a 595 cl_assert_equal_s(a.ptr, "test/string/join/test/string/join/more");
a4c291ef 596
ac3d33df 597 git_buf_dispose(&a);
a4c291ef 598}
41a82592 599
18234b14
RB
600void test_core_buffer__join3(void)
601{
602 git_buf a = GIT_BUF_INIT;
603
604 cl_git_pass(git_buf_join3(&a, '/', "test", "string", "join"));
605 cl_assert_equal_s("test/string/join", a.ptr);
606 cl_git_pass(git_buf_join3(&a, '/', "test/", "string", "join"));
607 cl_assert_equal_s("test/string/join", a.ptr);
608 cl_git_pass(git_buf_join3(&a, '/', "test/", "/string", "join"));
609 cl_assert_equal_s("test/string/join", a.ptr);
610 cl_git_pass(git_buf_join3(&a, '/', "test/", "/string/", "join"));
611 cl_assert_equal_s("test/string/join", a.ptr);
612 cl_git_pass(git_buf_join3(&a, '/', "test/", "/string/", "/join"));
613 cl_assert_equal_s("test/string/join", a.ptr);
614
615 cl_git_pass(git_buf_join3(&a, '/', "", "string", "join"));
616 cl_assert_equal_s("string/join", a.ptr);
617 cl_git_pass(git_buf_join3(&a, '/', "", "string/", "join"));
618 cl_assert_equal_s("string/join", a.ptr);
619 cl_git_pass(git_buf_join3(&a, '/', "", "string/", "/join"));
620 cl_assert_equal_s("string/join", a.ptr);
621
622 cl_git_pass(git_buf_join3(&a, '/', "string", "", "join"));
623 cl_assert_equal_s("string/join", a.ptr);
624 cl_git_pass(git_buf_join3(&a, '/', "string/", "", "join"));
625 cl_assert_equal_s("string/join", a.ptr);
626 cl_git_pass(git_buf_join3(&a, '/', "string/", "", "/join"));
627 cl_assert_equal_s("string/join", a.ptr);
628
ac3d33df 629 git_buf_dispose(&a);
18234b14
RB
630}
631
41a82592
RB
632void test_core_buffer__11(void)
633{
634 git_buf a = GIT_BUF_INIT;
41a82592
RB
635 char *t1[] = { "nothing", "in", "common" };
636 char *t2[] = { "something", "something else", "some other" };
637 char *t3[] = { "something", "some fun", "no fun" };
638 char *t4[] = { "happy", "happier", "happiest" };
639 char *t5[] = { "happiest", "happier", "happy" };
640 char *t6[] = { "no", "nope", "" };
641 char *t7[] = { "", "doesn't matter" };
642
c25aa7cd 643 cl_git_pass(git_buf_common_prefix(&a, t1, 3));
41a82592
RB
644 cl_assert_equal_s(a.ptr, "");
645
c25aa7cd 646 cl_git_pass(git_buf_common_prefix(&a, t2, 3));
41a82592
RB
647 cl_assert_equal_s(a.ptr, "some");
648
c25aa7cd 649 cl_git_pass(git_buf_common_prefix(&a, t3, 3));
41a82592
RB
650 cl_assert_equal_s(a.ptr, "");
651
c25aa7cd 652 cl_git_pass(git_buf_common_prefix(&a, t4, 3));
41a82592
RB
653 cl_assert_equal_s(a.ptr, "happ");
654
c25aa7cd 655 cl_git_pass(git_buf_common_prefix(&a, t5, 3));
41a82592
RB
656 cl_assert_equal_s(a.ptr, "happ");
657
c25aa7cd 658 cl_git_pass(git_buf_common_prefix(&a, t6, 3));
41a82592
RB
659 cl_assert_equal_s(a.ptr, "");
660
c25aa7cd 661 cl_git_pass(git_buf_common_prefix(&a, t7, 3));
41a82592
RB
662 cl_assert_equal_s(a.ptr, "");
663
ac3d33df 664 git_buf_dispose(&a);
41a82592 665}
039fc406
RB
666
667void test_core_buffer__rfind_variants(void)
668{
669 git_buf a = GIT_BUF_INIT;
670 ssize_t len;
671
672 cl_git_pass(git_buf_sets(&a, "/this/is/it/"));
673
674 len = (ssize_t)git_buf_len(&a);
675
676 cl_assert(git_buf_rfind(&a, '/') == len - 1);
677 cl_assert(git_buf_rfind_next(&a, '/') == len - 4);
678
679 cl_assert(git_buf_rfind(&a, 'i') == len - 3);
680 cl_assert(git_buf_rfind_next(&a, 'i') == len - 3);
681
682 cl_assert(git_buf_rfind(&a, 'h') == 2);
683 cl_assert(git_buf_rfind_next(&a, 'h') == 2);
684
685 cl_assert(git_buf_rfind(&a, 'q') == -1);
686 cl_assert(git_buf_rfind_next(&a, 'q') == -1);
687
ac3d33df 688 git_buf_dispose(&a);
039fc406
RB
689}
690
691void test_core_buffer__puts_escaped(void)
692{
693 git_buf a = GIT_BUF_INIT;
694
695 git_buf_clear(&a);
c25aa7cd 696 cl_git_pass(git_buf_puts_escaped(&a, "this is a test", "", ""));
039fc406
RB
697 cl_assert_equal_s("this is a test", a.ptr);
698
699 git_buf_clear(&a);
c25aa7cd 700 cl_git_pass(git_buf_puts_escaped(&a, "this is a test", "t", "\\"));
039fc406
RB
701 cl_assert_equal_s("\\this is a \\tes\\t", a.ptr);
702
703 git_buf_clear(&a);
c25aa7cd 704 cl_git_pass(git_buf_puts_escaped(&a, "this is a test", "i ", "__"));
039fc406
RB
705 cl_assert_equal_s("th__is__ __is__ a__ test", a.ptr);
706
707 git_buf_clear(&a);
c25aa7cd 708 cl_git_pass(git_buf_puts_escape_regex(&a, "^match\\s*[A-Z]+.*"));
039fc406
RB
709 cl_assert_equal_s("\\^match\\\\s\\*\\[A-Z\\]\\+\\.\\*", a.ptr);
710
ac3d33df 711 git_buf_dispose(&a);
039fc406 712}
02a0d651 713
714static void assert_unescape(char *expected, char *to_unescape) {
715 git_buf buf = GIT_BUF_INIT;
716
717 cl_git_pass(git_buf_sets(&buf, to_unescape));
c25aa7cd 718 git_buf_unescape(&buf);
02a0d651 719 cl_assert_equal_s(expected, buf.ptr);
e9ca852e 720 cl_assert_equal_sz(strlen(expected), buf.size);
02a0d651 721
ac3d33df 722 git_buf_dispose(&buf);
02a0d651 723}
724
725void test_core_buffer__unescape(void)
726{
727 assert_unescape("Escaped\\", "Es\\ca\\ped\\");
728 assert_unescape("Es\\caped\\", "Es\\\\ca\\ped\\\\");
729 assert_unescape("\\", "\\");
730 assert_unescape("\\", "\\\\");
731 assert_unescape("", "");
732}
2d3579be 733
e003f83a 734void test_core_buffer__encode_base64(void)
2d3579be
RB
735{
736 git_buf buf = GIT_BUF_INIT;
737
738 /* t h i s
739 * 0x 74 68 69 73
740 * 0b 01110100 01101000 01101001 01110011
741 * 0b 011101 000110 100001 101001 011100 110000
742 * 0x 1d 06 21 29 1c 30
743 * d G h p c w
744 */
e003f83a 745 cl_git_pass(git_buf_encode_base64(&buf, "this", 4));
2d3579be
RB
746 cl_assert_equal_s("dGhpcw==", buf.ptr);
747
748 git_buf_clear(&buf);
e003f83a 749 cl_git_pass(git_buf_encode_base64(&buf, "this!", 5));
2d3579be
RB
750 cl_assert_equal_s("dGhpcyE=", buf.ptr);
751
752 git_buf_clear(&buf);
e003f83a 753 cl_git_pass(git_buf_encode_base64(&buf, "this!\n", 6));
2d3579be
RB
754 cl_assert_equal_s("dGhpcyEK", buf.ptr);
755
ac3d33df 756 git_buf_dispose(&buf);
2d3579be 757}
0d65acad 758
e003f83a 759void test_core_buffer__decode_base64(void)
e349ed50
ET
760{
761 git_buf buf = GIT_BUF_INIT;
762
e003f83a
ET
763 cl_git_pass(git_buf_decode_base64(&buf, "dGhpcw==", 8));
764 cl_assert_equal_s("this", buf.ptr);
765
766 git_buf_clear(&buf);
767 cl_git_pass(git_buf_decode_base64(&buf, "dGhpcyE=", 8));
768 cl_assert_equal_s("this!", buf.ptr);
769
770 git_buf_clear(&buf);
771 cl_git_pass(git_buf_decode_base64(&buf, "dGhpcyEK", 8));
772 cl_assert_equal_s("this!\n", buf.ptr);
773
774 cl_git_fail(git_buf_decode_base64(&buf, "This is not a valid base64 string!!!", 36));
775 cl_assert_equal_s("this!\n", buf.ptr);
776
ac3d33df 777 git_buf_dispose(&buf);
e003f83a
ET
778}
779
780void test_core_buffer__encode_base85(void)
781{
782 git_buf buf = GIT_BUF_INIT;
783
784 cl_git_pass(git_buf_encode_base85(&buf, "this", 4));
e349ed50
ET
785 cl_assert_equal_s("bZBXF", buf.ptr);
786 git_buf_clear(&buf);
787
e003f83a 788 cl_git_pass(git_buf_encode_base85(&buf, "two rnds", 8));
e349ed50
ET
789 cl_assert_equal_s("ba!tca&BaE", buf.ptr);
790 git_buf_clear(&buf);
791
e003f83a 792 cl_git_pass(git_buf_encode_base85(&buf, "this is base 85 encoded",
e349ed50
ET
793 strlen("this is base 85 encoded")));
794 cl_assert_equal_s("bZBXFAZc?TVqtS-AUHK3Wo~0{WMyOk", buf.ptr);
795 git_buf_clear(&buf);
796
ac3d33df 797 git_buf_dispose(&buf);
e349ed50
ET
798}
799
5b78dbdb
ET
800void test_core_buffer__decode_base85(void)
801{
802 git_buf buf = GIT_BUF_INIT;
803
804 cl_git_pass(git_buf_decode_base85(&buf, "bZBXF", 5, 4));
805 cl_assert_equal_sz(4, buf.size);
806 cl_assert_equal_s("this", buf.ptr);
807 git_buf_clear(&buf);
808
809 cl_git_pass(git_buf_decode_base85(&buf, "ba!tca&BaE", 10, 8));
810 cl_assert_equal_sz(8, buf.size);
811 cl_assert_equal_s("two rnds", buf.ptr);
812 git_buf_clear(&buf);
813
814 cl_git_pass(git_buf_decode_base85(&buf, "bZBXFAZc?TVqtS-AUHK3Wo~0{WMyOk", 30, 23));
815 cl_assert_equal_sz(23, buf.size);
816 cl_assert_equal_s("this is base 85 encoded", buf.ptr);
817 git_buf_clear(&buf);
818
ac3d33df 819 git_buf_dispose(&buf);
5b78dbdb
ET
820}
821
822void test_core_buffer__decode_base85_fails_gracefully(void)
823{
824 git_buf buf = GIT_BUF_INIT;
825
826 git_buf_puts(&buf, "foobar");
827
828 cl_git_fail(git_buf_decode_base85(&buf, "invalid charsZZ", 15, 42));
829 cl_git_fail(git_buf_decode_base85(&buf, "invalidchars__ ", 15, 42));
830 cl_git_fail(git_buf_decode_base85(&buf, "overflowZZ~~~~~", 15, 42));
831 cl_git_fail(git_buf_decode_base85(&buf, "truncated", 9, 42));
832 cl_assert_equal_sz(6, buf.size);
833 cl_assert_equal_s("foobar", buf.ptr);
6278fbc5 834
ac3d33df 835 git_buf_dispose(&buf);
5b78dbdb
ET
836}
837
0d65acad
RB
838void test_core_buffer__classify_with_utf8(void)
839{
840 char *data0 = "Simple text\n";
841 size_t data0len = 12;
842 char *data1 = "Is that UTF-8 data I see…\nYep!\n";
843 size_t data1len = 31;
844 char *data2 = "Internal NUL!!!\000\n\nI see you!\n";
845 size_t data2len = 29;
c0b01b75
ET
846 char *data3 = "\xef\xbb\xbfThis is UTF-8 with a BOM.\n";
847 size_t data3len = 20;
0d65acad
RB
848 git_buf b;
849
850 b.ptr = data0; b.size = b.asize = data0len;
c25aa7cd
PP
851 cl_assert(!git_buf_is_binary(&b));
852 cl_assert(!git_buf_contains_nul(&b));
0d65acad
RB
853
854 b.ptr = data1; b.size = b.asize = data1len;
c25aa7cd
PP
855 cl_assert(!git_buf_is_binary(&b));
856 cl_assert(!git_buf_contains_nul(&b));
0d65acad
RB
857
858 b.ptr = data2; b.size = b.asize = data2len;
c25aa7cd
PP
859 cl_assert(git_buf_is_binary(&b));
860 cl_assert(git_buf_contains_nul(&b));
c0b01b75
ET
861
862 b.ptr = data3; b.size = b.asize = data3len;
c25aa7cd
PP
863 cl_assert(!git_buf_is_binary(&b));
864 cl_assert(!git_buf_contains_nul(&b));
0d65acad 865}
9c454b00 866
5e5848eb 867#define SIMILARITY_TEST_DATA_1 \
d730d3f4
RB
868 "000\n001\n002\n003\n004\n005\n006\n007\n008\n009\n" \
869 "010\n011\n012\n013\n014\n015\n016\n017\n018\n019\n" \
870 "020\n021\n022\n023\n024\n025\n026\n027\n028\n029\n" \
871 "030\n031\n032\n033\n034\n035\n036\n037\n038\n039\n" \
872 "040\n041\n042\n043\n044\n045\n046\n047\n048\n049\n"
5e5848eb 873
9c454b00
RB
874void test_core_buffer__similarity_metric(void)
875{
5e5848eb 876 git_hashsig *a, *b;
9c454b00
RB
877 git_buf buf = GIT_BUF_INIT;
878 int sim;
879
880 /* in the first case, we compare data to itself and expect 100% match */
881
5e5848eb 882 cl_git_pass(git_buf_sets(&buf, SIMILARITY_TEST_DATA_1));
9bc8be3d
RB
883 cl_git_pass(git_hashsig_create(&a, buf.ptr, buf.size, GIT_HASHSIG_NORMAL));
884 cl_git_pass(git_hashsig_create(&b, buf.ptr, buf.size, GIT_HASHSIG_NORMAL));
9c454b00 885
5e5848eb 886 cl_assert_equal_i(100, git_hashsig_compare(a, b));
9c454b00 887
5e5848eb
RB
888 git_hashsig_free(a);
889 git_hashsig_free(b);
9c454b00 890
5e5848eb 891 /* if we change just a single byte, how much does that change magnify? */
9c454b00 892
5e5848eb 893 cl_git_pass(git_buf_sets(&buf, SIMILARITY_TEST_DATA_1));
9bc8be3d 894 cl_git_pass(git_hashsig_create(&a, buf.ptr, buf.size, GIT_HASHSIG_NORMAL));
5e5848eb 895 cl_git_pass(git_buf_sets(&buf,
d730d3f4
RB
896 "000\n001\n002\n003\n004\n005\n006\n007\n008\n009\n" \
897 "010\n011\n012\n013\n014\n015\n016\n017\n018\n019\n" \
898 "x020x\n021\n022\n023\n024\n025\n026\n027\n028\n029\n" \
899 "030\n031\n032\n033\n034\n035\n036\n037\n038\n039\n" \
900 "040\n041\n042\n043\n044\n045\n046\n047\n048\n049\n"
901 ));
9bc8be3d 902 cl_git_pass(git_hashsig_create(&b, buf.ptr, buf.size, GIT_HASHSIG_NORMAL));
9c454b00 903
5e5848eb 904 sim = git_hashsig_compare(a, b);
9c454b00 905
d730d3f4 906 cl_assert_in_range(95, sim, 100); /* expect >95% similarity */
9c454b00 907
5e5848eb
RB
908 git_hashsig_free(a);
909 git_hashsig_free(b);
9c454b00 910
5e5848eb 911 /* let's try comparing data to a superset of itself */
9c454b00 912
5e5848eb 913 cl_git_pass(git_buf_sets(&buf, SIMILARITY_TEST_DATA_1));
9bc8be3d 914 cl_git_pass(git_hashsig_create(&a, buf.ptr, buf.size, GIT_HASHSIG_NORMAL));
5e5848eb 915 cl_git_pass(git_buf_sets(&buf, SIMILARITY_TEST_DATA_1
d730d3f4 916 "050\n051\n052\n053\n054\n055\n056\n057\n058\n059\n"));
9bc8be3d 917 cl_git_pass(git_hashsig_create(&b, buf.ptr, buf.size, GIT_HASHSIG_NORMAL));
9c454b00 918
5e5848eb 919 sim = git_hashsig_compare(a, b);
d730d3f4 920 /* 20% lines added ~= 10% lines changed */
9c454b00 921
d730d3f4 922 cl_assert_in_range(85, sim, 95); /* expect similarity around 90% */
9c454b00 923
5e5848eb
RB
924 git_hashsig_free(a);
925 git_hashsig_free(b);
926
927 /* what if we keep about half the original data and add half new */
928
929 cl_git_pass(git_buf_sets(&buf, SIMILARITY_TEST_DATA_1));
9bc8be3d 930 cl_git_pass(git_hashsig_create(&a, buf.ptr, buf.size, GIT_HASHSIG_NORMAL));
5e5848eb 931 cl_git_pass(git_buf_sets(&buf,
d730d3f4
RB
932 "000\n001\n002\n003\n004\n005\n006\n007\n008\n009\n" \
933 "010\n011\n012\n013\n014\n015\n016\n017\n018\n019\n" \
934 "020x\n021\n022\n023\n024\n" \
935 "x25\nx26\nx27\nx28\nx29\n" \
936 "x30\nx31\nx32\nx33\nx34\nx35\nx36\nx37\nx38\nx39\n" \
937 "x40\nx41\nx42\nx43\nx44\nx45\nx46\nx47\nx48\nx49\n"
938 ));
9bc8be3d 939 cl_git_pass(git_hashsig_create(&b, buf.ptr, buf.size, GIT_HASHSIG_NORMAL));
9c454b00 940
5e5848eb 941 sim = git_hashsig_compare(a, b);
d730d3f4 942 /* 50% lines changed */
9c454b00 943
d730d3f4 944 cl_assert_in_range(40, sim, 60); /* expect in the 40-60% similarity range */
9c454b00 945
5e5848eb
RB
946 git_hashsig_free(a);
947 git_hashsig_free(b);
9c454b00
RB
948
949 /* lastly, let's check that we can hash file content as well */
950
5e5848eb 951 cl_git_pass(git_buf_sets(&buf, SIMILARITY_TEST_DATA_1));
9bc8be3d 952 cl_git_pass(git_hashsig_create(&a, buf.ptr, buf.size, GIT_HASHSIG_NORMAL));
9c454b00 953
ac2fba0e 954 cl_git_pass(git_futils_mkdir("scratch", 0755, GIT_MKDIR_PATH));
5e5848eb
RB
955 cl_git_mkfile("scratch/testdata", SIMILARITY_TEST_DATA_1);
956 cl_git_pass(git_hashsig_create_fromfile(
957 &b, "scratch/testdata", GIT_HASHSIG_NORMAL));
9c454b00 958
5e5848eb 959 cl_assert_equal_i(100, git_hashsig_compare(a, b));
9c454b00 960
5e5848eb
RB
961 git_hashsig_free(a);
962 git_hashsig_free(b);
9c454b00 963
ac3d33df 964 git_buf_dispose(&buf);
9c454b00
RB
965 git_futils_rmdir_r("scratch", NULL, GIT_RMDIR_REMOVE_FILES);
966}
aa643260
RB
967
968
969void test_core_buffer__similarity_metric_whitespace(void)
970{
971 git_hashsig *a, *b;
972 git_buf buf = GIT_BUF_INIT;
973 int sim, i, j;
974 git_hashsig_option_t opt;
975 const char *tabbed =
976 " for (s = 0; s < sizeof(sep) / sizeof(char); ++s) {\n"
977 " separator = sep[s];\n"
978 " expect = expect_values[s];\n"
979 "\n"
980 " for (j = 0; j < sizeof(b) / sizeof(char*); ++j) {\n"
981 " for (i = 0; i < sizeof(a) / sizeof(char*); ++i) {\n"
982 " git_buf_join(&buf, separator, a[i], b[j]);\n"
983 " cl_assert_equal_s(*expect, buf.ptr);\n"
984 " expect++;\n"
985 " }\n"
986 " }\n"
987 " }\n";
988 const char *spaced =
989 " for (s = 0; s < sizeof(sep) / sizeof(char); ++s) {\n"
990 " separator = sep[s];\n"
991 " expect = expect_values[s];\n"
992 "\n"
993 " for (j = 0; j < sizeof(b) / sizeof(char*); ++j) {\n"
994 " for (i = 0; i < sizeof(a) / sizeof(char*); ++i) {\n"
995 " git_buf_join(&buf, separator, a[i], b[j]);\n"
996 " cl_assert_equal_s(*expect, buf.ptr);\n"
997 " expect++;\n"
998 " }\n"
999 " }\n"
1000 " }\n";
1001 const char *crlf_spaced2 =
1002 " for (s = 0; s < sizeof(sep) / sizeof(char); ++s) {\r\n"
1003 " separator = sep[s];\r\n"
1004 " expect = expect_values[s];\r\n"
1005 "\r\n"
1006 " for (j = 0; j < sizeof(b) / sizeof(char*); ++j) {\r\n"
1007 " for (i = 0; i < sizeof(a) / sizeof(char*); ++i) {\r\n"
1008 " git_buf_join(&buf, separator, a[i], b[j]);\r\n"
1009 " cl_assert_equal_s(*expect, buf.ptr);\r\n"
1010 " expect++;\r\n"
1011 " }\r\n"
1012 " }\r\n"
1013 " }\r\n";
1014 const char *text[3] = { tabbed, spaced, crlf_spaced2 };
1015
1016 /* let's try variations of our own code with whitespace changes */
1017
1018 for (opt = GIT_HASHSIG_NORMAL; opt <= GIT_HASHSIG_SMART_WHITESPACE; ++opt) {
1019 for (i = 0; i < 3; ++i) {
1020 for (j = 0; j < 3; ++j) {
1021 cl_git_pass(git_buf_sets(&buf, text[i]));
9bc8be3d 1022 cl_git_pass(git_hashsig_create(&a, buf.ptr, buf.size, opt));
aa643260
RB
1023
1024 cl_git_pass(git_buf_sets(&buf, text[j]));
9bc8be3d 1025 cl_git_pass(git_hashsig_create(&b, buf.ptr, buf.size, opt));
aa643260
RB
1026
1027 sim = git_hashsig_compare(a, b);
1028
1029 if (opt == GIT_HASHSIG_NORMAL) {
1030 if (i == j)
1031 cl_assert_equal_i(100, sim);
1032 else
d730d3f4 1033 cl_assert_in_range(0, sim, 30); /* pretty different */
aa643260
RB
1034 } else {
1035 cl_assert_equal_i(100, sim);
1036 }
1037
1038 git_hashsig_free(a);
1039 git_hashsig_free(b);
1040 }
1041 }
1042 }
1043
ac3d33df 1044 git_buf_dispose(&buf);
aa643260 1045}
3658e81e 1046
0cf77103
RB
1047#include "../filter/crlf.h"
1048
3658e81e
RB
1049#define check_buf(expected,buf) do { \
1050 cl_assert_equal_s(expected, buf.ptr); \
1051 cl_assert_equal_sz(strlen(expected), buf.size); } while (0)
1052
1053void test_core_buffer__lf_and_crlf_conversions(void)
1054{
1055 git_buf src = GIT_BUF_INIT, tgt = GIT_BUF_INIT;
1056
1057 /* LF source */
1058
1059 git_buf_sets(&src, "lf\nlf\nlf\nlf\n");
1060
c25aa7cd 1061 cl_git_pass(git_buf_lf_to_crlf(&tgt, &src));
3658e81e
RB
1062 check_buf("lf\r\nlf\r\nlf\r\nlf\r\n", tgt);
1063
c25aa7cd 1064 cl_git_pass(git_buf_crlf_to_lf(&tgt, &src));
0cf77103 1065 check_buf(src.ptr, tgt);
3658e81e
RB
1066
1067 git_buf_sets(&src, "\nlf\nlf\nlf\nlf\nlf");
1068
c25aa7cd 1069 cl_git_pass(git_buf_lf_to_crlf(&tgt, &src));
3658e81e
RB
1070 check_buf("\r\nlf\r\nlf\r\nlf\r\nlf\r\nlf", tgt);
1071
c25aa7cd 1072 cl_git_pass(git_buf_crlf_to_lf(&tgt, &src));
0cf77103 1073 check_buf(src.ptr, tgt);
3658e81e
RB
1074
1075 /* CRLF source */
1076
1077 git_buf_sets(&src, "crlf\r\ncrlf\r\ncrlf\r\ncrlf\r\n");
1078
c25aa7cd 1079 cl_git_pass(git_buf_lf_to_crlf(&tgt, &src));
8293c8f9
ET
1080 check_buf("crlf\r\ncrlf\r\ncrlf\r\ncrlf\r\n", tgt);
1081
1082 git_buf_sets(&src, "crlf\r\ncrlf\r\ncrlf\r\ncrlf\r\n");
3658e81e 1083
c25aa7cd 1084 cl_git_pass(git_buf_crlf_to_lf(&tgt, &src));
3658e81e
RB
1085 check_buf("crlf\ncrlf\ncrlf\ncrlf\n", tgt);
1086
1087 git_buf_sets(&src, "\r\ncrlf\r\ncrlf\r\ncrlf\r\ncrlf\r\ncrlf");
1088
c25aa7cd 1089 cl_git_pass(git_buf_lf_to_crlf(&tgt, &src));
8293c8f9
ET
1090 check_buf("\r\ncrlf\r\ncrlf\r\ncrlf\r\ncrlf\r\ncrlf", tgt);
1091
1092 git_buf_sets(&src, "\r\ncrlf\r\ncrlf\r\ncrlf\r\ncrlf\r\ncrlf");
3658e81e 1093
c25aa7cd 1094 cl_git_pass(git_buf_crlf_to_lf(&tgt, &src));
3658e81e
RB
1095 check_buf("\ncrlf\ncrlf\ncrlf\ncrlf\ncrlf", tgt);
1096
1097 /* CRLF in LF text */
1098
1099 git_buf_sets(&src, "\nlf\nlf\ncrlf\r\nlf\nlf\ncrlf\r\n");
1100
c25aa7cd 1101 cl_git_pass(git_buf_lf_to_crlf(&tgt, &src));
8293c8f9
ET
1102 check_buf("\r\nlf\r\nlf\r\ncrlf\r\nlf\r\nlf\r\ncrlf\r\n", tgt);
1103
1104 git_buf_sets(&src, "\nlf\nlf\ncrlf\r\nlf\nlf\ncrlf\r\n");
1105
c25aa7cd 1106 cl_git_pass(git_buf_crlf_to_lf(&tgt, &src));
3658e81e
RB
1107 check_buf("\nlf\nlf\ncrlf\nlf\nlf\ncrlf\n", tgt);
1108
1109 /* LF in CRLF text */
1110
1111 git_buf_sets(&src, "\ncrlf\r\ncrlf\r\nlf\ncrlf\r\ncrlf");
1112
c25aa7cd 1113 cl_git_pass(git_buf_lf_to_crlf(&tgt, &src));
8293c8f9
ET
1114 check_buf("\r\ncrlf\r\ncrlf\r\nlf\r\ncrlf\r\ncrlf", tgt);
1115
c25aa7cd 1116 cl_git_pass(git_buf_crlf_to_lf(&tgt, &src));
3658e81e
RB
1117 check_buf("\ncrlf\ncrlf\nlf\ncrlf\ncrlf", tgt);
1118
1119 /* bare CR test */
1120
1121 git_buf_sets(&src, "\rcrlf\r\nlf\nlf\ncr\rcrlf\r\nlf\ncr\r");
1122
c25aa7cd 1123 cl_git_pass(git_buf_lf_to_crlf(&tgt, &src));
8293c8f9
ET
1124 check_buf("\rcrlf\r\nlf\r\nlf\r\ncr\rcrlf\r\nlf\r\ncr\r", tgt);
1125
1126 git_buf_sets(&src, "\rcrlf\r\nlf\nlf\ncr\rcrlf\r\nlf\ncr\r");
1127
c25aa7cd 1128 cl_git_pass(git_buf_crlf_to_lf(&tgt, &src));
3658e81e
RB
1129 check_buf("\rcrlf\nlf\nlf\ncr\rcrlf\nlf\ncr\r", tgt);
1130
1131 git_buf_sets(&src, "\rcr\r");
c25aa7cd 1132 cl_git_pass(git_buf_lf_to_crlf(&tgt, &src));
0cf77103 1133 check_buf(src.ptr, tgt);
c25aa7cd 1134 cl_git_pass(git_buf_crlf_to_lf(&tgt, &src));
3658e81e
RB
1135 check_buf("\rcr\r", tgt);
1136
ac3d33df
JK
1137 git_buf_dispose(&src);
1138 git_buf_dispose(&tgt);
0cf77103
RB
1139
1140 /* blob correspondence tests */
1141
1142 git_buf_sets(&src, ALL_CRLF_TEXT_RAW);
c25aa7cd 1143 cl_git_pass(git_buf_lf_to_crlf(&tgt, &src));
8293c8f9
ET
1144 check_buf(ALL_CRLF_TEXT_AS_CRLF, tgt);
1145 git_buf_sets(&src, ALL_CRLF_TEXT_RAW);
c25aa7cd 1146 cl_git_pass(git_buf_crlf_to_lf(&tgt, &src));
0cf77103 1147 check_buf(ALL_CRLF_TEXT_AS_LF, tgt);
ac3d33df
JK
1148 git_buf_dispose(&src);
1149 git_buf_dispose(&tgt);
0cf77103
RB
1150
1151 git_buf_sets(&src, ALL_LF_TEXT_RAW);
c25aa7cd 1152 cl_git_pass(git_buf_lf_to_crlf(&tgt, &src));
0cf77103 1153 check_buf(ALL_LF_TEXT_AS_CRLF, tgt);
8293c8f9 1154 git_buf_sets(&src, ALL_LF_TEXT_RAW);
c25aa7cd 1155 cl_git_pass(git_buf_crlf_to_lf(&tgt, &src));
0cf77103 1156 check_buf(ALL_LF_TEXT_AS_LF, tgt);
ac3d33df
JK
1157 git_buf_dispose(&src);
1158 git_buf_dispose(&tgt);
0cf77103
RB
1159
1160 git_buf_sets(&src, MORE_CRLF_TEXT_RAW);
c25aa7cd 1161 cl_git_pass(git_buf_lf_to_crlf(&tgt, &src));
8293c8f9
ET
1162 check_buf(MORE_CRLF_TEXT_AS_CRLF, tgt);
1163 git_buf_sets(&src, MORE_CRLF_TEXT_RAW);
c25aa7cd 1164 cl_git_pass(git_buf_crlf_to_lf(&tgt, &src));
0cf77103 1165 check_buf(MORE_CRLF_TEXT_AS_LF, tgt);
ac3d33df
JK
1166 git_buf_dispose(&src);
1167 git_buf_dispose(&tgt);
0cf77103
RB
1168
1169 git_buf_sets(&src, MORE_LF_TEXT_RAW);
c25aa7cd 1170 cl_git_pass(git_buf_lf_to_crlf(&tgt, &src));
8293c8f9
ET
1171 check_buf(MORE_LF_TEXT_AS_CRLF, tgt);
1172 git_buf_sets(&src, MORE_LF_TEXT_RAW);
c25aa7cd 1173 cl_git_pass(git_buf_crlf_to_lf(&tgt, &src));
0cf77103 1174 check_buf(MORE_LF_TEXT_AS_LF, tgt);
ac3d33df
JK
1175 git_buf_dispose(&src);
1176 git_buf_dispose(&tgt);
3658e81e 1177}
caab22c0
CMN
1178
1179void test_core_buffer__dont_grow_borrowed(void)
1180{
1181 const char *somestring = "blah blah";
1182 git_buf buf = GIT_BUF_INIT;
1183
1184 git_buf_attach_notowned(&buf, somestring, strlen(somestring) + 1);
1185 cl_assert_equal_p(somestring, buf.ptr);
1186 cl_assert_equal_i(0, buf.asize);
1187 cl_assert_equal_i(strlen(somestring) + 1, buf.size);
1188
a6599235 1189 cl_git_fail_with(GIT_EINVALID, git_buf_grow(&buf, 1024));
caab22c0 1190}
22a2d3d5
UG
1191
1192void test_core_buffer__dont_hit_infinite_loop_when_resizing(void)
1193{
1194 git_buf buf = GIT_BUF_INIT;
1195
1196 cl_git_pass(git_buf_puts(&buf, "foobar"));
1197 /*
1198 * We do not care whether this succeeds or fails, which
1199 * would depend on platform-specific allocation
1200 * semantics. We only want to know that the function
1201 * actually returns.
1202 */
1203 (void)git_buf_try_grow(&buf, SIZE_MAX, true);
1204
1205 git_buf_dispose(&buf);
1206}
1207
1208void test_core_buffer__avoid_printing_into_oom_buffer(void)
1209{
1210 git_buf buf = GIT_BUF_INIT;
1211
1212 /* Emulate OOM situation with a previous allocation */
1213 buf.asize = 8;
1214 buf.ptr = git_buf__oom;
1215
1216 /*
1217 * Print the same string again. As the buffer still has
1218 * an `asize` of 8 due to the previous print,
1219 * `ENSURE_SIZE` would not try to reallocate the array at
1220 * all. As it didn't explicitly check for `git_buf__oom`
1221 * in earlier versions, this would've resulted in it
1222 * returning successfully and thus `git_buf_puts` would
1223 * just print into the `git_buf__oom` array.
1224 */
1225 cl_git_fail(git_buf_puts(&buf, "foobar"));
1226}