Skip to content

Commit

Permalink
Merge branch 'master' into 65-CollectionAliases
Browse files Browse the repository at this point in the history
  • Loading branch information
aloneguid authored Nov 4, 2022
2 parents 5f29631 + adf833f commit bb71920
Show file tree
Hide file tree
Showing 12 changed files with 166 additions and 32 deletions.
6 changes: 4 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
name: Release

env:
v: '5.1.2'
v: '5.1.4'
av: '5.0.0'
pv: '5.1.2'
pv: '5.1.4'

on:
push:
Expand All @@ -15,6 +15,7 @@ on:
jobs:
build:

# we need Windows to build for classic .NET Framework
runs-on: windows-latest

steps:
Expand Down Expand Up @@ -44,6 +45,7 @@ jobs:
needs: [build]
if: github.ref == 'refs/heads/master'
runs-on: ubuntu-latest
environment: nuget
steps:
- name: Download a Build Artifact
uses: actions/download-artifact@v2
Expand Down
4 changes: 3 additions & 1 deletion docs/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# Config.Net [![NuGet](https://img.shields.io/nuget/v/Config.Net.svg)](https://www.nuget.org/packages/Config.Net) [![open collective backers and sponsors](https://img.shields.io/opencollective/all/config.svg)](https://opencollective.com/config) [![Nuget](https://img.shields.io/nuget/dt/Config.Net)](https://www.nuget.org/packages/Config.Net)
# Config.Net

[![NuGet](https://img.shields.io/nuget/v/Config.Net.svg)](https://www.nuget.org/packages/Config.Net) ![Open Collective backers and sponsors](https://img.shields.io/opencollective/all/config?label=opencollective%20sponsors) ![GitHub Sponsors](https://img.shields.io/github/sponsors/aloneguid?label=github%20sponsors) [![Nuget](https://img.shields.io/nuget/dt/Config.Net)](https://www.nuget.org/packages/Config.Net)

A comprehensive, easy to use and powerful .NET configuration library, fully covered with unit tests and tested in the wild on thousands of servers and applications.

Expand Down
43 changes: 31 additions & 12 deletions src/Config.Net.Tests/Stores/Formats/IniKeyValueTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,15 @@ namespace Config.Net.Tests.Stores.Formats
public class IniKeyValueTest
{
[Theory]
[InlineData("key=value", "key", "value")]
[InlineData("key=value;123", "key", "value")]
[InlineData("key==value", "key", "=value")]
[InlineData("key=value;value;value", "key", "value;value")]
[InlineData("key=value=value;value", "key", "value=value")]
public void FromLine_ParsingInlineComments(string input, string expectedKey, string expectedValue)
[InlineData("key=value", "key", "value", null)]
[InlineData("key=value;123", "key", "value", "123")]
[InlineData("key==value", "key", "=value", null)]
[InlineData("key=value;value;value", "key", "value;value", "value")]
[InlineData("key=value=value;value", "key", "value=value", "value")]
[InlineData("key=value;rest;", "key", "value;rest", "")]
public void FromLine_ParsingInlineComments(string input, string expectedKey, string expectedValue, string expectedComment)
{
IniKeyValue kv = IniKeyValue.FromLine(input, true);

Assert.Equal(expectedKey, kv.Key);
Assert.Equal(expectedValue, kv.Value);
FromLine_DoTest(true, false, input, expectedKey, expectedValue, expectedComment);
}

[Theory]
Expand All @@ -27,11 +25,32 @@ public void FromLine_ParsingInlineComments(string input, string expectedKey, str
[InlineData("key=value=value;value", "key", "value=value;value")]
public void FromLine_IgnoringInlineComments(string input, string expectedKey, string expectedValue)
{
IniKeyValue kv = IniKeyValue.FromLine(input, false);
FromLine_DoTest(false, false, input, expectedKey, expectedValue, null);
}

[Theory]
[InlineData(true, @"k1\r\nk2=v1\r\nv2;c1\r\nc2", "k1\r\nk2", "v1\r\nv2", "c1\r\nc2")]
[InlineData(false, @"k1\r\nk2=v1\r\nv2;c1\r\nc2", @"k1\r\nk2", @"v1\r\nv2", @"c1\r\nc2")]
public void FromLine_UnescapeNewLines(bool unescapeNewLines, string input, string expectedKey, string expectedValue, string expectedComment)
{
FromLine_DoTest(true, unescapeNewLines, input, expectedKey, expectedValue, expectedComment);
}

private static void FromLine_DoTest(bool parseInlineComments, bool unescapeNewLines, string input, string expectedKey, string expectedValue, string expectedComment)
{
IniKeyValue kv = IniKeyValue.FromLine(input, parseInlineComments, unescapeNewLines);

Assert.Equal(expectedKey, kv.Key);
Assert.Equal(expectedValue, kv.Value);
}

if (expectedComment == null)
{
Assert.Null(kv.Comment);
}
else
{
Assert.Equal(expectedComment, kv.Comment.Value);
}
}
}
}
33 changes: 33 additions & 0 deletions src/Config.Net.Tests/Stores/Formats/StructuredIniFileTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using System;
using System.IO;
using System.Text;
using Config.Net.Stores.Formats.Ini;
using Xunit;

namespace Config.Net.Tests.Stores.Formats
{
public class StructuredIniFileTest : AbstractTestFixture
{
[Fact]
public void WriteInlineCommentWithNewLine()
{
string fullPath = Path.Combine(TestDir.FullName, Guid.NewGuid() + ".ini");
string content = @"key=value ;c1\r\nc2
";

StructuredIniFile file;
using (Stream input = new MemoryStream(Encoding.UTF8.GetBytes(content)))
{
file = StructuredIniFile.ReadFrom(input, true, true);
}

using (Stream output = File.OpenWrite(fullPath))
{
file.WriteTo(output);
}

string resultText = File.ReadAllText(fullPath);
Assert.Equal(content, resultText);
}
}
}
18 changes: 18 additions & 0 deletions src/Config.Net.Tests/Stores/IniFileConfigStoreTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -85,5 +85,23 @@ public void Write_NewFileWithNewValues_WritesCorrectText()
key0=s2value0
", resultText, false, true);
}

[Theory]
[InlineData("key", "l1\r\nl2", @"key=l1\r\nl2")]
[InlineData("key", "l1\rl2", @"key=l1\rl2")]
[InlineData("key", "l1\nl2", @"key=l1\nl2")]
[InlineData("k1\r\nk2", "value", @"k1\r\nk2=value")]
[InlineData("k1\rk2", "value", @"k1\rk2=value")]
[InlineData("k1\nk2", "value", @"k1\nk2=value")]
public void Write_NewLine(string key, string value, string expectedOutput)
{
string fullPath = Path.Combine(TestDir.FullName, Guid.NewGuid() + ".ini");
var ini = new IniFileConfigStore(fullPath, true, true);

ini.Write(key, value);

string resultText = File.ReadAllText(fullPath);
Assert.Equal(expectedOutput + "\r\n", resultText);
}
}
}
20 changes: 20 additions & 0 deletions src/Config.Net.Tests/Stores/JsonFileCOnfigStoreTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Text;
using Config.Net.Stores;
using Xunit;
using YamlDotNet.Core.Tokens;

namespace Config.Net.Tests.Stores
{
Expand Down Expand Up @@ -73,6 +74,25 @@ public void AliasesOnCollections()
Assert.Equal("user1", c.Name);
}
}

[Fact]
public void TestCreatingFileInMissingFolder()
{
_path = Path.Combine("C:\\temp", "TestData", "sample.json");

if (Directory.Exists(_path))
{
Directory.Delete(_path);
}

string key = "One.Two.Three";

_store = new JsonConfigStore(_path, true);
_store.Write(key, "111");

Assert.Equal("111", _store.Read(key));

Assert.True(File.Exists(_path));
}

public void Dispose()
Expand Down
5 changes: 5 additions & 0 deletions src/Config.Net/Stores/Formats/Ini/IniComment.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ public IniComment(string value)

public string Value { get; set; }

public string EscapedValue
{
get { return Value.Replace("\r", @"\r").Replace("\n", @"\n"); }
}

public override string ToString() => Value;
}
}
24 changes: 23 additions & 1 deletion src/Config.Net/Stores/Formats/Ini/IniKeyValue.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,19 @@ public IniKeyValue(string key, string value, string? comment)

public string Value { get; set; }

public string EscapedKey
{
get { return Key.Replace("\r", @"\r").Replace("\n", @"\n"); }
}

public string EscapedValue
{
get { return Value.Replace("\r", @"\r").Replace("\n", @"\n"); }
}

public IniComment? Comment { get; }

public static IniKeyValue? FromLine(string line, bool parseInlineComments)
public static IniKeyValue? FromLine(string line, bool parseInlineComments, bool unescapeNewLines = false)
{
int idx = line.IndexOf(KeyValueSeparator, StringComparison.CurrentCulture);
if(idx == -1) return null;
Expand All @@ -39,9 +49,21 @@ public IniKeyValue(string key, string value, string? comment)
}
}

if(unescapeNewLines)
{
key = UnescapeString(key);
value = UnescapeString(value);
comment = (comment != null) ? UnescapeString(comment) : null;
}

return new IniKeyValue(key, value, comment);
}

private static string UnescapeString(string key)
{
return key.Replace(@"\r", "\r").Replace(@"\n", "\n");
}

public override string ToString()
{
return $"{Value}";
Expand Down
4 changes: 2 additions & 2 deletions src/Config.Net/Stores/Formats/Ini/IniSection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -93,12 +93,12 @@ public void WriteTo(StreamWriter writer)
IniKeyValue? ikv = entity as IniKeyValue;
if(ikv != null)
{
writer.Write($"{ikv.Key}{IniKeyValue.KeyValueSeparator}{ikv.Value}");
writer.Write($"{ikv.EscapedKey}{IniKeyValue.KeyValueSeparator}{ikv.EscapedValue}");
if(ikv.Comment != null)
{
writer.Write(" ");
writer.Write(IniComment.CommentSeparator);
writer.Write(ikv.Comment.Value);
writer.Write(ikv.Comment.EscapedValue);
}
writer.WriteLine();
continue;
Expand Down
4 changes: 2 additions & 2 deletions src/Config.Net/Stores/Formats/Ini/StructuredIniFile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public string? this[string key]
}
}

public static StructuredIniFile ReadFrom(Stream inputStream, bool parseInlineComments)
public static StructuredIniFile ReadFrom(Stream inputStream, bool parseInlineComments, bool unescapeNewLines = false)
{
if(inputStream == null) throw new ArgumentNullException(nameof(inputStream));

Expand Down Expand Up @@ -90,7 +90,7 @@ public static StructuredIniFile ReadFrom(Stream inputStream, bool parseInlineCom
}
else
{
IniKeyValue? ikv = IniKeyValue.FromLine(line, parseInlineComments);
IniKeyValue? ikv = IniKeyValue.FromLine(line, parseInlineComments, unescapeNewLines);
if(ikv == null) continue;

section.Add(ikv);
Expand Down
14 changes: 7 additions & 7 deletions src/Config.Net/Stores/IniFileConfigStore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class IniFileConfigStore : IConfigStore
/// </summary>r
/// <param name="name">File does not have to exist, however it will be created as soon as you
/// try to write to it</param>
public IniFileConfigStore(string name, bool isFilePath, bool parseInlineComments)
public IniFileConfigStore(string name, bool isFilePath, bool parseInlineComments, bool unescapeNewLines = false)
{
if (name == null) throw new ArgumentNullException(nameof(name));

Expand All @@ -34,13 +34,13 @@ public IniFileConfigStore(string name, bool isFilePath, bool parseInlineComments
Directory.CreateDirectory(parentDirPath);
}

_iniFile = ReadIniFile(_fullName, parseInlineComments);
_iniFile = ReadIniFile(_fullName, parseInlineComments, unescapeNewLines);

CanWrite = true;
}
else
{
_iniFile = ReadIniContent(name, parseInlineComments);
_iniFile = ReadIniContent(name, parseInlineComments, unescapeNewLines);

CanWrite = false;
}
Expand Down Expand Up @@ -78,14 +78,14 @@ public void Write(string key, string? value)
WriteIniFile();
}

private static StructuredIniFile ReadIniFile(string fullName, bool parseInlineComments)
private static StructuredIniFile ReadIniFile(string fullName, bool parseInlineComments, bool unescapeNewLines = false)
{
FileInfo iniFile = new FileInfo(fullName);
if(iniFile.Exists)
{
using(FileStream stream = iniFile.Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
return StructuredIniFile.ReadFrom(stream, parseInlineComments);
return StructuredIniFile.ReadFrom(stream, parseInlineComments, unescapeNewLines);
}
}
else
Expand All @@ -94,11 +94,11 @@ private static StructuredIniFile ReadIniFile(string fullName, bool parseInlineCo
}
}

private static StructuredIniFile ReadIniContent(string content, bool parseInlineComments)
private static StructuredIniFile ReadIniContent(string content, bool parseInlineComments, bool unescapeNewLines = false)
{
using (Stream input = new MemoryStream(Encoding.UTF8.GetBytes(content)))
{
return StructuredIniFile.ReadFrom(input, parseInlineComments);
return StructuredIniFile.ReadFrom(input, parseInlineComments, unescapeNewLines);
}
}

Expand Down
Loading

0 comments on commit bb71920

Please sign in to comment.