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

exception in errorlist #10

Closed
jnyrup opened this issue Oct 22, 2017 · 6 comments
Closed

exception in errorlist #10

jnyrup opened this issue Oct 22, 2017 · 6 comments
Labels

Comments

@jnyrup
Copy link
Member

jnyrup commented Oct 22, 2017

I get several exceptions in the error list:
The stack traces seems to be identical for all of them, see below for one of them.
A lot of the analyzers mentioned in the stack traces don't seem to apply for my test method?

I haven't been able to come up with an example that triggers the bug.
Any ideas?

Severity	Code	Description	Project	File	Line	Suppression State	Detail Description
Warning	AD0001	Analyzer 'FluentAssertions.BestPractices.CollectionShouldEqualOtherCollectionByComparerAnalyzer' threw an exception of type 'System.ArgumentException' with message 'An item with the same key has already been added.'.	CIUnitTests		1	Active	Analyzer 'FluentAssertions.BestPractices.CollectionShouldEqualOtherCollectionByComparerAnalyzer' threw the following exception:
'Exception occurred with following context:
Compilation: CIUnitTests
ISymbol: MyTest (Method)
SyntaxTree: C:\Test.cs
SyntaxNode: [TestMethod] public void MyTest ... [MethodDeclarationSyntax]@[8641..10638) (200,8)-(232,9)

System.ArgumentException: An item with the same key has already been added.
   at System.ThrowHelper.ThrowArgumentException(ExceptionResource resource)
   at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
   at System.Collections.Generic.Dictionary`2.Add(TKey key, TValue value)
   at FluentAssertions.BestPractices.FluentAssertionsWithArgumentsCSharpSyntaxVisitor.VisitArguments(SeparatedSyntaxList`1 arguments)
   at FluentAssertions.BestPractices.FluentAssertionsWithArgumentsCSharpSyntaxVisitor.VisitArgumentList(ArgumentListSyntax node)
   at Microsoft.CodeAnalysis.CSharp.Syntax.ArgumentListSyntax.Accept(CSharpSyntaxVisitor visitor)
   at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.Visit(SyntaxNode node)
   at FluentAssertions.BestPractices.FluentAssertionsCSharpSyntaxVisitor.Visit(SyntaxNode node)
   at FluentAssertions.BestPractices.FluentAssertionsCSharpSyntaxVisitor.VisitInvocationExpression(InvocationExpressionSyntax node)
   at Microsoft.CodeAnalysis.CSharp.Syntax.InvocationExpressionSyntax.Accept(CSharpSyntaxVisitor visitor)
   at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.Visit(SyntaxNode node)
   at FluentAssertions.BestPractices.FluentAssertionsCSharpSyntaxVisitor.Visit(SyntaxNode node)
   at FluentAssertions.BestPractices.FluentAssertionsCSharpSyntaxVisitor.VisitExpressionStatement(ExpressionStatementSyntax node)
   at Microsoft.CodeAnalysis.CSharp.Syntax.ExpressionStatementSyntax.Accept(CSharpSyntaxVisitor visitor)
   at FluentAssertions.BestPractices.FluentAssertionsAnalyzer`1.AnalyzeExpressionStatement(ExpressionStatementSyntax statement)
   at FluentAssertions.BestPractices.FluentAssertionsAnalyzer`1.AnalyzeCodeBlock(CodeBlockAnalysisContext context)
   at Microsoft.CodeAnalysis.Diagnostics.AnalyzerExecutor.<>c__48`2.<ExecuteBlockActions>b__48_0(ValueTuple`2 data)
   at Microsoft.CodeAnalysis.Diagnostics.AnalyzerExecutor.ExecuteAndCatchIfThrows_NoLock[TArg](DiagnosticAnalyzer analyzer, Action`1 analyze, TArg argument, Nullable`1 info)
-----
'.
@Meir017
Copy link
Member

Meir017 commented Oct 22, 2017

this following line throw https://github.com/fluentassertions/fluentassertions.analyzers/blob/master/src/FluentAssertions.Analyzers/Utilities/FluentAssertionsWithArgumentsCSharpSyntaxVisitor.cs#L31

maybe you are chaining multiple methods with the same name and both of the method calls have arguments?

@jnyrup
Copy link
Member Author

jnyrup commented Oct 22, 2017

Heureka!

public class MyClass
    {
        public string Message { get; }
    }

    class Class1
    {
        [TestMethod]
        public void MyTestMethod()
        {
            var details = new List<MyClass>();

            details.Should().Contain(d => d.Message.Contains("a"))
                .And.Contain(d => d.Message.Contains("c"));
        }
    }

@Meir017
Copy link
Member

Meir017 commented Oct 22, 2017

I had a feeling it's something like this...

Looks like another redesign to the FluentAssertionsWithArgumentsCSharpSyntaxVisitor class which extracts the methods into a dictionary containing for each method its arguments.

I'm going to add a SanityTests class (not sure about the name yet) that will include cases the should not throw exceptions (and no diagnostics), this will help

@jnyrup
Copy link
Member Author

jnyrup commented Oct 23, 2017

Be careful with flattening the syntax tree in any way.

var nestedList = new List<List<int>>();

nestedList.Should().NotBeNull()
    .And.ContainSingle()
        .Which.Should().NotBeEmpty();

is currently simplified into:

nestedList.Should().NotBeNullOrEmpty()
                .And.ContainSingle()
                    .Which.Should();

@Meir017 Meir017 added the bug label Oct 23, 2017
@Meir017
Copy link
Member

Meir017 commented Oct 23, 2017

looks like the Should could be used as some kind of separators when looking for a sequence of method calls, does this make sense?

@jnyrup
Copy link
Member Author

jnyrup commented Oct 23, 2017

As of Fluent Assertions 5.0, I guess you should be able to do so.
The API has been changed, so all assertions now start with Should().
E.g. ShouldThrow() and ShouldBeEquivalent() are now Should().Throw() and Should().BeEquivalent().

Most assertions return an AndConstraint which is a continutation on the same assertions.
Others return an AndWhichConstraint which allows you to either continue on the same assertion (the And part) or begin an assertion on some result from the assertions.
There is also WhichValueConstraint.

E.g. ContainSingle() return and AndWhich which lets you assert on that single element.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants