Skip to content

Commit

Permalink
feat(configuration): added configuration section-related functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
godrose committed Jul 6, 2021
1 parent 25c0c61 commit 0238d67
Show file tree
Hide file tree
Showing 18 changed files with 245 additions and 3 deletions.
3 changes: 2 additions & 1 deletion Attest.Testing.Contracts/Attest.Testing.Contracts.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<TargetFramework>netstandard2.0</TargetFramework>
Expand All @@ -12,6 +12,7 @@
<DebugSymbols>true</DebugSymbols>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="5.0.0" />
<PackageReference Include="Solid.Core" Version="2.3.1" />
<PackageReference Include="Solid.Patterns.Builder" Version="2.3.1" />
</ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using System.Collections.Generic;

// ReSharper disable once CheckNamespace
namespace Attest.Testing.Configuration
{
public interface IConfigurationSectionKeySplitter
{
IEnumerable<string> Split(string key);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using Microsoft.Extensions.Configuration;

// ReSharper disable once CheckNamespace
namespace Attest.Testing.Configuration
{
/// <summary>
/// Provides facilities for interacting with configuration sections.
/// </summary>
public interface IConfigurationSectionValueProvider
{
/// <summary>
/// Gets the value for the configuration section by its key.
/// </summary>
/// <param name="configuration">The configuration.</param>
/// <param name="key">The section key.</param>
/// <returns></returns>
string GetValue(IConfiguration configuration, string key);
}
}
13 changes: 12 additions & 1 deletion Attest.Testing.Core.Specs/Attest.Testing.Core.Specs.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
Expand Down Expand Up @@ -29,9 +29,20 @@
<ProjectReference Include="..\Attest.Testing.SpecFlow\Attest.Testing.SpecFlow.csproj" />
<ProjectReference Include="..\Attest.Tests.Infra\Attest.Tests.Infra.csproj" />
</ItemGroup>
<ItemGroup>
<Compile Update="Configuration\Configuration.feature.cs">
<DesignTime>True</DesignTime>
</Compile>
</ItemGroup>
<ItemGroup>
<None Update="specflow.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<SpecFlowFeatureFiles Update="Configuration\Configuration.feature">
<Generator>SpecFlowSingleFileGenerator</Generator>
<LastGenOutput>Configuration.feature.cs</LastGenOutput>
</SpecFlowFeatureFiles>
</ItemGroup>
</Project>
16 changes: 16 additions & 0 deletions Attest.Testing.Core.Specs/Configuration/Configuration.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
Feature: Configuration
In order to support development with configuration
As an app developer
I want the framework to be able to resolve value by key

Scenario: Resolving simple value by an existing key should return value
Given The configuration uses environment variable compatible key splitter
And The configuration contains the key "key" mapped to value "value"
When I get the value by this key
Then The value is resolved successfully

Scenario: Resolving simple value by a non-existing key should return null
Given The configuration uses environment variable compatible key splitter
And The configuration does not contain the key "key"
When I get the value by this key
Then The value is returned as null
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
using Attest.Fake.Core;
using Attest.Testing.Configuration;
using Attest.Testing.Context.SpecFlow;
using Microsoft.Extensions.Configuration;
using TechTalk.SpecFlow;

namespace Attest.Testing.Core.Specs
{
internal sealed class ConfigurationScenarioDataStore : ScenarioDataStoreBase
{
public ConfigurationScenarioDataStore(ScenarioContext scenarioContext) : base(scenarioContext)
{}

public string Key
{
get => GetValue<string>();
set => SetValue(value);
}

public string ExpectedValue
{
get => GetValue<string>();
set => SetValue(value);
}

public string ActualValue
{
get => GetValue<string>();
set => SetValue(value);
}

public IConfigurationSectionKeySplitter KeySplitter
{
get => GetValue<IConfigurationSectionKeySplitter>();
set => SetValue(value);
}

public IFake<IConfiguration> Configuration
{
get => GetValue<IFake<IConfiguration>>();
set => SetValue(value);
}

public IFake<IConfigurationSection> ConfigurationSection
{
get => GetValue<IFake<IConfigurationSection>>();
set => SetValue(value);
}
}
}
83 changes: 83 additions & 0 deletions Attest.Testing.Core.Specs/Configuration/ConfigurationSteps.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
using Attest.Fake.Core;
using Attest.Fake.Moq;
using Attest.Testing.Configuration;
using FluentAssertions;
using Microsoft.Extensions.Configuration;
using TechTalk.SpecFlow;

namespace Attest.Testing.Core.Specs
{
[Binding]
internal sealed class ConfigurationSteps
{
private readonly ConfigurationScenarioDataStore _configurationScenarioDataStore;
private readonly IFakeFactory _fakeFactory;

public ConfigurationSteps(ScenarioContext scenarioContext)
{
_configurationScenarioDataStore = new ConfigurationScenarioDataStore(scenarioContext);
_fakeFactory = new FakeFactory();
}

[Given(@"The configuration uses environment variable compatible key splitter")]
public void GivenTheConfigurationUsesEnvironmentVariableCompatibleKeySplitter()
{
_configurationScenarioDataStore.KeySplitter = new EnvironmentVariableKeySplitter();
}

[Given(@"The configuration contains the key ""(.*)"" mapped to value ""(.*)""")]
public void GivenTheConfigurationContainsTheKeyMappedToValue(string key, string value)
{
_configurationScenarioDataStore.Key = key;
_configurationScenarioDataStore.ExpectedValue = value;
_configurationScenarioDataStore.Configuration = _fakeFactory.CreateFake<IConfiguration>();
_configurationScenarioDataStore.ConfigurationSection = _fakeFactory.CreateFake<IConfigurationSection>();
_configurationScenarioDataStore.ConfigurationSection
.Setup(t => t.Value)
.Callback(() => _configurationScenarioDataStore.ExpectedValue);
_configurationScenarioDataStore.Configuration
.Setup(t => t.GetSection(key))
.Callback(() => _configurationScenarioDataStore.ConfigurationSection.Object);
}

[Given(@"The configuration does not contain the key ""(.*)""")]
public void GivenTheConfigurationDoesNotContainTheKeyMappedToValue(string key)
{
_configurationScenarioDataStore.Key = key;
_configurationScenarioDataStore.Configuration = _fakeFactory.CreateFake<IConfiguration>();
_configurationScenarioDataStore.Configuration
.Setup(t => t.GetSection(key))
.Callback(() => null);
}

[When(@"I get the value by this key")]
public void WhenIGetTheValueByThisKey()
{
//TODO: Inject/Resolve
var configurationSectionValueProvider =
new ConfigurationSectionValueProvider(_configurationScenarioDataStore.KeySplitter);
var value = configurationSectionValueProvider.GetValue(
_configurationScenarioDataStore.Configuration.Object,
_configurationScenarioDataStore.Key);
_configurationScenarioDataStore.ActualValue = value;
}

[Then(@"The value is resolved successfully")]
public void ThenTheValueIsResolvedSuccessfully()
{
_configurationScenarioDataStore
.ActualValue
.Should()
.Be(_configurationScenarioDataStore.ExpectedValue);
}

[Then(@"The value is returned as null")]
public void ThenTheValueIsReturnedAsNull()
{
_configurationScenarioDataStore
.ActualValue
.Should()
.BeNull();
}
}
}
3 changes: 2 additions & 1 deletion Attest.Testing.Core/Attest.Testing.Core.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
Expand All @@ -12,6 +12,7 @@
<DebugSymbols>true</DebugSymbols>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="5.0.0" />
<PackageReference Include="Solid.Bootstrapping" Version="2.3.1" />
<PackageReference Include="Solid.Common.Core" Version="2.3.1" />
<PackageReference Include="Solid.Core" Version="2.3.1" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
using System.Linq;
using Microsoft.Extensions.Configuration;

// ReSharper disable once CheckNamespace
namespace Attest.Testing.Configuration
{
/// <inheritdoc />
public class ConfigurationSectionValueProvider : IConfigurationSectionValueProvider
{
private readonly IConfigurationSectionKeySplitter _configurationSectionKeySplitter;

public ConfigurationSectionValueProvider(IConfigurationSectionKeySplitter configurationSectionKeySplitter)
{
_configurationSectionKeySplitter = configurationSectionKeySplitter;
}

/// <inheritdoc />
public string GetValue(IConfiguration configuration, string key)
{
var sections = //key.Split(new[] {"__"}, StringSplitOptions.None)
_configurationSectionKeySplitter.Split(key)
.Where(x => !string.IsNullOrEmpty(x))
.ToArray();
IConfigurationSection section = null;
foreach (var sectionName in sections)
{
section = section == null ? configuration.GetSection(sectionName) : section.GetSection(sectionName);
}

var value = section?.Value;
return value;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;

// ReSharper disable once CheckNamespace
namespace Attest.Testing.Configuration
{
public sealed class EnvironmentVariableKeySplitter : IConfigurationSectionKeySplitter
{
/// <inheritdoc />
public IEnumerable<string> Split(string key)
{
return key.Split(new[] {"__"}, StringSplitOptions.None);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
<releaseNotes>
</releaseNotes>
<dependencies>
<dependency id="Microsoft.Extensions.Configuration.Abstractions" version="5.0.0" />
<dependency id="Solid.Patterns.Builder" version="2.3.1" />
<dependency id="Solid.Core" version="2.3.1" />
</dependencies>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
<dependency id="Attest.Fake.Data" version="2.3.2" />
<dependency id="Attest.Fake.Registration" version="2.3.2" />
<dependency id="Attest.Testing.Contracts" version="2.3.2" />
<dependency id="Microsoft.Extensions.Configuration.Abstractions" version="5.0.0" />
<dependency id="System.Management" version="5.0.0" />
</dependencies>
</metadata>
Expand Down

0 comments on commit 0238d67

Please sign in to comment.