public async void DoesNotFindErrorForIDisposableDisposeMethodOverrideFromParentClass() { var diagnostics = await CodeAnalyzerHelper.GetDiagnosticsAsync(analyzer, @"public class BaseClass : System.IDisposable { public virtual void Dispose() { } } public class TestClass : BaseClass { [Xunit.Fact] public void TestMethod() { } public override void Dispose() { } }"); Assert.Empty(diagnostics); }
public async void FindsError_WhenInlineDataDuplicateAndOriginalAreItemsOfDistinctAttributesLists() { var diagnostics = await CodeAnalyzerHelper.GetDiagnosticsAsync(analyzer, "public class TestClass" + "{" + " [Xunit.Theory]" + " [Xunit.InlineData(10, 20), Xunit.InlineData(30, 40)]" + Environment.NewLine + " [Xunit.InlineData(50, 60), Xunit.InlineData(10, 20)]" + " public void TestMethod(int x, int y) { } " + "}"); Assert.Collection(diagnostics, VerifyDiagnostic); }
public async void FindsWarningForPublicMethodWithParametersInTestClass(string attribute) { var diagnostics = await CodeAnalyzerHelper.GetDiagnosticsAsync(analyzer, "public class TestClass { [" + attribute + "] public void TestMethod() { } public void Method(int a) {} }"); Assert.Collection(diagnostics, d => { Assert.Equal("Public method 'Method' on test class 'TestClass' should be marked as a Theory.", d.GetMessage()); Assert.Equal("xUnit1013", d.Id); Assert.Equal(DiagnosticSeverity.Warning, d.Severity); }); }
public async void DoesNotCrashForSymbolDeclaringTypeHasDifferentArityThanICollection_Two() { var diagnostics = await CodeAnalyzerHelper.GetDiagnosticsAsync(analyzer, @"using System.Collections.Generic; interface IDictionary2<K, V> : ICollection<KeyValuePair<K, V>> { new int Count { get; } } class TestClass { void TestMethod() { Xunit.Assert.Equal(1, ((IDictionary2<int, int>)null).Count); } }"); Assert.Empty(diagnostics); }
public async void FindsError_WhenArgumentsAreArrayOfValues() { var diagnostics = await CodeAnalyzerHelper.GetDiagnosticsAsync(analyzer, "public class TestClass" + "{" + " [Xunit.Theory]" + " [Xunit.InlineData(new object[] {10, new object[] { new object[] {20}, 30}})]" + " [Xunit.InlineData(new object[] {10, new object[] { new object[] {20}, 30}})]" + " public void TestMethod(object x, object y) { }" + "}"); Assert.Collection(diagnostics, VerifyDiagnostic); }
public async void FindsError_ForEnumArgument(string type) { var diagnostics = await CodeAnalyzerHelper.GetDiagnosticsAsync(analyzer, "public class TestClass { [Xunit.Theory, Xunit.InlineData(System.StringComparison.InvariantCulture)] public void TestMethod(" + type + " a) { } }"); Assert.Collection(diagnostics, d => { Assert.Equal("The value is not convertible to the method parameter 'a' of type '" + type + "'.", d.GetMessage()); Assert.Equal("xUnit1010", d.Descriptor.Id); }); }
public async void FindsWarning_ForSingleNullValue(string type) { var diagnostics = await CodeAnalyzerHelper.GetDiagnosticsAsync(analyzer, "public class TestClass { [Xunit.Theory, Xunit.InlineData(null)] public void TestMethod(" + type + " a) { } }"); Assert.Collection(diagnostics, d => { Assert.Equal("Null should not be used for value type parameter 'a' of type 'int'.", d.GetMessage()); Assert.Equal("xUnit1012", d.Descriptor.Id); Assert.Equal(DiagnosticSeverity.Warning, d.Severity); }); }
public async void FindsError_UsingParams() { var diagnostics = await CodeAnalyzerHelper.GetDiagnosticsAsync(analyzer, "public class TestClass { [Xunit.Theory, Xunit.InlineData(1)] public void TestMethod(int a, int b, params string[] value) { } }"); Assert.Collection(diagnostics, d => { Assert.Equal("InlineData values must match the number of method parameters", d.GetMessage()); Assert.Equal("xUnit1009", d.Descriptor.Id); Assert.Equal(DiagnosticSeverity.Error, d.Severity); }); }
public async void FindsError_ForStringReferenceOnOtherClass() { var diagnostics = await CodeAnalyzerHelper.GetDiagnosticsAsync(analyzer, sharedCode, "public partial class TestClass { [Xunit.MemberData(\"OtherData\", MemberType = typeof(OtherClass))] public void TestMethod() { } }"); Assert.Collection(diagnostics, d => { Assert.Equal("MemberData should use nameof operator to reference member 'OtherData' on type 'OtherClass'.", d.GetMessage()); Assert.Equal("xUnit1014", d.Descriptor.Id); }); }
public async Task FindsWarning_ForThrowsCheck_WithExceptionParameter_OnThrowingMethod(string method) { var diagnostics = await CodeAnalyzerHelper.GetDiagnosticsAsync(analyzer, @"class TestClass { System.Threading.Tasks.Task ThrowingMethod() { throw new System.NotImplementedException(); } void TestMethod() { Xunit.Assert." + method + @"(typeof(System.NotImplementedException), ThrowingMethod); } }"); AssertHasDiagnostic(diagnostics); }
public async void DoesNotFindWarning_ForClassConstrainedGenericTypes(string method) { var diagnostics = await CodeAnalyzerHelper.GetDiagnosticsAsync(analyzer, @" class Class<T> where T : class { public void Method(T arg) { Xunit.Assert." + method + @"(arg); } }"); Assert.Empty(diagnostics); }
public async Task FindsWarning_ForThrowsCheck_WithExceptionParameter_OnAsyncThrowingLambda() { var diagnostics = await CodeAnalyzerHelper.GetDiagnosticsAsync(analyzer, @"class TestClass { void TestMethod() { Xunit.Assert.Throws(typeof(System.NotImplementedException), async () => await System.Threading.Tasks.Task.Delay(0)); } }"); Assert.Collection(diagnostics, d => { Assert.Equal("Do not use Assert.Throws() to check for asynchronously thrown exceptions.", d.GetMessage()); Assert.Equal("xUnit2014", d.Id); Assert.Equal(DiagnosticSeverity.Error, d.Severity); }); }
public async void FindsWarningForFalseCollectionContainsCheck(string collection) { var diagnostics = await CodeAnalyzerHelper.GetDiagnosticsAsync(analyzer, @"class TestClass { void TestMethod() { Xunit.Assert.False(" + collection + @".Contains(1)); } }"); Assert.Collection(diagnostics, d => { Assert.Equal("Do not use Contains() to check if a value exists in a collection.", d.GetMessage()); Assert.Equal("xUnit2017", d.Id); Assert.Equal(DiagnosticSeverity.Warning, d.Severity); }); }
public async void InterfaceWithBadBaseClass_ReturnsError(string @interface) { var code = string.Format(Template, $"Foo, {@interface}"); var diagnostics = await CodeAnalyzerHelper.GetDiagnosticsAsync(analyzer, CompilationReporting.IgnoreErrors, code); Assert.Collection(diagnostics, d => { Assert.Equal("Test case class MyTestCase must derive directly or indirectly from Xunit.LongLivedMarshalByRefObject", d.GetMessage()); Assert.Equal("xUnit3000", d.Descriptor.Id); } ); }
public async void MakesClassPublic(string nonPublicAccessModifier) { var source = $@" [Xunit.CollectionDefinition(""MyCollection"")] { nonPublicAccessModifier} class CollectionDefinitionClass {{ }}"; var expected = @" [Xunit.CollectionDefinition(""MyCollection"")] public class CollectionDefinitionClass { }"; var actual = await CodeAnalyzerHelper.GetFixedCodeAsync(analyzer, fixer, source); Assert.Equal(expected, actual); }
public async void DoesNotFindWarning_ForThrowsAnyAsyncCheck_WithExceptionTypeArgument_OnThrowingMethod() { var diagnostics = await CodeAnalyzerHelper.GetDiagnosticsAsync(analyzer, @"class TestClass { System.Threading.Tasks.Task ThrowingMethod() { throw new System.NotImplementedException(); } async System.Threading.Tasks.Task TestMethod() { await Xunit.Assert.ThrowsAnyAsync<System.NotImplementedException>(ThrowingMethod); } }"); Assert.Empty(diagnostics); }
public async void FindsWarningForStrictStringEqualityCheckWithGenericType(string expected, string value) { var diagnostics = await CodeAnalyzerHelper.GetDiagnosticsAsync(analyzer, @"class TestClass { void TestMethod() { Xunit.Assert.StrictEqual<string>(" + expected + @", " + value + @"); } }"); Assert.Collection(diagnostics, d => { Assert.Equal("Do not use Assert.StrictEqual to test for string equality.", d.GetMessage()); Assert.Equal("xUnit2006", d.Id); Assert.Equal(DiagnosticSeverity.Warning, d.Severity); }); }
public async Task FindsWarning_ForThrowsCheck_WithExceptionTypeArgument_OnThrowingLambda() { var diagnostics = await CodeAnalyzerHelper.GetDiagnosticsAsync(analyzer, true, @"class TestClass { void TestMethod() { Xunit.Assert.Throws<System.NotImplementedException>(() => System.Threading.Tasks.Task.Delay(0)); } }"); Assert.Collection(diagnostics, d => { Assert.Equal("Do not use obsolete Assert.Throws() to check for asynchronously thrown exceptions.", d.GetMessage()); Assert.Equal("xUnit2019", d.Id); Assert.Equal(DiagnosticSeverity.Hidden, d.Severity); }); }
public async void DoesNotFindWarning_ForThrowsCheck_WithExceptionParameter_OnNonAsyncThrowingMethod() { var diagnostics = await CodeAnalyzerHelper.GetDiagnosticsAsync(analyzer, true, @"class TestClass { void ThrowingMethod() { throw new System.NotImplementedException(); } void TestMethod() { Xunit.Assert.Throws(typeof(System.NotImplementedException), ThrowingMethod); } }"); Assert.Empty(diagnostics); }
public async Task FindsWarning_ForThrowsCheck_WithExceptionTypeArgument_OnAsyncThrowingLambdaWithParamName() { var diagnostics = await CodeAnalyzerHelper.GetDiagnosticsAsync(analyzer, CompilationReporting.IgnoreErrors, @"class TestClass { void TestMethod() { Xunit.Assert.Throws<System.ArgumentException>(""param1"", async () => await System.Threading.Tasks.Task.Delay(0)); } }"); Assert.Collection(diagnostics, d => { Assert.Equal("Do not use obsolete Assert.Throws() to check for asynchronously thrown exceptions.", d.GetMessage()); Assert.Equal("xUnit2019", d.Id); Assert.Equal(DiagnosticSeverity.Hidden, d.Severity); }); }
public async void FindsHiddenDiagnosticWhenProhibitedMethodIsUsed(string method) { var diagnostics = await CodeAnalyzerHelper.GetDiagnosticsAsync(analyzer, CompilationReporting.IgnoreErrors, @"class TestClass { void TestMethod() { Xunit.Assert." + method + @"(null, null); } }"); Assert.Collection(diagnostics, d => { Assert.Equal($"Do not use Assert.{method}().", d.GetMessage()); Assert.Equal("xUnit2001", d.Id); Assert.Equal(DiagnosticSeverity.Hidden, d.Severity); }); }
public async void FindsWarningForCollectionCheckWithoutAction(string collection) { var diagnostics = await CodeAnalyzerHelper.GetDiagnosticsAsync(analyzer, @"class TestClass { void TestMethod() { Xunit.Assert.Collection(" + collection + @"); } }"); Assert.Collection(diagnostics, d => { Assert.Equal("Do not use Assert.Collection() to check for empty collections.", d.GetMessage()); Assert.Equal("xUnit2011", d.Id); Assert.Equal(DiagnosticSeverity.Warning, d.Severity); }); }
public async void FindsError_WhenDuplicateContainsDefaultOfString(string firstDefaultOverride, string secondDefaultOverride) { var diagnostics = await CodeAnalyzerHelper.GetDiagnosticsAsync(analyzer, "public class TestClass" + "{" + " [Xunit.Theory]" + $" [Xunit.InlineData(1 {firstDefaultOverride})]" + $" [Xunit.InlineData(1 {secondDefaultOverride})]" + " public void TestMethod(int x, string y = null) { }" + "}"); Assert.Collection(diagnostics, VerifyDiagnostic); }
public async void NonPublicConstructor_ReturnsError(string @interface) { var code = string.Format(Template, @interface, "protected Foo() { }"); var diagnostics = await CodeAnalyzerHelper.GetDiagnosticsAsync(analyzer, code); Assert.Collection(diagnostics, d => { Assert.Equal("Class Foo must have a public parameterless constructor to support Xunit.Abstractions.IXunitSerializable", d.GetMessage()); Assert.Equal("xUnit3001", d.Descriptor.Id); } ); }
public async void DoesNotFindError_ForMethodOverrides() { var diagnostics = await CodeAnalyzerHelper.GetDiagnosticsAsync(analyzer, "public class BaseClass {" + " [Xunit.Fact]" + " public virtual void TestMethod() { }" + "}", "public class TestClass : BaseClass {" + " [Xunit.Fact]" + " public override void TestMethod() { }" + "}"); Assert.Empty(diagnostics); }
public async void FindsErrors_ForStaticMethodOverloads_InSameStaticClass() { var diagnostics = await CodeAnalyzerHelper.GetDiagnosticsAsync(analyzer, "public static class TestClass { " + " [Xunit.Fact]" + " public static void TestMethod() { }" + " [Xunit.Theory]" + " public static void TestMethod(int a) { }" + "}"); Assert.Collection(diagnostics, d => VerifyDiagnostic(d, "TestClass"), d => VerifyDiagnostic(d, "TestClass")); }
public async void FindsErrorForDataClassNotImplementingInterface() { var diagnostics = await CodeAnalyzerHelper.GetDiagnosticsAsync(analyzer, TestMethodSource, @"class DataClass : System.Collections.Generic.IEnumerable<object> { public System.Collections.Generic.IEnumerator<object> GetEnumerator() => null; System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => null; }"); Assert.Collection(diagnostics, d => { Assert.Equal("ClassData must point at a valid class", d.GetMessage()); Assert.Equal("xUnit1007", d.Descriptor.Id); }); }
public async void FindsErrorOnCorrectLineReferringToInitialOccurence_WhenDuplicateIsSeparatedByOtherNonDuplicateData() { var diagnostics = await CodeAnalyzerHelper.GetDiagnosticsAsync(analyzer, "public class TestClass" + "{" + " [Xunit.Theory]" + " [Xunit.InlineData(10)]" + Environment.NewLine + " [Xunit.InlineData(50)]" + Environment.NewLine + " [Xunit.InlineData(10)]" + " public void TestMethod(int x) { } " + "}"); Assert.Collection(diagnostics, VerifyDiagnostic); Assert.Collection(diagnostics, d => Assert.Equal(2, d.Location.GetLineSpan().StartLinePosition.Line)); }
public async void FindsError_ForStaticAndInstanceMethodOverload() { var diagnostics = await CodeAnalyzerHelper.GetDiagnosticsAsync(analyzer, "public class BaseClass {" + " [Xunit.Fact]" + " public static void TestMethod() { }" + "}", "public class TestClass : BaseClass {" + " [Xunit.Theory]" + " public void TestMethod(int a) { }" + "}"); Assert.Collection(diagnostics, d => VerifyDiagnostic(d, "BaseClass")); }
public async void FindsWarningForSecondValueParameters(string method) { var diagnostics = await CodeAnalyzerHelper.GetDiagnosticsAsync(analyzer, CompilationReporting.IgnoreErrors, @"class TestClass { void TestMethod() { object a = 0; Xunit.Assert." + method + @"(a, 0); } }"); Assert.Collection(diagnostics, d => { Assert.Equal($"Do not use Assert.{method}() on value type 'int'.", d.GetMessage()); Assert.Equal("xUnit2005", d.Id); Assert.Equal(DiagnosticSeverity.Warning, d.Severity); }); }