ProvidenceConfigParser { @Nonnull <M extends PMessage<M, F>, F extends PField> Pair<M, Set<String>> parseConfig(@Nonnull Path configFile, @Nullable M parent) throws ProvidenceConfigException { try { configFile = canonicalFileLocation(configFile); } catch (IOException e) { throw new ProvidenceConfigException(e, "Unable to resolve config file " + configFile) .setFile(configFile.getFileName() .toString()); } Pair<M, Set<String>> result = checkAndParseInternal(configFile, parent); if (result == null) { throw new ProvidenceConfigException("No config: " + configFile.toString()) .setFile(configFile.getFileName() .toString()); } return result; } ProvidenceConfigParser(TypeRegistry registry, boolean strict);   }
@Test public void testParseWithUnknownInclude() throws IOException { copyResourceTo("/net/morimekta/providence/config/files/unknown.cfg", temp.getRoot()); File file = copyResourceTo("/net/morimekta/providence/config/files/unknown_include.cfg", temp.getRoot()); Pair<Database, Set<String>> cfg = parser.parseConfig(file.toPath(), null); assertEquals("{\n" + " uri = \"jdbc:h2:localhost:mem\"\n" + " driver = \"org.h2.Driver\"\n" + "}", debugString(cfg.first)); file = copyResourceTo("/net/morimekta/providence/config/files/unknown_field.cfg", temp.getRoot()); cfg = parser.parseConfig(file.toPath(), null); assertEquals("{\n" + " uri = \"jdbc:h2:localhost:mem\"\n" + " driver = \"org.h2.Driver\"\n" + "}", debugString(cfg.first)); file = copyResourceTo("/net/morimekta/providence/config/files/unknown_enum_value.cfg", temp.getRoot()); cfg = parser.parseConfig(file.toPath(), null); assertEquals("{\n" + " uri = \"jdbc:h2:localhost:mem\"\n" + " driver = \"org.h2.Driver\"\n" + "}", debugString(cfg.first)); }
@Test public void testParseWithUnknown_strict() throws IOException { copyResourceTo("/net/morimekta/providence/config/files/unknown.cfg", temp.getRoot()); File file = copyResourceTo("/net/morimekta/providence/config/files/unknown_include.cfg", temp.getRoot()); ProvidenceConfigParser config = new ProvidenceConfigParser(registry, true); try { config.parseConfig(file.toPath(), null); fail("no exception"); } catch (ProvidenceConfigException e) { assertEquals("Unknown declared type: unknown.OtherConfig", e.getMessage()); } file = copyResourceTo("/net/morimekta/providence/config/files/unknown_field.cfg", temp.getRoot()); try { config.parseConfig(file.toPath(), null); fail("no exception"); } catch (ProvidenceConfigException e) { assertEquals("No such field unknown_field in config.Database", e.getMessage()); } file = copyResourceTo("/net/morimekta/providence/config/files/unknown_enum_value.cfg", temp.getRoot()); try { config.parseConfig(file.toPath(), null); fail("no exception"); } catch (ProvidenceConfigException e) { assertEquals("No such enum value 'LAST' for config.Value.", e.getMessage()); } file = copyResourceTo("/net/morimekta/providence/config/files/unknown_enum_value2.cfg", temp.getRoot()); try { config.parseConfig(file.toPath(), null); fail("no exception"); } catch (ProvidenceConfigException e) { assertEquals("No such enum value 'second' for config.Value, did you mean 'SECOND'?", e.getMessage()); } }
@Test public void testCircularIncludes() throws IOException { File a = temp.newFile("a.cfg"); File b = temp.newFile("b.cfg"); File c = temp.newFile("c.cfg"); writeContentTo("include \"b.cfg\" as a\n" + "config.Database {}\n", a); writeContentTo("include \"c.cfg\" as a\n" + "config.Database {}\n", b); writeContentTo("include \"a.cfg\" as a\n" + "config.Database {}\n", c); ProvidenceConfigParser config = new ProvidenceConfigParser(registry, false); try { config.parseConfig(a.toPath(), null); fail("no exception on circular deps"); } catch (SerializerException e) { assertEquals("Circular includes detected: a.cfg -> b.cfg -> c.cfg -> a.cfg", e.getMessage()); } }
@Test public void testIncludeNoSuchFile() throws IOException { File a = temp.newFile("a.cfg"); writeContentTo("include \"b.cfg\" as a\n" + "config.Database {}\n", a); ProvidenceConfigParser config = new ProvidenceConfigParser(registry, false); try { config.parseConfig(a.toPath(), null); fail("no exception on circular deps"); } catch (SerializerException e) { assertEquals("Included file \"b.cfg\" not found.", e.getMessage()); } }
@Test public void testInternalReference() throws IOException { File a = writeContentTo( "config.RefMerge {\n" + " ref1 & first = {\n" + " bool_value & boo = false\n" + " msg_value & db {\n" + " driver = \"Driver\"\n" + " }\n" + " }\n" + " ref1_1 = first {\n" + " i16_value = 12345\n" + " msg_value & db2 = db {\n" + " uri = \"someuri\"\n" + " }\n" + " }\n" + " ref2 {\n" + " bool_value = boo" + " msg_value = db2\n" + " }\n" + "}\n", temp.newFile("a.cfg")); try { ProvidenceConfigParser config = new ProvidenceConfigParser(registry, false); RefMerge merged = config.parseConfig(a.toPath(), (RefMerge) null).first; assertThat(debugString(merged), is( "{\n" + " ref1 = {\n" + " bool_value = false\n" + " msg_value = {\n" + " driver = \"Driver\"\n" + " }\n" + " }\n" + " ref1_1 = {\n" + " bool_value = false\n" + " i16_value = 12345\n" + " msg_value = {\n" + " uri = \"someuri\"\n" + " driver = \"Driver\"\n" + " }\n" + " }\n" + " ref2 = {\n" + " bool_value = false\n" + " msg_value = {\n" + " uri = \"someuri\"\n" + " driver = \"Driver\"\n" + " }\n" + " }\n" + "}")); } catch (ProvidenceConfigException e) { System.err.println(e.asString()); throw e; } }