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