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
));
72 static void clean_test_config(void *unused
)
75 cl_fixture_cleanup("./testconfig");
78 void test_config_read__multiline_value_and_eof(void)
82 cl_set_cleanup(&clean_test_config
, NULL
);
83 cl_git_mkfile("./testconfig", "[header]\n key1 = foo\\\n");
84 cl_git_pass(git_config_open_ondisk(&cfg
, "./testconfig"));
86 cl_git_pass(git_config_get_string_buf(&buf
, cfg
, "header.key1"));
87 cl_assert_equal_s("foo", git_buf_cstr(&buf
));
92 void test_config_read__multiline_eof(void)
96 cl_set_cleanup(&clean_test_config
, NULL
);
97 cl_git_mkfile("./testconfig", "[header]\n key1 = \\\n");
98 cl_git_pass(git_config_open_ondisk(&cfg
, "./testconfig"));
100 cl_git_pass(git_config_get_string_buf(&buf
, cfg
, "header.key1"));
101 cl_assert_equal_s("", git_buf_cstr(&buf
));
103 git_config_free(cfg
);
107 * This kind of subsection declaration is case-insensitive
109 void test_config_read__subsection_header(void)
113 cl_git_pass(git_config_open_ondisk(&cfg
, cl_fixture("config/config3")));
115 cl_git_pass(git_config_get_string_buf(&buf
, cfg
, "section.subsection.var"));
116 cl_assert_equal_s("hello", git_buf_cstr(&buf
));
118 /* The subsection is transformed to lower-case */
119 cl_must_fail(git_config_get_string_buf(&buf
, cfg
, "section.subSectIon.var"));
121 git_config_free(cfg
);
124 void test_config_read__lone_variable(void)
129 cl_git_pass(git_config_open_ondisk(&cfg
, cl_fixture("config/config4")));
131 cl_git_fail(git_config_get_int32(&i
, cfg
, "some.section.variable"));
133 cl_git_pass(git_config_get_string_buf(&buf
, cfg
, "some.section.variable"));
134 cl_assert_equal_s("", git_buf_cstr(&buf
));
137 cl_git_pass(git_config_get_bool(&i
, cfg
, "some.section.variable"));
140 cl_git_pass(git_config_get_string_buf(&buf
, cfg
, "some.section.variableeq"));
141 cl_assert_equal_s("", git_buf_cstr(&buf
));
143 cl_git_pass(git_config_get_bool(&i
, cfg
, "some.section.variableeq"));
146 git_config_free(cfg
);
149 void test_config_read__number_suffixes(void)
154 cl_git_pass(git_config_open_ondisk(&cfg
, cl_fixture("config/config5")));
156 cl_git_pass(git_config_get_int64(&i
, cfg
, "number.simple"));
159 cl_git_pass(git_config_get_int64(&i
, cfg
, "number.k"));
160 cl_assert(i
== 1 * 1024);
162 cl_git_pass(git_config_get_int64(&i
, cfg
, "number.kk"));
163 cl_assert(i
== 1 * 1024);
165 cl_git_pass(git_config_get_int64(&i
, cfg
, "number.m"));
166 cl_assert(i
== 1 * 1024 * 1024);
168 cl_git_pass(git_config_get_int64(&i
, cfg
, "number.mm"));
169 cl_assert(i
== 1 * 1024 * 1024);
171 cl_git_pass(git_config_get_int64(&i
, cfg
, "number.g"));
172 cl_assert(i
== 1 * 1024 * 1024 * 1024);
174 cl_git_pass(git_config_get_int64(&i
, cfg
, "number.gg"));
175 cl_assert(i
== 1 * 1024 * 1024 * 1024);
177 git_config_free(cfg
);
180 void test_config_read__blank_lines(void)
185 cl_git_pass(git_config_open_ondisk(&cfg
, cl_fixture("config/config6")));
187 cl_git_pass(git_config_get_bool(&i
, cfg
, "valid.subsection.something"));
190 cl_git_pass(git_config_get_bool(&i
, cfg
, "something.else.something"));
193 git_config_free(cfg
);
196 void test_config_read__invalid_ext_headers(void)
199 cl_must_fail(git_config_open_ondisk(&cfg
, cl_fixture("config/config7")));
202 void test_config_read__empty_files(void)
205 cl_git_pass(git_config_open_ondisk(&cfg
, cl_fixture("config/config8")));
206 git_config_free(cfg
);
209 void test_config_read__symbol_headers(void)
212 cl_git_pass(git_config_open_ondisk(&cfg
, cl_fixture("config/config20")));
213 git_config_free(cfg
);
216 void test_config_read__header_in_last_line(void)
220 cl_git_pass(git_config_open_ondisk(&cfg
, cl_fixture("config/config10")));
221 git_config_free(cfg
);
224 void test_config_read__prefixes(void)
228 cl_git_pass(git_config_open_ondisk(&cfg
, cl_fixture("config/config9")));
229 cl_git_pass(git_config_get_string_buf(&buf
, cfg
, "remote.ab.url"));
230 cl_assert_equal_s("http://example.com/git/ab", git_buf_cstr(&buf
));
233 cl_git_pass(git_config_get_string_buf(&buf
, cfg
, "remote.abba.url"));
234 cl_assert_equal_s("http://example.com/git/abba", git_buf_cstr(&buf
));
236 git_config_free(cfg
);
239 void test_config_read__escaping_quotes(void)
243 cl_git_pass(git_config_open_ondisk(&cfg
, cl_fixture("config/config13")));
244 cl_git_pass(git_config_get_string_buf(&buf
, cfg
, "core.editor"));
245 cl_assert_equal_s("\"C:/Program Files/Nonsense/bah.exe\" \"--some option\"", git_buf_cstr(&buf
));
247 git_config_free(cfg
);
250 void test_config_read__invalid_escape_sequence(void)
254 cl_set_cleanup(&clean_test_config
, NULL
);
255 cl_git_mkfile("./testconfig", "[header]\n key1 = \\\\\\;\n key2 = value2\n");
256 cl_git_fail(git_config_open_ondisk(&cfg
, "./testconfig"));
258 git_config_free(cfg
);
261 static int count_cfg_entries_and_compare_levels(
262 const git_config_entry
*entry
, void *payload
)
264 int *count
= payload
;
266 if (!strcmp(entry
->value
, "7") || !strcmp(entry
->value
, "17"))
267 cl_assert(entry
->level
== GIT_CONFIG_LEVEL_GLOBAL
);
269 cl_assert(entry
->level
== GIT_CONFIG_LEVEL_SYSTEM
);
275 static int cfg_callback_countdown(const git_config_entry
*entry
, void *payload
)
277 int *count
= payload
;
285 void test_config_read__foreach(void)
290 cl_git_pass(git_config_new(&cfg
));
291 cl_git_pass(git_config_add_file_ondisk(cfg
, cl_fixture("config/config9"),
292 GIT_CONFIG_LEVEL_SYSTEM
, NULL
, 0));
293 cl_git_pass(git_config_add_file_ondisk(cfg
, cl_fixture("config/config15"),
294 GIT_CONFIG_LEVEL_GLOBAL
, NULL
, 0));
297 cl_git_pass(git_config_foreach(cfg
, count_cfg_entries_and_compare_levels
, &count
));
298 cl_assert_equal_i(7, count
);
301 cl_git_fail(ret
= git_config_foreach(cfg
, cfg_callback_countdown
, &count
));
302 cl_assert_equal_i(-100, ret
);
304 git_config_free(cfg
);
307 void test_config_read__iterator(void)
309 const char *keys
[] = {
319 git_config_iterator
*iter
;
320 git_config_entry
*entry
;
323 cl_git_pass(git_config_new(&cfg
));
324 cl_git_pass(git_config_add_file_ondisk(cfg
, cl_fixture("config/config9"),
325 GIT_CONFIG_LEVEL_SYSTEM
, NULL
, 0));
326 cl_git_pass(git_config_add_file_ondisk(cfg
, cl_fixture("config/config15"),
327 GIT_CONFIG_LEVEL_GLOBAL
, NULL
, 0));
330 cl_git_pass(git_config_iterator_new(&iter
, cfg
));
332 while ((ret
= git_config_next(&entry
, iter
)) == 0) {
333 cl_assert_equal_s(entry
->name
, keys
[count
]);
337 git_config_iterator_free(iter
);
338 cl_assert_equal_i(GIT_ITEROVER
, ret
);
339 cl_assert_equal_i(7, count
);
342 cl_git_pass(git_config_iterator_new(&iter
, cfg
));
344 git_config_iterator_free(iter
);
345 git_config_free(cfg
);
348 static int count_cfg_entries(const git_config_entry
*entry
, void *payload
)
350 int *count
= payload
;
356 void test_config_read__foreach_match(void)
361 cl_git_pass(git_config_open_ondisk(&cfg
, cl_fixture("config/config9")));
365 git_config_foreach_match(cfg
, "core.*", count_cfg_entries
, &count
));
366 cl_assert_equal_i(3, count
);
370 git_config_foreach_match(cfg
, "remote\\.ab.*", count_cfg_entries
, &count
));
371 cl_assert_equal_i(2, count
);
375 git_config_foreach_match(cfg
, ".*url$", count_cfg_entries
, &count
));
376 cl_assert_equal_i(2, count
);
380 git_config_foreach_match(cfg
, ".*dummy.*", count_cfg_entries
, &count
));
381 cl_assert_equal_i(2, count
);
385 git_config_foreach_match(cfg
, ".*nomatch.*", count_cfg_entries
, &count
));
386 cl_assert_equal_i(0, count
);
388 git_config_free(cfg
);
391 static void check_glob_iter(git_config
*cfg
, const char *regexp
, int expected
)
393 git_config_iterator
*iter
;
394 git_config_entry
*entry
;
397 cl_git_pass(git_config_iterator_glob_new(&iter
, cfg
, regexp
));
400 while ((error
= git_config_next(&entry
, iter
)) == 0)
403 cl_assert_equal_i(GIT_ITEROVER
, error
);
404 cl_assert_equal_i(expected
, count
);
405 git_config_iterator_free(iter
);
408 void test_config_read__iterator_invalid_glob(void)
411 git_config_iterator
*iter
;
413 cl_git_pass(git_config_open_ondisk(&cfg
, cl_fixture("config/config9")));
415 cl_git_fail(git_config_iterator_glob_new(&iter
, cfg
, "*"));
417 git_config_free(cfg
);
420 void test_config_read__iterator_glob(void)
424 cl_git_pass(git_config_open_ondisk(&cfg
, cl_fixture("config/config9")));
426 check_glob_iter(cfg
, "core.*", 3);
427 check_glob_iter(cfg
, "remote\\.ab.*", 2);
428 check_glob_iter(cfg
, ".*url$", 2);
429 check_glob_iter(cfg
, ".*dummy.*", 2);
430 check_glob_iter(cfg
, ".*nomatch.*", 0);
432 git_config_free(cfg
);
435 void test_config_read__whitespace_not_required_around_assignment(void)
439 cl_git_pass(git_config_open_ondisk(&cfg
, cl_fixture("config/config14")));
441 cl_git_pass(git_config_get_string_buf(&buf
, cfg
, "a.b"));
442 cl_assert_equal_s("c", git_buf_cstr(&buf
));
445 cl_git_pass(git_config_get_string_buf(&buf
, cfg
, "d.e"));
446 cl_assert_equal_s("f", git_buf_cstr(&buf
));
448 git_config_free(cfg
);
451 void test_config_read__read_git_config_entry(void)
454 git_config_entry
*entry
;
456 cl_git_pass(git_config_new(&cfg
));
457 cl_git_pass(git_config_add_file_ondisk(cfg
, cl_fixture("config/config9"),
458 GIT_CONFIG_LEVEL_SYSTEM
, NULL
, 0));
460 cl_git_pass(git_config_get_entry(&entry
, cfg
, "core.dummy2"));
461 cl_assert_equal_s("core.dummy2", entry
->name
);
462 cl_assert_equal_s("42", entry
->value
);
463 cl_assert_equal_i(GIT_CONFIG_LEVEL_SYSTEM
, entry
->level
);
465 git_config_entry_free(entry
);
466 git_config_free(cfg
);
470 * At the beginning of the test:
471 * - config9 has: core.dummy2=42
472 * - config15 has: core.dummy2=7
473 * - config16 has: core.dummy2=28
475 void test_config_read__local_config_overrides_global_config_overrides_system_config(void)
480 cl_git_pass(git_config_new(&cfg
));
481 cl_git_pass(git_config_add_file_ondisk(cfg
, cl_fixture("config/config9"),
482 GIT_CONFIG_LEVEL_SYSTEM
, NULL
, 0));
483 cl_git_pass(git_config_add_file_ondisk(cfg
, cl_fixture("config/config15"),
484 GIT_CONFIG_LEVEL_GLOBAL
, NULL
, 0));
485 cl_git_pass(git_config_add_file_ondisk(cfg
, cl_fixture("config/config16"),
486 GIT_CONFIG_LEVEL_LOCAL
, NULL
, 0));
488 cl_git_pass(git_config_get_int32(&i
, cfg
, "core.dummy2"));
489 cl_assert_equal_i(28, i
);
491 git_config_free(cfg
);
493 cl_git_pass(git_config_new(&cfg
));
494 cl_git_pass(git_config_add_file_ondisk(cfg
, cl_fixture("config/config9"),
495 GIT_CONFIG_LEVEL_SYSTEM
, NULL
, 0));
496 cl_git_pass(git_config_add_file_ondisk(cfg
, cl_fixture("config/config15"),
497 GIT_CONFIG_LEVEL_GLOBAL
, NULL
, 0));
499 cl_git_pass(git_config_get_int32(&i
, cfg
, "core.dummy2"));
500 cl_assert_equal_i(7, i
);
502 git_config_free(cfg
);
506 * At the beginning of the test:
507 * - config9 has: core.global does not exist
508 * - config15 has: core.global=17
509 * - config16 has: core.global=29
512 * - config9 has: core.system does not exist
513 * - config15 has: core.system does not exist
514 * - config16 has: core.system=11
516 void test_config_read__fallback_from_local_to_global_and_from_global_to_system(void)
521 cl_git_pass(git_config_new(&cfg
));
522 cl_git_pass(git_config_add_file_ondisk(cfg
, cl_fixture("config/config9"),
523 GIT_CONFIG_LEVEL_SYSTEM
, NULL
, 0));
524 cl_git_pass(git_config_add_file_ondisk(cfg
, cl_fixture("config/config15"),
525 GIT_CONFIG_LEVEL_GLOBAL
, NULL
, 0));
526 cl_git_pass(git_config_add_file_ondisk(cfg
, cl_fixture("config/config16"),
527 GIT_CONFIG_LEVEL_LOCAL
, NULL
, 0));
529 cl_git_pass(git_config_get_int32(&i
, cfg
, "core.global"));
530 cl_assert_equal_i(17, i
);
531 cl_git_pass(git_config_get_int32(&i
, cfg
, "core.system"));
532 cl_assert_equal_i(11, i
);
534 git_config_free(cfg
);
537 void test_config_read__parent_dir_is_file(void)
542 cl_git_pass(git_config_new(&cfg
));
544 * Verify we can add non-existing files when the parent directory is not
547 cl_git_pass(git_config_add_file_ondisk(cfg
, "/dev/null/.gitconfig",
548 GIT_CONFIG_LEVEL_SYSTEM
, NULL
, 0));
551 cl_git_pass(git_config_foreach(cfg
, count_cfg_entries_and_compare_levels
, &count
));
552 cl_assert_equal_i(0, count
);
554 git_config_free(cfg
);
558 * At the beginning of the test, config18 has:
560 * int64global = 9223372036854775803
562 * stringglobal = I'm a global config value!
568 * stringglobal = don't find me!
571 void test_config_read__simple_read_from_specific_level(void)
573 git_config
*cfg
, *cfg_specific
;
575 int64_t l
, expected
= +9223372036854775803;
577 cl_git_pass(git_config_new(&cfg
));
578 cl_git_pass(git_config_add_file_ondisk(cfg
, cl_fixture("config/config18"),
579 GIT_CONFIG_LEVEL_GLOBAL
, NULL
, 0));
580 cl_git_pass(git_config_add_file_ondisk(cfg
, cl_fixture("config/config19"),
581 GIT_CONFIG_LEVEL_SYSTEM
, NULL
, 0));
583 cl_git_pass(git_config_open_level(&cfg_specific
, cfg
, GIT_CONFIG_LEVEL_GLOBAL
));
585 cl_git_pass(git_config_get_int32(&i
, cfg_specific
, "core.int32global"));
586 cl_assert_equal_i(28, i
);
587 cl_git_pass(git_config_get_int64(&l
, cfg_specific
, "core.int64global"));
588 cl_assert(l
== expected
);
589 cl_git_pass(git_config_get_bool(&i
, cfg_specific
, "core.boolglobal"));
590 cl_assert_equal_b(true, i
);
591 cl_git_pass(git_config_get_string_buf(&buf
, cfg_specific
, "core.stringglobal"));
592 cl_assert_equal_s("I'm a global config value!", git_buf_cstr(&buf
));
594 git_config_free(cfg_specific
);
595 git_config_free(cfg
);
598 void test_config_read__can_load_and_parse_an_empty_config_file(void)
603 cl_set_cleanup(&clean_test_config
, NULL
);
604 cl_git_mkfile("./testconfig", "");
605 cl_git_pass(git_config_open_ondisk(&cfg
, "./testconfig"));
606 cl_assert_equal_i(GIT_ENOTFOUND
, git_config_get_int32(&i
, cfg
, "nope.neither"));
608 git_config_free(cfg
);
611 void test_config_read__corrupt_header(void)
615 cl_set_cleanup(&clean_test_config
, NULL
);
616 cl_git_mkfile("./testconfig", "[sneaky ] \"quoted closing quote mark\\\"");
617 cl_git_fail(git_config_open_ondisk(&cfg
, "./testconfig"));
619 git_config_free(cfg
);
622 void test_config_read__corrupt_header2(void)
626 cl_set_cleanup(&clean_test_config
, NULL
);
627 cl_git_mkfile("./testconfig", "[unclosed \"bracket\"\n lib = git2\n");
628 cl_git_fail(git_config_open_ondisk(&cfg
, "./testconfig"));
630 git_config_free(cfg
);
633 void test_config_read__corrupt_header3(void)
637 cl_set_cleanup(&clean_test_config
, NULL
);
638 cl_git_mkfile("./testconfig", "[unclosed \"slash\\\"]\n lib = git2\n");
639 cl_git_fail(git_config_open_ondisk(&cfg
, "./testconfig"));
641 git_config_free(cfg
);
644 void test_config_read__invalid_key_chars(void)
648 cl_set_cleanup(&clean_test_config
, NULL
);
649 cl_git_mkfile("./testconfig", "[foo]\n has_underscore = git2\n");
650 cl_git_fail(git_config_open_ondisk(&cfg
, "./testconfig"));
652 cl_git_rewritefile("./testconfig", "[foo]\n has/slash = git2\n");
653 cl_git_fail(git_config_open_ondisk(&cfg
, "./testconfig"));
655 cl_git_rewritefile("./testconfig", "[foo]\n has+plus = git2\n");
656 cl_git_fail(git_config_open_ondisk(&cfg
, "./testconfig"));
658 cl_git_rewritefile("./testconfig", "[no_key]\n = git2\n");
659 cl_git_fail(git_config_open_ondisk(&cfg
, "./testconfig"));
661 git_config_free(cfg
);
664 void test_config_read__lone_variable_with_trailing_whitespace(void)
669 cl_set_cleanup(&clean_test_config
, NULL
);
670 cl_git_mkfile("./testconfig", "[foo]\n lonevariable \n");
671 cl_git_pass(git_config_open_ondisk(&cfg
, "./testconfig"));
673 cl_git_pass(git_config_get_bool(&b
, cfg
, "foo.lonevariable"));
674 cl_assert_equal_b(true, b
);
676 git_config_free(cfg
);
679 void test_config_read__override_variable(void)
683 cl_set_cleanup(&clean_test_config
, NULL
);
684 cl_git_mkfile("./testconfig", "[some] var = one\nvar = two");
685 cl_git_pass(git_config_open_ondisk(&cfg
, "./testconfig"));
687 cl_git_pass(git_config_get_string_buf(&buf
, cfg
, "some.var"));
688 cl_assert_equal_s("two", git_buf_cstr(&buf
));
690 git_config_free(cfg
);
693 void test_config_read__path(void)
696 git_buf path
= GIT_BUF_INIT
;
697 git_buf old_path
= GIT_BUF_INIT
;
698 git_buf home_path
= GIT_BUF_INIT
;
699 git_buf expected_path
= GIT_BUF_INIT
;
701 cl_git_pass(p_mkdir("fakehome", 0777));
702 cl_git_pass(git_path_prettify(&home_path
, "fakehome", NULL
));
703 cl_git_pass(git_libgit2_opts(GIT_OPT_GET_SEARCH_PATH
, GIT_CONFIG_LEVEL_GLOBAL
, &old_path
));
704 cl_git_pass(git_libgit2_opts(GIT_OPT_SET_SEARCH_PATH
, GIT_CONFIG_LEVEL_GLOBAL
, home_path
.ptr
));
705 cl_git_mkfile("./testconfig", "[some]\n path = ~/somefile");
706 cl_git_pass(git_path_join_unrooted(&expected_path
, "somefile", home_path
.ptr
, NULL
));
708 cl_git_pass(git_config_open_ondisk(&cfg
, "./testconfig"));
709 cl_git_pass(git_config_get_path(&path
, cfg
, "some.path"));
710 cl_assert_equal_s(expected_path
.ptr
, path
.ptr
);
711 git_buf_dispose(&path
);
713 cl_git_mkfile("./testconfig", "[some]\n path = ~/");
714 cl_git_pass(git_path_join_unrooted(&expected_path
, "", home_path
.ptr
, NULL
));
716 cl_git_pass(git_config_get_path(&path
, cfg
, "some.path"));
717 cl_assert_equal_s(expected_path
.ptr
, path
.ptr
);
718 git_buf_dispose(&path
);
720 cl_git_mkfile("./testconfig", "[some]\n path = ~");
721 cl_git_pass(git_buf_sets(&expected_path
, home_path
.ptr
));
723 cl_git_pass(git_config_get_path(&path
, cfg
, "some.path"));
724 cl_assert_equal_s(expected_path
.ptr
, path
.ptr
);
725 git_buf_dispose(&path
);
727 cl_git_mkfile("./testconfig", "[some]\n path = ~user/foo");
728 cl_git_fail(git_config_get_path(&path
, cfg
, "some.path"));
730 cl_git_pass(git_libgit2_opts(GIT_OPT_SET_SEARCH_PATH
, GIT_CONFIG_LEVEL_GLOBAL
, old_path
.ptr
));
731 git_buf_dispose(&old_path
);
732 git_buf_dispose(&home_path
);
733 git_buf_dispose(&expected_path
);
734 git_config_free(cfg
);
737 void test_config_read__crlf_style_line_endings(void)
739 git_buf buf
= GIT_BUF_INIT
;
742 cl_set_cleanup(&clean_test_config
, NULL
);
743 cl_git_mkfile("./testconfig", "[some]\r\n var = value\r\n");
744 cl_git_pass(git_config_open_ondisk(&cfg
, "./testconfig"));
745 cl_git_pass(git_config_get_string_buf(&buf
, cfg
, "some.var"));
746 cl_assert_equal_s(buf
.ptr
, "value");
748 git_config_free(cfg
);
749 git_buf_dispose(&buf
);
752 void test_config_read__trailing_crlf(void)
754 git_buf buf
= GIT_BUF_INIT
;
757 cl_set_cleanup(&clean_test_config
, NULL
);
758 cl_git_mkfile("./testconfig", "[some]\r\n var = value\r\n\r\n");
759 cl_git_pass(git_config_open_ondisk(&cfg
, "./testconfig"));
760 cl_git_pass(git_config_get_string_buf(&buf
, cfg
, "some.var"));
761 cl_assert_equal_s(buf
.ptr
, "value");
763 git_config_free(cfg
);
764 git_buf_dispose(&buf
);
767 void test_config_read__bom(void)
769 git_buf buf
= GIT_BUF_INIT
;
772 cl_set_cleanup(&clean_test_config
, NULL
);
773 cl_git_mkfile("./testconfig", "\xEF\xBB\xBF[some]\n var = value\n");
774 cl_git_pass(git_config_open_ondisk(&cfg
, "./testconfig"));
775 cl_git_pass(git_config_get_string_buf(&buf
, cfg
, "some.var"));
776 cl_assert_equal_s(buf
.ptr
, "value");
778 git_config_free(cfg
);
779 git_buf_dispose(&buf
);
782 void test_config_read__arbitrary_whitespace_before_subsection(void)
784 git_buf buf
= GIT_BUF_INIT
;
787 cl_set_cleanup(&clean_test_config
, NULL
);
788 cl_git_mkfile("./testconfig", "[some \t \"subsection\"]\n var = value\n");
789 cl_git_pass(git_config_open_ondisk(&cfg
, "./testconfig"));
790 cl_git_pass(git_config_get_string_buf(&buf
, cfg
, "some.subsection.var"));
791 cl_assert_equal_s(buf
.ptr
, "value");
793 git_config_free(cfg
);
794 git_buf_dispose(&buf
);
797 void test_config_read__no_whitespace_after_subsection(void)
801 cl_set_cleanup(&clean_test_config
, NULL
);
802 cl_git_mkfile("./testconfig", "[some \"subsection\" ]\n var = value\n");
803 cl_git_fail(git_config_open_ondisk(&cfg
, "./testconfig"));
805 git_config_free(cfg
);
808 void test_config_read__invalid_space_section(void)
812 cl_set_cleanup(&clean_test_config
, NULL
);
813 cl_git_mkfile("./testconfig", "\xEF\xBB\xBF[some section]\n var = value\n");
814 cl_git_fail(git_config_open_ondisk(&cfg
, "./testconfig"));
816 git_config_free(cfg
);
819 void test_config_read__invalid_quoted_first_section(void)
823 cl_set_cleanup(&clean_test_config
, NULL
);
824 cl_git_mkfile("./testconfig", "\xEF\xBB\xBF[\"some\"]\n var = value\n");
825 cl_git_fail(git_config_open_ondisk(&cfg
, "./testconfig"));
827 git_config_free(cfg
);
830 void test_config_read__invalid_unquoted_subsection(void)
834 cl_set_cleanup(&clean_test_config
, NULL
);
835 cl_git_mkfile("./testconfig", "\xEF\xBB\xBF[some sub section]\n var = value\n");
836 cl_git_fail(git_config_open_ondisk(&cfg
, "./testconfig"));
838 git_config_free(cfg
);
841 void test_config_read__invalid_quoted_third_section(void)
845 cl_set_cleanup(&clean_test_config
, NULL
);
846 cl_git_mkfile("./testconfig", "\xEF\xBB\xBF[some sub \"section\"]\n var = value\n");
847 cl_git_fail(git_config_open_ondisk(&cfg
, "./testconfig"));
849 git_config_free(cfg
);
852 void test_config_read__unreadable_file_ignored(void)
854 git_buf buf
= GIT_BUF_INIT
;
858 cl_set_cleanup(&clean_test_config
, NULL
);
859 cl_git_mkfile("./testconfig", "[some] var = value\n[some \"OtheR\"] var = value");
860 cl_git_pass(p_chmod("./testconfig", 0));
862 ret
= git_config_open_ondisk(&cfg
, "./test/config");
863 cl_assert(ret
== 0 || ret
== GIT_ENOTFOUND
);
865 git_config_free(cfg
);
866 git_buf_dispose(&buf
);
869 void test_config_read__single_line(void)
871 git_buf buf
= GIT_BUF_INIT
;
874 cl_set_cleanup(&clean_test_config
, NULL
);
875 cl_git_mkfile("./testconfig", "[some] var = value\n[some \"OtheR\"] var = value");
876 cl_git_pass(git_config_open_ondisk(&cfg
, "./testconfig"));
877 cl_git_pass(git_config_get_string_buf(&buf
, cfg
, "some.var"));
878 cl_assert_equal_s(buf
.ptr
, "value");
881 cl_git_pass(git_config_get_string_buf(&buf
, cfg
, "some.OtheR.var"));
882 cl_assert_equal_s(buf
.ptr
, "value");
884 git_config_free(cfg
);
885 cl_git_mkfile("./testconfig", "[some] var = value\n[some \"OtheR\"]var = value");
886 cl_git_pass(git_config_open_ondisk(&cfg
, "./testconfig"));
888 cl_git_pass(git_config_get_string_buf(&buf
, cfg
, "some.var"));
889 cl_assert_equal_s(buf
.ptr
, "value");
892 cl_git_pass(git_config_get_string_buf(&buf
, cfg
, "some.OtheR.var"));
893 cl_assert_equal_s(buf
.ptr
, "value");
895 git_config_free(cfg
);
896 git_buf_dispose(&buf
);
899 static int read_nosection_cb(const git_config_entry
*entry
, void *payload
) {
900 int *seen
= (int*)payload
;
901 if (strcmp(entry
->name
, "key") == 0) {
907 /* This would ideally issue a warning, if we had a way to do so. */
908 void test_config_read__nosection(void)
911 git_buf buf
= GIT_BUF_INIT
;
914 cl_git_pass(git_config_open_ondisk(&cfg
, cl_fixture("config/config-nosection")));
917 * Given a key with no section, we do not allow reading it,
918 * but we do include it in an iteration over the config
919 * store. This appears to match how git's own APIs (and
920 * git-config(1)) behave.
923 cl_git_fail_with(git_config_get_string_buf(&buf
, cfg
, "key"), GIT_EINVALIDSPEC
);
925 cl_git_pass(git_config_foreach(cfg
, read_nosection_cb
, &seen
));
926 cl_assert_equal_i(seen
, 1);
928 git_buf_dispose(&buf
);
929 git_config_free(cfg
);
938 static git_configmap _test_map1
[] = {
939 {GIT_CONFIGMAP_STRING
, "always", MAP_ALWAYS
},
940 {GIT_CONFIGMAP_FALSE
, NULL
, MAP_FALSE
},
941 {GIT_CONFIGMAP_TRUE
, NULL
, MAP_TRUE
},
944 static git_configmap _test_map2
[] = {
945 {GIT_CONFIGMAP_INT32
, NULL
, 0},
948 void test_config_read__get_mapped(void)
954 cl_set_cleanup(&clean_test_config
, NULL
);
955 cl_git_mkfile("./testconfig", "[header]\n"
965 cl_git_pass(git_config_open_ondisk(&cfg
, "./testconfig"));
967 // check parsing bool and string
968 cl_git_pass(git_config_get_mapped(&val
, cfg
, "header.key1", _test_map1
, ARRAY_SIZE(_test_map1
)));
969 cl_assert_equal_i(val
, MAP_TRUE
);
970 cl_git_pass(git_config_get_mapped(&val
, cfg
, "header.key2", _test_map1
, ARRAY_SIZE(_test_map1
)));
971 cl_assert_equal_i(val
, MAP_TRUE
);
972 cl_git_pass(git_config_get_mapped(&val
, cfg
, "header.key3", _test_map1
, ARRAY_SIZE(_test_map1
)));
973 cl_assert_equal_i(val
, MAP_TRUE
);
974 cl_git_pass(git_config_get_mapped(&val
, cfg
, "header.key8", _test_map1
, ARRAY_SIZE(_test_map1
)));
975 cl_assert_equal_i(val
, MAP_TRUE
);
977 cl_git_pass(git_config_get_mapped(&val
, cfg
, "header.key4", _test_map1
, ARRAY_SIZE(_test_map1
)));
978 cl_assert_equal_i(val
, MAP_ALWAYS
);
980 cl_git_pass(git_config_get_mapped(&val
, cfg
, "header.key5", _test_map1
, ARRAY_SIZE(_test_map1
)));
981 cl_assert_equal_i(val
, MAP_FALSE
);
982 cl_git_pass(git_config_get_mapped(&val
, cfg
, "header.key6", _test_map1
, ARRAY_SIZE(_test_map1
)));
983 cl_assert_equal_i(val
, MAP_FALSE
);
984 cl_git_pass(git_config_get_mapped(&val
, cfg
, "header.key9", _test_map1
, ARRAY_SIZE(_test_map1
)));
985 cl_assert_equal_i(val
, MAP_FALSE
);
987 cl_git_fail(git_config_get_mapped(&val
, cfg
, "header.key7", _test_map1
, ARRAY_SIZE(_test_map1
)));
989 // check parsing int values
990 cl_git_pass(git_config_get_mapped(&val
, cfg
, "header.key1", _test_map2
, ARRAY_SIZE(_test_map2
)));
991 cl_git_pass(git_config_get_int32(&known_good
, cfg
, "header.key1"));
992 cl_assert_equal_i(val
, known_good
);
993 cl_git_pass(git_config_get_mapped(&val
, cfg
, "header.key6", _test_map2
, ARRAY_SIZE(_test_map2
)));
994 cl_git_pass(git_config_get_int32(&known_good
, cfg
, "header.key6"));
995 cl_assert_equal_i(val
, known_good
);
997 cl_git_fail(git_config_get_mapped(&val
, cfg
, "header.key2", _test_map2
, ARRAY_SIZE(_test_map2
)));
998 cl_git_fail(git_config_get_mapped(&val
, cfg
, "header.key3", _test_map2
, ARRAY_SIZE(_test_map2
)));
999 cl_git_fail(git_config_get_mapped(&val
, cfg
, "header.key4", _test_map2
, ARRAY_SIZE(_test_map2
)));
1000 cl_git_fail(git_config_get_mapped(&val
, cfg
, "header.key5", _test_map2
, ARRAY_SIZE(_test_map2
)));
1001 cl_git_fail(git_config_get_mapped(&val
, cfg
, "header.key7", _test_map2
, ARRAY_SIZE(_test_map2
)));
1002 cl_git_fail(git_config_get_mapped(&val
, cfg
, "header.key8", _test_map2
, ARRAY_SIZE(_test_map2
)));
1003 cl_git_fail(git_config_get_mapped(&val
, cfg
, "header.key9", _test_map2
, ARRAY_SIZE(_test_map2
)));
1005 git_config_free(cfg
);