SpecFlow.VisualStudio icon indicating copy to clipboard operation
SpecFlow.VisualStudio copied to clipboard

standardizing regular expressions using constants breaks vs integration as steps don't resolve (stay purple)

Open BasHamer opened this issue 7 years ago • 4 comments

SpecFlow Version:

  • [] 2.2
  • [x] 2.1
  • [ ] 2.0
  • [ ] 1.9

Used Test Runner

  • [x ] SpecFlow+Runner
  • [ ] MSTest
  • [ ] NUnit
  • [ ] Xunit

Version number:

Visual Studio Version

  • [x ] VS 2017
  • [ ] VS 2015
  • [ ] VS 2013

Are the latest Visual Studio updates installed?

  • [x ] Yes
  • [ ] No

.NET Framework:

  • [x ] >= .NET 4
  • [ ] before .NET 4

Test Execution Method:

  • [x ] Visual Studio Test Explorer
  • [ ] TFS/VSTS – Task – PLEASE SPECIFY THE NAME OF THE TASK
  • [ ] Command line – PLEASE SPECIFY THE FULL COMMAND LINE

<SpecFlow> Section in app.config


Repro Project

@framework Feature: Variables

Background: Given the Domain Objects | Var | Id | Name | Fraction | | P | 42 | Bob | 42.5 | Given the Domain Objects | Var | Id | Name | Fraction | Parrent | | C | 24 | Bob | 42.5 | P |

Scenario: strings Given a "string" as a string argument Given a "string of "bob"" as a string argument Given a "2345.dsfsdf.werwer" as a string argument Given a P.Name as a string argument

Scenario: object Given a P as a object argument Given a {"Name":"Joe","Id":43} as a object argument Given a C.Parrent as a object argument Given a null as a object argument

Scenario: float Given a 42 as a float argument Given a 42.556 as a float argument Given a P.Fraction as a float argument

Scenario: int Given a 42 as a int argument Given a P.Id as a int argument

Scenario: bool Given a true as a bool argument Given a false as a bool argument

Scenario: list of strings Given a [] as a List string argument Given a ["string"] as a List string argument Given a ["string of "bob""] as a List string argument Given a [P.Name] as a List string argument Given a ["bubbles", "string"] as a List string argument Given a ["bubbles", "string of "bob""] as a List string argument Given a ["bubbles", P.Name] as a List string argument

Scenario: list of object Given a [] as a list object argument Given a [P] as a list object argument Given a [null] as a list object argument Given a [{"Name":"Joe","Id":43}] as a list object argument Given a [C.Parrent] as a list object argument Given a [P, P] as a list object argument Given a [P, {"Name":"Joe","Id":43}] as a list object argument Given a [P, C.Parrent] as a list object argument

Scenario: list of float Given a [] as a list float argument Given a [42] as a list float argument Given a [42.556] as a list float argument Given a [P.Fraction] as a list float argument Given a [3.14, 42] as a list float argument Given a [3.14, 42.556] as a list float argument Given a [3.14, P.Fraction] as a list float argument

Scenario: list of int Given a [] as a list int argument Given a [42] as a list int argument Given a [P.Id] as a list int argument Given a [3, 42] as a list int argument Given a [3, P.Id] as a list int argument

Scenario: list of bool Given a [true] as a list bool argument Given a [false] as a list bool argument Given a [true, false] as a list bool argument

public static class Rx
{
    private const string ObjPattern = @"[a-zA-Z][\w]*(?:\.[a-zA-Z][\w]*)*";
    private const string ObjPathPattern = @"[a-zA-Z][\w]*(?:\.[a-zA-Z][\w]*)+";
    private const string JsonObjPattern = @"{(?:\"".*\"":.*)*}";

    //Mainly for sanity
    private const string listPattern = @"(\[\s*(?:item(?:\s*,\s*item)*)?\s*])";

    private const string ObjectPattern = @"(?:(?:" + ObjPattern + @")|(?:" + JsonObjPattern + @"))";
    private const string IntPattern = @"(?:(?:" + ObjPathPattern + @")|(?:[0-9]+))";
    private const string FloatPattern = @"(?:(?:" + ObjPathPattern + @")|(?:[0-9]+(?:\.[0-9]+)?))";
    private const string StringPattern = @"(?:(?:" + ObjPathPattern + @")|(?:""(?:[^""\\]|\\.)*""))";
    private const string BoolPattern = @"(?:(?:" + ObjPathPattern + @")|(?:true)|(?:false))";

    public const string Object = @"("+ ObjectPattern + @")";
    public const string Int = @"("+ IntPattern + @")";
    public const string Float = @"("+ FloatPattern + @")";
    public const string String = @"("+ StringPattern + @")";
    public const string Bool = @"("+ BoolPattern + @")";


    public const string ListObject = @"(\[\s*(?:"+ ObjectPattern + @"(?:\s*,\s*"+ ObjectPattern + @")*)?\s*])";
    public const string ListInt = @"(\[\s*(?:"+ IntPattern + @"(?:\s*,\s*"+ IntPattern + @")*)?\s*])";
    public const string ListFloat = @"(\[\s*(?:"+ FloatPattern + @"(?:\s*,\s*"+ FloatPattern + @")*)?\s*])";
    public const string ListString = @"(\[\s*(?:"+ StringPattern + @"(?:\s*,\s*"+ StringPattern + @")*)?\s*])";
    public const string ListBool = @"(\[\s*(?:"+ BoolPattern + @"(?:\s*,\s*"+ BoolPattern + @")*)?\s*])";
}

[Binding]
public class VariablesSteps
{
    [Given(@"the Domain Objects")]
    public void GivenTheDomainObjects(Table table)
    {
    }

    [Given(@"a " + Rx.String + " as a string argument")]
    public void GivenAAsAStringArgument(string p0)
    {
    }


    [Given(@"a "+Rx.Object+" as a object argument")]
    public void GivenAPAsAObjectArgument(string p0)
    {
    }

    [Given(@"a " + Rx.Float + " as a float argument")]
    public void GivenAAsAFloatArgument(string p0)
    {
    }

    [Given(@"a " + Rx.Int + " as a int argument")]
    public void GivenAAsAIntArgument(string p0)
    {
    }


    [Given(@"a " + Rx.Bool + " as a bool argument")]
    public void GivenATrueAsABoolArgument(string p0)
    {
    }


    [Given(@"a " + Rx.ListString + " as a List string argument")]
    public void GivenAAsAListStringArgument(string p0)
    {
    }

    [Given(@"a " + Rx.ListObject + " as a list object argument")]
    public void GivenAAsAListObjectArgument(string p0)
    {
    }


    [Given(@"a " + Rx.ListFloat + " as a list float argument")]
    public void GivenAAsAListFloatArgument(string p0)
    {
    }

    [Given(@"a " + Rx.ListInt + " as a list int argument")]
    public void GivenAAsAListIntArgument(string p0)
    {
    }

    [Given(@"a " + Rx.ListBool + " as a list bool argument")]
    public void GivenATrueAsAListBoolArgument(string p0)
    {
    }
}

Issue Description

when running the preceding scenarios they will all pass, when viewing them in Visual Studio they all indicate they the steps don't resolve. you can't navigate to step definition, and they show up as purple, deleting the extensions folder and restarting does not solve this.

Steps to Reproduce

BasHamer avatar Feb 02 '18 18:02 BasHamer

The Visual Studio Integration can not handle constants in the attributes. There should be an issue here that explains it deeper.

SabotageAndi avatar Feb 02 '18 19:02 SabotageAndi

I tried to find it in the source, but as we know they are constants (have to be to be used in attributes) then it is possible to find them in the code model.

BasHamer avatar Feb 02 '18 21:02 BasHamer

@BasHamer: here is the explanation from @gasparnagy about this limitation: https://github.com/techtalk/SpecFlow/issues/926#issuecomment-327132745 In the particular case it was about the Scope tag, but it also applies to other attributes.

SabotageAndi avatar Feb 12 '18 14:02 SabotageAndi

One way is to reflect the compiled assembly for the attributes that use constant, but that is not nearly as simple as that assembly cannot be allowed to enter the visual studio app domain.

Yes this means that it can fall out of sync when you have not compiled in a while. It is a 90% solution, but it can help a lot in standardization.

So plan A, read the attributes you can from the integration; plan B augment that collection with attribute information from reflection.

I looked at the vs integration code and it is not easy to dereference any of those strings.

On Feb 12, 2018 7:11 AM, "Andreas Willich" [email protected] wrote:

@BasHamer https://github.com/bashamer: here is the explanation from @gasparnagy https://github.com/gasparnagy about this limitation: SpecFlowOSS/SpecFlow#926 (comment) https://github.com/techtalk/SpecFlow/issues/926#issuecomment-327132745 In the particular case it was about the Scope tag, but it also applies to other attributes.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/techtalk/SpecFlow/issues/1019#issuecomment-364933228, or mute the thread https://github.com/notifications/unsubscribe-auth/AAIiv5Fd2qwzZiWMQaNl3mI5zEw60ftPks5tUEaHgaJpZM4R3oJX .

BasHamer avatar Feb 12 '18 15:02 BasHamer