fluentassertions.analyzers icon indicating copy to clipboard operation
fluentassertions.analyzers copied to clipboard

AD0001: InvalidOperationException on 2 rules

Open Evangelink opened this issue 6 years ago • 8 comments

Description

The rules CollectionShouldContainSingleAnalyzer and CollectionShouldBeEmptyAnalyzer throws InvalidOperationException with message This operation does not apply to an empty instance.

For some weird reason, the stack trace disappear every time I try to expand the issue, this one is the only one which remains:

Severity	Code	Description	Project	File	Line	Category	Suppression State	Tool	Detail Description
Warning	AD0001	Analyzer 'FluentAssertions.Analyzers.CollectionShouldContainSingleAnalyzer' threw an exception of type 'System.InvalidOperationException' with message 'This operation does not apply to an empty instance.'.	SonarScanner.MSBuild.PreProcessor.Tests		1	Compiler	Active	FluentAssertions.Analyzers	Analyzer 'FluentAssertions.Analyzers.CollectionShouldContainSingleAnalyzer' threw the following exception:
'Exception occurred with following context:
Compilation: SonarScanner.MSBuild.PreProcessor.Tests
ISymbol: GetActiveRules_UseParamAsKey (Method)
SyntaxTree: C:\Src\SonarSource\scanner-msbuild\tests\SonarScanner.MSBuild.PreProcessor.Tests\SonarWebServiceTest.cs
SyntaxNode: [TestMethod] public void GetActiveRules_UseParamAsKey ... [MethodDeclarationSyntax]@[12810..14357) (264,8)-(305,9)

System.InvalidOperationException: This operation does not apply to an empty instance.
   at System.Collections.Immutable.ImmutableStack`1.Peek()
   at FluentAssertions.Analyzers.FluentAssertionsCSharpSyntaxVisitor.VisitElementAccessExpression(ElementAccessExpressionSyntax node)
   at Microsoft.CodeAnalysis.CSharp.Syntax.ElementAccessExpressionSyntax.Accept(CSharpSyntaxVisitor visitor)
   at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.Visit(SyntaxNode node)
   at FluentAssertions.Analyzers.FluentAssertionsCSharpSyntaxVisitor.VisitMemberAccessExpression(MemberAccessExpressionSyntax node)
   at Microsoft.CodeAnalysis.CSharp.Syntax.MemberAccessExpressionSyntax.Accept(CSharpSyntaxVisitor visitor)
   at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.Visit(SyntaxNode node)
   at FluentAssertions.Analyzers.FluentAssertionsCSharpSyntaxVisitor.VisitMemberAccessExpression(MemberAccessExpressionSyntax node)
   at Microsoft.CodeAnalysis.CSharp.Syntax.MemberAccessExpressionSyntax.Accept(CSharpSyntaxVisitor visitor)
   at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.Visit(SyntaxNode node)
   at FluentAssertions.Analyzers.FluentAssertionsCSharpSyntaxVisitor.VisitInvocationExpression(InvocationExpressionSyntax node)
   at Microsoft.CodeAnalysis.CSharp.Syntax.InvocationExpressionSyntax.Accept(CSharpSyntaxVisitor visitor)
   at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.Visit(SyntaxNode node)
   at FluentAssertions.Analyzers.FluentAssertionsCSharpSyntaxVisitor.VisitMemberAccessExpression(MemberAccessExpressionSyntax node)
   at Microsoft.CodeAnalysis.CSharp.Syntax.MemberAccessExpressionSyntax.Accept(CSharpSyntaxVisitor visitor)
   at Microsoft.CodeAnalysis.CSharp.CSharpSyntaxVisitor.Visit(SyntaxNode node)
   at FluentAssertions.Analyzers.FluentAssertionsCSharpSyntaxVisitor.VisitInvocationExpression(InvocationExpressionSyntax node)
   at Microsoft.CodeAnalysis.CSharp.Syntax.InvocationExpressionSyntax.Accept(CSharpSyntaxVisitor visitor)
   at FluentAssertions.Analyzers.FluentAssertionsAnalyzer`1.AnalyzeExpression(ExpressionSyntax expression, SemanticModel semanticModel)
   at FluentAssertions.Analyzers.FluentAssertionsAnalyzer`1.AnalyzeCodeBlock(CodeBlockAnalysisContext context)
   at Microsoft.CodeAnalysis.Diagnostics.AnalyzerExecutor.<>c__49`2.<ExecuteBlockActions>b__49_0(ValueTuple`2 data)
   at Microsoft.CodeAnalysis.Diagnostics.AnalyzerExecutor.ExecuteAndCatchIfThrows_NoLock[TArg](DiagnosticAnalyzer analyzer, Action`1 analyze, TArg argument, Nullable`1 info)
-----
'.

Complete minimal example reproducing the issue

My test project contains quite a lot of tests so it's quite hard to narrow down to the one failing but I hope that the stacktrace will help you understanding the failure.

Versions

  • Fluent Assertions Analyzers v0.11.4
  • Fluent Assertions v5.5.3
  • Targeting fwk 4.6.1

Additional Information

Seems to be related to #78

Evangelink avatar Nov 26 '18 14:11 Evangelink

I encountered the same issue in one of our projects today and was able to narrow down the issue and created a small example to reproduce the problem.

        public void Test1()
        {
            var sut = new List<Dictionary<string, string>>();
            sut.Add(new Dictionary<string, string> { {"testKey", "testValue"}});
            sut[0]["testKey"].Should().Be("testValue");
        }

Gokulaprakash avatar Jan 07 '20 21:01 Gokulaprakash

same issue here

getting

>CSC : warning AD0001: Analyzer 'FluentAssertions.Analyzers.CollectionShouldHaveElementAtAnalyzer' threw an exception of type 'System.InvalidOperationException' with message 'This operation does not apply to an empty instance.'.

bonesoul avatar Apr 14 '20 13:04 bonesoul

any updates on this?

bonesoul avatar Apr 22 '20 09:04 bonesoul

Could you share a code sample for that triggers this?

Meir017 avatar Apr 22 '20 10:04 Meir017

my best guess is;

using NodaTime;
using NodaTime.Extensions;
using System.Collections;
using System.Collections.Generic;

public class ProcessorTestsFixtureCollection : IEnumerable<object[]>
    {
        public IEnumerator<object[]> GetEnumerator()
        {
            yield return new object[]
            {
                new List<LocalDateTime>
                {
                    SystemClock.Instance.InTzdbSystemDefaultZone().GetCurrentLocalDateTime() // current hour.
                }
            };

            yield return new object[]
            {
                new List<LocalDateTime>
                {
                    SystemClock.Instance.InTzdbSystemDefaultZone().GetCurrentLocalDateTime() - Period.FromHours(1) // a hour ago.
                }
            };

            yield return new object[]
            {
                new List<LocalDateTime>
                {
                    SystemClock.Instance.InTzdbSystemDefaultZone().GetCurrentLocalDateTime() - Period.FromHours(1), // a hour ago
                    SystemClock.Instance.InTzdbSystemDefaultZone().GetCurrentLocalDateTime() // current hour
                }
            };

            yield return new object[]
            {
                new List<LocalDateTime>
                {
                    SystemClock.Instance.InTzdbSystemDefaultZone().GetCurrentLocalDateTime() - Period.FromHours(1), // two hour ago
                    SystemClock.Instance.InTzdbSystemDefaultZone().GetCurrentLocalDateTime() - Period.FromHours(2) // a hour ago
                }
            };

            yield return new object[]
            {
                new List<LocalDateTime>
                {
                    SystemClock.Instance.InTzdbSystemDefaultZone().GetCurrentLocalDateTime() - Period.FromDays(1) // a day ago
                }
            };

            yield return new object[]
            {
                new List<LocalDateTime>
                {
                    SystemClock.Instance.InTzdbSystemDefaultZone().GetCurrentLocalDateTime() - Period.FromDays(1), // a day ago
                    SystemClock.Instance.InTzdbSystemDefaultZone().GetCurrentLocalDateTime() // current day
                }
            };

            yield return new object[]
            {
                new List<LocalDateTime>
                {
                    SystemClock.Instance.InTzdbSystemDefaultZone().GetCurrentLocalDateTime() - Period.FromDays(2), // two days ago.
                    SystemClock.Instance.InTzdbSystemDefaultZone().GetCurrentLocalDateTime() - Period.FromDays(1) // a day ago.
                }
            };

            yield return new object[]
            {
                new List<LocalDateTime>
                {
                    SystemClock.Instance.InTzdbSystemDefaultZone().GetCurrentLocalDateTime() - Period.FromMonths(1) // a month ago
                }
            };

            yield return new object[]
            {
                new List<LocalDateTime>
                {
                    SystemClock.Instance.InTzdbSystemDefaultZone().GetCurrentLocalDateTime() - Period.FromMonths(1), // a month ago
                    SystemClock.Instance.InTzdbSystemDefaultZone().GetCurrentLocalDateTime() // current month
                }
            };

            yield return new object[]
            {
                new List<LocalDateTime>
                {
                    SystemClock.Instance.InTzdbSystemDefaultZone().GetCurrentLocalDateTime() - Period.FromMonths(2), // two months ago
                    SystemClock.Instance.InTzdbSystemDefaultZone().GetCurrentLocalDateTime() - Period.FromMonths(1) // a month ago.
                }
            };

            yield return new object[]
            {
                new List<LocalDateTime>
                {
                    SystemClock.Instance.InTzdbSystemDefaultZone().GetCurrentLocalDateTime() - Period.FromMonths(2) - Period.FromDays(2) - Period.FromHours(2), // 2 months, 2 days, 2 hours ago
                    SystemClock.Instance.InTzdbSystemDefaultZone().GetCurrentLocalDateTime() - Period.FromMonths(1) - Period.FromDays(1) - Period.FromHours(1) // a month, a day and a hour ago.
                }
            };
        }

        IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
    }

output;

3>CSC : warning AD0001: Analyzer 'FluentAssertions.Analyzers.CollectionShouldHaveCountAnalyzer' threw an exception of type 'System.InvalidOperationException' with message 'This operation does not apply to an empty instance.'.
3>CSC : warning AD0001: Analyzer 'FluentAssertions.Analyzers.CollectionShouldHaveCountAnalyzer' threw an exception of type 'System.InvalidOperationException' with message 'This operation does not apply to an empty instance.'.
3>CSC : warning AD0001: Analyzer 'FluentAssertions.Analyzers.CollectionShouldHaveElementAtAnalyzer' threw an exception of type 'System.InvalidOperationException' with message 'This operation does not apply to an empty instance.'.
3>CSC : warning AD0001: Analyzer 'FluentAssertions.Analyzers.CollectionShouldHaveElementAtAnalyzer' threw an exception of type 'System.InvalidOperationException' with message 'This operation does not apply to an empty instance.'.
3>CSC : warning AD0001: Analyzer 'FluentAssertions.Analyzers.CollectionShouldHaveCountAnalyzer' threw an exception of type 'System.InvalidOperationException' with message 'This operation does not apply to an empty instance.'.
3>CSC : warning AD0001: Analyzer 'FluentAssertions.Analyzers.CollectionShouldHaveElementAtAnalyzer' threw an exception of type 'System.InvalidOperationException' with message 'This operation does not apply to an empty instance.'.
3>CSC : warning AD0001: Analyzer 'FluentAssertions.Analyzers.CollectionShouldHaveCountAnalyzer' threw an exception of type 'System.InvalidOperationException' with message 'This operation does not apply to an empty instance.'.
3>CSC : warning AD0001: Analyzer 'FluentAssertions.Analyzers.CollectionShouldHaveElementAtAnalyzer' threw an exception of type 'System.InvalidOperationException' with message 'This operation does not apply to an empty instance.'.
3>CSC : warning AD0001: Analyzer 'FluentAssertions.Analyzers.CollectionShouldHaveCountAnalyzer' threw an exception of type 'System.InvalidOperationException' with message 'This operation does not apply to an empty instance.'.
3>CSC : warning AD0001: Analyzer 'FluentAssertions.Analyzers.CollectionShouldContainItemAnalyzer' threw an exception of type 'System.InvalidOperationException' with message 'This operation does not apply to an empty instance.'.
3>CSC : warning AD0001: Analyzer 'FluentAssertions.Analyzers.CollectionShouldHaveElementAtAnalyzer' threw an exception of type 'System.InvalidOperationException' with message 'This operation does not apply to an empty instance.'.
3>CSC : warning AD0001: Analyzer 'FluentAssertions.Analyzers.CollectionShouldHaveCountAnalyzer' threw an exception of type 'System.InvalidOperationException' with message 'This operation does not apply to an empty instance.'.
3>CSC : warning AD0001: Analyzer 'FluentAssertions.Analyzers.CollectionShouldHaveElementAtAnalyzer' threw an exception of type 'System.InvalidOperationException' with message 'This operation does not apply to an empty instance.'.
3>CSC : warning AD0001: Analyzer 'FluentAssertions.Analyzers.CollectionShouldHaveCountAnalyzer' threw an exception of type 'System.InvalidOperationException' with message 'This operation does not apply to an empty instance.'.
3>CSC : warning AD0001: Analyzer 'FluentAssertions.Analyzers.CollectionShouldHaveElementAtAnalyzer' threw an exception of type 'System.InvalidOperationException' with message 'This operation does not apply to an empty instance.'.
3>CSC : warning AD0001: Analyzer 'FluentAssertions.Analyzers.CollectionShouldHaveCountAnalyzer' threw an exception of type 'System.InvalidOperationException' with message 'This operation does not apply to an empty instance.'.
3>CSC : warning AD0001: Analyzer 'FluentAssertions.Analyzers.CollectionShouldHaveCountAnalyzer' threw an exception of type 'System.InvalidOperationException' with message 'This operation does not apply to an empty instance.'.
3>CSC : warning AD0001: Analyzer 'FluentAssertions.Analyzers.CollectionShouldHaveElementAtAnalyzer' threw an exception of type 'System.InvalidOperationException' with message 'This operation does not apply to an empty instance.'.
3>CSC : warning AD0001: Analyzer 'FluentAssertions.Analyzers.CollectionShouldHaveElementAtAnalyzer' threw an exception of type 'System.InvalidOperationException' with message 'This operation does not apply to an empty instance.'.
3>CSC : warning AD0001: Analyzer 'FluentAssertions.Analyzers.CollectionShouldHaveCountAnalyzer' threw an exception of type 'System.InvalidOperationException' with message 'This operation does not apply to an empty instance.'.

bonesoul avatar Apr 22 '20 10:04 bonesoul

I just hit this as well. This code works fine:

var conditions = blocks[2].Questions[1].Conditions;
conditions.Should().HaveCount(1);

This code triggers the exception:

blocks[2].Questions[1].Conditions.Should().HaveCount(1)

thomaslevesque avatar Jun 24 '20 21:06 thomaslevesque

I'm not able to reproduce this anymore, I think was fixed in #100

Meir017 avatar Oct 12 '21 18:10 Meir017

If I'm not mistaken, #100 just swallows exception. So maybe the exception is no longer visible to the user, but it doesn't mean the underlying problem (whatever it is) is solved.

thomaslevesque avatar Oct 13 '21 10:10 thomaslevesque