Skip to content

Commit

Permalink
Feat/117 empty files (#121)
Browse files Browse the repository at this point in the history
* feat: all loaders support empty configs. Will return an empty map. #117

* test: Integration tests for empty sources.
  • Loading branch information
credmond-git authored Oct 15, 2023
1 parent 4939bcd commit 9768add
Show file tree
Hide file tree
Showing 10 changed files with 152 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import org.github.gestalt.config.lexer.PathLexer;
import org.github.gestalt.config.lexer.SentenceLexer;
import org.github.gestalt.config.node.ConfigNode;
import org.github.gestalt.config.node.MapNode;
import org.github.gestalt.config.parser.ConfigParser;
import org.github.gestalt.config.parser.MapConfigParser;
import org.github.gestalt.config.source.ConfigSource;
Expand All @@ -15,6 +16,7 @@

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
* Loads Environment Variables from EnvironmentConfigSource.
Expand Down Expand Up @@ -64,6 +66,10 @@ public ValidateOf<List<ConfigNodeContainer>> loadSource(ConfigSource source) thr
throw new GestaltException("Config source: " + source.name() + " does not have a list to load.");
}

if (configs.isEmpty()) {
return ValidateOf.valid(List.of(new ConfigNodeContainer(new MapNode(Map.of()), source)));
}

ValidateOf<ConfigNode> loadedNode = ConfigCompiler.analyze(source.failOnErrors(), lexer, parser, configs);

List<ValidationError> errors = new ArrayList<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import org.github.gestalt.config.lexer.PathLexer;
import org.github.gestalt.config.lexer.SentenceLexer;
import org.github.gestalt.config.node.ConfigNode;
import org.github.gestalt.config.node.MapNode;
import org.github.gestalt.config.parser.ConfigParser;
import org.github.gestalt.config.parser.MapConfigParser;
import org.github.gestalt.config.source.ConfigSource;
Expand All @@ -15,6 +16,7 @@

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
* Loads an in memory map from MapConfigSource.
Expand Down Expand Up @@ -63,6 +65,10 @@ public ValidateOf<List<ConfigNodeContainer>> loadSource(ConfigSource source) thr
throw new GestaltException("Config source: " + source.name() + " does not have a list to load.");
}

if (configs.isEmpty()) {
return ValidateOf.valid(List.of(new ConfigNodeContainer(new MapNode(Map.of()), source)));
}

ValidateOf<ConfigNode> loadedNode = ConfigCompiler.analyze(source.failOnErrors(), lexer, parser, configs);

List<ValidationError> errors = new ArrayList<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import org.github.gestalt.config.lexer.PathLexer;
import org.github.gestalt.config.lexer.SentenceLexer;
import org.github.gestalt.config.node.ConfigNode;
import org.github.gestalt.config.node.MapNode;
import org.github.gestalt.config.parser.ConfigParser;
import org.github.gestalt.config.parser.MapConfigParser;
import org.github.gestalt.config.source.ConfigSource;
Expand All @@ -17,6 +18,7 @@
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.stream.Collectors;

Expand Down Expand Up @@ -81,6 +83,10 @@ public ValidateOf<List<ConfigNodeContainer>> loadSource(ConfigSource source) thr
throw new GestaltException("Config source: " + source.name() + " does not have a stream to load.");
}

if (properties.isEmpty()) {
return ValidateOf.valid(List.of(new ConfigNodeContainer(new MapNode(Map.of()), source)));
}

List<Pair<String, String>> configs = properties.entrySet()
.stream()
.map(prop -> new Pair<>((String) prop.getKey(), (String) prop.getValue()))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,11 @@
import org.github.gestalt.config.reflect.TypeCapture;
import org.github.gestalt.config.reload.CoreReloadListener;
import org.github.gestalt.config.reload.FileChangeReloadStrategy;
import org.github.gestalt.config.reload.ManualConfigReloadStrategy;
import org.github.gestalt.config.source.*;
import org.github.gestalt.config.tag.Tags;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;

import java.io.File;
Expand Down Expand Up @@ -81,7 +81,7 @@ public void integrationTestProxyPassThrough() throws GestaltException {

//to run this test it must be run as an administrator.
@Test
@Disabled
//@Disabled
public void integrationTestReloadFile() throws GestaltException, IOException, InterruptedException {
Map<String, String> configs = new HashMap<>();
configs.put("db.hosts[0].password", "1234");
Expand All @@ -108,6 +108,7 @@ public void integrationTestReloadFile() throws GestaltException, IOException, In
.addSource(new MapConfigSource(configs))
.addReloadStrategy(new FileChangeReloadStrategy(devFileSource))
.addCoreReloadListener(reloadListener)
.setTreatNullValuesInClassAsErrors(false)
.build();

gestalt.loadConfigs();
Expand Down Expand Up @@ -232,6 +233,64 @@ public void integrationTestReloadFile() throws GestaltException, IOException, In
Assertions.assertEquals("jdbc:postgresql://dev.host.name3:5432/mydb2", hosts.get(2).url);
}

@Test
public void integrationTestEmpty() throws GestaltException {
Map<String, String> configs = new HashMap<>();
configs.put("db.hosts[0].password", "1234");
configs.put("db.hosts[1].password", "5678");
configs.put("db.hosts[2].password", "9012");

String fileURL = "https://raw.githubusercontent.com/gestalt-config/gestalt/main/gestalt-core/src/test/resources/default.properties";

GestaltBuilder builder = new GestaltBuilder();
Gestalt gestalt = builder
.addSource(new URLConfigSource(fileURL))
.addSource(new ClassPathConfigSource("dev.properties"))
.addSource(new ClassPathConfigSource("empty.properties"))
.addSource(new MapConfigSource(configs))
.addSource(new StringConfigSource("db.idleTimeout=123", "properties"))
.addSource(new StringConfigSource("", "properties"))
.setTreatNullValuesInClassAsErrors(false)
.build();

gestalt.loadConfigs();

validateResults(gestalt);
}

@Test
public void integrationTestEmptyReload() throws GestaltException {
Map<String, String> configs = new HashMap<>();
configs.put("db.hosts[0].password", "1234");
configs.put("db.hosts[1].password", "5678");
configs.put("db.hosts[2].password", "9012");

String fileURL = "https://raw.githubusercontent.com/gestalt-config/gestalt/main/gestalt-core/src/test/resources/default.properties";

ConfigSource emptyString = new StringConfigSource("", "properties");
ManualConfigReloadStrategy reloadStrategy = new ManualConfigReloadStrategy(emptyString);

GestaltBuilder builder = new GestaltBuilder();
Gestalt gestalt = builder
.addSource(new URLConfigSource(fileURL))
.addSource(new ClassPathConfigSource("dev.properties"))
.addSource(new ClassPathConfigSource("empty.properties"))
.addSource(new MapConfigSource(configs))
.addSource(new StringConfigSource("db.idleTimeout=123", "properties"))
.addSource(emptyString)
.addReloadStrategy(reloadStrategy)
.setTreatNullValuesInClassAsErrors(false)
.build();

gestalt.loadConfigs();

validateResults(gestalt);

reloadStrategy.reload();

validateResults(gestalt);
}

@Test
public void integrationTestEnvVars() throws GestaltException {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -351,4 +351,20 @@ void loadSourceBadSource() throws GestaltException {
Assertions.assertEquals("Config source: String format: conf does not have a list to load.", e.getMessage());
}
}

@Test
void loadSourceEmpty() throws GestaltException {

MapConfigSource source = new MapConfigSource(Map.of());

MapConfigLoader mapConfigLoader = new MapConfigLoader();

ValidateOf<List<ConfigNodeContainer>> resultContainer = mapConfigLoader.loadSource(source);

Assertions.assertFalse(resultContainer.hasErrors());
Assertions.assertTrue(resultContainer.hasResults());

ConfigNode result = resultContainer.results().get(0).getConfigNode();
Assertions.assertEquals(0, result.size());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import org.github.gestalt.config.parser.ConfigParser;
import org.github.gestalt.config.source.ConfigSource;
import org.github.gestalt.config.source.MapConfigSource;
import org.github.gestalt.config.source.StringConfigSource;
import org.github.gestalt.config.tag.Tags;
import org.github.gestalt.config.token.ObjectToken;
import org.github.gestalt.config.token.Token;
Expand Down Expand Up @@ -367,4 +368,20 @@ void loadSourceBadSource() {
Assertions.assertEquals("Config source: mapConfig does not have a stream to load.", e.getMessage());
}
}

@Test
void loadSourceEmpty() throws GestaltException {

StringConfigSource source = new StringConfigSource("", "properties");

PropertyLoader propertyLoader = new PropertyLoader();

ValidateOf<List<ConfigNodeContainer>> resultContainer = propertyLoader.loadSource(source);

Assertions.assertFalse(resultContainer.hasErrors());
Assertions.assertTrue(resultContainer.hasResults());

ConfigNode result = resultContainer.results().get(0).getConfigNode();
Assertions.assertEquals(0, result.size());
}
}
Empty file.
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,23 @@ void loadSourceEmptyValue() throws GestaltException {
}
}

@Test
void loadSourceEmpty() throws GestaltException {

StringConfigSource source = new StringConfigSource("", "toml");

TomlLoader tomlLoader = new TomlLoader();

ValidateOf<List<ConfigNodeContainer>> resultContainer = tomlLoader.loadSource(source);

Assertions.assertFalse(resultContainer.hasErrors());
Assertions.assertTrue(resultContainer.hasResults());

ConfigNode result = resultContainer.results().get(0).getConfigNode();

Assertions.assertEquals(0, result.size());
}

@Test
void loadSourceBadInput() throws GestaltException {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
import java.io.InputStream;
import java.util.*;

import static com.fasterxml.jackson.databind.node.JsonNodeType.MISSING;

/**
* Loads from a yaml files from multiple sources, such as a file.
*
Expand Down Expand Up @@ -74,6 +76,10 @@ public ValidateOf<List<ConfigNodeContainer>> loadSource(ConfigSource source) thr
throw new GestaltException("Exception loading source: " + source.name() + " no yaml found");
}

if (jsonNode.getNodeType() == MISSING) {
return ValidateOf.valid(List.of(new ConfigNodeContainer(new MapNode(Map.of()), source)));
}

ValidateOf<ConfigNode> node = buildConfigTree("", jsonNode);

if (node.hasResults()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -209,4 +209,21 @@ void loadSourceBadSource() {
Assertions.assertEquals("Config source: mapConfig does not have a stream to load.", e.getMessage());
}
}

@Test
void loadSourceEmptySource() throws GestaltException {

StringConfigSource source = new StringConfigSource("", "yml");

YamlLoader yamlLoader = new YamlLoader();

ValidateOf<List<ConfigNodeContainer>> resultContainer = yamlLoader.loadSource(source);

Assertions.assertFalse(resultContainer.hasErrors());
Assertions.assertTrue(resultContainer.hasResults());

ConfigNode result = resultContainer.results().get(0).getConfigNode();

Assertions.assertEquals(0, result.size());
}
}

0 comments on commit 9768add

Please sign in to comment.