1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49 package org.eclipse.jgit.lib;
50
51 import static java.util.concurrent.TimeUnit.DAYS;
52 import static java.util.concurrent.TimeUnit.HOURS;
53 import static java.util.concurrent.TimeUnit.MILLISECONDS;
54 import static java.util.concurrent.TimeUnit.MINUTES;
55 import static java.util.concurrent.TimeUnit.NANOSECONDS;
56 import static java.util.concurrent.TimeUnit.MICROSECONDS;
57 import static java.util.concurrent.TimeUnit.SECONDS;
58 import static org.eclipse.jgit.util.FileUtils.pathToString;
59 import static org.junit.Assert.assertArrayEquals;
60 import static org.junit.Assert.assertEquals;
61 import static org.junit.Assert.assertFalse;
62 import static org.junit.Assert.assertNull;
63 import static org.junit.Assert.assertSame;
64 import static org.junit.Assert.assertTrue;
65 import static org.junit.Assert.fail;
66
67 import java.io.File;
68 import java.io.IOException;
69 import java.nio.file.Files;
70 import java.text.MessageFormat;
71 import java.util.Arrays;
72 import java.util.Iterator;
73 import java.util.LinkedList;
74 import java.util.Set;
75 import java.util.concurrent.TimeUnit;
76
77 import org.eclipse.jgit.api.MergeCommand.FastForwardMode;
78 import org.eclipse.jgit.errors.ConfigInvalidException;
79 import org.eclipse.jgit.internal.JGitText;
80 import org.eclipse.jgit.junit.MockSystemReader;
81 import org.eclipse.jgit.merge.MergeConfig;
82 import org.eclipse.jgit.storage.file.FileBasedConfig;
83 import org.eclipse.jgit.util.FS;
84 import org.eclipse.jgit.util.SystemReader;
85 import org.junit.After;
86 import org.junit.Rule;
87 import org.junit.Test;
88 import org.junit.rules.ExpectedException;
89 import org.junit.rules.TemporaryFolder;
90
91
92
93
94 @SuppressWarnings("boxing")
95 public class ConfigTest {
96
97 private static final char WS = '\u2002';
98
99 @Rule
100 public ExpectedException expectedEx = ExpectedException.none();
101
102 @Rule
103 public TemporaryFolder tmp = new TemporaryFolder();
104
105 @After
106 public void tearDown() {
107 SystemReader.setInstance(null);
108 }
109
110 @Test
111 public void test001_ReadBareKey() throws ConfigInvalidException {
112 final Config c = parse("[foo]\nbar\n");
113 assertTrue(c.getBoolean("foo", null, "bar", false));
114 assertEquals("", c.getString("foo", null, "bar"));
115 }
116
117 @Test
118 public void test002_ReadWithSubsection() throws ConfigInvalidException {
119 final Config c = parse("[foo \"zip\"]\nbar\n[foo \"zap\"]\nbar=false\nn=3\n");
120 assertTrue(c.getBoolean("foo", "zip", "bar", false));
121 assertEquals("", c.getString("foo","zip", "bar"));
122 assertFalse(c.getBoolean("foo", "zap", "bar", true));
123 assertEquals("false", c.getString("foo", "zap", "bar"));
124 assertEquals(3, c.getInt("foo", "zap", "n", 4));
125 assertEquals(4, c.getInt("foo", "zap","m", 4));
126 }
127
128 @Test
129 public void test003_PutRemote() {
130 final Config c = new Config();
131 c.setString("sec", "ext", "name", "value");
132 c.setString("sec", "ext", "name2", "value2");
133 final String expText = "[sec \"ext\"]\n\tname = value\n\tname2 = value2\n";
134 assertEquals(expText, c.toText());
135 }
136
137 @Test
138 public void test004_PutGetSimple() {
139 Config c = new Config();
140 c.setString("my", null, "somename", "false");
141 assertEquals("false", c.getString("my", null, "somename"));
142 assertEquals("[my]\n\tsomename = false\n", c.toText());
143 }
144
145 @Test
146 public void test005_PutGetStringList() {
147 Config c = new Config();
148 final LinkedList<String> values = new LinkedList<>();
149 values.add("value1");
150 values.add("value2");
151 c.setStringList("my", null, "somename", values);
152
153 final Object[] expArr = values.toArray();
154 final String[] actArr = c.getStringList("my", null, "somename");
155 assertArrayEquals(expArr, actArr);
156
157 final String expText = "[my]\n\tsomename = value1\n\tsomename = value2\n";
158 assertEquals(expText, c.toText());
159 }
160
161 @Test
162 public void test006_readCaseInsensitive() throws ConfigInvalidException {
163 final Config c = parse("[Foo]\nBar\n");
164 assertTrue(c.getBoolean("foo", null, "bar", false));
165 assertEquals("", c.getString("foo", null, "bar"));
166 }
167
168 @Test
169 public void test007_readUserConfig() {
170 final MockSystemReader mockSystemReader = new MockSystemReader();
171 SystemReader.setInstance(mockSystemReader);
172 final String hostname = mockSystemReader.getHostname();
173 final Config userGitConfig = mockSystemReader.openUserConfig(null,
174 FS.DETECTED);
175 final Config localConfig = new Config(userGitConfig);
176 mockSystemReader.clearProperties();
177
178 String authorName;
179 String authorEmail;
180
181
182 authorName = localConfig.get(UserConfig.KEY).getAuthorName();
183 authorEmail = localConfig.get(UserConfig.KEY).getAuthorEmail();
184 assertEquals(Constants.UNKNOWN_USER_DEFAULT, authorName);
185 assertEquals(Constants.UNKNOWN_USER_DEFAULT + "@" + hostname, authorEmail);
186 assertTrue(localConfig.get(UserConfig.KEY).isAuthorNameImplicit());
187 assertTrue(localConfig.get(UserConfig.KEY).isAuthorEmailImplicit());
188
189
190 mockSystemReader.setProperty(Constants.OS_USER_NAME_KEY, "os user name");
191 localConfig.uncache(UserConfig.KEY);
192 authorName = localConfig.get(UserConfig.KEY).getAuthorName();
193 assertEquals("os user name", authorName);
194 assertTrue(localConfig.get(UserConfig.KEY).isAuthorNameImplicit());
195
196 if (hostname != null && hostname.length() != 0) {
197 authorEmail = localConfig.get(UserConfig.KEY).getAuthorEmail();
198 assertEquals("os user name@" + hostname, authorEmail);
199 }
200 assertTrue(localConfig.get(UserConfig.KEY).isAuthorEmailImplicit());
201
202
203 mockSystemReader.setProperty(Constants.GIT_AUTHOR_NAME_KEY, "git author name");
204 mockSystemReader.setProperty(Constants.GIT_AUTHOR_EMAIL_KEY, "author@email");
205 localConfig.uncache(UserConfig.KEY);
206 authorName = localConfig.get(UserConfig.KEY).getAuthorName();
207 authorEmail = localConfig.get(UserConfig.KEY).getAuthorEmail();
208 assertEquals("git author name", authorName);
209 assertEquals("author@email", authorEmail);
210 assertFalse(localConfig.get(UserConfig.KEY).isAuthorNameImplicit());
211 assertFalse(localConfig.get(UserConfig.KEY).isAuthorEmailImplicit());
212
213
214
215
216 mockSystemReader.clearProperties();
217 userGitConfig.setString("user", null, "name", "global username");
218 userGitConfig.setString("user", null, "email", "author@globalemail");
219 authorName = localConfig.get(UserConfig.KEY).getAuthorName();
220 authorEmail = localConfig.get(UserConfig.KEY).getAuthorEmail();
221 assertEquals("global username", authorName);
222 assertEquals("author@globalemail", authorEmail);
223 assertFalse(localConfig.get(UserConfig.KEY).isAuthorNameImplicit());
224 assertFalse(localConfig.get(UserConfig.KEY).isAuthorEmailImplicit());
225
226
227 localConfig.setString("user", null, "name", "local username");
228 localConfig.setString("user", null, "email", "author@localemail");
229 authorName = localConfig.get(UserConfig.KEY).getAuthorName();
230 authorEmail = localConfig.get(UserConfig.KEY).getAuthorEmail();
231 assertEquals("local username", authorName);
232 assertEquals("author@localemail", authorEmail);
233 assertFalse(localConfig.get(UserConfig.KEY).isAuthorNameImplicit());
234 assertFalse(localConfig.get(UserConfig.KEY).isAuthorEmailImplicit());
235
236 authorName = localConfig.get(UserConfig.KEY).getCommitterName();
237 authorEmail = localConfig.get(UserConfig.KEY).getCommitterEmail();
238 assertEquals("local username", authorName);
239 assertEquals("author@localemail", authorEmail);
240 assertFalse(localConfig.get(UserConfig.KEY).isCommitterNameImplicit());
241 assertFalse(localConfig.get(UserConfig.KEY).isCommitterEmailImplicit());
242
243
244 mockSystemReader.setProperty(Constants.GIT_AUTHOR_NAME_KEY,
245 "git author name");
246 mockSystemReader.setProperty(Constants.GIT_AUTHOR_EMAIL_KEY,
247 "author@email");
248 localConfig.setString("user", null, "name", "local username");
249 localConfig.setString("user", null, "email", "author@localemail");
250 authorName = localConfig.get(UserConfig.KEY).getAuthorName();
251 authorEmail = localConfig.get(UserConfig.KEY).getAuthorEmail();
252 assertEquals("git author name", authorName);
253 assertEquals("author@email", authorEmail);
254 assertFalse(localConfig.get(UserConfig.KEY).isAuthorNameImplicit());
255 assertFalse(localConfig.get(UserConfig.KEY).isAuthorEmailImplicit());
256 }
257
258 @Test
259 public void testReadUserConfigWithInvalidCharactersStripped() {
260 final MockSystemReader mockSystemReader = new MockSystemReader();
261 final Config localConfig = new Config(mockSystemReader.openUserConfig(
262 null, FS.DETECTED));
263
264 localConfig.setString("user", null, "name", "foo<bar");
265 localConfig.setString("user", null, "email", "baz>\nqux@example.com");
266
267 UserConfig userConfig = localConfig.get(UserConfig.KEY);
268 assertEquals("foobar", userConfig.getAuthorName());
269 assertEquals("bazqux@example.com", userConfig.getAuthorEmail());
270 }
271
272 @Test
273 public void testReadBoolean_TrueFalse1() throws ConfigInvalidException {
274 final Config c = parse("[s]\na = true\nb = false\n");
275 assertEquals("true", c.getString("s", null, "a"));
276 assertEquals("false", c.getString("s", null, "b"));
277
278 assertTrue(c.getBoolean("s", "a", false));
279 assertFalse(c.getBoolean("s", "b", true));
280 }
281
282 @Test
283 public void testReadBoolean_TrueFalse2() throws ConfigInvalidException {
284 final Config c = parse("[s]\na = TrUe\nb = fAlSe\n");
285 assertEquals("TrUe", c.getString("s", null, "a"));
286 assertEquals("fAlSe", c.getString("s", null, "b"));
287
288 assertTrue(c.getBoolean("s", "a", false));
289 assertFalse(c.getBoolean("s", "b", true));
290 }
291
292 @Test
293 public void testReadBoolean_YesNo1() throws ConfigInvalidException {
294 final Config c = parse("[s]\na = yes\nb = no\n");
295 assertEquals("yes", c.getString("s", null, "a"));
296 assertEquals("no", c.getString("s", null, "b"));
297
298 assertTrue(c.getBoolean("s", "a", false));
299 assertFalse(c.getBoolean("s", "b", true));
300 }
301
302 @Test
303 public void testReadBoolean_YesNo2() throws ConfigInvalidException {
304 final Config c = parse("[s]\na = yEs\nb = NO\n");
305 assertEquals("yEs", c.getString("s", null, "a"));
306 assertEquals("NO", c.getString("s", null, "b"));
307
308 assertTrue(c.getBoolean("s", "a", false));
309 assertFalse(c.getBoolean("s", "b", true));
310 }
311
312 @Test
313 public void testReadBoolean_OnOff1() throws ConfigInvalidException {
314 final Config c = parse("[s]\na = on\nb = off\n");
315 assertEquals("on", c.getString("s", null, "a"));
316 assertEquals("off", c.getString("s", null, "b"));
317
318 assertTrue(c.getBoolean("s", "a", false));
319 assertFalse(c.getBoolean("s", "b", true));
320 }
321
322 @Test
323 public void testReadBoolean_OnOff2() throws ConfigInvalidException {
324 final Config c = parse("[s]\na = ON\nb = OFF\n");
325 assertEquals("ON", c.getString("s", null, "a"));
326 assertEquals("OFF", c.getString("s", null, "b"));
327
328 assertTrue(c.getBoolean("s", "a", false));
329 assertFalse(c.getBoolean("s", "b", true));
330 }
331
332 static enum TestEnum {
333 ONE_TWO;
334 }
335
336 @Test
337 public void testGetEnum() throws ConfigInvalidException {
338 Config c = parse("[s]\na = ON\nb = input\nc = true\nd = off\n");
339 assertSame(CoreConfig.AutoCRLF.TRUE, c.getEnum("s", null, "a",
340 CoreConfig.AutoCRLF.FALSE));
341
342 assertSame(CoreConfig.AutoCRLF.INPUT, c.getEnum("s", null, "b",
343 CoreConfig.AutoCRLF.FALSE));
344
345 assertSame(CoreConfig.AutoCRLF.TRUE, c.getEnum("s", null, "c",
346 CoreConfig.AutoCRLF.FALSE));
347
348 assertSame(CoreConfig.AutoCRLF.FALSE, c.getEnum("s", null, "d",
349 CoreConfig.AutoCRLF.TRUE));
350
351 c = new Config();
352 assertSame(CoreConfig.AutoCRLF.FALSE, c.getEnum("s", null, "d",
353 CoreConfig.AutoCRLF.FALSE));
354
355 c = parse("[s \"b\"]\n\tc = one two\n");
356 assertSame(TestEnum.ONE_TWO, c.getEnum("s", "b", "c", TestEnum.ONE_TWO));
357
358 c = parse("[s \"b\"]\n\tc = one-two\n");
359 assertSame(TestEnum.ONE_TWO, c.getEnum("s", "b", "c", TestEnum.ONE_TWO));
360 }
361
362 @Test
363 public void testGetInvalidEnum() throws ConfigInvalidException {
364 Config c = parse("[a]\n\tb = invalid\n");
365 try {
366 c.getEnum("a", null, "b", TestEnum.ONE_TWO);
367 fail();
368 } catch (IllegalArgumentException e) {
369 assertEquals("Invalid value: a.b=invalid", e.getMessage());
370 }
371
372 c = parse("[a \"b\"]\n\tc = invalid\n");
373 try {
374 c.getEnum("a", "b", "c", TestEnum.ONE_TWO);
375 fail();
376 } catch (IllegalArgumentException e) {
377 assertEquals("Invalid value: a.b.c=invalid", e.getMessage());
378 }
379 }
380
381 @Test
382 public void testSetEnum() {
383 final Config c = new Config();
384 c.setEnum("s", "b", "c", TestEnum.ONE_TWO);
385 assertEquals("[s \"b\"]\n\tc = one two\n", c.toText());
386 }
387
388 @Test
389 public void testGetFastForwardMergeoptions() throws ConfigInvalidException {
390 Config c = new Config(null);
391 assertSame(FastForwardMode.FF, c.getEnum(
392 ConfigConstants.CONFIG_BRANCH_SECTION, "side",
393 ConfigConstants.CONFIG_KEY_MERGEOPTIONS, FastForwardMode.FF));
394 MergeConfig mergeConfig = c.get(MergeConfig.getParser("side"));
395 assertSame(FastForwardMode.FF, mergeConfig.getFastForwardMode());
396 c = parse("[branch \"side\"]\n\tmergeoptions = --ff-only\n");
397 assertSame(FastForwardMode.FF_ONLY, c.getEnum(
398 ConfigConstants.CONFIG_BRANCH_SECTION, "side",
399 ConfigConstants.CONFIG_KEY_MERGEOPTIONS,
400 FastForwardMode.FF_ONLY));
401 mergeConfig = c.get(MergeConfig.getParser("side"));
402 assertSame(FastForwardMode.FF_ONLY, mergeConfig.getFastForwardMode());
403 c = parse("[branch \"side\"]\n\tmergeoptions = --ff\n");
404 assertSame(FastForwardMode.FF, c.getEnum(
405 ConfigConstants.CONFIG_BRANCH_SECTION, "side",
406 ConfigConstants.CONFIG_KEY_MERGEOPTIONS, FastForwardMode.FF));
407 mergeConfig = c.get(MergeConfig.getParser("side"));
408 assertSame(FastForwardMode.FF, mergeConfig.getFastForwardMode());
409 c = parse("[branch \"side\"]\n\tmergeoptions = --no-ff\n");
410 assertSame(FastForwardMode.NO_FF, c.getEnum(
411 ConfigConstants.CONFIG_BRANCH_SECTION, "side",
412 ConfigConstants.CONFIG_KEY_MERGEOPTIONS, FastForwardMode.NO_FF));
413 mergeConfig = c.get(MergeConfig.getParser("side"));
414 assertSame(FastForwardMode.NO_FF, mergeConfig.getFastForwardMode());
415 }
416
417 @Test
418 public void testSetFastForwardMergeoptions() {
419 final Config c = new Config();
420 c.setEnum("branch", "side", "mergeoptions", FastForwardMode.FF);
421 assertEquals("[branch \"side\"]\n\tmergeoptions = --ff\n", c.toText());
422 c.setEnum("branch", "side", "mergeoptions", FastForwardMode.FF_ONLY);
423 assertEquals("[branch \"side\"]\n\tmergeoptions = --ff-only\n",
424 c.toText());
425 c.setEnum("branch", "side", "mergeoptions", FastForwardMode.NO_FF);
426 assertEquals("[branch \"side\"]\n\tmergeoptions = --no-ff\n",
427 c.toText());
428 }
429
430 @Test
431 public void testGetFastForwardMerge() throws ConfigInvalidException {
432 Config c = new Config(null);
433 assertSame(FastForwardMode.Merge.TRUE, c.getEnum(
434 ConfigConstants.CONFIG_KEY_MERGE, null,
435 ConfigConstants.CONFIG_KEY_FF, FastForwardMode.Merge.TRUE));
436 MergeConfig mergeConfig = c.get(MergeConfig.getParser("side"));
437 assertSame(FastForwardMode.FF, mergeConfig.getFastForwardMode());
438 c = parse("[merge]\n\tff = only\n");
439 assertSame(FastForwardMode.Merge.ONLY, c.getEnum(
440 ConfigConstants.CONFIG_KEY_MERGE, null,
441 ConfigConstants.CONFIG_KEY_FF, FastForwardMode.Merge.ONLY));
442 mergeConfig = c.get(MergeConfig.getParser("side"));
443 assertSame(FastForwardMode.FF_ONLY, mergeConfig.getFastForwardMode());
444 c = parse("[merge]\n\tff = true\n");
445 assertSame(FastForwardMode.Merge.TRUE, c.getEnum(
446 ConfigConstants.CONFIG_KEY_MERGE, null,
447 ConfigConstants.CONFIG_KEY_FF, FastForwardMode.Merge.TRUE));
448 mergeConfig = c.get(MergeConfig.getParser("side"));
449 assertSame(FastForwardMode.FF, mergeConfig.getFastForwardMode());
450 c = parse("[merge]\n\tff = false\n");
451 assertSame(FastForwardMode.Merge.FALSE, c.getEnum(
452 ConfigConstants.CONFIG_KEY_MERGE, null,
453 ConfigConstants.CONFIG_KEY_FF, FastForwardMode.Merge.FALSE));
454 mergeConfig = c.get(MergeConfig.getParser("side"));
455 assertSame(FastForwardMode.NO_FF, mergeConfig.getFastForwardMode());
456 }
457
458 @Test
459 public void testCombinedMergeOptions() throws ConfigInvalidException {
460 Config c = new Config(null);
461 MergeConfig mergeConfig = c.get(MergeConfig.getParser("side"));
462 assertSame(FastForwardMode.FF, mergeConfig.getFastForwardMode());
463 assertTrue(mergeConfig.isCommit());
464 assertFalse(mergeConfig.isSquash());
465
466 c = parse("[merge]\n\tff = false\n"
467 + "[branch \"side\"]\n\tmergeoptions = --ff-only\n");
468 mergeConfig = c.get(MergeConfig.getParser("side"));
469 assertSame(FastForwardMode.FF_ONLY, mergeConfig.getFastForwardMode());
470 assertTrue(mergeConfig.isCommit());
471 assertFalse(mergeConfig.isSquash());
472
473 c = parse("[merge]\n\tff = only\n"
474 + "[branch \"side\"]\n\tmergeoptions = --squash\n");
475 mergeConfig = c.get(MergeConfig.getParser("side"));
476 assertSame(FastForwardMode.FF_ONLY, mergeConfig.getFastForwardMode());
477 assertTrue(mergeConfig.isCommit());
478 assertTrue(mergeConfig.isSquash());
479
480 c = parse("[merge]\n\tff = false\n"
481 + "[branch \"side\"]\n\tmergeoptions = --ff-only --no-commit\n");
482 mergeConfig = c.get(MergeConfig.getParser("side"));
483 assertSame(FastForwardMode.FF_ONLY, mergeConfig.getFastForwardMode());
484 assertFalse(mergeConfig.isCommit());
485 assertFalse(mergeConfig.isSquash());
486 }
487
488 @Test
489 public void testSetFastForwardMerge() {
490 final Config c = new Config();
491 c.setEnum("merge", null, "ff",
492 FastForwardMode.Merge.valueOf(FastForwardMode.FF));
493 assertEquals("[merge]\n\tff = true\n", c.toText());
494 c.setEnum("merge", null, "ff",
495 FastForwardMode.Merge.valueOf(FastForwardMode.FF_ONLY));
496 assertEquals("[merge]\n\tff = only\n", c.toText());
497 c.setEnum("merge", null, "ff",
498 FastForwardMode.Merge.valueOf(FastForwardMode.NO_FF));
499 assertEquals("[merge]\n\tff = false\n", c.toText());
500 }
501
502 @Test
503 public void testReadLong() throws ConfigInvalidException {
504 assertReadLong(1L);
505 assertReadLong(-1L);
506 assertReadLong(Long.MIN_VALUE);
507 assertReadLong(Long.MAX_VALUE);
508 assertReadLong(4L * 1024 * 1024 * 1024, "4g");
509 assertReadLong(3L * 1024 * 1024, "3 m");
510 assertReadLong(8L * 1024, "8 k");
511
512 try {
513 assertReadLong(-1, "1.5g");
514 fail("incorrectly accepted 1.5g");
515 } catch (IllegalArgumentException e) {
516 assertEquals("Invalid integer value: s.a=1.5g", e.getMessage());
517 }
518 }
519
520 @Test
521 public void testBooleanWithNoValue() throws ConfigInvalidException {
522 Config c = parse("[my]\n\tempty\n");
523 assertEquals("", c.getString("my", null, "empty"));
524 assertEquals(1, c.getStringList("my", null, "empty").length);
525 assertEquals("", c.getStringList("my", null, "empty")[0]);
526 assertTrue(c.getBoolean("my", "empty", false));
527 assertEquals("[my]\n\tempty\n", c.toText());
528 }
529
530 @Test
531 public void testUnsetBranchSection() throws ConfigInvalidException {
532 Config c = parse(""
533 + "[branch \"keep\"]\n"
534 + " merge = master.branch.to.keep.in.the.file\n"
535 + "\n"
536 + "[branch \"remove\"]\n"
537 + " merge = this.will.get.deleted\n"
538 + " remote = origin-for-some-long-gone-place\n"
539 + "\n"
540 + "[core-section-not-to-remove-in-test]\n"
541 + " packedGitLimit = 14\n");
542 c.unsetSection("branch", "does.not.exist");
543 c.unsetSection("branch", "remove");
544 assertEquals(""
545 + "[branch \"keep\"]\n"
546 + " merge = master.branch.to.keep.in.the.file\n"
547 + "\n"
548 + "[core-section-not-to-remove-in-test]\n"
549 + " packedGitLimit = 14\n", c.toText());
550 }
551
552 @Test
553 public void testUnsetSingleSection() throws ConfigInvalidException {
554 Config c = parse(""
555 + "[branch \"keep\"]\n"
556 + " merge = master.branch.to.keep.in.the.file\n"
557 + "\n"
558 + "[single]\n"
559 + " merge = this.will.get.deleted\n"
560 + " remote = origin-for-some-long-gone-place\n"
561 + "\n"
562 + "[core-section-not-to-remove-in-test]\n"
563 + " packedGitLimit = 14\n");
564 c.unsetSection("single", null);
565 assertEquals(""
566 + "[branch \"keep\"]\n"
567 + " merge = master.branch.to.keep.in.the.file\n"
568 + "\n"
569 + "[core-section-not-to-remove-in-test]\n"
570 + " packedGitLimit = 14\n", c.toText());
571 }
572
573 @Test
574 public void test008_readSectionNames() throws ConfigInvalidException {
575 final Config c = parse("[a]\n [B]\n");
576 Set<String> sections = c.getSections();
577 assertTrue("Sections should contain \"a\"", sections.contains("a"));
578 assertTrue("Sections should contain \"b\"", sections.contains("b"));
579 }
580
581 @Test
582 public void test009_readNamesInSection() throws ConfigInvalidException {
583 String configString = "[core]\n" + "repositoryFormatVersion = 0\n"
584 + "filemode = false\n" + "logAllRefUpdates = true\n";
585 final Config c = parse(configString);
586 Set<String> names = c.getNames("core");
587 assertEquals("Core section size", 3, names.size());
588 assertTrue("Core section should contain \"filemode\"", names
589 .contains("filemode"));
590
591 assertTrue("Core section should contain \"repositoryFormatVersion\"",
592 names.contains("repositoryFormatVersion"));
593
594 assertTrue("Core section should contain \"repositoryformatversion\"",
595 names.contains("repositoryformatversion"));
596
597 Iterator<String> itr = names.iterator();
598 assertEquals("filemode", itr.next());
599 assertEquals("logAllRefUpdates", itr.next());
600 assertEquals("repositoryFormatVersion", itr.next());
601 assertFalse(itr.hasNext());
602 }
603
604 @Test
605 public void test_ReadNamesInSectionRecursive()
606 throws ConfigInvalidException {
607 String baseConfigString = "[core]\n" + "logAllRefUpdates = true\n";
608 String configString = "[core]\n" + "repositoryFormatVersion = 0\n"
609 + "filemode = false\n";
610 final Config c = parse(configString, parse(baseConfigString));
611 Set<String> names = c.getNames("core", true);
612 assertEquals("Core section size", 3, names.size());
613 assertTrue("Core section should contain \"filemode\"",
614 names.contains("filemode"));
615 assertTrue("Core section should contain \"repositoryFormatVersion\"",
616 names.contains("repositoryFormatVersion"));
617 assertTrue("Core section should contain \"logAllRefUpdates\"",
618 names.contains("logAllRefUpdates"));
619 assertTrue("Core section should contain \"logallrefupdates\"",
620 names.contains("logallrefupdates"));
621
622 Iterator<String> itr = names.iterator();
623 assertEquals("filemode", itr.next());
624 assertEquals("repositoryFormatVersion", itr.next());
625 assertEquals("logAllRefUpdates", itr.next());
626 assertFalse(itr.hasNext());
627 }
628
629 @Test
630 public void test010_readNamesInSubSection() throws ConfigInvalidException {
631 String configString = "[a \"sub1\"]\n"
632 + "x = 0\n"
633 + "y = false\n"
634 + "z = true\n"
635 + "[a \"sub2\"]\n"
636 + "a=0\n"
637 + "b=1\n";
638 final Config c = parse(configString);
639 Set<String> names = c.getNames("a", "sub1");
640 assertEquals("Subsection size", 3, names.size());
641 assertTrue("Subsection should contain \"x\"", names.contains("x"));
642 assertTrue("Subsection should contain \"y\"", names.contains("y"));
643 assertTrue("Subsection should contain \"z\"", names.contains("z"));
644 names = c.getNames("a", "sub2");
645 assertEquals("Subsection size", 2, names.size());
646 assertTrue("Subsection should contain \"a\"", names.contains("a"));
647 assertTrue("Subsection should contain \"b\"", names.contains("b"));
648 }
649
650 @Test
651 public void readNamesInSubSectionRecursive() throws ConfigInvalidException {
652 String baseConfigString = "[a \"sub1\"]\n"
653 + "x = 0\n"
654 + "y = false\n"
655 + "[a \"sub2\"]\n"
656 + "A=0\n";
657 String configString = "[a \"sub1\"]\n"
658 + "z = true\n"
659 + "[a \"sub2\"]\n"
660 + "B=1\n";
661 final Config c = parse(configString, parse(baseConfigString));
662 Set<String> names = c.getNames("a", "sub1", true);
663 assertEquals("Subsection size", 3, names.size());
664 assertTrue("Subsection should contain \"x\"", names.contains("x"));
665 assertTrue("Subsection should contain \"y\"", names.contains("y"));
666 assertTrue("Subsection should contain \"z\"", names.contains("z"));
667 names = c.getNames("a", "sub2", true);
668 assertEquals("Subsection size", 2, names.size());
669 assertTrue("Subsection should contain \"A\"", names.contains("A"));
670 assertTrue("Subsection should contain \"a\"", names.contains("a"));
671 assertTrue("Subsection should contain \"B\"", names.contains("B"));
672 }
673
674
675 @Test
676 public void testNoFinalNewline() throws ConfigInvalidException {
677 Config c = parse("[a]\n"
678 + "x = 0\n"
679 + "y = 1");
680 assertEquals("0", c.getString("a", null, "x"));
681 assertEquals("1", c.getString("a", null, "y"));
682 }
683
684 @Test
685 public void testExplicitlySetEmptyString() throws Exception {
686 Config c = new Config();
687 c.setString("a", null, "x", "0");
688 c.setString("a", null, "y", "");
689
690 assertEquals("0", c.getString("a", null, "x"));
691 assertEquals(0, c.getInt("a", null, "x", 1));
692
693 assertEquals("", c.getString("a", null, "y"));
694 assertArrayEquals(new String[]{""}, c.getStringList("a", null, "y"));
695 try {
696 c.getInt("a", null, "y", 1);
697 } catch (IllegalArgumentException e) {
698 assertEquals("Invalid integer value: a.y=", e.getMessage());
699 }
700
701 assertNull(c.getString("a", null, "z"));
702 assertArrayEquals(new String[]{}, c.getStringList("a", null, "z"));
703 }
704
705 @Test
706 public void testParsedEmptyString() throws Exception {
707 Config c = parse("[a]\n"
708 + "x = 0\n"
709 + "y =\n");
710
711 assertEquals("0", c.getString("a", null, "x"));
712 assertEquals(0, c.getInt("a", null, "x", 1));
713
714 assertNull(c.getString("a", null, "y"));
715 assertArrayEquals(new String[]{null}, c.getStringList("a", null, "y"));
716 try {
717 c.getInt("a", null, "y", 1);
718 } catch (IllegalArgumentException e) {
719 assertEquals("Invalid integer value: a.y=", e.getMessage());
720 }
721
722 assertNull(c.getString("a", null, "z"));
723 assertArrayEquals(new String[]{}, c.getStringList("a", null, "z"));
724 }
725
726 @Test
727 public void testSetStringListWithEmptyValue() throws Exception {
728 Config c = new Config();
729 c.setStringList("a", null, "x", Arrays.asList(""));
730 assertArrayEquals(new String[]{""}, c.getStringList("a", null, "x"));
731 }
732
733 @Test
734 public void testEmptyValueAtEof() throws Exception {
735 String text = "[a]\nx =";
736 Config c = parse(text);
737 assertNull(c.getString("a", null, "x"));
738 assertArrayEquals(new String[]{null},
739 c.getStringList("a", null, "x"));
740 c = parse(text + "\n");
741 assertNull(c.getString("a", null, "x"));
742 assertArrayEquals(new String[]{null},
743 c.getStringList("a", null, "x"));
744 }
745
746 @Test
747 public void testReadMultipleValuesForName() throws ConfigInvalidException {
748 Config c = parse("[foo]\nbar=false\nbar=true\n");
749 assertTrue(c.getBoolean("foo", "bar", false));
750 }
751
752 @Test
753 public void testIncludeInvalidName() throws ConfigInvalidException {
754 expectedEx.expect(ConfigInvalidException.class);
755 expectedEx.expectMessage(JGitText.get().invalidLineInConfigFile);
756 parse("[include]\nbar\n");
757 }
758
759 @Test
760 public void testIncludeNoValue() throws ConfigInvalidException {
761 expectedEx.expect(ConfigInvalidException.class);
762 expectedEx.expectMessage(JGitText.get().invalidLineInConfigFile);
763 parse("[include]\npath\n");
764 }
765
766 @Test
767 public void testIncludeEmptyValue() throws ConfigInvalidException {
768 expectedEx.expect(ConfigInvalidException.class);
769 expectedEx.expectMessage(JGitText.get().invalidLineInConfigFile);
770 parse("[include]\npath=\n");
771 }
772
773 @Test
774 public void testIncludeValuePathNotFound() throws ConfigInvalidException {
775
776 String notFound = "/not/found";
777 Config parsed = parse("[include]\npath=" + notFound + "\n");
778 assertEquals(1, parsed.getSections().size());
779 assertEquals(notFound, parsed.getString("include", null, "path"));
780 }
781
782 @Test
783 public void testIncludeValuePathWithTilde() throws ConfigInvalidException {
784
785
786 String notSupported = "~/someFile";
787 Config parsed = parse("[include]\npath=" + notSupported + "\n");
788 assertEquals(1, parsed.getSections().size());
789 assertEquals(notSupported, parsed.getString("include", null, "path"));
790 }
791
792 @Test
793 public void testIncludeValuePathRelative() throws ConfigInvalidException {
794
795
796 String notSupported = "someRelativeFile";
797 Config parsed = parse("[include]\npath=" + notSupported + "\n");
798 assertEquals(1, parsed.getSections().size());
799 assertEquals(notSupported, parsed.getString("include", null, "path"));
800 }
801
802 @Test
803 public void testIncludeTooManyRecursions() throws IOException {
804 File config = tmp.newFile("config");
805 String include = "[include]\npath=" + pathToString(config) + "\n";
806 Files.write(config.toPath(), include.getBytes());
807 FileBasedConfig fbConfig = new FileBasedConfig(null, config,
808 FS.DETECTED);
809 try {
810 fbConfig.load();
811 fail();
812 } catch (ConfigInvalidException cie) {
813 for (Throwable t = cie; t != null; t = t.getCause()) {
814 if (t.getMessage()
815 .equals(JGitText.get().tooManyIncludeRecursions)) {
816 return;
817 }
818 }
819 fail("Expected to find expected exception message: "
820 + JGitText.get().tooManyIncludeRecursions);
821 }
822 }
823
824 @Test
825 public void testIncludeIsNoop() throws IOException, ConfigInvalidException {
826 File config = tmp.newFile("config");
827
828 String fooBar = "[foo]\nbar=true\n";
829 Files.write(config.toPath(), fooBar.getBytes());
830
831 Config parsed = parse("[include]\npath=" + pathToString(config) + "\n");
832 assertFalse(parsed.getBoolean("foo", "bar", false));
833 }
834
835 @Test
836 public void testIncludeCaseInsensitiveSection()
837 throws IOException, ConfigInvalidException {
838 File included = tmp.newFile("included");
839 String content = "[foo]\nbar=true\n";
840 Files.write(included.toPath(), content.getBytes());
841
842 File config = tmp.newFile("config");
843 content = "[Include]\npath=" + pathToString(included) + "\n";
844 Files.write(config.toPath(), content.getBytes());
845
846 FileBasedConfig fbConfig = new FileBasedConfig(null, config,
847 FS.DETECTED);
848 fbConfig.load();
849 assertTrue(fbConfig.getBoolean("foo", "bar", false));
850 }
851
852 @Test
853 public void testIncludeCaseInsensitiveKey()
854 throws IOException, ConfigInvalidException {
855 File included = tmp.newFile("included");
856 String content = "[foo]\nbar=true\n";
857 Files.write(included.toPath(), content.getBytes());
858
859 File config = tmp.newFile("config");
860 content = "[include]\nPath=" + pathToString(included) + "\n";
861 Files.write(config.toPath(), content.getBytes());
862
863 FileBasedConfig fbConfig = new FileBasedConfig(null, config,
864 FS.DETECTED);
865 fbConfig.load();
866 assertTrue(fbConfig.getBoolean("foo", "bar", false));
867 }
868
869 @Test
870 public void testIncludeExceptionContainsLine() {
871 try {
872 parse("[include]\npath=\n");
873 fail("Expected ConfigInvalidException");
874 } catch (ConfigInvalidException e) {
875 assertTrue(
876 "Expected to find the problem line in the exception message",
877 e.getMessage().contains("include.path"));
878 }
879 }
880
881 @Test
882 public void testIncludeExceptionContainsFile() throws IOException {
883 File included = tmp.newFile("included");
884 String includedPath = pathToString(included);
885 String content = "[include]\npath=\n";
886 Files.write(included.toPath(), content.getBytes());
887
888 File config = tmp.newFile("config");
889 String include = "[include]\npath=" + includedPath + "\n";
890 Files.write(config.toPath(), include.getBytes());
891 FileBasedConfig fbConfig = new FileBasedConfig(null, config,
892 FS.DETECTED);
893 try {
894 fbConfig.load();
895 fail("Expected ConfigInvalidException");
896 } catch (ConfigInvalidException e) {
897
898
899 for (Throwable t = e; t != null; t = t.getCause()) {
900 if (t.getMessage().contains(includedPath)) {
901 return;
902 }
903 }
904 fail("Expected to find the path in the exception message: "
905 + includedPath);
906 }
907 }
908
909 private static void assertReadLong(long exp) throws ConfigInvalidException {
910 assertReadLong(exp, String.valueOf(exp));
911 }
912
913 private static void assertReadLong(long exp, String act)
914 throws ConfigInvalidException {
915 final Config c = parse("[s]\na = " + act + "\n");
916 assertEquals(exp, c.getLong("s", null, "a", 0L));
917 }
918
919 private static Config parse(String content)
920 throws ConfigInvalidException {
921 return parse(content, null);
922 }
923
924 private static Config parse(String content, Config baseConfig)
925 throws ConfigInvalidException {
926 final Config c = new Config(baseConfig);
927 c.fromText(content);
928 return c;
929 }
930
931 @Test
932 public void testTimeUnit() throws ConfigInvalidException {
933 assertEquals(0, parseTime("0", NANOSECONDS));
934 assertEquals(2, parseTime("2ns", NANOSECONDS));
935 assertEquals(200, parseTime("200 nanoseconds", NANOSECONDS));
936
937 assertEquals(0, parseTime("0", MICROSECONDS));
938 assertEquals(2, parseTime("2us", MICROSECONDS));
939 assertEquals(2, parseTime("2000 nanoseconds", MICROSECONDS));
940 assertEquals(200, parseTime("200 microseconds", MICROSECONDS));
941
942 assertEquals(0, parseTime("0", MILLISECONDS));
943 assertEquals(2, parseTime("2ms", MILLISECONDS));
944 assertEquals(2, parseTime("2000microseconds", MILLISECONDS));
945 assertEquals(200, parseTime("200 milliseconds", MILLISECONDS));
946
947 assertEquals(0, parseTime("0s", SECONDS));
948 assertEquals(2, parseTime("2s", SECONDS));
949 assertEquals(231, parseTime("231sec", SECONDS));
950 assertEquals(1, parseTime("1second", SECONDS));
951 assertEquals(300, parseTime("300 seconds", SECONDS));
952
953 assertEquals(2, parseTime("2m", MINUTES));
954 assertEquals(2, parseTime("2min", MINUTES));
955 assertEquals(1, parseTime("1 minute", MINUTES));
956 assertEquals(10, parseTime("10 minutes", MINUTES));
957
958 assertEquals(5, parseTime("5h", HOURS));
959 assertEquals(5, parseTime("5hr", HOURS));
960 assertEquals(1, parseTime("1hour", HOURS));
961 assertEquals(48, parseTime("48hours", HOURS));
962
963 assertEquals(5, parseTime("5 h", HOURS));
964 assertEquals(5, parseTime("5 hr", HOURS));
965 assertEquals(1, parseTime("1 hour", HOURS));
966 assertEquals(48, parseTime("48 hours", HOURS));
967 assertEquals(48, parseTime("48 \t \r hours", HOURS));
968
969 assertEquals(4, parseTime("4d", DAYS));
970 assertEquals(1, parseTime("1day", DAYS));
971 assertEquals(14, parseTime("14days", DAYS));
972
973 assertEquals(7, parseTime("1w", DAYS));
974 assertEquals(7, parseTime("1week", DAYS));
975 assertEquals(14, parseTime("2w", DAYS));
976 assertEquals(14, parseTime("2weeks", DAYS));
977
978 assertEquals(30, parseTime("1mon", DAYS));
979 assertEquals(30, parseTime("1month", DAYS));
980 assertEquals(60, parseTime("2mon", DAYS));
981 assertEquals(60, parseTime("2months", DAYS));
982
983 assertEquals(365, parseTime("1y", DAYS));
984 assertEquals(365, parseTime("1year", DAYS));
985 assertEquals(365 * 2, parseTime("2years", DAYS));
986 }
987
988 private long parseTime(String value, TimeUnit unit)
989 throws ConfigInvalidException {
990 Config c = parse("[a]\na=" + value + "\n");
991 return c.getTimeUnit("a", null, "a", 0, unit);
992 }
993
994 @Test
995 public void testTimeUnitDefaultValue() throws ConfigInvalidException {
996
997 assertEquals(20, parse("[a]\na=0\n").getTimeUnit("a", null, "b", 20,
998 MILLISECONDS));
999
1000 assertEquals(20, parse("[a]\na=\" \"\n").getTimeUnit("a", null, "a", 20,
1001 MILLISECONDS));
1002
1003
1004 assertEquals(20, parse("[a]\na=test\n").getTimeUnit("a", null, "a", 20,
1005 MILLISECONDS));
1006 }
1007
1008 @Test
1009 public void testTimeUnitInvalid() throws ConfigInvalidException {
1010 expectedEx.expect(IllegalArgumentException.class);
1011 expectedEx
1012 .expectMessage("Invalid time unit value: a.a=1 monttthhh");
1013 parseTime("1 monttthhh", DAYS);
1014 }
1015
1016 @Test
1017 public void testTimeUnitInvalidWithSection() throws ConfigInvalidException {
1018 Config c = parse("[a \"b\"]\na=1 monttthhh\n");
1019 expectedEx.expect(IllegalArgumentException.class);
1020 expectedEx.expectMessage("Invalid time unit value: a.b.a=1 monttthhh");
1021 c.getTimeUnit("a", "b", "a", 0, DAYS);
1022 }
1023
1024 @Test
1025 public void testTimeUnitNegative() throws ConfigInvalidException {
1026 expectedEx.expect(IllegalArgumentException.class);
1027 parseTime("-1", MILLISECONDS);
1028 }
1029
1030 @Test
1031 public void testEscapeSpacesOnly() throws ConfigInvalidException {
1032
1033 assertEquals("", Config.escapeValue(""));
1034
1035 assertValueRoundTrip(" ", "\" \"");
1036 assertValueRoundTrip(" ", "\" \"");
1037 }
1038
1039 @Test
1040 public void testEscapeLeadingSpace() throws ConfigInvalidException {
1041 assertValueRoundTrip("x", "x");
1042 assertValueRoundTrip(" x", "\" x\"");
1043 assertValueRoundTrip(" x", "\" x\"");
1044 }
1045
1046 @Test
1047 public void testEscapeTrailingSpace() throws ConfigInvalidException {
1048 assertValueRoundTrip("x", "x");
1049 assertValueRoundTrip("x ","\"x \"");
1050 assertValueRoundTrip("x ","\"x \"");
1051 }
1052
1053 @Test
1054 public void testEscapeLeadingAndTrailingSpace()
1055 throws ConfigInvalidException {
1056 assertValueRoundTrip(" x ", "\" x \"");
1057 assertValueRoundTrip(" x ", "\" x \"");
1058 assertValueRoundTrip(" x ", "\" x \"");
1059 assertValueRoundTrip(" x ", "\" x \"");
1060 }
1061
1062 @Test
1063 public void testNoEscapeInternalSpaces() throws ConfigInvalidException {
1064 assertValueRoundTrip("x y");
1065 assertValueRoundTrip("x y");
1066 assertValueRoundTrip("x y");
1067 assertValueRoundTrip("x y z");
1068 assertValueRoundTrip("x " + WS + " y");
1069 }
1070
1071 @Test
1072 public void testNoEscapeSpecialCharacters() throws ConfigInvalidException {
1073 assertValueRoundTrip("x\\y", "x\\\\y");
1074 assertValueRoundTrip("x\"y", "x\\\"y");
1075 assertValueRoundTrip("x\ny", "x\\ny");
1076 assertValueRoundTrip("x\ty", "x\\ty");
1077 assertValueRoundTrip("x\by", "x\\by");
1078 }
1079
1080 @Test
1081 public void testParseLiteralBackspace() throws ConfigInvalidException {
1082
1083
1084 assertEquals("x\by", parseEscapedValue("x\by"));
1085 }
1086
1087 @Test
1088 public void testEscapeCommentCharacters() throws ConfigInvalidException {
1089 assertValueRoundTrip("x#y", "\"x#y\"");
1090 assertValueRoundTrip("x;y", "\"x;y\"");
1091 }
1092
1093 @Test
1094 public void testEscapeValueInvalidCharacters() {
1095 assertIllegalArgumentException(() -> Config.escapeSubsection("x\0y"));
1096 }
1097
1098 @Test
1099 public void testEscapeSubsectionInvalidCharacters() {
1100 assertIllegalArgumentException(() -> Config.escapeSubsection("x\ny"));
1101 assertIllegalArgumentException(() -> Config.escapeSubsection("x\0y"));
1102 }
1103
1104 @Test
1105 public void testParseMultipleQuotedRegions() throws ConfigInvalidException {
1106 assertEquals("b a z; \n", parseEscapedValue("b\" a\"\" z; \\n\""));
1107 }
1108
1109 @Test
1110 public void testParseComments() throws ConfigInvalidException {
1111 assertEquals("baz", parseEscapedValue("baz; comment"));
1112 assertEquals("baz", parseEscapedValue("baz# comment"));
1113 assertEquals("baz", parseEscapedValue("baz ; comment"));
1114 assertEquals("baz", parseEscapedValue("baz # comment"));
1115
1116 assertEquals("baz", parseEscapedValue("baz ; comment"));
1117 assertEquals("baz", parseEscapedValue("baz # comment"));
1118 assertEquals("baz", parseEscapedValue("baz " + WS + " ; comment"));
1119 assertEquals("baz", parseEscapedValue("baz " + WS + " # comment"));
1120
1121 assertEquals("baz ", parseEscapedValue("\"baz \"; comment"));
1122 assertEquals("baz ", parseEscapedValue("\"baz \"# comment"));
1123 assertEquals("baz ", parseEscapedValue("\"baz \" ; comment"));
1124 assertEquals("baz ", parseEscapedValue("\"baz \" # comment"));
1125 }
1126
1127 @Test
1128 public void testEscapeSubsection() throws ConfigInvalidException {
1129 assertSubsectionRoundTrip("", "\"\"");
1130 assertSubsectionRoundTrip("x", "\"x\"");
1131 assertSubsectionRoundTrip(" x", "\" x\"");
1132 assertSubsectionRoundTrip("x ", "\"x \"");
1133 assertSubsectionRoundTrip(" x ", "\" x \"");
1134 assertSubsectionRoundTrip("x y", "\"x y\"");
1135 assertSubsectionRoundTrip("x y", "\"x y\"");
1136 assertSubsectionRoundTrip("x\\y", "\"x\\\\y\"");
1137 assertSubsectionRoundTrip("x\"y", "\"x\\\"y\"");
1138
1139
1140 assertSubsectionRoundTrip("x\by", "\"x\by\"");
1141 assertSubsectionRoundTrip("x\ty", "\"x\ty\"");
1142 }
1143
1144 @Test
1145 public void testParseInvalidValues() {
1146 assertInvalidValue(JGitText.get().newlineInQuotesNotAllowed, "x\"\n\"y");
1147 assertInvalidValue(JGitText.get().endOfFileInEscape, "x\\");
1148 assertInvalidValue(
1149 MessageFormat.format(JGitText.get().badEscape, 'q'), "x\\q");
1150 }
1151
1152 @Test
1153 public void testParseInvalidSubsections() {
1154 assertInvalidSubsection(
1155 JGitText.get().newlineInQuotesNotAllowed, "\"x\ny\"");
1156 }
1157
1158 @Test
1159 public void testDropBackslashFromInvalidEscapeSequenceInSubsectionName()
1160 throws ConfigInvalidException {
1161 assertEquals("x0", parseEscapedSubsection("\"x\\0\""));
1162 assertEquals("xq", parseEscapedSubsection("\"x\\q\""));
1163
1164 assertEquals("xb", parseEscapedSubsection("\"x\\b\""));
1165 assertEquals("xn", parseEscapedSubsection("\"x\\n\""));
1166 assertEquals("xt", parseEscapedSubsection("\"x\\t\""));
1167 }
1168
1169 private static void assertValueRoundTrip(String value)
1170 throws ConfigInvalidException {
1171 assertValueRoundTrip(value, value);
1172 }
1173
1174 private static void assertValueRoundTrip(String value, String expectedEscaped)
1175 throws ConfigInvalidException {
1176 String escaped = Config.escapeValue(value);
1177 assertEquals("escape failed;", expectedEscaped, escaped);
1178 assertEquals("parse failed;", value, parseEscapedValue(escaped));
1179 }
1180
1181 private static String parseEscapedValue(String escapedValue)
1182 throws ConfigInvalidException {
1183 String text = "[foo]\nbar=" + escapedValue;
1184 Config c = parse(text);
1185 return c.getString("foo", null, "bar");
1186 }
1187
1188 private static void assertInvalidValue(String expectedMessage,
1189 String escapedValue) {
1190 try {
1191 parseEscapedValue(escapedValue);
1192 fail("expected ConfigInvalidException");
1193 } catch (ConfigInvalidException e) {
1194 assertEquals(expectedMessage, e.getMessage());
1195 }
1196 }
1197
1198 private static void assertSubsectionRoundTrip(String subsection,
1199 String expectedEscaped) throws ConfigInvalidException {
1200 String escaped = Config.escapeSubsection(subsection);
1201 assertEquals("escape failed;", expectedEscaped, escaped);
1202 assertEquals("parse failed;", subsection, parseEscapedSubsection(escaped));
1203 }
1204
1205 private static String parseEscapedSubsection(String escapedSubsection)
1206 throws ConfigInvalidException {
1207 String text = "[foo " + escapedSubsection + "]\nbar = value";
1208 Config c = parse(text);
1209 Set<String> subsections = c.getSubsections("foo");
1210 assertEquals("only one section", 1, subsections.size());
1211 return subsections.iterator().next();
1212 }
1213
1214 private static void assertIllegalArgumentException(Runnable r) {
1215 try {
1216 r.run();
1217 fail("expected IllegalArgumentException");
1218 } catch (IllegalArgumentException e) {
1219
1220 }
1221 }
1222
1223 private static void assertInvalidSubsection(String expectedMessage,
1224 String escapedSubsection) {
1225 try {
1226 parseEscapedSubsection(escapedSubsection);
1227 fail("expected ConfigInvalidException");
1228 } catch (ConfigInvalidException e) {
1229 assertEquals(expectedMessage, e.getMessage());
1230 }
1231 }
1232 }