-
Notifications
You must be signed in to change notification settings - Fork 84
Open
Labels
need-more-infoNeeds more information or there a pending questions that need answering.Needs more information or there a pending questions that need answering.
Description
When using the fluent interface the ExecutableAttributes (Given, When, Then) are not supported.
Here is some example code to illustrate how it might be implemented:
void Main()
{
var cts = new CancellationTokenSource(TimeSpan.FromSeconds(1));
var bez = "bez";
new Foo().Given(s => s.BarAsync("let", bez, cts.Token));
}
public sealed class Foo
{
[When("foo {0} {1} baz")]
public ValueTask<int> BarAsync(string let, string bar, CancellationToken cancellationToken)
{
return ValueTask.FromResult(0);
}
}
public static class TestExtensions
{
private static IEnumerable<Type> GetParentTypes(this Type type)
{
yield return type;
if (type.BaseType == null) yield break;
yield return type.BaseType;
foreach (Type b in type.BaseType.GetParentTypes())
{
yield return b;
}
}
private static object GetValue(this MemberInfo memberInfo, object forObject)
{
switch (memberInfo.MemberType)
{
case MemberTypes.Field:
return ((FieldInfo)memberInfo).GetValue(forObject);
case MemberTypes.Property:
return ((PropertyInfo)memberInfo).GetValue(forObject);
default:
throw new NotImplementedException();
}
}
public static void Given<T>(this T model, Expression<Func<T, ValueTask<int>>> expression)
where T:class
{
var argumentProvider = (expression.Body as MethodCallExpression);
var formatString = argumentProvider
.Method
.CustomAttributes
.Where(cad => cad.AttributeType.GetParentTypes().Any(t => t == typeof(ExecutableAttribute)))
.Select(c => (ExecutableAttribute)c.Constructor.Invoke(c.ConstructorArguments.Select(c => c.Value).ToArray()))
.Select(e => e.StepTitle)
.FirstOrDefault();
for (int i = 0; i < argumentProvider.Arguments.Count; i++)
{
if (!formatString.Contains("{" + i + "}")) continue;
var argumentExpression = argumentProvider.Arguments[i];
if (argumentExpression.NodeType == ExpressionType.Constant)
{
var str = argumentExpression.ToString();
formatString = formatString.Replace("{" + i + "}", str);
}
else if(argumentExpression is MemberExpression me)
{
if (me.Expression is ConstantExpression ce)
{
var value = me.Member.GetValue(ce.Value)?.ToString();
formatString = formatString.Replace("{" + i + "}", value);
}
}
}
Console.WriteLine(formatString); // foo "let" bez baz
}
}Metadata
Metadata
Assignees
Labels
need-more-infoNeeds more information or there a pending questions that need answering.Needs more information or there a pending questions that need answering.