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

[GH-1] - Checking constructor arguments passed via Substitute.For/Substitute.ForPartsOf #13

Merged
merged 38 commits into from
Jun 18, 2018

Conversation

tpodolak
Copy link
Member

@tpodolak tpodolak commented Jun 14, 2018

Substitute.For/Substitute.ForPartsOf constructor usage analyzers

This one comes together with two code fix providers. First one removes arguments from Substitute.For when used with interface. So it converts Substitute.For<IFoo>(1, 2, 3) to Substitute.For<IFoo>(). The second one replaces usages of Substitute.ForPartsOf to Substitute.For when ForPartsOf is used with interface or delegate.
When it comes to analyzers apart from the one which corresponds to beforementioned fix-providers, I've implemented:

  • analyzers for checking if constructors are accessible
  • analyzers for checking if parameters match any constructor
  • analyzers for checking if parameters count matches any constructor
  • analyzers for checking for proper usage of multi-generic For/ForPartsOf e.g Substitute.For<Class1,Class2> is invalid whereas Substitute.For<Class1, Interfacd1> is ok

There were a couple of unexpected behaviors I wasn't aware of before, such as

public class Foo(decimal x)
{
}

var x = new Foo(1); // works fine
var @for = Substitute.For<Foo>(1); // crashes in runtime during proxy generation

so if you are aware of any other corner-cases let me know. I am a bit afraid of VisualBasic implementation as I don't know that language that well (and I had to analyze the syntax model not only semantic model), it seems to work fine with the examples converted from c# but I might have missed something.

PS
I am not that good at naming things/messages so if you think given diagnostic message is not descriptive enough let me know

PPS
For some reasons github show much more files in diff then it is supposed to. Either I did a wrong merge or it is a Github issue

tpodolak added 30 commits May 27, 2018 02:00
@coveralls
Copy link

coveralls commented Jun 14, 2018

Pull Request Test Coverage Report for Build a94vxlc6i7y4fhg2

  • 0 of 0 changed or added relevant lines in 0 files are covered.
  • No unchanged relevant lines lost coverage.
  • Overall coverage decreased (-1.1%) to 97.273%

Totals Coverage Status
Change from base Build 2llh38knwbdcuwj7: -1.1%
Covered Lines: 428
Relevant Lines: 440

💛 - Coveralls

@dtchepak
Copy link
Member

This looks amazing @tpodolak! I should be able to have a more thorough look at this over the weekend.

PS: I've updated the docs to strongly advise the installation of NSubstitute.Analyzers along with the core NSubstitute package, and also included a dedicated doc page for the Analyzers project. This will go live with the next NSub release. I'll try to keep the dedicated doc page up to date with Analyzer features, but if you notice I miss any please raise an issue and I'll sort it out.

@dtchepak
Copy link
Member

Running through a large test project found false-positives if there is a generic T : class constraint. Minimal repro:

public class Sample {
        public T Foo<T>() where T : class {
            return Substitute.For<T>();
        }
}

Very edge-case, but can come up when writing some test infrastructure for a project.

@dtchepak
Copy link
Member

How do I activate the quick fixes? Jumping to the compile error location doesn't seem to give me the option:

screen shot 2018-06-16 at 12 33 26

Also these compiler errors should have NS codes like the other errors?

screen shot 2018-06-16 at 12 34 15

Ideally I think the errors should contain info on how to fix the problems. For example:

Arguments passed to Substitute.For<Foo> do not match the constructor arguments for Foo. Check the Foo constructors and make sure you have passed the required arguments and argument types.

Can only substitute for parts of classes, not interfaces or delegates. Use Substitute.For<IFoo> instead of Substitute.ForPartsOf<IFoo> here.

Can not provide constructor arguments when substituting for an interface. Use Substitute.For<IFoo>() instead.

Ideally with Foo and IFoo replaced with the actual types causing a problem. 😉

(sorry for brain-dumping all this info; I was just scribbling notes while playing around with this)

@tpodolak
Copy link
Member Author

@dtchepak

How do I activate the quick fixes? Jumping to the compile error location doesn't seem to give me the option:

Quick fixes are visible once the warning squiggle is shown in editor. This is managed by VS and it works fine for my instance of VS2017 (didnt test it on other instances). I had similar behavior once after upgrading the analyzer, I had to restart VS and reinstall the analyzer itself, so that VS picks it correctly.

fixes

Also these compiler errors should have NS codes like the other errors?

when ti comes to compiler errors, VS adds them automatically based on what is returned by analyzer, in my case it works as expected as well
devenv_2018-06-16_16-53-05

Ideally I think the errors should contain info on how to fix the problems. For example:

I will add more descriptive messaging ;]

Running through a large test project found false-positives if there is a generic T : class constraint.

Will take a lookt at this one

Copy link
Member

@alexandrnikitin alexandrnikitin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great job!! @tpodolak Thank you for doing this!

LGTM! (Although I superficially reviewed it)

@tpodolak
Copy link
Member Author

tpodolak commented Jun 16, 2018

@dtchepak

Running through a large test project found false-positives if there is a generic T : class constraint. Minimal repro:

public class Sample {
public T Foo() where T : class {
return Substitute.For();
}
}
Very edge-case, but can come up when writing some test infrastructure for a project.

This one should be fixed now

@dtchepak
Copy link
Member

@tpodolak Ah, I forgot the first rule of computing: try turning it off and on again 🤦‍♂️ . Works fine now. 😄Can confirm the T : class thing works now too. 👍

Did you want to merge this now? We can push description changes to another change (feel free to assign to me). Happy for you to merge this in whatever way is easiest for you.

@tpodolak
Copy link
Member Author

I would wait with merge as I am now working on message changes. Will push them today or tomorrow morning for the review, then we can merge. No need to create separate PR for that.

@dtchepak
Copy link
Member

@tpodolak Great. Feel free to push things out to other issues though if it is something others can work on, or even if it's just something you don't feel like working on at the moment. You're carrying the whole workload for this at the moment so don't want you getting burned out chasing up my little suggestions. 😂

@tpodolak
Copy link
Member Author

@dtchepak messages should be fixed now, please take a look if they are good enough

@dtchepak
Copy link
Member

@tpodolak Looks great 👍. I fixed a spacing issue in #14. If you're happy with that please feel free to merge the whole lot in. 😄

[GH-1] - Minor message tweaks
@tpodolak tpodolak merged commit 980eee2 into dev Jun 18, 2018
@tpodolak tpodolak deleted the GH-1-SubstituteForAnalyzers branch June 18, 2018 19:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants