Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# [vNext]

## Improvements:

* Refactored Formatters Configuration deserialization to align with Reqnroll JsonConfig. Created typed configuration settings object. Breaking change for custom Formatter implementers.
## Bug fixes:

*Contributors of this release (in alphabetical order):*
*Contributors of this release (in alphabetical order):*@clrudolphi

# v3.3.4 - 2026-03-23

Expand Down
3 changes: 3 additions & 0 deletions Reqnroll/Configuration/ConfigDefaults.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using System;
using System.Collections.Generic;
using Reqnroll.BindingSkeletons;
using Reqnroll.Formatters.Configuration;

namespace Reqnroll.Configuration
{
Expand Down Expand Up @@ -30,6 +32,7 @@ public static class ConfigDefaults
public const bool DisableFriendlyTestNames = false;

public static readonly string[] AddNonParallelizableMarkerForTags = Array.Empty<string>();
public static Dictionary<string, FormatterConfiguration> Formatters => new Dictionary<string, FormatterConfiguration>(StringComparer.OrdinalIgnoreCase);
}
// ReSharper restore RedundantNameQualifier
}
6 changes: 5 additions & 1 deletion Reqnroll/Configuration/ConfigurationLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.IO;
using Reqnroll.BindingSkeletons;
using Reqnroll.Configuration.JsonConfig;
using Reqnroll.Formatters.Configuration;
using Reqnroll.PlatformCompatibility;
using Reqnroll.Tracing;

Expand Down Expand Up @@ -50,6 +51,8 @@ public ConfigurationLoader(IReqnrollJsonLocator reqnrollJsonLocator)

public static bool DefaultColoredOutput => ConfigDefaults.ColoredOutput;

private static Dictionary<string, FormatterConfiguration> DefaultFormatters => ConfigDefaults.Formatters;

public bool HasJsonConfig
{
get
Expand Down Expand Up @@ -132,7 +135,8 @@ public static ReqnrollConfiguration GetDefault()
DefaultAddNonParallelizableMarkerForTags,
DefaultDisableFriendlyTestNames,
DefaultObsoleteBehavior,
DefaultColoredOutput
DefaultColoredOutput,
DefaultFormatters
);
}

Expand Down
18 changes: 18 additions & 0 deletions Reqnroll/Configuration/JsonConfig/FormatterOptionsElement.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System.Collections.Generic;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace Reqnroll.Configuration.JsonConfig
{
public class FormatterOptionsElement
{
[JsonPropertyName("outputFilePath")]
public string OutputFilePath { get; set; }

/// <summary>
/// Captures any additional options not explicitly defined above.
/// </summary>
[JsonExtensionData]
public Dictionary<string, JsonElement> AdditionalOptions { get; set; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using System.Text.Json;
using System.Text.Json.Serialization;

namespace Reqnroll.Configuration.JsonConfig;

[JsonSourceGenerationOptions(WriteIndented = true,
PropertyNamingPolicy = JsonKnownNamingPolicy.Unspecified, // We specifiy the names explicitly
PropertyNameCaseInsensitive = true, // old custom parser supported ordinal ignore case, so we should do
UseStringEnumConverter = true, // use strings instead of numbers for enums
ReadCommentHandling = JsonCommentHandling.Skip)] // the user can comment his used configuration value
[JsonSerializable(typeof(FormattersElement))]
internal partial class FormattersConfigurationSourceGenerator : JsonSerializerContext
{

}
21 changes: 21 additions & 0 deletions Reqnroll/Configuration/JsonConfig/FormattersElement.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using System.Collections.Generic;
using System.Text.Json.Serialization;

namespace Reqnroll.Configuration.JsonConfig;

/// <summary>
/// Represents a collection of formatter configuration options, keyed by formatter name.
/// </summary>
/// <remarks>This json configuration element is used when overriding a formatter/s configuration by environment variable.
/// The json should be structured as:
/// { "formatters":
/// { "myformatter":
/// "settingKey": "settingValue"
/// }
/// }
/// </remarks>
public class FormattersElement
{
[JsonPropertyName("formatters")]
public IDictionary<string, FormatterOptionsElement> Formatters { get; set; }
}
3 changes: 3 additions & 0 deletions Reqnroll/Configuration/JsonConfig/JsonConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,8 @@ public class JsonConfig

[JsonPropertyName("bindingAssemblies")]
public List<StepAssemblyElement> BindingAssemblies { get; set; }

[JsonPropertyName("formatters")]
public IDictionary<string, FormatterOptionsElement> Formatters { get; set; }
}
}
13 changes: 12 additions & 1 deletion Reqnroll/Configuration/JsonConfig/JsonConfigurationLoader.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using Reqnroll.Formatters.Configuration;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text.Json;

Expand Down Expand Up @@ -32,6 +34,7 @@ public ReqnrollConfiguration LoadJson(ReqnrollConfiguration reqnrollConfiguratio
var addNonParallelizableMarkerForTags = reqnrollConfiguration.AddNonParallelizableMarkerForTags;
bool disableFriendlyTestNames = reqnrollConfiguration.DisableFriendlyTestNames;
var obsoleteBehavior = reqnrollConfiguration.ObsoleteBehavior;
var formatters = new Dictionary<string, FormatterConfiguration>(reqnrollConfiguration.Formatters, StringComparer.OrdinalIgnoreCase);

if (jsonConfig.Language != null)
{
Expand Down Expand Up @@ -106,6 +109,13 @@ public ReqnrollConfiguration LoadJson(ReqnrollConfiguration reqnrollConfiguratio
}
}

if (jsonConfig.Formatters != null)
{
foreach (var formatterEntry in jsonConfig.Formatters)
{
formatters[formatterEntry.Key] = FormattersConfigExtractor.ConvertFormatterOptions(formatterEntry.Value);
}
}
return new ReqnrollConfiguration(
ConfigSource.Json,
containerRegistrationCollection,
Expand All @@ -124,7 +134,8 @@ public ReqnrollConfiguration LoadJson(ReqnrollConfiguration reqnrollConfiguratio
addNonParallelizableMarkerForTags,
disableFriendlyTestNames,
obsoleteBehavior,
coloredOutput
coloredOutput,
formatters
)
{
ConfigSourceText = jsonContent
Expand Down
11 changes: 9 additions & 2 deletions Reqnroll/Configuration/ReqnrollConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Globalization;
using System.Linq;
using Reqnroll.BindingSkeletons;
using Reqnroll.Formatters.Configuration;

namespace Reqnroll.Configuration
{
Expand Down Expand Up @@ -33,7 +34,8 @@ public ReqnrollConfiguration(ConfigSource configSource,
string[] addNonParallelizableMarkerForTags,
bool disableFriendlyTestNames,
ObsoleteBehavior obsoleteBehavior,
bool coloredOutput
bool coloredOutput,
IDictionary<string, FormatterConfiguration> formatters
)
{
ConfigSource = configSource;
Expand All @@ -54,6 +56,7 @@ bool coloredOutput
DisableFriendlyTestNames = disableFriendlyTestNames;
ObsoleteBehavior = obsoleteBehavior;
ColoredOutput = coloredOutput;
Formatters = formatters ?? new Dictionary<string, FormatterConfiguration>(StringComparer.OrdinalIgnoreCase);
}

public ConfigSource ConfigSource { get; set; }
Expand Down Expand Up @@ -86,6 +89,8 @@ bool coloredOutput

public List<string> AdditionalStepAssemblies { get; set; }

public IDictionary<string, FormatterConfiguration> Formatters { get; set; }

protected bool Equals(ReqnrollConfiguration other) => ConfigSource == other.ConfigSource
&& Equals(CustomDependencies, other.CustomDependencies)
&& Equals(GeneratorCustomDependencies, other.GeneratorCustomDependencies)
Expand All @@ -102,7 +107,8 @@ protected bool Equals(ReqnrollConfiguration other) => ConfigSource == other.Conf
&& StepDefinitionSkeletonStyle == other.StepDefinitionSkeletonStyle
&& AdditionalStepAssemblies.SequenceEqual(other.AdditionalStepAssemblies)
&& AddNonParallelizableMarkerForTags.SequenceEqual(other.AddNonParallelizableMarkerForTags)
&& DisableFriendlyTestNames == other.DisableFriendlyTestNames;
&& DisableFriendlyTestNames == other.DisableFriendlyTestNames
&& Formatters == other.Formatters;

public override bool Equals(object obj)
{
Expand Down Expand Up @@ -145,6 +151,7 @@ public override int GetHashCode()
hashCode = (hashCode * 397) ^ (AdditionalStepAssemblies != null ? AdditionalStepAssemblies.GetHashCode() : 0);
hashCode = (hashCode * 397) ^ (AddNonParallelizableMarkerForTags != null ? AddNonParallelizableMarkerForTags.GetHashCode() : 0);
hashCode = (hashCode * 397) ^ DisableFriendlyTestNames.GetHashCode();
hashCode = (hashCode * 397) ^ (Formatters != null ? Formatters.GetHashCode() : 0);
return hashCode;
}
}
Expand Down

This file was deleted.

Loading
Loading