read.c 14.5 KB
Newer Older
1
#include "clar_libgit2.h"
2 3 4 5 6 7 8 9

void test_config_read__simple_read(void)
{
	git_config *cfg;
	int32_t i;

	cl_git_pass(git_config_open_ondisk(&cfg, cl_fixture("config/config0")));

10
	cl_git_pass(git_config_get_int32(&i, cfg, "core.repositoryformatversion"));
11
	cl_assert(i == 0);
12
	cl_git_pass(git_config_get_bool(&i, cfg, "core.filemode"));
13
	cl_assert(i == 1);
14
	cl_git_pass(git_config_get_bool(&i, cfg, "core.bare"));
15
	cl_assert(i == 0);
16
	cl_git_pass(git_config_get_bool(&i, cfg, "core.logallrefupdates"));
17 18 19 20 21 22 23 24 25 26 27 28 29
	cl_assert(i == 1);

	git_config_free(cfg);
}

void test_config_read__case_sensitive(void)
{
	git_config *cfg;
	int i;
	const char *str;

	cl_git_pass(git_config_open_ondisk(&cfg, cl_fixture("config/config1")));

30
	cl_git_pass(git_config_get_string(&str, cfg, "this.that.other"));
Vicent Martí committed
31
	cl_assert_equal_s(str, "true");
32
	cl_git_pass(git_config_get_string(&str, cfg, "this.That.other"));
Vicent Martí committed
33
	cl_assert_equal_s(str, "yes");
34

35
	cl_git_pass(git_config_get_bool(&i, cfg, "this.that.other"));
36
	cl_assert(i == 1);
37
	cl_git_pass(git_config_get_bool(&i, cfg, "this.That.other"));
38 39 40
	cl_assert(i == 1);

	/* This one doesn't exist */
41
	cl_must_fail(git_config_get_bool(&i, cfg, "this.thaT.other"));
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56

	git_config_free(cfg);
}

/*
 * If \ is the last non-space character on the line, we read the next
 * one, separating each line with SP.
 */
void test_config_read__multiline_value(void)
{
	git_config *cfg;
	const char *str;

	cl_git_pass(git_config_open_ondisk(&cfg, cl_fixture("config/config2")));

57
	cl_git_pass(git_config_get_string(&str, cfg, "this.That.and"));
Vicent Martí committed
58
	cl_assert_equal_s(str, "one one one two two three three");
59 60 61 62 63 64 65 66 67 68 69 70 71 72

	git_config_free(cfg);
}

/*
 * This kind of subsection declaration is case-insensitive
 */
void test_config_read__subsection_header(void)
{
	git_config *cfg;
	const char *str;

	cl_git_pass(git_config_open_ondisk(&cfg, cl_fixture("config/config3")));

73
	cl_git_pass(git_config_get_string(&str, cfg, "section.subsection.var"));
Vicent Martí committed
74
	cl_assert_equal_s(str, "hello");
75 76

	/* The subsection is transformed to lower-case */
77
	cl_must_fail(git_config_get_string(&str, cfg, "section.subSectIon.var"));
78 79 80 81 82 83 84 85 86 87 88 89

	git_config_free(cfg);
}

void test_config_read__lone_variable(void)
{
	git_config *cfg;
	const char *str;
	int i;

	cl_git_pass(git_config_open_ondisk(&cfg, cl_fixture("config/config4")));

90 91
	cl_git_fail(git_config_get_int32(&i, cfg, "some.section.variable"));

92
	cl_git_pass(git_config_get_string(&str, cfg, "some.section.variable"));
93
	cl_assert_equal_s(str, "");
94

95
	cl_git_pass(git_config_get_bool(&i, cfg, "some.section.variable"));
96 97
	cl_assert(i == 1);

98 99 100 101 102 103
	cl_git_pass(git_config_get_string(&str, cfg, "some.section.variableeq"));
	cl_assert_equal_s(str, "");

	cl_git_pass(git_config_get_bool(&i, cfg, "some.section.variableeq"));
	cl_assert(i == 0);

104 105 106 107 108 109 110 111 112 113
	git_config_free(cfg);
}

void test_config_read__number_suffixes(void)
{
	git_config *cfg;
	int64_t i;

	cl_git_pass(git_config_open_ondisk(&cfg, cl_fixture("config/config5")));

114
	cl_git_pass(git_config_get_int64(&i, cfg, "number.simple"));
115 116
	cl_assert(i == 1);

117
	cl_git_pass(git_config_get_int64(&i, cfg, "number.k"));
118 119
	cl_assert(i == 1 * 1024);

120
	cl_git_pass(git_config_get_int64(&i, cfg, "number.kk"));
121 122
	cl_assert(i == 1 * 1024);

123
	cl_git_pass(git_config_get_int64(&i, cfg, "number.m"));
124 125
	cl_assert(i == 1 * 1024 * 1024);

126
	cl_git_pass(git_config_get_int64(&i, cfg, "number.mm"));
127 128
	cl_assert(i == 1 * 1024 * 1024);

129
	cl_git_pass(git_config_get_int64(&i, cfg, "number.g"));
130 131
	cl_assert(i == 1 * 1024 * 1024 * 1024);

132
	cl_git_pass(git_config_get_int64(&i, cfg, "number.gg"));
133 134 135 136 137 138 139 140 141 142 143 144
	cl_assert(i == 1 * 1024 * 1024 * 1024);

	git_config_free(cfg);
}

void test_config_read__blank_lines(void)
{
	git_config *cfg;
	int i;

	cl_git_pass(git_config_open_ondisk(&cfg, cl_fixture("config/config6")));

145
	cl_git_pass(git_config_get_bool(&i, cfg, "valid.subsection.something"));
146 147
	cl_assert(i == 1);

148
	cl_git_pass(git_config_get_bool(&i, cfg, "something.else.something"));
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
	cl_assert(i == 0);

	git_config_free(cfg);
}

void test_config_read__invalid_ext_headers(void)
{
	git_config *cfg;
	cl_must_fail(git_config_open_ondisk(&cfg, cl_fixture("config/config7")));
}

void test_config_read__empty_files(void)
{
	git_config *cfg;
	cl_git_pass(git_config_open_ondisk(&cfg, cl_fixture("config/config8")));
	git_config_free(cfg);
}

167 168 169 170 171 172 173
void test_config_read__symbol_headers(void)
{
	git_config *cfg;
	cl_git_pass(git_config_open_ondisk(&cfg, cl_fixture("config/config20")));
	git_config_free(cfg);
}

174 175 176 177 178 179 180 181 182 183 184 185 186 187
void test_config_read__header_in_last_line(void)
{
	git_config *cfg;

	cl_git_pass(git_config_open_ondisk(&cfg, cl_fixture("config/config10")));
	git_config_free(cfg);
}

void test_config_read__prefixes(void)
{
	git_config *cfg;
	const char *str;

	cl_git_pass(git_config_open_ondisk(&cfg, cl_fixture("config/config9")));
188
	cl_git_pass(git_config_get_string(&str, cfg, "remote.ab.url"));
Vicent Martí committed
189
	cl_assert_equal_s(str, "http://example.com/git/ab");
190

191
	cl_git_pass(git_config_get_string(&str, cfg, "remote.abba.url"));
Vicent Martí committed
192
	cl_assert_equal_s(str, "http://example.com/git/abba");
193 194 195 196

	git_config_free(cfg);
}

197 198 199 200 201 202
void test_config_read__escaping_quotes(void)
{
	git_config *cfg;
	const char *str;

	cl_git_pass(git_config_open_ondisk(&cfg, cl_fixture("config/config13")));
203
	cl_git_pass(git_config_get_string(&str, cfg, "core.editor"));
204
	cl_assert_equal_s("\"C:/Program Files/Nonsense/bah.exe\" \"--some option\"", str);
205 206 207 208

	git_config_free(cfg);
}

209 210
static int count_cfg_entries_and_compare_levels(
	const git_config_entry *entry, void *payload)
211 212
{
	int *count = payload;
213 214 215 216 217 218

	if (!strcmp(entry->value, "7") || !strcmp(entry->value, "17"))
		cl_assert(entry->level == GIT_CONFIG_LEVEL_GLOBAL);
	else
		cl_assert(entry->level == GIT_CONFIG_LEVEL_SYSTEM);

219 220 221 222
	(*count)++;
	return 0;
}

223
static int cfg_callback_countdown(const git_config_entry *entry, void *payload)
224 225
{
	int *count = payload;
226
	GIT_UNUSED(entry);
227 228 229 230 231 232 233 234 235 236 237
	(*count)--;
	if (*count == 0)
		return -100;
	return 0;
}

void test_config_read__foreach(void)
{
	git_config *cfg;
	int count, ret;

238 239 240 241 242
	cl_git_pass(git_config_new(&cfg));
	cl_git_pass(git_config_add_file_ondisk(cfg, cl_fixture("config/config9"),
		GIT_CONFIG_LEVEL_SYSTEM, 0));
	cl_git_pass(git_config_add_file_ondisk(cfg, cl_fixture("config/config15"),
		GIT_CONFIG_LEVEL_GLOBAL, 0));
243 244

	count = 0;
245 246
	cl_git_pass(git_config_foreach(cfg, count_cfg_entries_and_compare_levels, &count));
	cl_assert_equal_i(7, count);
247 248 249

	count = 3;
	cl_git_fail(ret = git_config_foreach(cfg, cfg_callback_countdown, &count));
250
	cl_assert_equal_i(GIT_EUSER, ret);
251 252 253 254

	git_config_free(cfg);
}

255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274
void test_config_read__iterator(void)
{
	git_config *cfg;
	git_config_iterator *iter;
	git_config_entry *entry;
	int count, ret;

	cl_git_pass(git_config_new(&cfg));
	cl_git_pass(git_config_add_file_ondisk(cfg, cl_fixture("config/config9"),
		GIT_CONFIG_LEVEL_SYSTEM, 0));
	cl_git_pass(git_config_add_file_ondisk(cfg, cl_fixture("config/config15"),
		GIT_CONFIG_LEVEL_GLOBAL, 0));

	count = 0;
	cl_git_pass(git_config_iterator_new(&iter, cfg));

	while ((ret = git_config_next(&entry, iter)) == 0) {
		count++;
	}

275
	git_config_iterator_free(iter);
276 277 278 279 280 281 282 283 284 285
	cl_assert_equal_i(GIT_ITEROVER, ret);
	cl_assert_equal_i(7, count);

	count = 3;
	cl_git_pass(git_config_iterator_new(&iter, cfg));

	git_config_iterator_free(iter);
	git_config_free(cfg);
}

286 287 288 289 290 291 292 293
static int count_cfg_entries(const git_config_entry *entry, void *payload)
{
	int *count = payload;
	GIT_UNUSED(entry);
	(*count)++;
	return 0;
}

294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328
void test_config_read__foreach_match(void)
{
	git_config *cfg;
	int count;

	cl_git_pass(git_config_open_ondisk(&cfg, cl_fixture("config/config9")));

	count = 0;
	cl_git_pass(
		git_config_foreach_match(cfg, "core.*", count_cfg_entries, &count));
	cl_assert_equal_i(3, count);

	count = 0;
	cl_git_pass(
		git_config_foreach_match(cfg, "remote\\.ab.*", count_cfg_entries, &count));
	cl_assert_equal_i(2, count);

	count = 0;
	cl_git_pass(
		git_config_foreach_match(cfg, ".*url$", count_cfg_entries, &count));
	cl_assert_equal_i(2, count);

	count = 0;
	cl_git_pass(
		git_config_foreach_match(cfg, ".*dummy.*", count_cfg_entries, &count));
	cl_assert_equal_i(2, count);

	count = 0;
	cl_git_pass(
		git_config_foreach_match(cfg, ".*nomatch.*", count_cfg_entries, &count));
	cl_assert_equal_i(0, count);

	git_config_free(cfg);
}

329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360
static void check_glob_iter(git_config *cfg, const char *regexp, int expected)
{
	git_config_iterator *iter;
	git_config_entry *entry;
	int count, error;

	cl_git_pass(git_config_iterator_glob_new(&iter, cfg, regexp));

	count = 0;
	while ((error = git_config_next(&entry, iter)) == 0)
		count++;

	cl_assert_equal_i(GIT_ITEROVER, error);
	cl_assert_equal_i(expected, count);
	git_config_iterator_free(iter);
}

void test_config_read__iterator_glob(void)
{
	git_config *cfg;

	cl_git_pass(git_config_open_ondisk(&cfg, cl_fixture("config/config9")));

	check_glob_iter(cfg, "core.*", 3);
	check_glob_iter(cfg, "remote\\.ab.*", 2);
	check_glob_iter(cfg, ".*url$", 2);
	check_glob_iter(cfg, ".*dummy.*", 2);
	check_glob_iter(cfg, ".*nomatch.*", 0);

	git_config_free(cfg);
}

361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376
void test_config_read__whitespace_not_required_around_assignment(void)
{
	git_config *cfg;
	const char *str;

	cl_git_pass(git_config_open_ondisk(&cfg, cl_fixture("config/config14")));

	cl_git_pass(git_config_get_string(&str, cfg, "a.b"));
	cl_assert_equal_s(str, "c");

	cl_git_pass(git_config_get_string(&str, cfg, "d.e"));
	cl_assert_equal_s(str, "f");

	git_config_free(cfg);
}

377 378 379 380
void test_config_read__read_git_config_entry(void)
{
	git_config *cfg;
	const git_config_entry *entry;
381

382 383 384 385
	cl_git_pass(git_config_new(&cfg));
	cl_git_pass(git_config_add_file_ondisk(cfg, cl_fixture("config/config9"),
		GIT_CONFIG_LEVEL_SYSTEM, 0));

386
	cl_git_pass(git_config_get_entry(&entry, cfg, "core.dummy2"));
387 388 389 390 391 392 393 394 395 396 397 398 399 400 401
	cl_assert_equal_s("core.dummy2", entry->name);
	cl_assert_equal_s("42", entry->value);
	cl_assert_equal_i(GIT_CONFIG_LEVEL_SYSTEM, entry->level);

	git_config_free(cfg);
}

/*
 * At the beginning of the test:
 *  - config9 has: core.dummy2=42
 *  - config15 has: core.dummy2=7
 *  - config16 has: core.dummy2=28
 */
void test_config_read__local_config_overrides_global_config_overrides_system_config(void)
{
402
	git_config *cfg;
403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425
	int32_t i;

	cl_git_pass(git_config_new(&cfg));
	cl_git_pass(git_config_add_file_ondisk(cfg, cl_fixture("config/config9"),
		GIT_CONFIG_LEVEL_SYSTEM, 0));
	cl_git_pass(git_config_add_file_ondisk(cfg, cl_fixture("config/config15"),
		GIT_CONFIG_LEVEL_GLOBAL, 0));
	cl_git_pass(git_config_add_file_ondisk(cfg, cl_fixture("config/config16"),
		GIT_CONFIG_LEVEL_LOCAL, 0));

	cl_git_pass(git_config_get_int32(&i, cfg, "core.dummy2"));
	cl_assert_equal_i(28, i);

	git_config_free(cfg);

	cl_git_pass(git_config_new(&cfg));
	cl_git_pass(git_config_add_file_ondisk(cfg, cl_fixture("config/config9"),
		GIT_CONFIG_LEVEL_SYSTEM, 0));
	cl_git_pass(git_config_add_file_ondisk(cfg, cl_fixture("config/config15"),
		GIT_CONFIG_LEVEL_GLOBAL, 0));

	cl_git_pass(git_config_get_int32(&i, cfg, "core.dummy2"));
	cl_assert_equal_i(7, i);
426 427

	git_config_free(cfg);
428
}
429

430 431 432 433 434 435 436 437 438 439 440 441 442
/*
 * At the beginning of the test:
 *  - config9 has: core.global does not exist
 *  - config15 has: core.global=17
 *  - config16 has: core.global=29
 *
 * And also:
 *  - config9 has: core.system does not exist
 *  - config15 has: core.system does not exist
 *  - config16 has: core.system=11
 */
void test_config_read__fallback_from_local_to_global_and_from_global_to_system(void)
{
443
	git_config *cfg;
444
	int32_t i;
445

446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500
	cl_git_pass(git_config_new(&cfg));
	cl_git_pass(git_config_add_file_ondisk(cfg, cl_fixture("config/config9"),
		GIT_CONFIG_LEVEL_SYSTEM, 0));
	cl_git_pass(git_config_add_file_ondisk(cfg, cl_fixture("config/config15"),
		GIT_CONFIG_LEVEL_GLOBAL, 0));
	cl_git_pass(git_config_add_file_ondisk(cfg, cl_fixture("config/config16"),
		GIT_CONFIG_LEVEL_LOCAL, 0));

	cl_git_pass(git_config_get_int32(&i, cfg, "core.global"));
	cl_assert_equal_i(17, i);
	cl_git_pass(git_config_get_int32(&i, cfg, "core.system"));
	cl_assert_equal_i(11, i);

	git_config_free(cfg);
}

/*
 * At the beginning of the test, config18 has:
 *	int32global = 28
 *	int64global = 9223372036854775803
 *	boolglobal = true
 *	stringglobal = I'm a global config value!
 *
 * And config19 has:
 *	int32global = -1
 *	int64global = -2
 *	boolglobal = false
 *	stringglobal = don't find me!
 *
 */
void test_config_read__simple_read_from_specific_level(void)
{
	git_config *cfg, *cfg_specific;
	int i;
	int64_t l, expected = +9223372036854775803;
	const char *s;

	cl_git_pass(git_config_new(&cfg));
	cl_git_pass(git_config_add_file_ondisk(cfg, cl_fixture("config/config18"),
		GIT_CONFIG_LEVEL_GLOBAL, 0));
	cl_git_pass(git_config_add_file_ondisk(cfg, cl_fixture("config/config19"),
		GIT_CONFIG_LEVEL_SYSTEM, 0));

	cl_git_pass(git_config_open_level(&cfg_specific, cfg, GIT_CONFIG_LEVEL_GLOBAL));

	cl_git_pass(git_config_get_int32(&i, cfg_specific, "core.int32global"));
	cl_assert_equal_i(28, i);
	cl_git_pass(git_config_get_int64(&l, cfg_specific, "core.int64global"));
	cl_assert(l == expected);
	cl_git_pass(git_config_get_bool(&i, cfg_specific, "core.boolglobal"));
	cl_assert_equal_b(true, i);
	cl_git_pass(git_config_get_string(&s, cfg_specific, "core.stringglobal"));
	cl_assert_equal_s("I'm a global config value!", s);

	git_config_free(cfg_specific);
501
	git_config_free(cfg);
502
}
503

504
static void clean_test_config(void *unused)
Vicent Marti committed
505 506
{
	GIT_UNUSED(unused);
507
	cl_fixture_cleanup("./testconfig");
Vicent Marti committed
508 509
}

510 511 512 513 514
void test_config_read__can_load_and_parse_an_empty_config_file(void)
{
	git_config *cfg;
	int i;

515 516 517
	cl_set_cleanup(&clean_test_config, NULL);
	cl_git_mkfile("./testconfig", "");
	cl_git_pass(git_config_open_ondisk(&cfg, "./testconfig"));
518 519 520 521
	cl_assert_equal_i(GIT_ENOTFOUND, git_config_get_int32(&i, cfg, "nope.neither"));

	git_config_free(cfg);
}
522 523 524 525 526 527 528 529 530 531 532

void test_config_read__corrupt_header(void)
{
	git_config *cfg;

	cl_set_cleanup(&clean_test_config, NULL);
	cl_git_mkfile("./testconfig", "[sneaky ] \"quoted closing quote mark\\\"");
	cl_git_fail(git_config_open_ondisk(&cfg, "./testconfig"));

	git_config_free(cfg);
}
533

534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555
void test_config_read__corrupt_header2(void)
{
	git_config *cfg;

	cl_set_cleanup(&clean_test_config, NULL);
	cl_git_mkfile("./testconfig", "[unclosed \"bracket\"\n    lib = git2\n");
	cl_git_fail(git_config_open_ondisk(&cfg, "./testconfig"));

	git_config_free(cfg);
}

void test_config_read__corrupt_header3(void)
{
	git_config *cfg;

	cl_set_cleanup(&clean_test_config, NULL);
	cl_git_mkfile("./testconfig", "[unclosed \"slash\\\"]\n    lib = git2\n");
	cl_git_fail(git_config_open_ondisk(&cfg, "./testconfig"));

	git_config_free(cfg);
}

556 557 558 559 560 561 562 563 564 565 566 567 568 569
void test_config_read__override_variable(void)
{
	git_config *cfg;
	const char *str;

	cl_set_cleanup(&clean_test_config, NULL);
	cl_git_mkfile("./testconfig", "[some] var = one\nvar = two");
	cl_git_pass(git_config_open_ondisk(&cfg, "./testconfig"));

	cl_git_pass(git_config_get_string(&str, cfg, "some.var"));
	cl_assert_equal_s(str, "two");

	git_config_free(cfg);
}