1 #include "clar_libgit2.h"
5 static git_buf buf
= GIT_BUF_INIT
;
7 void test_config_read__cleanup(void)
12 void test_config_read__simple_read(void)
17 cl_git_pass(git_config_open_ondisk(&cfg
, cl_fixture("config/config0")));
19 cl_git_pass(git_config_get_int32(&i
, cfg
, "core.repositoryformatversion"));
21 cl_git_pass(git_config_get_bool(&i
, cfg
, "core.filemode"));
23 cl_git_pass(git_config_get_bool(&i
, cfg
, "core.bare"));
25 cl_git_pass(git_config_get_bool(&i
, cfg
, "core.logallrefupdates"));
31 void test_config_read__case_sensitive(void)
36 cl_git_pass(git_config_open_ondisk(&cfg
, cl_fixture("config/config1")));
38 cl_git_pass(git_config_get_string_buf(&buf
, cfg
, "this.that.other"));
39 cl_assert_equal_s("true", git_buf_cstr(&buf
));
42 cl_git_pass(git_config_get_string_buf(&buf
, cfg
, "this.That.other"));
43 cl_assert_equal_s("yes", git_buf_cstr(&buf
));
45 cl_git_pass(git_config_get_bool(&i
, cfg
, "this.that.other"));
47 cl_git_pass(git_config_get_bool(&i
, cfg
, "this.That.other"));
50 /* This one doesn't exist */
51 cl_must_fail(git_config_get_bool(&i
, cfg
, "this.thaT.other"));
57 * If \ is the last non-space character on the line, we read the next
58 * one, separating each line with SP.
60 void test_config_read__multiline_value(void)
64 cl_git_pass(git_config_open_ondisk(&cfg
, cl_fixture("config/config2")));
66 cl_git_pass(git_config_get_string_buf(&buf
, cfg
, "this.That.and"));
67 cl_assert_equal_s("one one one two two three three", git_buf_cstr(&buf
));
73 * This kind of subsection declaration is case-insensitive
75 void test_config_read__subsection_header(void)
79 cl_git_pass(git_config_open_ondisk(&cfg
, cl_fixture("config/config3")));
81 cl_git_pass(git_config_get_string_buf(&buf
, cfg
, "section.subsection.var"));
82 cl_assert_equal_s("hello", git_buf_cstr(&buf
));
84 /* The subsection is transformed to lower-case */
85 cl_must_fail(git_config_get_string_buf(&buf
, cfg
, "section.subSectIon.var"));
90 void test_config_read__lone_variable(void)
95 cl_git_pass(git_config_open_ondisk(&cfg
, cl_fixture("config/config4")));
97 cl_git_fail(git_config_get_int32(&i
, cfg
, "some.section.variable"));
99 cl_git_pass(git_config_get_string_buf(&buf
, cfg
, "some.section.variable"));
100 cl_assert_equal_s("", git_buf_cstr(&buf
));
103 cl_git_pass(git_config_get_bool(&i
, cfg
, "some.section.variable"));
106 cl_git_pass(git_config_get_string_buf(&buf
, cfg
, "some.section.variableeq"));
107 cl_assert_equal_s("", git_buf_cstr(&buf
));
109 cl_git_pass(git_config_get_bool(&i
, cfg
, "some.section.variableeq"));
112 git_config_free(cfg
);
115 void test_config_read__number_suffixes(void)
120 cl_git_pass(git_config_open_ondisk(&cfg
, cl_fixture("config/config5")));
122 cl_git_pass(git_config_get_int64(&i
, cfg
, "number.simple"));
125 cl_git_pass(git_config_get_int64(&i
, cfg
, "number.k"));
126 cl_assert(i
== 1 * 1024);
128 cl_git_pass(git_config_get_int64(&i
, cfg
, "number.kk"));
129 cl_assert(i
== 1 * 1024);
131 cl_git_pass(git_config_get_int64(&i
, cfg
, "number.m"));
132 cl_assert(i
== 1 * 1024 * 1024);
134 cl_git_pass(git_config_get_int64(&i
, cfg
, "number.mm"));
135 cl_assert(i
== 1 * 1024 * 1024);
137 cl_git_pass(git_config_get_int64(&i
, cfg
, "number.g"));
138 cl_assert(i
== 1 * 1024 * 1024 * 1024);
140 cl_git_pass(git_config_get_int64(&i
, cfg
, "number.gg"));
141 cl_assert(i
== 1 * 1024 * 1024 * 1024);
143 git_config_free(cfg
);
146 void test_config_read__blank_lines(void)
151 cl_git_pass(git_config_open_ondisk(&cfg
, cl_fixture("config/config6")));
153 cl_git_pass(git_config_get_bool(&i
, cfg
, "valid.subsection.something"));
156 cl_git_pass(git_config_get_bool(&i
, cfg
, "something.else.something"));
159 git_config_free(cfg
);
162 void test_config_read__invalid_ext_headers(void)
165 cl_must_fail(git_config_open_ondisk(&cfg
, cl_fixture("config/config7")));
168 void test_config_read__empty_files(void)
171 cl_git_pass(git_config_open_ondisk(&cfg
, cl_fixture("config/config8")));
172 git_config_free(cfg
);
175 void test_config_read__symbol_headers(void)
178 cl_git_pass(git_config_open_ondisk(&cfg
, cl_fixture("config/config20")));
179 git_config_free(cfg
);
182 void test_config_read__header_in_last_line(void)
186 cl_git_pass(git_config_open_ondisk(&cfg
, cl_fixture("config/config10")));
187 git_config_free(cfg
);
190 void test_config_read__prefixes(void)
194 cl_git_pass(git_config_open_ondisk(&cfg
, cl_fixture("config/config9")));
195 cl_git_pass(git_config_get_string_buf(&buf
, cfg
, "remote.ab.url"));
196 cl_assert_equal_s("http://example.com/git/ab", git_buf_cstr(&buf
));
199 cl_git_pass(git_config_get_string_buf(&buf
, cfg
, "remote.abba.url"));
200 cl_assert_equal_s("http://example.com/git/abba", git_buf_cstr(&buf
));
202 git_config_free(cfg
);
205 void test_config_read__escaping_quotes(void)
209 cl_git_pass(git_config_open_ondisk(&cfg
, cl_fixture("config/config13")));
210 cl_git_pass(git_config_get_string_buf(&buf
, cfg
, "core.editor"));
211 cl_assert_equal_s("\"C:/Program Files/Nonsense/bah.exe\" \"--some option\"", git_buf_cstr(&buf
));
213 git_config_free(cfg
);
216 static int count_cfg_entries_and_compare_levels(
217 const git_config_entry
*entry
, void *payload
)
219 int *count
= payload
;
221 if (!strcmp(entry
->value
, "7") || !strcmp(entry
->value
, "17"))
222 cl_assert(entry
->level
== GIT_CONFIG_LEVEL_GLOBAL
);
224 cl_assert(entry
->level
== GIT_CONFIG_LEVEL_SYSTEM
);
230 static int cfg_callback_countdown(const git_config_entry
*entry
, void *payload
)
232 int *count
= payload
;
240 void test_config_read__foreach(void)
245 cl_git_pass(git_config_new(&cfg
));
246 cl_git_pass(git_config_add_file_ondisk(cfg
, cl_fixture("config/config9"),
247 GIT_CONFIG_LEVEL_SYSTEM
, 0));
248 cl_git_pass(git_config_add_file_ondisk(cfg
, cl_fixture("config/config15"),
249 GIT_CONFIG_LEVEL_GLOBAL
, 0));
252 cl_git_pass(git_config_foreach(cfg
, count_cfg_entries_and_compare_levels
, &count
));
253 cl_assert_equal_i(7, count
);
256 cl_git_fail(ret
= git_config_foreach(cfg
, cfg_callback_countdown
, &count
));
257 cl_assert_equal_i(-100, ret
);
259 git_config_free(cfg
);
262 void test_config_read__iterator(void)
265 git_config_iterator
*iter
;
266 git_config_entry
*entry
;
269 cl_git_pass(git_config_new(&cfg
));
270 cl_git_pass(git_config_add_file_ondisk(cfg
, cl_fixture("config/config9"),
271 GIT_CONFIG_LEVEL_SYSTEM
, 0));
272 cl_git_pass(git_config_add_file_ondisk(cfg
, cl_fixture("config/config15"),
273 GIT_CONFIG_LEVEL_GLOBAL
, 0));
276 cl_git_pass(git_config_iterator_new(&iter
, cfg
));
278 while ((ret
= git_config_next(&entry
, iter
)) == 0) {
282 git_config_iterator_free(iter
);
283 cl_assert_equal_i(GIT_ITEROVER
, ret
);
284 cl_assert_equal_i(7, count
);
287 cl_git_pass(git_config_iterator_new(&iter
, cfg
));
289 git_config_iterator_free(iter
);
290 git_config_free(cfg
);
293 static int count_cfg_entries(const git_config_entry
*entry
, void *payload
)
295 int *count
= payload
;
301 void test_config_read__foreach_match(void)
306 cl_git_pass(git_config_open_ondisk(&cfg
, cl_fixture("config/config9")));
310 git_config_foreach_match(cfg
, "core.*", count_cfg_entries
, &count
));
311 cl_assert_equal_i(3, count
);
315 git_config_foreach_match(cfg
, "remote\\.ab.*", count_cfg_entries
, &count
));
316 cl_assert_equal_i(2, count
);
320 git_config_foreach_match(cfg
, ".*url$", count_cfg_entries
, &count
));
321 cl_assert_equal_i(2, count
);
325 git_config_foreach_match(cfg
, ".*dummy.*", count_cfg_entries
, &count
));
326 cl_assert_equal_i(2, count
);
330 git_config_foreach_match(cfg
, ".*nomatch.*", count_cfg_entries
, &count
));
331 cl_assert_equal_i(0, count
);
333 git_config_free(cfg
);
336 static void check_glob_iter(git_config
*cfg
, const char *regexp
, int expected
)
338 git_config_iterator
*iter
;
339 git_config_entry
*entry
;
342 cl_git_pass(git_config_iterator_glob_new(&iter
, cfg
, regexp
));
345 while ((error
= git_config_next(&entry
, iter
)) == 0)
348 cl_assert_equal_i(GIT_ITEROVER
, error
);
349 cl_assert_equal_i(expected
, count
);
350 git_config_iterator_free(iter
);
353 void test_config_read__iterator_invalid_glob(void)
356 git_config_iterator
*iter
;
358 cl_git_pass(git_config_open_ondisk(&cfg
, cl_fixture("config/config9")));
360 cl_git_fail(git_config_iterator_glob_new(&iter
, cfg
, "*"));
362 git_config_free(cfg
);
365 void test_config_read__iterator_glob(void)
369 cl_git_pass(git_config_open_ondisk(&cfg
, cl_fixture("config/config9")));
371 check_glob_iter(cfg
, "core.*", 3);
372 check_glob_iter(cfg
, "remote\\.ab.*", 2);
373 check_glob_iter(cfg
, ".*url$", 2);
374 check_glob_iter(cfg
, ".*dummy.*", 2);
375 check_glob_iter(cfg
, ".*nomatch.*", 0);
377 git_config_free(cfg
);
380 void test_config_read__whitespace_not_required_around_assignment(void)
384 cl_git_pass(git_config_open_ondisk(&cfg
, cl_fixture("config/config14")));
386 cl_git_pass(git_config_get_string_buf(&buf
, cfg
, "a.b"));
387 cl_assert_equal_s("c", git_buf_cstr(&buf
));
390 cl_git_pass(git_config_get_string_buf(&buf
, cfg
, "d.e"));
391 cl_assert_equal_s("f", git_buf_cstr(&buf
));
393 git_config_free(cfg
);
396 void test_config_read__read_git_config_entry(void)
399 git_config_entry
*entry
;
401 cl_git_pass(git_config_new(&cfg
));
402 cl_git_pass(git_config_add_file_ondisk(cfg
, cl_fixture("config/config9"),
403 GIT_CONFIG_LEVEL_SYSTEM
, 0));
405 cl_git_pass(git_config_get_entry(&entry
, cfg
, "core.dummy2"));
406 cl_assert_equal_s("core.dummy2", entry
->name
);
407 cl_assert_equal_s("42", entry
->value
);
408 cl_assert_equal_i(GIT_CONFIG_LEVEL_SYSTEM
, entry
->level
);
410 git_config_entry_free(entry
);
411 git_config_free(cfg
);
415 * At the beginning of the test:
416 * - config9 has: core.dummy2=42
417 * - config15 has: core.dummy2=7
418 * - config16 has: core.dummy2=28
420 void test_config_read__local_config_overrides_global_config_overrides_system_config(void)
425 cl_git_pass(git_config_new(&cfg
));
426 cl_git_pass(git_config_add_file_ondisk(cfg
, cl_fixture("config/config9"),
427 GIT_CONFIG_LEVEL_SYSTEM
, 0));
428 cl_git_pass(git_config_add_file_ondisk(cfg
, cl_fixture("config/config15"),
429 GIT_CONFIG_LEVEL_GLOBAL
, 0));
430 cl_git_pass(git_config_add_file_ondisk(cfg
, cl_fixture("config/config16"),
431 GIT_CONFIG_LEVEL_LOCAL
, 0));
433 cl_git_pass(git_config_get_int32(&i
, cfg
, "core.dummy2"));
434 cl_assert_equal_i(28, i
);
436 git_config_free(cfg
);
438 cl_git_pass(git_config_new(&cfg
));
439 cl_git_pass(git_config_add_file_ondisk(cfg
, cl_fixture("config/config9"),
440 GIT_CONFIG_LEVEL_SYSTEM
, 0));
441 cl_git_pass(git_config_add_file_ondisk(cfg
, cl_fixture("config/config15"),
442 GIT_CONFIG_LEVEL_GLOBAL
, 0));
444 cl_git_pass(git_config_get_int32(&i
, cfg
, "core.dummy2"));
445 cl_assert_equal_i(7, i
);
447 git_config_free(cfg
);
451 * At the beginning of the test:
452 * - config9 has: core.global does not exist
453 * - config15 has: core.global=17
454 * - config16 has: core.global=29
457 * - config9 has: core.system does not exist
458 * - config15 has: core.system does not exist
459 * - config16 has: core.system=11
461 void test_config_read__fallback_from_local_to_global_and_from_global_to_system(void)
466 cl_git_pass(git_config_new(&cfg
));
467 cl_git_pass(git_config_add_file_ondisk(cfg
, cl_fixture("config/config9"),
468 GIT_CONFIG_LEVEL_SYSTEM
, 0));
469 cl_git_pass(git_config_add_file_ondisk(cfg
, cl_fixture("config/config15"),
470 GIT_CONFIG_LEVEL_GLOBAL
, 0));
471 cl_git_pass(git_config_add_file_ondisk(cfg
, cl_fixture("config/config16"),
472 GIT_CONFIG_LEVEL_LOCAL
, 0));
474 cl_git_pass(git_config_get_int32(&i
, cfg
, "core.global"));
475 cl_assert_equal_i(17, i
);
476 cl_git_pass(git_config_get_int32(&i
, cfg
, "core.system"));
477 cl_assert_equal_i(11, i
);
479 git_config_free(cfg
);
483 * At the beginning of the test, config18 has:
485 * int64global = 9223372036854775803
487 * stringglobal = I'm a global config value!
493 * stringglobal = don't find me!
496 void test_config_read__simple_read_from_specific_level(void)
498 git_config
*cfg
, *cfg_specific
;
500 int64_t l
, expected
= +9223372036854775803;
502 cl_git_pass(git_config_new(&cfg
));
503 cl_git_pass(git_config_add_file_ondisk(cfg
, cl_fixture("config/config18"),
504 GIT_CONFIG_LEVEL_GLOBAL
, 0));
505 cl_git_pass(git_config_add_file_ondisk(cfg
, cl_fixture("config/config19"),
506 GIT_CONFIG_LEVEL_SYSTEM
, 0));
508 cl_git_pass(git_config_open_level(&cfg_specific
, cfg
, GIT_CONFIG_LEVEL_GLOBAL
));
510 cl_git_pass(git_config_get_int32(&i
, cfg_specific
, "core.int32global"));
511 cl_assert_equal_i(28, i
);
512 cl_git_pass(git_config_get_int64(&l
, cfg_specific
, "core.int64global"));
513 cl_assert(l
== expected
);
514 cl_git_pass(git_config_get_bool(&i
, cfg_specific
, "core.boolglobal"));
515 cl_assert_equal_b(true, i
);
516 cl_git_pass(git_config_get_string_buf(&buf
, cfg_specific
, "core.stringglobal"));
517 cl_assert_equal_s("I'm a global config value!", git_buf_cstr(&buf
));
519 git_config_free(cfg_specific
);
520 git_config_free(cfg
);
523 static void clean_test_config(void *unused
)
526 cl_fixture_cleanup("./testconfig");
529 void test_config_read__can_load_and_parse_an_empty_config_file(void)
534 cl_set_cleanup(&clean_test_config
, NULL
);
535 cl_git_mkfile("./testconfig", "");
536 cl_git_pass(git_config_open_ondisk(&cfg
, "./testconfig"));
537 cl_assert_equal_i(GIT_ENOTFOUND
, git_config_get_int32(&i
, cfg
, "nope.neither"));
539 git_config_free(cfg
);
542 void test_config_read__corrupt_header(void)
546 cl_set_cleanup(&clean_test_config
, NULL
);
547 cl_git_mkfile("./testconfig", "[sneaky ] \"quoted closing quote mark\\\"");
548 cl_git_fail(git_config_open_ondisk(&cfg
, "./testconfig"));
550 git_config_free(cfg
);
553 void test_config_read__corrupt_header2(void)
557 cl_set_cleanup(&clean_test_config
, NULL
);
558 cl_git_mkfile("./testconfig", "[unclosed \"bracket\"\n lib = git2\n");
559 cl_git_fail(git_config_open_ondisk(&cfg
, "./testconfig"));
561 git_config_free(cfg
);
564 void test_config_read__corrupt_header3(void)
568 cl_set_cleanup(&clean_test_config
, NULL
);
569 cl_git_mkfile("./testconfig", "[unclosed \"slash\\\"]\n lib = git2\n");
570 cl_git_fail(git_config_open_ondisk(&cfg
, "./testconfig"));
572 git_config_free(cfg
);
575 void test_config_read__override_variable(void)
579 cl_set_cleanup(&clean_test_config
, NULL
);
580 cl_git_mkfile("./testconfig", "[some] var = one\nvar = two");
581 cl_git_pass(git_config_open_ondisk(&cfg
, "./testconfig"));
583 cl_git_pass(git_config_get_string_buf(&buf
, cfg
, "some.var"));
584 cl_assert_equal_s("two", git_buf_cstr(&buf
));
586 git_config_free(cfg
);
589 void test_config_read__path(void)
592 git_buf path
= GIT_BUF_INIT
;
593 git_buf old_path
= GIT_BUF_INIT
;
594 git_buf home_path
= GIT_BUF_INIT
;
595 git_buf expected_path
= GIT_BUF_INIT
;
597 cl_git_pass(p_mkdir("fakehome", 0777));
598 cl_git_pass(git_path_prettify(&home_path
, "fakehome", NULL
));
599 cl_git_pass(git_libgit2_opts(GIT_OPT_GET_SEARCH_PATH
, GIT_CONFIG_LEVEL_GLOBAL
, &old_path
));
600 cl_git_pass(git_libgit2_opts(GIT_OPT_SET_SEARCH_PATH
, GIT_CONFIG_LEVEL_GLOBAL
, home_path
.ptr
));
601 cl_git_mkfile("./testconfig", "[some]\n path = ~/somefile");
602 cl_git_pass(git_path_join_unrooted(&expected_path
, "somefile", home_path
.ptr
, NULL
));
604 cl_git_pass(git_config_open_ondisk(&cfg
, "./testconfig"));
605 cl_git_pass(git_config_get_path(&path
, cfg
, "some.path"));
606 cl_assert_equal_s(expected_path
.ptr
, path
.ptr
);
609 cl_git_mkfile("./testconfig", "[some]\n path = ~/");
610 cl_git_pass(git_path_join_unrooted(&expected_path
, "", home_path
.ptr
, NULL
));
612 cl_git_pass(git_config_get_path(&path
, cfg
, "some.path"));
613 cl_assert_equal_s(expected_path
.ptr
, path
.ptr
);
616 cl_git_mkfile("./testconfig", "[some]\n path = ~");
617 cl_git_pass(git_buf_sets(&expected_path
, home_path
.ptr
));
619 cl_git_pass(git_config_get_path(&path
, cfg
, "some.path"));
620 cl_assert_equal_s(expected_path
.ptr
, path
.ptr
);
623 cl_git_mkfile("./testconfig", "[some]\n path = ~user/foo");
624 cl_git_fail(git_config_get_path(&path
, cfg
, "some.path"));
626 cl_git_pass(git_libgit2_opts(GIT_OPT_SET_SEARCH_PATH
, GIT_CONFIG_LEVEL_GLOBAL
, old_path
.ptr
));
627 git_buf_free(&old_path
);
628 git_buf_free(&home_path
);
629 git_buf_free(&expected_path
);
630 git_config_free(cfg
);