Skip to content

Commit

Permalink
Add app.config configuration for Cucumber-Messages (#1759)
Browse files Browse the repository at this point in the history
* update submodule

* add specs and bindings

* add app.config dtos

* convert into SpecFlowConfiguration & unit tests for it

* make app.config scenarios only available for full framework

* update vswhere

* fix cucumber messages specs

* remove unnecessary csproj changes
  • Loading branch information
SabotageAndi authored Oct 24, 2019
1 parent 5f66c61 commit c227205
Show file tree
Hide file tree
Showing 10 changed files with 296 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,16 @@ public Configuration.SpecFlowConfiguration LoadAppConfig(Configuration.SpecFlowC
additionalStepAssemblies.Add(assemblyName);
}

if (IsSpecified(configSection.CucumberMessages))
{
cucumberMessagesConfiguration.Enabled = configSection.CucumberMessages.Enabled;

foreach (CucumberMessageSinkElement cucumberMessagesSink in configSection.CucumberMessages.Sinks)
{
cucumberMessagesConfiguration.Sinks.Add(new CucumberMessagesSink(cucumberMessagesSink.Type, cucumberMessagesSink.Path));
}
}

return new SpecFlowConfiguration(ConfigSource.AppConfig,
runtimeContainerRegistrationCollection,
generatorContainerRegistrationCollection,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ public LanguageConfigElement Language
{
get { return (LanguageConfigElement)this["language"]; }
set { this["language"] = value; }
}
}

[ConfigurationProperty("bindingCulture", IsRequired = false)]
public BindingCultureConfigElement BindingCulture
{
Expand Down Expand Up @@ -49,7 +49,14 @@ public StepAssemblyCollection StepAssemblies
get { return (StepAssemblyCollection)this["stepAssemblies"]; }
set { this["stepAssemblies"] = value; }
}


[ConfigurationProperty("cucumber-messages", IsRequired = false)]
public CucumberMessagesElement CucumberMessages
{
get => (CucumberMessagesElement)this["cucumber-messages"];
set => this["cucumber-messages"] = value;
}

public static ConfigurationSectionHandler CreateFromXml(string xmlContent)
{
ConfigurationSectionHandler section = new ConfigurationSectionHandler();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using System.Configuration;

namespace TechTalk.SpecFlow.Configuration.AppConfig
{
public class CucumberMessageSinkElement : ConfigurationElement
{
[ConfigurationProperty("type", IsRequired = true)]
public string Type
{
get => (string) this["type"];
set => this["type"] = value;
}

[ConfigurationProperty("path", IsRequired = true)]
public string Path
{
get => (string) this["path"];
set => this["path"] = value;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using System.Collections.Generic;
using System.Configuration;

namespace TechTalk.SpecFlow.Configuration.AppConfig
{
public class CucumberMessagesElement : ConfigurationElement
{
[ConfigurationProperty("enabled", DefaultValue = false, IsRequired = false)]
public bool Enabled
{
get => (bool)this["enabled"];
set => this["enabled"] = value;
}

[ConfigurationProperty("sinks", IsDefaultCollection = false, IsRequired = false)]
[ConfigurationCollection(typeof(CucumberMessagesSinkCollection), AddItemName = "sink")]
public CucumberMessagesSinkCollection Sinks
{
get => (CucumberMessagesSinkCollection) this["sinks"];
set => this["sinks"] = value;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System.Configuration;

namespace TechTalk.SpecFlow.Configuration.AppConfig
{
public class CucumberMessagesSinkCollection : ConfigurationElementCollection
{
protected override ConfigurationElement CreateNewElement()
{
return new CucumberMessageSinkElement();
}

protected override object GetElementKey(ConfigurationElement element)
{
var cucumberMessageSinkElement = ((CucumberMessageSinkElement)element);
return cucumberMessageSinkElement.Type + cucumberMessageSinkElement.Path;
}
}
}
124 changes: 124 additions & 0 deletions Tests/TechTalk.SpecFlow.RuntimeTests/Configuration/AppConfigTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -328,5 +328,129 @@ public void Check_StepAssemblies_TwoEntry()
runtimeConfig.AdditionalStepAssemblies[1].Should().Be("testEntry2");
}


[Fact]
public void Check_CucumberMessages_NotConfigured_EnabledIsFalse()
{
string config = @"<specflow>
</specflow>";

var configSection = ConfigurationSectionHandler.CreateFromXml(config);

var runtimeConfig = new AppConfigConfigurationLoader().LoadAppConfig(ConfigurationLoader.GetDefault(), configSection);
runtimeConfig.CucumberMessagesConfiguration.Enabled.Should().BeFalse();
}


[Fact]
public void Check_CucumberMessages_EmptyTag_EnabledIsFalse()
{
string config = @"<specflow>
<cucumber-messages />
</specflow>";

var configSection = ConfigurationSectionHandler.CreateFromXml(config);

var runtimeConfig = new AppConfigConfigurationLoader().LoadAppConfig(ConfigurationLoader.GetDefault(), configSection);
runtimeConfig.CucumberMessagesConfiguration.Enabled.Should().BeFalse();
}

[Fact]
public void Check_CucumberMessages_Enabled_True()
{
string config = @"<specflow>
<cucumber-messages enabled=""true""/>
</specflow>";

var configSection = ConfigurationSectionHandler.CreateFromXml(config);

var runtimeConfig = new AppConfigConfigurationLoader().LoadAppConfig(ConfigurationLoader.GetDefault(), configSection);
runtimeConfig.CucumberMessagesConfiguration.Enabled.Should().BeTrue();
}

[Fact]
public void Check_CucumberMessages_Enabled_False()
{
string config = @"<specflow>
<cucumber-messages enabled=""false""/>
</specflow>";

var configSection = ConfigurationSectionHandler.CreateFromXml(config);

var runtimeConfig = new AppConfigConfigurationLoader().LoadAppConfig(ConfigurationLoader.GetDefault(), configSection);
runtimeConfig.CucumberMessagesConfiguration.Enabled.Should().BeFalse();
}

[Fact]
public void Check_CucumberMessages_Sinks_EmptyList()
{
string config = @"<specflow>
<cucumber-messages enabled=""false"">
<sinks>
</sinks>
</cucumber-messages>
</specflow>";

var configSection = ConfigurationSectionHandler.CreateFromXml(config);

var runtimeConfig = new AppConfigConfigurationLoader().LoadAppConfig(ConfigurationLoader.GetDefault(), configSection);
runtimeConfig.CucumberMessagesConfiguration.Sinks.Should().BeEmpty();
}

[Fact]
public void Check_CucumberMessages_Sinks_ListOneEntry()
{
string config = @"<specflow>
<cucumber-messages enabled=""false"">
<sinks>
<sink type=""file"" path=""C:\temp\testrun.cm"" />
</sinks>
</cucumber-messages>
</specflow>";

var configSection = ConfigurationSectionHandler.CreateFromXml(config);

var runtimeConfig = new AppConfigConfigurationLoader().LoadAppConfig(ConfigurationLoader.GetDefault(), configSection);
runtimeConfig.CucumberMessagesConfiguration.Sinks.Count.Should().Be(1);
}

[Fact]
public void Check_CucumberMessages_Sinks_ListMultipleEntry()
{
string config = @"<specflow>
<cucumber-messages enabled=""false"">
<sinks>
<sink type=""file"" path=""C:\temp\testrun1.cm"" />
<sink type=""file"" path=""C:\temp\testrun2.cm"" />
<sink type=""file"" path=""C:\temp\testrun3.cm"" />
</sinks>
</cucumber-messages>
</specflow>";

var configSection = ConfigurationSectionHandler.CreateFromXml(config);

var runtimeConfig = new AppConfigConfigurationLoader().LoadAppConfig(ConfigurationLoader.GetDefault(), configSection);
runtimeConfig.CucumberMessagesConfiguration.Sinks.Count.Should().Be(3);
}

[Fact]
public void Check_CucumberMessages_Sinks_DataOfEntry()
{
string config = @"<specflow>
<cucumber-messages enabled=""false"">
<sinks>
<sink type=""file"" path=""C:\temp\testrun.cm"" />
</sinks>
</cucumber-messages>
</specflow>";

var configSection = ConfigurationSectionHandler.CreateFromXml(config);

var runtimeConfig = new AppConfigConfigurationLoader().LoadAppConfig(ConfigurationLoader.GetDefault(), configSection);
var cucumberMessagesSink = runtimeConfig.CucumberMessagesConfiguration.Sinks.First();

cucumberMessagesSink.Type.Should().Be("file");
cucumberMessagesSink.Path.Should().Be(@"C:\temp\testrun.cm");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ public MemoryStream GetWritableStream()
return new MemoryStream();
}

public ProtobufFileSinkConfiguration GetProtobufFileSinkConfiguration(string targetFilePath = "CucumberMessageQueue")
public ProtobufFileSinkConfiguration GetProtobufFileSinkConfiguration(string targetFilePath = "cucumbermessages")
{
return new ProtobufFileSinkConfiguration(targetFilePath);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
@fullframework
Feature: Cucumber-Messages Configuration via app.config

Cucumber-messages can be configured in the SpecFlow section of the app.config file to enable/disable messages
and configure alternative output sinks

Scenario: No configuration creates no output file

Given there is a project with this app.config configuration
"""
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="specFlow" type="TechTalk.SpecFlow.Configuration.ConfigurationSectionHandler, TechTalk.SpecFlow" />
</configSections>
<specFlow>
<cucumber-messages />
</specFlow>
</configuration>
"""
When the test suite is executed
Then no Cucumber-Messages file is created

Scenario: Disabled configuration creates no output file
Given there is a project with this app.config configuration
"""
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="specFlow" type="TechTalk.SpecFlow.Configuration.ConfigurationSectionHandler, TechTalk.SpecFlow" />
</configSections>
<specFlow>
<cucumber-messages enabled="false" />
</specFlow>
</configuration>
"""
When the test suite is executed
Then no Cucumber-Messages file is created

Scenario: Enabled configuration with no sinks configured create default output file
The default Cucumber-Messages file is created at `cucumbermessages\messages` relative to the output directory

Given there is a project with this app.config configuration
"""
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="specFlow" type="TechTalk.SpecFlow.Configuration.ConfigurationSectionHandler, TechTalk.SpecFlow" />
</configSections>
<specFlow>
<cucumber-messages enabled="true" />
</specFlow>
</configuration>
"""
When the test suite is executed
Then the Cucumber-Messages file 'cucumbermessages\messages' is created

Scenario: Configured sinks are respected
Given there is a project with this app.config configuration
"""
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<section name="specFlow" type="TechTalk.SpecFlow.Configuration.ConfigurationSectionHandler, TechTalk.SpecFlow" />
</configSections>
<specFlow>
<cucumber-messages enabled="true" >
<sinks>
<sink type="file" path="custom_cucumber_messages_file.cm" />
</sinks>
</cucumber-messages>
</specFlow>
</configuration>
"""
When the test suite is executed
Then the Cucumber-Messages file 'custom_cucumber_messages_file.cm' is created

Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,13 @@ public void GivenThereIsAProjectWithThisSpecFlowJsonConfiguration(string specFlo
_testSuiteSetupDriver.AddSpecFlowJsonFromString(specFlowJson);
}

[Given(@"there is a project with this app\.config configuration")]
public void GivenThereIsAProjectWithThisApp_ConfigConfiguration(string multilineText)
{
_testSuiteSetupDriver.AddAppConfigFromString(multilineText);
}


[Given(@"the specflow configuration is")]
public void GivenTheSpecFlowConfigurationIs(string specFlowSection)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@
</None>
</ItemGroup>


<PropertyGroup>
<_SpecFlow_TaskFolder Condition=" '$(MSBuildRuntimeType)' == 'Core' And '$(_SpecFlow_TaskFolder)' == ''">netcoreapp2.0</_SpecFlow_TaskFolder>
<_SpecFlow_TaskFolder Condition=" '$(MSBuildRuntimeType)' != 'Core' And '$(_SpecFlow_TaskFolder)' == ''">net471</_SpecFlow_TaskFolder>
Expand Down

0 comments on commit c227205

Please sign in to comment.