Skip to content

Commit

Permalink
Merge branch 'dev' into new-master
Browse files Browse the repository at this point in the history
  • Loading branch information
Aaronontheweb committed Jan 15, 2020
2 parents 6cfd951 + e213c96 commit f287a0f
Show file tree
Hide file tree
Showing 22 changed files with 320 additions and 95 deletions.
17 changes: 7 additions & 10 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
#### 1.2.1 December 27 2019 ####
HOCON 1.2.1 contains many minor bug fixes and behavioral changes.
#### 1.3.0 January 14 2020 ####
HOCON 1.3.0 contains some significant API changes:

**Default HOCON loading order**
Per [issue 151](https://github.com/akkadotnet/HOCON/issues/151), `HOCON.Configuration` now looks for default HOCON content in the following places in the following order:
* [API parity with pre-existing Akka.NET HOCON implementation](https://github.com/akkadotnet/HOCON/issues/157)
* Added `HoconType.String`, `HoconType.Number`, `HoconType.Bool`, and removed `HoconType.Literal` - now it's possible to discover data types more easily while inspecting individual HOCON objects.
* [Fixed: Need to be able to include Config fallback values to string representation](https://github.com/akkadotnet/HOCON/issues/161)
* [Added SourceLink.Github support](https://github.com/akkadotnet/HOCON/pull/166)

1. [.NET Core / .NET Framework] An "app.conf" or an "app.hocon" file in the current working directory of the executable when it loads;
2. [.NET Framework] - the `<hocon>` `ConfigurationSection` inside `App.config` or `Web.config`; or
3. [.NET Framework] - and a legacy option, to load the old `<akka>` HOCON section for backwards compatibility purposes with all users who have been using HOCON with Akka.NET.

**Bug fixes**:
For a set of complete bug fixes and changes, please see [the HOCON v1.2.1 milestone on Github](https://github.com/akkadotnet/HOCON/milestone/2).
For a set of complete bug fixes and changes, please see [the HOCON v1.3.0 milestone on Github](https://github.com/akkadotnet/HOCON/milestone/3).
38 changes: 38 additions & 0 deletions src/HOCON.Tests/Extensions/IsStringTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using FluentAssertions;
using Hocon.Extensions;
using Xunit;

namespace Hocon.Tests.Extensions
{
public class IsStringTests
{
public readonly string RawTestHocon = @"
root{
foo {
bar = str
baz = 1 # int
biz = 2m # time
boz = 4.0 # float
byz = #empty
boy = ""quoted-string""
}
}
";

public HoconRoot TestHocon => Parser.Parse(RawTestHocon);

[Fact]
public void IsString_should_detect_String_literals()
{
TestHocon.GetObject("root").Type.Should().NotBe(HoconType.String);
TestHocon.GetObject("root.foo").Type.Should().NotBe(HoconType.String);
var values = TestHocon.GetObject("root.foo");
values["bar"].Type.Should().Be(HoconType.String);
}
}
}
79 changes: 79 additions & 0 deletions src/Hocon.Configuration.Test/ConfigurationSpec.cs
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,63 @@ public void CanUseFallback()
Assert.Equal(3, config.GetInt("foo.bar.c"));
}

[Fact]
public void CanUseFallbackString()
{
var hocon1 = @"
foo {
bar {
a=123str
}
}";
var hocon2 = @"
foo {
bar {
a=1str
b=2str
c=3str
}
car = ""bar""
}
dar = d";

var config1 = ConfigurationFactory.ParseString(hocon1);
var config2 = ConfigurationFactory.ParseString(hocon2);

var config = config1.WithFallback(config2);

Assert.Equal("123str", config.GetString("foo.bar.a"));
Assert.Equal("2str", config.GetString("foo.bar.b"));
Assert.Equal("3str", config.GetString("foo.bar.c"));
Assert.Equal("bar", config.GetString("foo.car"));
Assert.Equal("d", config.GetString("dar"));
}

[Fact]
public void CanUseFallbackWithEmpty()
{
var config1 = Config.Empty;
var hocon2 = @"
foo {
bar {
a=1str
b=2str
c=3str
}
car = ""bar""
}
dar = d";
var config2 = ConfigurationFactory.ParseString(hocon2);

var config = config1.SafeWithFallback(config2);

Assert.Equal("1str", config.GetString("foo.bar.a"));
Assert.Equal("2str", config.GetString("foo.bar.b"));
Assert.Equal("3str", config.GetString("foo.bar.c"));
Assert.Equal("bar", config.GetString("foo.car"));
Assert.Equal("d", config.GetString("dar"));
}

[Fact]
public void CanUseFallbackInSubConfig()
{
Expand Down Expand Up @@ -260,6 +317,22 @@ public void CanUseFluentMultiLevelFallback()
Assert.Equal(-1, config.GetInt("foo.bar.borkbork"));
}

[Fact]
public void ShouldSerializeFallbackValues()
{
var a = ConfigurationFactory.ParseString(@" akka : {
some-key : value
}");
var b = ConfigurationFactory.ParseString(@"akka : {
other-key : 42
}");

var c = a.WithFallback(b);
c.GetInt("akka.other-key").Should().Be(42, "Fallback value should exist as data");
c.ToString().Should().NotContain("other-key", "Fallback values are ignored by default");
c.ToString(useFallbackValues: true).Should().Contain("other-key", "Fallback values should be displayed when requested");
}

[Fact]
public void CanParseQuotedKeys()
{
Expand Down Expand Up @@ -345,6 +418,12 @@ public void CanParseSerializersAndBindings()
);
}

[Fact]
public void Config_Empty_is_Empty()
{
ConfigurationFactory.Empty.IsEmpty.Should().BeTrue();
}

public class MyObjectConfig
{
public string StringProperty { get; set; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="FluentAssertions" Version="5.9.0" />
<PackageReference Include="FluentAssertions" Version="5.10.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="$(TestSdkVersion)" />
<PackageReference Include="xunit" Version="$(XunitVersion)" />
<DotNetCliToolReference Include="dotnet-xunit" Version="$(XunitCliVersion)" />
Expand Down
28 changes: 26 additions & 2 deletions src/Hocon.Configuration/Config.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,14 @@ namespace Hocon
/// </summary>
public class Config: HoconRoot
{
/// <summary>
/// Identical to <see cref="ConfigurationFactory.Empty"/>.
/// </summary>
/// <remarks>
/// Added for brevity and API backwards-compatibility with Akka.Hocon.
/// </remarks>
public static Config Empty => ConfigurationFactory.Empty;

/// <summary>
/// The configuration used as a secondary source.
/// </summary>
Expand All @@ -27,7 +35,7 @@ public class Config: HoconRoot
/// <summary>
/// The root node of this configuration section
/// </summary>
public HoconValue Root => Value;
public virtual HoconValue Root => Value;

/// <inheritdoc/>
/// <summary>
Expand All @@ -51,6 +59,22 @@ public Config(HoconRoot source, Config fallback):base(source?.Value, source?.Sub
Fallback = fallback;
}

/// <summary>
/// Returns string representation of <see cref="Config"/>, allowing to include fallback values
/// </summary>
/// <param name="useFallbackValues">If set to <c>true</c>, fallback values are included in the output</param>
public string ToString(bool useFallbackValues)
{
if (!useFallbackValues)
return base.ToString();

var config = this;
while (config.Fallback != null)
config = config.Fallback;

return config.ToString();
}

/// <summary>
/// Generates a deep clone of the current configuration.
/// </summary>
Expand Down Expand Up @@ -89,7 +113,7 @@ protected override HoconValue GetNode(HoconPath path, bool throwIfNotFound = fal
/// </summary>
/// <param name="path">The path that contains the configuration to retrieve.</param>
/// <returns>A new configuration with the root node being the supplied path.</returns>
public Config GetConfig(string path)
public virtual Config GetConfig(string path)
=> GetConfig(HoconPath.Parse(path));

public virtual Config GetConfig(HoconPath path)
Expand Down
2 changes: 1 addition & 1 deletion src/Hocon.Configuration/ConfigurationFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public static class ConfigurationFactory
/// <summary>
/// Generates an empty configuration.
/// </summary>
public static Config Empty => ParseString("{}");
public static Config Empty => new Config(new HoconRoot(new HoconEmptyValue(null)));

/// <summary>
/// Generates a configuration defined in the supplied
Expand Down
2 changes: 2 additions & 0 deletions src/Hocon.Configuration/Hocon.Configuration.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
<TargetFrameworks>net461;netstandard2.0</TargetFrameworks>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<RootNamespace>Hocon</RootNamespace>
<PackageTags>$(HoconPackageTags)</PackageTags>
<Description>HOCON (Human-Optimized Config Object Notation) parser and application-ready implementation.</Description>
</PropertyGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<PackageTags>$(HoconPackageTags)</PackageTags>
<Description>HOCON (Human-Optimized Config Object Notation) support for Microsoft.Extensions.Configuration.</Description>
</PropertyGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,10 @@ private void VisitObject(HoconValue value)
case HoconType.Array:
VisitArray(value.GetArray());
break;

case HoconType.Literal:

case HoconType.Boolean:
case HoconType.Number:
case HoconType.String:
VisitPrimitive(value);
break;
}
Expand Down
4 changes: 3 additions & 1 deletion src/Hocon.Immutable/Extensions/HoconImmutableExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,9 @@ public static HoconImmutableElement ToHoconImmutable(this HoconValue value)
return new HoconImmutableArrayBuilder()
.AddRange(value)
.Build();
case HoconType.Literal:
case HoconType.Boolean:
case HoconType.Number:
case HoconType.String:
return new HoconImmutableLiteralBuilder()
.Append(value)
.Build();
Expand Down
2 changes: 2 additions & 0 deletions src/Hocon.Immutable/Hocon.Immutable.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
<TargetFrameworks>net461;netstandard2.0</TargetFrameworks>
<LangVersion>7.2</LangVersion>
<DefineConstants Condition="'$(TargetFramework)' == 'netstandard2.1'">NS2_1</DefineConstants>
<PackageTags>$(HoconPackageTags)</PackageTags>
<Description>HOCON (Human-Optimized Config Object Notation) Experimental Immutable Support</Description>
</PropertyGroup>

<ItemGroup>
Expand Down
2 changes: 1 addition & 1 deletion src/Hocon.Tests/Hocon.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="FluentAssertions" Version="5.9.0" />
<PackageReference Include="FluentAssertions" Version="5.10.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="$(TestSdkVersion)" />
<PackageReference Include="xunit" Version="$(XunitVersion)" />
<DotNetCliToolReference Include="dotnet-xunit" Version="$(XunitCliVersion)" />
Expand Down
25 changes: 25 additions & 0 deletions src/Hocon/Extensions/HoconElementExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
using System.Linq;

namespace Hocon.Extensions
{
/// <summary>
Expand All @@ -15,5 +17,28 @@ public static IHoconElement CloneValue(this IHoconElement hoconElement, IHoconEl
{
return hoconElement is HoconSubstitution ? hoconElement : hoconElement.Clone(newParent);
}

public static bool IsLiteral(this HoconType hoconType)
{
switch (hoconType)
{
case HoconType.Boolean:
case HoconType.Number:
case HoconType.String:
return true;
default:
return false;
}
}

public static bool IsMergeable(this HoconType t1, HoconType t2)
{
return t1 == t2 || (t1.IsLiteral() && t2.IsLiteral());
}

public static bool IsMergeable(this IHoconElement e1, IHoconElement e2)
{
return e1.Type.IsMergeable(e2.Type);
}
}
}
2 changes: 2 additions & 0 deletions src/Hocon/Hocon.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,7 @@
<PropertyGroup>
<TargetFrameworks>net461;netstandard1.3</TargetFrameworks>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<PackageTags>$(HoconPackageTags)</PackageTags>
<Description>HOCON (Human-Optimized Config Object Notation) core API implementation. For full access inside your application, install the Hocon.Configuration package.</Description>
</PropertyGroup>
</Project>
Loading

0 comments on commit f287a0f

Please sign in to comment.