Skip to content

Commit

Permalink
Enhanced BindingException with sub-class AmbiguousBindingException to…
Browse files Browse the repository at this point in the history
… carry along the candidate BindingMatches that cause the ambiguity. These are used in the Step tracker and message factory to populate the array of StepDef Ids that cause the ambiguity.
  • Loading branch information
clrudolphi committed Sep 17, 2024
1 parent 5b714d3 commit fb47688
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 6 deletions.
5 changes: 3 additions & 2 deletions Reqnroll/CucumberMesssages/CucumberMessageFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,8 @@ private static SourceReference ToSourceRef(IBinding binding)

internal static TestStep ToPickleTestStep(ScenarioEventProcessor scenarioState, ScenarioStepProcessor stepState)
{
bool bound = stepState.StepDefinitionId != null;
bool bound = stepState.Bound;
bool ambiguous = stepState.Ambiguous;

var args = stepState.StepArguments
.Select(arg => CucumberMessageFactory.ToStepMatchArgument(arg))
Expand All @@ -132,7 +133,7 @@ internal static TestStep ToPickleTestStep(ScenarioEventProcessor scenarioState,
null,
stepState.TestStepID,
stepState.PickleStepID,
bound ? new List<string> { stepState.StepDefinitionId } : new List<string>(),
bound ? new List<string> { stepState.StepDefinitionId } : ambiguous ? new List<string>(stepState.AmbiguousStepDefinitions) : new List<string>(),
bound ? new List<StepMatchArgumentsList> { new StepMatchArgumentsList(args) } : new List<StepMatchArgumentsList>()
);

Expand Down
8 changes: 8 additions & 0 deletions Reqnroll/CucumberMesssages/ScenarioStepProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;

namespace Reqnroll.CucumberMessages
{
Expand All @@ -26,6 +27,8 @@ public ScenarioStepProcessor(ScenarioEventProcessor parentScenarioState) : base(
public bool Bound { get; set; }
public string CanonicalizedStepPattern { get; set; }
public string StepDefinitionId { get; private set; }
public IEnumerable<string> AmbiguousStepDefinitions { get; set; }
public bool Ambiguous { get { return AmbiguousStepDefinitions != null && AmbiguousStepDefinitions.Count() > 0;} }
public IStepDefinitionBinding StepDefinition { get; set; }

public List<StepArgument> StepArguments { get; set; }
Expand Down Expand Up @@ -64,6 +67,11 @@ internal IEnumerable<Envelope> ProcessEvent(StepFinishedEvent stepFinishedEvent)
if (Status == ScenarioExecutionStatus.TestError && stepFinishedEvent.ScenarioContext.TestError != null)
{
Exception = stepFinishedEvent.ScenarioContext.TestError;
if (Exception is AmbiguousBindingException)
{
AmbiguousStepDefinitions = new List<string>(((AmbiguousBindingException)Exception).Matches.Select(m =>
FindStepDefIDByStepPattern(CucumberMessageFactory.CanonicalizeStepDefinitionPattern(m.StepBinding))));
}
}

var argumentValues = Bound ? stepFinishedEvent.StepContext.StepInfo.BindingMatch.Arguments.Select(arg => arg.ToString()).ToList() : new List<string>();
Expand Down
49 changes: 49 additions & 0 deletions Reqnroll/ErrorHandling/BindingException.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
using Reqnroll.Bindings;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.Serialization;

// the exceptions are part of the public API, keep them in Reqnroll namespace
Expand All @@ -25,4 +28,50 @@ protected BindingException(
{
}
}

[Serializable]
public class AmbiguousBindingException : BindingException
{
public IEnumerable<BindingMatch> Matches { get; private set; }

public AmbiguousBindingException()
{
}

public AmbiguousBindingException(string message) : base(message)
{
}

public AmbiguousBindingException(string message, Exception inner) : base(message, inner)
{
}

public AmbiguousBindingException(string message, IEnumerable<BindingMatch> matches) : base(message)
{
Matches = new List<BindingMatch>(matches);
}

protected AmbiguousBindingException(
SerializationInfo info,
StreamingContext context) : base(info, context)
{
if (info == null)
{
throw new ArgumentNullException(nameof(info));
}

Matches = (List<BindingMatch>)info.GetValue("Matches", typeof(List<BindingMatch>));
}

public override void GetObjectData(SerializationInfo info, StreamingContext context)
{
if (info == null)
{
throw new ArgumentNullException(nameof(info));
}

base.GetObjectData(info, context);
info.AddValue("Matches", Matches);
}
}
}
10 changes: 6 additions & 4 deletions Reqnroll/ErrorHandling/ErrorProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,17 +59,19 @@ public Exception GetParameterCountError(BindingMatch match, int expectedParamete
public Exception GetAmbiguousMatchError(List<BindingMatch> matches, StepInstance stepInstance)
{
string stepDescription = stepFormatter.GetStepDescription(stepInstance);
return new BindingException(
$"Ambiguous step definitions found for step '{stepDescription}': {string.Join(", ", matches.Select(m => GetMethodText(m.StepBinding.Method)).ToArray())}");
return new AmbiguousBindingException(
$"Ambiguous step definitions found for step '{stepDescription}': {string.Join(", ", matches.Select(m => GetMethodText(m.StepBinding.Method)).ToArray())}",
matches);
}


public Exception GetAmbiguousBecauseParamCheckMatchError(List<BindingMatch> matches, StepInstance stepInstance)
{
string stepDescription = stepFormatter.GetStepDescription(stepInstance);
return new BindingException(
return new AmbiguousBindingException(
"Multiple step definitions found, but none of them have matching parameter count and type for step "
+ $"'{stepDescription}': {string.Join(", ", matches.Select(m => GetMethodText(m.StepBinding.Method)).ToArray())}");
+ $"'{stepDescription}': {string.Join(", ", matches.Select(m => GetMethodText(m.StepBinding.Method)).ToArray())}",
matches);
}

public Exception GetNoMatchBecauseOfScopeFilterError(List<BindingMatch> matches, StepInstance stepInstance)
Expand Down

0 comments on commit fb47688

Please sign in to comment.