Skip to content

Commit

Permalink
Handle merge references correctly
Browse files Browse the repository at this point in the history
  • Loading branch information
Lucas Michon authored and otsenkun committed May 18, 2021
1 parent 9bc7f1a commit 277264a
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ namespace NetEscapades.Configuration.Yaml
internal class YamlConfigurationFileParser
{
private readonly IDictionary<string, string> _data = new SortedDictionary<string, string>(StringComparer.OrdinalIgnoreCase);
private readonly HashSet<string> _mergedKeys = new HashSet<string>();
private readonly Stack<string> _context = new Stack<string>();
private string _currentPath;

Expand Down Expand Up @@ -61,7 +62,13 @@ private void VisitYamlScalarNode(string context, YamlScalarNode yamlValue)
EnterContext(context);
var currentKey = _currentPath;

if (_data.ContainsKey(currentKey))
if (currentKey.Contains("<<"))
{
currentKey = currentKey.Replace("<<:", "");
_mergedKeys.Add(currentKey);
}

if (_data.ContainsKey(currentKey) && !_mergedKeys.Contains(currentKey))
{
throw new FormatException(Resources.FormatError_KeyIsDuplicated(currentKey));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,78 @@ public void ReturnEmptyConfigWhenFileIsEmpty()
Assert.Empty(config.AsEnumerable());
}

[Fact]
public void ShouldMergeKeysInsideAnObject()
{
var yaml = @"---
defaults: &defaults
A: 1
B: 2
D:
E: 78
F: 79
mapping:
<< : *defaults
A: 23
C: 99
D:
E: 56
G:
- 1
- 2";

var yamlConfigSrc = LoadProvider(yaml);

Assert.Equal("23", yamlConfigSrc.Get("mapping:A"));
Assert.Equal("2", yamlConfigSrc.Get("mapping:B"));
Assert.Equal("99", yamlConfigSrc.Get("mapping:C"));
Assert.Equal("56", yamlConfigSrc.Get("mapping:D:E"));
Assert.Equal("79", yamlConfigSrc.Get("mapping:D:F"));
Assert.Equal("1", yamlConfigSrc.Get("mapping:D:G:0"));
Assert.Equal("2", yamlConfigSrc.Get("mapping:D:G:1"));
}

[Fact]
public void ShouldMergeKeysInsideASequence()
{
var yaml = @"---
defaults: &defaults
A: 1
B: 2
D:
E: 78
F: 79
mapping:
- <<: *defaults
A: 23
C: 99
- A: 2
B: 3
D:
E: 4
F: 5
- <<: *defaults";

var yamlConfigSrc = LoadProvider(yaml);

Assert.Equal("23", yamlConfigSrc.Get("mapping:0:A"));
Assert.Equal("2", yamlConfigSrc.Get("mapping:0:B"));
Assert.Equal("99", yamlConfigSrc.Get("mapping:0:C"));
Assert.Equal("78", yamlConfigSrc.Get("mapping:0:D:E"));
Assert.Equal("79", yamlConfigSrc.Get("mapping:0:D:F"));

Assert.Equal("2", yamlConfigSrc.Get("mapping:1:A"));
Assert.Equal("3", yamlConfigSrc.Get("mapping:1:B"));
Assert.Throws<InvalidOperationException>(() => yamlConfigSrc.Get("mapping:1:C"));
Assert.Equal("4", yamlConfigSrc.Get("mapping:1:D:E"));
Assert.Equal("5", yamlConfigSrc.Get("mapping:1:D:F"));

Assert.Equal("1", yamlConfigSrc.Get("mapping:2:A"));
Assert.Equal("2", yamlConfigSrc.Get("mapping:2:B"));
Assert.Equal("78", yamlConfigSrc.Get("mapping:2:D:E"));
Assert.Equal("79", yamlConfigSrc.Get("mapping:2:D:F"));
}

[Fact]
public void ThrowExceptionWhenUnexpectedFirstCharacterInScalarValue()
{
Expand Down

0 comments on commit 277264a

Please sign in to comment.