]>
Commit | Line | Data |
---|---|---|
3fd1520c | 1 | #include "clar_libgit2.h" |
9a97f49e | 2 | #include "buffer.h" |
6dc55872 | 3 | #include "fileops.h" |
9462c471 VM |
4 | |
5 | void test_config_write__initialize(void) | |
6 | { | |
7 | cl_fixture_sandbox("config/config9"); | |
a1abe66a | 8 | cl_fixture_sandbox("config/config15"); |
f8ede948 | 9 | cl_fixture_sandbox("config/config17"); |
9462c471 VM |
10 | } |
11 | ||
12 | void test_config_write__cleanup(void) | |
13 | { | |
14 | cl_fixture_cleanup("config9"); | |
a1abe66a | 15 | cl_fixture_cleanup("config15"); |
f8ede948 | 16 | cl_fixture_cleanup("config17"); |
9462c471 VM |
17 | } |
18 | ||
19 | void test_config_write__replace_value(void) | |
20 | { | |
21 | git_config *cfg; | |
22 | int i; | |
23 | int64_t l, expected = +9223372036854775803; | |
24 | ||
25 | /* By freeing the config, we make sure we flush the values */ | |
26 | cl_git_pass(git_config_open_ondisk(&cfg, "config9")); | |
27 | cl_git_pass(git_config_set_int32(cfg, "core.dummy", 5)); | |
28 | git_config_free(cfg); | |
29 | ||
30 | cl_git_pass(git_config_open_ondisk(&cfg, "config9")); | |
255c38c5 | 31 | cl_git_pass(git_config_get_int32(&i, cfg, "core.dummy")); |
9462c471 VM |
32 | cl_assert(i == 5); |
33 | git_config_free(cfg); | |
34 | ||
35 | cl_git_pass(git_config_open_ondisk(&cfg, "config9")); | |
36 | cl_git_pass(git_config_set_int32(cfg, "core.dummy", 1)); | |
37 | git_config_free(cfg); | |
38 | ||
39 | cl_git_pass(git_config_open_ondisk(&cfg, "config9")); | |
40 | cl_git_pass(git_config_set_int64(cfg, "core.verylong", expected)); | |
41 | git_config_free(cfg); | |
42 | ||
43 | cl_git_pass(git_config_open_ondisk(&cfg, "config9")); | |
255c38c5 | 44 | cl_git_pass(git_config_get_int64(&l, cfg, "core.verylong")); |
9462c471 VM |
45 | cl_assert(l == expected); |
46 | git_config_free(cfg); | |
47 | ||
48 | cl_git_pass(git_config_open_ondisk(&cfg, "config9")); | |
255c38c5 | 49 | cl_must_fail(git_config_get_int32(&i, cfg, "core.verylong")); |
9462c471 VM |
50 | git_config_free(cfg); |
51 | ||
52 | cl_git_pass(git_config_open_ondisk(&cfg, "config9")); | |
53 | cl_git_pass(git_config_set_int64(cfg, "core.verylong", 1)); | |
54 | git_config_free(cfg); | |
55 | } | |
56 | ||
57 | void test_config_write__delete_value(void) | |
58 | { | |
59 | git_config *cfg; | |
60 | int32_t i; | |
61 | ||
62 | cl_git_pass(git_config_open_ondisk(&cfg, "config9")); | |
63 | cl_git_pass(git_config_set_int32(cfg, "core.dummy", 5)); | |
64 | git_config_free(cfg); | |
65 | ||
66 | cl_git_pass(git_config_open_ondisk(&cfg, "config9")); | |
54b2a37a | 67 | cl_git_pass(git_config_delete_entry(cfg, "core.dummy")); |
9462c471 VM |
68 | git_config_free(cfg); |
69 | ||
70 | cl_git_pass(git_config_open_ondisk(&cfg, "config9")); | |
904b67e6 | 71 | cl_assert(git_config_get_int32(&i, cfg, "core.dummy") == GIT_ENOTFOUND); |
9462c471 VM |
72 | cl_git_pass(git_config_set_int32(cfg, "core.dummy", 1)); |
73 | git_config_free(cfg); | |
74 | } | |
75 | ||
a1abe66a | 76 | /* |
77 | * At the beginning of the test: | |
78 | * - config9 has: core.dummy2=42 | |
79 | * - config15 has: core.dummy2=7 | |
80 | */ | |
81 | void test_config_write__delete_value_at_specific_level(void) | |
82 | { | |
83 | git_config *cfg, *cfg_specific; | |
84 | int32_t i; | |
85 | ||
86 | cl_git_pass(git_config_open_ondisk(&cfg, "config15")); | |
87 | cl_git_pass(git_config_get_int32(&i, cfg, "core.dummy2")); | |
88 | cl_assert(i == 7); | |
89 | git_config_free(cfg); | |
90 | ||
91 | cl_git_pass(git_config_new(&cfg)); | |
92 | cl_git_pass(git_config_add_file_ondisk(cfg, "config9", | |
93 | GIT_CONFIG_LEVEL_LOCAL, 0)); | |
94 | cl_git_pass(git_config_add_file_ondisk(cfg, "config15", | |
95 | GIT_CONFIG_LEVEL_GLOBAL, 0)); | |
96 | ||
97 | cl_git_pass(git_config_open_level(&cfg_specific, cfg, GIT_CONFIG_LEVEL_GLOBAL)); | |
98 | ||
54b2a37a | 99 | cl_git_pass(git_config_delete_entry(cfg_specific, "core.dummy2")); |
a1abe66a | 100 | git_config_free(cfg); |
101 | ||
102 | cl_git_pass(git_config_open_ondisk(&cfg, "config15")); | |
103 | cl_assert(git_config_get_int32(&i, cfg, "core.dummy2") == GIT_ENOTFOUND); | |
104 | cl_git_pass(git_config_set_int32(cfg, "core.dummy2", 7)); | |
105 | ||
106 | git_config_free(cfg_specific); | |
107 | git_config_free(cfg); | |
108 | } | |
109 | ||
a060cccc RRC |
110 | /* |
111 | * This test exposes a bug where duplicate empty section headers could prevent | |
112 | * deletion of config entries. | |
113 | */ | |
114 | void test_config_write__delete_value_with_duplicate_header(void) | |
115 | { | |
f56a417d | 116 | const char *file_name = "config-duplicate-header"; |
a060cccc RRC |
117 | const char *entry_name = "remote.origin.url"; |
118 | git_config *cfg; | |
119 | git_config_entry *entry; | |
120 | ||
f56a417d RRC |
121 | /* This config can occur after removing and re-adding the origin remote */ |
122 | const char *file_content = | |
123 | "[remote \"origin\"]\n" \ | |
124 | "[branch \"master\"]\n" \ | |
125 | " remote = \"origin\"\n" \ | |
126 | "[remote \"origin\"]\n" \ | |
127 | " url = \"foo\"\n"; | |
128 | ||
129 | /* Write the test config and make sure the expected entry exists */ | |
130 | cl_git_mkfile(file_name, file_content); | |
a060cccc RRC |
131 | cl_git_pass(git_config_open_ondisk(&cfg, file_name)); |
132 | cl_git_pass(git_config_get_entry(&entry, cfg, entry_name)); | |
133 | ||
134 | /* Delete that entry */ | |
135 | cl_git_pass(git_config_delete_entry(cfg, entry_name)); | |
136 | ||
137 | /* Reopen the file and make sure the entry no longer exists */ | |
138 | git_config_entry_free(entry); | |
139 | git_config_free(cfg); | |
140 | cl_git_pass(git_config_open_ondisk(&cfg, file_name)); | |
141 | cl_git_fail(git_config_get_entry(&entry, cfg, entry_name)); | |
142 | ||
143 | /* Cleanup */ | |
144 | git_config_entry_free(entry); | |
145 | git_config_free(cfg); | |
146 | } | |
147 | ||
5a70df94 RRC |
148 | /* |
149 | * This test exposes a bug where duplicate section headers could cause | |
150 | * config_write to add a new entry when one already exists. | |
151 | */ | |
152 | void test_config_write__add_value_with_duplicate_header(void) | |
153 | { | |
154 | const char *file_name = "config-duplicate-insert"; | |
155 | const char *entry_name = "foo.c"; | |
156 | const char *old_val = "old"; | |
157 | const char *new_val = "new"; | |
158 | const char *str; | |
159 | git_config *cfg, *snapshot; | |
160 | ||
161 | /* c = old should be replaced by c = new. | |
162 | * The bug causes c = new to be inserted under the first 'foo' header. | |
163 | */ | |
164 | const char *file_content = | |
165 | "[foo]\n" \ | |
166 | " a = b\n" \ | |
167 | "[other]\n" \ | |
168 | " a = b\n" \ | |
169 | "[foo]\n" \ | |
170 | " c = old\n"; | |
171 | ||
172 | /* Write the test config */ | |
173 | cl_git_mkfile(file_name, file_content); | |
174 | cl_git_pass(git_config_open_ondisk(&cfg, file_name)); | |
175 | ||
176 | /* make sure the expected entry (foo.c) exists */ | |
177 | cl_git_pass(git_config_snapshot(&snapshot, cfg)); | |
178 | cl_git_pass(git_config_get_string(&str, snapshot, entry_name)); | |
179 | cl_assert_equal_s(old_val, str); | |
180 | git_config_free(snapshot); | |
181 | ||
182 | /* Try setting foo.c to something else */ | |
183 | cl_git_pass(git_config_set_string(cfg, entry_name, new_val)); | |
184 | git_config_free(cfg); | |
185 | ||
186 | /* Reopen the file and make sure the new value was set */ | |
187 | cl_git_pass(git_config_open_ondisk(&cfg, file_name)); | |
188 | cl_git_pass(git_config_snapshot(&snapshot, cfg)); | |
189 | cl_git_pass(git_config_get_string(&str, snapshot, entry_name)); | |
190 | cl_assert_equal_s(new_val, str); | |
191 | ||
192 | /* Cleanup */ | |
193 | git_config_free(snapshot); | |
194 | git_config_free(cfg); | |
195 | } | |
196 | ||
f79c7322 ET |
197 | void test_config_write__overwrite_value_with_duplicate_header(void) |
198 | { | |
199 | const char *file_name = "config-duplicate-header"; | |
200 | const char *entry_name = "remote.origin.url"; | |
201 | git_config *cfg; | |
202 | git_config_entry *entry; | |
203 | ||
204 | /* This config can occur after removing and re-adding the origin remote */ | |
205 | const char *file_content = | |
206 | "[remote \"origin\"]\n" \ | |
207 | "[branch \"master\"]\n" \ | |
208 | " remote = \"origin\"\n" \ | |
209 | "[remote \"origin\"]\n" \ | |
210 | " url = \"foo\"\n"; | |
211 | ||
212 | /* Write the test config and make sure the expected entry exists */ | |
213 | cl_git_mkfile(file_name, file_content); | |
214 | cl_git_pass(git_config_open_ondisk(&cfg, file_name)); | |
215 | cl_git_pass(git_config_get_entry(&entry, cfg, entry_name)); | |
216 | ||
217 | /* Update that entry */ | |
218 | cl_git_pass(git_config_set_string(cfg, entry_name, "newurl")); | |
219 | ||
220 | /* Reopen the file and make sure the entry was updated */ | |
221 | git_config_entry_free(entry); | |
222 | git_config_free(cfg); | |
223 | cl_git_pass(git_config_open_ondisk(&cfg, file_name)); | |
224 | cl_git_pass(git_config_get_entry(&entry, cfg, entry_name)); | |
225 | ||
226 | cl_assert_equal_s("newurl", entry->value); | |
227 | ||
228 | /* Cleanup */ | |
229 | git_config_entry_free(entry); | |
230 | git_config_free(cfg); | |
231 | } | |
232 | ||
bf99390e ET |
233 | void test_config_write__overwrite_multivar_within_duplicate_header(void) |
234 | { | |
235 | const char *file_name = "config-duplicate-header"; | |
236 | const char *entry_name = "remote.origin.url"; | |
237 | git_config *cfg; | |
238 | git_config_entry *entry; | |
239 | ||
240 | /* This config can occur after removing and re-adding the origin remote */ | |
241 | const char *file_content = | |
242 | "[remote \"origin\"]\n" \ | |
243 | " url = \"bar\"\n" \ | |
244 | "[branch \"master\"]\n" \ | |
245 | " remote = \"origin\"\n" \ | |
246 | "[remote \"origin\"]\n" \ | |
247 | " url = \"foo\"\n"; | |
248 | ||
249 | /* Write the test config and make sure the expected entry exists */ | |
250 | cl_git_mkfile(file_name, file_content); | |
251 | cl_git_pass(git_config_open_ondisk(&cfg, file_name)); | |
252 | cl_git_pass(git_config_get_entry(&entry, cfg, entry_name)); | |
253 | ||
254 | /* Update that entry */ | |
255 | cl_git_pass(git_config_set_multivar(cfg, entry_name, "", "newurl")); | |
256 | ||
257 | /* Reopen the file and make sure the entry was updated */ | |
258 | git_config_entry_free(entry); | |
259 | git_config_free(cfg); | |
260 | cl_git_pass(git_config_open_ondisk(&cfg, file_name)); | |
261 | cl_git_pass(git_config_get_entry(&entry, cfg, entry_name)); | |
262 | ||
263 | cl_assert_equal_s("newurl", entry->value); | |
264 | ||
265 | /* Cleanup */ | |
266 | git_config_entry_free(entry); | |
267 | git_config_free(cfg); | |
268 | } | |
269 | ||
54fef6eb CMN |
270 | void test_config_write__write_subsection(void) |
271 | { | |
272 | git_config *cfg; | |
9a97f49e | 273 | git_buf buf = GIT_BUF_INIT; |
54fef6eb CMN |
274 | |
275 | cl_git_pass(git_config_open_ondisk(&cfg, "config9")); | |
276 | cl_git_pass(git_config_set_string(cfg, "my.own.var", "works")); | |
277 | git_config_free(cfg); | |
278 | ||
279 | cl_git_pass(git_config_open_ondisk(&cfg, "config9")); | |
9a97f49e CMN |
280 | cl_git_pass(git_config_get_string_buf(&buf, cfg, "my.own.var")); |
281 | cl_assert_equal_s("works", git_buf_cstr(&buf)); | |
282 | ||
283 | git_buf_free(&buf); | |
54fef6eb CMN |
284 | git_config_free(cfg); |
285 | } | |
286 | ||
9462c471 VM |
287 | void test_config_write__delete_inexistent(void) |
288 | { | |
289 | git_config *cfg; | |
290 | ||
291 | cl_git_pass(git_config_open_ondisk(&cfg, "config9")); | |
54b2a37a | 292 | cl_assert(git_config_delete_entry(cfg, "core.imaginary") == GIT_ENOTFOUND); |
9462c471 VM |
293 | git_config_free(cfg); |
294 | } | |
750be86a AR |
295 | |
296 | void test_config_write__value_containing_quotes(void) | |
297 | { | |
298 | git_config *cfg; | |
9a97f49e | 299 | git_buf buf = GIT_BUF_INIT; |
750be86a AR |
300 | |
301 | cl_git_pass(git_config_open_ondisk(&cfg, "config9")); | |
302 | cl_git_pass(git_config_set_string(cfg, "core.somevar", "this \"has\" quotes")); | |
9a97f49e CMN |
303 | cl_git_pass(git_config_get_string_buf(&buf, cfg, "core.somevar")); |
304 | cl_assert_equal_s("this \"has\" quotes", git_buf_cstr(&buf)); | |
305 | git_buf_clear(&buf); | |
750be86a AR |
306 | git_config_free(cfg); |
307 | ||
308 | cl_git_pass(git_config_open_ondisk(&cfg, "config9")); | |
9a97f49e CMN |
309 | cl_git_pass(git_config_get_string_buf(&buf, cfg, "core.somevar")); |
310 | cl_assert_equal_s("this \"has\" quotes", git_buf_cstr(&buf)); | |
311 | git_buf_clear(&buf); | |
750be86a | 312 | git_config_free(cfg); |
67d334c1 CMN |
313 | |
314 | /* The code path for values that already exist is different, check that one as well */ | |
315 | cl_git_pass(git_config_open_ondisk(&cfg, "config9")); | |
316 | cl_git_pass(git_config_set_string(cfg, "core.somevar", "this also \"has\" quotes")); | |
9a97f49e CMN |
317 | cl_git_pass(git_config_get_string_buf(&buf, cfg, "core.somevar")); |
318 | cl_assert_equal_s("this also \"has\" quotes", git_buf_cstr(&buf)); | |
319 | git_buf_clear(&buf); | |
67d334c1 CMN |
320 | git_config_free(cfg); |
321 | ||
322 | cl_git_pass(git_config_open_ondisk(&cfg, "config9")); | |
9a97f49e CMN |
323 | cl_git_pass(git_config_get_string_buf(&buf, cfg, "core.somevar")); |
324 | cl_assert_equal_s("this also \"has\" quotes", git_buf_cstr(&buf)); | |
325 | git_buf_free(&buf); | |
67d334c1 CMN |
326 | git_config_free(cfg); |
327 | } | |
328 | ||
329 | void test_config_write__escape_value(void) | |
330 | { | |
331 | git_config *cfg; | |
9a97f49e | 332 | git_buf buf = GIT_BUF_INIT; |
67d334c1 CMN |
333 | |
334 | cl_git_pass(git_config_open_ondisk(&cfg, "config9")); | |
335 | cl_git_pass(git_config_set_string(cfg, "core.somevar", "this \"has\" quotes and \t")); | |
9a97f49e CMN |
336 | cl_git_pass(git_config_get_string_buf(&buf, cfg, "core.somevar")); |
337 | cl_assert_equal_s("this \"has\" quotes and \t", git_buf_cstr(&buf)); | |
338 | git_buf_clear(&buf); | |
67d334c1 CMN |
339 | git_config_free(cfg); |
340 | ||
341 | cl_git_pass(git_config_open_ondisk(&cfg, "config9")); | |
9a97f49e CMN |
342 | cl_git_pass(git_config_get_string_buf(&buf, cfg, "core.somevar")); |
343 | cl_assert_equal_s("this \"has\" quotes and \t", git_buf_cstr(&buf)); | |
344 | git_buf_free(&buf); | |
67d334c1 | 345 | git_config_free(cfg); |
750be86a | 346 | } |
f8ede948 | 347 | |
a1abe66a | 348 | void test_config_write__add_value_at_specific_level(void) |
349 | { | |
350 | git_config *cfg, *cfg_specific; | |
351 | int i; | |
352 | int64_t l, expected = +9223372036854775803; | |
9a97f49e | 353 | git_buf buf = GIT_BUF_INIT; |
a1abe66a | 354 | |
355 | // open config15 as global level config file | |
356 | cl_git_pass(git_config_new(&cfg)); | |
357 | cl_git_pass(git_config_add_file_ondisk(cfg, "config9", | |
358 | GIT_CONFIG_LEVEL_LOCAL, 0)); | |
359 | cl_git_pass(git_config_add_file_ondisk(cfg, "config15", | |
360 | GIT_CONFIG_LEVEL_GLOBAL, 0)); | |
361 | ||
362 | cl_git_pass(git_config_open_level(&cfg_specific, cfg, GIT_CONFIG_LEVEL_GLOBAL)); | |
363 | ||
364 | cl_git_pass(git_config_set_int32(cfg_specific, "core.int32global", 28)); | |
365 | cl_git_pass(git_config_set_int64(cfg_specific, "core.int64global", expected)); | |
366 | cl_git_pass(git_config_set_bool(cfg_specific, "core.boolglobal", true)); | |
367 | cl_git_pass(git_config_set_string(cfg_specific, "core.stringglobal", "I'm a global config value!")); | |
368 | git_config_free(cfg_specific); | |
369 | git_config_free(cfg); | |
370 | ||
371 | // open config15 as local level config file | |
372 | cl_git_pass(git_config_open_ondisk(&cfg, "config15")); | |
373 | ||
374 | cl_git_pass(git_config_get_int32(&i, cfg, "core.int32global")); | |
375 | cl_assert_equal_i(28, i); | |
376 | cl_git_pass(git_config_get_int64(&l, cfg, "core.int64global")); | |
377 | cl_assert(l == expected); | |
378 | cl_git_pass(git_config_get_bool(&i, cfg, "core.boolglobal")); | |
379 | cl_assert_equal_b(true, i); | |
9a97f49e CMN |
380 | cl_git_pass(git_config_get_string_buf(&buf, cfg, "core.stringglobal")); |
381 | cl_assert_equal_s("I'm a global config value!", git_buf_cstr(&buf)); | |
a1abe66a | 382 | |
9a97f49e | 383 | git_buf_free(&buf); |
a1abe66a | 384 | git_config_free(cfg); |
385 | } | |
386 | ||
387 | void test_config_write__add_value_at_file_with_no_clrf_at_the_end(void) | |
f8ede948 | 388 | { |
389 | git_config *cfg; | |
390 | int i; | |
391 | ||
392 | cl_git_pass(git_config_open_ondisk(&cfg, "config17")); | |
393 | cl_git_pass(git_config_set_int32(cfg, "core.newline", 7)); | |
394 | git_config_free(cfg); | |
395 | ||
396 | cl_git_pass(git_config_open_ondisk(&cfg, "config17")); | |
397 | cl_git_pass(git_config_get_int32(&i, cfg, "core.newline")); | |
398 | cl_assert_equal_i(7, i); | |
399 | ||
400 | git_config_free(cfg); | |
401 | } | |
48bde2f1 | 402 | |
69374869 L |
403 | void test_config_write__add_section_at_file_with_no_clrf_at_the_end(void) |
404 | { | |
405 | git_config *cfg; | |
406 | int i; | |
407 | ||
408 | cl_git_pass(git_config_open_ondisk(&cfg, "config17")); | |
409 | cl_git_pass(git_config_set_int32(cfg, "diff.context", 10)); | |
410 | git_config_free(cfg); | |
411 | ||
412 | cl_git_pass(git_config_open_ondisk(&cfg, "config17")); | |
413 | cl_git_pass(git_config_get_int32(&i, cfg, "diff.context")); | |
414 | cl_assert_equal_i(10, i); | |
415 | ||
416 | git_config_free(cfg); | |
417 | } | |
418 | ||
a9f7236a SS |
419 | void test_config_write__add_value_which_needs_quotes(void) |
420 | { | |
9a97f49e | 421 | git_config *cfg, *base; |
a9f7236a SS |
422 | const char* str1; |
423 | const char* str2; | |
424 | const char* str3; | |
425 | const char* str4; | |
7dd28dde | 426 | const char* str5; |
a9f7236a SS |
427 | |
428 | cl_git_pass(git_config_open_ondisk(&cfg, "config17")); | |
429 | cl_git_pass(git_config_set_string(cfg, "core.startwithspace", " Something")); | |
430 | cl_git_pass(git_config_set_string(cfg, "core.endwithspace", "Something ")); | |
431 | cl_git_pass(git_config_set_string(cfg, "core.containscommentchar1", "some#thing")); | |
432 | cl_git_pass(git_config_set_string(cfg, "core.containscommentchar2", "some;thing")); | |
7dd28dde | 433 | cl_git_pass(git_config_set_string(cfg, "core.startwhithsapceandcontainsdoublequote", " some\"thing")); |
a9f7236a SS |
434 | git_config_free(cfg); |
435 | ||
9a97f49e CMN |
436 | cl_git_pass(git_config_open_ondisk(&base, "config17")); |
437 | cl_git_pass(git_config_snapshot(&cfg, base)); | |
a9f7236a SS |
438 | cl_git_pass(git_config_get_string(&str1, cfg, "core.startwithspace")); |
439 | cl_assert_equal_s(" Something", str1); | |
440 | cl_git_pass(git_config_get_string(&str2, cfg, "core.endwithspace")); | |
441 | cl_assert_equal_s("Something ", str2); | |
442 | cl_git_pass(git_config_get_string(&str3, cfg, "core.containscommentchar1")); | |
443 | cl_assert_equal_s("some#thing", str3); | |
444 | cl_git_pass(git_config_get_string(&str4, cfg, "core.containscommentchar2")); | |
445 | cl_assert_equal_s("some;thing", str4); | |
7dd28dde SS |
446 | cl_git_pass(git_config_get_string(&str5, cfg, "core.startwhithsapceandcontainsdoublequote")); |
447 | cl_assert_equal_s(" some\"thing", str5); | |
a9f7236a | 448 | git_config_free(cfg); |
9a97f49e | 449 | git_config_free(base); |
a9f7236a SS |
450 | } |
451 | ||
48bde2f1 CMN |
452 | void test_config_write__can_set_a_value_to_NULL(void) |
453 | { | |
454 | git_repository *repository; | |
455 | git_config *config; | |
456 | ||
457 | repository = cl_git_sandbox_init("testrepo.git"); | |
458 | ||
459 | cl_git_pass(git_repository_config(&config, repository)); | |
460 | cl_git_fail(git_config_set_string(config, "a.b.c", NULL)); | |
461 | git_config_free(config); | |
462 | ||
463 | cl_git_sandbox_cleanup(); | |
464 | } | |
c57f6682 NV |
465 | |
466 | void test_config_write__can_set_an_empty_value(void) | |
467 | { | |
468 | git_repository *repository; | |
469 | git_config *config; | |
9a97f49e | 470 | git_buf buf = {0}; |
c57f6682 NV |
471 | |
472 | repository = cl_git_sandbox_init("testrepo.git"); | |
473 | cl_git_pass(git_repository_config(&config, repository)); | |
474 | ||
475 | cl_git_pass(git_config_set_string(config, "core.somevar", "")); | |
9a97f49e CMN |
476 | cl_git_pass(git_config_get_string_buf(&buf, config, "core.somevar")); |
477 | cl_assert_equal_s("", buf.ptr); | |
c57f6682 | 478 | |
9a97f49e | 479 | git_buf_free(&buf); |
c57f6682 NV |
480 | git_config_free(config); |
481 | cl_git_sandbox_cleanup(); | |
482 | } | |
e8162fd0 | 483 | |
484 | void test_config_write__updating_a_locked_config_file_returns_ELOCKED(void) | |
485 | { | |
486 | git_config *cfg; | |
487 | ||
488 | cl_git_pass(git_config_open_ondisk(&cfg, "config9")); | |
489 | ||
490 | cl_git_mkfile("config9.lock", "[core]\n"); | |
491 | ||
492 | cl_git_fail_with(git_config_set_string(cfg, "core.dump", "boom"), GIT_ELOCKED); | |
493 | ||
494 | git_config_free(cfg); | |
495 | } | |
96869a4e | 496 | |
36913b8c CMN |
497 | void test_config_write__outside_change(void) |
498 | { | |
499 | int32_t tmp; | |
500 | git_config *cfg; | |
501 | const char *filename = "config-ext-change"; | |
502 | ||
503 | cl_git_mkfile(filename, "[old]\nvalue = 5\n"); | |
504 | ||
505 | cl_git_pass(git_config_open_ondisk(&cfg, filename)); | |
506 | ||
507 | cl_git_pass(git_config_get_int32(&tmp, cfg, "old.value")); | |
508 | ||
509 | /* Change the value on the file itself (simulate external process) */ | |
510 | cl_git_mkfile(filename, "[old]\nvalue = 6\n"); | |
511 | ||
512 | cl_git_pass(git_config_set_int32(cfg, "new.value", 7)); | |
513 | ||
514 | cl_git_pass(git_config_get_int32(&tmp, cfg, "old.value")); | |
eaf37034 | 515 | cl_assert_equal_i(6, tmp); |
36913b8c | 516 | |
36913b8c CMN |
517 | git_config_free(cfg); |
518 | } | |
6dc55872 | 519 | |
7ee61b8e ET |
520 | #define SECTION_FOO \ |
521 | "\n" \ | |
522 | " \n" \ | |
523 | " [section \"foo\"] \n" \ | |
524 | " # here's a comment\n" \ | |
525 | "\tname = \"value\"\n" \ | |
526 | " name2 = \"value2\"\n" \ | |
527 | "; another comment!\n" | |
528 | ||
529 | #define SECTION_BAR \ | |
530 | "[section \"bar\"]\t\n" \ | |
531 | "\t \n" \ | |
532 | " barname=\"value\"\n" | |
533 | ||
534 | ||
535 | void test_config_write__preserves_whitespace_and_comments(void) | |
536 | { | |
537 | const char *file_name = "config-duplicate-header"; | |
7ee61b8e ET |
538 | const char *n; |
539 | git_config *cfg; | |
540 | git_buf newfile = GIT_BUF_INIT; | |
541 | ||
542 | /* This config can occur after removing and re-adding the origin remote */ | |
543 | const char *file_content = SECTION_FOO SECTION_BAR; | |
544 | ||
545 | /* Write the test config and make sure the expected entry exists */ | |
546 | cl_git_mkfile(file_name, file_content); | |
547 | cl_git_pass(git_config_open_ondisk(&cfg, file_name)); | |
548 | cl_git_pass(git_config_set_string(cfg, "section.foo.other", "otherval")); | |
549 | cl_git_pass(git_config_set_string(cfg, "newsection.newname", "new_value")); | |
550 | ||
551 | /* Ensure that we didn't needlessly mangle the config file */ | |
552 | cl_git_pass(git_futils_readbuffer(&newfile, file_name)); | |
553 | n = newfile.ptr; | |
554 | ||
555 | cl_assert_equal_strn(SECTION_FOO, n, strlen(SECTION_FOO)); | |
556 | n += strlen(SECTION_FOO); | |
557 | ||
558 | cl_assert_equal_strn("\tother = otherval\n", n, strlen("\tother = otherval\n")); | |
559 | n += strlen("\tother = otherval\n"); | |
560 | ||
561 | cl_assert_equal_strn(SECTION_BAR, n, strlen(SECTION_BAR)); | |
562 | n += strlen(SECTION_BAR); | |
563 | ||
564 | cl_assert_equal_s("[newsection]\n\tnewname = new_value\n", n); | |
565 | ||
566 | git_buf_free(&newfile); | |
567 | git_config_free(cfg); | |
568 | } | |
569 | ||
570 | void test_config_write__preserves_entry_with_name_only(void) | |
571 | { | |
572 | const char *file_name = "config-empty-value"; | |
7ee61b8e ET |
573 | git_config *cfg; |
574 | git_buf newfile = GIT_BUF_INIT; | |
575 | ||
576 | /* Write the test config and make sure the expected entry exists */ | |
577 | cl_git_mkfile(file_name, "[section \"foo\"]\n\tname\n"); | |
578 | cl_git_pass(git_config_open_ondisk(&cfg, file_name)); | |
579 | cl_git_pass(git_config_set_string(cfg, "newsection.newname", "new_value")); | |
580 | cl_git_pass(git_config_set_string(cfg, "section.foo.other", "otherval")); | |
581 | ||
582 | cl_git_pass(git_futils_readbuffer(&newfile, file_name)); | |
583 | cl_assert_equal_s("[section \"foo\"]\n\tname\n\tother = otherval\n[newsection]\n\tnewname = new_value\n", newfile.ptr); | |
584 | ||
585 | git_buf_free(&newfile); | |
586 | git_config_free(cfg); | |
587 | } | |
588 | ||
6dc55872 ET |
589 | void test_config_write__to_empty_file(void) |
590 | { | |
591 | git_config *cfg; | |
592 | const char *filename = "config-file"; | |
593 | git_buf result = GIT_BUF_INIT; | |
594 | ||
595 | cl_git_mkfile(filename, ""); | |
596 | cl_git_pass(git_config_open_ondisk(&cfg, filename)); | |
597 | cl_git_pass(git_config_set_string(cfg, "section.name", "value")); | |
598 | git_config_free(cfg); | |
599 | ||
600 | cl_git_pass(git_futils_readbuffer(&result, "config-file")); | |
601 | cl_assert_equal_s("[section]\n\tname = value\n", result.ptr); | |
602 | ||
603 | git_buf_free(&result); | |
604 | } | |
605 | ||
606 | void test_config_write__to_file_with_only_comment(void) | |
607 | { | |
608 | git_config *cfg; | |
609 | const char *filename = "config-file"; | |
610 | git_buf result = GIT_BUF_INIT; | |
611 | ||
612 | cl_git_mkfile(filename, "\n\n"); | |
613 | cl_git_pass(git_config_open_ondisk(&cfg, filename)); | |
614 | cl_git_pass(git_config_set_string(cfg, "section.name", "value")); | |
615 | git_config_free(cfg); | |
616 | ||
617 | cl_git_pass(git_futils_readbuffer(&result, "config-file")); | |
618 | cl_assert_equal_s("\n\n[section]\n\tname = value\n", result.ptr); | |
619 | ||
620 | git_buf_free(&result); | |
621 | } | |
7ee61b8e | 622 |