diff --git a/src/xunit.analyzers.tests/Analyzers/X2000/AssertEqualShouldNotBeUsedForCollectionSizeCheckTests.cs b/src/xunit.analyzers.tests/Analyzers/X2000/AssertEqualShouldNotBeUsedForCollectionSizeCheckTests.cs index 00452e77..989761d3 100644 --- a/src/xunit.analyzers.tests/Analyzers/X2000/AssertEqualShouldNotBeUsedForCollectionSizeCheckTests.cs +++ b/src/xunit.analyzers.tests/Analyzers/X2000/AssertEqualShouldNotBeUsedForCollectionSizeCheckTests.cs @@ -11,7 +11,7 @@ public class AssertEqualShouldNotBeUsedForCollectionSizeCheckTests "Microsoft.Extensions.Primitives.StringValues.Empty.Count", }; - public static TheoryData Collections = new() + public static TheoryData DisallowedCollections = new() { "new int[0].Length", "new System.Collections.ArrayList().Count", @@ -23,19 +23,7 @@ public class AssertEqualShouldNotBeUsedForCollectionSizeCheckTests "System.Linq.Enumerable.Empty().Count()", }; - public static TheoryData CollectionsWithUnsupportedSize = new() - { - { "new int[0].Length", -1 }, - { "new System.Collections.ArrayList().Count", -2 }, - { "new System.Collections.Generic.List().Count", 2 }, - { "new System.Collections.Generic.HashSet().Count", 3 }, - { "System.Collections.Immutable.ImmutableArray.Create().Length", 42 }, - { "new System.Collections.ObjectModel.Collection().Count", 13 }, - { "new System.Collections.Generic.List().AsReadOnly().Count", 2 }, - { "System.Linq.Enumerable.Empty().Count()", 354 }, - }; - - public static TheoryData CollectionInterfaces = new() + public static TheoryData DisallowedCollectionInterfaces = new() { "ICollection", "ICollection", @@ -51,6 +39,8 @@ public async void AllowedCollection_DoesNotTrigger(string collection) class TestClass {{ void TestMethod() {{ + Xunit.Assert.Equal(0, {collection}); + Xunit.Assert.Equal(1, {collection}); Xunit.Assert.NotEqual(0, {collection}); }} }}"; @@ -59,54 +49,65 @@ void TestMethod() {{ } [Theory] - [MemberData(nameof(Collections))] - public async void FindsWarningForEmptyCollectionSizeCheck(string collection) + [MemberData(nameof(AllowedCollections))] + [MemberData(nameof(DisallowedCollections))] + public async void AllowedCheck_DoesNotTrigger(string collection) { + // Anything that's non-zero for Equal/NotEqual and non-one for Equal is allowed var source = $@" using System.Linq; class TestClass {{ void TestMethod() {{ - Xunit.Assert.Equal(0, {collection}); + Xunit.Assert.Equal(2, {collection}); + Xunit.Assert.NotEqual(1, {collection}); + Xunit.Assert.NotEqual(2, {collection}); }} }}"; - var expected = - Verify - .Diagnostic() - .WithSpan(6, 9, 6, 32 + collection.Length) - .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments("Assert.Equal()", Constants.Asserts.Empty); - await Verify.VerifyAnalyzer(source, expected); + await Verify.VerifyAnalyzer(source); } + [Theory] - [MemberData(nameof(CollectionInterfaces))] - public async void FindsWarningForCollectionInterface_Empty(string @interface) + [MemberData(nameof(DisallowedCollections))] + public async void InvalidCheckWithConcreteType_Triggers(string collection) { var source = $@" -using System.Collections; -using System.Collections.Generic; +using System.Linq; class TestClass {{ void TestMethod() {{ - {@interface} collection = null; - Xunit.Assert.Equal(0, collection.Count); + Xunit.Assert.Equal(0, {collection}); + Xunit.Assert.Equal(1, {collection}); + Xunit.Assert.NotEqual(0, {collection}); }} }}"; - var expected = + var expected = new[] + { Verify .Diagnostic() - .WithSpan(8, 9, 8, 48) + .WithSpan(6, 9, 6, 32 + collection.Length) + .WithSeverity(DiagnosticSeverity.Warning) + .WithArguments("Assert.Equal()", Constants.Asserts.Empty), + Verify + .Diagnostic() + .WithSpan(7, 9, 7, 32 + collection.Length) + .WithSeverity(DiagnosticSeverity.Warning) + .WithArguments("Assert.Equal()", Constants.Asserts.Single), + Verify + .Diagnostic() + .WithSpan(8, 9, 8, 35 + collection.Length) .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments("Assert.Equal()", Constants.Asserts.Empty); + .WithArguments("Assert.NotEqual()", Constants.Asserts.NotEmpty), + }; await Verify.VerifyAnalyzer(source, expected); } [Theory] - [MemberData(nameof(CollectionInterfaces))] - public async void FindsWarningForCollectionInterface_Single(string @interface) + [MemberData(nameof(DisallowedCollectionInterfaces))] + public async void InvalidCheckWithInterfaceType_Triggers(string @interface) { var source = $@" using System.Collections; @@ -115,65 +116,35 @@ public async void FindsWarningForCollectionInterface_Single(string @interface) class TestClass {{ void TestMethod() {{ {@interface} collection = null; + Xunit.Assert.Equal(0, collection.Count); Xunit.Assert.Equal(1, collection.Count); + Xunit.Assert.NotEqual(0, collection.Count); }} }}"; - var expected = + var expected = new[] + { Verify .Diagnostic() .WithSpan(8, 9, 8, 48) .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments("Assert.Equal()", Constants.Asserts.Single); - - await Verify.VerifyAnalyzer(source, expected); - } - - [Theory] - [MemberData(nameof(Collections))] - public async void FindsWarningForNonEmptyCollectionSizeCheck(string collection) - { - var source = $@" -using System.Linq; - -class TestClass {{ - void TestMethod() {{ - Xunit.Assert.NotEqual(0, {collection}); - }} -}}"; - var expected = + .WithArguments("Assert.Equal()", Constants.Asserts.Empty), Verify .Diagnostic() - .WithSpan(6, 9, 6, 35 + collection.Length) + .WithSpan(9, 9, 9, 48) .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments("Assert.NotEqual()", Constants.Asserts.NotEmpty); - - await Verify.VerifyAnalyzer(source, expected); - } - - [Theory] - [MemberData(nameof(Collections))] - public async void FindsWarningForSingleItemCollectionSizeCheck(string collection) - { - var source = $@" -using System.Linq; - -class TestClass {{ - void TestMethod() {{ - Xunit.Assert.Equal(1, {collection}); - }} -}}"; - var expected = + .WithArguments("Assert.Equal()", Constants.Asserts.Single), Verify .Diagnostic() - .WithSpan(6, 9, 6, 32 + collection.Length) + .WithSpan(10, 9, 10, 51) .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments("Assert.Equal()", Constants.Asserts.Single); + .WithArguments("Assert.NotEqual()", Constants.Asserts.NotEmpty), + }; await Verify.VerifyAnalyzer(source, expected); } [Fact] - public async void FindsWarningForSymbolDeclaringTypeHasZeroArity_ImplementsICollectionOfT() + public async void InvalidCheckWithCustomNonGenericCollection_Triggers() { var source = @" using System.Collections; @@ -194,73 +165,35 @@ class IntCollection : ICollection { class TestClass { void TestMethod() { + Assert.Equal(0, new IntCollection().Count); Assert.Equal(1, new IntCollection().Count); + Assert.NotEqual(0, new IntCollection().Count); } }"; - var expected = + var expected = new[] + { Verify .Diagnostic() .WithSpan(20, 9, 20, 51) .WithSeverity(DiagnosticSeverity.Warning) - .WithArguments("Assert.Equal()", Constants.Asserts.Single); + .WithArguments("Assert.Equal()", Constants.Asserts.Empty), + Verify + .Diagnostic() + .WithSpan(21, 9, 21, 51) + .WithSeverity(DiagnosticSeverity.Warning) + .WithArguments("Assert.Equal()", Constants.Asserts.Single), + Verify + .Diagnostic() + .WithSpan(22, 9, 22, 54) + .WithSeverity(DiagnosticSeverity.Warning) + .WithArguments("Assert.NotEqual()", Constants.Asserts.NotEmpty), + }; await Verify.VerifyAnalyzer(source, expected); } - [Theory] - [MemberData(nameof(Collections))] - public async void DoesNotFindWarningForNonSingleItemCollectionSizeCheck(string collection) - { - var source = $@" -using System.Linq; - -class TestClass {{ - void TestMethod() {{ - Xunit.Assert.NotEqual(1, {collection}); - }} -}}"; - - await Verify.VerifyAnalyzer(source); - } - - [Theory] - [MemberData(nameof(CollectionsWithUnsupportedSize))] - public async void DoesNotFindWarningForUnsupportedCollectionSizeCheck( - string collection, - int size) - { - var source = $@" -using System.Linq; - -class TestClass {{ - void TestMethod() {{ - Xunit.Assert.Equal({size}, {collection}); - }} -}}"; - - await Verify.VerifyAnalyzer(source); - } - - [Theory] - [MemberData(nameof(CollectionsWithUnsupportedSize))] - public async void DoesNotFindWarningForUnsupportedNonEqualCollectionSizeCheck( - string collection, - int size) - { - var source = $@" -using System.Linq; - -class TestClass {{ - void TestMethod() {{ - Xunit.Assert.NotEqual({size}, {collection}); - }} -}}"; - - await Verify.VerifyAnalyzer(source); - } - [Fact] - public async void DoesNotCrashForSymbolDeclaringTypeHasDifferentArityThanICollection_Zero() + public async void OverridingCountMethod_DoesNotTrigger() { var source = @" using System.Collections.Generic; @@ -269,28 +202,19 @@ interface IIntCollection : ICollection { new int Count { get; } } -class TestClass { - void TestMethod() { - Xunit.Assert.Equal(1, ((IIntCollection)null).Count); - } -}"; - - await Verify.VerifyAnalyzer(source); - } - - [Fact] - public async void DoesNotCrashForSymbolDeclaringTypeHasDifferentArityThanICollection_Two() - { - var source = @" -using System.Collections.Generic; +interface ICustomCollection : ICollection { + new int Count { get; } +} -interface IDictionary2 : ICollection> { +interface ICustomDictionary : ICollection> { new int Count { get; } } class TestClass { void TestMethod() { - Xunit.Assert.Equal(1, ((IDictionary2)null).Count); + Xunit.Assert.Equal(1, ((IIntCollection)null).Count); + Xunit.Assert.Equal(1, ((ICustomCollection)null).Count); + Xunit.Assert.Equal(1, ((ICustomDictionary)null).Count); } }";