Skip to content

Commit

Permalink
fix Table SpecFlow compatibility
Browse files Browse the repository at this point in the history
  • Loading branch information
gasparnagy committed Jan 29, 2024
1 parent 0cafb18 commit a5baaf1
Show file tree
Hide file tree
Showing 6 changed files with 154 additions and 73 deletions.
Original file line number Diff line number Diff line change
@@ -1,3 +1,60 @@
// ReSharper disable once CheckNamespace
using System.ComponentModel;
using System.Globalization;
using System;

// ReSharper disable once CheckNamespace
namespace TechTalk.SpecFlow;
public class Table(params string[] header) : Reqnroll.Table(header);

[TypeConverter(typeof(SpecFlowTableConverter))]
public class Table : Reqnroll.Table
{
public Table(params string[] header) : base(header)
{
}

protected internal Table(Reqnroll.Table copyFrom) : base(copyFrom)
{
}
}

internal class SpecFlowTableConverter : TypeConverter
{
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
return typeof(Reqnroll.Table).IsAssignableFrom(sourceType);
}

public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
{
if (value == null)
return null;

if (value is Table specFlowTable)
return specFlowTable;

if (value is Reqnroll.Table tableValue)
{
return new Table(tableValue);
}

return base.ConvertFrom(context, culture, value);
}

public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
return destinationType == typeof(Reqnroll.Table);
}

public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
{
if (destinationType == typeof(Table) || value == null)
return value;

if (destinationType == typeof(Reqnroll.Table) && value is Table specFlowTable)
{
return new Reqnroll.Table(specFlowTable);
}

return base.ConvertTo(context, culture, value, destinationType);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using System;
using BoDi;
using Reqnroll;

// ReSharper disable once CheckNamespace
namespace TechTalk.SpecFlow;

public class TestThreadContext(Reqnroll.TestThreadContext originalContext) : ITestThreadContext
{
public Exception TestError => originalContext.TestError;

public IObjectContainer TestThreadContainer => originalContext.TestThreadContainer;
}
2 changes: 2 additions & 0 deletions Reqnroll/AssemblyAttributes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@
#if REQNROLL_ENABLE_STRONG_NAME_SIGNING
[assembly: InternalsVisibleTo("Reqnroll.RuntimeTests, PublicKey=002400000480000094000000060200000024000052534131000400000100010059bb085601a8b65a8a7b00f34e6d85df230f1e4913d3c0eaadcd13c1fd9cd15c3f01567c49d5f41f617dbda6f544ea3e2d5b5a042f307a7c8d21a079254509ba543efaefce96fac977abd0a76206b721abc33f84ee45ae5383cf50eeb8e234595656fd4af916e1dcde644ce20bb9a68bd72bc7957b759560524c63ca294585ca")]
[assembly: InternalsVisibleTo("Reqnroll.PluginTests, PublicKey=002400000480000094000000060200000024000052534131000400000100010059bb085601a8b65a8a7b00f34e6d85df230f1e4913d3c0eaadcd13c1fd9cd15c3f01567c49d5f41f617dbda6f544ea3e2d5b5a042f307a7c8d21a079254509ba543efaefce96fac977abd0a76206b721abc33f84ee45ae5383cf50eeb8e234595656fd4af916e1dcde644ce20bb9a68bd72bc7957b759560524c63ca294585ca")]
[assembly: InternalsVisibleTo("Reqnroll.SpecFlowCompatibility.ReqnrollPlugin, PublicKey=002400000480000094000000060200000024000052534131000400000100010059bb085601a8b65a8a7b00f34e6d85df230f1e4913d3c0eaadcd13c1fd9cd15c3f01567c49d5f41f617dbda6f544ea3e2d5b5a042f307a7c8d21a079254509ba543efaefce96fac977abd0a76206b721abc33f84ee45ae5383cf50eeb8e234595656fd4af916e1dcde644ce20bb9a68bd72bc7957b759560524c63ca294585ca")]
#else
[assembly: InternalsVisibleTo("Reqnroll.RuntimeTests")]
[assembly: InternalsVisibleTo("Reqnroll.PluginTests")]
[assembly: InternalsVisibleTo("Reqnroll.SpecFlowCompatibility.ReqnrollPlugin")]
#endif
14 changes: 11 additions & 3 deletions Reqnroll/Bindings/StepArgumentTypeConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ private async Task<object> DoTransformAsync(IStepArgumentTransformationBinding s
if (stepTransformation.Regex != null && value is string stringValue)
arguments = await GetStepTransformationArgumentsFromRegexAsync(stepTransformation, stringValue, cultureInfo);
else
arguments = new[] {value};
arguments = new[] { await ConvertAsync(value, stepTransformation.Method.Parameters.ElementAtOrDefault(0)?.Type ?? new RuntimeBindingType(typeof(object)), cultureInfo)};

var result = await bindingInvoker.InvokeBindingAsync(stepTransformation, contextManager, arguments, testTracer, new DurationHolder());

Expand Down Expand Up @@ -103,14 +103,22 @@ private bool CanConvert(IStepArgumentTransformationBinding stepTransformationBin
if (stepTransformationBinding.Regex != null && valueToConvert is string stringValue)
return stepTransformationBinding.Regex.IsMatch(stringValue);

var transformationFirstArgumentTypeName = stepTransformationBinding.Method.Parameters.FirstOrDefault()?.Type.FullName;
var transformationFirstArgumentType = stepTransformationBinding.Method.Parameters.FirstOrDefault()?.Type;

var isTableStepTransformation = transformationFirstArgumentTypeName == typeof(Table).FullName;
var isTableStepTransformation = transformationFirstArgumentType != null &&
IsDataTableType(transformationFirstArgumentType);
var valueIsTable = valueToConvert is Table;

return isTableStepTransformation == valueIsTable;
}

protected virtual bool IsDataTableType(IBindingType bindingType)
{
return bindingType.FullName == typeof(Table).FullName ||
(bindingType is RuntimeBindingType runtimeBindingType &&
typeof(Table).IsAssignableFrom(runtimeBindingType));
}

private static object ConvertSimple(IBindingType typeToConvertTo, object value, CultureInfo cultureInfo)
{
if (typeToConvertTo is not RuntimeBindingType runtimeBindingType)
Expand Down
Loading

0 comments on commit a5baaf1

Please sign in to comment.