1 #include "clar_libgit2.h"
4 static git_buf buf
= GIT_BUF_INIT
;
6 void test_config_read__cleanup(void)
11 void test_config_read__simple_read(void)
16 cl_git_pass(git_config_open_ondisk(&cfg
, cl_fixture("config/config0")));
18 cl_git_pass(git_config_get_int32(&i
, cfg
, "core.repositoryformatversion"));
20 cl_git_pass(git_config_get_bool(&i
, cfg
, "core.filemode"));
22 cl_git_pass(git_config_get_bool(&i
, cfg
, "core.bare"));
24 cl_git_pass(git_config_get_bool(&i
, cfg
, "core.logallrefupdates"));
30 void test_config_read__case_sensitive(void)
35 cl_git_pass(git_config_open_ondisk(&cfg
, cl_fixture("config/config1")));
37 cl_git_pass(git_config_get_string_buf(&buf
, cfg
, "this.that.other"));
38 cl_assert_equal_s("true", buf
.ptr
);
39 git_buf_dispose(&buf
);
41 cl_git_pass(git_config_get_string_buf(&buf
, cfg
, "this.That.other"));
42 cl_assert_equal_s("yes", buf
.ptr
);
44 cl_git_pass(git_config_get_bool(&i
, cfg
, "this.that.other"));
46 cl_git_pass(git_config_get_bool(&i
, cfg
, "this.That.other"));
49 /* This one doesn't exist */
50 cl_must_fail(git_config_get_bool(&i
, cfg
, "this.thaT.other"));
56 * If \ is the last non-space character on the line, we read the next
57 * one, separating each line with SP.
59 void test_config_read__multiline_value(void)
63 cl_git_pass(git_config_open_ondisk(&cfg
, cl_fixture("config/config2")));
65 cl_git_pass(git_config_get_string_buf(&buf
, cfg
, "this.That.and"));
66 cl_assert_equal_s("one one one two two three three", buf
.ptr
);
71 static void clean_test_config(void *unused
)
74 cl_fixture_cleanup("./testconfig");
77 void test_config_read__multiline_value_and_eof(void)
81 cl_set_cleanup(&clean_test_config
, NULL
);
82 cl_git_mkfile("./testconfig", "[header]\n key1 = foo\\\n");
83 cl_git_pass(git_config_open_ondisk(&cfg
, "./testconfig"));
85 cl_git_pass(git_config_get_string_buf(&buf
, cfg
, "header.key1"));
86 cl_assert_equal_s("foo", buf
.ptr
);
91 void test_config_read__multiline_eof(void)
95 cl_set_cleanup(&clean_test_config
, NULL
);
96 cl_git_mkfile("./testconfig", "[header]\n key1 = \\\n");
97 cl_git_pass(git_config_open_ondisk(&cfg
, "./testconfig"));
99 cl_git_pass(git_config_get_string_buf(&buf
, cfg
, "header.key1"));
100 cl_assert_equal_s("", buf
.ptr
);
102 git_config_free(cfg
);
106 * This kind of subsection declaration is case-insensitive
108 void test_config_read__subsection_header(void)
112 cl_git_pass(git_config_open_ondisk(&cfg
, cl_fixture("config/config3")));
114 cl_git_pass(git_config_get_string_buf(&buf
, cfg
, "section.subsection.var"));
115 cl_assert_equal_s("hello", buf
.ptr
);
117 /* The subsection is transformed to lower-case */
118 cl_must_fail(git_config_get_string_buf(&buf
, cfg
, "section.subSectIon.var"));
120 git_config_free(cfg
);
123 void test_config_read__lone_variable(void)
128 cl_git_pass(git_config_open_ondisk(&cfg
, cl_fixture("config/config4")));
130 cl_git_fail(git_config_get_int32(&i
, cfg
, "some.section.variable"));
132 cl_git_pass(git_config_get_string_buf(&buf
, cfg
, "some.section.variable"));
133 cl_assert_equal_s("", buf
.ptr
);
134 git_buf_dispose(&buf
);
136 cl_git_pass(git_config_get_bool(&i
, cfg
, "some.section.variable"));
139 cl_git_pass(git_config_get_string_buf(&buf
, cfg
, "some.section.variableeq"));
140 cl_assert_equal_s("", buf
.ptr
);
142 cl_git_pass(git_config_get_bool(&i
, cfg
, "some.section.variableeq"));
145 git_config_free(cfg
);
148 void test_config_read__number_suffixes(void)
153 cl_git_pass(git_config_open_ondisk(&cfg
, cl_fixture("config/config5")));
155 cl_git_pass(git_config_get_int64(&i
, cfg
, "number.simple"));
158 cl_git_pass(git_config_get_int64(&i
, cfg
, "number.k"));
159 cl_assert(i
== 1 * 1024);
161 cl_git_pass(git_config_get_int64(&i
, cfg
, "number.kk"));
162 cl_assert(i
== 1 * 1024);
164 cl_git_pass(git_config_get_int64(&i
, cfg
, "number.m"));
165 cl_assert(i
== 1 * 1024 * 1024);
167 cl_git_pass(git_config_get_int64(&i
, cfg
, "number.mm"));
168 cl_assert(i
== 1 * 1024 * 1024);
170 cl_git_pass(git_config_get_int64(&i
, cfg
, "number.g"));
171 cl_assert(i
== 1 * 1024 * 1024 * 1024);
173 cl_git_pass(git_config_get_int64(&i
, cfg
, "number.gg"));
174 cl_assert(i
== 1 * 1024 * 1024 * 1024);
176 git_config_free(cfg
);
179 void test_config_read__blank_lines(void)
184 cl_git_pass(git_config_open_ondisk(&cfg
, cl_fixture("config/config6")));
186 cl_git_pass(git_config_get_bool(&i
, cfg
, "valid.subsection.something"));
189 cl_git_pass(git_config_get_bool(&i
, cfg
, "something.else.something"));
192 git_config_free(cfg
);
195 void test_config_read__invalid_ext_headers(void)
198 cl_must_fail(git_config_open_ondisk(&cfg
, cl_fixture("config/config7")));
201 void test_config_read__empty_files(void)
204 cl_git_pass(git_config_open_ondisk(&cfg
, cl_fixture("config/config8")));
205 git_config_free(cfg
);
208 void test_config_read__symbol_headers(void)
211 cl_git_pass(git_config_open_ondisk(&cfg
, cl_fixture("config/config20")));
212 cl_git_pass(git_config_get_string_buf(&buf
, cfg
, "valid.[subsection].something"));
213 cl_assert_equal_s("a", buf
.ptr
);
214 git_buf_dispose(&buf
);
215 cl_git_pass(git_config_get_string_buf(&buf
, cfg
, "sec.[subsec]/child.parent"));
216 cl_assert_equal_s("grand", buf
.ptr
);
217 git_buf_dispose(&buf
);
218 cl_git_pass(git_config_get_string_buf(&buf
, cfg
, "sec2.[subsec2]/child2.type"));
219 cl_assert_equal_s("dvcs", buf
.ptr
);
220 git_buf_dispose(&buf
);
221 cl_git_pass(git_config_get_string_buf(&buf
, cfg
, "sec3.escape\"quote.vcs"));
222 cl_assert_equal_s("git", buf
.ptr
);
223 git_buf_dispose(&buf
);
224 cl_git_pass(git_config_get_string_buf(&buf
, cfg
, "sec4.escaping\\slash.lib"));
225 cl_assert_equal_s("git2", buf
.ptr
);
226 git_buf_dispose(&buf
);
227 git_config_free(cfg
);
230 void test_config_read__multiline_multiple_quoted_comment_chars(void)
233 cl_git_pass(git_config_open_ondisk(&cfg
, cl_fixture("config/config21")));
234 git_config_free(cfg
);
237 void test_config_read__multiline_multiple_quoted_quote_at_beginning_of_line(void)
240 cl_git_pass(git_config_open_ondisk(&cfg
, cl_fixture("config/config22")));
241 cl_git_pass(git_config_get_string_buf(&buf
, cfg
, "alias.m"));
242 cl_assert_equal_s("cmd ;; ;; bar", buf
.ptr
);
243 git_buf_dispose(&buf
);
244 cl_git_pass(git_config_get_string_buf(&buf
, cfg
, "alias.m2"));
245 cl_assert_equal_s("'; ; something '", buf
.ptr
);
246 git_buf_dispose(&buf
);
247 git_config_free(cfg
);
250 void test_config_read__header_in_last_line(void)
254 cl_git_pass(git_config_open_ondisk(&cfg
, cl_fixture("config/config10")));
255 git_config_free(cfg
);
258 void test_config_read__prefixes(void)
262 cl_git_pass(git_config_open_ondisk(&cfg
, cl_fixture("config/config9")));
263 cl_git_pass(git_config_get_string_buf(&buf
, cfg
, "remote.ab.url"));
264 cl_assert_equal_s("http://example.com/git/ab", buf
.ptr
);
265 git_buf_dispose(&buf
);
267 cl_git_pass(git_config_get_string_buf(&buf
, cfg
, "remote.abba.url"));
268 cl_assert_equal_s("http://example.com/git/abba", buf
.ptr
);
270 git_config_free(cfg
);
273 void test_config_read__escaping_quotes(void)
277 cl_git_pass(git_config_open_ondisk(&cfg
, cl_fixture("config/config13")));
278 cl_git_pass(git_config_get_string_buf(&buf
, cfg
, "core.editor"));
279 cl_assert_equal_s("\"C:/Program Files/Nonsense/bah.exe\" \"--some option\"", buf
.ptr
);
281 git_config_free(cfg
);
284 void test_config_read__invalid_escape_sequence(void)
288 cl_set_cleanup(&clean_test_config
, NULL
);
289 cl_git_mkfile("./testconfig", "[header]\n key1 = \\\\\\;\n key2 = value2\n");
290 cl_git_fail(git_config_open_ondisk(&cfg
, "./testconfig"));
292 git_config_free(cfg
);
295 static int count_cfg_entries_and_compare_levels(
296 const git_config_entry
*entry
, void *payload
)
298 int *count
= payload
;
300 if (!strcmp(entry
->value
, "7") || !strcmp(entry
->value
, "17"))
301 cl_assert(entry
->level
== GIT_CONFIG_LEVEL_GLOBAL
);
303 cl_assert(entry
->level
== GIT_CONFIG_LEVEL_SYSTEM
);
309 static int cfg_callback_countdown(const git_config_entry
*entry
, void *payload
)
311 int *count
= payload
;
319 void test_config_read__foreach(void)
324 cl_git_pass(git_config_new(&cfg
));
325 cl_git_pass(git_config_add_file_ondisk(cfg
, cl_fixture("config/config9"),
326 GIT_CONFIG_LEVEL_SYSTEM
, NULL
, 0));
327 cl_git_pass(git_config_add_file_ondisk(cfg
, cl_fixture("config/config15"),
328 GIT_CONFIG_LEVEL_GLOBAL
, NULL
, 0));
331 cl_git_pass(git_config_foreach(cfg
, count_cfg_entries_and_compare_levels
, &count
));
332 cl_assert_equal_i(7, count
);
335 cl_git_fail(ret
= git_config_foreach(cfg
, cfg_callback_countdown
, &count
));
336 cl_assert_equal_i(-100, ret
);
338 git_config_free(cfg
);
341 void test_config_read__iterator(void)
343 const char *keys
[] = {
353 git_config_iterator
*iter
;
354 git_config_entry
*entry
;
357 cl_git_pass(git_config_new(&cfg
));
358 cl_git_pass(git_config_add_file_ondisk(cfg
, cl_fixture("config/config9"),
359 GIT_CONFIG_LEVEL_SYSTEM
, NULL
, 0));
360 cl_git_pass(git_config_add_file_ondisk(cfg
, cl_fixture("config/config15"),
361 GIT_CONFIG_LEVEL_GLOBAL
, NULL
, 0));
364 cl_git_pass(git_config_iterator_new(&iter
, cfg
));
366 while ((ret
= git_config_next(&entry
, iter
)) == 0) {
367 cl_assert_equal_s(entry
->name
, keys
[count
]);
371 git_config_iterator_free(iter
);
372 cl_assert_equal_i(GIT_ITEROVER
, ret
);
373 cl_assert_equal_i(7, count
);
376 cl_git_pass(git_config_iterator_new(&iter
, cfg
));
378 git_config_iterator_free(iter
);
379 git_config_free(cfg
);
382 static int count_cfg_entries(const git_config_entry
*entry
, void *payload
)
384 int *count
= payload
;
390 void test_config_read__foreach_match(void)
395 cl_git_pass(git_config_open_ondisk(&cfg
, cl_fixture("config/config9")));
399 git_config_foreach_match(cfg
, "core.*", count_cfg_entries
, &count
));
400 cl_assert_equal_i(3, count
);
404 git_config_foreach_match(cfg
, "remote\\.ab.*", count_cfg_entries
, &count
));
405 cl_assert_equal_i(2, count
);
409 git_config_foreach_match(cfg
, ".*url$", count_cfg_entries
, &count
));
410 cl_assert_equal_i(2, count
);
414 git_config_foreach_match(cfg
, ".*dummy.*", count_cfg_entries
, &count
));
415 cl_assert_equal_i(2, count
);
419 git_config_foreach_match(cfg
, ".*nomatch.*", count_cfg_entries
, &count
));
420 cl_assert_equal_i(0, count
);
422 git_config_free(cfg
);
425 static void check_glob_iter(git_config
*cfg
, const char *regexp
, int expected
)
427 git_config_iterator
*iter
;
428 git_config_entry
*entry
;
431 cl_git_pass(git_config_iterator_glob_new(&iter
, cfg
, regexp
));
434 while ((error
= git_config_next(&entry
, iter
)) == 0)
437 cl_assert_equal_i(GIT_ITEROVER
, error
);
438 cl_assert_equal_i(expected
, count
);
439 git_config_iterator_free(iter
);
442 void test_config_read__iterator_invalid_glob(void)
445 git_config_iterator
*iter
;
447 cl_git_pass(git_config_open_ondisk(&cfg
, cl_fixture("config/config9")));
449 cl_git_fail(git_config_iterator_glob_new(&iter
, cfg
, "*"));
451 git_config_free(cfg
);
454 void test_config_read__iterator_glob(void)
458 cl_git_pass(git_config_open_ondisk(&cfg
, cl_fixture("config/config9")));
460 check_glob_iter(cfg
, "core.*", 3);
461 check_glob_iter(cfg
, "remote\\.ab.*", 2);
462 check_glob_iter(cfg
, ".*url$", 2);
463 check_glob_iter(cfg
, ".*dummy.*", 2);
464 check_glob_iter(cfg
, ".*nomatch.*", 0);
466 git_config_free(cfg
);
469 void test_config_read__whitespace_not_required_around_assignment(void)
473 cl_git_pass(git_config_open_ondisk(&cfg
, cl_fixture("config/config14")));
475 cl_git_pass(git_config_get_string_buf(&buf
, cfg
, "a.b"));
476 cl_assert_equal_s("c", buf
.ptr
);
477 git_buf_dispose(&buf
);
479 cl_git_pass(git_config_get_string_buf(&buf
, cfg
, "d.e"));
480 cl_assert_equal_s("f", buf
.ptr
);
482 git_config_free(cfg
);
485 void test_config_read__read_git_config_entry(void)
488 git_config_entry
*entry
;
490 cl_git_pass(git_config_new(&cfg
));
491 cl_git_pass(git_config_add_file_ondisk(cfg
, cl_fixture("config/config9"),
492 GIT_CONFIG_LEVEL_SYSTEM
, NULL
, 0));
494 cl_git_pass(git_config_get_entry(&entry
, cfg
, "core.dummy2"));
495 cl_assert_equal_s("core.dummy2", entry
->name
);
496 cl_assert_equal_s("42", entry
->value
);
497 cl_assert_equal_i(GIT_CONFIG_LEVEL_SYSTEM
, entry
->level
);
499 git_config_entry_free(entry
);
500 git_config_free(cfg
);
504 * At the beginning of the test:
505 * - config9 has: core.dummy2=42
506 * - config15 has: core.dummy2=7
507 * - config16 has: core.dummy2=28
509 void test_config_read__local_config_overrides_global_config_overrides_system_config(void)
514 cl_git_pass(git_config_new(&cfg
));
515 cl_git_pass(git_config_add_file_ondisk(cfg
, cl_fixture("config/config9"),
516 GIT_CONFIG_LEVEL_SYSTEM
, NULL
, 0));
517 cl_git_pass(git_config_add_file_ondisk(cfg
, cl_fixture("config/config15"),
518 GIT_CONFIG_LEVEL_GLOBAL
, NULL
, 0));
519 cl_git_pass(git_config_add_file_ondisk(cfg
, cl_fixture("config/config16"),
520 GIT_CONFIG_LEVEL_LOCAL
, NULL
, 0));
522 cl_git_pass(git_config_get_int32(&i
, cfg
, "core.dummy2"));
523 cl_assert_equal_i(28, i
);
525 git_config_free(cfg
);
527 cl_git_pass(git_config_new(&cfg
));
528 cl_git_pass(git_config_add_file_ondisk(cfg
, cl_fixture("config/config9"),
529 GIT_CONFIG_LEVEL_SYSTEM
, NULL
, 0));
530 cl_git_pass(git_config_add_file_ondisk(cfg
, cl_fixture("config/config15"),
531 GIT_CONFIG_LEVEL_GLOBAL
, NULL
, 0));
533 cl_git_pass(git_config_get_int32(&i
, cfg
, "core.dummy2"));
534 cl_assert_equal_i(7, i
);
536 git_config_free(cfg
);
540 * At the beginning of the test:
541 * - config9 has: core.global does not exist
542 * - config15 has: core.global=17
543 * - config16 has: core.global=29
546 * - config9 has: core.system does not exist
547 * - config15 has: core.system does not exist
548 * - config16 has: core.system=11
550 void test_config_read__fallback_from_local_to_global_and_from_global_to_system(void)
555 cl_git_pass(git_config_new(&cfg
));
556 cl_git_pass(git_config_add_file_ondisk(cfg
, cl_fixture("config/config9"),
557 GIT_CONFIG_LEVEL_SYSTEM
, NULL
, 0));
558 cl_git_pass(git_config_add_file_ondisk(cfg
, cl_fixture("config/config15"),
559 GIT_CONFIG_LEVEL_GLOBAL
, NULL
, 0));
560 cl_git_pass(git_config_add_file_ondisk(cfg
, cl_fixture("config/config16"),
561 GIT_CONFIG_LEVEL_LOCAL
, NULL
, 0));
563 cl_git_pass(git_config_get_int32(&i
, cfg
, "core.global"));
564 cl_assert_equal_i(17, i
);
565 cl_git_pass(git_config_get_int32(&i
, cfg
, "core.system"));
566 cl_assert_equal_i(11, i
);
568 git_config_free(cfg
);
571 void test_config_read__parent_dir_is_file(void)
576 cl_git_pass(git_config_new(&cfg
));
578 * Verify we can add non-existing files when the parent directory is not
581 cl_git_pass(git_config_add_file_ondisk(cfg
, "/dev/null/.gitconfig",
582 GIT_CONFIG_LEVEL_SYSTEM
, NULL
, 0));
585 cl_git_pass(git_config_foreach(cfg
, count_cfg_entries_and_compare_levels
, &count
));
586 cl_assert_equal_i(0, count
);
588 git_config_free(cfg
);
592 * At the beginning of the test, config18 has:
594 * int64global = 9223372036854775803
596 * stringglobal = I'm a global config value!
602 * stringglobal = don't find me!
605 void test_config_read__simple_read_from_specific_level(void)
607 git_config
*cfg
, *cfg_specific
;
609 int64_t l
, expected
= +9223372036854775803;
611 cl_git_pass(git_config_new(&cfg
));
612 cl_git_pass(git_config_add_file_ondisk(cfg
, cl_fixture("config/config18"),
613 GIT_CONFIG_LEVEL_GLOBAL
, NULL
, 0));
614 cl_git_pass(git_config_add_file_ondisk(cfg
, cl_fixture("config/config19"),
615 GIT_CONFIG_LEVEL_SYSTEM
, NULL
, 0));
617 cl_git_pass(git_config_open_level(&cfg_specific
, cfg
, GIT_CONFIG_LEVEL_GLOBAL
));
619 cl_git_pass(git_config_get_int32(&i
, cfg_specific
, "core.int32global"));
620 cl_assert_equal_i(28, i
);
621 cl_git_pass(git_config_get_int64(&l
, cfg_specific
, "core.int64global"));
622 cl_assert(l
== expected
);
623 cl_git_pass(git_config_get_bool(&i
, cfg_specific
, "core.boolglobal"));
624 cl_assert_equal_b(true, i
);
625 cl_git_pass(git_config_get_string_buf(&buf
, cfg_specific
, "core.stringglobal"));
626 cl_assert_equal_s("I'm a global config value!", buf
.ptr
);
628 git_config_free(cfg_specific
);
629 git_config_free(cfg
);
632 void test_config_read__can_load_and_parse_an_empty_config_file(void)
637 cl_set_cleanup(&clean_test_config
, NULL
);
638 cl_git_mkfile("./testconfig", "");
639 cl_git_pass(git_config_open_ondisk(&cfg
, "./testconfig"));
640 cl_assert_equal_i(GIT_ENOTFOUND
, git_config_get_int32(&i
, cfg
, "nope.neither"));
642 git_config_free(cfg
);
645 void test_config_read__corrupt_header(void)
649 cl_set_cleanup(&clean_test_config
, NULL
);
650 cl_git_mkfile("./testconfig", "[sneaky ] \"quoted closing quote mark\\\"");
651 cl_git_fail(git_config_open_ondisk(&cfg
, "./testconfig"));
653 git_config_free(cfg
);
656 void test_config_read__corrupt_header2(void)
660 cl_set_cleanup(&clean_test_config
, NULL
);
661 cl_git_mkfile("./testconfig", "[unclosed \"bracket\"\n lib = git2\n");
662 cl_git_fail(git_config_open_ondisk(&cfg
, "./testconfig"));
664 git_config_free(cfg
);
667 void test_config_read__corrupt_header3(void)
671 cl_set_cleanup(&clean_test_config
, NULL
);
672 cl_git_mkfile("./testconfig", "[unclosed \"slash\\\"]\n lib = git2\n");
673 cl_git_fail(git_config_open_ondisk(&cfg
, "./testconfig"));
675 git_config_free(cfg
);
678 void test_config_read__invalid_key_chars(void)
682 cl_set_cleanup(&clean_test_config
, NULL
);
683 cl_git_mkfile("./testconfig", "[foo]\n has_underscore = git2\n");
684 cl_git_fail(git_config_open_ondisk(&cfg
, "./testconfig"));
686 cl_git_rewritefile("./testconfig", "[foo]\n has/slash = git2\n");
687 cl_git_fail(git_config_open_ondisk(&cfg
, "./testconfig"));
689 cl_git_rewritefile("./testconfig", "[foo]\n has+plus = git2\n");
690 cl_git_fail(git_config_open_ondisk(&cfg
, "./testconfig"));
692 cl_git_rewritefile("./testconfig", "[no_key]\n = git2\n");
693 cl_git_fail(git_config_open_ondisk(&cfg
, "./testconfig"));
695 git_config_free(cfg
);
698 void test_config_read__lone_variable_with_trailing_whitespace(void)
703 cl_set_cleanup(&clean_test_config
, NULL
);
704 cl_git_mkfile("./testconfig", "[foo]\n lonevariable \n");
705 cl_git_pass(git_config_open_ondisk(&cfg
, "./testconfig"));
707 cl_git_pass(git_config_get_bool(&b
, cfg
, "foo.lonevariable"));
708 cl_assert_equal_b(true, b
);
710 git_config_free(cfg
);
713 void test_config_read__override_variable(void)
717 cl_set_cleanup(&clean_test_config
, NULL
);
718 cl_git_mkfile("./testconfig", "[some] var = one\nvar = two");
719 cl_git_pass(git_config_open_ondisk(&cfg
, "./testconfig"));
721 cl_git_pass(git_config_get_string_buf(&buf
, cfg
, "some.var"));
722 cl_assert_equal_s("two", buf
.ptr
);
724 git_config_free(cfg
);
727 void test_config_read__path(void)
730 git_buf path
= GIT_BUF_INIT
;
731 git_buf old_path
= GIT_BUF_INIT
;
732 git_str home_path
= GIT_STR_INIT
;
733 git_str expected_path
= GIT_STR_INIT
;
735 cl_git_pass(p_mkdir("fakehome", 0777));
736 cl_git_pass(git_fs_path_prettify(&home_path
, "fakehome", NULL
));
737 cl_git_pass(git_libgit2_opts(GIT_OPT_GET_SEARCH_PATH
, GIT_CONFIG_LEVEL_GLOBAL
, &old_path
));
738 cl_git_pass(git_libgit2_opts(GIT_OPT_SET_SEARCH_PATH
, GIT_CONFIG_LEVEL_GLOBAL
, home_path
.ptr
));
739 cl_git_mkfile("./testconfig", "[some]\n path = ~/somefile");
740 cl_git_pass(git_fs_path_join_unrooted(&expected_path
, "somefile", home_path
.ptr
, NULL
));
742 cl_git_pass(git_config_open_ondisk(&cfg
, "./testconfig"));
743 cl_git_pass(git_config_get_path(&path
, cfg
, "some.path"));
744 cl_assert_equal_s(expected_path
.ptr
, path
.ptr
);
745 git_buf_dispose(&path
);
747 cl_git_mkfile("./testconfig", "[some]\n path = ~/");
748 cl_git_pass(git_fs_path_join_unrooted(&expected_path
, "", home_path
.ptr
, NULL
));
750 cl_git_pass(git_config_get_path(&path
, cfg
, "some.path"));
751 cl_assert_equal_s(expected_path
.ptr
, path
.ptr
);
752 git_buf_dispose(&path
);
754 cl_git_mkfile("./testconfig", "[some]\n path = ~");
755 cl_git_pass(git_str_sets(&expected_path
, home_path
.ptr
));
757 cl_git_pass(git_config_get_path(&path
, cfg
, "some.path"));
758 cl_assert_equal_s(expected_path
.ptr
, path
.ptr
);
759 git_buf_dispose(&path
);
761 cl_git_mkfile("./testconfig", "[some]\n path = ~user/foo");
762 cl_git_fail(git_config_get_path(&path
, cfg
, "some.path"));
764 cl_git_pass(git_libgit2_opts(GIT_OPT_SET_SEARCH_PATH
, GIT_CONFIG_LEVEL_GLOBAL
, old_path
.ptr
));
765 git_buf_dispose(&old_path
);
766 git_str_dispose(&home_path
);
767 git_str_dispose(&expected_path
);
768 git_config_free(cfg
);
771 void test_config_read__crlf_style_line_endings(void)
773 git_buf buf
= GIT_BUF_INIT
;
776 cl_set_cleanup(&clean_test_config
, NULL
);
777 cl_git_mkfile("./testconfig", "[some]\r\n var = value\r\n");
778 cl_git_pass(git_config_open_ondisk(&cfg
, "./testconfig"));
779 cl_git_pass(git_config_get_string_buf(&buf
, cfg
, "some.var"));
780 cl_assert_equal_s(buf
.ptr
, "value");
782 git_config_free(cfg
);
783 git_buf_dispose(&buf
);
786 void test_config_read__trailing_crlf(void)
788 git_buf buf
= GIT_BUF_INIT
;
791 cl_set_cleanup(&clean_test_config
, NULL
);
792 cl_git_mkfile("./testconfig", "[some]\r\n var = value\r\n\r\n");
793 cl_git_pass(git_config_open_ondisk(&cfg
, "./testconfig"));
794 cl_git_pass(git_config_get_string_buf(&buf
, cfg
, "some.var"));
795 cl_assert_equal_s(buf
.ptr
, "value");
797 git_config_free(cfg
);
798 git_buf_dispose(&buf
);
801 void test_config_read__bom(void)
803 git_buf buf
= GIT_BUF_INIT
;
806 cl_set_cleanup(&clean_test_config
, NULL
);
807 cl_git_mkfile("./testconfig", "\xEF\xBB\xBF[some]\n var = value\n");
808 cl_git_pass(git_config_open_ondisk(&cfg
, "./testconfig"));
809 cl_git_pass(git_config_get_string_buf(&buf
, cfg
, "some.var"));
810 cl_assert_equal_s(buf
.ptr
, "value");
812 git_config_free(cfg
);
813 git_buf_dispose(&buf
);
816 void test_config_read__arbitrary_whitespace_before_subsection(void)
818 git_buf buf
= GIT_BUF_INIT
;
821 cl_set_cleanup(&clean_test_config
, NULL
);
822 cl_git_mkfile("./testconfig", "[some \t \"subsection\"]\n var = value\n");
823 cl_git_pass(git_config_open_ondisk(&cfg
, "./testconfig"));
824 cl_git_pass(git_config_get_string_buf(&buf
, cfg
, "some.subsection.var"));
825 cl_assert_equal_s(buf
.ptr
, "value");
827 git_config_free(cfg
);
828 git_buf_dispose(&buf
);
831 void test_config_read__no_whitespace_after_subsection(void)
835 cl_set_cleanup(&clean_test_config
, NULL
);
836 cl_git_mkfile("./testconfig", "[some \"subsection\" ]\n var = value\n");
837 cl_git_fail(git_config_open_ondisk(&cfg
, "./testconfig"));
839 git_config_free(cfg
);
842 void test_config_read__invalid_space_section(void)
846 cl_set_cleanup(&clean_test_config
, NULL
);
847 cl_git_mkfile("./testconfig", "\xEF\xBB\xBF[some section]\n var = value\n");
848 cl_git_fail(git_config_open_ondisk(&cfg
, "./testconfig"));
850 git_config_free(cfg
);
853 void test_config_read__invalid_quoted_first_section(void)
857 cl_set_cleanup(&clean_test_config
, NULL
);
858 cl_git_mkfile("./testconfig", "\xEF\xBB\xBF[\"some\"]\n var = value\n");
859 cl_git_fail(git_config_open_ondisk(&cfg
, "./testconfig"));
861 git_config_free(cfg
);
864 void test_config_read__invalid_unquoted_subsection(void)
868 cl_set_cleanup(&clean_test_config
, NULL
);
869 cl_git_mkfile("./testconfig", "\xEF\xBB\xBF[some sub section]\n var = value\n");
870 cl_git_fail(git_config_open_ondisk(&cfg
, "./testconfig"));
872 git_config_free(cfg
);
875 void test_config_read__invalid_quoted_third_section(void)
879 cl_set_cleanup(&clean_test_config
, NULL
);
880 cl_git_mkfile("./testconfig", "\xEF\xBB\xBF[some sub \"section\"]\n var = value\n");
881 cl_git_fail(git_config_open_ondisk(&cfg
, "./testconfig"));
883 git_config_free(cfg
);
886 void test_config_read__unreadable_file_ignored(void)
888 git_buf buf
= GIT_BUF_INIT
;
892 cl_set_cleanup(&clean_test_config
, NULL
);
893 cl_git_mkfile("./testconfig", "[some] var = value\n[some \"OtheR\"] var = value");
894 cl_git_pass(p_chmod("./testconfig", 0));
896 ret
= git_config_open_ondisk(&cfg
, "./test/config");
897 cl_assert(ret
== 0 || ret
== GIT_ENOTFOUND
);
899 git_config_free(cfg
);
900 git_buf_dispose(&buf
);
903 void test_config_read__single_line(void)
905 git_buf buf
= GIT_BUF_INIT
;
908 cl_set_cleanup(&clean_test_config
, NULL
);
909 cl_git_mkfile("./testconfig", "[some] var = value\n[some \"OtheR\"] var = value");
910 cl_git_pass(git_config_open_ondisk(&cfg
, "./testconfig"));
911 cl_git_pass(git_config_get_string_buf(&buf
, cfg
, "some.var"));
912 cl_assert_equal_s(buf
.ptr
, "value");
914 git_buf_dispose(&buf
);
915 cl_git_pass(git_config_get_string_buf(&buf
, cfg
, "some.OtheR.var"));
916 cl_assert_equal_s(buf
.ptr
, "value");
918 git_config_free(cfg
);
919 cl_git_mkfile("./testconfig", "[some] var = value\n[some \"OtheR\"]var = value");
920 cl_git_pass(git_config_open_ondisk(&cfg
, "./testconfig"));
921 git_buf_dispose(&buf
);
922 cl_git_pass(git_config_get_string_buf(&buf
, cfg
, "some.var"));
923 cl_assert_equal_s(buf
.ptr
, "value");
925 git_buf_dispose(&buf
);
926 cl_git_pass(git_config_get_string_buf(&buf
, cfg
, "some.OtheR.var"));
927 cl_assert_equal_s(buf
.ptr
, "value");
929 git_config_free(cfg
);
930 git_buf_dispose(&buf
);
933 static int read_nosection_cb(const git_config_entry
*entry
, void *payload
) {
934 int *seen
= (int*)payload
;
935 if (strcmp(entry
->name
, "key") == 0) {
941 /* This would ideally issue a warning, if we had a way to do so. */
942 void test_config_read__nosection(void)
945 git_buf buf
= GIT_BUF_INIT
;
948 cl_git_pass(git_config_open_ondisk(&cfg
, cl_fixture("config/config-nosection")));
951 * Given a key with no section, we do not allow reading it,
952 * but we do include it in an iteration over the config
953 * store. This appears to match how git's own APIs (and
954 * git-config(1)) behave.
957 cl_git_fail_with(git_config_get_string_buf(&buf
, cfg
, "key"), GIT_EINVALIDSPEC
);
959 cl_git_pass(git_config_foreach(cfg
, read_nosection_cb
, &seen
));
960 cl_assert_equal_i(seen
, 1);
962 git_buf_dispose(&buf
);
963 git_config_free(cfg
);
972 static git_configmap _test_map1
[] = {
973 {GIT_CONFIGMAP_STRING
, "always", MAP_ALWAYS
},
974 {GIT_CONFIGMAP_FALSE
, NULL
, MAP_FALSE
},
975 {GIT_CONFIGMAP_TRUE
, NULL
, MAP_TRUE
},
978 static git_configmap _test_map2
[] = {
979 {GIT_CONFIGMAP_INT32
, NULL
, 0},
982 void test_config_read__get_mapped(void)
988 cl_set_cleanup(&clean_test_config
, NULL
);
989 cl_git_mkfile("./testconfig", "[header]\n"
999 cl_git_pass(git_config_open_ondisk(&cfg
, "./testconfig"));
1001 /* check parsing bool and string */
1002 cl_git_pass(git_config_get_mapped(&val
, cfg
, "header.key1", _test_map1
, ARRAY_SIZE(_test_map1
)));
1003 cl_assert_equal_i(val
, MAP_TRUE
);
1004 cl_git_pass(git_config_get_mapped(&val
, cfg
, "header.key2", _test_map1
, ARRAY_SIZE(_test_map1
)));
1005 cl_assert_equal_i(val
, MAP_TRUE
);
1006 cl_git_pass(git_config_get_mapped(&val
, cfg
, "header.key3", _test_map1
, ARRAY_SIZE(_test_map1
)));
1007 cl_assert_equal_i(val
, MAP_TRUE
);
1008 cl_git_pass(git_config_get_mapped(&val
, cfg
, "header.key8", _test_map1
, ARRAY_SIZE(_test_map1
)));
1009 cl_assert_equal_i(val
, MAP_TRUE
);
1011 cl_git_pass(git_config_get_mapped(&val
, cfg
, "header.key4", _test_map1
, ARRAY_SIZE(_test_map1
)));
1012 cl_assert_equal_i(val
, MAP_ALWAYS
);
1014 cl_git_pass(git_config_get_mapped(&val
, cfg
, "header.key5", _test_map1
, ARRAY_SIZE(_test_map1
)));
1015 cl_assert_equal_i(val
, MAP_FALSE
);
1016 cl_git_pass(git_config_get_mapped(&val
, cfg
, "header.key6", _test_map1
, ARRAY_SIZE(_test_map1
)));
1017 cl_assert_equal_i(val
, MAP_FALSE
);
1018 cl_git_pass(git_config_get_mapped(&val
, cfg
, "header.key9", _test_map1
, ARRAY_SIZE(_test_map1
)));
1019 cl_assert_equal_i(val
, MAP_FALSE
);
1021 cl_git_fail(git_config_get_mapped(&val
, cfg
, "header.key7", _test_map1
, ARRAY_SIZE(_test_map1
)));
1023 /* check parsing int values */
1024 cl_git_pass(git_config_get_mapped(&val
, cfg
, "header.key1", _test_map2
, ARRAY_SIZE(_test_map2
)));
1025 cl_git_pass(git_config_get_int32(&known_good
, cfg
, "header.key1"));
1026 cl_assert_equal_i(val
, known_good
);
1027 cl_git_pass(git_config_get_mapped(&val
, cfg
, "header.key6", _test_map2
, ARRAY_SIZE(_test_map2
)));
1028 cl_git_pass(git_config_get_int32(&known_good
, cfg
, "header.key6"));
1029 cl_assert_equal_i(val
, known_good
);
1031 cl_git_fail(git_config_get_mapped(&val
, cfg
, "header.key2", _test_map2
, ARRAY_SIZE(_test_map2
)));
1032 cl_git_fail(git_config_get_mapped(&val
, cfg
, "header.key3", _test_map2
, ARRAY_SIZE(_test_map2
)));
1033 cl_git_fail(git_config_get_mapped(&val
, cfg
, "header.key4", _test_map2
, ARRAY_SIZE(_test_map2
)));
1034 cl_git_fail(git_config_get_mapped(&val
, cfg
, "header.key5", _test_map2
, ARRAY_SIZE(_test_map2
)));
1035 cl_git_fail(git_config_get_mapped(&val
, cfg
, "header.key7", _test_map2
, ARRAY_SIZE(_test_map2
)));
1036 cl_git_fail(git_config_get_mapped(&val
, cfg
, "header.key8", _test_map2
, ARRAY_SIZE(_test_map2
)));
1037 cl_git_fail(git_config_get_mapped(&val
, cfg
, "header.key9", _test_map2
, ARRAY_SIZE(_test_map2
)));
1039 git_config_free(cfg
);