Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix unused step defs #24

Merged
merged 8 commits into from
Jun 14, 2024
Merged
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
8 changes: 7 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# [vNext]

## Improvements:

* Find Unused Step Definitions Command: Improved handling of Step Definitions decorated with the 'StepDefinition' attribute. If a Step Definition is used in any Given/Then/When step in a Feature file, the step will no longer show in the 'Find Unused Step Definitions' context menu.

*Contributors of this release (in alphabetical order):* @UL-ChrisGlew

# v2024.2.93 - 2024-06-05

## Improvements:
Expand All @@ -19,4 +25,4 @@
* Support for .NET 8 projects
* New editor command: "Go To Hooks" (Ctrl B,H) to navigate to the hooks related to the scenario
* The "Go To Definition" lists hooks when invoked from scenario header (tags, header line, description)
* Initial release based on v2022.1.91 of the [SpecFlow for Visual Studio](https://github.com/SpecFlowOSS/SpecFlow.VS/) extension.
* Initial release based on v2022.1.91 of the [SpecFlow for Visual Studio](https://github.com/SpecFlowOSS/SpecFlow.VS/) extension.
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@ public UnusedStepDefinitionsFinder(IIdeScope ideScope) : base(ideScope)
_ideScope = ideScope;
}

public IEnumerable<ProjectStepDefinitionBinding> FindUnused(ProjectBindingRegistry bindingRegistry,
string[] featureFiles, DeveroomConfiguration configuration)
public IEnumerable<ProjectStepDefinitionBinding> FindUnused(ProjectBindingRegistry bindingRegistry, string[] featureFiles, DeveroomConfiguration configuration)
{
var stepDefUsageCounts = bindingRegistry.StepDefinitions.ToDictionary(stepDef => stepDef, _ => 0);
foreach (var ff in featureFiles)
Expand All @@ -28,7 +27,9 @@ public IEnumerable<ProjectStepDefinitionBinding> FindUnused(ProjectBindingRegist
foreach (var step in usedSteps) stepDefUsageCounts[step]++;
}

return stepDefUsageCounts.Where(x => x.Value == 0).Select(x => x.Key);
var allUsedSteps = stepDefUsageCounts.Where(x => x.Value > 0).Select(x => x.Key).ToList();
var allUnusedSteps = stepDefUsageCounts.Where(x => x.Value == 0).Select(x => x.Key);
return allUnusedSteps.Where(x => !allUsedSteps.Any(y => y.Expression.Equals(x.Expression) && ReferenceEquals(x.Implementation, y.Implementation)));
}

protected IEnumerable<ProjectStepDefinitionBinding> FindUsed(ProjectBindingRegistry bindingRegistry,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,19 @@ public async Task Can_find_a_StepDefinition_With_Multiple_Step_Attributes_Not_Us
.HaveCount(2).And
.Contain(mi => mi.Label == "Steps.cs(10,9): [When(\"I choose add\")] WhenIPressAdd");
}


[Fact]
public async Task Cannot_find_an_unused_StepDefinition_With_StepDefinition_Attribute()
{
var stepDefinition = ArrangeStepDefinition(@"""I press add""", "StepDefinition");
var featureFile = ArrangeOneFeatureFile();
var (textView, command) = await ArrangeSut(stepDefinition, featureFile);

await InvokeAndWaitAnalyticsEvent(command, textView);

(ProjectScope.IdeScope.Actions as StubIdeActions)!.LastShowContextMenuItems.Should()
.HaveCount(1).And
.Contain(mi => mi.Label == "There are no unused step definitions");
}
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
using Gherkin.CucumberMessages.Types;
using Newtonsoft.Json;

namespace Reqnroll.VisualStudio.VsxStubs.StepDefinitions;

public class MockableDiscoveryService : DiscoveryService
Expand All @@ -22,11 +25,34 @@ public static MockableDiscoveryService SetupWithInitialStepDefinitions(IProjectS
{
var discoveryResultProviderMock = new Mock<IDiscoveryResultProvider>(MockBehavior.Strict);

var allStepDefinitions = new List<StepDefinition>();
foreach (var stepDefinition in stepDefinitions)
{
if (stepDefinition.Type.Equals("StepDefinition"))
{
var serialized = JsonConvert.SerializeObject(stepDefinition);
var stepDefAttributes = new List<string>() { "Given", "Then", "When" };
foreach (string stepDefAttribute in stepDefAttributes)
{
StepDefinition? clonedStepDef = JsonConvert.DeserializeObject<StepDefinition>(serialized);
if (clonedStepDef != null)
{
clonedStepDef.Type = stepDefAttribute;
allStepDefinitions.Add(clonedStepDef);
}
}
}
else
{
allStepDefinitions.Add(stepDefinition);
}
}

var discoveryService = new MockableDiscoveryService(projectScope, discoveryResultProviderMock)
{
LastDiscoveryResult = new DiscoveryResult
{
StepDefinitions = stepDefinitions,
StepDefinitions = allStepDefinitions.ToArray(),
Hooks = Array.Empty<Hook>()
}
};
Expand Down
Loading