diff --git a/.editorconfig b/.editorconfig index a493a9cd..705dbcf3 100644 --- a/.editorconfig +++ b/.editorconfig @@ -136,6 +136,9 @@ dotnet_naming_rule.parameters_and_locals.style = camel_case ################################################################################## # IDE Code Style Analyzers +# IDE0005: Using directive is unnecessary +dotnet_diagnostic.IDE0005.severity = warning + # IDE0041: Use 'is null' check dotnet_diagnostic.IDE0041.severity = warning diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 70d56efc..2960f4bb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,5 +15,9 @@ jobs: uses: actions/setup-dotnet@main with: global-json-file: ./global.json - - name: dotnet test - run: dotnet test --configuration=Release ./src/nunit.analyzers.tests/ + + - name: dotnet test (NUnit4) + run: dotnet test --configuration=Release -p:NUnitVersion=4 ./src/nunit.analyzers.tests/ + + - name: dotnet test (NUnit3) + run: dotnet test --configuration=Release -p:NUnitVersion=3 ./src/nunit.analyzers.tests/ diff --git a/documentation/NUnit1015.md b/documentation/NUnit1015.md index e8267258..d843f768 100644 --- a/documentation/NUnit1015.md +++ b/documentation/NUnit1015.md @@ -28,7 +28,7 @@ public class MyTestClass [TestCaseSource(typeof(DivideCases))] public void DivideTest(int n, int d, int q) { - Assert.AreEqual(q, n / d); + ClassicAssert.AreEqual(q, n / d); } } @@ -59,7 +59,7 @@ public class MyTestClass [TestCaseSource(typeof(DivideCases))] public void DivideTest(int n, int d, int q) { - Assert.AreEqual(q, n / d); + ClassicAssert.AreEqual(q, n / d); } } diff --git a/documentation/NUnit1016.md b/documentation/NUnit1016.md index b01031ce..871520a5 100644 --- a/documentation/NUnit1016.md +++ b/documentation/NUnit1016.md @@ -28,7 +28,7 @@ public class MyTestClass [TestCaseSource(typeof(DivideCases))] public void DivideTest(int n, int d, int q) { - Assert.AreEqual(q, n / d); + ClassicAssert.AreEqual(q, n / d); } } @@ -61,7 +61,7 @@ public class MyTestClass [TestCaseSource(typeof(DivideCases))] public void DivideTest(int n, int d, int q) { - Assert.AreEqual(q, n / d); + ClassicAssert.AreEqual(q, n / d); } } diff --git a/documentation/NUnit1017.md b/documentation/NUnit1017.md index 034051be..1d6ac093 100644 --- a/documentation/NUnit1017.md +++ b/documentation/NUnit1017.md @@ -28,7 +28,7 @@ public class MyTestClass [TestCaseSource(nameof(DivideCases))] public void DivideTest(int n, int d, int q) { - Assert.AreEqual(q, n / d); + ClassicAssert.AreEqual(q, n / d); } object[] DivideCases = @@ -56,7 +56,7 @@ public class MyTestClass [TestCaseSource(nameof(DivideCases))] public void DivideTest(int n, int d, int q) { - Assert.AreEqual(q, n / d); + ClassicAssert.AreEqual(q, n / d); } static object[] DivideCases = diff --git a/documentation/NUnit1020.md b/documentation/NUnit1020.md index 5c553058..b01c1280 100644 --- a/documentation/NUnit1020.md +++ b/documentation/NUnit1020.md @@ -28,7 +28,7 @@ public class MyTestClass [TestCaseSource(nameof(DivideCases), new object[] { "Testing" })] public void DivideTest(int n, int d, int q) { - Assert.AreEqual(q, n / d); + ClassicAssert.AreEqual(q, n / d); } static object[] DivideCases = @@ -54,7 +54,7 @@ public class MyTestClass [TestCaseSource(nameof(DivideCases), new object[] { "Testing" })] public void DivideTest(int n, int d, int q) { - Assert.AreEqual(q, n / d); + ClassicAssert.AreEqual(q, n / d); } static object[] DivideCases(string input) diff --git a/documentation/NUnit1022.md b/documentation/NUnit1022.md index a3a23f83..5ade682a 100644 --- a/documentation/NUnit1022.md +++ b/documentation/NUnit1022.md @@ -28,7 +28,7 @@ public class MyTestClass [Test] public void DivideTest([ValueSource(nameof(Numbers))] int n) { - Assert.AreEqual(n, Is.GreaterThanOrEqualTo(0)); + ClassicAssert.AreEqual(n, Is.GreaterThanOrEqualTo(0)); } object[] Numbers => new int[] { 1, 2, 3 }; @@ -51,7 +51,7 @@ public class MyTestClass [Test] public void DivideTest([ValueSource(nameof(Numbers))] int n) { - Assert.AreEqual(n, Is.GreaterThanOrEqualTo(0)); + ClassicAssert.AreEqual(n, Is.GreaterThanOrEqualTo(0)); } static object[] Numbers => new int[] { 1, 2, 3 }; diff --git a/documentation/NUnit2001.md b/documentation/NUnit2001.md index 687064fa..25ab3ccb 100644 --- a/documentation/NUnit2001.md +++ b/documentation/NUnit2001.md @@ -1,6 +1,6 @@ # NUnit2001 -## Consider using Assert.That(expr, Is.False) instead of Assert.False(expr) +## Consider using Assert.That(expr, Is.False) instead of ClassicAssert.False(expr) | Topic | Value | :-- | :-- @@ -12,24 +12,24 @@ ## Description -Consider using the constraint model, `Assert.That(expr, Is.False)`, instead of the classic model, `Assert.False(expr)`. +Consider using the constraint model, `Assert.That(expr, Is.False)`, instead of the classic model, `ClassicAssert.False(expr)`. ## Motivation The classic Assert model contains less flexibility than the constraint model, -so this analyzer marks usages of `Assert.False` from the classic Assert model. +so this analyzer marks usages of `ClassicAssert.False` from the classic Assert model. ```csharp [Test] public void Test() { - Assert.False(expression); + ClassicAssert.False(expression); } ``` ## How to fix violations -The analyzer comes with a code fix that will replace `Assert.False(expression)` with +The analyzer comes with a code fix that will replace `ClassicAssert.False(expression)` with `Assert.That(expression, Is.False)`. So the code block above will be changed into. ```csharp @@ -50,7 +50,7 @@ Configure the severity per project, for more info see [MSDN](https://learn.micro ### Via .editorconfig file ```ini -# NUnit2001: Consider using Assert.That(expr, Is.False) instead of Assert.False(expr) +# NUnit2001: Consider using Assert.That(expr, Is.False) instead of ClassicAssert.False(expr) dotnet_diagnostic.NUnit2001.severity = chosenSeverity ``` @@ -59,22 +59,22 @@ where `chosenSeverity` can be one of `none`, `silent`, `suggestion`, `warning`, ### Via #pragma directive ```csharp -#pragma warning disable NUnit2001 // Consider using Assert.That(expr, Is.False) instead of Assert.False(expr) +#pragma warning disable NUnit2001 // Consider using Assert.That(expr, Is.False) instead of ClassicAssert.False(expr) Code violating the rule here -#pragma warning restore NUnit2001 // Consider using Assert.That(expr, Is.False) instead of Assert.False(expr) +#pragma warning restore NUnit2001 // Consider using Assert.That(expr, Is.False) instead of ClassicAssert.False(expr) ``` Or put this at the top of the file to disable all instances. ```csharp -#pragma warning disable NUnit2001 // Consider using Assert.That(expr, Is.False) instead of Assert.False(expr) +#pragma warning disable NUnit2001 // Consider using Assert.That(expr, Is.False) instead of ClassicAssert.False(expr) ``` ### Via attribute `[SuppressMessage]` ```csharp [System.Diagnostics.CodeAnalysis.SuppressMessage("Assertion", - "NUnit2001:Consider using Assert.That(expr, Is.False) instead of Assert.False(expr)", + "NUnit2001:Consider using Assert.That(expr, Is.False) instead of ClassicAssert.False(expr)", Justification = "Reason...")] ``` diff --git a/documentation/NUnit2002.md b/documentation/NUnit2002.md index 9fccc13f..b128cae4 100644 --- a/documentation/NUnit2002.md +++ b/documentation/NUnit2002.md @@ -1,6 +1,6 @@ # NUnit2002 -## Consider using Assert.That(expr, Is.False) instead of Assert.IsFalse(expr) +## Consider using Assert.That(expr, Is.False) instead of ClassicAssert.IsFalse(expr) | Topic | Value | :-- | :-- @@ -12,24 +12,24 @@ ## Description -Consider using the constraint model, `Assert.That(expr, Is.False)`, instead of the classic model, `Assert.IsFalse(expr)`. +Consider using the constraint model, `Assert.That(expr, Is.False)`, instead of the classic model, `ClassicAssert.IsFalse(expr)`. ## Motivation The classic Assert model contains less flexibility than the constraint model, -so this analyzer marks usages of `Assert.IsFalse` from the classic Assert model. +so this analyzer marks usages of `ClassicAssert.IsFalse` from the classic Assert model. ```csharp [Test] public void Test() { - Assert.IsFalse(expression); + ClassicAssert.IsFalse(expression); } ``` ## How to fix violations -The analyzer comes with a code fix that will replace `Assert.IsFalse(expression)` with +The analyzer comes with a code fix that will replace `ClassicAssert.IsFalse(expression)` with `Assert.That(expression, Is.False)`. So the code block above will be changed into. ```csharp @@ -50,7 +50,7 @@ Configure the severity per project, for more info see [MSDN](https://learn.micro ### Via .editorconfig file ```ini -# NUnit2002: Consider using Assert.That(expr, Is.False) instead of Assert.IsFalse(expr) +# NUnit2002: Consider using Assert.That(expr, Is.False) instead of ClassicAssert.IsFalse(expr) dotnet_diagnostic.NUnit2002.severity = chosenSeverity ``` @@ -59,22 +59,22 @@ where `chosenSeverity` can be one of `none`, `silent`, `suggestion`, `warning`, ### Via #pragma directive ```csharp -#pragma warning disable NUnit2002 // Consider using Assert.That(expr, Is.False) instead of Assert.IsFalse(expr) +#pragma warning disable NUnit2002 // Consider using Assert.That(expr, Is.False) instead of ClassicAssert.IsFalse(expr) Code violating the rule here -#pragma warning restore NUnit2002 // Consider using Assert.That(expr, Is.False) instead of Assert.IsFalse(expr) +#pragma warning restore NUnit2002 // Consider using Assert.That(expr, Is.False) instead of ClassicAssert.IsFalse(expr) ``` Or put this at the top of the file to disable all instances. ```csharp -#pragma warning disable NUnit2002 // Consider using Assert.That(expr, Is.False) instead of Assert.IsFalse(expr) +#pragma warning disable NUnit2002 // Consider using Assert.That(expr, Is.False) instead of ClassicAssert.IsFalse(expr) ``` ### Via attribute `[SuppressMessage]` ```csharp [System.Diagnostics.CodeAnalysis.SuppressMessage("Assertion", - "NUnit2002:Consider using Assert.That(expr, Is.False) instead of Assert.IsFalse(expr)", + "NUnit2002:Consider using Assert.That(expr, Is.False) instead of ClassicAssert.IsFalse(expr)", Justification = "Reason...")] ``` diff --git a/documentation/NUnit2003.md b/documentation/NUnit2003.md index 9b5588bc..a9f9bc3b 100644 --- a/documentation/NUnit2003.md +++ b/documentation/NUnit2003.md @@ -1,6 +1,6 @@ # NUnit2003 -## Consider using Assert.That(expr, Is.True) instead of Assert.IsTrue(expr) +## Consider using Assert.That(expr, Is.True) instead of ClassicAssert.IsTrue(expr) | Topic | Value | :-- | :-- @@ -12,24 +12,24 @@ ## Description -Consider using the constraint model, `Assert.That(expr, Is.True)`, instead of the classic model, `Assert.IsTrue(expr)`. +Consider using the constraint model, `Assert.That(expr, Is.True)`, instead of the classic model, `ClassicAssert.IsTrue(expr)`. ## Motivation The classic Assert model contains less flexibility than the constraint model, -so this analyzer marks usages of `Assert.IsTrue` from the classic Assert model. +so this analyzer marks usages of `ClassicAssert.IsTrue` from the classic Assert model. ```csharp [Test] public void Test() { - Assert.IsTrue(expression); + ClassicAssert.IsTrue(expression); } ``` ## How to fix violations -The analyzer comes with a code fix that will replace `Assert.IsTrue(expression)` with +The analyzer comes with a code fix that will replace `ClassicAssert.IsTrue(expression)` with `Assert.That(expression, Is.True)`. So the code block above will be changed into. ```csharp @@ -50,7 +50,7 @@ Configure the severity per project, for more info see [MSDN](https://learn.micro ### Via .editorconfig file ```ini -# NUnit2003: Consider using Assert.That(expr, Is.True) instead of Assert.IsTrue(expr) +# NUnit2003: Consider using Assert.That(expr, Is.True) instead of ClassicAssert.IsTrue(expr) dotnet_diagnostic.NUnit2003.severity = chosenSeverity ``` @@ -59,22 +59,22 @@ where `chosenSeverity` can be one of `none`, `silent`, `suggestion`, `warning`, ### Via #pragma directive ```csharp -#pragma warning disable NUnit2003 // Consider using Assert.That(expr, Is.True) instead of Assert.IsTrue(expr) +#pragma warning disable NUnit2003 // Consider using Assert.That(expr, Is.True) instead of ClassicAssert.IsTrue(expr) Code violating the rule here -#pragma warning restore NUnit2003 // Consider using Assert.That(expr, Is.True) instead of Assert.IsTrue(expr) +#pragma warning restore NUnit2003 // Consider using Assert.That(expr, Is.True) instead of ClassicAssert.IsTrue(expr) ``` Or put this at the top of the file to disable all instances. ```csharp -#pragma warning disable NUnit2003 // Consider using Assert.That(expr, Is.True) instead of Assert.IsTrue(expr) +#pragma warning disable NUnit2003 // Consider using Assert.That(expr, Is.True) instead of ClassicAssert.IsTrue(expr) ``` ### Via attribute `[SuppressMessage]` ```csharp [System.Diagnostics.CodeAnalysis.SuppressMessage("Assertion", - "NUnit2003:Consider using Assert.That(expr, Is.True) instead of Assert.IsTrue(expr)", + "NUnit2003:Consider using Assert.That(expr, Is.True) instead of ClassicAssert.IsTrue(expr)", Justification = "Reason...")] ``` diff --git a/documentation/NUnit2004.md b/documentation/NUnit2004.md index 99b5aad9..fad7d58c 100644 --- a/documentation/NUnit2004.md +++ b/documentation/NUnit2004.md @@ -1,6 +1,6 @@ # NUnit2004 -## Consider using Assert.That(expr, Is.True) instead of Assert.True(expr) +## Consider using Assert.That(expr, Is.True) instead of ClassicAssert.True(expr) | Topic | Value | :-- | :-- @@ -12,24 +12,24 @@ ## Description -Consider using the constraint model, `Assert.That(expr, Is.True)`, instead of the classic model, `Assert.True(expr)`. +Consider using the constraint model, `Assert.That(expr, Is.True)`, instead of the classic model, `ClassicAssert.True(expr)`. ## Motivation The classic Assert model contains less flexibility than the constraint model, -so this analyzer marks usages of `Assert.True` from the classic Assert model. +so this analyzer marks usages of `ClassicAssert.True` from the classic Assert model. ```csharp [Test] public void Test() { - Assert.True(expression); + ClassicAssert.True(expression); } ``` ## How to fix violations -The analyzer comes with a code fix that will replace `Assert.True(expression)` with +The analyzer comes with a code fix that will replace `ClassicAssert.True(expression)` with `Assert.That(expression, Is.True)`. So the code block above will be changed into. ```csharp @@ -50,7 +50,7 @@ Configure the severity per project, for more info see [MSDN](https://learn.micro ### Via .editorconfig file ```ini -# NUnit2004: Consider using Assert.That(expr, Is.True) instead of Assert.True(expr) +# NUnit2004: Consider using Assert.That(expr, Is.True) instead of ClassicAssert.True(expr) dotnet_diagnostic.NUnit2004.severity = chosenSeverity ``` @@ -59,22 +59,22 @@ where `chosenSeverity` can be one of `none`, `silent`, `suggestion`, `warning`, ### Via #pragma directive ```csharp -#pragma warning disable NUnit2004 // Consider using Assert.That(expr, Is.True) instead of Assert.True(expr) +#pragma warning disable NUnit2004 // Consider using Assert.That(expr, Is.True) instead of ClassicAssert.True(expr) Code violating the rule here -#pragma warning restore NUnit2004 // Consider using Assert.That(expr, Is.True) instead of Assert.True(expr) +#pragma warning restore NUnit2004 // Consider using Assert.That(expr, Is.True) instead of ClassicAssert.True(expr) ``` Or put this at the top of the file to disable all instances. ```csharp -#pragma warning disable NUnit2004 // Consider using Assert.That(expr, Is.True) instead of Assert.True(expr) +#pragma warning disable NUnit2004 // Consider using Assert.That(expr, Is.True) instead of ClassicAssert.True(expr) ``` ### Via attribute `[SuppressMessage]` ```csharp [System.Diagnostics.CodeAnalysis.SuppressMessage("Assertion", - "NUnit2004:Consider using Assert.That(expr, Is.True) instead of Assert.True(expr)", + "NUnit2004:Consider using Assert.That(expr, Is.True) instead of ClassicAssert.True(expr)", Justification = "Reason...")] ``` diff --git a/documentation/NUnit2005.md b/documentation/NUnit2005.md index c7d354b1..f563b2cb 100644 --- a/documentation/NUnit2005.md +++ b/documentation/NUnit2005.md @@ -1,6 +1,6 @@ # NUnit2005 -## Consider using Assert.That(actual, Is.EqualTo(expected)) instead of Assert.AreEqual(expected, actual) +## Consider using Assert.That(actual, Is.EqualTo(expected)) instead of ClassicAssert.AreEqual(expected, actual) | Topic | Value | :-- | :-- @@ -12,24 +12,24 @@ ## Description -Consider using the constraint model, `Assert.That(actual, Is.EqualTo(expected))`, instead of the classic model, `Assert.AreEqual(expected, actual)`. +Consider using the constraint model, `Assert.That(actual, Is.EqualTo(expected))`, instead of the classic model, `ClassicAssert.AreEqual(expected, actual)`. ## Motivation -The classic Assert model, `Assert.AreEqual(expected, actual)`, makes it easy to mix the `expected` and the `actual` parameter, -so this analyzer marks usages of `Assert.AreEqual` from the classic Assert model. +The classic Assert model, `ClassicAssert.AreEqual(expected, actual)`, makes it easy to mix the `expected` and the `actual` parameter, +so this analyzer marks usages of `ClassicAssert.AreEqual` from the classic Assert model. ```csharp [Test] public void Test() { - Assert.AreEqual(expression1, expression2); + ClassicAssert.AreEqual(expression1, expression2); } ``` ## How to fix violations -The analyzer comes with a code fix that will replace `Assert.AreEqual(expression1, expression2)` with +The analyzer comes with a code fix that will replace `ClassicAssert.AreEqual(expression1, expression2)` with `Assert.That(expression2, Is.EqualTo(expression1))`. So the code block above will be changed into. ```csharp @@ -50,7 +50,7 @@ Configure the severity per project, for more info see [MSDN](https://learn.micro ### Via .editorconfig file ```ini -# NUnit2005: Consider using Assert.That(actual, Is.EqualTo(expected)) instead of Assert.AreEqual(expected, actual) +# NUnit2005: Consider using Assert.That(actual, Is.EqualTo(expected)) instead of ClassicAssert.AreEqual(expected, actual) dotnet_diagnostic.NUnit2005.severity = chosenSeverity ``` @@ -59,22 +59,22 @@ where `chosenSeverity` can be one of `none`, `silent`, `suggestion`, `warning`, ### Via #pragma directive ```csharp -#pragma warning disable NUnit2005 // Consider using Assert.That(actual, Is.EqualTo(expected)) instead of Assert.AreEqual(expected, actual) +#pragma warning disable NUnit2005 // Consider using Assert.That(actual, Is.EqualTo(expected)) instead of ClassicAssert.AreEqual(expected, actual) Code violating the rule here -#pragma warning restore NUnit2005 // Consider using Assert.That(actual, Is.EqualTo(expected)) instead of Assert.AreEqual(expected, actual) +#pragma warning restore NUnit2005 // Consider using Assert.That(actual, Is.EqualTo(expected)) instead of ClassicAssert.AreEqual(expected, actual) ``` Or put this at the top of the file to disable all instances. ```csharp -#pragma warning disable NUnit2005 // Consider using Assert.That(actual, Is.EqualTo(expected)) instead of Assert.AreEqual(expected, actual) +#pragma warning disable NUnit2005 // Consider using Assert.That(actual, Is.EqualTo(expected)) instead of ClassicAssert.AreEqual(expected, actual) ``` ### Via attribute `[SuppressMessage]` ```csharp [System.Diagnostics.CodeAnalysis.SuppressMessage("Assertion", - "NUnit2005:Consider using Assert.That(actual, Is.EqualTo(expected)) instead of Assert.AreEqual(expected, actual)", + "NUnit2005:Consider using Assert.That(actual, Is.EqualTo(expected)) instead of ClassicAssert.AreEqual(expected, actual)", Justification = "Reason...")] ``` diff --git a/documentation/NUnit2006.md b/documentation/NUnit2006.md index 2dde116b..e3e8d2fb 100644 --- a/documentation/NUnit2006.md +++ b/documentation/NUnit2006.md @@ -1,6 +1,6 @@ # NUnit2006 -## Consider using Assert.That(actual, Is.Not.EqualTo(expected)) instead of Assert.AreNotEqual(expected, actual) +## Consider using Assert.That(actual, Is.Not.EqualTo(expected)) instead of ClassicAssert.AreNotEqual(expected, actual) | Topic | Value | :-- | :-- @@ -12,24 +12,24 @@ ## Description -Consider using the constraint model, `Assert.That(actual, Is.Not.EqualTo(expected))`, instead of the classic model, `Assert.AreNotEqual(expected, actual)`. +Consider using the constraint model, `Assert.That(actual, Is.Not.EqualTo(expected))`, instead of the classic model, `ClassicAssert.AreNotEqual(expected, actual)`. ## Motivation -The classic Assert model, `Assert.AreNotEqual(expected, actual)`, makes it easy to mix the `expected` and the `actual` parameter, -so this analyzer marks usages of `Assert.AreNotEqual` from the classic Assert model. +The classic Assert model, `ClassicAssert.AreNotEqual(expected, actual)`, makes it easy to mix the `expected` and the `actual` parameter, +so this analyzer marks usages of `ClassicAssert.AreNotEqual` from the classic Assert model. ```csharp [Test] public void Test() { - Assert.AreNotEqual(expression1, expression2) + ClassicAssert.AreNotEqual(expression1, expression2) } ``` ## How to fix violations -The analyzer comes with a code fix that will replace `Assert.AreNotEqual(expression1, expression2)` +The analyzer comes with a code fix that will replace `ClassicAssert.AreNotEqual(expression1, expression2)` with `Assert.That(expression2, Is.Not.EqualTo(expression1))`. So the code block above will be changed into. ```csharp @@ -50,7 +50,7 @@ Configure the severity per project, for more info see [MSDN](https://learn.micro ### Via .editorconfig file ```ini -# NUnit2006: Consider using Assert.That(actual, Is.Not.EqualTo(expected)) instead of Assert.AreNotEqual(expected, actual) +# NUnit2006: Consider using Assert.That(actual, Is.Not.EqualTo(expected)) instead of ClassicAssert.AreNotEqual(expected, actual) dotnet_diagnostic.NUnit2006.severity = chosenSeverity ``` @@ -59,22 +59,22 @@ where `chosenSeverity` can be one of `none`, `silent`, `suggestion`, `warning`, ### Via #pragma directive ```csharp -#pragma warning disable NUnit2006 // Consider using Assert.That(actual, Is.Not.EqualTo(expected)) instead of Assert.AreNotEqual(expected, actual) +#pragma warning disable NUnit2006 // Consider using Assert.That(actual, Is.Not.EqualTo(expected)) instead of ClassicAssert.AreNotEqual(expected, actual) Code violating the rule here -#pragma warning restore NUnit2006 // Consider using Assert.That(actual, Is.Not.EqualTo(expected)) instead of Assert.AreNotEqual(expected, actual) +#pragma warning restore NUnit2006 // Consider using Assert.That(actual, Is.Not.EqualTo(expected)) instead of ClassicAssert.AreNotEqual(expected, actual) ``` Or put this at the top of the file to disable all instances. ```csharp -#pragma warning disable NUnit2006 // Consider using Assert.That(actual, Is.Not.EqualTo(expected)) instead of Assert.AreNotEqual(expected, actual) +#pragma warning disable NUnit2006 // Consider using Assert.That(actual, Is.Not.EqualTo(expected)) instead of ClassicAssert.AreNotEqual(expected, actual) ``` ### Via attribute `[SuppressMessage]` ```csharp [System.Diagnostics.CodeAnalysis.SuppressMessage("Assertion", - "NUnit2006:Consider using Assert.That(actual, Is.Not.EqualTo(expected)) instead of Assert.AreNotEqual(expected, actual)", + "NUnit2006:Consider using Assert.That(actual, Is.Not.EqualTo(expected)) instead of ClassicAssert.AreNotEqual(expected, actual)", Justification = "Reason...")] ``` diff --git a/documentation/NUnit2007.md b/documentation/NUnit2007.md index 3b0096b6..3924403c 100644 --- a/documentation/NUnit2007.md +++ b/documentation/NUnit2007.md @@ -28,7 +28,7 @@ public void NUnit2007SampleTest() { var x = 5; Assert.That(5, Is.EqualTo(x)); - Assert.AreEqual(x, 5); + ClassicAssert.AreEqual(x, 5); } ``` @@ -50,7 +50,7 @@ public void NUnit2007SampleTest() { var x = 5; Assert.That(x, Is.EqualTo(5)); - Assert.AreEqual(5, x); + ClassicAssert.AreEqual(5, x); } ``` diff --git a/documentation/NUnit2010.md b/documentation/NUnit2010.md index fb2d1d2b..0aea4ae3 100644 --- a/documentation/NUnit2010.md +++ b/documentation/NUnit2010.md @@ -24,13 +24,13 @@ with `Is.EqualTo` constraint. [Test] public void Test() { - Assert.True(actual == expected); + ClassicAssert.True(actual == expected); } ``` ## How to fix violations -The analyzer comes with a code fix that will replace `Assert.True(actual == expected)` with +The analyzer comes with a code fix that will replace `ClassicAssert.True(actual == expected)` with `Assert.That(actual, Is.EqualTo(expected))`. So the code block above will be changed into ```csharp diff --git a/documentation/NUnit2011.md b/documentation/NUnit2011.md index a5f815eb..8bee1fa0 100644 --- a/documentation/NUnit2011.md +++ b/documentation/NUnit2011.md @@ -26,13 +26,13 @@ public void Test() { string actual = "..."; string expected = "..."; - Assert.True(actual.Contains(expected)); + ClassicAssert.True(actual.Contains(expected)); } ``` ## How to fix violations -The analyzer comes with a code fix that will replace `Assert.True(actual.Contains(expected))` with +The analyzer comes with a code fix that will replace `ClassicAssert.True(actual.Contains(expected))` with `Assert.That(actual, Does.Contain(expected))`. So the code block above will be changed into ```csharp diff --git a/documentation/NUnit2012.md b/documentation/NUnit2012.md index 681127a0..917737bd 100644 --- a/documentation/NUnit2012.md +++ b/documentation/NUnit2012.md @@ -26,13 +26,13 @@ public void Test() { string actual = "..."; string expected = "..."; - Assert.True(actual.StartsWith(expected)); + ClassicAssert.True(actual.StartsWith(expected)); } ``` ## How to fix violations -The analyzer comes with a code fix that will replace `Assert.True(actual.StartWith(expected))` with +The analyzer comes with a code fix that will replace `ClassicAssert.True(actual.StartWith(expected))` with `Assert.That(actual, Does.StartWith(expected))`. So the code block above will be changed into ```csharp diff --git a/documentation/NUnit2013.md b/documentation/NUnit2013.md index 63e689ef..b468305e 100644 --- a/documentation/NUnit2013.md +++ b/documentation/NUnit2013.md @@ -26,13 +26,13 @@ public void Test() { string actual = "..."; string expected = "..."; - Assert.True(actual.EndsWith(expected)); + ClassicAssert.True(actual.EndsWith(expected)); } ``` ## How to fix violations -The analyzer comes with a code fix that will replace `Assert.True(actual.EndsWith(expected))` with +The analyzer comes with a code fix that will replace `ClassicAssert.True(actual.EndsWith(expected))` with `Assert.That(actual, Does.EndWith(expected))`. So the code block above will be changed into ```csharp diff --git a/documentation/NUnit2014.md b/documentation/NUnit2014.md index a2045895..b428fe4a 100644 --- a/documentation/NUnit2014.md +++ b/documentation/NUnit2014.md @@ -26,13 +26,13 @@ public void Test() { var actual = new List {1,2,3}; int expected = 1; - Assert.True(actual.Contains(expected)); + ClassicAssert.True(actual.Contains(expected)); } ``` ## How to fix violations -The analyzer comes with a code fix that will replace `Assert.True(actual.Contains(expected))` with +The analyzer comes with a code fix that will replace `ClassicAssert.True(actual.Contains(expected))` with `Assert.That(actual, Does.Contain(expected))`. So the code block above will be changed into ```csharp diff --git a/documentation/NUnit2015.md b/documentation/NUnit2015.md index 25e0fd0f..18c8d953 100644 --- a/documentation/NUnit2015.md +++ b/documentation/NUnit2015.md @@ -1,6 +1,6 @@ # NUnit2015 -## Consider using Assert.That(actual, Is.SameAs(expected)) instead of Assert.AreSame(expected, actual) +## Consider using Assert.That(actual, Is.SameAs(expected)) instead of ClassicAssert.AreSame(expected, actual) | Topic | Value | :-- | :-- @@ -12,24 +12,24 @@ ## Description -Consider using the constraint model, `Assert.That(actual, Is.SameAs(expected))`, instead of the classic model, `Assert.AreSame(expected, actual)`. +Consider using the constraint model, `Assert.That(actual, Is.SameAs(expected))`, instead of the classic model, `ClassicAssert.AreSame(expected, actual)`. ## Motivation -The assert `Assert.AreSame` from the classic Assert model makes it easy to confuse the `expected` and the `actual` argument, -so this analyzer marks usages of `Assert.AreSame`. +The assert `ClassicAssert.AreSame` from the classic Assert model makes it easy to confuse the `expected` and the `actual` argument, +so this analyzer marks usages of `ClassicAssert.AreSame`. ```csharp [Test] public void Test() { - Assert.AreSame(expected, actual); + ClassicAssert.AreSame(expected, actual); } ``` ## How to fix violations -The analyzer comes with a code fix that will replace `Assert.AreSame(expected, actual)` with +The analyzer comes with a code fix that will replace `ClassicAssert.AreSame(expected, actual)` with `Assert.That(actual, Is.SameAs(expected))`. So the code block above will be changed into. ```csharp @@ -50,7 +50,7 @@ Configure the severity per project, for more info see [MSDN](https://learn.micro ### Via .editorconfig file ```ini -# NUnit2015: Consider using Assert.That(actual, Is.SameAs(expected)) instead of Assert.AreSame(expected, actual) +# NUnit2015: Consider using Assert.That(actual, Is.SameAs(expected)) instead of ClassicAssert.AreSame(expected, actual) dotnet_diagnostic.NUnit2015.severity = chosenSeverity ``` @@ -59,22 +59,22 @@ where `chosenSeverity` can be one of `none`, `silent`, `suggestion`, `warning`, ### Via #pragma directive ```csharp -#pragma warning disable NUnit2015 // Consider using Assert.That(actual, Is.SameAs(expected)) instead of Assert.AreSame(expected, actual) +#pragma warning disable NUnit2015 // Consider using Assert.That(actual, Is.SameAs(expected)) instead of ClassicAssert.AreSame(expected, actual) Code violating the rule here -#pragma warning restore NUnit2015 // Consider using Assert.That(actual, Is.SameAs(expected)) instead of Assert.AreSame(expected, actual) +#pragma warning restore NUnit2015 // Consider using Assert.That(actual, Is.SameAs(expected)) instead of ClassicAssert.AreSame(expected, actual) ``` Or put this at the top of the file to disable all instances. ```csharp -#pragma warning disable NUnit2015 // Consider using Assert.That(actual, Is.SameAs(expected)) instead of Assert.AreSame(expected, actual) +#pragma warning disable NUnit2015 // Consider using Assert.That(actual, Is.SameAs(expected)) instead of ClassicAssert.AreSame(expected, actual) ``` ### Via attribute `[SuppressMessage]` ```csharp [System.Diagnostics.CodeAnalysis.SuppressMessage("Assertion", - "NUnit2015:Consider using Assert.That(actual, Is.SameAs(expected)) instead of Assert.AreSame(expected, actual)", + "NUnit2015:Consider using Assert.That(actual, Is.SameAs(expected)) instead of ClassicAssert.AreSame(expected, actual)", Justification = "Reason...")] ``` diff --git a/documentation/NUnit2016.md b/documentation/NUnit2016.md index ce6b6c7b..d9095dcb 100644 --- a/documentation/NUnit2016.md +++ b/documentation/NUnit2016.md @@ -1,6 +1,6 @@ # NUnit2016 -## Consider using Assert.That(expr, Is.Null) instead of Assert.Null(expr) +## Consider using Assert.That(expr, Is.Null) instead of ClassicAssert.Null(expr) | Topic | Value | :-- | :-- @@ -12,25 +12,25 @@ ## Description -Consider using the constraint model, `Assert.That(expr, Is.Null)`, instead of the classic model, `Assert.Null(expr)`. +Consider using the constraint model, `Assert.That(expr, Is.Null)`, instead of the classic model, `ClassicAssert.Null(expr)`. ## Motivation The classic Assert model contains less flexibility than the constraint model, -so this analyzer marks usages of `Assert.Null` from the classic Assert model. +so this analyzer marks usages of `ClassicAssert.Null` from the classic Assert model. ```csharp [Test] public void Test() { object obj = null; - Assert.Null(obj); + ClassicAssert.Null(obj); } ``` ## How to fix violations -The analyzer comes with a code fix that will replace `Assert.Null(expression)` with +The analyzer comes with a code fix that will replace `ClassicAssert.Null(expression)` with `Assert.That(expression, Is.Null)`. So the code block above will be changed into. ```csharp @@ -52,7 +52,7 @@ Configure the severity per project, for more info see [MSDN](https://learn.micro ### Via .editorconfig file ```ini -# NUnit2016: Consider using Assert.That(expr, Is.Null) instead of Assert.Null(expr) +# NUnit2016: Consider using Assert.That(expr, Is.Null) instead of ClassicAssert.Null(expr) dotnet_diagnostic.NUnit2016.severity = chosenSeverity ``` @@ -61,22 +61,22 @@ where `chosenSeverity` can be one of `none`, `silent`, `suggestion`, `warning`, ### Via #pragma directive ```csharp -#pragma warning disable NUnit2016 // Consider using Assert.That(expr, Is.Null) instead of Assert.Null(expr) +#pragma warning disable NUnit2016 // Consider using Assert.That(expr, Is.Null) instead of ClassicAssert.Null(expr) Code violating the rule here -#pragma warning restore NUnit2016 // Consider using Assert.That(expr, Is.Null) instead of Assert.Null(expr) +#pragma warning restore NUnit2016 // Consider using Assert.That(expr, Is.Null) instead of ClassicAssert.Null(expr) ``` Or put this at the top of the file to disable all instances. ```csharp -#pragma warning disable NUnit2016 // Consider using Assert.That(expr, Is.Null) instead of Assert.Null(expr) +#pragma warning disable NUnit2016 // Consider using Assert.That(expr, Is.Null) instead of ClassicAssert.Null(expr) ``` ### Via attribute `[SuppressMessage]` ```csharp [System.Diagnostics.CodeAnalysis.SuppressMessage("Assertion", - "NUnit2016:Consider using Assert.That(expr, Is.Null) instead of Assert.Null(expr)", + "NUnit2016:Consider using Assert.That(expr, Is.Null) instead of ClassicAssert.Null(expr)", Justification = "Reason...")] ``` diff --git a/documentation/NUnit2017.md b/documentation/NUnit2017.md index 173e5ca2..4386df78 100644 --- a/documentation/NUnit2017.md +++ b/documentation/NUnit2017.md @@ -1,6 +1,6 @@ # NUnit2017 -## Consider using Assert.That(expr, Is.Null) instead of Assert.IsNull(expr) +## Consider using Assert.That(expr, Is.Null) instead of ClassicAssert.IsNull(expr) | Topic | Value | :-- | :-- @@ -12,25 +12,25 @@ ## Description -Consider using the constraint model, `Assert.That(expr, Is.Null)`, instead of the classic model, `Assert.IsNull(expr)`. +Consider using the constraint model, `Assert.That(expr, Is.Null)`, instead of the classic model, `ClassicAssert.IsNull(expr)`. ## Motivation The classic Assert model contains less flexibility than the constraint model, -so this analyzer marks usages of `Assert.IsNull` from the classic Assert model. +so this analyzer marks usages of `ClassicAssert.IsNull` from the classic Assert model. ```csharp [Test] public void Test() { object obj = null; - Assert.IsNull(obj); + ClassicAssert.IsNull(obj); } ``` ## How to fix violations -The analyzer comes with a code fix that will replace `Assert.IsNull(expression)` with +The analyzer comes with a code fix that will replace `ClassicAssert.IsNull(expression)` with `Assert.That(expression, Is.Null)`. So the code block above will be changed into. ```csharp @@ -52,7 +52,7 @@ Configure the severity per project, for more info see [MSDN](https://learn.micro ### Via .editorconfig file ```ini -# NUnit2017: Consider using Assert.That(expr, Is.Null) instead of Assert.IsNull(expr) +# NUnit2017: Consider using Assert.That(expr, Is.Null) instead of ClassicAssert.IsNull(expr) dotnet_diagnostic.NUnit2017.severity = chosenSeverity ``` @@ -61,22 +61,22 @@ where `chosenSeverity` can be one of `none`, `silent`, `suggestion`, `warning`, ### Via #pragma directive ```csharp -#pragma warning disable NUnit2017 // Consider using Assert.That(expr, Is.Null) instead of Assert.IsNull(expr) +#pragma warning disable NUnit2017 // Consider using Assert.That(expr, Is.Null) instead of ClassicAssert.IsNull(expr) Code violating the rule here -#pragma warning restore NUnit2017 // Consider using Assert.That(expr, Is.Null) instead of Assert.IsNull(expr) +#pragma warning restore NUnit2017 // Consider using Assert.That(expr, Is.Null) instead of ClassicAssert.IsNull(expr) ``` Or put this at the top of the file to disable all instances. ```csharp -#pragma warning disable NUnit2017 // Consider using Assert.That(expr, Is.Null) instead of Assert.IsNull(expr) +#pragma warning disable NUnit2017 // Consider using Assert.That(expr, Is.Null) instead of ClassicAssert.IsNull(expr) ``` ### Via attribute `[SuppressMessage]` ```csharp [System.Diagnostics.CodeAnalysis.SuppressMessage("Assertion", - "NUnit2017:Consider using Assert.That(expr, Is.Null) instead of Assert.IsNull(expr)", + "NUnit2017:Consider using Assert.That(expr, Is.Null) instead of ClassicAssert.IsNull(expr)", Justification = "Reason...")] ``` diff --git a/documentation/NUnit2018.md b/documentation/NUnit2018.md index 2452465d..d5a62576 100644 --- a/documentation/NUnit2018.md +++ b/documentation/NUnit2018.md @@ -1,6 +1,6 @@ # NUnit2018 -## Consider using Assert.That(expr, Is.Not.Null) instead of Assert.NotNull(expr) +## Consider using Assert.That(expr, Is.Not.Null) instead of ClassicAssert.NotNull(expr) | Topic | Value | :-- | :-- @@ -12,25 +12,25 @@ ## Description -Consider using the constraint model, `Assert.That(expr, Is.Not.Null)`, instead of the classic model, `Assert.NotNull(expr)`. +Consider using the constraint model, `Assert.That(expr, Is.Not.Null)`, instead of the classic model, `ClassicAssert.NotNull(expr)`. ## Motivation The classic Assert model contains less flexibility than the constraint model, -so this analyzer marks usages of `Assert.NotNull` from the classic Assert model. +so this analyzer marks usages of `ClassicAssert.NotNull` from the classic Assert model. ```csharp [Test] public void Test() { object obj = null; - Assert.NotNull(obj); + ClassicAssert.NotNull(obj); } ``` ## How to fix violations -The analyzer comes with a code fix that will replace `Assert.NotNull(expression)` with +The analyzer comes with a code fix that will replace `ClassicAssert.NotNull(expression)` with `Assert.That(expression, Is.Not.Null)`. So the code block above will be changed into. ```csharp @@ -52,7 +52,7 @@ Configure the severity per project, for more info see [MSDN](https://learn.micro ### Via .editorconfig file ```ini -# NUnit2018: Consider using Assert.That(expr, Is.Not.Null) instead of Assert.NotNull(expr) +# NUnit2018: Consider using Assert.That(expr, Is.Not.Null) instead of ClassicAssert.NotNull(expr) dotnet_diagnostic.NUnit2018.severity = chosenSeverity ``` @@ -61,22 +61,22 @@ where `chosenSeverity` can be one of `none`, `silent`, `suggestion`, `warning`, ### Via #pragma directive ```csharp -#pragma warning disable NUnit2018 // Consider using Assert.That(expr, Is.Not.Null) instead of Assert.NotNull(expr) +#pragma warning disable NUnit2018 // Consider using Assert.That(expr, Is.Not.Null) instead of ClassicAssert.NotNull(expr) Code violating the rule here -#pragma warning restore NUnit2018 // Consider using Assert.That(expr, Is.Not.Null) instead of Assert.NotNull(expr) +#pragma warning restore NUnit2018 // Consider using Assert.That(expr, Is.Not.Null) instead of ClassicAssert.NotNull(expr) ``` Or put this at the top of the file to disable all instances. ```csharp -#pragma warning disable NUnit2018 // Consider using Assert.That(expr, Is.Not.Null) instead of Assert.NotNull(expr) +#pragma warning disable NUnit2018 // Consider using Assert.That(expr, Is.Not.Null) instead of ClassicAssert.NotNull(expr) ``` ### Via attribute `[SuppressMessage]` ```csharp [System.Diagnostics.CodeAnalysis.SuppressMessage("Assertion", - "NUnit2018:Consider using Assert.That(expr, Is.Not.Null) instead of Assert.NotNull(expr)", + "NUnit2018:Consider using Assert.That(expr, Is.Not.Null) instead of ClassicAssert.NotNull(expr)", Justification = "Reason...")] ``` diff --git a/documentation/NUnit2019.md b/documentation/NUnit2019.md index 74ba0952..04380c17 100644 --- a/documentation/NUnit2019.md +++ b/documentation/NUnit2019.md @@ -1,6 +1,6 @@ # NUnit2019 -## Consider using Assert.That(expr, Is.Not.Null) instead of Assert.IsNotNull(expr) +## Consider using Assert.That(expr, Is.Not.Null) instead of ClassicAssert.IsNotNull(expr) | Topic | Value | :-- | :-- @@ -12,25 +12,25 @@ ## Description -Consider using the constraint model, `Assert.That(expr, Is.Not.Null)`, instead of the classic model, `Assert.IsNotNull(expr)`. +Consider using the constraint model, `Assert.That(expr, Is.Not.Null)`, instead of the classic model, `ClassicAssert.IsNotNull(expr)`. ## Motivation The classic Assert model contains less flexibility than the constraint model, -so this analyzer marks usages of `Assert.IsNotNull` from the classic Assert model. +so this analyzer marks usages of `ClassicAssert.IsNotNull` from the classic Assert model. ```csharp [Test] public void Test() { object obj = null; - Assert.IsNotNull(obj); + ClassicAssert.IsNotNull(obj); } ``` ## How to fix violations -The analyzer comes with a code fix that will replace `Assert.IsNotNull(expression)` with +The analyzer comes with a code fix that will replace `ClassicAssert.IsNotNull(expression)` with `Assert.That(expression, Is.Not.Null)`. So the code block above will be changed into. ```csharp @@ -52,7 +52,7 @@ Configure the severity per project, for more info see [MSDN](https://learn.micro ### Via .editorconfig file ```ini -# NUnit2019: Consider using Assert.That(expr, Is.Not.Null) instead of Assert.IsNotNull(expr) +# NUnit2019: Consider using Assert.That(expr, Is.Not.Null) instead of ClassicAssert.IsNotNull(expr) dotnet_diagnostic.NUnit2019.severity = chosenSeverity ``` @@ -61,22 +61,22 @@ where `chosenSeverity` can be one of `none`, `silent`, `suggestion`, `warning`, ### Via #pragma directive ```csharp -#pragma warning disable NUnit2019 // Consider using Assert.That(expr, Is.Not.Null) instead of Assert.IsNotNull(expr) +#pragma warning disable NUnit2019 // Consider using Assert.That(expr, Is.Not.Null) instead of ClassicAssert.IsNotNull(expr) Code violating the rule here -#pragma warning restore NUnit2019 // Consider using Assert.That(expr, Is.Not.Null) instead of Assert.IsNotNull(expr) +#pragma warning restore NUnit2019 // Consider using Assert.That(expr, Is.Not.Null) instead of ClassicAssert.IsNotNull(expr) ``` Or put this at the top of the file to disable all instances. ```csharp -#pragma warning disable NUnit2019 // Consider using Assert.That(expr, Is.Not.Null) instead of Assert.IsNotNull(expr) +#pragma warning disable NUnit2019 // Consider using Assert.That(expr, Is.Not.Null) instead of ClassicAssert.IsNotNull(expr) ``` ### Via attribute `[SuppressMessage]` ```csharp [System.Diagnostics.CodeAnalysis.SuppressMessage("Assertion", - "NUnit2019:Consider using Assert.That(expr, Is.Not.Null) instead of Assert.IsNotNull(expr)", + "NUnit2019:Consider using Assert.That(expr, Is.Not.Null) instead of ClassicAssert.IsNotNull(expr)", Justification = "Reason...")] ``` diff --git a/documentation/NUnit2027.md b/documentation/NUnit2027.md index 576050c0..d90ff745 100644 --- a/documentation/NUnit2027.md +++ b/documentation/NUnit2027.md @@ -1,6 +1,6 @@ # NUnit2027 -## Consider using Assert.That(actual, Is.GreaterThan(expected)) instead of Assert.Greater(actual, expected) +## Consider using Assert.That(actual, Is.GreaterThan(expected)) instead of ClassicAssert.Greater(actual, expected) | Topic | Value | :-- | :-- @@ -12,24 +12,24 @@ ## Description -Consider using the constraint model, `Assert.That(actual, Is.GreaterThan(expected))`, instead of the classic model, `Assert.Greater(actual, expected)`. +Consider using the constraint model, `Assert.That(actual, Is.GreaterThan(expected))`, instead of the classic model, `ClassicAssert.Greater(actual, expected)`. ## Motivation -The assert `Assert.Greater` from the classic Assert model makes it easy to confuse the `expected` and the `actual` argument, -so this analyzer marks usages of `Assert.Greater`. +The assert `ClassicAssert.Greater` from the classic Assert model makes it easy to confuse the `expected` and the `actual` argument, +so this analyzer marks usages of `ClassicAssert.Greater`. ```csharp [Test] public void Test() { - Assert.Greater(actual, expected); + ClassicAssert.Greater(actual, expected); } ``` ## How to fix violations -The analyzer comes with a code fix that will replace `Assert.Greater(actual, expected)` with +The analyzer comes with a code fix that will replace `ClassicAssert.Greater(actual, expected)` with `Assert.That(actual, Is.GreaterThan(expected))`. So the code block above will be changed into. ```csharp @@ -50,7 +50,7 @@ Configure the severity per project, for more info see [MSDN](https://learn.micro ### Via .editorconfig file ```ini -# NUnit2027: Consider using Assert.That(actual, Is.GreaterThan(expected)) instead of Assert.Greater(actual, expected) +# NUnit2027: Consider using Assert.That(actual, Is.GreaterThan(expected)) instead of ClassicAssert.Greater(actual, expected) dotnet_diagnostic.NUnit2027.severity = chosenSeverity ``` @@ -59,22 +59,22 @@ where `chosenSeverity` can be one of `none`, `silent`, `suggestion`, `warning`, ### Via #pragma directive ```csharp -#pragma warning disable NUnit2027 // Consider using Assert.That(actual, Is.GreaterThan(expected)) instead of Assert.Greater(actual, expected) +#pragma warning disable NUnit2027 // Consider using Assert.That(actual, Is.GreaterThan(expected)) instead of ClassicAssert.Greater(actual, expected) Code violating the rule here -#pragma warning restore NUnit2027 // Consider using Assert.That(actual, Is.GreaterThan(expected)) instead of Assert.Greater(actual, expected) +#pragma warning restore NUnit2027 // Consider using Assert.That(actual, Is.GreaterThan(expected)) instead of ClassicAssert.Greater(actual, expected) ``` Or put this at the top of the file to disable all instances. ```csharp -#pragma warning disable NUnit2027 // Consider using Assert.That(actual, Is.GreaterThan(expected)) instead of Assert.Greater(actual, expected) +#pragma warning disable NUnit2027 // Consider using Assert.That(actual, Is.GreaterThan(expected)) instead of ClassicAssert.Greater(actual, expected) ``` ### Via attribute `[SuppressMessage]` ```csharp [System.Diagnostics.CodeAnalysis.SuppressMessage("Assertion", - "NUnit2027:Consider using Assert.That(actual, Is.GreaterThan(expected)) instead of Assert.Greater(actual, expected)", + "NUnit2027:Consider using Assert.That(actual, Is.GreaterThan(expected)) instead of ClassicAssert.Greater(actual, expected)", Justification = "Reason...")] ``` diff --git a/documentation/NUnit2028.md b/documentation/NUnit2028.md index 10fc7051..60136b23 100644 --- a/documentation/NUnit2028.md +++ b/documentation/NUnit2028.md @@ -1,6 +1,6 @@ # NUnit2028 -## Consider using Assert.That(actual, Is.GreaterThanOrEqualTo(expected)) instead of Assert.GreaterOrEqual(actual, expected) +## Consider using Assert.That(actual, Is.GreaterThanOrEqualTo(expected)) instead of ClassicAssert.GreaterOrEqual(actual, expected) | Topic | Value | :-- | :-- @@ -12,24 +12,24 @@ ## Description -Consider using the constraint model, `Assert.That(actual, Is.GreaterThanOrEqualTo(expected))`, instead of the classic model, `Assert.GreaterOrEqual(actual, expected)`. +Consider using the constraint model, `Assert.That(actual, Is.GreaterThanOrEqualTo(expected))`, instead of the classic model, `ClassicAssert.GreaterOrEqual(actual, expected)`. ## Motivation -The assert `Assert.GreaterOrEqual` from the classic Assert model makes it easy to confuse the `expected` and the `actual` argument, -so this analyzer marks usages of `Assert.GreaterOrEqual`. +The assert `ClassicAssert.GreaterOrEqual` from the classic Assert model makes it easy to confuse the `expected` and the `actual` argument, +so this analyzer marks usages of `ClassicAssert.GreaterOrEqual`. ```csharp [Test] public void Test() { - Assert.GreaterOrEqual(actual, expected); + ClassicAssert.GreaterOrEqual(actual, expected); } ``` ## How to fix violations -The analyzer comes with a code fix that will replace `Assert.GreaterOrEqual(actual, expected)` with +The analyzer comes with a code fix that will replace `ClassicAssert.GreaterOrEqual(actual, expected)` with `Assert.That(actual, Is.GreaterThanOrEqualTo(expected))`. So the code block above will be changed into. ```csharp @@ -50,7 +50,7 @@ Configure the severity per project, for more info see [MSDN](https://learn.micro ### Via .editorconfig file ```ini -# NUnit2028: Consider using Assert.That(actual, Is.GreaterThanOrEqualTo(expected)) instead of Assert.GreaterOrEqual(actual, expected) +# NUnit2028: Consider using Assert.That(actual, Is.GreaterThanOrEqualTo(expected)) instead of ClassicAssert.GreaterOrEqual(actual, expected) dotnet_diagnostic.NUnit2028.severity = chosenSeverity ``` @@ -59,22 +59,22 @@ where `chosenSeverity` can be one of `none`, `silent`, `suggestion`, `warning`, ### Via #pragma directive ```csharp -#pragma warning disable NUnit2028 // Consider using Assert.That(actual, Is.GreaterThanOrEqualTo(expected)) instead of Assert.GreaterOrEqual(actual, expected) +#pragma warning disable NUnit2028 // Consider using Assert.That(actual, Is.GreaterThanOrEqualTo(expected)) instead of ClassicAssert.GreaterOrEqual(actual, expected) Code violating the rule here -#pragma warning restore NUnit2028 // Consider using Assert.That(actual, Is.GreaterThanOrEqualTo(expected)) instead of Assert.GreaterOrEqual(actual, expected) +#pragma warning restore NUnit2028 // Consider using Assert.That(actual, Is.GreaterThanOrEqualTo(expected)) instead of ClassicAssert.GreaterOrEqual(actual, expected) ``` Or put this at the top of the file to disable all instances. ```csharp -#pragma warning disable NUnit2028 // Consider using Assert.That(actual, Is.GreaterThanOrEqualTo(expected)) instead of Assert.GreaterOrEqual(actual, expected) +#pragma warning disable NUnit2028 // Consider using Assert.That(actual, Is.GreaterThanOrEqualTo(expected)) instead of ClassicAssert.GreaterOrEqual(actual, expected) ``` ### Via attribute `[SuppressMessage]` ```csharp [System.Diagnostics.CodeAnalysis.SuppressMessage("Assertion", - "NUnit2028:Consider using Assert.That(actual, Is.GreaterThanOrEqualTo(expected)) instead of Assert.GreaterOrEqual(actual, expected)", + "NUnit2028:Consider using Assert.That(actual, Is.GreaterThanOrEqualTo(expected)) instead of ClassicAssert.GreaterOrEqual(actual, expected)", Justification = "Reason...")] ``` diff --git a/documentation/NUnit2029.md b/documentation/NUnit2029.md index ad217376..7e9c96f5 100644 --- a/documentation/NUnit2029.md +++ b/documentation/NUnit2029.md @@ -1,6 +1,6 @@ # NUnit2029 -## Consider using Assert.That(actual, Is.LessThan(expected)) instead of Assert.Less(actual, expected) +## Consider using Assert.That(actual, Is.LessThan(expected)) instead of ClassicAssert.Less(actual, expected) | Topic | Value | :-- | :-- @@ -12,24 +12,24 @@ ## Description -Consider using the constraint model, `Assert.That(actual, Is.LessThan(expected))`, instead of the classic model, `Assert.Less(actual, expected)`. +Consider using the constraint model, `Assert.That(actual, Is.LessThan(expected))`, instead of the classic model, `ClassicAssert.Less(actual, expected)`. ## Motivation -The assert `Assert.Less` from the classic Assert model makes it easy to confuse the `expected` and the `actual` argument, -so this analyzer marks usages of `Assert.Less`. +The assert `ClassicAssert.Less` from the classic Assert model makes it easy to confuse the `expected` and the `actual` argument, +so this analyzer marks usages of `ClassicAssert.Less`. ```csharp [Test] public void Test() { - Assert.Less(actual, expected); + ClassicAssert.Less(actual, expected); } ``` ## How to fix violations -The analyzer comes with a code fix that will replace `Assert.Less(actual, expected)` with +The analyzer comes with a code fix that will replace `ClassicAssert.Less(actual, expected)` with `Assert.That(actual, Is.LessThan(expected))`. So the code block above will be changed into. ```csharp @@ -50,7 +50,7 @@ Configure the severity per project, for more info see [MSDN](https://learn.micro ### Via .editorconfig file ```ini -# NUnit2029: Consider using Assert.That(actual, Is.LessThan(expected)) instead of Assert.Less(actual, expected) +# NUnit2029: Consider using Assert.That(actual, Is.LessThan(expected)) instead of ClassicAssert.Less(actual, expected) dotnet_diagnostic.NUnit2029.severity = chosenSeverity ``` @@ -59,22 +59,22 @@ where `chosenSeverity` can be one of `none`, `silent`, `suggestion`, `warning`, ### Via #pragma directive ```csharp -#pragma warning disable NUnit2029 // Consider using Assert.That(actual, Is.LessThan(expected)) instead of Assert.Less(actual, expected) +#pragma warning disable NUnit2029 // Consider using Assert.That(actual, Is.LessThan(expected)) instead of ClassicAssert.Less(actual, expected) Code violating the rule here -#pragma warning restore NUnit2029 // Consider using Assert.That(actual, Is.LessThan(expected)) instead of Assert.Less(actual, expected) +#pragma warning restore NUnit2029 // Consider using Assert.That(actual, Is.LessThan(expected)) instead of ClassicAssert.Less(actual, expected) ``` Or put this at the top of the file to disable all instances. ```csharp -#pragma warning disable NUnit2029 // Consider using Assert.That(actual, Is.LessThan(expected)) instead of Assert.Less(actual, expected) +#pragma warning disable NUnit2029 // Consider using Assert.That(actual, Is.LessThan(expected)) instead of ClassicAssert.Less(actual, expected) ``` ### Via attribute `[SuppressMessage]` ```csharp [System.Diagnostics.CodeAnalysis.SuppressMessage("Assertion", - "NUnit2029:Consider using Assert.That(actual, Is.LessThan(expected)) instead of Assert.Less(actual, expected)", + "NUnit2029:Consider using Assert.That(actual, Is.LessThan(expected)) instead of ClassicAssert.Less(actual, expected)", Justification = "Reason...")] ``` diff --git a/documentation/NUnit2030.md b/documentation/NUnit2030.md index d3d8eff6..634b403b 100644 --- a/documentation/NUnit2030.md +++ b/documentation/NUnit2030.md @@ -1,6 +1,6 @@ # NUnit2030 -## Consider using Assert.That(actual, Is.LessThanOrEqualTo(expected)) instead of Assert.LessOrEqual(actual, expected) +## Consider using Assert.That(actual, Is.LessThanOrEqualTo(expected)) instead of ClassicAssert.LessOrEqual(actual, expected) | Topic | Value | :-- | :-- @@ -12,24 +12,24 @@ ## Description -Consider using the constraint model, `Assert.That(actual, Is.LessThanOrEqualTo(expected))`, instead of the classic model, `Assert.LessOrEqual(actual, expected)`. +Consider using the constraint model, `Assert.That(actual, Is.LessThanOrEqualTo(expected))`, instead of the classic model, `ClassicAssert.LessOrEqual(actual, expected)`. ## Motivation -The assert `Assert.LessOrEqual` from the classic Assert model makes it easy to confuse the `expected` and the `actual` argument, -so this analyzer marks usages of `Assert.LessOrEqual`. +The assert `ClassicAssert.LessOrEqual` from the classic Assert model makes it easy to confuse the `expected` and the `actual` argument, +so this analyzer marks usages of `ClassicAssert.LessOrEqual`. ```csharp [Test] public void Test() { - Assert.LessOrEqual(actual, expected); + ClassicAssert.LessOrEqual(actual, expected); } ``` ## How to fix violations -The analyzer comes with a code fix that will replace `Assert.LessOrEqual(actual, expected)` with +The analyzer comes with a code fix that will replace `ClassicAssert.LessOrEqual(actual, expected)` with `Assert.That(actual, Is.LessThanOrEqualTo(expected))`. So the code block above will be changed into. ```csharp @@ -50,7 +50,7 @@ Configure the severity per project, for more info see [MSDN](https://learn.micro ### Via .editorconfig file ```ini -# NUnit2030: Consider using Assert.That(actual, Is.LessThanOrEqualTo(expected)) instead of Assert.LessOrEqual(actual, expected) +# NUnit2030: Consider using Assert.That(actual, Is.LessThanOrEqualTo(expected)) instead of ClassicAssert.LessOrEqual(actual, expected) dotnet_diagnostic.NUnit2030.severity = chosenSeverity ``` @@ -59,22 +59,22 @@ where `chosenSeverity` can be one of `none`, `silent`, `suggestion`, `warning`, ### Via #pragma directive ```csharp -#pragma warning disable NUnit2030 // Consider using Assert.That(actual, Is.LessThanOrEqualTo(expected)) instead of Assert.LessOrEqual(actual, expected) +#pragma warning disable NUnit2030 // Consider using Assert.That(actual, Is.LessThanOrEqualTo(expected)) instead of ClassicAssert.LessOrEqual(actual, expected) Code violating the rule here -#pragma warning restore NUnit2030 // Consider using Assert.That(actual, Is.LessThanOrEqualTo(expected)) instead of Assert.LessOrEqual(actual, expected) +#pragma warning restore NUnit2030 // Consider using Assert.That(actual, Is.LessThanOrEqualTo(expected)) instead of ClassicAssert.LessOrEqual(actual, expected) ``` Or put this at the top of the file to disable all instances. ```csharp -#pragma warning disable NUnit2030 // Consider using Assert.That(actual, Is.LessThanOrEqualTo(expected)) instead of Assert.LessOrEqual(actual, expected) +#pragma warning disable NUnit2030 // Consider using Assert.That(actual, Is.LessThanOrEqualTo(expected)) instead of ClassicAssert.LessOrEqual(actual, expected) ``` ### Via attribute `[SuppressMessage]` ```csharp [System.Diagnostics.CodeAnalysis.SuppressMessage("Assertion", - "NUnit2030:Consider using Assert.That(actual, Is.LessThanOrEqualTo(expected)) instead of Assert.LessOrEqual(actual, expected)", + "NUnit2030:Consider using Assert.That(actual, Is.LessThanOrEqualTo(expected)) instead of ClassicAssert.LessOrEqual(actual, expected)", Justification = "Reason...")] ``` diff --git a/documentation/NUnit2031.md b/documentation/NUnit2031.md index 7bc87344..93a8b7a3 100644 --- a/documentation/NUnit2031.md +++ b/documentation/NUnit2031.md @@ -1,6 +1,6 @@ # NUnit2031 -## Consider using Assert.That(actual, Is.Not.SameAs(expected)) instead of Assert.AreNotSame(expected, actual) +## Consider using Assert.That(actual, Is.Not.SameAs(expected)) instead of ClassicAssert.AreNotSame(expected, actual) | Topic | Value | :-- | :-- @@ -12,24 +12,24 @@ ## Description -Consider using the constraint model, `Assert.That(actual, Is.Not.SameAs(expected))`, instead of the classic model, `Assert.AreNotSame(expected, actual)`. +Consider using the constraint model, `Assert.That(actual, Is.Not.SameAs(expected))`, instead of the classic model, `ClassicAssert.AreNotSame(expected, actual)`. ## Motivation -The assert `Assert.AreNotSame` from the classic Assert model makes it easy to confuse the `expected` and the `actual` argument, -so this analyzer marks usages of `Assert.AreNotSame`. +The assert `ClassicAssert.AreNotSame` from the classic Assert model makes it easy to confuse the `expected` and the `actual` argument, +so this analyzer marks usages of `ClassicAssert.AreNotSame`. ```csharp [Test] public void Test() { - Assert.AreNotSame(expected, actual); + ClassicAssert.AreNotSame(expected, actual); } ``` ## How to fix violations -The analyzer comes with a code fix that will replace `Assert.AreNotSame(expected, actual)` with +The analyzer comes with a code fix that will replace `ClassicAssert.AreNotSame(expected, actual)` with `Assert.That(actual, Is.Not.SameAs(expected))`. So the code block above will be changed into. ```csharp @@ -50,7 +50,7 @@ Configure the severity per project, for more info see [MSDN](https://learn.micro ### Via .editorconfig file ```ini -# NUnit2031: Consider using Assert.That(actual, Is.Not.SameAs(expected)) instead of Assert.AreNotSame(expected, actual) +# NUnit2031: Consider using Assert.That(actual, Is.Not.SameAs(expected)) instead of ClassicAssert.AreNotSame(expected, actual) dotnet_diagnostic.NUnit2031.severity = chosenSeverity ``` @@ -59,22 +59,22 @@ where `chosenSeverity` can be one of `none`, `silent`, `suggestion`, `warning`, ### Via #pragma directive ```csharp -#pragma warning disable NUnit2031 // Consider using Assert.That(actual, Is.Not.SameAs(expected)) instead of Assert.AreNotSame(expected, actual) +#pragma warning disable NUnit2031 // Consider using Assert.That(actual, Is.Not.SameAs(expected)) instead of ClassicAssert.AreNotSame(expected, actual) Code violating the rule here -#pragma warning restore NUnit2031 // Consider using Assert.That(actual, Is.Not.SameAs(expected)) instead of Assert.AreNotSame(expected, actual) +#pragma warning restore NUnit2031 // Consider using Assert.That(actual, Is.Not.SameAs(expected)) instead of ClassicAssert.AreNotSame(expected, actual) ``` Or put this at the top of the file to disable all instances. ```csharp -#pragma warning disable NUnit2031 // Consider using Assert.That(actual, Is.Not.SameAs(expected)) instead of Assert.AreNotSame(expected, actual) +#pragma warning disable NUnit2031 // Consider using Assert.That(actual, Is.Not.SameAs(expected)) instead of ClassicAssert.AreNotSame(expected, actual) ``` ### Via attribute `[SuppressMessage]` ```csharp [System.Diagnostics.CodeAnalysis.SuppressMessage("Assertion", - "NUnit2031:Consider using Assert.That(actual, Is.Not.SameAs(expected)) instead of Assert.AreNotSame(expected, actual)", + "NUnit2031:Consider using Assert.That(actual, Is.Not.SameAs(expected)) instead of ClassicAssert.AreNotSame(expected, actual)", Justification = "Reason...")] ``` diff --git a/documentation/NUnit2032.md b/documentation/NUnit2032.md index 806704d4..4eb848ca 100644 --- a/documentation/NUnit2032.md +++ b/documentation/NUnit2032.md @@ -1,6 +1,6 @@ # NUnit2032 -## Consider using Assert.That(expr, Is.Zero) instead of Assert.Zero(expr) +## Consider using Assert.That(expr, Is.Zero) instead of ClassicAssert.Zero(expr) | Topic | Value | :-- | :-- @@ -12,24 +12,24 @@ ## Description -Consider using the constraint model, `Assert.That(expr, Is.Zero)`, instead of the classic model, `Assert.Zero(expr)`. +Consider using the constraint model, `Assert.That(expr, Is.Zero)`, instead of the classic model, `ClassicAssert.Zero(expr)`. ## Motivation The classic Assert model contains less flexibility than the constraint model, -so this analyzer marks usages of `Assert.Zero` from the classic Assert model. +so this analyzer marks usages of `ClassicAssert.Zero` from the classic Assert model. ```csharp [Test] public void Test() { - Assert.Zero(expression); + ClassicAssert.Zero(expression); } ``` ## How to fix violations -The analyzer comes with a code fix that will replace `Assert.Zero(expression)` with +The analyzer comes with a code fix that will replace `ClassicAssert.Zero(expression)` with `Assert.That(expression, Is.Zero)`. So the code block above will be changed into. ```csharp @@ -50,7 +50,7 @@ Configure the severity per project, for more info see [MSDN](https://learn.micro ### Via .editorconfig file ```ini -# NUnit2032: Consider using Assert.That(expr, Is.Zero) instead of Assert.Zero(expr) +# NUnit2032: Consider using Assert.That(expr, Is.Zero) instead of ClassicAssert.Zero(expr) dotnet_diagnostic.NUnit2032.severity = chosenSeverity ``` @@ -59,22 +59,22 @@ where `chosenSeverity` can be one of `none`, `silent`, `suggestion`, `warning`, ### Via #pragma directive ```csharp -#pragma warning disable NUnit2032 // Consider using Assert.That(expr, Is.Zero) instead of Assert.Zero(expr) +#pragma warning disable NUnit2032 // Consider using Assert.That(expr, Is.Zero) instead of ClassicAssert.Zero(expr) Code violating the rule here -#pragma warning restore NUnit2032 // Consider using Assert.That(expr, Is.Zero) instead of Assert.Zero(expr) +#pragma warning restore NUnit2032 // Consider using Assert.That(expr, Is.Zero) instead of ClassicAssert.Zero(expr) ``` Or put this at the top of the file to disable all instances. ```csharp -#pragma warning disable NUnit2032 // Consider using Assert.That(expr, Is.Zero) instead of Assert.Zero(expr) +#pragma warning disable NUnit2032 // Consider using Assert.That(expr, Is.Zero) instead of ClassicAssert.Zero(expr) ``` ### Via attribute `[SuppressMessage]` ```csharp [System.Diagnostics.CodeAnalysis.SuppressMessage("Assertion", - "NUnit2032:Consider using Assert.That(expr, Is.Zero) instead of Assert.Zero(expr)", + "NUnit2032:Consider using Assert.That(expr, Is.Zero) instead of ClassicAssert.Zero(expr)", Justification = "Reason...")] ``` diff --git a/documentation/NUnit2033.md b/documentation/NUnit2033.md index c22cb1a7..9c8520da 100644 --- a/documentation/NUnit2033.md +++ b/documentation/NUnit2033.md @@ -1,6 +1,6 @@ # NUnit2033 -## Consider using Assert.That(expr, Is.Not.Zero) instead of Assert.NotZero(expr) +## Consider using Assert.That(expr, Is.Not.Zero) instead of ClassicAssert.NotZero(expr) | Topic | Value | :-- | :-- @@ -12,24 +12,24 @@ ## Description -Consider using the constraint model, `Assert.That(expr, Is.Not.Zero)`, instead of the classic model, `Assert.NotZero(expr)`. +Consider using the constraint model, `Assert.That(expr, Is.Not.Zero)`, instead of the classic model, `ClassicAssert.NotZero(expr)`. ## Motivation The classic Assert model contains less flexibility than the constraint model, -so this analyzer marks usages of `Assert.NotZero` from the classic Assert model. +so this analyzer marks usages of `ClassicAssert.NotZero` from the classic Assert model. ```csharp [Test] public void Test() { - Assert.NotZero(expression); + ClassicAssert.NotZero(expression); } ``` ## How to fix violations -The analyzer comes with a code fix that will replace `Assert.NotZero(expression)` with +The analyzer comes with a code fix that will replace `ClassicAssert.NotZero(expression)` with `Assert.That(expression, Is.Not.Zero)`. So the code block above will be changed into. ```csharp @@ -50,7 +50,7 @@ Configure the severity per project, for more info see [MSDN](https://learn.micro ### Via .editorconfig file ```ini -# NUnit2033: Consider using Assert.That(expr, Is.Not.Zero) instead of Assert.NotZero(expr) +# NUnit2033: Consider using Assert.That(expr, Is.Not.Zero) instead of ClassicAssert.NotZero(expr) dotnet_diagnostic.NUnit2033.severity = chosenSeverity ``` @@ -59,22 +59,22 @@ where `chosenSeverity` can be one of `none`, `silent`, `suggestion`, `warning`, ### Via #pragma directive ```csharp -#pragma warning disable NUnit2033 // Consider using Assert.That(expr, Is.Not.Zero) instead of Assert.NotZero(expr) +#pragma warning disable NUnit2033 // Consider using Assert.That(expr, Is.Not.Zero) instead of ClassicAssert.NotZero(expr) Code violating the rule here -#pragma warning restore NUnit2033 // Consider using Assert.That(expr, Is.Not.Zero) instead of Assert.NotZero(expr) +#pragma warning restore NUnit2033 // Consider using Assert.That(expr, Is.Not.Zero) instead of ClassicAssert.NotZero(expr) ``` Or put this at the top of the file to disable all instances. ```csharp -#pragma warning disable NUnit2033 // Consider using Assert.That(expr, Is.Not.Zero) instead of Assert.NotZero(expr) +#pragma warning disable NUnit2033 // Consider using Assert.That(expr, Is.Not.Zero) instead of ClassicAssert.NotZero(expr) ``` ### Via attribute `[SuppressMessage]` ```csharp [System.Diagnostics.CodeAnalysis.SuppressMessage("Assertion", - "NUnit2033:Consider using Assert.That(expr, Is.Not.Zero) instead of Assert.NotZero(expr)", + "NUnit2033:Consider using Assert.That(expr, Is.Not.Zero) instead of ClassicAssert.NotZero(expr)", Justification = "Reason...")] ``` diff --git a/documentation/NUnit2034.md b/documentation/NUnit2034.md index 806918e1..3709482b 100644 --- a/documentation/NUnit2034.md +++ b/documentation/NUnit2034.md @@ -1,6 +1,6 @@ # NUnit2034 -## Consider using Assert.That(expr, Is.NaN) instead of Assert.IsNaN(expr) +## Consider using Assert.That(expr, Is.NaN) instead of ClassicAssert.IsNaN(expr) | Topic | Value | :-- | :-- @@ -12,24 +12,24 @@ ## Description -Consider using the constraint model, `Assert.That(expr, Is.NaN)`, instead of the classic model, `Assert.IsNaN(expr)`. +Consider using the constraint model, `Assert.That(expr, Is.NaN)`, instead of the classic model, `ClassicAssert.IsNaN(expr)`. ## Motivation The classic Assert model contains less flexibility than the constraint model, -so this analyzer marks usages of `Assert.IsNaN` from the classic Assert model. +so this analyzer marks usages of `ClassicAssert.IsNaN` from the classic Assert model. ```csharp [Test] public void Test() { - Assert.IsNaN(expression); + ClassicAssert.IsNaN(expression); } ``` ## How to fix violations -The analyzer comes with a code fix that will replace `Assert.IsNaN(expression)` with +The analyzer comes with a code fix that will replace `ClassicAssert.IsNaN(expression)` with `Assert.That(expression, Is.NaN)`. So the code block above will be changed into. ```csharp @@ -50,7 +50,7 @@ Configure the severity per project, for more info see [MSDN](https://learn.micro ### Via .editorconfig file ```ini -# NUnit2034: Consider using Assert.That(expr, Is.NaN) instead of Assert.IsNaN(expr) +# NUnit2034: Consider using Assert.That(expr, Is.NaN) instead of ClassicAssert.IsNaN(expr) dotnet_diagnostic.NUnit2034.severity = chosenSeverity ``` @@ -59,22 +59,22 @@ where `chosenSeverity` can be one of `none`, `silent`, `suggestion`, `warning`, ### Via #pragma directive ```csharp -#pragma warning disable NUnit2034 // Consider using Assert.That(expr, Is.NaN) instead of Assert.IsNaN(expr) +#pragma warning disable NUnit2034 // Consider using Assert.That(expr, Is.NaN) instead of ClassicAssert.IsNaN(expr) Code violating the rule here -#pragma warning restore NUnit2034 // Consider using Assert.That(expr, Is.NaN) instead of Assert.IsNaN(expr) +#pragma warning restore NUnit2034 // Consider using Assert.That(expr, Is.NaN) instead of ClassicAssert.IsNaN(expr) ``` Or put this at the top of the file to disable all instances. ```csharp -#pragma warning disable NUnit2034 // Consider using Assert.That(expr, Is.NaN) instead of Assert.IsNaN(expr) +#pragma warning disable NUnit2034 // Consider using Assert.That(expr, Is.NaN) instead of ClassicAssert.IsNaN(expr) ``` ### Via attribute `[SuppressMessage]` ```csharp [System.Diagnostics.CodeAnalysis.SuppressMessage("Assertion", - "NUnit2034:Consider using Assert.That(expr, Is.NaN) instead of Assert.IsNaN(expr)", + "NUnit2034:Consider using Assert.That(expr, Is.NaN) instead of ClassicAssert.IsNaN(expr)", Justification = "Reason...")] ``` diff --git a/documentation/NUnit2035.md b/documentation/NUnit2035.md index 6a2630cc..eefeee87 100644 --- a/documentation/NUnit2035.md +++ b/documentation/NUnit2035.md @@ -1,6 +1,6 @@ # NUnit2035 -## Consider using Assert.That(collection, Is.Empty) instead of Assert.IsEmpty(collection) +## Consider using Assert.That(collection, Is.Empty) instead of ClassicAssert.IsEmpty(collection) | Topic | Value | :-- | :-- @@ -12,24 +12,24 @@ ## Description -Consider using the constraint model, `Assert.That(collection, Is.Empty)`, instead of the classic model, `Assert.IsEmpty(collection)`. +Consider using the constraint model, `Assert.That(collection, Is.Empty)`, instead of the classic model, `ClassicAssert.IsEmpty(collection)`. ## Motivation The classic Assert model contains less flexibility than the constraint model, -so this analyzer marks usages of `Assert.IsEmpty` from the classic Assert model. +so this analyzer marks usages of `ClassicAssert.IsEmpty` from the classic Assert model. ```csharp [Test] public void Test() { - Assert.IsEmpty(collection); + ClassicAssert.IsEmpty(collection); } ``` ## How to fix violations -The analyzer comes with a code fix that will replace `Assert.IsEmpty(collection)` with +The analyzer comes with a code fix that will replace `ClassicAssert.IsEmpty(collection)` with `Assert.That(collection, Is.Empty)`. So the code block above will be changed into. ```csharp @@ -50,7 +50,7 @@ Configure the severity per project, for more info see [MSDN](https://learn.micro ### Via .editorconfig file ```ini -# NUnit2035: Consider using Assert.That(collection, Is.Empty) instead of Assert.IsEmpty(collection) +# NUnit2035: Consider using Assert.That(collection, Is.Empty) instead of ClassicAssert.IsEmpty(collection) dotnet_diagnostic.NUnit2035.severity = chosenSeverity ``` @@ -59,22 +59,22 @@ where `chosenSeverity` can be one of `none`, `silent`, `suggestion`, `warning`, ### Via #pragma directive ```csharp -#pragma warning disable NUnit2035 // Consider using Assert.That(collection, Is.Empty) instead of Assert.IsEmpty(collection) +#pragma warning disable NUnit2035 // Consider using Assert.That(collection, Is.Empty) instead of ClassicAssert.IsEmpty(collection) Code violating the rule here -#pragma warning restore NUnit2035 // Consider using Assert.That(collection, Is.Empty) instead of Assert.IsEmpty(collection) +#pragma warning restore NUnit2035 // Consider using Assert.That(collection, Is.Empty) instead of ClassicAssert.IsEmpty(collection) ``` Or put this at the top of the file to disable all instances. ```csharp -#pragma warning disable NUnit2035 // Consider using Assert.That(collection, Is.Empty) instead of Assert.IsEmpty(collection) +#pragma warning disable NUnit2035 // Consider using Assert.That(collection, Is.Empty) instead of ClassicAssert.IsEmpty(collection) ``` ### Via attribute `[SuppressMessage]` ```csharp [System.Diagnostics.CodeAnalysis.SuppressMessage("Assertion", - "NUnit2035:Consider using Assert.That(collection, Is.Empty) instead of Assert.IsEmpty(collection)", + "NUnit2035:Consider using Assert.That(collection, Is.Empty) instead of ClassicAssert.IsEmpty(collection)", Justification = "Reason...")] ``` diff --git a/documentation/NUnit2036.md b/documentation/NUnit2036.md index 7534bfe4..54a9af5e 100644 --- a/documentation/NUnit2036.md +++ b/documentation/NUnit2036.md @@ -1,6 +1,6 @@ # NUnit2036 -## Consider using Assert.That(collection, Is.Not.Empty) instead of Assert.IsNotEmpty(collection) +## Consider using Assert.That(collection, Is.Not.Empty) instead of ClassicAssert.IsNotEmpty(collection) | Topic | Value | :-- | :-- @@ -12,24 +12,24 @@ ## Description -Consider using the constraint model, `Assert.That(collection, Is.Not.Empty)`, instead of the classic model, `Assert.IsNotEmpty(collection)`. +Consider using the constraint model, `Assert.That(collection, Is.Not.Empty)`, instead of the classic model, `ClassicAssert.IsNotEmpty(collection)`. ## Motivation The classic Assert model contains less flexibility than the constraint model, -so this analyzer marks usages of `Assert.IsNotEmpty` from the classic Assert model. +so this analyzer marks usages of `ClassicAssert.IsNotEmpty` from the classic Assert model. ```csharp [Test] public void Test() { - Assert.IsNotEmpty(collection); + ClassicAssert.IsNotEmpty(collection); } ``` ## How to fix violations -The analyzer comes with a code fix that will replace `Assert.IsNotEmpty(collection)` with +The analyzer comes with a code fix that will replace `ClassicAssert.IsNotEmpty(collection)` with `Assert.That(collection, Is.Not.Empty)`. So the code block above will be changed into. ```csharp @@ -50,7 +50,7 @@ Configure the severity per project, for more info see [MSDN](https://learn.micro ### Via .editorconfig file ```ini -# NUnit2036: Consider using Assert.That(collection, Is.Not.Empty) instead of Assert.IsNotEmpty(collection) +# NUnit2036: Consider using Assert.That(collection, Is.Not.Empty) instead of ClassicAssert.IsNotEmpty(collection) dotnet_diagnostic.NUnit2036.severity = chosenSeverity ``` @@ -59,22 +59,22 @@ where `chosenSeverity` can be one of `none`, `silent`, `suggestion`, `warning`, ### Via #pragma directive ```csharp -#pragma warning disable NUnit2036 // Consider using Assert.That(collection, Is.Not.Empty) instead of Assert.IsNotEmpty(collection) +#pragma warning disable NUnit2036 // Consider using Assert.That(collection, Is.Not.Empty) instead of ClassicAssert.IsNotEmpty(collection) Code violating the rule here -#pragma warning restore NUnit2036 // Consider using Assert.That(collection, Is.Not.Empty) instead of Assert.IsNotEmpty(collection) +#pragma warning restore NUnit2036 // Consider using Assert.That(collection, Is.Not.Empty) instead of ClassicAssert.IsNotEmpty(collection) ``` Or put this at the top of the file to disable all instances. ```csharp -#pragma warning disable NUnit2036 // Consider using Assert.That(collection, Is.Not.Empty) instead of Assert.IsNotEmpty(collection) +#pragma warning disable NUnit2036 // Consider using Assert.That(collection, Is.Not.Empty) instead of ClassicAssert.IsNotEmpty(collection) ``` ### Via attribute `[SuppressMessage]` ```csharp [System.Diagnostics.CodeAnalysis.SuppressMessage("Assertion", - "NUnit2036:Consider using Assert.That(collection, Is.Not.Empty) instead of Assert.IsNotEmpty(collection)", + "NUnit2036:Consider using Assert.That(collection, Is.Not.Empty) instead of ClassicAssert.IsNotEmpty(collection)", Justification = "Reason...")] ``` diff --git a/documentation/NUnit2037.md b/documentation/NUnit2037.md index 5dbb8157..417c7cb8 100644 --- a/documentation/NUnit2037.md +++ b/documentation/NUnit2037.md @@ -1,6 +1,6 @@ # NUnit2037 -## Consider using Assert.That(collection, Does.Contain(instance)) instead of Assert.Contains(instance, collection) +## Consider using Assert.That(collection, Does.Contain(instance)) instead of ClassicAssert.Contains(instance, collection) | Topic | Value | :-- | :-- @@ -12,24 +12,24 @@ ## Description -Consider using the constraint model, `Assert.That(collection, Does.Contain(instance))`, instead of the classic model, `Assert.Contains(instance, collection)`. +Consider using the constraint model, `Assert.That(collection, Does.Contain(instance))`, instead of the classic model, `ClassicAssert.Contains(instance, collection)`. ## Motivation -The assert `Assert.Contains` from the classic Assert model makes it easy to confuse the `instance` and the `collection` argument, -so this analyzer marks usages of `Assert.Contains`. +The assert `ClassicAssert.Contains` from the classic Assert model makes it easy to confuse the `instance` and the `collection` argument, +so this analyzer marks usages of `ClassicAssert.Contains`. ```csharp [Test] public void Test() { - Assert.Contains(instance, collection); + ClassicAssert.Contains(instance, collection); } ``` ## How to fix violations -The analyzer comes with a code fix that will replace `Assert.Contains(instance, collection)` with +The analyzer comes with a code fix that will replace `ClassicAssert.Contains(instance, collection)` with `Assert.That(collection, Does.Contain(instance))`. So the code block above will be changed into. ```csharp @@ -50,7 +50,7 @@ Configure the severity per project, for more info see [MSDN](https://learn.micro ### Via .editorconfig file ```ini -# NUnit2037: Consider using Assert.That(collection, Does.Contain(instance)) instead of Assert.Contains(instance, collection) +# NUnit2037: Consider using Assert.That(collection, Does.Contain(instance)) instead of ClassicAssert.Contains(instance, collection) dotnet_diagnostic.NUnit2037.severity = chosenSeverity ``` @@ -59,22 +59,22 @@ where `chosenSeverity` can be one of `none`, `silent`, `suggestion`, `warning`, ### Via #pragma directive ```csharp -#pragma warning disable NUnit2037 // Consider using Assert.That(collection, Does.Contain(instance)) instead of Assert.Contains(instance, collection) +#pragma warning disable NUnit2037 // Consider using Assert.That(collection, Does.Contain(instance)) instead of ClassicAssert.Contains(instance, collection) Code violating the rule here -#pragma warning restore NUnit2037 // Consider using Assert.That(collection, Does.Contain(instance)) instead of Assert.Contains(instance, collection) +#pragma warning restore NUnit2037 // Consider using Assert.That(collection, Does.Contain(instance)) instead of ClassicAssert.Contains(instance, collection) ``` Or put this at the top of the file to disable all instances. ```csharp -#pragma warning disable NUnit2037 // Consider using Assert.That(collection, Does.Contain(instance)) instead of Assert.Contains(instance, collection) +#pragma warning disable NUnit2037 // Consider using Assert.That(collection, Does.Contain(instance)) instead of ClassicAssert.Contains(instance, collection) ``` ### Via attribute `[SuppressMessage]` ```csharp [System.Diagnostics.CodeAnalysis.SuppressMessage("Assertion", - "NUnit2037:Consider using Assert.That(collection, Does.Contain(instance)) instead of Assert.Contains(instance, collection)", + "NUnit2037:Consider using Assert.That(collection, Does.Contain(instance)) instead of ClassicAssert.Contains(instance, collection)", Justification = "Reason...")] ``` diff --git a/documentation/NUnit2038.md b/documentation/NUnit2038.md index 36138d4a..85e3a83e 100644 --- a/documentation/NUnit2038.md +++ b/documentation/NUnit2038.md @@ -1,6 +1,6 @@ # NUnit2038 -## Consider using Assert.That(actual, Is.InstanceOf(expected)) instead of Assert.IsInstanceOf(expected, actual) +## Consider using Assert.That(actual, Is.InstanceOf(expected)) instead of ClassicAssert.IsInstanceOf(expected, actual) | Topic | Value | :-- | :-- @@ -12,24 +12,24 @@ ## Description -Consider using the constraint model, `Assert.That(actual, Is.InstanceOf(expected))`, instead of the classic model, `Assert.IsInstanceOf(expected, actual)`. +Consider using the constraint model, `Assert.That(actual, Is.InstanceOf(expected))`, instead of the classic model, `ClassicAssert.IsInstanceOf(expected, actual)`. ## Motivation -The assert `Assert.IsInstanceOf` from the classic Assert model makes it easy to confuse the `expected` and the `actual` argument, -so this analyzer marks usages of `Assert.IsInstanceOf`. +The assert `ClassicAssert.IsInstanceOf` from the classic Assert model makes it easy to confuse the `expected` and the `actual` argument, +so this analyzer marks usages of `ClassicAssert.IsInstanceOf`. ```csharp [Test] public void Test() { - Assert.IsInstanceOf(expected, actual); + ClassicAssert.IsInstanceOf(expected, actual); } ``` ## How to fix violations -The analyzer comes with a code fix that will replace `Assert.IsInstanceOf(expected, actual)` with +The analyzer comes with a code fix that will replace `ClassicAssert.IsInstanceOf(expected, actual)` with `Assert.That(actual, Is.InstanceOf(expected))`. So the code block above will be changed into. ```csharp @@ -50,7 +50,7 @@ Configure the severity per project, for more info see [MSDN](https://learn.micro ### Via .editorconfig file ```ini -# NUnit2038: Consider using Assert.That(actual, Is.InstanceOf(expected)) instead of Assert.IsInstanceOf(expected, actual) +# NUnit2038: Consider using Assert.That(actual, Is.InstanceOf(expected)) instead of ClassicAssert.IsInstanceOf(expected, actual) dotnet_diagnostic.NUnit2038.severity = chosenSeverity ``` @@ -59,22 +59,22 @@ where `chosenSeverity` can be one of `none`, `silent`, `suggestion`, `warning`, ### Via #pragma directive ```csharp -#pragma warning disable NUnit2038 // Consider using Assert.That(actual, Is.InstanceOf(expected)) instead of Assert.IsInstanceOf(expected, actual) +#pragma warning disable NUnit2038 // Consider using Assert.That(actual, Is.InstanceOf(expected)) instead of ClassicAssert.IsInstanceOf(expected, actual) Code violating the rule here -#pragma warning restore NUnit2038 // Consider using Assert.That(actual, Is.InstanceOf(expected)) instead of Assert.IsInstanceOf(expected, actual) +#pragma warning restore NUnit2038 // Consider using Assert.That(actual, Is.InstanceOf(expected)) instead of ClassicAssert.IsInstanceOf(expected, actual) ``` Or put this at the top of the file to disable all instances. ```csharp -#pragma warning disable NUnit2038 // Consider using Assert.That(actual, Is.InstanceOf(expected)) instead of Assert.IsInstanceOf(expected, actual) +#pragma warning disable NUnit2038 // Consider using Assert.That(actual, Is.InstanceOf(expected)) instead of ClassicAssert.IsInstanceOf(expected, actual) ``` ### Via attribute `[SuppressMessage]` ```csharp [System.Diagnostics.CodeAnalysis.SuppressMessage("Assertion", - "NUnit2038:Consider using Assert.That(actual, Is.InstanceOf(expected)) instead of Assert.IsInstanceOf(expected, actual)", + "NUnit2038:Consider using Assert.That(actual, Is.InstanceOf(expected)) instead of ClassicAssert.IsInstanceOf(expected, actual)", Justification = "Reason...")] ``` diff --git a/documentation/NUnit2039.md b/documentation/NUnit2039.md index 853aa384..c11c9233 100644 --- a/documentation/NUnit2039.md +++ b/documentation/NUnit2039.md @@ -1,6 +1,6 @@ # NUnit2039 -## Consider using Assert.That(actual, Is.Not.InstanceOf(expected)) instead of Assert.IsNotInstanceOf(expected, actual) +## Consider using Assert.That(actual, Is.Not.InstanceOf(expected)) instead of ClassicAssert.IsNotInstanceOf(expected, actual) | Topic | Value | :-- | :-- @@ -12,24 +12,24 @@ ## Description -Consider using the constraint model, `Assert.That(actual, Is.Not.InstanceOf(expected))`, instead of the classic model, `Assert.IsNotInstanceOf(expected, actual)`. +Consider using the constraint model, `Assert.That(actual, Is.Not.InstanceOf(expected))`, instead of the classic model, `ClassicAssert.IsNotInstanceOf(expected, actual)`. ## Motivation -The assert `Assert.IsNotInstanceOf` from the classic Assert model makes it easy to confuse the `expected` and the `actual` argument, -so this analyzer marks usages of `Assert.IsNotInstanceOf`. +The assert `ClassicAssert.IsNotInstanceOf` from the classic Assert model makes it easy to confuse the `expected` and the `actual` argument, +so this analyzer marks usages of `ClassicAssert.IsNotInstanceOf`. ```csharp [Test] public void Test() { - Assert.IsNotInstanceOf(expected, actual); + ClassicAssert.IsNotInstanceOf(expected, actual); } ``` ## How to fix violations -The analyzer comes with a code fix that will replace `Assert.IsNotInstanceOf(expected, actual)` with +The analyzer comes with a code fix that will replace `ClassicAssert.IsNotInstanceOf(expected, actual)` with `Assert.That(actual, Is.Not.InstanceOf(expected))`. So the code block above will be changed into. ```csharp @@ -50,7 +50,7 @@ Configure the severity per project, for more info see [MSDN](https://learn.micro ### Via .editorconfig file ```ini -# NUnit2039: Consider using Assert.That(actual, Is.Not.InstanceOf(expected)) instead of Assert.IsNotInstanceOf(expected, actual) +# NUnit2039: Consider using Assert.That(actual, Is.Not.InstanceOf(expected)) instead of ClassicAssert.IsNotInstanceOf(expected, actual) dotnet_diagnostic.NUnit2039.severity = chosenSeverity ``` @@ -59,22 +59,22 @@ where `chosenSeverity` can be one of `none`, `silent`, `suggestion`, `warning`, ### Via #pragma directive ```csharp -#pragma warning disable NUnit2039 // Consider using Assert.That(actual, Is.Not.InstanceOf(expected)) instead of Assert.IsNotInstanceOf(expected, actual) +#pragma warning disable NUnit2039 // Consider using Assert.That(actual, Is.Not.InstanceOf(expected)) instead of ClassicAssert.IsNotInstanceOf(expected, actual) Code violating the rule here -#pragma warning restore NUnit2039 // Consider using Assert.That(actual, Is.Not.InstanceOf(expected)) instead of Assert.IsNotInstanceOf(expected, actual) +#pragma warning restore NUnit2039 // Consider using Assert.That(actual, Is.Not.InstanceOf(expected)) instead of ClassicAssert.IsNotInstanceOf(expected, actual) ``` Or put this at the top of the file to disable all instances. ```csharp -#pragma warning disable NUnit2039 // Consider using Assert.That(actual, Is.Not.InstanceOf(expected)) instead of Assert.IsNotInstanceOf(expected, actual) +#pragma warning disable NUnit2039 // Consider using Assert.That(actual, Is.Not.InstanceOf(expected)) instead of ClassicAssert.IsNotInstanceOf(expected, actual) ``` ### Via attribute `[SuppressMessage]` ```csharp [System.Diagnostics.CodeAnalysis.SuppressMessage("Assertion", - "NUnit2039:Consider using Assert.That(actual, Is.Not.InstanceOf(expected)) instead of Assert.IsNotInstanceOf(expected, actual)", + "NUnit2039:Consider using Assert.That(actual, Is.Not.InstanceOf(expected)) instead of ClassicAssert.IsNotInstanceOf(expected, actual)", Justification = "Reason...")] ``` diff --git a/documentation/NUnit2043.md b/documentation/NUnit2043.md index 3c989137..ccd4fe1c 100644 --- a/documentation/NUnit2043.md +++ b/documentation/NUnit2043.md @@ -24,13 +24,13 @@ where it is possible to replace with the appropriate comparison constraint. [Test] public void Test() { - Assert.True(actual > expected); + ClassicAssert.True(actual > expected); } ``` ## How to fix violations -The analyzer comes with a code fix that will replace `Assert.True(actual > expected)` with +The analyzer comes with a code fix that will replace `ClassicAssert.True(actual > expected)` with `Assert.That(actual, Is.GreaterThan(expected))`. So the code block above will be changed into ```csharp diff --git a/documentation/NUnit2048.md b/documentation/NUnit2048.md new file mode 100644 index 00000000..6227a45e --- /dev/null +++ b/documentation/NUnit2048.md @@ -0,0 +1,98 @@ +# NUnit2048 + +## Consider using Assert.That(...) instead of StringAssert(...) + +| Topic | Value +| :-- | :-- +| Id | NUnit2048 +| Severity | Warning +| Enabled | True +| Category | Assertion +| Code | [StringAssertUsageAnalyzer](https://github.com/nunit/nunit.analyzers/blob/master/src/nunit.analyzers/StringAssertUsage/StringAssertUsageAnalyzer.cs) + +## Description + +Consider using the constraint model, `Assert.That(actual, {0}(expected))`, instead of the classic model, `StringAssert.{1}(expected, actual)`. + +## Motivation + +The classic Assert model contains less flexibility than the constraint model and makes it easy to mix the `expected` and the `actual` parameter, +so this analyzer marks usages of all `StringAssert` methods from the classic Assert model. + +```csharp +[Test] +public void Test() +{ + StringAssert.Contains(expected, actual); + StringAssert.DoesNotContain(expected, actual); + StringAssert.StartsWith(expected, actual); + StringAssert.DoesNotStartWith(expected, actual); + StringAssert.EndsWith(expected, actual); + StringAssert.DoesNotEndWith(expected, actual); + StringAssert.AreEqualIgnoreCase(expected, actual); + StringAssert.AreNotEqualIgnoreCase(expected, actual); + StringAssert.IsMatch(expected, actual); + StringAssert.DoesNotMatch(expected, actual); +} +``` + +## How to fix violations + +The analyzer comes with a code fix that will replace `StringAssert.(expected, actual)` with +`Assert.That(actual, (expected))`. So the code block above will be changed into. + +```csharp +[Test] +public void Test() +{ + Assert.That(actual, Does.Contain(expected)); + Assert.That(actual, Does.Not.Contain(expected)); + Assert.That(actual, Does.StartWith(expected)); + Assert.That(actual, Does.Not.StartWith(expected)); + Assert.That(actual, Does.EndWith(expected)); + Assert.That(actual, Does.Not.EndWith(expected)); + Assert.That(actual, Is.EqualTo(expected).IgnoreCase); + Assert.That(actual, Is.Not.EqualTo(expected).IgnoreCase); + Assert.That(actual, Does.Match(expected)); + Assert.That(actual, Does.Not.Match(expected)); +} +``` + + +## Configure severity + +### Via ruleset file + +Configure the severity per project, for more info see [MSDN](https://learn.microsoft.com/en-us/visualstudio/code-quality/using-rule-sets-to-group-code-analysis-rules?view=vs-2022). + +### Via .editorconfig file + +```ini +# NUnit2048: Consider using Assert.That(...) instead of StringAssert(...) +dotnet_diagnostic.NUnit2048.severity = chosenSeverity +``` + +where `chosenSeverity` can be one of `none`, `silent`, `suggestion`, `warning`, or `error`. + +### Via #pragma directive + +```csharp +#pragma warning disable NUnit2048 // Consider using Assert.That(...) instead of StringAssert(...) +Code violating the rule here +#pragma warning restore NUnit2048 // Consider using Assert.That(...) instead of StringAssert(...) +``` + +Or put this at the top of the file to disable all instances. + +```csharp +#pragma warning disable NUnit2048 // Consider using Assert.That(...) instead of StringAssert(...) +``` + +### Via attribute `[SuppressMessage]` + +```csharp +[System.Diagnostics.CodeAnalysis.SuppressMessage("Assertion", + "NUnit2048:Consider using Assert.That(...) instead of StringAssert(...)", + Justification = "Reason...")] +``` + diff --git a/documentation/NUnit2049.md b/documentation/NUnit2049.md new file mode 100644 index 00000000..cac47396 --- /dev/null +++ b/documentation/NUnit2049.md @@ -0,0 +1,110 @@ +# NUnit2049 + +## Consider using Assert.That(...) instead of CollectionAssert(...) + +| Topic | Value +| :-- | :-- +| Id | NUnit2049 +| Severity | Warning +| Enabled | True +| Category | Assertion +| Code | [CollectionAssertUsageAnalyzer](https://github.com/nunit/nunit.analyzers/blob/master/src/nunit.analyzers/CollectionAssertUsage/CollectionAssertUsageAnalyzer.cs) + +## Description + +Consider using the constraint model, `Assert.That(actual, {0}(expected))`, instead of the classic model, `CollectionAssert.{1}(expected, actual)`. + +## Motivation + +The classic Assert model contains less flexibility than the constraint model and makes it easy to mix the order of the parameters, +so this analyzer marks usages of all `CollectionAssert` methods from the classic Assert model. + +```csharp +[Test] +public void Test() +{ + CollectionAssert.AllItemsAreInstancesOfType(collection, expected); + CollectionAssert.AllItemsAreNotNull(collection); + CollectionAssert.AllItemsAreUnique(collection); + CollectionAssert.AreEqual(expected, actual); + CollectionAssert.AreEquivalent(expected, actual); + CollectionAssert.AreNotEqual(expected, actual); + CollectionAssert.AreNotEquivalent(expected, actual); + CollectionAssert.Contains(collection, expected); + CollectionAssert.DoesNotContain(collection, expected); + CollectionAssert.IsNotSubsetOf(subset, superset); + CollectionAssert.IsSubsetOf(subset, superset); + CollectionAssert.IsNotSupersetOf(superset, subset); + CollectionAssert.IsSupersetOf(superset, subset); + CollectionAssert.IsEmpty(collection); + CollectionAssert.IsNotEmpty(collection); + CollectionAssert.IsOrdered(collection); +} +``` + +## How to fix violations + +The analyzer comes with a code fix that will replace `StringAssert.(expected, actual)` with +`Assert.That(actual, (expected))`. So the code block above will be changed into. + +```csharp +[Test] +public void Test() +{ + Assert.That(collection, Is.All.InstanceOf(expected)); + Assert.That(collection, Is.All.Not.Null); + Assert.That(collection, Is.Unique); + Assert.That(actual, Is.EqualTo(expected).AsCollection); + Assert.That(actual, Is.EquivalentTo(expected)); + Assert.That(actual, Is.Not.EqualTo(expected).AsCollection); + Assert.That(actual, Is.Not.EquivalentTo(expected)); + Assert.That(collection, Has.Member(expected)); + Assert.That(collection, Has.No.Member(expected)); + Assert.That(subset, Is.Not.SubsetOf(superset)); + Assert.That(subset, Is.SubsetOf(superset)); + Assert.That(superset, Is.Not.SupersetOf(subset)); + Assert.That(superset, Is.SupersetOf(subset)); + Assert.That(collection, Is.Empty); + Assert.That(collection, Is.Not.Empty); + Assert.That(collection, Is.Ordered); +} +``` + + +## Configure severity + +### Via ruleset file + +Configure the severity per project, for more info see [MSDN](https://learn.microsoft.com/en-us/visualstudio/code-quality/using-rule-sets-to-group-code-analysis-rules?view=vs-2022). + +### Via .editorconfig file + +```ini +# NUnit2049: Consider using Assert.That(...) instead of CollectionAssert(...) +dotnet_diagnostic.NUnit2049.severity = chosenSeverity +``` + +where `chosenSeverity` can be one of `none`, `silent`, `suggestion`, `warning`, or `error`. + +### Via #pragma directive + +```csharp +#pragma warning disable NUnit2049 // Consider using Assert.That(...) instead of CollectionAssert(...) +Code violating the rule here +#pragma warning restore NUnit2049 // Consider using Assert.That(...) instead of CollectionAssert(...) +``` + +Or put this at the top of the file to disable all instances. + +```csharp +#pragma warning disable NUnit2049 // Consider using Assert.That(...) instead of CollectionAssert(...) +``` + +### Via attribute `[SuppressMessage]` + +```csharp +[System.Diagnostics.CodeAnalysis.SuppressMessage("Assertion", + "NUnit2049:Consider using Assert.That(...) instead of CollectionAssert(...)", + Justification = "Reason...")] +``` + diff --git a/documentation/NUnit2050.md b/documentation/NUnit2050.md new file mode 100644 index 00000000..2ec0da35 --- /dev/null +++ b/documentation/NUnit2050.md @@ -0,0 +1,107 @@ +# NUnit2050 + +## NUnit 4 no longer supports string.Format specification + +| Topic | Value +| :-- | :-- +| Id | NUnit2050 +| Severity | Error +| Enabled | True +| Category | Assertion +| Code | [UpdateStringFormatToInterpolatableStringAnalyzer](https://github.com/nunit/nunit.analyzers/blob/master/src/nunit.analyzers/UpdateStringFormatToInterpolatableString/UpdateStringFormatToInterpolatableStringAnalyzer.cs) + +## Description + +Replace format specification with interpolated string. + +## Motivation + +In order to get better failure messages, NUnit4 uses [`CallerArgumentExpression`](https://learn.microsoft.com/en-us/dotnet/api/system.runtime.compilerservices.callerargumentexpressionattribute?view=net-7.0) +to include the expression passed in for the _actual_ and _constraint_ parameters. +These are parameters automatically supplied by the compiler. + +To facilitate this, we needed to drop support for [composite formatting](https://learn.microsoft.com/en-us/dotnet/standard/base-types/composite-formatting) +All NUnit4 asserts only allow a single *message* parameter which can be either a simple string literal +or a [interpolatable string](https://learn.microsoft.com/en-us/dotnet/csharp/tutorials/string-interpolation) + +This analyzer needs to be run when still building against NUnit3 as otherwise your code won't compile. +When usages of the new methods with `params` are detected, the associated CodeFix will convert the format specification +into an interpolated string. + +## How to fix violations + +The following code, valid in NUNit3: + +```csharp +[TestCase(4)] +public void MustBeMultipleOf3(int value) +{ + Assert.That(value % 3, Is.Zero, "Expected value ({0}) to be multiple of 3", value); +} +``` + +Will fail with the following message: + +``` +Expected value (4) to be multiple of 3 +Expected: 0 +But was: 1 +``` + +The associated CodeFix for this Analyzer rule will convert the test into: + +```csharp +[TestCase(4)] +public void MustBeMultipleOf3(int value) +{ + Assert.That(value % 3, Is.Zero, $"Expected value ({value}) to be multiple of 3"); +} +``` + +The failure message for NUnit4 becomes: + +``` +Expected value (4) to be multiple of 3 +Assert.That(value % 3, Is.Zero) +Expected: 0 +But was: 1 +``` + + +## Configure severity + +### Via ruleset file + +Configure the severity per project, for more info see [MSDN](https://learn.microsoft.com/en-us/visualstudio/code-quality/using-rule-sets-to-group-code-analysis-rules?view=vs-2022). + +### Via .editorconfig file + +```ini +# NUnit2050: NUnit 4 no longer supports string.Format specification +dotnet_diagnostic.NUnit2050.severity = chosenSeverity +``` + +where `chosenSeverity` can be one of `none`, `silent`, `suggestion`, `warning`, or `error`. + +### Via #pragma directive + +```csharp +#pragma warning disable NUnit2050 // NUnit 4 no longer supports string.Format specification +Code violating the rule here +#pragma warning restore NUnit2050 // NUnit 4 no longer supports string.Format specification +``` + +Or put this at the top of the file to disable all instances. + +```csharp +#pragma warning disable NUnit2050 // NUnit 4 no longer supports string.Format specification +``` + +### Via attribute `[SuppressMessage]` + +```csharp +[System.Diagnostics.CodeAnalysis.SuppressMessage("Assertion", + "NUnit2050:NUnit 4 no longer supports string.Format specification", + Justification = "Reason...")] +``` + diff --git a/documentation/NUnit3001.md b/documentation/NUnit3001.md index d1b210df..dfc5b7d1 100644 --- a/documentation/NUnit3001.md +++ b/documentation/NUnit3001.md @@ -1,6 +1,6 @@ # NUnit3001 -## Expression was checked in an Assert.NotNull, Assert.IsNotNull or Assert.That call +## Expression was checked in an ClassicAssert.NotNull, ClassicAssert.IsNotNull or Assert.That call | Topic | Value | :-- | :-- @@ -18,8 +18,8 @@ This rule check diagnostics reported by the CS8601-CS8607 and CS8629 compiler er It then checks the previous statements for one of: -* `Assert.NotNull(...)` -* `Assert.IsNotNull(...)` +* `ClassicAssert.NotNull(...)` +* `ClassicAssert.IsNotNull(...)` * `Assert.That(..., Is.Not.Null)` For the same expression as the one that raised the original compiler error. @@ -31,8 +31,8 @@ In this case, the previous statement is allowed to be one of: * `Assert.That(...HasValue)` * `Assert.That(...HasValue, Is.True)` -* `Assert.True(...HasValue)` -* `Assert.IsTrue(...HasValue)` +* `ClassicAssert.True(...HasValue)` +* `ClassicAssert.IsTrue(...HasValue)` The exception is that if the statement is part of an `Assert.Multiple` it is not suppressed, as in this case the statement containing the compiler error will be executed. @@ -119,7 +119,7 @@ For more info about rulesets see [MSDN](https://learn.microsoft.com/en-us/visual This is currently not working. Waiting for [Roslyn](https://github.com/dotnet/roslyn/issues/49727) ```ini -# NUnit3001: Expression was checked in an Assert.NotNull, Assert.IsNotNull or Assert.That call +# NUnit3001: Expression was checked in an ClassicAssert.NotNull, ClassicAssert.IsNotNull or Assert.That call dotnet_diagnostic.NUnit3001.severity = none ``` diff --git a/documentation/index.md b/documentation/index.md index f09207af..29f975c2 100644 --- a/documentation/index.md +++ b/documentation/index.md @@ -58,12 +58,12 @@ Rules which improve assertions in the test code. | Id | Title | :mag: | :memo: | :bulb: | | :-- | :-- | :--: | :--: | :--: | -| [NUnit2001](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit2001.md) | Consider using Assert.That(expr, Is.False) instead of Assert.False(expr) | :white_check_mark: | :information_source: | :white_check_mark: | -| [NUnit2002](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit2002.md) | Consider using Assert.That(expr, Is.False) instead of Assert.IsFalse(expr) | :white_check_mark: | :information_source: | :white_check_mark: | -| [NUnit2003](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit2003.md) | Consider using Assert.That(expr, Is.True) instead of Assert.IsTrue(expr) | :white_check_mark: | :information_source: | :white_check_mark: | -| [NUnit2004](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit2004.md) | Consider using Assert.That(expr, Is.True) instead of Assert.True(expr) | :white_check_mark: | :information_source: | :white_check_mark: | -| [NUnit2005](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit2005.md) | Consider using Assert.That(actual, Is.EqualTo(expected)) instead of Assert.AreEqual(expected, actual) | :white_check_mark: | :warning: | :white_check_mark: | -| [NUnit2006](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit2006.md) | Consider using Assert.That(actual, Is.Not.EqualTo(expected)) instead of Assert.AreNotEqual(expected, actual) | :white_check_mark: | :warning: | :white_check_mark: | +| [NUnit2001](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit2001.md) | Consider using Assert.That(expr, Is.False) instead of ClassicAssert.False(expr) | :white_check_mark: | :information_source: | :white_check_mark: | +| [NUnit2002](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit2002.md) | Consider using Assert.That(expr, Is.False) instead of ClassicAssert.IsFalse(expr) | :white_check_mark: | :information_source: | :white_check_mark: | +| [NUnit2003](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit2003.md) | Consider using Assert.That(expr, Is.True) instead of ClassicAssert.IsTrue(expr) | :white_check_mark: | :information_source: | :white_check_mark: | +| [NUnit2004](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit2004.md) | Consider using Assert.That(expr, Is.True) instead of ClassicAssert.True(expr) | :white_check_mark: | :information_source: | :white_check_mark: | +| [NUnit2005](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit2005.md) | Consider using Assert.That(actual, Is.EqualTo(expected)) instead of ClassicAssert.AreEqual(expected, actual) | :white_check_mark: | :warning: | :white_check_mark: | +| [NUnit2006](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit2006.md) | Consider using Assert.That(actual, Is.Not.EqualTo(expected)) instead of ClassicAssert.AreNotEqual(expected, actual) | :white_check_mark: | :warning: | :white_check_mark: | | [NUnit2007](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit2007.md) | The actual value should not be a constant | :white_check_mark: | :warning: | :white_check_mark: | | [NUnit2008](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit2008.md) | Incorrect IgnoreCase usage | :white_check_mark: | :warning: | :x: | | [NUnit2009](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit2009.md) | The same value has been provided as both the actual and the expected argument | :white_check_mark: | :warning: | :x: | @@ -72,11 +72,11 @@ Rules which improve assertions in the test code. | [NUnit2012](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit2012.md) | Use StartsWithConstraint for better assertion messages in case of failure | :white_check_mark: | :information_source: | :white_check_mark: | | [NUnit2013](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit2013.md) | Use EndsWithConstraint for better assertion messages in case of failure | :white_check_mark: | :information_source: | :white_check_mark: | | [NUnit2014](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit2014.md) | Use SomeItemsConstraint for better assertion messages in case of failure | :white_check_mark: | :information_source: | :white_check_mark: | -| [NUnit2015](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit2015.md) | Consider using Assert.That(actual, Is.SameAs(expected)) instead of Assert.AreSame(expected, actual) | :white_check_mark: | :warning: | :white_check_mark: | -| [NUnit2016](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit2016.md) | Consider using Assert.That(expr, Is.Null) instead of Assert.Null(expr) | :white_check_mark: | :information_source: | :white_check_mark: | -| [NUnit2017](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit2017.md) | Consider using Assert.That(expr, Is.Null) instead of Assert.IsNull(expr) | :white_check_mark: | :information_source: | :white_check_mark: | -| [NUnit2018](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit2018.md) | Consider using Assert.That(expr, Is.Not.Null) instead of Assert.NotNull(expr) | :white_check_mark: | :information_source: | :white_check_mark: | -| [NUnit2019](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit2019.md) | Consider using Assert.That(expr, Is.Not.Null) instead of Assert.IsNotNull(expr) | :white_check_mark: | :information_source: | :white_check_mark: | +| [NUnit2015](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit2015.md) | Consider using Assert.That(actual, Is.SameAs(expected)) instead of ClassicAssert.AreSame(expected, actual) | :white_check_mark: | :warning: | :white_check_mark: | +| [NUnit2016](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit2016.md) | Consider using Assert.That(expr, Is.Null) instead of ClassicAssert.Null(expr) | :white_check_mark: | :information_source: | :white_check_mark: | +| [NUnit2017](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit2017.md) | Consider using Assert.That(expr, Is.Null) instead of ClassicAssert.IsNull(expr) | :white_check_mark: | :information_source: | :white_check_mark: | +| [NUnit2018](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit2018.md) | Consider using Assert.That(expr, Is.Not.Null) instead of ClassicAssert.NotNull(expr) | :white_check_mark: | :information_source: | :white_check_mark: | +| [NUnit2019](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit2019.md) | Consider using Assert.That(expr, Is.Not.Null) instead of ClassicAssert.IsNotNull(expr) | :white_check_mark: | :information_source: | :white_check_mark: | | [NUnit2020](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit2020.md) | Incompatible types for SameAs constraint | :white_check_mark: | :exclamation: | :x: | | [NUnit2021](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit2021.md) | Incompatible types for EqualTo constraint | :white_check_mark: | :exclamation: | :x: | | [NUnit2022](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit2022.md) | Missing property required for constraint | :white_check_mark: | :exclamation: | :white_check_mark: | @@ -84,19 +84,19 @@ Rules which improve assertions in the test code. | [NUnit2024](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit2024.md) | Wrong actual type used with String Constraint | :white_check_mark: | :exclamation: | :x: | | [NUnit2025](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit2025.md) | Wrong actual type used with ContainsConstraint | :white_check_mark: | :exclamation: | :x: | | [NUnit2026](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit2026.md) | Wrong actual type used with the SomeItemsConstraint with EqualConstraint | :white_check_mark: | :exclamation: | :x: | -| [NUnit2027](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit2027.md) | Consider using Assert.That(actual, Is.GreaterThan(expected)) instead of Assert.Greater(actual, expected) | :white_check_mark: | :information_source: | :white_check_mark: | -| [NUnit2028](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit2028.md) | Consider using Assert.That(actual, Is.GreaterThanOrEqualTo(expected)) instead of Assert.GreaterOrEqual(actual, expected) | :white_check_mark: | :information_source: | :white_check_mark: | -| [NUnit2029](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit2029.md) | Consider using Assert.That(actual, Is.LessThan(expected)) instead of Assert.Less(actual, expected) | :white_check_mark: | :information_source: | :white_check_mark: | -| [NUnit2030](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit2030.md) | Consider using Assert.That(actual, Is.LessThanOrEqualTo(expected)) instead of Assert.LessOrEqual(actual, expected) | :white_check_mark: | :information_source: | :white_check_mark: | -| [NUnit2031](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit2031.md) | Consider using Assert.That(actual, Is.Not.SameAs(expected)) instead of Assert.AreNotSame(expected, actual) | :white_check_mark: | :warning: | :white_check_mark: | -| [NUnit2032](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit2032.md) | Consider using Assert.That(expr, Is.Zero) instead of Assert.Zero(expr) | :white_check_mark: | :information_source: | :white_check_mark: | -| [NUnit2033](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit2033.md) | Consider using Assert.That(expr, Is.Not.Zero) instead of Assert.NotZero(expr) | :white_check_mark: | :information_source: | :white_check_mark: | -| [NUnit2034](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit2034.md) | Consider using Assert.That(expr, Is.NaN) instead of Assert.IsNaN(expr) | :white_check_mark: | :information_source: | :white_check_mark: | -| [NUnit2035](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit2035.md) | Consider using Assert.That(collection, Is.Empty) instead of Assert.IsEmpty(collection) | :white_check_mark: | :information_source: | :white_check_mark: | -| [NUnit2036](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit2036.md) | Consider using Assert.That(collection, Is.Not.Empty) instead of Assert.IsNotEmpty(collection) | :white_check_mark: | :information_source: | :white_check_mark: | -| [NUnit2037](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit2037.md) | Consider using Assert.That(collection, Does.Contain(instance)) instead of Assert.Contains(instance, collection) | :white_check_mark: | :information_source: | :white_check_mark: | -| [NUnit2038](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit2038.md) | Consider using Assert.That(actual, Is.InstanceOf(expected)) instead of Assert.IsInstanceOf(expected, actual) | :white_check_mark: | :information_source: | :white_check_mark: | -| [NUnit2039](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit2039.md) | Consider using Assert.That(actual, Is.Not.InstanceOf(expected)) instead of Assert.IsNotInstanceOf(expected, actual) | :white_check_mark: | :information_source: | :white_check_mark: | +| [NUnit2027](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit2027.md) | Consider using Assert.That(actual, Is.GreaterThan(expected)) instead of ClassicAssert.Greater(actual, expected) | :white_check_mark: | :information_source: | :white_check_mark: | +| [NUnit2028](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit2028.md) | Consider using Assert.That(actual, Is.GreaterThanOrEqualTo(expected)) instead of ClassicAssert.GreaterOrEqual(actual, expected) | :white_check_mark: | :information_source: | :white_check_mark: | +| [NUnit2029](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit2029.md) | Consider using Assert.That(actual, Is.LessThan(expected)) instead of ClassicAssert.Less(actual, expected) | :white_check_mark: | :information_source: | :white_check_mark: | +| [NUnit2030](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit2030.md) | Consider using Assert.That(actual, Is.LessThanOrEqualTo(expected)) instead of ClassicAssert.LessOrEqual(actual, expected) | :white_check_mark: | :information_source: | :white_check_mark: | +| [NUnit2031](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit2031.md) | Consider using Assert.That(actual, Is.Not.SameAs(expected)) instead of ClassicAssert.AreNotSame(expected, actual) | :white_check_mark: | :warning: | :white_check_mark: | +| [NUnit2032](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit2032.md) | Consider using Assert.That(expr, Is.Zero) instead of ClassicAssert.Zero(expr) | :white_check_mark: | :information_source: | :white_check_mark: | +| [NUnit2033](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit2033.md) | Consider using Assert.That(expr, Is.Not.Zero) instead of ClassicAssert.NotZero(expr) | :white_check_mark: | :information_source: | :white_check_mark: | +| [NUnit2034](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit2034.md) | Consider using Assert.That(expr, Is.NaN) instead of ClassicAssert.IsNaN(expr) | :white_check_mark: | :information_source: | :white_check_mark: | +| [NUnit2035](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit2035.md) | Consider using Assert.That(collection, Is.Empty) instead of ClassicAssert.IsEmpty(collection) | :white_check_mark: | :information_source: | :white_check_mark: | +| [NUnit2036](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit2036.md) | Consider using Assert.That(collection, Is.Not.Empty) instead of ClassicAssert.IsNotEmpty(collection) | :white_check_mark: | :information_source: | :white_check_mark: | +| [NUnit2037](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit2037.md) | Consider using Assert.That(collection, Does.Contain(instance)) instead of ClassicAssert.Contains(instance, collection) | :white_check_mark: | :information_source: | :white_check_mark: | +| [NUnit2038](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit2038.md) | Consider using Assert.That(actual, Is.InstanceOf(expected)) instead of ClassicAssert.IsInstanceOf(expected, actual) | :white_check_mark: | :information_source: | :white_check_mark: | +| [NUnit2039](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit2039.md) | Consider using Assert.That(actual, Is.Not.InstanceOf(expected)) instead of ClassicAssert.IsNotInstanceOf(expected, actual) | :white_check_mark: | :information_source: | :white_check_mark: | | [NUnit2040](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit2040.md) | Non-reference types for SameAs constraint | :white_check_mark: | :exclamation: | :white_check_mark: | | [NUnit2041](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit2041.md) | Incompatible types for comparison constraint | :white_check_mark: | :exclamation: | :x: | | [NUnit2042](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit2042.md) | Comparison constraint on object | :white_check_mark: | :information_source: | :x: | @@ -105,6 +105,9 @@ Rules which improve assertions in the test code. | [NUnit2045](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit2045.md) | Use Assert.Multiple | :white_check_mark: | :information_source: | :white_check_mark: | | [NUnit2046](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit2046.md) | Use CollectionConstraint for better assertion messages in case of failure | :white_check_mark: | :information_source: | :white_check_mark: | | [NUnit2047](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit2047.md) | Incompatible types for Within constraint | :white_check_mark: | :warning: | :white_check_mark: | +| [NUnit2048](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit2048.md) | Consider using Assert.That(...) instead of StringAssert(...) | :white_check_mark: | :warning: | :white_check_mark: | +| [NUnit2049](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit2049.md) | Consider using Assert.That(...) instead of CollectionAssert(...) | :white_check_mark: | :warning: | :white_check_mark: | +| [NUnit2050](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit2050.md) | NUnit 4 no longer supports string.Format specification | :white_check_mark: | :exclamation: | :white_check_mark: | ### Suppressor Rules (NUnit3001 - ) @@ -112,7 +115,7 @@ Rules which suppress compiler errors based on context. Note that these rules are | Id | Title | :mag: | :memo: | :bulb: | | :-- | :-- | :--: | :--: | :--: | -| [NUnit3001](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit3001.md) | Expression was checked in an Assert.NotNull, Assert.IsNotNull or Assert.That call | :white_check_mark: | :information_source: | :x: | +| [NUnit3001](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit3001.md) | Expression was checked in an ClassicAssert.NotNull, ClassicAssert.IsNotNull or Assert.That call | :white_check_mark: | :information_source: | :x: | | [NUnit3002](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit3002.md) | Field/Property is initialized in SetUp or OneTimeSetUp method | :white_check_mark: | :information_source: | :x: | | [NUnit3003](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit3003.md) | Class is an NUnit TestFixture and is instantiated using reflection | :white_check_mark: | :information_source: | :x: | | [NUnit3004](https://github.com/nunit/nunit.analyzers/tree/master/documentation/NUnit3004.md) | Field should be Disposed in TearDown or OneTimeTearDown method | :white_check_mark: | :information_source: | :x: | diff --git a/global.json b/global.json index 05098708..dffff818 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "7.0.100", + "version": "6.0.100", "rollForward" : "latestFeature", "allowPrerelease": false } diff --git a/src/Directory.Build.props b/src/Directory.Build.props index c6c7fe82..9f826a72 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -7,11 +7,11 @@ NUnit Analyzers Copyright © 2018-2023 NUnit project - + true enable - 9.0 + 10.0 false false diff --git a/src/nunit.analyzers.sln b/src/nunit.analyzers.sln index e1625c04..fb6e0c31 100644 --- a/src/nunit.analyzers.sln +++ b/src/nunit.analyzers.sln @@ -91,6 +91,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "documentation", "documentat ..\documentation\NUnit2045.md = ..\documentation\NUnit2045.md ..\documentation\NUnit2046.md = ..\documentation\NUnit2046.md ..\documentation\NUnit2047.md = ..\documentation\NUnit2047.md + ..\documentation\NUnit2048.md = ..\documentation\NUnit2048.md + ..\documentation\NUnit2049.md = ..\documentation\NUnit2049.md + ..\documentation\NUnit2050.md = ..\documentation\NUnit2050.md ..\documentation\NUnit3001.md = ..\documentation\NUnit3001.md ..\documentation\NUnit3002.md = ..\documentation\NUnit3002.md ..\documentation\NUnit3003.md = ..\documentation\NUnit3003.md diff --git a/src/nunit.analyzers.tests/ClassicModelAssertUsage/AreEqualClassicModelAssertUsageCodeFixTests.cs b/src/nunit.analyzers.tests/ClassicModelAssertUsage/AreEqualClassicModelAssertUsageCodeFixTests.cs index d845b191..424a6977 100644 --- a/src/nunit.analyzers.tests/ClassicModelAssertUsage/AreEqualClassicModelAssertUsageCodeFixTests.cs +++ b/src/nunit.analyzers.tests/ClassicModelAssertUsage/AreEqualClassicModelAssertUsageCodeFixTests.cs @@ -1,4 +1,3 @@ -using System.Collections.Immutable; using Gu.Roslyn.Asserts; using Microsoft.CodeAnalysis.CodeFixes; using Microsoft.CodeAnalysis.Diagnostics; @@ -31,7 +30,7 @@ public void VerifyAreEqualFix() var code = TestUtility.WrapMethodInClassNamespaceAndAddUsings($@" public void TestMethod() {{ - ↓Assert.AreEqual(2d, 3d); + ↓ClassicAssert.AreEqual(2d, 3d); }}"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" public void TestMethod() @@ -47,7 +46,7 @@ public void VerifyAreEqualFixWithMessage() var code = TestUtility.WrapMethodInClassNamespaceAndAddUsings($@" public void TestMethod() {{ - ↓Assert.AreEqual(2d, 3d, ""message""); + ↓ClassicAssert.AreEqual(2d, 3d, ""message""); }}"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" public void TestMethod() @@ -63,12 +62,12 @@ public void VerifyAreEqualFixWithMessageAndParams() var code = TestUtility.WrapMethodInClassNamespaceAndAddUsings($@" public void TestMethod() {{ - ↓Assert.AreEqual(2d, 3d, ""message"", Guid.NewGuid()); + ↓ClassicAssert.AreEqual(2d, 3d, ""message-id: {{0}}"", Guid.NewGuid()); }}"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" public void TestMethod() { - Assert.That(3d, Is.EqualTo(2d), ""message"", Guid.NewGuid()); + Assert.That(3d, Is.EqualTo(2d), $""message-id: {Guid.NewGuid()}""); }"); RoslynAssert.CodeFix(analyzer, fix, expectedDiagnostic, code, fixedCode, fixTitle: ClassicModelAssertUsageCodeFix.TransformToConstraintModelDescription); } @@ -79,7 +78,7 @@ public void VerifyAreEqualFixWhenToleranceExists() var code = TestUtility.WrapMethodInClassNamespaceAndAddUsings($@" public void TestMethod() {{ - ↓Assert.AreEqual(2d, 3d, 0.0000001d); + ↓ClassicAssert.AreEqual(2d, 3d, 0.0000001d); }}"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" public void TestMethod() @@ -95,7 +94,7 @@ public void VerifyAreEqualFixWhenToleranceExistsWithMessage() var code = TestUtility.WrapMethodInClassNamespaceAndAddUsings($@" public void TestMethod() {{ - ↓Assert.AreEqual(2d, 3d, 0.0000001d, ""message""); + ↓ClassicAssert.AreEqual(2d, 3d, 0.0000001d, ""message""); }}"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" public void TestMethod() @@ -111,12 +110,12 @@ public void VerifyAreEqualFixWhenToleranceExistsWithMessageAndParams() var code = TestUtility.WrapMethodInClassNamespaceAndAddUsings($@" public void TestMethod() {{ - ↓Assert.AreEqual(2d, 3d, 0.0000001d, ""message"", Guid.NewGuid()); + ↓ClassicAssert.AreEqual(2d, 3d, 0.0000001d, ""message-id: {{0}}"", Guid.NewGuid()); }}"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" public void TestMethod() { - Assert.That(3d, Is.EqualTo(2d).Within(0.0000001d), ""message"", Guid.NewGuid()); + Assert.That(3d, Is.EqualTo(2d).Within(0.0000001d), $""message-id: {Guid.NewGuid()}""); }"); RoslynAssert.CodeFix(analyzer, fix, expectedDiagnostic, code, fixedCode, fixTitle: ClassicModelAssertUsageCodeFix.TransformToConstraintModelDescription); } @@ -125,14 +124,12 @@ public void TestMethod() public void CodeFixPreservesLineBreakBeforeMessage() { var code = TestUtility.WrapInTestMethod($@" - Assert.AreEqual(2d, 3d, 0.0000001d, - ""message"", - Guid.NewGuid());"); + ClassicAssert.AreEqual(2d, 3d, 0.0000001d, + ""message"");"); var fixedCode = TestUtility.WrapInTestMethod(@" Assert.That(3d, Is.EqualTo(2d).Within(0.0000001d), - ""message"", - Guid.NewGuid());"); + ""message"");"); RoslynAssert.CodeFix(analyzer, fix, expectedDiagnostic, code, fixedCode, fixTitle: ClassicModelAssertUsageCodeFix.TransformToConstraintModelDescription); } diff --git a/src/nunit.analyzers.tests/ClassicModelAssertUsage/AreNotEqualClassicModelAssertUsageCodeFixTests.cs b/src/nunit.analyzers.tests/ClassicModelAssertUsage/AreNotEqualClassicModelAssertUsageCodeFixTests.cs index 783b9dbb..b7d21257 100644 --- a/src/nunit.analyzers.tests/ClassicModelAssertUsage/AreNotEqualClassicModelAssertUsageCodeFixTests.cs +++ b/src/nunit.analyzers.tests/ClassicModelAssertUsage/AreNotEqualClassicModelAssertUsageCodeFixTests.cs @@ -1,4 +1,3 @@ -using System.Collections.Immutable; using Gu.Roslyn.Asserts; using Microsoft.CodeAnalysis.CodeFixes; using Microsoft.CodeAnalysis.Diagnostics; @@ -31,7 +30,7 @@ public void VerifyAreNotEqualFix() var code = TestUtility.WrapMethodInClassNamespaceAndAddUsings($@" public void TestMethod() {{ - ↓Assert.AreNotEqual(2d, 3d); + ↓ClassicAssert.AreNotEqual(2d, 3d); }}"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" public void TestMethod() @@ -47,7 +46,7 @@ public void VerifyAreNotEqualFixWithMessage() var code = TestUtility.WrapMethodInClassNamespaceAndAddUsings($@" public void TestMethod() {{ - ↓Assert.AreNotEqual(2d, 3d, ""message""); + ↓ClassicAssert.AreNotEqual(2d, 3d, ""message""); }}"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" public void TestMethod() @@ -63,12 +62,12 @@ public void VerifyAreNotEqualFixWithMessageAndParams() var code = TestUtility.WrapMethodInClassNamespaceAndAddUsings($@" public void TestMethod() {{ - ↓Assert.AreNotEqual(2d, 3d, ""message"", Guid.NewGuid()); + ↓ClassicAssert.AreNotEqual(2d, 3d, ""message-id: {{0}}"", Guid.NewGuid()); }}"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" public void TestMethod() { - Assert.That(3d, Is.Not.EqualTo(2d), ""message"", Guid.NewGuid()); + Assert.That(3d, Is.Not.EqualTo(2d), $""message-id: {Guid.NewGuid()}""); }"); RoslynAssert.CodeFix(analyzer, fix, expectedDiagnostic, code, fixedCode, fixTitle: ClassicModelAssertUsageCodeFix.TransformToConstraintModelDescription); } diff --git a/src/nunit.analyzers.tests/ClassicModelAssertUsage/AreNotSameClassicModelAssertUsageCodeFixTests.cs b/src/nunit.analyzers.tests/ClassicModelAssertUsage/AreNotSameClassicModelAssertUsageCodeFixTests.cs index 7ec1b49b..62bf0e68 100644 --- a/src/nunit.analyzers.tests/ClassicModelAssertUsage/AreNotSameClassicModelAssertUsageCodeFixTests.cs +++ b/src/nunit.analyzers.tests/ClassicModelAssertUsage/AreNotSameClassicModelAssertUsageCodeFixTests.cs @@ -1,4 +1,3 @@ -using System.Collections.Immutable; using Gu.Roslyn.Asserts; using Microsoft.CodeAnalysis.CodeFixes; using Microsoft.CodeAnalysis.Diagnostics; @@ -34,7 +33,7 @@ public void TestMethod() var expected = new object(); var actual = new object(); - ↓Assert.AreNotSame(expected, actual); + ↓ClassicAssert.AreNotSame(expected, actual); }}"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" public void TestMethod() @@ -56,7 +55,7 @@ public void TestMethod() var expected = new object(); var actual = new object(); - ↓Assert.AreNotSame(expected, actual, ""message""); + ↓ClassicAssert.AreNotSame(expected, actual, ""message""); }}"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" public void TestMethod() @@ -78,7 +77,7 @@ public void TestMethod() var expected = new object(); var actual = new object(); - ↓Assert.AreNotSame(expected, actual, ""message"", Guid.NewGuid()); + ↓ClassicAssert.AreNotSame(expected, actual, ""message-id: {{0}}"", Guid.NewGuid()); }}"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" public void TestMethod() @@ -86,7 +85,7 @@ public void TestMethod() var expected = new object(); var actual = new object(); - Assert.That(actual, Is.Not.SameAs(expected), ""message"", Guid.NewGuid()); + Assert.That(actual, Is.Not.SameAs(expected), $""message-id: {Guid.NewGuid()}""); }"); RoslynAssert.CodeFix(analyzer, fix, expectedDiagnostic, code, fixedCode, fixTitle: ClassicModelAssertUsageCodeFix.TransformToConstraintModelDescription); } diff --git a/src/nunit.analyzers.tests/ClassicModelAssertUsage/AreSameClassicModelAssertUsageCodeFixTests.cs b/src/nunit.analyzers.tests/ClassicModelAssertUsage/AreSameClassicModelAssertUsageCodeFixTests.cs index cbb2146f..cd6b5a38 100644 --- a/src/nunit.analyzers.tests/ClassicModelAssertUsage/AreSameClassicModelAssertUsageCodeFixTests.cs +++ b/src/nunit.analyzers.tests/ClassicModelAssertUsage/AreSameClassicModelAssertUsageCodeFixTests.cs @@ -1,4 +1,3 @@ -using System.Collections.Immutable; using Gu.Roslyn.Asserts; using Microsoft.CodeAnalysis.CodeFixes; using Microsoft.CodeAnalysis.Diagnostics; @@ -34,7 +33,7 @@ public void TestMethod() var expected = new object(); var actual = new object(); - ↓Assert.AreSame(expected, actual); + ↓ClassicAssert.AreSame(expected, actual); }}"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" public void TestMethod() @@ -56,7 +55,7 @@ public void TestMethod() var expected = new object(); var actual = new object(); - ↓Assert.AreSame(expected, actual, ""message""); + ↓ClassicAssert.AreSame(expected, actual, ""message""); }}"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" public void TestMethod() @@ -78,7 +77,7 @@ public void TestMethod() var expected = new object(); var actual = new object(); - ↓Assert.AreSame(expected, actual, ""message"", Guid.NewGuid()); + ↓ClassicAssert.AreSame(expected, actual, ""message-id: {{0}}"", Guid.NewGuid()); }}"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" public void TestMethod() @@ -86,7 +85,7 @@ public void TestMethod() var expected = new object(); var actual = new object(); - Assert.That(actual, Is.SameAs(expected), ""message"", Guid.NewGuid()); + Assert.That(actual, Is.SameAs(expected), $""message-id: {Guid.NewGuid()}""); }"); RoslynAssert.CodeFix(analyzer, fix, expectedDiagnostic, code, fixedCode, fixTitle: ClassicModelAssertUsageCodeFix.TransformToConstraintModelDescription); } diff --git a/src/nunit.analyzers.tests/ClassicModelAssertUsage/ClassicModelAssertUsageAnalyzerTests.cs b/src/nunit.analyzers.tests/ClassicModelAssertUsage/ClassicModelAssertUsageAnalyzerTests.cs index acaa28e3..0acc9f62 100644 --- a/src/nunit.analyzers.tests/ClassicModelAssertUsage/ClassicModelAssertUsageAnalyzerTests.cs +++ b/src/nunit.analyzers.tests/ClassicModelAssertUsage/ClassicModelAssertUsageAnalyzerTests.cs @@ -115,10 +115,10 @@ public sealed class AnalyzeWhenInvocationIsNotFromAssert { public void Test() { - Assert.AreEqual(3, 4); + ClassicAssert.AreEqual(3, 4); } - private static class Assert + private static class ClassicAssert { public static bool AreEqual(int a, int b) => false; } @@ -136,7 +136,7 @@ public sealed class AnalyzeWhenIsTrueIsUsed { public void Test() { - ↓Assert.IsTrue(true); + ↓ClassicAssert.IsTrue(true); } }"); RoslynAssert.Diagnostics(this.analyzer, expectedDiagnostic, testCode); @@ -152,7 +152,7 @@ public sealed class AnalyzeWhenTrueIsUsed { public void Test() { - ↓Assert.True(true); + ↓ClassicAssert.True(true); } }"); RoslynAssert.Diagnostics(this.analyzer, expectedDiagnostic, testCode); @@ -168,7 +168,7 @@ public sealed class AnalyzeWhenIsFalseIsUsed { public void Test() { - ↓Assert.IsFalse(false); + ↓ClassicAssert.IsFalse(false); } }"); RoslynAssert.Diagnostics(this.analyzer, expectedDiagnostic, testCode); @@ -184,7 +184,7 @@ public sealed class AnalyzeWhenFalseIsUsed { public void Test() { - ↓Assert.False(false); + ↓ClassicAssert.False(false); } }"); RoslynAssert.Diagnostics(this.analyzer, expectedDiagnostic, testCode); @@ -200,7 +200,7 @@ public sealed class AnalyzeWhenAreEqualIsUsed { public void Test() { - ↓Assert.AreEqual(2, 2); + ↓ClassicAssert.AreEqual(2, 2); } }"); RoslynAssert.Diagnostics(this.analyzer, expectedDiagnostic, testCode); @@ -216,7 +216,7 @@ public sealed class AnalyzeWhenAreEqualIsUsedWithTolerance { public void Test() { - ↓Assert.AreEqual(2d, 2d, 0.0000001d); + ↓ClassicAssert.AreEqual(2d, 2d, 0.0000001d); } }"); RoslynAssert.Diagnostics(this.analyzer, expectedDiagnostic, testCode); @@ -232,7 +232,7 @@ public sealed class AnalyzeWhenAreNotEqualIsUsed { public void Test() { - ↓Assert.AreNotEqual(2, 3); + ↓ClassicAssert.AreNotEqual(2, 3); } }"); RoslynAssert.Diagnostics(this.analyzer, expectedDiagnostic, testCode); @@ -248,7 +248,7 @@ public sealed class AnalyzeWhenAreSameIsUsed { public void Test() { - ↓Assert.AreSame(2, 3); + ↓ClassicAssert.AreSame(2, 3); } }"); RoslynAssert.Diagnostics(this.analyzer, expectedDiagnostic, testCode); @@ -265,7 +265,7 @@ public sealed class AnalyzeWhenIsNullIsUsed public void Test() { object? obj = null; - ↓Assert.IsNull(obj); + ↓ClassicAssert.IsNull(obj); } }"); RoslynAssert.Diagnostics(this.analyzer, expectedDiagnostic, testCode); @@ -282,7 +282,7 @@ public sealed class AnalyzeWhenNullIsUsed public void Test() { object? obj = null; - ↓Assert.Null(obj); + ↓ClassicAssert.Null(obj); } }"); RoslynAssert.Diagnostics(this.analyzer, expectedDiagnostic, testCode); @@ -299,7 +299,7 @@ public sealed class AnalyzeWhenIsNotNullIsUsed public void Test() { object? obj = null; - ↓Assert.IsNotNull(obj); + ↓ClassicAssert.IsNotNull(obj); } }"); RoslynAssert.Diagnostics(this.analyzer, expectedDiagnostic, testCode); @@ -316,7 +316,7 @@ public sealed class AnalyzeWhenNotNullIsUsed public void Test() { object? obj = null; - ↓Assert.NotNull(obj); + ↓ClassicAssert.NotNull(obj); } }"); RoslynAssert.Diagnostics(this.analyzer, expectedDiagnostic, testCode); @@ -343,7 +343,7 @@ public sealed class AnalyzeWhenGreaterIsUsed { public void Test() { - ↓Assert.Greater(2, 3); + ↓ClassicAssert.Greater(2, 3); } }"); RoslynAssert.Diagnostics(this.analyzer, expectedDiagnostic, testCode); @@ -359,7 +359,7 @@ public sealed class AnalyzeWhenGreaterOrEqualIsUsed { public void Test() { - ↓Assert.GreaterOrEqual(2, 3); + ↓ClassicAssert.GreaterOrEqual(2, 3); } }"); RoslynAssert.Diagnostics(this.analyzer, expectedDiagnostic, testCode); @@ -375,7 +375,7 @@ public sealed class AnalyzeWhenLessIsUsed { public void Test() { - ↓Assert.Less(2, 3); + ↓ClassicAssert.Less(2, 3); } }"); RoslynAssert.Diagnostics(this.analyzer, expectedDiagnostic, testCode); @@ -391,7 +391,7 @@ public sealed class AnalyzeWhenLessOrEqualIsUsed { public void Test() { - ↓Assert.LessOrEqual(2, 3); + ↓ClassicAssert.LessOrEqual(2, 3); } }"); RoslynAssert.Diagnostics(this.analyzer, expectedDiagnostic, testCode); @@ -407,7 +407,7 @@ public sealed class AnalyzeWhenAreNotSameIsUsed { public void Test() { - ↓Assert.AreNotSame(2, 3); + ↓ClassicAssert.AreNotSame(2, 3); } }"); RoslynAssert.Diagnostics(this.analyzer, expectedDiagnostic, testCode); @@ -423,7 +423,7 @@ public sealed class AnalyzeWhenZeroIsUsed { public void Test() { - ↓Assert.Zero(2); + ↓ClassicAssert.Zero(2); } }"); RoslynAssert.Diagnostics(this.analyzer, expectedDiagnostic, testCode); @@ -439,7 +439,7 @@ public sealed class AnalyzeWhenNotZeroIsUsed { public void Test() { - ↓Assert.NotZero(2); + ↓ClassicAssert.NotZero(2); } }"); RoslynAssert.Diagnostics(this.analyzer, expectedDiagnostic, testCode); @@ -455,7 +455,7 @@ public sealed class AnalyzeWhenIsNaNIsUsed { public void Test() { - ↓Assert.IsNaN(2); + ↓ClassicAssert.IsNaN(2); } }"); RoslynAssert.Diagnostics(this.analyzer, expectedDiagnostic, testCode); @@ -471,7 +471,7 @@ public sealed class AnalyzeWhenIsEmptyIsUsed { public void Test() { - ↓Assert.IsEmpty(Array.Empty()); + ↓ClassicAssert.IsEmpty(Array.Empty()); } }"); RoslynAssert.Diagnostics(this.analyzer, expectedDiagnostic, testCode); @@ -487,7 +487,7 @@ public sealed class AnalyzeWhenIsNotEmptyIsUsed { public void Test() { - ↓Assert.IsNotEmpty(Array.Empty()); + ↓ClassicAssert.IsNotEmpty(Array.Empty()); } }"); RoslynAssert.Diagnostics(this.analyzer, expectedDiagnostic, testCode); @@ -503,7 +503,7 @@ public sealed class AnalyzeWhenContainsIsUsed { public void Test() { - ↓Assert.Contains(this, Array.Empty()); + ↓ClassicAssert.Contains(this, Array.Empty()); } }"); RoslynAssert.Diagnostics(this.analyzer, expectedDiagnostic, testCode); @@ -519,7 +519,7 @@ public sealed class AnalyzeWhenIsInstanceOfIsUsed { public void Test() { - ↓Assert.IsInstanceOf(typeof(int), 2); + ↓ClassicAssert.IsInstanceOf(typeof(int), 2); } }"); RoslynAssert.Diagnostics(this.analyzer, expectedDiagnostic, testCode); @@ -535,7 +535,7 @@ public sealed class AnalyzeWhenGenericIsInstanceOfIsUsed { public void Test() { - ↓Assert.IsInstanceOf(2); + ↓ClassicAssert.IsInstanceOf(2); } }"); RoslynAssert.Diagnostics(this.analyzer, expectedDiagnostic, testCode); @@ -551,7 +551,7 @@ public sealed class AnalyzeWhenIsNotInstanceOfIsUsed { public void Test() { - ↓Assert.IsNotInstanceOf(typeof(int), 2); + ↓ClassicAssert.IsNotInstanceOf(typeof(int), 2); } }"); RoslynAssert.Diagnostics(this.analyzer, expectedDiagnostic, testCode); @@ -567,7 +567,7 @@ public sealed class AnalyzeWhenGenericIsNotInstanceOfIsUsed { public void Test() { - ↓Assert.IsNotInstanceOf(2); + ↓ClassicAssert.IsNotInstanceOf(2); } }"); RoslynAssert.Diagnostics(this.analyzer, expectedDiagnostic, testCode); diff --git a/src/nunit.analyzers.tests/ClassicModelAssertUsage/ContainsClassicModelAssertUsageCodeFixTests.cs b/src/nunit.analyzers.tests/ClassicModelAssertUsage/ContainsClassicModelAssertUsageCodeFixTests.cs index a8563d09..a491763f 100644 --- a/src/nunit.analyzers.tests/ClassicModelAssertUsage/ContainsClassicModelAssertUsageCodeFixTests.cs +++ b/src/nunit.analyzers.tests/ClassicModelAssertUsage/ContainsClassicModelAssertUsageCodeFixTests.cs @@ -1,4 +1,3 @@ -using System.Collections.Immutable; using Gu.Roslyn.Asserts; using Microsoft.CodeAnalysis.CodeFixes; using Microsoft.CodeAnalysis.Diagnostics; @@ -34,7 +33,7 @@ public void TestMethod() var instance = new object(); var collection = Array.Empty(); - ↓Assert.Contains(instance, collection); + ↓ClassicAssert.Contains(instance, collection); }}"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" public void TestMethod() @@ -56,7 +55,7 @@ public void TestMethod() var instance = new object(); var collection = Array.Empty(); - ↓Assert.Contains(instance, collection, ""message""); + ↓ClassicAssert.Contains(instance, collection, ""message""); }}"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" public void TestMethod() @@ -78,7 +77,7 @@ public void TestMethod() var instance = new object(); var collection = Array.Empty(); - ↓Assert.Contains(instance, collection, ""message"", Guid.NewGuid()); + ↓ClassicAssert.Contains(instance, collection, ""message-id: {{0}}"", Guid.NewGuid()); }}"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" public void TestMethod() @@ -86,7 +85,7 @@ public void TestMethod() var instance = new object(); var collection = Array.Empty(); - Assert.That(collection, Does.Contain(instance), ""message"", Guid.NewGuid()); + Assert.That(collection, Does.Contain(instance), $""message-id: {Guid.NewGuid()}""); }"); RoslynAssert.CodeFix(analyzer, fix, instanceDiagnostic, code, fixedCode, fixTitle: ClassicModelAssertUsageCodeFix.TransformToConstraintModelDescription); } diff --git a/src/nunit.analyzers.tests/ClassicModelAssertUsage/GreaterClassicModelAssertUsageCodeFixTests.cs b/src/nunit.analyzers.tests/ClassicModelAssertUsage/GreaterClassicModelAssertUsageCodeFixTests.cs index 8bd0f650..75b3568b 100644 --- a/src/nunit.analyzers.tests/ClassicModelAssertUsage/GreaterClassicModelAssertUsageCodeFixTests.cs +++ b/src/nunit.analyzers.tests/ClassicModelAssertUsage/GreaterClassicModelAssertUsageCodeFixTests.cs @@ -1,4 +1,3 @@ -using System.Collections.Immutable; using Gu.Roslyn.Asserts; using Microsoft.CodeAnalysis.CodeFixes; using Microsoft.CodeAnalysis.Diagnostics; @@ -31,7 +30,7 @@ public void VerifyGreaterFix() var code = TestUtility.WrapMethodInClassNamespaceAndAddUsings($@" public void TestMethod() {{ - ↓Assert.Greater(2d, 3d); + ↓ClassicAssert.Greater(2d, 3d); }}"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" public void TestMethod() @@ -47,7 +46,7 @@ public void VerifyGreaterFixWithMessage() var code = TestUtility.WrapMethodInClassNamespaceAndAddUsings($@" public void TestMethod() {{ - ↓Assert.Greater(2d, 3d, ""message""); + ↓ClassicAssert.Greater(2d, 3d, ""message""); }}"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" public void TestMethod() @@ -63,12 +62,12 @@ public void VerifyGreaterFixWithMessageAndParams() var code = TestUtility.WrapMethodInClassNamespaceAndAddUsings($@" public void TestMethod() {{ - ↓Assert.Greater(2d, 3d, ""message"", Guid.NewGuid()); + ↓ClassicAssert.Greater(2d, 3d, ""message-id: {{0}}"", Guid.NewGuid()); }}"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" public void TestMethod() { - Assert.That(2d, Is.GreaterThan(3d), ""message"", Guid.NewGuid()); + Assert.That(2d, Is.GreaterThan(3d), $""message-id: {Guid.NewGuid()}""); }"); RoslynAssert.CodeFix(analyzer, fix, expectedDiagnostic, code, fixedCode, fixTitle: ClassicModelAssertUsageCodeFix.TransformToConstraintModelDescription); } @@ -77,14 +76,12 @@ public void TestMethod() public void CodeFixPreservesLineBreakBeforeMessage() { var code = TestUtility.WrapInTestMethod($@" - Assert.Greater(2d, 3d, - ""message"", - Guid.NewGuid());"); + ClassicAssert.Greater(2d, 3d, + ""message"");"); var fixedCode = TestUtility.WrapInTestMethod(@" Assert.That(2d, Is.GreaterThan(3d), - ""message"", - Guid.NewGuid());"); + ""message"");"); RoslynAssert.CodeFix(analyzer, fix, expectedDiagnostic, code, fixedCode, fixTitle: ClassicModelAssertUsageCodeFix.TransformToConstraintModelDescription); } @@ -106,7 +103,7 @@ public void TestMethod() { MyFloat x = 1; float y = 2; - ↓Assert.Greater(x, y); + ↓ClassicAssert.Greater(x, y); }"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" private struct MyFloat @@ -144,7 +141,7 @@ public void TestMethod() { float x = 1; MyFloat y = 2; - ↓Assert.Greater(x, y); + ↓ClassicAssert.Greater(x, y); }"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" private struct MyFloat diff --git a/src/nunit.analyzers.tests/ClassicModelAssertUsage/GreaterOrEqualClassicModelAssertUsageCodeFixTests.cs b/src/nunit.analyzers.tests/ClassicModelAssertUsage/GreaterOrEqualClassicModelAssertUsageCodeFixTests.cs index 3c17e636..05f77920 100644 --- a/src/nunit.analyzers.tests/ClassicModelAssertUsage/GreaterOrEqualClassicModelAssertUsageCodeFixTests.cs +++ b/src/nunit.analyzers.tests/ClassicModelAssertUsage/GreaterOrEqualClassicModelAssertUsageCodeFixTests.cs @@ -1,4 +1,3 @@ -using System.Collections.Immutable; using Gu.Roslyn.Asserts; using Microsoft.CodeAnalysis.CodeFixes; using Microsoft.CodeAnalysis.Diagnostics; @@ -31,7 +30,7 @@ public void VerifyGreaterOrEqualFix() var code = TestUtility.WrapMethodInClassNamespaceAndAddUsings($@" public void TestMethod() {{ - ↓Assert.GreaterOrEqual(2d, 3d); + ↓ClassicAssert.GreaterOrEqual(2d, 3d); }}"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" public void TestMethod() @@ -47,7 +46,7 @@ public void VerifyGreaterOrEqualFixWithMessage() var code = TestUtility.WrapMethodInClassNamespaceAndAddUsings($@" public void TestMethod() {{ - ↓Assert.GreaterOrEqual(2d, 3d, ""message""); + ↓ClassicAssert.GreaterOrEqual(2d, 3d, ""message""); }}"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" public void TestMethod() @@ -63,12 +62,12 @@ public void VerifyGreaterOrEqualFixWithMessageAndParams() var code = TestUtility.WrapMethodInClassNamespaceAndAddUsings($@" public void TestMethod() {{ - ↓Assert.GreaterOrEqual(2d, 3d, ""message"", Guid.NewGuid()); + ↓ClassicAssert.GreaterOrEqual(2d, 3d, ""message-id: {{0}}"", Guid.NewGuid()); }}"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" public void TestMethod() { - Assert.That(2d, Is.GreaterThanOrEqualTo(3d), ""message"", Guid.NewGuid()); + Assert.That(2d, Is.GreaterThanOrEqualTo(3d), $""message-id: {Guid.NewGuid()}""); }"); RoslynAssert.CodeFix(analyzer, fix, expectedDiagnostic, code, fixedCode, fixTitle: ClassicModelAssertUsageCodeFix.TransformToConstraintModelDescription); } @@ -77,14 +76,12 @@ public void TestMethod() public void CodeFixPreservesLineBreakBeforeMessage() { var code = TestUtility.WrapInTestMethod($@" - Assert.GreaterOrEqual(2d, 3d, - ""message"", - Guid.NewGuid());"); + ClassicAssert.GreaterOrEqual(2d, 3d, + ""message"");"); var fixedCode = TestUtility.WrapInTestMethod(@" Assert.That(2d, Is.GreaterThanOrEqualTo(3d), - ""message"", - Guid.NewGuid());"); + ""message"");"); RoslynAssert.CodeFix(analyzer, fix, expectedDiagnostic, code, fixedCode, fixTitle: ClassicModelAssertUsageCodeFix.TransformToConstraintModelDescription); } @@ -106,7 +103,7 @@ public void TestMethod() { MyFloat x = 1; float y = 2; - ↓Assert.GreaterOrEqual(x, y); + ↓ClassicAssert.GreaterOrEqual(x, y); }"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" private struct MyFloat @@ -144,7 +141,7 @@ public void TestMethod() { float x = 1; MyFloat y = 2; - ↓Assert.GreaterOrEqual(x, y); + ↓ClassicAssert.GreaterOrEqual(x, y); }"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" private struct MyFloat diff --git a/src/nunit.analyzers.tests/ClassicModelAssertUsage/IsEmptyClassicModelAssertUsageCodeFixTests.cs b/src/nunit.analyzers.tests/ClassicModelAssertUsage/IsEmptyClassicModelAssertUsageCodeFixTests.cs index 06e13b06..aa031eb0 100644 --- a/src/nunit.analyzers.tests/ClassicModelAssertUsage/IsEmptyClassicModelAssertUsageCodeFixTests.cs +++ b/src/nunit.analyzers.tests/ClassicModelAssertUsage/IsEmptyClassicModelAssertUsageCodeFixTests.cs @@ -1,4 +1,3 @@ -using System.Collections.Immutable; using Gu.Roslyn.Asserts; using Microsoft.CodeAnalysis.CodeFixes; using Microsoft.CodeAnalysis.Diagnostics; @@ -33,7 +32,7 @@ public void TestMethod() {{ var collection = Array.Empty(); - ↓Assert.IsEmpty(collection); + ↓ClassicAssert.IsEmpty(collection); }}"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" public void TestMethod() @@ -53,7 +52,7 @@ public void TestMethod() {{ var collection = Array.Empty(); - ↓Assert.IsEmpty(collection, ""message""); + ↓ClassicAssert.IsEmpty(collection, ""message""); }}"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" public void TestMethod() @@ -73,14 +72,14 @@ public void TestMethod() {{ var collection = Array.Empty(); - ↓Assert.IsEmpty(collection, ""message"", Guid.NewGuid()); + ↓ClassicAssert.IsEmpty(collection, ""message-id: {{0}}"", Guid.NewGuid()); }}"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" public void TestMethod() { var collection = Array.Empty(); - Assert.That(collection, Is.Empty, ""message"", Guid.NewGuid()); + Assert.That(collection, Is.Empty, $""message-id: {Guid.NewGuid()}""); }"); RoslynAssert.CodeFix(analyzer, fix, expectedDiagnostic, code, fixedCode, fixTitle: ClassicModelAssertUsageCodeFix.TransformToConstraintModelDescription); } @@ -101,7 +100,7 @@ private struct MyString public void TestMethod() { MyString s = string.Empty; - ↓Assert.IsEmpty(s); + ↓ClassicAssert.IsEmpty(s); }"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" private struct MyString diff --git a/src/nunit.analyzers.tests/ClassicModelAssertUsage/IsFalseAndFalseClassicModelAssertUsageCodeFixTests.cs b/src/nunit.analyzers.tests/ClassicModelAssertUsage/IsFalseAndFalseClassicModelAssertUsageCodeFixTests.cs index 8c107981..26c1f2f1 100644 --- a/src/nunit.analyzers.tests/ClassicModelAssertUsage/IsFalseAndFalseClassicModelAssertUsageCodeFixTests.cs +++ b/src/nunit.analyzers.tests/ClassicModelAssertUsage/IsFalseAndFalseClassicModelAssertUsageCodeFixTests.cs @@ -1,4 +1,3 @@ -using System.Collections.Immutable; using Gu.Roslyn.Asserts; using Microsoft.CodeAnalysis.CodeFixes; using Microsoft.CodeAnalysis.Diagnostics; @@ -32,7 +31,7 @@ public void VerifyIsFalseAndFalseFixes(string assertion, string diagnosticId) var code = TestUtility.WrapMethodInClassNamespaceAndAddUsings($@" public void TestMethod() {{ - ↓Assert.{assertion}(false); + ↓ClassicAssert.{assertion}(false); }}"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" public void TestMethod() @@ -51,7 +50,7 @@ public void VerifyIsFalseAndFalseFixesWithMessage(string assertion, string diagn var code = TestUtility.WrapMethodInClassNamespaceAndAddUsings($@" public void TestMethod() {{ - ↓Assert.{assertion}(false, ""message""); + ↓ClassicAssert.{assertion}(false, ""message""); }}"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" public void TestMethod() @@ -70,12 +69,12 @@ public void VerifyIsFalseAndFalseFixesWithMessageAndParams(string assertion, str var code = TestUtility.WrapMethodInClassNamespaceAndAddUsings($@" public void TestMethod() {{ - ↓Assert.{assertion}(false, ""message"", Guid.NewGuid()); + ↓ClassicAssert.{assertion}(false, ""message-id: {{0}}"", Guid.NewGuid()); }}"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" public void TestMethod() { - Assert.That(false, Is.False, ""message"", Guid.NewGuid()); + Assert.That(false, Is.False, $""message-id: {Guid.NewGuid()}""); }"); RoslynAssert.CodeFix(analyzer, fix, expectedDiagnostic, code, fixedCode, fixTitle: ClassicModelAssertUsageCodeFix.TransformToConstraintModelDescription); } @@ -99,7 +98,7 @@ private struct MyBool public void TestMethod() {{ MyBool x = false; - ↓Assert.{assertion}(x); + ↓ClassicAssert.{assertion}(x); }}"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" private struct MyBool diff --git a/src/nunit.analyzers.tests/ClassicModelAssertUsage/IsInstanceOfClassicModelAssertUsageCodeFixTests.cs b/src/nunit.analyzers.tests/ClassicModelAssertUsage/IsInstanceOfClassicModelAssertUsageCodeFixTests.cs index 8e54d998..cc8fa63d 100644 --- a/src/nunit.analyzers.tests/ClassicModelAssertUsage/IsInstanceOfClassicModelAssertUsageCodeFixTests.cs +++ b/src/nunit.analyzers.tests/ClassicModelAssertUsage/IsInstanceOfClassicModelAssertUsageCodeFixTests.cs @@ -1,4 +1,3 @@ -using System.Collections.Immutable; using Gu.Roslyn.Asserts; using Microsoft.CodeAnalysis.CodeFixes; using Microsoft.CodeAnalysis.Diagnostics; @@ -34,7 +33,7 @@ public void TestMethod() var expected = typeof(int); var actual = 42; - ↓Assert.IsInstanceOf(expected, actual); + ↓ClassicAssert.IsInstanceOf(expected, actual); }}"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" public void TestMethod() @@ -56,7 +55,7 @@ public void TestMethod() var expected = typeof(int); var actual = 42; - ↓Assert.IsInstanceOf(expected, actual, ""message""); + ↓ClassicAssert.IsInstanceOf(expected, actual, ""message""); }}"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" public void TestMethod() @@ -78,7 +77,7 @@ public void TestMethod() var expected = typeof(int); var actual = 42; - ↓Assert.IsInstanceOf(expected, actual, ""message"", Guid.NewGuid()); + ↓ClassicAssert.IsInstanceOf(expected, actual, ""message-id: {{0}}"", Guid.NewGuid()); }}"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" public void TestMethod() @@ -86,7 +85,7 @@ public void TestMethod() var expected = typeof(int); var actual = 42; - Assert.That(actual, Is.InstanceOf(expected), ""message"", Guid.NewGuid()); + Assert.That(actual, Is.InstanceOf(expected), $""message-id: {Guid.NewGuid()}""); }"); RoslynAssert.CodeFix(analyzer, fix, expectedDiagnostic, code, fixedCode, fixTitle: ClassicModelAssertUsageCodeFix.TransformToConstraintModelDescription); } @@ -95,19 +94,19 @@ public void TestMethod() public void VerifyIsInstanceOfGenericFix() { var code = TestUtility.WrapMethodInClassNamespaceAndAddUsings($@" - public void TestMethod() - {{ - var actual = 42; + public void TestMethod() + {{ + var actual = 42; - ↓Assert.IsInstanceOf(actual); - }}"); + ↓ClassicAssert.IsInstanceOf(actual); + }}"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" - public void TestMethod() - { - var actual = 42; + public void TestMethod() + { + var actual = 42; - Assert.That(actual, Is.InstanceOf()); - }"); + Assert.That(actual, Is.InstanceOf()); + }"); RoslynAssert.CodeFix(analyzer, fix, expectedDiagnostic, code, fixedCode, fixTitle: ClassicModelAssertUsageCodeFix.TransformToConstraintModelDescription); } @@ -115,41 +114,41 @@ public void TestMethod() public void VerifyIsInstanceOfSingleNestedGenericFix() { var code = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" - public void TestMethod() - { - var wrapped = Create(42); - ↓Assert.IsInstanceOf>(wrapped); - } + public void TestMethod() + { + var wrapped = Create(42); + ↓ClassicAssert.IsInstanceOf>(wrapped); + } - private Wrapped Create(T value) => new Wrapped(value); + private Wrapped Create(T value) => new Wrapped(value); - private class Wrapped + private class Wrapped + { + public Wrapped(T value) { - public Wrapped(T value) - { - Value = value; - } + Value = value; + } - public T Value { get; } - }"); + public T Value { get; } + }"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" - public void TestMethod() - { - var wrapped = Create(42); - Assert.That(wrapped, Is.InstanceOf>()); - } + public void TestMethod() + { + var wrapped = Create(42); + Assert.That(wrapped, Is.InstanceOf>()); + } - private Wrapped Create(T value) => new Wrapped(value); + private Wrapped Create(T value) => new Wrapped(value); - private class Wrapped + private class Wrapped + { + public Wrapped(T value) { - public Wrapped(T value) - { - Value = value; - } + Value = value; + } - public T Value { get; } - }"); + public T Value { get; } + }"); RoslynAssert.CodeFix(analyzer, fix, expectedDiagnostic, code, fixedCode, fixTitle: ClassicModelAssertUsageCodeFix.TransformToConstraintModelDescription); } @@ -157,43 +156,43 @@ public Wrapped(T value) public void VerifyIsInstanceOfDoubleNestedGenericFix() { var code = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" - public void TestMethod() - { - var wrapped = Create(42); - var nested = Create(wrapped); - ↓Assert.IsInstanceOf>>(wrapped); - } + public void TestMethod() + { + var wrapped = Create(42); + var nested = Create(wrapped); + ↓ClassicAssert.IsInstanceOf>>(wrapped); + } - private Wrapped Create(T value) => new Wrapped(value); + private Wrapped Create(T value) => new Wrapped(value); - private class Wrapped + private class Wrapped + { + public Wrapped(T value) { - public Wrapped(T value) - { - Value = value; - } + Value = value; + } - public T Value { get; } - }"); + public T Value { get; } + }"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" - public void TestMethod() - { - var wrapped = Create(42); - var nested = Create(wrapped); - Assert.That(wrapped, Is.InstanceOf>>()); - } + public void TestMethod() + { + var wrapped = Create(42); + var nested = Create(wrapped); + Assert.That(wrapped, Is.InstanceOf>>()); + } - private Wrapped Create(T value) => new Wrapped(value); + private Wrapped Create(T value) => new Wrapped(value); - private class Wrapped + private class Wrapped + { + public Wrapped(T value) { - public Wrapped(T value) - { - Value = value; - } + Value = value; + } - public T Value { get; } - }"); + public T Value { get; } + }"); RoslynAssert.CodeFix(analyzer, fix, expectedDiagnostic, code, fixedCode, fixTitle: ClassicModelAssertUsageCodeFix.TransformToConstraintModelDescription); } @@ -201,39 +200,33 @@ public Wrapped(T value) public void VerifyIsInstanceOfGenericFixWithMessage() { var code = TestUtility.WrapMethodInClassNamespaceAndAddUsings($@" - public void TestMethod() - {{ - var actual = 42; + public void TestMethod() + {{ + var actual = 42; - ↓Assert.IsInstanceOf(actual, ""message""); - }}"); + ↓ClassicAssert.IsInstanceOf(actual, ""message""); + }}"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" - public void TestMethod() - { - var actual = 42; + public void TestMethod() + { + var actual = 42; - Assert.That(actual, Is.InstanceOf(), ""message""); - }"); + Assert.That(actual, Is.InstanceOf(), ""message""); + }"); RoslynAssert.CodeFix(analyzer, fix, expectedDiagnostic, code, fixedCode, fixTitle: ClassicModelAssertUsageCodeFix.TransformToConstraintModelDescription); } [Test] public void VerifyIsInstanceOfGenericFixWithMessageAndParams() { - var code = TestUtility.WrapMethodInClassNamespaceAndAddUsings($@" - public void TestMethod() - {{ - var actual = 42; + var code = TestUtility.WrapInTestMethod($@" + var actual = 42; - ↓Assert.IsInstanceOf(actual, ""message"", Guid.NewGuid()); - }}"); - var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" - public void TestMethod() - { - var actual = 42; + ↓ClassicAssert.IsInstanceOf(actual, ""message-id: {{0}}"", Guid.NewGuid());"); + var fixedCode = TestUtility.WrapInTestMethod(@" + var actual = 42; - Assert.That(actual, Is.InstanceOf(), ""message"", Guid.NewGuid()); - }"); + Assert.That(actual, Is.InstanceOf(), $""message-id: {Guid.NewGuid()}"");"); RoslynAssert.CodeFix(analyzer, fix, expectedDiagnostic, code, fixedCode, fixTitle: ClassicModelAssertUsageCodeFix.TransformToConstraintModelDescription); } } diff --git a/src/nunit.analyzers.tests/ClassicModelAssertUsage/IsNaNClassicModelAssertUsageCodeFixTests.cs b/src/nunit.analyzers.tests/ClassicModelAssertUsage/IsNaNClassicModelAssertUsageCodeFixTests.cs index 941e37eb..cc5a8649 100644 --- a/src/nunit.analyzers.tests/ClassicModelAssertUsage/IsNaNClassicModelAssertUsageCodeFixTests.cs +++ b/src/nunit.analyzers.tests/ClassicModelAssertUsage/IsNaNClassicModelAssertUsageCodeFixTests.cs @@ -1,4 +1,3 @@ -using System.Collections.Immutable; using Gu.Roslyn.Asserts; using Microsoft.CodeAnalysis.CodeFixes; using Microsoft.CodeAnalysis.Diagnostics; @@ -33,7 +32,7 @@ public void TestMethod() {{ var expr = double.NaN; - ↓Assert.IsNaN(expr); + ↓ClassicAssert.IsNaN(expr); }}"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" public void TestMethod() @@ -53,7 +52,7 @@ public void TestMethod() {{ var expr = double.NaN; - ↓Assert.IsNaN(expr, ""message""); + ↓ClassicAssert.IsNaN(expr, ""message""); }}"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" public void TestMethod() @@ -73,14 +72,14 @@ public void TestMethod() {{ var expr = double.NaN; - ↓Assert.IsNaN(expr, ""message"", Guid.NewGuid()); + ↓ClassicAssert.IsNaN(expr, ""message-id: {{0}}"", Guid.NewGuid()); }}"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" public void TestMethod() { var expr = double.NaN; - Assert.That(expr, Is.NaN, ""message"", Guid.NewGuid()); + Assert.That(expr, Is.NaN, $""message-id: {Guid.NewGuid()}""); }"); RoslynAssert.CodeFix(analyzer, fix, expectedDiagnostic, code, fixedCode, fixTitle: ClassicModelAssertUsageCodeFix.TransformToConstraintModelDescription); } diff --git a/src/nunit.analyzers.tests/ClassicModelAssertUsage/IsNotEmptyClassicModelAssertUsageCodeFixTests.cs b/src/nunit.analyzers.tests/ClassicModelAssertUsage/IsNotEmptyClassicModelAssertUsageCodeFixTests.cs index 9016ff93..f24d963f 100644 --- a/src/nunit.analyzers.tests/ClassicModelAssertUsage/IsNotEmptyClassicModelAssertUsageCodeFixTests.cs +++ b/src/nunit.analyzers.tests/ClassicModelAssertUsage/IsNotEmptyClassicModelAssertUsageCodeFixTests.cs @@ -1,4 +1,3 @@ -using System.Collections.Immutable; using Gu.Roslyn.Asserts; using Microsoft.CodeAnalysis.CodeFixes; using Microsoft.CodeAnalysis.Diagnostics; @@ -33,7 +32,7 @@ public void TestMethod() {{ var collection = Array.Empty(); - ↓Assert.IsNotEmpty(collection); + ↓ClassicAssert.IsNotEmpty(collection); }}"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" public void TestMethod() @@ -53,7 +52,7 @@ public void TestMethod() {{ var collection = Array.Empty(); - ↓Assert.IsNotEmpty(collection, ""message""); + ↓ClassicAssert.IsNotEmpty(collection, ""message""); }}"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" public void TestMethod() @@ -73,14 +72,14 @@ public void TestMethod() {{ var collection = Array.Empty(); - ↓Assert.IsNotEmpty(collection, ""message"", Guid.NewGuid()); + ↓ClassicAssert.IsNotEmpty(collection, ""message-id: {{0}}"", Guid.NewGuid()); }}"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" public void TestMethod() { var collection = Array.Empty(); - Assert.That(collection, Is.Not.Empty, ""message"", Guid.NewGuid()); + Assert.That(collection, Is.Not.Empty, $""message-id: {Guid.NewGuid()}""); }"); RoslynAssert.CodeFix(analyzer, fix, expectedDiagnostic, code, fixedCode, fixTitle: ClassicModelAssertUsageCodeFix.TransformToConstraintModelDescription); } @@ -101,7 +100,7 @@ private struct MyString public void TestMethod() { MyString s = ""Hello NUnit""; - ↓Assert.IsNotEmpty(s); + ↓ClassicAssert.IsNotEmpty(s); }"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" private struct MyString diff --git a/src/nunit.analyzers.tests/ClassicModelAssertUsage/IsNotInstanceOfClassicModelAssertUsageCodeFixTests.cs b/src/nunit.analyzers.tests/ClassicModelAssertUsage/IsNotInstanceOfClassicModelAssertUsageCodeFixTests.cs index 49cfa5d7..2529f035 100644 --- a/src/nunit.analyzers.tests/ClassicModelAssertUsage/IsNotInstanceOfClassicModelAssertUsageCodeFixTests.cs +++ b/src/nunit.analyzers.tests/ClassicModelAssertUsage/IsNotInstanceOfClassicModelAssertUsageCodeFixTests.cs @@ -1,4 +1,3 @@ -using System.Collections.Immutable; using Gu.Roslyn.Asserts; using Microsoft.CodeAnalysis.CodeFixes; using Microsoft.CodeAnalysis.Diagnostics; @@ -34,7 +33,7 @@ public void TestMethod() var expected = typeof(int); var actual = 42; - ↓Assert.IsNotInstanceOf(expected, actual); + ↓ClassicAssert.IsNotInstanceOf(expected, actual); }}"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" public void TestMethod() @@ -56,7 +55,7 @@ public void TestMethod() var expected = typeof(int); var actual = 42; - ↓Assert.IsNotInstanceOf(expected, actual, ""message""); + ↓ClassicAssert.IsNotInstanceOf(expected, actual, ""message""); }}"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" public void TestMethod() @@ -78,7 +77,7 @@ public void TestMethod() var expected = typeof(int); var actual = 42; - ↓Assert.IsNotInstanceOf(expected, actual, ""message"", Guid.NewGuid()); + ↓ClassicAssert.IsNotInstanceOf(expected, actual, ""message-id: {{0}}"", Guid.NewGuid()); }}"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" public void TestMethod() @@ -86,7 +85,7 @@ public void TestMethod() var expected = typeof(int); var actual = 42; - Assert.That(actual, Is.Not.InstanceOf(expected), ""message"", Guid.NewGuid()); + Assert.That(actual, Is.Not.InstanceOf(expected), $""message-id: {Guid.NewGuid()}""); }"); RoslynAssert.CodeFix(analyzer, fix, expectedDiagnostic, code, fixedCode, fixTitle: ClassicModelAssertUsageCodeFix.TransformToConstraintModelDescription); } @@ -95,19 +94,19 @@ public void TestMethod() public void VerifyIsNotInstanceOfGenericFix() { var code = TestUtility.WrapMethodInClassNamespaceAndAddUsings($@" - public void TestMethod() - {{ - var actual = 42; + public void TestMethod() + {{ + var actual = 42; - ↓Assert.IsNotInstanceOf(actual); - }}"); + ↓ClassicAssert.IsNotInstanceOf(actual); + }}"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" - public void TestMethod() - { - var actual = 42; + public void TestMethod() + { + var actual = 42; - Assert.That(actual, Is.Not.InstanceOf()); - }"); + Assert.That(actual, Is.Not.InstanceOf()); + }"); RoslynAssert.CodeFix(analyzer, fix, expectedDiagnostic, code, fixedCode, fixTitle: ClassicModelAssertUsageCodeFix.TransformToConstraintModelDescription); } @@ -115,41 +114,41 @@ public void TestMethod() public void VerifyIsNotInstanceOfSingleNestedGenericFix() { var code = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" - public void TestMethod() - { - var wrapped = Create(42); - ↓Assert.IsNotInstanceOf>(wrapped); - } + public void TestMethod() + { + var wrapped = Create(42); + ↓ClassicAssert.IsNotInstanceOf>(wrapped); + } - private Wrapped Create(T value) => new Wrapped(value); + private Wrapped Create(T value) => new Wrapped(value); - private class Wrapped + private class Wrapped + { + public Wrapped(T value) { - public Wrapped(T value) - { - Value = value; - } + Value = value; + } - public T Value { get; } - }"); + public T Value { get; } + }"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" - public void TestMethod() - { - var wrapped = Create(42); - Assert.That(wrapped, Is.Not.InstanceOf>()); - } + public void TestMethod() + { + var wrapped = Create(42); + Assert.That(wrapped, Is.Not.InstanceOf>()); + } - private Wrapped Create(T value) => new Wrapped(value); + private Wrapped Create(T value) => new Wrapped(value); - private class Wrapped + private class Wrapped + { + public Wrapped(T value) { - public Wrapped(T value) - { - Value = value; - } + Value = value; + } - public T Value { get; } - }"); + public T Value { get; } + }"); RoslynAssert.CodeFix(analyzer, fix, expectedDiagnostic, code, fixedCode, fixTitle: ClassicModelAssertUsageCodeFix.TransformToConstraintModelDescription); } @@ -157,43 +156,43 @@ public Wrapped(T value) public void VerifyIsNotInstanceOfDoubleNestedGenericFix() { var code = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" - public void TestMethod() - { - var wrapped = Create(42); - var nested = Create(wrapped); - ↓Assert.IsNotInstanceOf>>(wrapped); - } + public void TestMethod() + { + var wrapped = Create(42); + var nested = Create(wrapped); + ↓ClassicAssert.IsNotInstanceOf>>(wrapped); + } - private Wrapped Create(T value) => new Wrapped(value); + private Wrapped Create(T value) => new Wrapped(value); - private class Wrapped + private class Wrapped + { + public Wrapped(T value) { - public Wrapped(T value) - { - Value = value; - } + Value = value; + } - public T Value { get; } - }"); + public T Value { get; } + }"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" - public void TestMethod() - { - var wrapped = Create(42); - var nested = Create(wrapped); - Assert.That(wrapped, Is.Not.InstanceOf>>()); - } + public void TestMethod() + { + var wrapped = Create(42); + var nested = Create(wrapped); + Assert.That(wrapped, Is.Not.InstanceOf>>()); + } - private Wrapped Create(T value) => new Wrapped(value); + private Wrapped Create(T value) => new Wrapped(value); - private class Wrapped + private class Wrapped + { + public Wrapped(T value) { - public Wrapped(T value) - { - Value = value; - } + Value = value; + } - public T Value { get; } - }"); + public T Value { get; } + }"); RoslynAssert.CodeFix(analyzer, fix, expectedDiagnostic, code, fixedCode, fixTitle: ClassicModelAssertUsageCodeFix.TransformToConstraintModelDescription); } @@ -201,39 +200,33 @@ public Wrapped(T value) public void VerifyIsNotInstanceOfGenericFixWithMessage() { var code = TestUtility.WrapMethodInClassNamespaceAndAddUsings($@" - public void TestMethod() - {{ - var actual = 42; + public void TestMethod() + {{ + var actual = 42; - ↓Assert.IsNotInstanceOf(actual, ""message""); - }}"); + ↓ClassicAssert.IsNotInstanceOf(actual, ""message""); + }}"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" - public void TestMethod() - { - var actual = 42; + public void TestMethod() + { + var actual = 42; - Assert.That(actual, Is.Not.InstanceOf(), ""message""); - }"); + Assert.That(actual, Is.Not.InstanceOf(), ""message""); + }"); RoslynAssert.CodeFix(analyzer, fix, expectedDiagnostic, code, fixedCode, fixTitle: ClassicModelAssertUsageCodeFix.TransformToConstraintModelDescription); } [Test] public void VerifyIsNotInstanceOfGenericFixWithMessageAndParams() { - var code = TestUtility.WrapMethodInClassNamespaceAndAddUsings($@" - public void TestMethod() - {{ - var actual = 42; + var code = TestUtility.WrapInTestMethod($@" + var actual = 42; - ↓Assert.IsNotInstanceOf(actual, ""message"", Guid.NewGuid()); - }}"); - var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" - public void TestMethod() - { - var actual = 42; + ↓ClassicAssert.IsNotInstanceOf(actual, ""message-id: {{0}}"", Guid.NewGuid());"); + var fixedCode = TestUtility.WrapInTestMethod(@" + var actual = 42; - Assert.That(actual, Is.Not.InstanceOf(), ""message"", Guid.NewGuid()); - }"); + Assert.That(actual, Is.Not.InstanceOf(), $""message-id: {Guid.NewGuid()}"");"); RoslynAssert.CodeFix(analyzer, fix, expectedDiagnostic, code, fixedCode, fixTitle: ClassicModelAssertUsageCodeFix.TransformToConstraintModelDescription); } } diff --git a/src/nunit.analyzers.tests/ClassicModelAssertUsage/IsNotNullAndNotNullClassicModelAssertUsageCodeFixTests.cs b/src/nunit.analyzers.tests/ClassicModelAssertUsage/IsNotNullAndNotNullClassicModelAssertUsageCodeFixTests.cs index 39bee013..b270b290 100644 --- a/src/nunit.analyzers.tests/ClassicModelAssertUsage/IsNotNullAndNotNullClassicModelAssertUsageCodeFixTests.cs +++ b/src/nunit.analyzers.tests/ClassicModelAssertUsage/IsNotNullAndNotNullClassicModelAssertUsageCodeFixTests.cs @@ -1,4 +1,3 @@ -using System.Collections.Immutable; using Gu.Roslyn.Asserts; using Microsoft.CodeAnalysis.CodeFixes; using Microsoft.CodeAnalysis.Diagnostics; @@ -33,7 +32,7 @@ public void VerifyIsNotNullAndNotNullFixes(string assertion, string diagnosticId public void TestMethod() {{ object? obj = null; - ↓Assert.{assertion}(obj); + ↓ClassicAssert.{assertion}(obj); }}"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" public void TestMethod() @@ -54,7 +53,7 @@ public void VerifyIsNotNullAndNotNullFixesWithMessage(string assertion, string d public void TestMethod() {{ object? obj = null; - ↓Assert.{assertion}(obj, ""message""); + ↓ClassicAssert.{assertion}(obj, ""message""); }}"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" public void TestMethod() @@ -75,13 +74,13 @@ public void VerifyIsNotNullAndNotNullFixesWithMessageAndParams(string assertion, public void TestMethod() {{ object? obj = null; - ↓Assert.{assertion}(obj, ""message"", Guid.NewGuid()); + ↓ClassicAssert.{assertion}(obj, ""message-id: {{0}}"", Guid.NewGuid()); }}"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" public void TestMethod() { object? obj = null; - Assert.That(obj, Is.Not.Null, ""message"", Guid.NewGuid()); + Assert.That(obj, Is.Not.Null, $""message-id: {Guid.NewGuid()}""); }"); RoslynAssert.CodeFix(analyzer, fix, expectedDiagnostic, code, fixedCode, fixTitle: ClassicModelAssertUsageCodeFix.TransformToConstraintModelDescription); } diff --git a/src/nunit.analyzers.tests/ClassicModelAssertUsage/IsNullAndNullClassicModelAssertUsageCodeFixTests.cs b/src/nunit.analyzers.tests/ClassicModelAssertUsage/IsNullAndNullClassicModelAssertUsageCodeFixTests.cs index 7a69787f..638b821e 100644 --- a/src/nunit.analyzers.tests/ClassicModelAssertUsage/IsNullAndNullClassicModelAssertUsageCodeFixTests.cs +++ b/src/nunit.analyzers.tests/ClassicModelAssertUsage/IsNullAndNullClassicModelAssertUsageCodeFixTests.cs @@ -1,4 +1,3 @@ -using System.Collections.Immutable; using Gu.Roslyn.Asserts; using Microsoft.CodeAnalysis.CodeFixes; using Microsoft.CodeAnalysis.Diagnostics; @@ -33,7 +32,7 @@ public void VerifyIsNullAndNullFixes(string assertion, string diagnosticId) public void TestMethod() {{ object? obj = null; - ↓Assert.{assertion}(obj); + ↓ClassicAssert.{assertion}(obj); }}"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" public void TestMethod() @@ -54,7 +53,7 @@ public void VerifyIsNullAndNullFixesWithMessage(string assertion, string diagnos public void TestMethod() {{ object? obj = null; - ↓Assert.{assertion}(obj, ""message""); + ↓ClassicAssert.{assertion}(obj, ""message""); }}"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" public void TestMethod() @@ -75,13 +74,13 @@ public void VerifyIsNullAndNullFixesWithMessageAndParams(string assertion, strin public void TestMethod() {{ object? obj = null; - ↓Assert.{assertion}(obj, ""message"", Guid.NewGuid()); + ↓ClassicAssert.{assertion}(obj, ""message-id: {{0}}"", Guid.NewGuid()); }}"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" public void TestMethod() { object? obj = null; - Assert.That(obj, Is.Null, ""message"", Guid.NewGuid()); + Assert.That(obj, Is.Null, $""message-id: {Guid.NewGuid()}""); }"); RoslynAssert.CodeFix(analyzer, fix, expectedDiagnostic, code, fixedCode, fixTitle: ClassicModelAssertUsageCodeFix.TransformToConstraintModelDescription); } diff --git a/src/nunit.analyzers.tests/ClassicModelAssertUsage/IsTrueAndTrueClassicModelAssertUsageCodeFixTests.cs b/src/nunit.analyzers.tests/ClassicModelAssertUsage/IsTrueAndTrueClassicModelAssertUsageCodeFixTests.cs index 75421c6d..9f093c0b 100644 --- a/src/nunit.analyzers.tests/ClassicModelAssertUsage/IsTrueAndTrueClassicModelAssertUsageCodeFixTests.cs +++ b/src/nunit.analyzers.tests/ClassicModelAssertUsage/IsTrueAndTrueClassicModelAssertUsageCodeFixTests.cs @@ -1,4 +1,3 @@ -using System.Collections.Immutable; using Gu.Roslyn.Asserts; using Microsoft.CodeAnalysis.CodeFixes; using Microsoft.CodeAnalysis.Diagnostics; @@ -32,7 +31,7 @@ public void VerifyIsTrueAndTrueFixes(string assertion, string diagnosticId) var code = TestUtility.WrapMethodInClassNamespaceAndAddUsings($@" public void TestMethod() {{ - ↓Assert.{assertion}(true); + ↓ClassicAssert.{assertion}(true); }}"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" public void TestMethod() @@ -51,7 +50,7 @@ public void VerifyIsTrueAndTrueFixesWithMessage(string assertion, string diagnos var code = TestUtility.WrapMethodInClassNamespaceAndAddUsings($@" public void TestMethod() {{ - ↓Assert.{assertion}(true, ""message""); + ↓ClassicAssert.{assertion}(true, ""message""); }}"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" public void TestMethod() @@ -70,12 +69,12 @@ public void VerifyIsTrueAndTrueFixesWithMessageAndParams(string assertion, strin var code = TestUtility.WrapMethodInClassNamespaceAndAddUsings($@" public void TestMethod() {{ - ↓Assert.{assertion}(true, ""message"", Guid.NewGuid()); + ↓ClassicAssert.{assertion}(true, ""message-id: {{0}}"", Guid.NewGuid()); }}"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" public void TestMethod() { - Assert.That(true, Is.True, ""message"", Guid.NewGuid()); + Assert.That(true, Is.True, $""message-id: {Guid.NewGuid()}""); }"); RoslynAssert.CodeFix(analyzer, fix, expectedDiagnostic, code, fixedCode, fixTitle: ClassicModelAssertUsageCodeFix.TransformToConstraintModelDescription); } @@ -99,7 +98,7 @@ private struct MyBool public void TestMethod() {{ MyBool x = true; - ↓Assert.{assertion}(x); + ↓ClassicAssert.{assertion}(x); }}"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" private struct MyBool diff --git a/src/nunit.analyzers.tests/ClassicModelAssertUsage/IsTrueAndTrueClassicModelAssertUsageCondensedCodeFixTests.cs b/src/nunit.analyzers.tests/ClassicModelAssertUsage/IsTrueAndTrueClassicModelAssertUsageCondensedCodeFixTests.cs index 2fc8bfe3..2505d814 100644 --- a/src/nunit.analyzers.tests/ClassicModelAssertUsage/IsTrueAndTrueClassicModelAssertUsageCondensedCodeFixTests.cs +++ b/src/nunit.analyzers.tests/ClassicModelAssertUsage/IsTrueAndTrueClassicModelAssertUsageCondensedCodeFixTests.cs @@ -1,4 +1,3 @@ -using System.Collections.Immutable; using Gu.Roslyn.Asserts; using Microsoft.CodeAnalysis.CodeFixes; using Microsoft.CodeAnalysis.Diagnostics; @@ -32,7 +31,7 @@ public void VerifyIsTrueAndTrueFixes(string assertion, string diagnosticId) var code = TestUtility.WrapMethodInClassNamespaceAndAddUsings($@" public void TestMethod() {{ - ↓Assert.{assertion}(true); + ↓ClassicAssert.{assertion}(true); }}"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" public void TestMethod() @@ -52,7 +51,7 @@ public void VerifyIsTrueAndTrueFixesWithMessage(string assertion, string diagnos var code = TestUtility.WrapMethodInClassNamespaceAndAddUsings($@" public void TestMethod() {{ - ↓Assert.{assertion}(true, ""message""); + ↓ClassicAssert.{assertion}(true, ""message""); }}"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" public void TestMethod() @@ -72,12 +71,12 @@ public void VerifyIsTrueAndTrueFixesWithMessageAndParams(string assertion, strin var code = TestUtility.WrapMethodInClassNamespaceAndAddUsings($@" public void TestMethod() {{ - ↓Assert.{assertion}(true, ""message"", Guid.NewGuid()); + ↓ClassicAssert.{assertion}(true, ""message-id: {{0}}"", Guid.NewGuid()); }}"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" public void TestMethod() { - Assert.That(true, ""message"", Guid.NewGuid()); + Assert.That(true, $""message-id: {Guid.NewGuid()}""); }"); RoslynAssert.CodeFix(analyzer, fix, expectedDiagnostic, code, fixedCode, fixTitle: ClassicModelAssertUsageCodeFix.TransformToConstraintModelDescription + IsTrueAndTrueClassicModelAssertUsageCondensedCodeFix.Suffix); diff --git a/src/nunit.analyzers.tests/ClassicModelAssertUsage/LessClassicModelAssertUsageCodeFixTests.cs b/src/nunit.analyzers.tests/ClassicModelAssertUsage/LessClassicModelAssertUsageCodeFixTests.cs index 81676c94..76a802f5 100644 --- a/src/nunit.analyzers.tests/ClassicModelAssertUsage/LessClassicModelAssertUsageCodeFixTests.cs +++ b/src/nunit.analyzers.tests/ClassicModelAssertUsage/LessClassicModelAssertUsageCodeFixTests.cs @@ -1,4 +1,3 @@ -using System.Collections.Immutable; using Gu.Roslyn.Asserts; using Microsoft.CodeAnalysis.CodeFixes; using Microsoft.CodeAnalysis.Diagnostics; @@ -31,7 +30,7 @@ public void VerifyLessFix() var code = TestUtility.WrapMethodInClassNamespaceAndAddUsings($@" public void TestMethod() {{ - ↓Assert.Less(2d, 3d); + ↓ClassicAssert.Less(2d, 3d); }}"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" public void TestMethod() @@ -47,7 +46,7 @@ public void VerifyLessFixWithMessage() var code = TestUtility.WrapMethodInClassNamespaceAndAddUsings($@" public void TestMethod() {{ - ↓Assert.Less(2d, 3d, ""message""); + ↓ClassicAssert.Less(2d, 3d, ""message""); }}"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" public void TestMethod() @@ -63,12 +62,12 @@ public void VerifyLessFixWithMessageAndParams() var code = TestUtility.WrapMethodInClassNamespaceAndAddUsings($@" public void TestMethod() {{ - ↓Assert.Less(2d, 3d, ""message"", Guid.NewGuid()); + ↓ClassicAssert.Less(2d, 3d, ""message-id: {{0}}"", Guid.NewGuid()); }}"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" public void TestMethod() { - Assert.That(2d, Is.LessThan(3d), ""message"", Guid.NewGuid()); + Assert.That(2d, Is.LessThan(3d), $""message-id: {Guid.NewGuid()}""); }"); RoslynAssert.CodeFix(analyzer, fix, expectedDiagnostic, code, fixedCode, fixTitle: ClassicModelAssertUsageCodeFix.TransformToConstraintModelDescription); } @@ -77,14 +76,12 @@ public void TestMethod() public void CodeFixPreservesLineBreakBeforeMessage() { var code = TestUtility.WrapInTestMethod($@" - Assert.Less(2d, 3d, - ""message"", - Guid.NewGuid());"); + ClassicAssert.Less(2d, 3d, + ""message"");"); var fixedCode = TestUtility.WrapInTestMethod(@" Assert.That(2d, Is.LessThan(3d), - ""message"", - Guid.NewGuid());"); + ""message"");"); RoslynAssert.CodeFix(analyzer, fix, expectedDiagnostic, code, fixedCode, fixTitle: ClassicModelAssertUsageCodeFix.TransformToConstraintModelDescription); } @@ -106,7 +103,7 @@ public void TestMethod() { MyFloat x = 1; float y = 2; - ↓Assert.Less(x, y); + ↓ClassicAssert.Less(x, y); }"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" private struct MyFloat @@ -144,7 +141,7 @@ public void TestMethod() { float x = 1; MyFloat y = 2; - ↓Assert.Less(x, y); + ↓ClassicAssert.Less(x, y); }"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" private struct MyFloat diff --git a/src/nunit.analyzers.tests/ClassicModelAssertUsage/LessOrEqualClassicModelAssertUsageCodeFixTests.cs b/src/nunit.analyzers.tests/ClassicModelAssertUsage/LessOrEqualClassicModelAssertUsageCodeFixTests.cs index a6aad3d0..22654092 100644 --- a/src/nunit.analyzers.tests/ClassicModelAssertUsage/LessOrEqualClassicModelAssertUsageCodeFixTests.cs +++ b/src/nunit.analyzers.tests/ClassicModelAssertUsage/LessOrEqualClassicModelAssertUsageCodeFixTests.cs @@ -1,4 +1,3 @@ -using System.Collections.Immutable; using Gu.Roslyn.Asserts; using Microsoft.CodeAnalysis.CodeFixes; using Microsoft.CodeAnalysis.Diagnostics; @@ -31,7 +30,7 @@ public void VerifyLessOrEqualFix() var code = TestUtility.WrapMethodInClassNamespaceAndAddUsings($@" public void TestMethod() {{ - ↓Assert.LessOrEqual(2d, 3d); + ↓ClassicAssert.LessOrEqual(2d, 3d); }}"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" public void TestMethod() @@ -47,7 +46,7 @@ public void VerifyLessOrEqualFixWithMessage() var code = TestUtility.WrapMethodInClassNamespaceAndAddUsings($@" public void TestMethod() {{ - ↓Assert.LessOrEqual(2d, 3d, ""message""); + ↓ClassicAssert.LessOrEqual(2d, 3d, ""message""); }}"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" public void TestMethod() @@ -63,12 +62,12 @@ public void VerifyLessOrEqualFixWithMessageAndParams() var code = TestUtility.WrapMethodInClassNamespaceAndAddUsings($@" public void TestMethod() {{ - ↓Assert.LessOrEqual(2d, 3d, ""message"", Guid.NewGuid()); + ↓ClassicAssert.LessOrEqual(2d, 3d, ""message-id: {{0}}"", Guid.NewGuid()); }}"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" public void TestMethod() { - Assert.That(2d, Is.LessThanOrEqualTo(3d), ""message"", Guid.NewGuid()); + Assert.That(2d, Is.LessThanOrEqualTo(3d), $""message-id: {Guid.NewGuid()}""); }"); RoslynAssert.CodeFix(analyzer, fix, expectedDiagnostic, code, fixedCode, fixTitle: ClassicModelAssertUsageCodeFix.TransformToConstraintModelDescription); } @@ -77,14 +76,12 @@ public void TestMethod() public void CodeFixPreservesLineBreakBeforeMessage() { var code = TestUtility.WrapInTestMethod($@" - Assert.LessOrEqual(2d, 3d, - ""message"", - Guid.NewGuid());"); + ClassicAssert.LessOrEqual(2d, 3d, + ""message"");"); var fixedCode = TestUtility.WrapInTestMethod(@" Assert.That(2d, Is.LessThanOrEqualTo(3d), - ""message"", - Guid.NewGuid());"); + ""message"");"); RoslynAssert.CodeFix(analyzer, fix, expectedDiagnostic, code, fixedCode, fixTitle: ClassicModelAssertUsageCodeFix.TransformToConstraintModelDescription); } @@ -106,7 +103,7 @@ public void TestMethod() { MyFloat x = 1; float y = 2; - ↓Assert.LessOrEqual(x, y); + ↓ClassicAssert.LessOrEqual(x, y); }"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" private struct MyFloat @@ -144,7 +141,7 @@ public void TestMethod() { float x = 1; MyFloat y = 2; - ↓Assert.LessOrEqual(x, y); + ↓ClassicAssert.LessOrEqual(x, y); }"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" private struct MyFloat diff --git a/src/nunit.analyzers.tests/ClassicModelAssertUsage/NotZeroClassicModelAssertUsageCodeFixTests.cs b/src/nunit.analyzers.tests/ClassicModelAssertUsage/NotZeroClassicModelAssertUsageCodeFixTests.cs index 04bd62f7..db0cca19 100644 --- a/src/nunit.analyzers.tests/ClassicModelAssertUsage/NotZeroClassicModelAssertUsageCodeFixTests.cs +++ b/src/nunit.analyzers.tests/ClassicModelAssertUsage/NotZeroClassicModelAssertUsageCodeFixTests.cs @@ -1,4 +1,3 @@ -using System.Collections.Immutable; using Gu.Roslyn.Asserts; using Microsoft.CodeAnalysis.CodeFixes; using Microsoft.CodeAnalysis.Diagnostics; @@ -33,7 +32,7 @@ public void TestMethod() {{ var expr = default(int); - ↓Assert.NotZero(expr); + ↓ClassicAssert.NotZero(expr); }}"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" public void TestMethod() @@ -53,7 +52,7 @@ public void TestMethod() {{ var expr = default(int); - ↓Assert.NotZero(expr, ""message""); + ↓ClassicAssert.NotZero(expr, ""message""); }}"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" public void TestMethod() @@ -73,14 +72,14 @@ public void TestMethod() {{ var expr = default(int); - ↓Assert.NotZero(expr, ""message"", Guid.NewGuid()); + ↓ClassicAssert.NotZero(expr, ""message-id: {{0}}"", Guid.NewGuid()); }}"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" public void TestMethod() { var expr = default(int); - Assert.That(expr, Is.Not.Zero, ""message"", Guid.NewGuid()); + Assert.That(expr, Is.Not.Zero, $""message-id: {Guid.NewGuid()}""); }"); RoslynAssert.CodeFix(analyzer, fix, expectedDiagnostic, code, fixedCode, fixTitle: ClassicModelAssertUsageCodeFix.TransformToConstraintModelDescription); } diff --git a/src/nunit.analyzers.tests/ClassicModelAssertUsage/ZeroClassicModelAssertUsageCodeFixTests.cs b/src/nunit.analyzers.tests/ClassicModelAssertUsage/ZeroClassicModelAssertUsageCodeFixTests.cs index 8b973b9c..6f326729 100644 --- a/src/nunit.analyzers.tests/ClassicModelAssertUsage/ZeroClassicModelAssertUsageCodeFixTests.cs +++ b/src/nunit.analyzers.tests/ClassicModelAssertUsage/ZeroClassicModelAssertUsageCodeFixTests.cs @@ -1,4 +1,3 @@ -using System.Collections.Immutable; using Gu.Roslyn.Asserts; using Microsoft.CodeAnalysis.CodeFixes; using Microsoft.CodeAnalysis.Diagnostics; @@ -33,7 +32,7 @@ public void TestMethod() {{ var expr = default(int); - ↓Assert.Zero(expr); + ↓ClassicAssert.Zero(expr); }}"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" public void TestMethod() @@ -53,7 +52,7 @@ public void TestMethod() {{ var expr = default(int); - ↓Assert.Zero(expr, ""message""); + ↓ClassicAssert.Zero(expr, ""message""); }}"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" public void TestMethod() @@ -73,14 +72,14 @@ public void TestMethod() {{ var expr = default(int); - ↓Assert.Zero(expr, ""message"", Guid.NewGuid()); + ↓ClassicAssert.Zero(expr, ""message-id: {{0}}"", Guid.NewGuid()); }}"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" public void TestMethod() { var expr = default(int); - Assert.That(expr, Is.Zero, ""message"", Guid.NewGuid()); + Assert.That(expr, Is.Zero, $""message-id: {Guid.NewGuid()}""); }"); RoslynAssert.CodeFix(analyzer, fix, expectedDiagnostic, code, fixedCode, fixTitle: ClassicModelAssertUsageCodeFix.TransformToConstraintModelDescription); } diff --git a/src/nunit.analyzers.tests/CollectionAssertUsage/CollectionAssertUsageAnalyzerTests.cs b/src/nunit.analyzers.tests/CollectionAssertUsage/CollectionAssertUsageAnalyzerTests.cs new file mode 100644 index 00000000..b2ae923d --- /dev/null +++ b/src/nunit.analyzers.tests/CollectionAssertUsage/CollectionAssertUsageAnalyzerTests.cs @@ -0,0 +1,137 @@ +using System.Collections.Generic; +using Gu.Roslyn.Asserts; +using Microsoft.CodeAnalysis.Diagnostics; +using NUnit.Analyzers.CollectionAssertUsage; +using NUnit.Analyzers.Constants; +using NUnit.Framework; + +namespace NUnit.Analyzers.Tests.CollectionAssertUsage +{ + [TestFixture] + internal sealed class CollectionAssertUsageAnalyzerTests + { + private readonly DiagnosticAnalyzer analyzer = new CollectionAssertUsageAnalyzer(); + private readonly ExpectedDiagnostic diagnostic = ExpectedDiagnostic.Create(AnalyzerIdentifiers.CollectionAssertUsage); + + private static IEnumerable OneCollectionParameterAsserts => CollectionAssertUsageAnalyzer.OneCollectionParameterAsserts.Keys; + + private static IEnumerable TwoCollectionParameterAsserts => CollectionAssertUsageAnalyzer.TwoCollectionParameterAsserts.Keys; + + private static IEnumerable CollectionAndItemParameterAsserts => CollectionAssertUsageAnalyzer.CollectionAndItemParameterAsserts.Keys; + + [TestCaseSource(nameof(OneCollectionParameterAsserts))] + public void AnalyzeOneCollectionWhenNoMessageArgumentsAreUsed(string method) + { + var testCode = TestUtility.WrapInTestMethod(@$" + var collection = new[] {{ 1, 2, 3 }}; + ↓CollectionAssert.{method}(collection); + "); + RoslynAssert.Diagnostics(this.analyzer, this.diagnostic, testCode); + } + + [TestCaseSource(nameof(OneCollectionParameterAsserts))] + public void AnalyzeOneCollectionWhenOnlyMessageArgumentsAreUsed(string method) + { + var testCode = TestUtility.WrapInTestMethod(@$" + var collection = new[] {{ 1, 2, 3 }}; + ↓CollectionAssert.{method}(collection, ""message""); + "); + RoslynAssert.Diagnostics(this.analyzer, this.diagnostic, testCode); + } + + [TestCaseSource(nameof(OneCollectionParameterAsserts))] + public void AnalyzeOneCollectionWhenFormatAndParamsArgumentsAreUsed(string method) + { + var testCode = TestUtility.WrapInTestMethod(@$" + var collection = new[] {{ 1, 2, 3 }}; + ↓CollectionAssert.{method}(collection, ""Because of {{0}}"", ""message""); + "); + RoslynAssert.Diagnostics(this.analyzer, this.diagnostic, testCode); + } + + [TestCaseSource(nameof(TwoCollectionParameterAsserts))] + public void AnalyzeTwoCollectionWhenNoMessageArgumentsAreUsed(string method) + { + var testCode = TestUtility.WrapInTestMethod(@$" + var collection1 = new[] {{ 1, 2, 3 }}; + var collection2 = new[] {{ 2, 4, 6 }}; + ↓CollectionAssert.{method}(collection1, collection2); + "); + RoslynAssert.Diagnostics(this.analyzer, this.diagnostic, testCode); + } + + [TestCaseSource(nameof(TwoCollectionParameterAsserts))] + public void AnalyzeTwoCollectionWhenOnlyMessageArgumentsAreUsed(string method) + { + var testCode = TestUtility.WrapInTestMethod(@$" + var collection1 = new[] {{ 1, 2, 3 }}; + var collection2 = new[] {{ 2, 4, 6 }}; + ↓CollectionAssert.{method}(collection1, collection2, ""message""); + "); + RoslynAssert.Diagnostics(this.analyzer, this.diagnostic, testCode); + } + + [TestCaseSource(nameof(TwoCollectionParameterAsserts))] + public void AnalyzeTwoCollectionWhenFormatAndParamsArgumentsAreUsed(string method) + { + var testCode = TestUtility.WrapInTestMethod(@$" + var collection1 = new[] {{ 1, 2, 3 }}; + var collection2 = new[] {{ 2, 4, 6 }}; + ↓CollectionAssert.{method}(collection1, collection2, ""Because of {{0}}"", ""message""); + "); + RoslynAssert.Diagnostics(this.analyzer, this.diagnostic, testCode); + } + + [TestCase(NUnitFrameworkConstants.NameOfCollectionAssertAreEqual)] + [TestCase(NUnitFrameworkConstants.NameOfCollectionAssertAreNotEqual)] + public void AnalyzeTwoCollectionWithComparerWhenFormatAndParamsArgumentsAreUsed(string method) + { + var testCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@$" + [Test] + public void TestMethod() + {{ + var collection1 = new[] {{ 1, 2, 3 }}; + var collection2 = new[] {{ 2, 4, 6 }}; + var comparer = new AlwaysEqualComparer(); + ↓CollectionAssert.{method}(collection1, collection2, comparer, ""Because of {{0}}"", ""message""); + }} + + private sealed class AlwaysEqualComparer : IComparer + {{ + public int Compare(object? x, object? y) => 0; + }} + ", "using System.Collections;"); + RoslynAssert.Diagnostics(this.analyzer, this.diagnostic, testCode); + } + + [TestCaseSource(nameof(CollectionAndItemParameterAsserts))] + public void AnalyzeCollectionAndItemWhenNoMessageArgumentsAreUsed(string method) + { + var testCode = TestUtility.WrapInTestMethod(@$" + var collection = new[] {{ typeof(byte), typeof(char) }}; + ↓CollectionAssert.{method}(collection, typeof(byte)); + "); + RoslynAssert.Diagnostics(this.analyzer, this.diagnostic, testCode); + } + + [TestCaseSource(nameof(CollectionAndItemParameterAsserts))] + public void AnalyzeCollectionAndItemWhenOnlyMessageArgumentsAreUsed(string method) + { + var testCode = TestUtility.WrapInTestMethod(@$" + var collection = new[] {{ typeof(byte), typeof(char) }}; + ↓CollectionAssert.{method}(collection, typeof(byte), ""message""); + "); + RoslynAssert.Diagnostics(this.analyzer, this.diagnostic, testCode); + } + + [TestCaseSource(nameof(CollectionAndItemParameterAsserts))] + public void AnalyzeCollectionAndItemWhenFormatAndParamsArgumentsAreUsed(string method) + { + var testCode = TestUtility.WrapInTestMethod(@$" + var collection = new[] {{ typeof(byte), typeof(char) }}; + ↓CollectionAssert.{method}(collection, typeof(byte), ""Because of {{0}}"", ""message""); + "); + RoslynAssert.Diagnostics(this.analyzer, this.diagnostic, testCode); + } + } +} diff --git a/src/nunit.analyzers.tests/CollectionAssertUsage/CollectionAssertUsageCodeFixTests.cs b/src/nunit.analyzers.tests/CollectionAssertUsage/CollectionAssertUsageCodeFixTests.cs new file mode 100644 index 00000000..b0cd749a --- /dev/null +++ b/src/nunit.analyzers.tests/CollectionAssertUsage/CollectionAssertUsageCodeFixTests.cs @@ -0,0 +1,218 @@ +using System.Collections.Generic; +using Gu.Roslyn.Asserts; +using Microsoft.CodeAnalysis.CodeFixes; +using Microsoft.CodeAnalysis.Diagnostics; +using NUnit.Analyzers.CollectionAssertUsage; +using NUnit.Analyzers.Constants; +using NUnit.Framework; + +namespace NUnit.Analyzers.Tests.CollectionAssertUsage +{ + [TestFixture] + internal sealed class CollectionAssertUsageCodeFixTests + { + private static readonly DiagnosticAnalyzer analyzer = new CollectionAssertUsageAnalyzer(); + private static readonly CodeFixProvider fix = new CollectionAssertUsageCodeFix(); + private static readonly ExpectedDiagnostic expectedDiagnostic = ExpectedDiagnostic.Create(AnalyzerIdentifiers.CollectionAssertUsage); + + private static IEnumerable OneCollectionParameterAsserts => CollectionAssertUsageAnalyzer.OneCollectionParameterAsserts.Keys; + + private static IEnumerable TwoCollectionParameterAsserts => CollectionAssertUsageAnalyzer.TwoCollectionParameterAsserts.Keys; + + private static IEnumerable CollectionAndItemParameterAsserts => CollectionAssertUsageAnalyzer.CollectionAndItemParameterAsserts.Keys; + + [TestCaseSource(nameof(OneCollectionParameterAsserts))] + public void AnalyzeOneCollectionWhenNoMessageArgumentsAreUsed(string method) + { + var code = TestUtility.WrapInTestMethod(@$" + var collection = new[] {{ 1, 2, 3 }}; + ↓CollectionAssert.{method}(collection); + "); + var fixedCode = TestUtility.WrapInTestMethod(@$" + var collection = new[] {{ 1, 2, 3 }}; + Assert.That(collection, {CollectionAssertUsageAnalyzer.OneCollectionParameterAsserts[method]}); + "); + RoslynAssert.CodeFix(analyzer, fix, expectedDiagnostic, code, fixedCode); + } + + [TestCaseSource(nameof(OneCollectionParameterAsserts))] + public void AnalyzeOneCollectionWhenOnlyMessageArgumentsAreUsed(string method) + { + var code = TestUtility.WrapInTestMethod(@$" + var collection = new[] {{ 1, 2, 3 }}; + ↓CollectionAssert.{method}(collection, ""message""); + "); + var fixedCode = TestUtility.WrapInTestMethod(@$" + var collection = new[] {{ 1, 2, 3 }}; + Assert.That(collection, {CollectionAssertUsageAnalyzer.OneCollectionParameterAsserts[method]}, ""message""); + "); + RoslynAssert.CodeFix(analyzer, fix, expectedDiagnostic, code, fixedCode); + } + + [TestCaseSource(nameof(OneCollectionParameterAsserts))] + public void AnalyzeOneCollectionWhenFormatAndParamsArgumentsAreUsed(string method) + { + var code = TestUtility.WrapInTestMethod(@$" + var collection = new[] {{ 1, 2, 3 }}; + ↓CollectionAssert.{method}(collection, ""Because of {{0}}"", ""message""); + "); + var fixedCode = TestUtility.WrapInTestMethod(@$" + var collection = new[] {{ 1, 2, 3 }}; + Assert.That(collection, {CollectionAssertUsageAnalyzer.OneCollectionParameterAsserts[method]}, $""Because of {{""message""}}""); + "); + RoslynAssert.CodeFix(analyzer, fix, expectedDiagnostic, code, fixedCode); + } + + [TestCase(NUnitFrameworkConstants.NameOfCollectionAssertIsOrdered)] + public void AnalyzeOneCollectionWithComparerWhenFormatAndParamsArgumentsAreUsed(string method) + { + var code = TestUtility.WrapInTestMethod(@$" + var collection = new[] {{ 2, 4, 6 }}; + IComparer comparer = Comparer.Default; + ↓CollectionAssert.{method}(collection, comparer, ""Because of {{0}}"", ""message""); + ", "using System.Collections;using System.Collections.Generic;"); + var fixedCode = TestUtility.WrapInTestMethod(@$" + var collection = new[] {{ 2, 4, 6 }}; + IComparer comparer = Comparer.Default; + Assert.That(collection, {CollectionAssertUsageAnalyzer.OneCollectionParameterAsserts[method]}.Using(comparer), $""Because of {{""message""}}""); + ", "using System.Collections;using System.Collections.Generic;"); + RoslynAssert.CodeFix(analyzer, fix, expectedDiagnostic, code, fixedCode); + } + + [TestCaseSource(nameof(TwoCollectionParameterAsserts))] + public void AnalyzeTwoCollectionWhenNoMessageArgumentsAreUsed(string method) + { + var code = TestUtility.WrapInTestMethod(@$" + var collection1 = new[] {{ 1, 2, 3 }}; + var collection2 = new[] {{ 2, 4, 6 }}; + ↓CollectionAssert.{method}(collection1, collection2); + "); + var fixedCode = TestUtility.WrapInTestMethod(@$" + var collection1 = new[] {{ 1, 2, 3 }}; + var collection2 = new[] {{ 2, 4, 6 }}; + Assert.That({GetAdjustedTwoCollectionConstraint(method)}); + "); + RoslynAssert.CodeFix(analyzer, fix, expectedDiagnostic, code, fixedCode); + } + + [TestCaseSource(nameof(TwoCollectionParameterAsserts))] + public void AnalyzeTwoCollectionWhenOnlyMessageArgumentsAreUsed(string method) + { + var code = TestUtility.WrapInTestMethod(@$" + var collection1 = new[] {{ 1, 2, 3 }}; + var collection2 = new[] {{ 2, 4, 6 }}; + ↓CollectionAssert.{method}(collection1, collection2, ""message""); + "); + var fixedCode = TestUtility.WrapInTestMethod(@$" + var collection1 = new[] {{ 1, 2, 3 }}; + var collection2 = new[] {{ 2, 4, 6 }}; + Assert.That({GetAdjustedTwoCollectionConstraint(method)}, ""message""); + "); + RoslynAssert.CodeFix(analyzer, fix, expectedDiagnostic, code, fixedCode); + } + + [TestCaseSource(nameof(TwoCollectionParameterAsserts))] + public void AnalyzeTwoCollectionWhenFormatAndParamsArgumentsAreUsed(string method) + { + var code = TestUtility.WrapInTestMethod(@$" + var collection1 = new[] {{ 1, 2, 3 }}; + var collection2 = new[] {{ 2, 4, 6 }}; + ↓CollectionAssert.{method}(collection1, collection2, ""Because of {{0}}"", ""message""); + "); + var fixedCode = TestUtility.WrapInTestMethod(@$" + var collection1 = new[] {{ 1, 2, 3 }}; + var collection2 = new[] {{ 2, 4, 6 }}; + Assert.That({GetAdjustedTwoCollectionConstraint(method)}, $""Because of {{""message""}}""); + "); + RoslynAssert.CodeFix(analyzer, fix, expectedDiagnostic, code, fixedCode); + } + + [TestCase(NUnitFrameworkConstants.NameOfCollectionAssertAreEqual)] + [TestCase(NUnitFrameworkConstants.NameOfCollectionAssertAreNotEqual)] + public void AnalyzeTwoCollectionWithComparerWhenFormatAndParamsArgumentsAreUsed(string method) + { + var code = TestUtility.WrapInTestMethod(@$" + var collection1 = new[] {{ 1, 2, 3 }}; + var collection2 = new[] {{ 2, 4, 6 }}; + IComparer comparer = Comparer.Default; + ↓CollectionAssert.{method}(collection1, collection2, comparer, ""Because of {{0}}"", ""message""); + ", "using System.Collections;using System.Collections.Generic;"); + var fixedCode = TestUtility.WrapInTestMethod(@$" + var collection1 = new[] {{ 1, 2, 3 }}; + var collection2 = new[] {{ 2, 4, 6 }}; + IComparer comparer = Comparer.Default; + Assert.That({GetAdjustedTwoCollectionConstraint(method).Replace(".AsCollection", ".Using(comparer)")}, $""Because of {{""message""}}""); + ", "using System.Collections;using System.Collections.Generic;"); + RoslynAssert.CodeFix(analyzer, fix, expectedDiagnostic, code, fixedCode); + } + + [TestCaseSource(nameof(CollectionAndItemParameterAsserts))] + public void AnalyzeCollectionAndItemWhenNoMessageArgumentsAreUsed(string method) + { + var code = TestUtility.WrapInTestMethod(@$" + var collection = new[] {{ typeof(byte), typeof(char) }}; + var expected = typeof(byte); + ↓CollectionAssert.{method}(collection, expected); + "); + var fixedCode = TestUtility.WrapInTestMethod(@$" + var collection = new[] {{ typeof(byte), typeof(char) }}; + var expected = typeof(byte); + Assert.That(collection, {CollectionAssertUsageAnalyzer.CollectionAndItemParameterAsserts[method]}); + "); + RoslynAssert.CodeFix(analyzer, fix, expectedDiagnostic, code, fixedCode); + } + + [TestCaseSource(nameof(CollectionAndItemParameterAsserts))] + public void AnalyzeCollectionAndItemWhenOnlyMessageArgumentsAreUsed(string method) + { + var code = TestUtility.WrapInTestMethod(@$" + var collection = new[] {{ typeof(byte), typeof(char) }}; + var expected = typeof(byte); + ↓CollectionAssert.{method}(collection, expected, ""message""); + "); + var fixedCode = TestUtility.WrapInTestMethod(@$" + var collection = new[] {{ typeof(byte), typeof(char) }}; + var expected = typeof(byte); + Assert.That(collection, {CollectionAssertUsageAnalyzer.CollectionAndItemParameterAsserts[method]}, ""message""); + "); + RoslynAssert.CodeFix(analyzer, fix, expectedDiagnostic, code, fixedCode); + } + + [TestCaseSource(nameof(CollectionAndItemParameterAsserts))] + public void AnalyzeCollectionAndItemWhenFormatAndParamsArgumentsAreUsed(string method) + { + var code = TestUtility.WrapInTestMethod(@$" + var collection = new[] {{ typeof(byte), typeof(char) }}; + var expected = typeof(byte); + ↓CollectionAssert.{method}(collection, expected, ""Because of {{0}}"", ""message""); + "); + var fixedCode = TestUtility.WrapInTestMethod(@$" + var collection = new[] {{ typeof(byte), typeof(char) }}; + var expected = typeof(byte); + Assert.That(collection, {CollectionAssertUsageAnalyzer.CollectionAndItemParameterAsserts[method]}, $""Because of {{""message""}}""); + "); + RoslynAssert.CodeFix(analyzer, fix, expectedDiagnostic, code, fixedCode); + } + + private static string GetAdjustedTwoCollectionConstraint(string method) + { + string actualArgument; + string constraintArgument; + + if (CollectionAssertUsageCodeFix.CollectionAssertToOneUnswappedParameterConstraints.ContainsKey(method)) + { + actualArgument = "collection1"; + constraintArgument = "collection2"; + } + else + { + actualArgument = "collection2"; + constraintArgument = "collection1"; + } + + string constraint = CollectionAssertUsageAnalyzer.TwoCollectionParameterAsserts[method] + .Replace("expected", constraintArgument); + return $"{actualArgument}, {constraint}"; + } + } +} diff --git a/src/nunit.analyzers.tests/ConstActualValueUsage/ConstActualValueUsageAnalyzerTests.cs b/src/nunit.analyzers.tests/ConstActualValueUsage/ConstActualValueUsageAnalyzerTests.cs index 51c2258b..4489f201 100644 --- a/src/nunit.analyzers.tests/ConstActualValueUsage/ConstActualValueUsageAnalyzerTests.cs +++ b/src/nunit.analyzers.tests/ConstActualValueUsage/ConstActualValueUsageAnalyzerTests.cs @@ -19,7 +19,7 @@ public void AnalyzeWhenLiteralArgumentIsProvidedForAreEqual() public void Test() { int expected = 5; - Assert.AreEqual(expected, ↓1); + ClassicAssert.AreEqual(expected, ↓1); }"); RoslynAssert.Diagnostics(analyzer, expectedDiagnostic, testCode); @@ -32,7 +32,7 @@ public void AnalyzeWhenLiteralNamedArgumentIsProvidedForAreEqual() public void Test() { int expected = 5; - Assert.AreEqual(actual: ↓1, expected: expected); + ClassicAssert.AreEqual(actual: ↓1, expected: expected); }"); RoslynAssert.Diagnostics(analyzer, expectedDiagnostic, testCode); @@ -59,7 +59,7 @@ public void Test() { const string actual = ""act""; string expected = ""exp""; - Assert.AreEqual(expected, ↓actual); + ClassicAssert.AreEqual(expected, ↓actual); }"); RoslynAssert.Diagnostics(analyzer, expectedDiagnostic, testCode); @@ -73,7 +73,7 @@ public void Test() { const string actual = ""act""; string expected = ""exp""; - Assert.AreEqual(actual: ↓actual, expected: expected); + ClassicAssert.AreEqual(actual: ↓actual, expected: expected); }"); RoslynAssert.Diagnostics(analyzer, expectedDiagnostic, testCode); @@ -104,7 +104,7 @@ public class TestFixture public void Test() { string expected = ""exp""; - Assert.AreEqual(expected, ↓actual); + ClassicAssert.AreEqual(expected, ↓actual); } }"); @@ -136,7 +136,7 @@ public void AnalyzeWhenStringEmptyArgumentIsProvidedForAreEqual() public void Test() { string actual = ""act""; - Assert.AreEqual(actual, string.Empty); + ClassicAssert.AreEqual(actual, string.Empty); }"); RoslynAssert.Diagnostics(analyzer, expectedDiagnostic, testCode); @@ -166,7 +166,7 @@ public class TestFixture public void Test() { string actual = ""act""; - Assert.AreEqual(expected, actual); + ClassicAssert.AreEqual(expected, actual); } }"); @@ -184,7 +184,7 @@ public class TestFixture public void Test() { const string actual = ""act""; - Assert.AreEqual(expected, actual); + ClassicAssert.AreEqual(expected, actual); } }"); @@ -202,7 +202,7 @@ public class TestFixture public void Test() { string actual = ""act""; - Assert.AreEqual(actual: actual, expected: expected); + ClassicAssert.AreEqual(actual: actual, expected: expected); } }"); @@ -220,7 +220,7 @@ public class TestFixture public void Test() { const string actual = ""act""; - Assert.AreEqual(actual: actual, expected: expected); + ClassicAssert.AreEqual(actual: actual, expected: expected); } }"); diff --git a/src/nunit.analyzers.tests/ConstActualValueUsage/ConstActualValueUsageCodeFixTests.cs b/src/nunit.analyzers.tests/ConstActualValueUsage/ConstActualValueUsageCodeFixTests.cs index e99e3e7b..24ecc21d 100644 --- a/src/nunit.analyzers.tests/ConstActualValueUsage/ConstActualValueUsageCodeFixTests.cs +++ b/src/nunit.analyzers.tests/ConstActualValueUsage/ConstActualValueUsageCodeFixTests.cs @@ -6,6 +6,12 @@ using NUnit.Framework; using NUnit.Framework.Internal; +#if NUNIT4 +using NUnit.Framework.Legacy; +#else +using ClassicAssert = NUnit.Framework.Assert; +#endif + namespace NUnit.Analyzers.Tests.ConstActualValueUsage { public class ConstActualValueUsageCodeFixTests @@ -15,24 +21,24 @@ public class ConstActualValueUsageCodeFixTests private static readonly ExpectedDiagnostic expectedDiagnostic = ExpectedDiagnostic.Create(AnalyzerIdentifiers.ConstActualValueUsage); - [TestCase(nameof(Assert.AreEqual))] - [TestCase(nameof(Assert.AreNotEqual))] - [TestCase(nameof(Assert.AreSame))] - [TestCase(nameof(Assert.AreNotSame))] + [TestCase(nameof(ClassicAssert.AreEqual))] + [TestCase(nameof(ClassicAssert.AreNotEqual))] + [TestCase(nameof(ClassicAssert.AreSame))] + [TestCase(nameof(ClassicAssert.AreNotSame))] public void LiteralArgumentIsProvidedForClassicAssertCodeFix(string classicAssertMethod) { var code = TestUtility.WrapMethodInClassNamespaceAndAddUsings($@" public void Test() {{ int expected = 5; - Assert.{classicAssertMethod}(expected, ↓1); + ClassicAssert.{classicAssertMethod}(expected, ↓1); }}"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings($@" public void Test() {{ int expected = 5; - Assert.{classicAssertMethod}(1, expected); + ClassicAssert.{classicAssertMethod}(1, expected); }}"); RoslynAssert.CodeFix(analyzer, fix, expectedDiagnostic, code, fixedCode, @@ -46,14 +52,14 @@ public void LiteralNamedArgumentIsProvidedForAreEqualCodeFix() public void Test() { int expected = 5; - Assert.AreEqual(actual: ↓1, expected: expected); + ClassicAssert.AreEqual(actual: ↓1, expected: expected); }"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" public void Test() { int expected = 5; - Assert.AreEqual(actual: expected, expected: 1); + ClassicAssert.AreEqual(actual: expected, expected: 1); }"); RoslynAssert.CodeFix(analyzer, fix, expectedDiagnostic, code, fixedCode, diff --git a/src/nunit.analyzers.tests/Constants/NUnitFrameworkConstantsTests.cs b/src/nunit.analyzers.tests/Constants/NUnitFrameworkConstantsTests.cs index 208db289..0fed2337 100644 --- a/src/nunit.analyzers.tests/Constants/NUnitFrameworkConstantsTests.cs +++ b/src/nunit.analyzers.tests/Constants/NUnitFrameworkConstantsTests.cs @@ -8,6 +8,12 @@ using NUnit.Framework.Interfaces; using NUnit.Framework.Internal; +#if NUNIT4 +using NUnit.Framework.Legacy; +#else +using ClassicAssert = NUnit.Framework.Assert; +#endif + namespace NUnit.Analyzers.Tests.Constants { /// @@ -19,7 +25,6 @@ public sealed class NUnitFrameworkConstantsTests { private static readonly (string Constant, string TypeName)[] NameOfSource = new (string Constant, string TypeName)[] { - (nameof(NUnitFrameworkConstants.NameOfEqualConstraintWithin), nameof(EqualConstraint.Within)), (nameof(NUnitFrameworkConstants.NameOfIs), nameof(Is)), (nameof(NUnitFrameworkConstants.NameOfIsFalse), nameof(Is.False)), (nameof(NUnitFrameworkConstants.NameOfIsTrue), nameof(Is.True)), @@ -28,10 +33,9 @@ public sealed class NUnitFrameworkConstantsTests (nameof(NUnitFrameworkConstants.NameOfIsSubsetOf), nameof(Is.SubsetOf)), (nameof(NUnitFrameworkConstants.NameOfIsSupersetOf), nameof(Is.SupersetOf)), (nameof(NUnitFrameworkConstants.NameOfIsNot), nameof(Is.Not)), - (nameof(NUnitFrameworkConstants.NameOfIsNotEqualTo), nameof(Is.Not.EqualTo)), (nameof(NUnitFrameworkConstants.NameOfIsSameAs), nameof(Is.SameAs)), (nameof(NUnitFrameworkConstants.NameOfIsSamePath), nameof(Is.SamePath)), - (nameof(NUnitFrameworkConstants.NameOfNull), nameof(Is.Null)), + (nameof(NUnitFrameworkConstants.NameOfIsNull), nameof(Is.Null)), (nameof(NUnitFrameworkConstants.NameOfIsGreaterThan), nameof(Is.GreaterThan)), (nameof(NUnitFrameworkConstants.NameOfIsGreaterThanOrEqualTo), nameof(Is.GreaterThanOrEqualTo)), (nameof(NUnitFrameworkConstants.NameOfIsLessThan), nameof(Is.LessThan)), @@ -41,6 +45,9 @@ public sealed class NUnitFrameworkConstantsTests (nameof(NUnitFrameworkConstants.NameOfIsNaN), nameof(Is.NaN)), (nameof(NUnitFrameworkConstants.NameOfIsEmpty), nameof(Is.Empty)), (nameof(NUnitFrameworkConstants.NameOfIsInstanceOf), nameof(Is.InstanceOf)), + (nameof(NUnitFrameworkConstants.NameOfIsAll), nameof(Is.All)), + (nameof(NUnitFrameworkConstants.NameOfIsUnique), nameof(Is.Unique)), + (nameof(NUnitFrameworkConstants.NameOfIsOrdered), nameof(Is.Ordered)), (nameof(NUnitFrameworkConstants.NameOfContains), nameof(Contains)), (nameof(NUnitFrameworkConstants.NameOfContainsItem), nameof(Contains.Item)), @@ -50,6 +57,7 @@ public sealed class NUnitFrameworkConstantsTests (nameof(NUnitFrameworkConstants.NameOfDoesContain), nameof(Does.Contain)), (nameof(NUnitFrameworkConstants.NameOfDoesStartWith), nameof(Does.StartWith)), (nameof(NUnitFrameworkConstants.NameOfDoesEndWith), nameof(Does.EndWith)), + (nameof(NUnitFrameworkConstants.NameOfDoesMatch), nameof(Does.Match)), (nameof(NUnitFrameworkConstants.NameOfHas), nameof(Has)), (nameof(NUnitFrameworkConstants.NameOfHasProperty), nameof(Has.Property)), @@ -58,6 +66,7 @@ public sealed class NUnitFrameworkConstantsTests (nameof(NUnitFrameworkConstants.NameOfHasMessage), nameof(Has.Message)), (nameof(NUnitFrameworkConstants.NameOfHasInnerException), nameof(Has.InnerException)), (nameof(NUnitFrameworkConstants.NameOfHasNo), nameof(Has.No)), + (nameof(NUnitFrameworkConstants.NameOfHasMember), nameof(Has.Member)), (nameof(NUnitFrameworkConstants.NameOfMultiple), nameof(Assert.Multiple)), @@ -68,31 +77,38 @@ public sealed class NUnitFrameworkConstantsTests (nameof(NUnitFrameworkConstants.NameOfThrowsTargetInvocationException), nameof(Throws.TargetInvocationException)), (nameof(NUnitFrameworkConstants.NameOfAssert), nameof(Assert)), - (nameof(NUnitFrameworkConstants.NameOfAssertIsTrue), nameof(Assert.IsTrue)), - (nameof(NUnitFrameworkConstants.NameOfAssertTrue), nameof(Assert.True)), - (nameof(NUnitFrameworkConstants.NameOfAssertIsFalse), nameof(Assert.IsFalse)), - (nameof(NUnitFrameworkConstants.NameOfAssertFalse), nameof(Assert.False)), - (nameof(NUnitFrameworkConstants.NameOfAssertAreEqual), nameof(Assert.AreEqual)), - (nameof(NUnitFrameworkConstants.NameOfAssertAreNotEqual), nameof(Assert.AreNotEqual)), - (nameof(NUnitFrameworkConstants.NameOfAssertAreSame), nameof(Assert.AreSame)), - (nameof(NUnitFrameworkConstants.NameOfAssertAreNotSame), nameof(Assert.AreNotSame)), - (nameof(NUnitFrameworkConstants.NameOfAssertNull), nameof(Assert.Null)), - (nameof(NUnitFrameworkConstants.NameOfAssertIsNull), nameof(Assert.IsNull)), - (nameof(NUnitFrameworkConstants.NameOfAssertIsNotNull), nameof(Assert.IsNotNull)), - (nameof(NUnitFrameworkConstants.NameOfAssertNotNull), nameof(Assert.NotNull)), - (nameof(NUnitFrameworkConstants.NameOfAssertThat), nameof(Assert.That)), - (nameof(NUnitFrameworkConstants.NameOfAssertGreater), nameof(Assert.Greater)), - (nameof(NUnitFrameworkConstants.NameOfAssertGreaterOrEqual), nameof(Assert.GreaterOrEqual)), - (nameof(NUnitFrameworkConstants.NameOfAssertLess), nameof(Assert.Less)), - (nameof(NUnitFrameworkConstants.NameOfAssertLessOrEqual), nameof(Assert.LessOrEqual)), - (nameof(NUnitFrameworkConstants.NameOfAssertZero), nameof(Assert.Zero)), - (nameof(NUnitFrameworkConstants.NameOfAssertNotZero), nameof(Assert.NotZero)), - (nameof(NUnitFrameworkConstants.NameOfAssertIsNaN), nameof(Assert.IsNaN)), - (nameof(NUnitFrameworkConstants.NameOfAssertIsEmpty), nameof(Assert.IsEmpty)), - (nameof(NUnitFrameworkConstants.NameOfAssertIsNotEmpty), nameof(Assert.IsNotEmpty)), - (nameof(NUnitFrameworkConstants.NameOfAssertContains), nameof(Assert.Contains)), - (nameof(NUnitFrameworkConstants.NameOfAssertIsInstanceOf), nameof(Assert.IsInstanceOf)), - (nameof(NUnitFrameworkConstants.NameOfAssertIsNotInstanceOf), nameof(Assert.IsNotInstanceOf)), + + (nameof(NUnitFrameworkConstants.NameOfAssertPass), nameof(Assert.Pass)), + (nameof(NUnitFrameworkConstants.NameOfAssertFail), nameof(Assert.Fail)), + (nameof(NUnitFrameworkConstants.NameOfAssertWarn), nameof(Assert.Warn)), + (nameof(NUnitFrameworkConstants.NameOfAssertIgnore), nameof(Assert.Ignore)), + (nameof(NUnitFrameworkConstants.NameOfAssertInconclusive), nameof(Assert.Inconclusive)), + + (nameof(NUnitFrameworkConstants.NameOfAssertIsTrue), nameof(ClassicAssert.IsTrue)), + (nameof(NUnitFrameworkConstants.NameOfAssertTrue), nameof(ClassicAssert.True)), + (nameof(NUnitFrameworkConstants.NameOfAssertIsFalse), nameof(ClassicAssert.IsFalse)), + (nameof(NUnitFrameworkConstants.NameOfAssertFalse), nameof(ClassicAssert.False)), + (nameof(NUnitFrameworkConstants.NameOfAssertAreEqual), nameof(ClassicAssert.AreEqual)), + (nameof(NUnitFrameworkConstants.NameOfAssertAreNotEqual), nameof(ClassicAssert.AreNotEqual)), + (nameof(NUnitFrameworkConstants.NameOfAssertAreSame), nameof(ClassicAssert.AreSame)), + (nameof(NUnitFrameworkConstants.NameOfAssertAreNotSame), nameof(ClassicAssert.AreNotSame)), + (nameof(NUnitFrameworkConstants.NameOfAssertNull), nameof(ClassicAssert.Null)), + (nameof(NUnitFrameworkConstants.NameOfAssertIsNull), nameof(ClassicAssert.IsNull)), + (nameof(NUnitFrameworkConstants.NameOfAssertIsNotNull), nameof(ClassicAssert.IsNotNull)), + (nameof(NUnitFrameworkConstants.NameOfAssertNotNull), nameof(ClassicAssert.NotNull)), + (nameof(NUnitFrameworkConstants.NameOfAssertThat), nameof(ClassicAssert.That)), + (nameof(NUnitFrameworkConstants.NameOfAssertGreater), nameof(ClassicAssert.Greater)), + (nameof(NUnitFrameworkConstants.NameOfAssertGreaterOrEqual), nameof(ClassicAssert.GreaterOrEqual)), + (nameof(NUnitFrameworkConstants.NameOfAssertLess), nameof(ClassicAssert.Less)), + (nameof(NUnitFrameworkConstants.NameOfAssertLessOrEqual), nameof(ClassicAssert.LessOrEqual)), + (nameof(NUnitFrameworkConstants.NameOfAssertZero), nameof(ClassicAssert.Zero)), + (nameof(NUnitFrameworkConstants.NameOfAssertNotZero), nameof(ClassicAssert.NotZero)), + (nameof(NUnitFrameworkConstants.NameOfAssertIsNaN), nameof(ClassicAssert.IsNaN)), + (nameof(NUnitFrameworkConstants.NameOfAssertIsEmpty), nameof(ClassicAssert.IsEmpty)), + (nameof(NUnitFrameworkConstants.NameOfAssertIsNotEmpty), nameof(ClassicAssert.IsNotEmpty)), + (nameof(NUnitFrameworkConstants.NameOfAssertContains), nameof(ClassicAssert.Contains)), + (nameof(NUnitFrameworkConstants.NameOfAssertIsInstanceOf), nameof(ClassicAssert.IsInstanceOf)), + (nameof(NUnitFrameworkConstants.NameOfAssertIsNotInstanceOf), nameof(ClassicAssert.IsNotInstanceOf)), (nameof(NUnitFrameworkConstants.NameOfAssertCatch), nameof(Assert.Catch)), (nameof(NUnitFrameworkConstants.NameOfAssertCatchAsync), nameof(Assert.CatchAsync)), @@ -100,16 +116,34 @@ public sealed class NUnitFrameworkConstantsTests (nameof(NUnitFrameworkConstants.NameOfAssertThrowsAsync), nameof(Assert.ThrowsAsync)), (nameof(NUnitFrameworkConstants.NameOfStringAssert), nameof(StringAssert)), - (nameof(NUnitFrameworkConstants.NameOfStringAssertAreEqualIgnoringCase), nameof(StringAssert.AreEqualIgnoringCase)), - (nameof(NUnitFrameworkConstants.NameOfStringAssertAreNotEqualIgnoringCase), nameof(StringAssert.AreNotEqualIgnoringCase)), (nameof(NUnitFrameworkConstants.NameOfStringAssertContains), nameof(StringAssert.Contains)), (nameof(NUnitFrameworkConstants.NameOfStringAssertDoesNotContain), nameof(StringAssert.DoesNotContain)), - (nameof(NUnitFrameworkConstants.NameOfStringAssertDoesNotEndWith), nameof(StringAssert.DoesNotEndWith)), - (nameof(NUnitFrameworkConstants.NameOfStringAssertDoesNotMatch), nameof(StringAssert.DoesNotMatch)), + (nameof(NUnitFrameworkConstants.NameOfStringAssertStartsWith), nameof(StringAssert.StartsWith)), (nameof(NUnitFrameworkConstants.NameOfStringAssertDoesNotStartWith), nameof(StringAssert.DoesNotStartWith)), (nameof(NUnitFrameworkConstants.NameOfStringAssertEndsWith), nameof(StringAssert.EndsWith)), + (nameof(NUnitFrameworkConstants.NameOfStringAssertDoesNotEndWith), nameof(StringAssert.DoesNotEndWith)), + (nameof(NUnitFrameworkConstants.NameOfStringAssertAreEqualIgnoringCase), nameof(StringAssert.AreEqualIgnoringCase)), + (nameof(NUnitFrameworkConstants.NameOfStringAssertAreNotEqualIgnoringCase), nameof(StringAssert.AreNotEqualIgnoringCase)), (nameof(NUnitFrameworkConstants.NameOfStringAssertIsMatch), nameof(StringAssert.IsMatch)), - (nameof(NUnitFrameworkConstants.NameOfStringAssertStartsWith), nameof(StringAssert.StartsWith)), + (nameof(NUnitFrameworkConstants.NameOfStringAssertDoesNotMatch), nameof(StringAssert.DoesNotMatch)), + + (nameof(NUnitFrameworkConstants.NameOfCollectionAssert), nameof(CollectionAssert)), + (nameof(NUnitFrameworkConstants.NameOfCollectionAssertAllItemsAreInstancesOfType), nameof(CollectionAssert.AllItemsAreInstancesOfType)), + (nameof(NUnitFrameworkConstants.NameOfCollectionAssertAllItemsAreNotNull), nameof(CollectionAssert.AllItemsAreNotNull)), + (nameof(NUnitFrameworkConstants.NameOfCollectionAssertAllItemsAreUnique), nameof(CollectionAssert.AllItemsAreUnique)), + (nameof(NUnitFrameworkConstants.NameOfCollectionAssertAreEqual), nameof(CollectionAssert.AreEqual)), + (nameof(NUnitFrameworkConstants.NameOfCollectionAssertAreEquivalent), nameof(CollectionAssert.AreEquivalent)), + (nameof(NUnitFrameworkConstants.NameOfCollectionAssertAreNotEqual), nameof(CollectionAssert.AreNotEqual)), + (nameof(NUnitFrameworkConstants.NameOfCollectionAssertAreNotEquivalent), nameof(CollectionAssert.AreNotEquivalent)), + (nameof(NUnitFrameworkConstants.NameOfCollectionAssertContains), nameof(CollectionAssert.Contains)), + (nameof(NUnitFrameworkConstants.NameOfCollectionAssertDoesNotContain), nameof(CollectionAssert.DoesNotContain)), + (nameof(NUnitFrameworkConstants.NameOfCollectionAssertIsNotSubsetOf), nameof(CollectionAssert.IsNotSubsetOf)), + (nameof(NUnitFrameworkConstants.NameOfCollectionAssertIsSubsetOf), nameof(CollectionAssert.IsSubsetOf)), + (nameof(NUnitFrameworkConstants.NameOfCollectionAssertIsNotSupersetOf), nameof(CollectionAssert.IsNotSupersetOf)), + (nameof(NUnitFrameworkConstants.NameOfCollectionAssertIsSupersetOf), nameof(CollectionAssert.IsSupersetOf)), + (nameof(NUnitFrameworkConstants.NameOfCollectionAssertIsEmpty), nameof(CollectionAssert.IsEmpty)), + (nameof(NUnitFrameworkConstants.NameOfCollectionAssertIsNotEmpty), nameof(CollectionAssert.IsNotEmpty)), + (nameof(NUnitFrameworkConstants.NameOfCollectionAssertIsOrdered), nameof(CollectionAssert.IsOrdered)), (nameof(NUnitFrameworkConstants.NameOfConstraint), nameof(Constraint)), @@ -131,8 +165,12 @@ public sealed class NUnitFrameworkConstantsTests (nameof(NUnitFrameworkConstants.NameOfConstraintExpressionOr), nameof(EqualConstraint.Or)), (nameof(NUnitFrameworkConstants.NameOfConstraintExpressionWith), nameof(ConstraintExpression.With)), - (nameof(NUnitFrameworkConstants.NameOfIgnoreCase), nameof(EqualConstraint.IgnoreCase)), - (nameof(NUnitFrameworkConstants.NameOfUsing), nameof(EqualConstraint.Using)), + (nameof(NUnitFrameworkConstants.NameOfEqualConstraintIgnoreCase), nameof(EqualConstraint.IgnoreCase)), + (nameof(NUnitFrameworkConstants.NameOfEqualConstraintUsing), nameof(EqualConstraint.Using)), + (nameof(NUnitFrameworkConstants.NameOfEqualConstraintWithin), nameof(EqualConstraint.Within)), + (nameof(NUnitFrameworkConstants.NameOfEqualConstraintAsCollection), nameof(EqualConstraint.AsCollection)), + + (nameof(NUnitFrameworkConstants.NameOfClassicAssert), "ClassicAssert"), }; private static readonly (string Constant, Type Type)[] FullNameOfTypeSource = new (string Constant, Type Type)[] @@ -191,8 +229,8 @@ public void TestFullNameOfConstants((string Constant, Type Type) pair) [Test] public void NameOfAssertAreEqualParameters() { - var parameters = typeof(Assert).GetMethods() - .First(m => m.Name == nameof(Assert.AreEqual)) + var parameters = typeof(ClassicAssert).GetMethods() + .First(m => m.Name == nameof(ClassicAssert.AreEqual)) .GetParameters(); var parameterNames = parameters.Select(p => p.Name); @@ -215,14 +253,14 @@ public void NameOfAssertThatParameters() Assert.That(parameterNames, Does.Contain(NUnitFrameworkConstants.NameOfConditionParameter)); } - [TestCase(nameof(Assert.True))] - [TestCase(nameof(Assert.IsTrue))] - [TestCase(nameof(Assert.False))] - [TestCase(nameof(Assert.IsFalse))] - [TestCase(nameof(Assert.IsTrue))] + [TestCase(nameof(ClassicAssert.True))] + [TestCase(nameof(ClassicAssert.IsTrue))] + [TestCase(nameof(ClassicAssert.False))] + [TestCase(nameof(ClassicAssert.IsFalse))] + [TestCase(nameof(ClassicAssert.IsTrue))] public void NameOfAssertConditionParameters(string method) { - var parameters = typeof(Assert).GetMethods() + var parameters = typeof(ClassicAssert).GetMethods() .First(m => m.Name == method) .GetParameters(); var parameterNames = parameters.Select(p => p.Name); @@ -241,6 +279,20 @@ public void NUnitAssemblyNameTest() #pragma warning restore NUnit2007 // The actual value should not be a constant } + [Test] + public void NUnitLegacyAssemblyNameTest() + { + // We are testing that the value of the constant is correct +#pragma warning disable NUnit2007 // The actual value should not be a constant +#if NUNIT4 + Assert.That(NUnitFrameworkConstants.NUnitFrameworkLegacyAssemblyName, +#else + Assert.That(NUnitFrameworkConstants.NUnitFrameworkAssemblyName, +#endif + Is.EqualTo(typeof(ClassicAssert).Assembly.GetName().Name)); +#pragma warning restore NUnit2007 // The actual value should not be a constant + } + [Test] public void EnsureAllNameOfDefinitionsAreTested() { diff --git a/src/nunit.analyzers.tests/ConstraintsUsage/ComparisonConstraintUsageCodeFixTests.cs b/src/nunit.analyzers.tests/ConstraintsUsage/ComparisonConstraintUsageCodeFixTests.cs index f59d1021..232872b0 100644 --- a/src/nunit.analyzers.tests/ConstraintsUsage/ComparisonConstraintUsageCodeFixTests.cs +++ b/src/nunit.analyzers.tests/ConstraintsUsage/ComparisonConstraintUsageCodeFixTests.cs @@ -20,12 +20,12 @@ public class ComparisonConstraintUsageCodeFixTests public void FixesComparisonOperator(string operatorToken, string constraint) { var code = TestUtility.WrapInTestMethod(@$" - int actual = 5; - Assert.That(↓actual {operatorToken} 9);"); + int actual = 5; + Assert.That(↓actual {operatorToken} 9);"); var fixedCode = TestUtility.WrapInTestMethod(@$" - int actual = 5; - Assert.That(actual, {constraint}(9));"); + int actual = 5; + Assert.That(actual, {constraint}(9));"); var diagnostic = ExpectedDiagnostic.Create(AnalyzerIdentifiers.ComparisonConstraintUsage, string.Format(CultureInfo.InvariantCulture, ComparisonConstraintUsageConstants.Message, constraint)); @@ -40,12 +40,12 @@ public void FixesComparisonOperator(string operatorToken, string constraint) public void FixesComparisonOperatorWithIsTrue(string operatorToken, string constraint) { var code = TestUtility.WrapInTestMethod(@$" - int actual = 5; - Assert.That(↓actual {operatorToken} 9, Is.True);"); + int actual = 5; + Assert.That(↓actual {operatorToken} 9, Is.True);"); var fixedCode = TestUtility.WrapInTestMethod(@$" - int actual = 5; - Assert.That(actual, {constraint}(9));"); + int actual = 5; + Assert.That(actual, {constraint}(9));"); var diagnostic = ExpectedDiagnostic.Create(AnalyzerIdentifiers.ComparisonConstraintUsage, string.Format(CultureInfo.InvariantCulture, ComparisonConstraintUsageConstants.Message, constraint)); @@ -60,12 +60,12 @@ public void FixesComparisonOperatorWithIsTrue(string operatorToken, string const public void FixesWhenComparisonOperatorUsedWithIsFalse(string operatorToken, string constraint) { var code = TestUtility.WrapInTestMethod(@$" - int actual = 5; - Assert.That(↓actual {operatorToken} 9, Is.False);"); + int actual = 5; + Assert.That(↓actual {operatorToken} 9, Is.False);"); var fixedCode = TestUtility.WrapInTestMethod(@$" - int actual = 5; - Assert.That(actual, {constraint}(9));"); + int actual = 5; + Assert.That(actual, {constraint}(9));"); var diagnostic = ExpectedDiagnostic.Create(AnalyzerIdentifiers.ComparisonConstraintUsage, string.Format(CultureInfo.InvariantCulture, ComparisonConstraintUsageConstants.Message, constraint)); @@ -80,12 +80,12 @@ public void FixesWhenComparisonOperatorUsedWithIsFalse(string operatorToken, str public void FixesWhenComparisonOperatorUseConstantOnLeftHandSide(string operatorToken, string constraint) { var code = TestUtility.WrapInTestMethod(@$" - int actual = 5; - Assert.That(↓9 {operatorToken} actual, Is.True);"); + int actual = 5; + Assert.That(↓9 {operatorToken} actual, Is.True);"); var fixedCode = TestUtility.WrapInTestMethod(@$" - int actual = 5; - Assert.That(actual, {constraint}(9));"); + int actual = 5; + Assert.That(actual, {constraint}(9));"); var diagnostic = ExpectedDiagnostic.Create(AnalyzerIdentifiers.ComparisonConstraintUsage, string.Format(CultureInfo.InvariantCulture, ComparisonConstraintUsageConstants.Message, constraint)); diff --git a/src/nunit.analyzers.tests/ConstraintsUsage/EqualConstraintUsageAnalyzerTests.cs b/src/nunit.analyzers.tests/ConstraintsUsage/EqualConstraintUsageAnalyzerTests.cs index d3e4155b..df963251 100644 --- a/src/nunit.analyzers.tests/ConstraintsUsage/EqualConstraintUsageAnalyzerTests.cs +++ b/src/nunit.analyzers.tests/ConstraintsUsage/EqualConstraintUsageAnalyzerTests.cs @@ -106,7 +106,7 @@ public void AnalyzeWhenEqualsMethodUsedWithAssertTrue() { var testCode = TestUtility.WrapInTestMethod(@" var actual = ""abc""; - Assert.True(↓actual.Equals(""abc""));"); + ClassicAssert.True(↓actual.Equals(""abc""));"); RoslynAssert.Diagnostics(analyzer, isEqualToDiagnostic, testCode); } @@ -116,7 +116,7 @@ public void AnalyzeWhenEqualsMethodUsedWithAssertFalse() { var testCode = TestUtility.WrapInTestMethod(@" var actual = ""abc""; - Assert.False(↓actual.Equals(""bcd""));"); + ClassicAssert.False(↓actual.Equals(""bcd""));"); RoslynAssert.Diagnostics(analyzer, isNotEqualToDiagnostic, testCode); } @@ -126,7 +126,7 @@ public void AnalyzeWhenEqualsMethodUsedWithAssertIsTrue() { var testCode = TestUtility.WrapInTestMethod(@" var actual = ""abc""; - Assert.IsTrue(↓actual.Equals(""abc""));"); + ClassicAssert.IsTrue(↓actual.Equals(""abc""));"); RoslynAssert.Diagnostics(analyzer, isEqualToDiagnostic, testCode); } @@ -136,7 +136,7 @@ public void AnalyzeWhenEqualsMethodUsedWithAssertIsFalse() { var testCode = TestUtility.WrapInTestMethod(@" var actual = ""abc""; - Assert.IsFalse(↓actual.Equals(""bcd""));"); + ClassicAssert.IsFalse(↓actual.Equals(""bcd""));"); RoslynAssert.Diagnostics(analyzer, isNotEqualToDiagnostic, testCode); } @@ -146,7 +146,7 @@ public void AnalyzeDoubleNegationAsPositive() { var testCode = TestUtility.WrapInTestMethod(@" var actual = ""abc""; - Assert.IsFalse(↓!actual.Equals(""bcd""));"); + ClassicAssert.IsFalse(↓!actual.Equals(""bcd""));"); RoslynAssert.Diagnostics(analyzer, isEqualToDiagnostic, testCode); } @@ -176,7 +176,7 @@ public void AnalyzeWhenEqualsMethodUsedWithAssertTrueWithMessage() { var testCode = TestUtility.WrapInTestMethod(@" var actual = ""abc""; - Assert.True(↓actual.Equals(""abc""), ""Assertion message"");"); + ClassicAssert.True(↓actual.Equals(""abc""), ""Assertion message"");"); RoslynAssert.Diagnostics(analyzer, isEqualToDiagnostic, testCode); } @@ -186,7 +186,7 @@ public void AnalyzeWhenEqualsMethodUsedWithAssertFalseWithMessage() { var testCode = TestUtility.WrapInTestMethod(@" var actual = ""abc""; - Assert.False(↓actual.Equals(""bcd""), ""Assertion message"");"); + ClassicAssert.False(↓actual.Equals(""bcd""), ""Assertion message"");"); RoslynAssert.Diagnostics(analyzer, isNotEqualToDiagnostic, testCode); } diff --git a/src/nunit.analyzers.tests/ConstraintsUsage/EqualConstraintUsageCodeFixTests.cs b/src/nunit.analyzers.tests/ConstraintsUsage/EqualConstraintUsageCodeFixTests.cs index 4ec117c9..e9db73a5 100644 --- a/src/nunit.analyzers.tests/ConstraintsUsage/EqualConstraintUsageCodeFixTests.cs +++ b/src/nunit.analyzers.tests/ConstraintsUsage/EqualConstraintUsageCodeFixTests.cs @@ -17,12 +17,12 @@ public class EqualConstraintUsageCodeFixTests public void FixesEqualsOperator() { var code = TestUtility.WrapInTestMethod(@" - var actual = ""abc""; - Assert.That(actual == ""abc"");"); + var actual = ""abc""; + Assert.That(actual == ""abc"");"); var fixedCode = TestUtility.WrapInTestMethod(@" - var actual = ""abc""; - Assert.That(actual, Is.EqualTo(""abc""));"); + var actual = ""abc""; + Assert.That(actual, Is.EqualTo(""abc""));"); RoslynAssert.CodeFix(analyzer, fix, equalConstraintDiagnostic, code, fixedCode); } @@ -31,12 +31,12 @@ public void FixesEqualsOperator() public void FixesNotEqualsOperator() { var code = TestUtility.WrapInTestMethod(@" - var actual = ""abc""; - Assert.That(actual != ""abc"");"); + var actual = ""abc""; + Assert.That(actual != ""abc"");"); var fixedCode = TestUtility.WrapInTestMethod(@" - var actual = ""abc""; - Assert.That(actual, Is.Not.EqualTo(""abc""));"); + var actual = ""abc""; + Assert.That(actual, Is.Not.EqualTo(""abc""));"); RoslynAssert.CodeFix(analyzer, fix, equalConstraintDiagnostic, code, fixedCode); } @@ -45,12 +45,12 @@ public void FixesNotEqualsOperator() public void FixesEqualsInstanceMethod() { var code = TestUtility.WrapInTestMethod(@" - var actual = ""abc""; - Assert.That(actual.Equals(""abc""));"); + var actual = ""abc""; + Assert.That(actual.Equals(""abc""));"); var fixedCode = TestUtility.WrapInTestMethod(@" - var actual = ""abc""; - Assert.That(actual, Is.EqualTo(""abc""));"); + var actual = ""abc""; + Assert.That(actual, Is.EqualTo(""abc""));"); RoslynAssert.CodeFix(analyzer, fix, equalConstraintDiagnostic, code, fixedCode); } @@ -59,12 +59,12 @@ public void FixesEqualsInstanceMethod() public void FixesNegatedEqualsInstanceMethod() { var code = TestUtility.WrapInTestMethod(@" - var actual = ""abc""; - Assert.That(!actual.Equals(""bcd""));"); + var actual = ""abc""; + Assert.That(!actual.Equals(""bcd""));"); var fixedCode = TestUtility.WrapInTestMethod(@" - var actual = ""abc""; - Assert.That(actual, Is.Not.EqualTo(""bcd""));"); + var actual = ""abc""; + Assert.That(actual, Is.Not.EqualTo(""bcd""));"); RoslynAssert.CodeFix(analyzer, fix, equalConstraintDiagnostic, code, fixedCode); } @@ -73,12 +73,12 @@ public void FixesNegatedEqualsInstanceMethod() public void FixesEqualsStaticMethod() { var code = TestUtility.WrapInTestMethod(@" - var actual = ""abc""; - Assert.That(Equals(actual,""abc""));"); + var actual = ""abc""; + Assert.That(Equals(actual,""abc""));"); var fixedCode = TestUtility.WrapInTestMethod(@" - var actual = ""abc""; - Assert.That(actual, Is.EqualTo(""abc""));"); + var actual = ""abc""; + Assert.That(actual, Is.EqualTo(""abc""));"); RoslynAssert.CodeFix(analyzer, fix, equalConstraintDiagnostic, code, fixedCode); } @@ -87,12 +87,12 @@ public void FixesEqualsStaticMethod() public void FixesNegatedEqualsStaticMethod() { var code = TestUtility.WrapInTestMethod(@" - var actual = ""abc""; - Assert.That(!Equals(actual,""bcd""));"); + var actual = ""abc""; + Assert.That(!Equals(actual,""bcd""));"); var fixedCode = TestUtility.WrapInTestMethod(@" - var actual = ""abc""; - Assert.That(actual, Is.Not.EqualTo(""bcd""));"); + var actual = ""abc""; + Assert.That(actual, Is.Not.EqualTo(""bcd""));"); RoslynAssert.CodeFix(analyzer, fix, equalConstraintDiagnostic, code, fixedCode); } @@ -101,12 +101,12 @@ public void FixesNegatedEqualsStaticMethod() public void FixesEqualsMethodWithIsTrue() { var code = TestUtility.WrapInTestMethod(@" - var actual = ""abc""; - Assert.That(actual.Equals(""abc""), Is.True);"); + var actual = ""abc""; + Assert.That(actual.Equals(""abc""), Is.True);"); var fixedCode = TestUtility.WrapInTestMethod(@" - var actual = ""abc""; - Assert.That(actual, Is.EqualTo(""abc""));"); + var actual = ""abc""; + Assert.That(actual, Is.EqualTo(""abc""));"); RoslynAssert.CodeFix(analyzer, fix, equalConstraintDiagnostic, code, fixedCode); } @@ -115,12 +115,12 @@ public void FixesEqualsMethodWithIsTrue() public void FixesEqualsMethodWithIsFalse() { var code = TestUtility.WrapInTestMethod(@" - var actual = ""abc""; - Assert.That(actual.Equals(""bcd""), Is.False);"); + var actual = ""abc""; + Assert.That(actual.Equals(""bcd""), Is.False);"); var fixedCode = TestUtility.WrapInTestMethod(@" - var actual = ""abc""; - Assert.That(actual, Is.Not.EqualTo(""bcd""));"); + var actual = ""abc""; + Assert.That(actual, Is.Not.EqualTo(""bcd""));"); RoslynAssert.CodeFix(analyzer, fix, equalConstraintDiagnostic, code, fixedCode); } @@ -129,12 +129,12 @@ public void FixesEqualsMethodWithIsFalse() public void FixesEqualsMethodWithAssertTrue() { var code = TestUtility.WrapInTestMethod(@" - var actual = ""abc""; - Assert.True(actual.Equals(""abc""));"); + var actual = ""abc""; + ClassicAssert.True(actual.Equals(""abc""));"); var fixedCode = TestUtility.WrapInTestMethod(@" - var actual = ""abc""; - Assert.That(actual, Is.EqualTo(""abc""));"); + var actual = ""abc""; + Assert.That(actual, Is.EqualTo(""abc""));"); RoslynAssert.CodeFix(analyzer, fix, equalConstraintDiagnostic, code, fixedCode); } @@ -143,12 +143,12 @@ public void FixesEqualsMethodWithAssertTrue() public void FixesEqualsMethodWithAssertFalse() { var code = TestUtility.WrapInTestMethod(@" - var actual = ""abc""; - Assert.False(actual.Equals(""bcd""));"); + var actual = ""abc""; + ClassicAssert.False(actual.Equals(""bcd""));"); var fixedCode = TestUtility.WrapInTestMethod(@" - var actual = ""abc""; - Assert.That(actual, Is.Not.EqualTo(""bcd""));"); + var actual = ""abc""; + Assert.That(actual, Is.Not.EqualTo(""bcd""));"); RoslynAssert.CodeFix(analyzer, fix, equalConstraintDiagnostic, code, fixedCode); } @@ -157,12 +157,12 @@ public void FixesEqualsMethodWithAssertFalse() public void FixesEqualsMethodWithAssertIsTrue() { var code = TestUtility.WrapInTestMethod(@" - var actual = ""abc""; - Assert.IsTrue(actual.Equals(""abc""));"); + var actual = ""abc""; + ClassicAssert.IsTrue(actual.Equals(""abc""));"); var fixedCode = TestUtility.WrapInTestMethod(@" - var actual = ""abc""; - Assert.That(actual, Is.EqualTo(""abc""));"); + var actual = ""abc""; + Assert.That(actual, Is.EqualTo(""abc""));"); RoslynAssert.CodeFix(analyzer, fix, equalConstraintDiagnostic, code, fixedCode); } @@ -171,12 +171,12 @@ public void FixesEqualsMethodWithAssertIsTrue() public void FixesEqualsMethodWithAssertIsFalse() { var code = TestUtility.WrapInTestMethod(@" - var actual = ""abc""; - Assert.IsFalse(actual.Equals(""bcd""));"); + var actual = ""abc""; + ClassicAssert.IsFalse(actual.Equals(""bcd""));"); var fixedCode = TestUtility.WrapInTestMethod(@" - var actual = ""abc""; - Assert.That(actual, Is.Not.EqualTo(""bcd""));"); + var actual = ""abc""; + Assert.That(actual, Is.Not.EqualTo(""bcd""));"); RoslynAssert.CodeFix(analyzer, fix, equalConstraintDiagnostic, code, fixedCode); } @@ -185,12 +185,12 @@ public void FixesEqualsMethodWithAssertIsFalse() public void FixesAssertThatWithMessage() { var code = TestUtility.WrapInTestMethod(@" - var actual = ""abc""; - Assert.That(actual == ""abc"", ""Assertion message"");"); + var actual = ""abc""; + Assert.That(actual == ""abc"", ""Assertion message"");"); var fixedCode = TestUtility.WrapInTestMethod(@" - var actual = ""abc""; - Assert.That(actual, Is.EqualTo(""abc""), ""Assertion message"");"); + var actual = ""abc""; + Assert.That(actual, Is.EqualTo(""abc""), ""Assertion message"");"); RoslynAssert.CodeFix(analyzer, fix, equalConstraintDiagnostic, code, fixedCode); } @@ -199,12 +199,12 @@ public void FixesAssertThatWithMessage() public void FixesEqualsMethodWithIsTrueWithMessage() { var code = TestUtility.WrapInTestMethod(@" - var actual = ""abc""; - Assert.That(actual.Equals(""abc""), Is.True, ""Assertion message"");"); + var actual = ""abc""; + Assert.That(actual.Equals(""abc""), Is.True, ""Assertion message"");"); var fixedCode = TestUtility.WrapInTestMethod(@" - var actual = ""abc""; - Assert.That(actual, Is.EqualTo(""abc""), ""Assertion message"");"); + var actual = ""abc""; + Assert.That(actual, Is.EqualTo(""abc""), ""Assertion message"");"); RoslynAssert.CodeFix(analyzer, fix, equalConstraintDiagnostic, code, fixedCode); } @@ -213,12 +213,12 @@ public void FixesEqualsMethodWithIsTrueWithMessage() public void FixesEqualsMethodWithAssertTrueWithMessage() { var code = TestUtility.WrapInTestMethod(@" - var actual = ""abc""; - Assert.True(actual.Equals(""abc""), ""Assertion message"");"); + var actual = ""abc""; + ClassicAssert.True(actual.Equals(""abc""), ""Assertion message"");"); var fixedCode = TestUtility.WrapInTestMethod(@" - var actual = ""abc""; - Assert.That(actual, Is.EqualTo(""abc""), ""Assertion message"");"); + var actual = ""abc""; + Assert.That(actual, Is.EqualTo(""abc""), ""Assertion message"");"); RoslynAssert.CodeFix(analyzer, fix, equalConstraintDiagnostic, code, fixedCode); } @@ -227,12 +227,12 @@ public void FixesEqualsMethodWithAssertTrueWithMessage() public void FixesEqualsMethodWithAssertFalseWithMessage() { var code = TestUtility.WrapInTestMethod(@" - var actual = ""abc""; - Assert.False(actual.Equals(""bcd""), ""Assertion message"");"); + var actual = ""abc""; + ClassicAssert.False(actual.Equals(""bcd""), ""Assertion message"");"); var fixedCode = TestUtility.WrapInTestMethod(@" - var actual = ""abc""; - Assert.That(actual, Is.Not.EqualTo(""bcd""), ""Assertion message"");"); + var actual = ""abc""; + Assert.That(actual, Is.Not.EqualTo(""bcd""), ""Assertion message"");"); RoslynAssert.CodeFix(analyzer, fix, equalConstraintDiagnostic, code, fixedCode); } @@ -241,16 +241,16 @@ public void FixesEqualsMethodWithAssertFalseWithMessage() public void CodeFixPreservesLineBreakBeforeMessage() { var code = TestUtility.WrapInTestMethod(@" - var actual = ""abc""; + var actual = ""abc""; - Assert.False(actual.Equals(""bcd""), - ""Assertion message from new line"");"); + ClassicAssert.False(actual.Equals(""bcd""), + ""Assertion message from new line"");"); var fixedCode = TestUtility.WrapInTestMethod(@" - var actual = ""abc""; + var actual = ""abc""; - Assert.That(actual, Is.Not.EqualTo(""bcd""), - ""Assertion message from new line"");"); + Assert.That(actual, Is.Not.EqualTo(""bcd""), + ""Assertion message from new line"");"); RoslynAssert.CodeFix(analyzer, fix, equalConstraintDiagnostic, code, fixedCode); } diff --git a/src/nunit.analyzers.tests/ConstraintsUsage/SomeItemsConstraintUsageAnalyzerTests.cs b/src/nunit.analyzers.tests/ConstraintsUsage/SomeItemsConstraintUsageAnalyzerTests.cs index 34e9c894..d9f5b0bf 100644 --- a/src/nunit.analyzers.tests/ConstraintsUsage/SomeItemsConstraintUsageAnalyzerTests.cs +++ b/src/nunit.analyzers.tests/ConstraintsUsage/SomeItemsConstraintUsageAnalyzerTests.cs @@ -31,7 +31,7 @@ public void AnalyzeWhenListContainsUsedAssertThat() public void AnalyzeWhenListContainsUsedAssertIsTrue() { var testCode = TestUtility.WrapInTestMethod(@" - Assert.IsTrue(↓new List {1, 2, 3}.Contains(1));", + ClassicAssert.IsTrue(↓new List {1, 2, 3}.Contains(1));", additionalUsings: "using System.Collections.Generic;"); RoslynAssert.Diagnostics(analyzer, doesContainDiagnostic, testCode); @@ -41,7 +41,7 @@ public void AnalyzeWhenListContainsUsedAssertIsTrue() public void AnalyzeWhenListContainsUsedAssertIsFalse() { var testCode = TestUtility.WrapInTestMethod(@" - Assert.IsFalse(↓new List {1, 2, 3}.Contains(1));", + ClassicAssert.IsFalse(↓new List {1, 2, 3}.Contains(1));", additionalUsings: "using System.Collections.Generic;"); RoslynAssert.Diagnostics(analyzer, doesNotContainDiagnostic, testCode); @@ -61,7 +61,7 @@ public void AnalyzeWhenLinqContainsUsedAssertThat() public void AnalyzeWhenLinqContainsUsedAssertIsTrue() { var testCode = TestUtility.WrapInTestMethod(@" - Assert.IsTrue(↓new[] {1, 2, 3}.Contains(1));", + ClassicAssert.IsTrue(↓new[] {1, 2, 3}.Contains(1));", additionalUsings: "using System.Linq;"); RoslynAssert.Diagnostics(analyzer, doesContainDiagnostic, testCode); @@ -71,7 +71,7 @@ public void AnalyzeWhenLinqContainsUsedAssertIsTrue() public void AnalyzeWhenLinqContainsUsedAssertIsFalse() { var testCode = TestUtility.WrapInTestMethod(@" - Assert.IsFalse(↓new[] {1, 2, 3}.Contains(1));", + ClassicAssert.IsFalse(↓new[] {1, 2, 3}.Contains(1));", additionalUsings: "using System.Linq;"); RoslynAssert.Diagnostics(analyzer, doesNotContainDiagnostic, testCode); diff --git a/src/nunit.analyzers.tests/ConstraintsUsage/SomeItemsConstraintUsageCodeFixTests.cs b/src/nunit.analyzers.tests/ConstraintsUsage/SomeItemsConstraintUsageCodeFixTests.cs index 33c2a0a1..1c23876c 100644 --- a/src/nunit.analyzers.tests/ConstraintsUsage/SomeItemsConstraintUsageCodeFixTests.cs +++ b/src/nunit.analyzers.tests/ConstraintsUsage/SomeItemsConstraintUsageCodeFixTests.cs @@ -24,11 +24,11 @@ public class SomeItemsConstraintUsageCodeFixTests public void AnalyzeWhenListContainsUsedAssertThat() { var testCode = TestUtility.WrapInTestMethod(@" - Assert.That(↓new List {1, 2, 3}.Contains(1));", + Assert.That(↓new List {1, 2, 3}.Contains(1));", additionalUsings: "using System.Collections.Generic;"); var fixedCode = TestUtility.WrapInTestMethod(@" - Assert.That(new List {1, 2, 3}, Does.Contain(1));", + Assert.That(new List {1, 2, 3}, Does.Contain(1));", additionalUsings: "using System.Collections.Generic;"); RoslynAssert.CodeFix(analyzer, fix, doesContainDiagnostic, testCode, fixedCode); @@ -38,11 +38,11 @@ public void AnalyzeWhenListContainsUsedAssertThat() public void AnalyzeWhenListContainsUsedAssertIsTrue() { var testCode = TestUtility.WrapInTestMethod(@" - Assert.IsTrue(↓new List {1, 2, 3}.Contains(1));", + ClassicAssert.IsTrue(↓new List {1, 2, 3}.Contains(1));", additionalUsings: "using System.Collections.Generic;"); var fixedCode = TestUtility.WrapInTestMethod(@" - Assert.That(new List {1, 2, 3}, Does.Contain(1));", + Assert.That(new List {1, 2, 3}, Does.Contain(1));", additionalUsings: "using System.Collections.Generic;"); RoslynAssert.CodeFix(analyzer, fix, doesContainDiagnostic, testCode, fixedCode); @@ -52,11 +52,11 @@ public void AnalyzeWhenListContainsUsedAssertIsTrue() public void AnalyzeWhenListContainsUsedAssertIsFalse() { var testCode = TestUtility.WrapInTestMethod(@" - Assert.IsFalse(↓new List {1, 2, 3}.Contains(1));", + ClassicAssert.IsFalse(↓new List {1, 2, 3}.Contains(1));", additionalUsings: "using System.Collections.Generic;"); var fixedCode = TestUtility.WrapInTestMethod(@" - Assert.That(new List {1, 2, 3}, Does.Not.Contain(1));", + Assert.That(new List {1, 2, 3}, Does.Not.Contain(1));", additionalUsings: "using System.Collections.Generic;"); RoslynAssert.CodeFix(analyzer, fix, doesNotContainDiagnostic, testCode, fixedCode); @@ -66,11 +66,11 @@ public void AnalyzeWhenListContainsUsedAssertIsFalse() public void AnalyzeWhenLinqContainsUsedAssertThat() { var testCode = TestUtility.WrapInTestMethod(@" - Assert.That(↓new[] {1, 2, 3}.Contains(1));", + Assert.That(↓new[] {1, 2, 3}.Contains(1));", additionalUsings: "using System.Linq;"); var fixedCode = TestUtility.WrapInTestMethod(@" - Assert.That(new[] {1, 2, 3}, Does.Contain(1));", + Assert.That(new[] {1, 2, 3}, Does.Contain(1));", additionalUsings: "using System.Linq;"); RoslynAssert.CodeFix(analyzer, fix, doesContainDiagnostic, testCode, fixedCode); @@ -80,11 +80,11 @@ public void AnalyzeWhenLinqContainsUsedAssertThat() public void AnalyzeWhenLinqContainsUsedAssertIsTrue() { var testCode = TestUtility.WrapInTestMethod(@" - Assert.IsTrue(↓new[] {1, 2, 3}.Contains(1));", + ClassicAssert.IsTrue(↓new[] {1, 2, 3}.Contains(1));", additionalUsings: "using System.Linq;"); var fixedCode = TestUtility.WrapInTestMethod(@" - Assert.That(new[] {1, 2, 3}, Does.Contain(1));", + Assert.That(new[] {1, 2, 3}, Does.Contain(1));", additionalUsings: "using System.Linq;"); RoslynAssert.CodeFix(analyzer, fix, doesContainDiagnostic, testCode, fixedCode); @@ -94,11 +94,11 @@ public void AnalyzeWhenLinqContainsUsedAssertIsTrue() public void AnalyzeWhenLinqContainsUsedAssertIsFalse() { var testCode = TestUtility.WrapInTestMethod(@" - Assert.IsFalse(↓new[] {1, 2, 3}.Contains(1));", + ClassicAssert.IsFalse(↓new[] {1, 2, 3}.Contains(1));", additionalUsings: "using System.Linq;"); var fixedCode = TestUtility.WrapInTestMethod(@" - Assert.That(new[] {1, 2, 3}, Does.Not.Contain(1));", + Assert.That(new[] {1, 2, 3}, Does.Not.Contain(1));", additionalUsings: "using System.Linq;"); RoslynAssert.CodeFix(analyzer, fix, doesNotContainDiagnostic, testCode, fixedCode); diff --git a/src/nunit.analyzers.tests/ConstraintsUsage/StringConstraintUsageAnalyzerTests.cs b/src/nunit.analyzers.tests/ConstraintsUsage/StringConstraintUsageAnalyzerTests.cs index a691a519..890c3ceb 100644 --- a/src/nunit.analyzers.tests/ConstraintsUsage/StringConstraintUsageAnalyzerTests.cs +++ b/src/nunit.analyzers.tests/ConstraintsUsage/StringConstraintUsageAnalyzerTests.cs @@ -28,7 +28,7 @@ public class StringConstraintUsageAnalyzerTests [TestCaseSource(nameof(PositiveAssertData))] public void AnalyzeStringBooleanMethodAssertTrue(string method, string analyzerId, string suggestedConstraint) { - var testCode = TestUtility.WrapInTestMethod($@"Assert.True(↓""abc"".{method}(""ab""));"); + var testCode = TestUtility.WrapInTestMethod($@"ClassicAssert.True(↓""abc"".{method}(""ab""));"); var diagnostic = ExpectedDiagnostic.Create(analyzerId, string.Format(CultureInfo.InvariantCulture, StringConstraintUsageConstants.Message, suggestedConstraint)); @@ -38,7 +38,7 @@ public void AnalyzeStringBooleanMethodAssertTrue(string method, string analyzerI [TestCaseSource(nameof(PositiveAssertData))] public void AnalyzeStringBooleanMethodAssertIsTrue(string method, string analyzerId, string suggestedConstraint) { - var testCode = TestUtility.WrapInTestMethod($@"Assert.IsTrue(↓""abc"".{method}(""ab""));"); + var testCode = TestUtility.WrapInTestMethod($@"ClassicAssert.IsTrue(↓""abc"".{method}(""ab""));"); var diagnostic = ExpectedDiagnostic.Create(analyzerId, string.Format(CultureInfo.InvariantCulture, StringConstraintUsageConstants.Message, suggestedConstraint)); @@ -68,7 +68,7 @@ public void AnalyzeStringBooleanMethodAssertThatIsTrue(string method, string ana [TestCaseSource(nameof(NegativeAssertData))] public void AnalyzeStringBooleanMethodAssertFalse(string method, string analyzerId, string suggestedConstraint) { - var testCode = TestUtility.WrapInTestMethod($@"Assert.False(↓""abc"".{method}(""ab""));"); + var testCode = TestUtility.WrapInTestMethod($@"ClassicAssert.False(↓""abc"".{method}(""ab""));"); var diagnostic = ExpectedDiagnostic.Create(analyzerId, string.Format(CultureInfo.InvariantCulture, StringConstraintUsageConstants.Message, suggestedConstraint)); @@ -78,7 +78,7 @@ public void AnalyzeStringBooleanMethodAssertFalse(string method, string analyzer [TestCaseSource(nameof(NegativeAssertData))] public void AnalyzeStringBooleanMethodAssertIsFalse(string method, string analyzerId, string suggestedConstraint) { - var testCode = TestUtility.WrapInTestMethod($@"Assert.IsFalse(↓""abc"".{method}(""ab""));"); + var testCode = TestUtility.WrapInTestMethod($@"ClassicAssert.IsFalse(↓""abc"".{method}(""ab""));"); var diagnostic = ExpectedDiagnostic.Create(analyzerId, string.Format(CultureInfo.InvariantCulture, StringConstraintUsageConstants.Message, suggestedConstraint)); diff --git a/src/nunit.analyzers.tests/ConstraintsUsage/StringConstraintUsageCodeFixTests.cs b/src/nunit.analyzers.tests/ConstraintsUsage/StringConstraintUsageCodeFixTests.cs index 4125b69d..785f19dd 100644 --- a/src/nunit.analyzers.tests/ConstraintsUsage/StringConstraintUsageCodeFixTests.cs +++ b/src/nunit.analyzers.tests/ConstraintsUsage/StringConstraintUsageCodeFixTests.cs @@ -29,9 +29,11 @@ public class StringConstraintUsageCodeFixTests [TestCaseSource(nameof(PositiveAssertData))] public void AnalyzeStringBooleanMethodAssertTrue(string method, string analyzerId, string suggestedConstraint) { - var code = TestUtility.WrapInTestMethod($@"Assert.True(↓""abc"".{method}(""ab""));"); + var code = TestUtility.WrapInTestMethod($@" + ClassicAssert.True(↓""abc"".{method}(""ab""));"); - var fixedCode = TestUtility.WrapInTestMethod($@"Assert.That(""abc"", {suggestedConstraint}(""ab""));"); + var fixedCode = TestUtility.WrapInTestMethod($@" + Assert.That(""abc"", {suggestedConstraint}(""ab""));"); RoslynAssert.CodeFix(analyzer, fix, ExpectedDiagnostic.Create(analyzerId), code, fixedCode); } @@ -39,9 +41,11 @@ public void AnalyzeStringBooleanMethodAssertTrue(string method, string analyzerI [TestCaseSource(nameof(PositiveAssertData))] public void AnalyzeStringBooleanMethodAssertIsTrue(string method, string analyzerId, string suggestedConstraint) { - var code = TestUtility.WrapInTestMethod($@"Assert.IsTrue(↓""abc"".{method}(""ab""));"); + var code = TestUtility.WrapInTestMethod($@" + ClassicAssert.IsTrue(↓""abc"".{method}(""ab""));"); - var fixedCode = TestUtility.WrapInTestMethod($@"Assert.That(""abc"", {suggestedConstraint}(""ab""));"); + var fixedCode = TestUtility.WrapInTestMethod($@" + Assert.That(""abc"", {suggestedConstraint}(""ab""));"); RoslynAssert.CodeFix(analyzer, fix, ExpectedDiagnostic.Create(analyzerId), code, fixedCode); } @@ -49,9 +53,11 @@ public void AnalyzeStringBooleanMethodAssertIsTrue(string method, string analyze [TestCaseSource(nameof(PositiveAssertData))] public void AnalyzeStringBooleanMethodAssertThat(string method, string analyzerId, string suggestedConstraint) { - var code = TestUtility.WrapInTestMethod($@"Assert.That(↓""abc"".{method}(""ab""));"); + var code = TestUtility.WrapInTestMethod($@" + Assert.That(↓""abc"".{method}(""ab""));"); - var fixedCode = TestUtility.WrapInTestMethod($@"Assert.That(""abc"", {suggestedConstraint}(""ab""));"); + var fixedCode = TestUtility.WrapInTestMethod($@" + Assert.That(""abc"", {suggestedConstraint}(""ab""));"); RoslynAssert.CodeFix(analyzer, fix, ExpectedDiagnostic.Create(analyzerId), code, fixedCode); } @@ -59,9 +65,11 @@ public void AnalyzeStringBooleanMethodAssertThat(string method, string analyzerI [TestCaseSource(nameof(PositiveAssertData))] public void AnalyzeStringBooleanMethodAssertThatIsTrue(string method, string analyzerId, string suggestedConstraint) { - var code = TestUtility.WrapInTestMethod($@"Assert.That(↓""abc"".{method}(""ab""), Is.True);"); + var code = TestUtility.WrapInTestMethod($@" + Assert.That(↓""abc"".{method}(""ab""), Is.True);"); - var fixedCode = TestUtility.WrapInTestMethod($@"Assert.That(""abc"", {suggestedConstraint}(""ab""));"); + var fixedCode = TestUtility.WrapInTestMethod($@" + Assert.That(""abc"", {suggestedConstraint}(""ab""));"); RoslynAssert.CodeFix(analyzer, fix, ExpectedDiagnostic.Create(analyzerId), code, fixedCode); } @@ -69,9 +77,11 @@ public void AnalyzeStringBooleanMethodAssertThatIsTrue(string method, string ana [TestCaseSource(nameof(NegativeAssertData))] public void AnalyzeStringBooleanMethodAssertThatNegated(string method, string analyzerId, string suggestedConstraint) { - var code = TestUtility.WrapInTestMethod($@"Assert.That(↓!""abc"".{method}(""ab""));"); + var code = TestUtility.WrapInTestMethod($@" + Assert.That(↓!""abc"".{method}(""ab""));"); - var fixedCode = TestUtility.WrapInTestMethod($@"Assert.That(""abc"", {suggestedConstraint}(""ab""));"); + var fixedCode = TestUtility.WrapInTestMethod($@" + Assert.That(""abc"", {suggestedConstraint}(""ab""));"); RoslynAssert.CodeFix(analyzer, fix, ExpectedDiagnostic.Create(analyzerId), code, fixedCode); } @@ -79,9 +89,11 @@ public void AnalyzeStringBooleanMethodAssertThatNegated(string method, string an [TestCaseSource(nameof(NegativeAssertData))] public void AnalyzeStringBooleanMethodAssertFalse(string method, string analyzerId, string suggestedConstraint) { - var code = TestUtility.WrapInTestMethod($@"Assert.False(↓""abc"".{method}(""ab""));"); + var code = TestUtility.WrapInTestMethod($@" + ClassicAssert.False(↓""abc"".{method}(""ab""));"); - var fixedCode = TestUtility.WrapInTestMethod($@"Assert.That(""abc"", {suggestedConstraint}(""ab""));"); + var fixedCode = TestUtility.WrapInTestMethod($@" + Assert.That(""abc"", {suggestedConstraint}(""ab""));"); RoslynAssert.CodeFix(analyzer, fix, ExpectedDiagnostic.Create(analyzerId), code, fixedCode); } @@ -89,9 +101,11 @@ public void AnalyzeStringBooleanMethodAssertFalse(string method, string analyzer [TestCaseSource(nameof(NegativeAssertData))] public void AnalyzeStringBooleanMethodAssertIsFalse(string method, string analyzerId, string suggestedConstraint) { - var code = TestUtility.WrapInTestMethod($@"Assert.IsFalse(↓""abc"".{method}(""ab""));"); + var code = TestUtility.WrapInTestMethod($@" + ClassicAssert.IsFalse(↓""abc"".{method}(""ab""));"); - var fixedCode = TestUtility.WrapInTestMethod($@"Assert.That(""abc"", {suggestedConstraint}(""ab""));"); + var fixedCode = TestUtility.WrapInTestMethod($@" + Assert.That(""abc"", {suggestedConstraint}(""ab""));"); RoslynAssert.CodeFix(analyzer, fix, ExpectedDiagnostic.Create(analyzerId), code, fixedCode); } @@ -99,9 +113,11 @@ public void AnalyzeStringBooleanMethodAssertIsFalse(string method, string analyz [TestCaseSource(nameof(NegativeAssertData))] public void AnalyzeStringBooleanMethodAssertThatIsFalse(string method, string analyzerId, string suggestedConstraint) { - var code = TestUtility.WrapInTestMethod($@"Assert.That(↓""abc"".{method}(""ab""), Is.False);"); + var code = TestUtility.WrapInTestMethod($@" + Assert.That(↓""abc"".{method}(""ab""), Is.False);"); - var fixedCode = TestUtility.WrapInTestMethod($@"Assert.That(""abc"", {suggestedConstraint}(""ab""));"); + var fixedCode = TestUtility.WrapInTestMethod($@" + Assert.That(""abc"", {suggestedConstraint}(""ab""));"); RoslynAssert.CodeFix(analyzer, fix, ExpectedDiagnostic.Create(analyzerId), code, fixedCode); } diff --git a/src/nunit.analyzers.tests/DelegateRequired/DelegateRequiredAnalyzerTests.cs b/src/nunit.analyzers.tests/DelegateRequired/DelegateRequiredAnalyzerTests.cs index 06f6a288..a459f1f9 100644 --- a/src/nunit.analyzers.tests/DelegateRequired/DelegateRequiredAnalyzerTests.cs +++ b/src/nunit.analyzers.tests/DelegateRequired/DelegateRequiredAnalyzerTests.cs @@ -1,5 +1,3 @@ -using System; -using System.Threading.Tasks; using Gu.Roslyn.Asserts; using Microsoft.CodeAnalysis.Diagnostics; using NUnit.Analyzers.Constants; diff --git a/src/nunit.analyzers.tests/DelegateRequired/DelegateRequiredCodeFixTests.cs b/src/nunit.analyzers.tests/DelegateRequired/DelegateRequiredCodeFixTests.cs index bc9c5463..1c538961 100644 --- a/src/nunit.analyzers.tests/DelegateRequired/DelegateRequiredCodeFixTests.cs +++ b/src/nunit.analyzers.tests/DelegateRequired/DelegateRequiredCodeFixTests.cs @@ -57,16 +57,16 @@ public void VerifyNonDelegateFixWithMessage() } [Test] - public void VerifyNonDelegateFixWithMessageAndParams() + public void VerifyNonDelegateFixWithFormattableMessage() { var code = TestUtility.WrapInTestMethod(@" - Assert.That(↓MyOperation() + MyOtherOperation(), Throws.InstanceOf(), ""message"", Guid.NewGuid()); + Assert.That(↓MyOperation() + MyOtherOperation(), Throws.InstanceOf(), $""message-id: {Guid.NewGuid()}""); int MyOperation() => throw new InvalidOperationException(); int MyOtherOperation() => throw new InvalidOperationException(); "); var fixedCode = TestUtility.WrapInTestMethod(@" - Assert.That(() => MyOperation() + MyOtherOperation(), Throws.InstanceOf(), ""message"", Guid.NewGuid()); + Assert.That(() => MyOperation() + MyOtherOperation(), Throws.InstanceOf(), $""message-id: {Guid.NewGuid()}""); int MyOperation() => throw new InvalidOperationException(); int MyOtherOperation() => throw new InvalidOperationException(); diff --git a/src/nunit.analyzers.tests/DiagnosticSuppressors/DereferencePossiblyNullReferenceSuppressorTests.cs b/src/nunit.analyzers.tests/DiagnosticSuppressors/DereferencePossiblyNullReferenceSuppressorTests.cs index 21dc9056..927a7c07 100644 --- a/src/nunit.analyzers.tests/DiagnosticSuppressors/DereferencePossiblyNullReferenceSuppressorTests.cs +++ b/src/nunit.analyzers.tests/DiagnosticSuppressors/DereferencePossiblyNullReferenceSuppressorTests.cs @@ -1,7 +1,4 @@ -using System.IO; -using System.Threading.Tasks; using Gu.Roslyn.Asserts; -using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Diagnostics; using NUnit.Analyzers.DiagnosticSuppressors; using NUnit.Framework; @@ -36,10 +33,10 @@ private class B private static readonly DiagnosticSuppressor suppressor = new DereferencePossiblyNullReferenceSuppressor(); [TestCase("")] - [TestCase("Assert.NotNull(string.Empty)")] - [TestCase("Assert.IsNull(s)")] - [TestCase("Assert.Null(s)")] - [TestCase("Assert.That(s, Is.Null)")] + [TestCase("ClassicAssert.NotNull(string.Empty)")] + [TestCase("ClassicAssert.IsNull(s)")] + [TestCase("ClassicAssert.Null(s)")] + [TestCase("ClassicAssert.That(s, Is.Null)")] public void NoValidAssert(string assert) { var testCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@$" @@ -56,8 +53,8 @@ public void Test(string? s) testCode); } - [TestCase("Assert.NotNull(s)")] - [TestCase("Assert.IsNotNull(s)")] + [TestCase("ClassicAssert.NotNull(s)")] + [TestCase("ClassicAssert.IsNotNull(s)")] [TestCase("Assert.That(s, Is.Not.Null)")] public void WithLocalValidAssert(string assert) { @@ -75,8 +72,8 @@ public void Test(string? s) testCode); } - [TestCase("Assert.NotNull(s)")] - [TestCase("Assert.IsNotNull(s)")] + [TestCase("ClassicAssert.NotNull(s)")] + [TestCase("ClassicAssert.IsNotNull(s)")] [TestCase("Assert.That(s, Is.Not.Null)")] public void WithFieldValidAssert(string assert) { @@ -109,7 +106,7 @@ public void Test(string? s) private static string DoSomething(string? s) { - Assert.NotNull(s); + ClassicAssert.NotNull(s); return ↓s; } "); @@ -122,18 +119,18 @@ private static string DoSomething(string? s) [Test] public void Parameter() { - var testCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" + var testCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@$" [TestCase("""")] public void Test(string? s) - { - Assert.NotNull(s); + {{ + ClassicAssert.NotNull(s); DoSomething(↓s); - } + }} private static void DoSomething(string s) - { + {{ _ = s; - } + }} "); RoslynAssert.Suppressed(suppressor, @@ -144,15 +141,15 @@ private static void DoSomething(string s) [Test] public void NullableCast() { - var testCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" + var testCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@$" [Test] public void Test() - { + {{ int? possibleNull = GetNext(); - Assert.NotNull(possibleNull); + ClassicAssert.NotNull(possibleNull); int i = ↓(int)possibleNull; AssertOne(i); - } + }} private static int? GetNext() => 1; @@ -185,8 +182,8 @@ public void Test() RoslynAssert.Suppressed(suppressor, new[] { - ExpectedDiagnostic.Create("CS8600", 18, 31), - ExpectedDiagnostic.Create("CS8604", 19, 32), + ExpectedDiagnostic.Create("CS8600", 24, 31), + ExpectedDiagnostic.Create("CS8604", 25, 32), }, testCode); } @@ -213,8 +210,8 @@ public void Test() RoslynAssert.Suppressed(suppressor, new[] { - ExpectedDiagnostic.Create("CS8600", 19, 24), - ExpectedDiagnostic.Create("CS8604", 20, 32), + ExpectedDiagnostic.Create("CS8600", 25, 24), + ExpectedDiagnostic.Create("CS8604", 26, 32), }, testCode); } @@ -239,8 +236,8 @@ public void Test() RoslynAssert.Suppressed(suppressor, new[] { - ExpectedDiagnostic.Create("CS8600", 18, 32), - ExpectedDiagnostic.Create("CS8604", 18, 32), + ExpectedDiagnostic.Create("CS8600", 24, 32), + ExpectedDiagnostic.Create("CS8604", 24, 32), }, testCode); } @@ -248,14 +245,14 @@ public void Test() [Test] public void WithReassignedAfterAssert() { - var testCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" + var testCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@$" [TestCase("""")] public void Test(string? s) - { - Assert.NotNull(s); + {{ + ClassicAssert.NotNull(s); s = null; Assert.That(↓s.Length, Is.GreaterThan(0)); - } + }} "); RoslynAssert.NotSuppressed(suppressor, @@ -266,15 +263,15 @@ public void Test(string? s) [Test] public void WithReassignedFieldAfterAssert() { - var testCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" + var testCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@$" private string? s; [Test] public void Test() - { - Assert.NotNull(this.s); + {{ + ClassicAssert.NotNull(this.s); this.s = null; Assert.That(↓this.s.Length, Is.GreaterThan(0)); - } + }} "); RoslynAssert.NotSuppressed(suppressor, @@ -348,16 +345,16 @@ public void Test([Values] bool create) [Test] public void InsideAssertMultiple() { - var testCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" + var testCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@$" [TestCase("""")] public void Test(string? s) - { + {{ Assert.Multiple(() => - { - Assert.NotNull(s); + {{ + ClassicAssert.NotNull(s); Assert.That(↓s.Length, Is.GreaterThan(0)); - }); - } + }}); + }} "); RoslynAssert.NotSuppressed(suppressor, @@ -365,8 +362,8 @@ public void Test(string? s) testCode); } - [TestCase("Assert.True(nullable.HasValue)")] - [TestCase("Assert.IsTrue(nullable.HasValue)")] + [TestCase("ClassicAssert.True(nullable.HasValue)")] + [TestCase("ClassicAssert.IsTrue(nullable.HasValue)")] [TestCase("Assert.That(nullable.HasValue, \"Ensure Value is set\")")] [TestCase("Assert.That(nullable.HasValue)")] [TestCase("Assert.That(nullable.HasValue, Is.True)")] @@ -387,8 +384,8 @@ public void Test(int? nullable) testCode); } - [TestCase("Assert.False(nullable.HasValue)")] - [TestCase("Assert.IsFalse(nullable.HasValue)")] + [TestCase("ClassicAssert.False(nullable.HasValue)")] + [TestCase("ClassicAssert.IsFalse(nullable.HasValue)")] [TestCase("Assert.That(!nullable.HasValue)")] [TestCase("Assert.That(nullable.HasValue, Is.False)")] [TestCase("Assert.That(nullable, Is.Null)")] @@ -783,7 +780,7 @@ public void Test() {{ object? possibleNull = GetNext(); object? assertedNotNull = possibleNull; - Assert.NotNull(assertedNotNull); + ClassicAssert.NotNull(assertedNotNull); ↓DoNothing(assertedNotNull); }} @@ -809,7 +806,7 @@ public void Test() {{ object? possibleNull = GetNext(); object? assertedNotNull = GetNext(); - Assert.NotNull(assertedNotNull); + ClassicAssert.NotNull(assertedNotNull); ↓DoNothing(assertedNotNull, possibleNull); }} @@ -836,7 +833,7 @@ public void Test() {{ object? possibleNull = GetNext(); object? assertedNotNull = GetNext(); - Assert.NotNull(assertedNotNull); + ClassicAssert.NotNull(assertedNotNull); ↓DoNothing(assertedNotNull, assertedNotNull); }} @@ -863,7 +860,7 @@ public void Test() {{ object? possibleNull = GetNext(); object? assertedNotNull = GetNext(); - Assert.NotNull(assertedNotNull); + ClassicAssert.NotNull(assertedNotNull); ↓DoNothing(assertedNotNull, assertedNotNull); }} @@ -889,7 +886,7 @@ public void Test() {{ object? possibleNull = GetNext(); object? assertedNotNull = possibleNull; - Assert.NotNull(assertedNotNull); + ClassicAssert.NotNull(assertedNotNull); ↓DoNothing(possibleNull); }} @@ -917,7 +914,7 @@ public void Test() {{ object? possibleNull = GetNext(); object? assertedNotNull = GetNext(); - Assert.NotNull(assertedNotNull); + ClassicAssert.NotNull(assertedNotNull); ↓DoNothing(assertedNotNull, possibleNull); }} diff --git a/src/nunit.analyzers.tests/DiagnosticSuppressors/NonNullableFieldOrPropertyIsUninitializedSuppressorTests.cs b/src/nunit.analyzers.tests/DiagnosticSuppressors/NonNullableFieldOrPropertyIsUninitializedSuppressorTests.cs index 8e7b4ec8..36660f2a 100644 --- a/src/nunit.analyzers.tests/DiagnosticSuppressors/NonNullableFieldOrPropertyIsUninitializedSuppressorTests.cs +++ b/src/nunit.analyzers.tests/DiagnosticSuppressors/NonNullableFieldOrPropertyIsUninitializedSuppressorTests.cs @@ -1,4 +1,3 @@ -using System.Threading.Tasks; using Gu.Roslyn.Asserts; using Microsoft.CodeAnalysis.Diagnostics; using NUnit.Analyzers.DiagnosticSuppressors; diff --git a/src/nunit.analyzers.tests/DisposeFieldsAndPropertiesInTearDown/DisposeFieldsAndPropertiesInTearDownAnalyzerTests.cs b/src/nunit.analyzers.tests/DisposeFieldsAndPropertiesInTearDown/DisposeFieldsAndPropertiesInTearDownAnalyzerTests.cs index c47d0446..6275c457 100644 --- a/src/nunit.analyzers.tests/DisposeFieldsAndPropertiesInTearDown/DisposeFieldsAndPropertiesInTearDownAnalyzerTests.cs +++ b/src/nunit.analyzers.tests/DisposeFieldsAndPropertiesInTearDown/DisposeFieldsAndPropertiesInTearDownAnalyzerTests.cs @@ -1,4 +1,3 @@ -using System.Threading.Tasks; using Gu.Roslyn.Asserts; using Microsoft.CodeAnalysis.Diagnostics; using NUnit.Analyzers.Constants; diff --git a/src/nunit.analyzers.tests/DocumentationTests.cs b/src/nunit.analyzers.tests/DocumentationTests.cs index b473b778..0389e243 100644 --- a/src/nunit.analyzers.tests/DocumentationTests.cs +++ b/src/nunit.analyzers.tests/DocumentationTests.cs @@ -18,6 +18,9 @@ namespace NUnit.Analyzers.Tests { public class DocumentationTests { + // Overload of Append(AppendInterpolatedStringHandler) with IFormatProvider not available in .NET 462 +#pragma warning disable CA1305 // Specify IFormatProvider + private static readonly IReadOnlyList analyzers = typeof(BaseAssertionAnalyzer) .Assembly @@ -361,7 +364,7 @@ public static IEnumerable Create(DiagnosticAnalyzer analyzer) private static string CreateStub(DiagnosticAnalyzer analyzer, DiagnosticDescriptor descriptor) { var builder = new StringBuilder(); - builder.Append($"|{(builder.Length == 0 ? " Code " : " ")}| "); + builder.Append("| Code | "); builder.Append($"[{analyzer.GetType().Name}]({CodeFile.Find(analyzer.GetType()).Uri})"); var text = builder.ToString(); diff --git a/src/nunit.analyzers.tests/EqualToIncompatibleTypes/EqualToIncompatibleTypesAnalyzerTests.cs b/src/nunit.analyzers.tests/EqualToIncompatibleTypes/EqualToIncompatibleTypesAnalyzerTests.cs index 5b01fcd0..4cb42ac5 100644 --- a/src/nunit.analyzers.tests/EqualToIncompatibleTypes/EqualToIncompatibleTypesAnalyzerTests.cs +++ b/src/nunit.analyzers.tests/EqualToIncompatibleTypes/EqualToIncompatibleTypesAnalyzerTests.cs @@ -31,7 +31,7 @@ public void AnalyzeWhenIncompatibleTypesProvided() public void AnalyzeClassicWhenIncompatibleTypesProvided() { var testCode = TestUtility.WrapInTestMethod( - "Assert.AreEqual(↓\"1\", 1);"); + "ClassicAssert.AreEqual(↓\"1\", 1);"); RoslynAssert.Diagnostics(analyzer, expectedDiagnostic, testCode); } @@ -246,7 +246,7 @@ public void AnalyzeWhenIncompatibleTypesProvidedWithNegatedAssert() { var actual = new A(); var expected = new B(); - Assert.AreNotEqual(↓expected, actual); + ClassicAssert.AreNotEqual(↓expected, actual); } }"); diff --git a/src/nunit.analyzers.tests/Extensions/ITypeSymbolExtensionsTests.cs b/src/nunit.analyzers.tests/Extensions/ITypeSymbolExtensionsTests.cs index 17340de0..9a71a5ef 100644 --- a/src/nunit.analyzers.tests/Extensions/ITypeSymbolExtensionsTests.cs +++ b/src/nunit.analyzers.tests/Extensions/ITypeSymbolExtensionsTests.cs @@ -200,24 +200,6 @@ public sealed class IsAssertWhenSymbolIsAssertType Assert.That(typeSymbol.IsAssert(), Is.True); } - [TestCase("Assert")] - [TestCase("StringAssert")] - public async Task IsAnyAssertWhenSymbolIsAnyAssertType(string assertType) - { - var testCode = $@" -using NUnit.Framework; - -namespace NUnit.Analyzers.Tests.Targets.Extensions -{{ - public sealed class IsAnyAssertWhenSymbolIsAnyAssertType - {{ - public {assertType} x; - }} -}}"; - var typeSymbol = await GetTypeSymbolFromFieldAsync(testCode, "IsAnyAssertWhenSymbolIsAnyAssertType").ConfigureAwait(false); - Assert.That(typeSymbol.IsAnyAssert(), Is.True); - } - private static async Task> GetTypeSymbolAsync(string code, string[] typeNames) { var rootAndModel = await TestHelpers.GetRootAndModel(code).ConfigureAwait(false); @@ -250,10 +232,11 @@ private static async Task GetTypeSymbolFromFieldAsync(string code, .DescendantNodes().OfType().Single(); VariableDeclaratorSyntax variableDeclaration = fieldNode.Declaration.Variables[0]; - ISymbol? symbol = rootAndModel.Model.GetDeclaredSymbol(variableDeclaration); + IFieldSymbol? symbol = rootAndModel.Model.GetDeclaredSymbol(variableDeclaration) as IFieldSymbol; Assert.That(symbol, Is.Not.Null, $"Cannot find symbol for {variableDeclaration.Identifier}"); + Assert.That(symbol.Type.Kind, Is.Not.EqualTo(SymbolKind.ErrorType), $"Cannot find type for {fieldNode.ToString()}"); - return ((IFieldSymbol)symbol).Type; + return symbol.Type; } } } diff --git a/src/nunit.analyzers.tests/ParallelizableUsage/ParallelizableUsageAnalyzerTests.cs b/src/nunit.analyzers.tests/ParallelizableUsage/ParallelizableUsageAnalyzerTests.cs index 0f976128..d294136d 100644 --- a/src/nunit.analyzers.tests/ParallelizableUsage/ParallelizableUsageAnalyzerTests.cs +++ b/src/nunit.analyzers.tests/ParallelizableUsage/ParallelizableUsageAnalyzerTests.cs @@ -30,7 +30,8 @@ public void VerifySupportedDiagnostics() AnalyzerIdentifiers.ParallelScopeChildrenOnNonParameterizedTestMethodUsage, AnalyzerIdentifiers.ParallelScopeFixturesOnTestMethodUsage }; - CollectionAssert.AreEquivalent(expectedIdentifiers, diagnostics.Select(d => d.Id)); + + Assert.That(diagnostics.Select(d => d.Id), Is.EquivalentTo(expectedIdentifiers)); foreach (var diagnostic in diagnostics) { diff --git a/src/nunit.analyzers.tests/SameAsIncompatibleTypes/SameAsIncompatibleTypesAnalyzerTests.cs b/src/nunit.analyzers.tests/SameAsIncompatibleTypes/SameAsIncompatibleTypesAnalyzerTests.cs index 5e52c8e6..647a8cb5 100644 --- a/src/nunit.analyzers.tests/SameAsIncompatibleTypes/SameAsIncompatibleTypesAnalyzerTests.cs +++ b/src/nunit.analyzers.tests/SameAsIncompatibleTypes/SameAsIncompatibleTypesAnalyzerTests.cs @@ -47,7 +47,7 @@ public void AnalyzeWhenIncompatibleTypesProvided() { var actual = new A(); var expected = new B(); - Assert.AreSame(↓expected, actual); + ClassicAssert.AreSame(↓expected, actual); } }"); @@ -128,7 +128,7 @@ public void AnalyzeWhenIncompatibleTypesProvidedWithNegatedAssert() { var actual = new A(); var expected = new B(); - Assert.AreNotSame(↓expected, actual); + ClassicAssert.AreNotSame(↓expected, actual); } }"); @@ -246,7 +246,7 @@ public void NoDiagnosticClassicWhenActualAndExpectedTypesAreSame() var testCode = TestUtility.WrapInTestMethod(@" var actual = """"; var expected = """"; - Assert.AreSame(expected, actual);"); + ClassicAssert.AreSame(expected, actual);"); RoslynAssert.Valid(analyzer, testCode); } @@ -268,7 +268,7 @@ public void NoDiagnosticClassicWhenActualAndExpectedTypesAreSameWithNegatedAsser var testCode = TestUtility.WrapInTestMethod(@" var actual = """"; var expected = """"; - Assert.AreNotSame(expected, actual);"); + ClassicAssert.AreNotSame(expected, actual);"); RoslynAssert.Valid(analyzer, testCode); } diff --git a/src/nunit.analyzers.tests/SameAsOnValueTypes/SameAsOnValueTypesAnalyzerTests.cs b/src/nunit.analyzers.tests/SameAsOnValueTypes/SameAsOnValueTypesAnalyzerTests.cs index 4d5299f6..1b353a2c 100644 --- a/src/nunit.analyzers.tests/SameAsOnValueTypes/SameAsOnValueTypesAnalyzerTests.cs +++ b/src/nunit.analyzers.tests/SameAsOnValueTypes/SameAsOnValueTypesAnalyzerTests.cs @@ -98,7 +98,7 @@ public void AnalyzeWhenCollectionsWithValueTypesProvided() public void AnalyzeClassicWhenLiteralTypesProvided() { var testCode = TestUtility.WrapInTestMethod( - "Assert.AreSame(↓1, 1);"); + "ClassicAssert.AreSame(↓1, 1);"); RoslynAssert.Diagnostics(analyzer, expectedDiagnostic, testCode); } @@ -110,7 +110,7 @@ public void AnalyzeClassicWhenStructTypesProvided() var expected = Guid.Empty; var actual = expected; - Assert.AreSame(↓expected, actual);"); + ClassicAssert.AreSame(↓expected, actual);"); RoslynAssert.Diagnostics(analyzer, expectedDiagnostic, testCode); } @@ -119,7 +119,7 @@ public void AnalyzeClassicWhenStructTypesProvided() public void AnalyzeClassicWhenActualIsReferenceTypeAndExpectedIsValueType() { var testCode = TestUtility.WrapInTestMethod( - @"Assert.AreNotSame(↓3, ""3"");"); + @"ClassicAssert.AreNotSame(↓3, ""3"");"); RoslynAssert.Diagnostics(analyzer, expectedDiagnostic, testCode); } @@ -128,7 +128,7 @@ public void AnalyzeClassicWhenActualIsReferenceTypeAndExpectedIsValueType() public void AnalyzeClassicWhenActualIsValueTypeAndExpectedIsReferenceType() { var testCode = TestUtility.WrapInTestMethod( - @"Assert.AreNotSame(""3"", ↓3);"); + @"ClassicAssert.AreNotSame(""3"", ↓3);"); RoslynAssert.Diagnostics(analyzer, expectedDiagnostic, testCode); } @@ -137,7 +137,7 @@ public void AnalyzeClassicWhenActualIsValueTypeAndExpectedIsReferenceType() public void AnalyzeClassicWhenBothArgumentsAreReferenceType() { var testCode = TestUtility.WrapInTestMethod( - @"Assert.AreSame(""3"", ""3"");"); + @"ClassicAssert.AreSame(""3"", ""3"");"); RoslynAssert.Valid(analyzer, testCode); } diff --git a/src/nunit.analyzers.tests/SameAsOnValueTypes/SameAsOnValueTypesCodeFixTests.cs b/src/nunit.analyzers.tests/SameAsOnValueTypes/SameAsOnValueTypesCodeFixTests.cs index c8212358..4a803f74 100644 --- a/src/nunit.analyzers.tests/SameAsOnValueTypes/SameAsOnValueTypesCodeFixTests.cs +++ b/src/nunit.analyzers.tests/SameAsOnValueTypes/SameAsOnValueTypesCodeFixTests.cs @@ -1,4 +1,3 @@ -using System.Collections.Immutable; using Gu.Roslyn.Asserts; using Microsoft.CodeAnalysis.CodeFixes; using Microsoft.CodeAnalysis.Diagnostics; @@ -59,6 +58,7 @@ public void VerifySameAsIntoEqualToFixWithMessage() RoslynAssert.CodeFix(analyzer, fix, expectedDiagnostic, code, fixedCode, fixTitle: SameAsOnValueTypesCodeFix.UseIsEqualToDescription); } +#if !NUNIT4 [Test] public void VerifySameAsIntoEqualToFixWithMessageAndParams() { @@ -74,6 +74,7 @@ public void VerifySameAsIntoEqualToFixWithMessageAndParams() "); RoslynAssert.CodeFix(analyzer, fix, expectedDiagnostic, code, fixedCode, fixTitle: SameAsOnValueTypesCodeFix.UseIsEqualToDescription); } +#endif [Test] public void VerifyAreSameIntoAreEqualFix() @@ -82,13 +83,13 @@ public void VerifyAreSameIntoAreEqualFix() var expected = Guid.Empty; var actual = expected; - Assert.AreSame(↓expected, actual); + ClassicAssert.AreSame(↓expected, actual); "); var fixedCode = TestUtility.WrapInTestMethod(@" var expected = Guid.Empty; var actual = expected; - Assert.AreEqual(expected, actual); + ClassicAssert.AreEqual(expected, actual); "); RoslynAssert.CodeFix(analyzer, fix, expectedDiagnostic, code, fixedCode, fixTitle: SameAsOnValueTypesCodeFix.UseIsEqualToDescription); } @@ -99,31 +100,33 @@ public void VerifyAreNotSameIntoAreNotEqualFixWithMessage() var code = TestUtility.WrapInTestMethod(@" var expected = Guid.Empty; - Assert.AreNotSame(↓expected, Guid.NewGuid(), ""message""); + ClassicAssert.AreNotSame(↓expected, Guid.NewGuid(), ""message""); "); var fixedCode = TestUtility.WrapInTestMethod(@" var expected = Guid.Empty; - Assert.AreNotEqual(expected, Guid.NewGuid(), ""message""); + ClassicAssert.AreNotEqual(expected, Guid.NewGuid(), ""message""); "); RoslynAssert.CodeFix(analyzer, fix, expectedDiagnostic, code, fixedCode, fixTitle: SameAsOnValueTypesCodeFix.UseIsEqualToDescription); } +#if !NUNIT4 [Test] public void VerifyAreSameIntoAreEqualFixWithMessageAndParams() { var code = TestUtility.WrapInTestMethod(@" - var expected = Guid.Empty; + var expected = Guid.Empty; - Assert.AreSame(↓expected, expected, ""message"", Guid.Empty); + ClassicAssert.AreSame(↓expected, expected, ""message"", Guid.Empty); "); var fixedCode = TestUtility.WrapInTestMethod(@" - var expected = Guid.Empty; + var expected = Guid.Empty; - Assert.AreEqual(expected, expected, ""message"", Guid.Empty); + ClassicAssert.AreEqual(expected, expected, ""message"", Guid.Empty); "); RoslynAssert.CodeFix(analyzer, fix, expectedDiagnostic, code, fixedCode, fixTitle: SameAsOnValueTypesCodeFix.UseIsEqualToDescription); } +#endif [Test] public void AnalyzeWhenMoreThanOneConstraintExpressionIsUsed() diff --git a/src/nunit.analyzers.tests/SetUpFixture.cs b/src/nunit.analyzers.tests/SetUpFixture.cs index 7ba628b2..9a248c2d 100644 --- a/src/nunit.analyzers.tests/SetUpFixture.cs +++ b/src/nunit.analyzers.tests/SetUpFixture.cs @@ -1,6 +1,10 @@ -using Gu.Roslyn.Asserts; +using Gu.Roslyn.Asserts; using NUnit.Framework; +#if NUNIT4 +using NUnit.Framework.Legacy; +#endif + namespace NUnit.Analyzers.Tests { [SetUpFixture] @@ -9,7 +13,13 @@ internal class SetUpFixture [OneTimeSetUp] public void SetDefaults() { - Settings.Default = Settings.Default.WithMetadataReferences(MetadataReferences.Transitive(typeof(Assert))); + Settings.Default = Settings.Default +#if NUNIT4 + .WithMetadataReferences(MetadataReferences.Transitive(typeof(Assert), typeof(ClassicAssert))) + .WithParseOption(Settings.Default.ParseOptions.WithPreprocessorSymbols("NUNIT4")); +#else + .WithMetadataReferences(MetadataReferences.Transitive(typeof(Assert))); +#endif } } } diff --git a/src/nunit.analyzers.tests/SomeItemsIncompatibleTypes/SomeItemsIncompatibleTypesAnalyzerTests.cs b/src/nunit.analyzers.tests/SomeItemsIncompatibleTypes/SomeItemsIncompatibleTypesAnalyzerTests.cs index 21a12431..6824cebd 100644 --- a/src/nunit.analyzers.tests/SomeItemsIncompatibleTypes/SomeItemsIncompatibleTypesAnalyzerTests.cs +++ b/src/nunit.analyzers.tests/SomeItemsIncompatibleTypes/SomeItemsIncompatibleTypesAnalyzerTests.cs @@ -1,5 +1,3 @@ -using System; -using System.Collections; using Gu.Roslyn.Asserts; using Microsoft.CodeAnalysis.Diagnostics; using NUnit.Analyzers.Constants; diff --git a/src/nunit.analyzers.tests/StringAssertUsage/StringAssertUsageAnalyzerTests.cs b/src/nunit.analyzers.tests/StringAssertUsage/StringAssertUsageAnalyzerTests.cs new file mode 100644 index 00000000..d19529c6 --- /dev/null +++ b/src/nunit.analyzers.tests/StringAssertUsage/StringAssertUsageAnalyzerTests.cs @@ -0,0 +1,45 @@ +using System.Collections.Generic; +using Gu.Roslyn.Asserts; +using Microsoft.CodeAnalysis.Diagnostics; +using NUnit.Analyzers.Constants; +using NUnit.Analyzers.StringAssertUsage; +using NUnit.Framework; + +namespace NUnit.Analyzers.Tests.StringAssertUsage +{ + [TestFixture] + internal class StringAssertUsageAnalyzerTests + { + private readonly DiagnosticAnalyzer analyzer = new StringAssertUsageAnalyzer(); + private readonly ExpectedDiagnostic diagnostic = ExpectedDiagnostic.Create(AnalyzerIdentifiers.StringAssertUsage); + + private static IEnumerable StringAsserts => StringAssertUsageAnalyzer.StringAssertToConstraint.Keys; + + [TestCaseSource(nameof(StringAsserts))] + public void AnalyzeWhenNoArgumentsAreUsed(string method) + { + var testCode = TestUtility.WrapInTestMethod(@$" + ↓StringAssert.{method}(""expected"", ""actual""); + "); + RoslynAssert.Diagnostics(this.analyzer, this.diagnostic, testCode); + } + + [TestCaseSource(nameof(StringAsserts))] + public void AnalyzeWhenOnlyMessageArgumentIsUsed(string method) + { + var testCode = TestUtility.WrapInTestMethod(@$" + ↓StringAssert.{method}(""expected"", ""actual"", ""message""); + "); + RoslynAssert.Diagnostics(this.analyzer, this.diagnostic, testCode); + } + + [TestCaseSource(nameof(StringAsserts))] + public void AnalyzeWhenFormatAndArgumentsAreUsed(string method) + { + var testCode = TestUtility.WrapInTestMethod(@$" + ↓StringAssert.{method}(""expected"", ""actual"", ""Because of {{0}}"", ""message""); + "); + RoslynAssert.Diagnostics(this.analyzer, this.diagnostic, testCode); + } + } +} diff --git a/src/nunit.analyzers.tests/StringAssertUsage/StringAssertUsageCodeFixTests.cs b/src/nunit.analyzers.tests/StringAssertUsage/StringAssertUsageCodeFixTests.cs new file mode 100644 index 00000000..92b4c161 --- /dev/null +++ b/src/nunit.analyzers.tests/StringAssertUsage/StringAssertUsageCodeFixTests.cs @@ -0,0 +1,62 @@ +using System.Collections.Generic; +using Gu.Roslyn.Asserts; +using Microsoft.CodeAnalysis.CodeFixes; +using Microsoft.CodeAnalysis.Diagnostics; +using NUnit.Analyzers.Constants; +using NUnit.Analyzers.StringAssertUsage; +using NUnit.Framework; + +namespace NUnit.Analyzers.Tests.StringAssertUsage +{ + [TestFixture] + internal sealed class StringAssertUsageCodeFixTests + { + private static readonly DiagnosticAnalyzer analyzer = new StringAssertUsageAnalyzer(); + private static readonly CodeFixProvider fix = new StringAssertUsageCodeFix(); + private static readonly ExpectedDiagnostic expectedDiagnostic = ExpectedDiagnostic.Create(AnalyzerIdentifiers.StringAssertUsage); + + private static IEnumerable StringAsserts => StringAssertUsageAnalyzer.StringAssertToConstraint.Keys; + + [TestCaseSource(nameof(StringAsserts))] + public void AnalyzeWhenNoArgumentsAreUsed(string method) + { + var code = TestUtility.WrapInTestMethod(@$" + ↓StringAssert.{method}(""expected"", ""actual""); + "); + var fixedCode = TestUtility.WrapInTestMethod(@$" + Assert.That(""actual"", {GetAdjustedConstraint(method)}); + "); + RoslynAssert.CodeFix(analyzer, fix, expectedDiagnostic, code, fixedCode); + } + + [TestCaseSource(nameof(StringAsserts))] + public void AnalyzeWhenOnlyMessageArgumentIsUsed(string method) + { + var code = TestUtility.WrapInTestMethod(@$" + ↓StringAssert.{method}(""expected"", ""actual"", ""message""); + "); + var fixedCode = TestUtility.WrapInTestMethod(@$" + Assert.That(""actual"", {GetAdjustedConstraint(method)}, ""message""); + "); + RoslynAssert.CodeFix(analyzer, fix, expectedDiagnostic, code, fixedCode); + } + + [TestCaseSource(nameof(StringAsserts))] + public void AnalyzeWhenFormatAndArgumentsAreUsed(string method) + { + var code = TestUtility.WrapInTestMethod(@$" + ↓StringAssert.{method}(""expected"", ""actual"", ""Because of {{0}}"", ""message""); + "); + var fixedCode = TestUtility.WrapInTestMethod(@$" + Assert.That(""actual"", {GetAdjustedConstraint(method)}, $""Because of {{""message""}}""); + "); + RoslynAssert.CodeFix(analyzer, fix, expectedDiagnostic, code, fixedCode); + } + + private static string GetAdjustedConstraint(string method) + { + return StringAssertUsageAnalyzer.StringAssertToConstraint[method] + .Replace("expected", "\"expected\""); + } + } +} diff --git a/src/nunit.analyzers.tests/TestCaseSourceUsage/TestCaseSourceExistsTests.cs b/src/nunit.analyzers.tests/TestCaseSourceUsage/TestCaseSourceExistsTests.cs index 0df5951c..0b8387f2 100644 --- a/src/nunit.analyzers.tests/TestCaseSourceUsage/TestCaseSourceExistsTests.cs +++ b/src/nunit.analyzers.tests/TestCaseSourceUsage/TestCaseSourceExistsTests.cs @@ -40,7 +40,7 @@ internal class Tests : Base [TestCaseSource(nameof(TargetFrameworks))] public void Test(string targetFramework) { - Assert.IsNotNull(targetFramework); + ClassicAssert.IsNotNull(targetFramework); } }", "using System.Collections.Generic;"); diff --git a/src/nunit.analyzers.tests/TestCaseSourceUsage/TestCaseSourceUsesStringAnalyzerTests.cs b/src/nunit.analyzers.tests/TestCaseSourceUsage/TestCaseSourceUsesStringAnalyzerTests.cs index edd0076e..0d9d7fab 100644 --- a/src/nunit.analyzers.tests/TestCaseSourceUsage/TestCaseSourceUsesStringAnalyzerTests.cs +++ b/src/nunit.analyzers.tests/TestCaseSourceUsage/TestCaseSourceUsesStringAnalyzerTests.cs @@ -356,7 +356,7 @@ public class AnalyzeWhenSourceIsInAnotherClass [TestCaseSource(typeof(AnotherClass), ""DivideCases"")] public void DivideTest(int n, int d, int q) { - Assert.AreEqual(q, n / d); + ClassicAssert.AreEqual(q, n / d); } } @@ -381,7 +381,7 @@ public class AnalyzeWhenSourceIsInNestedClass [TestCaseSource(typeof(AnotherClass), ""DivideCases"")] public void DivideTest(int n, int d, int q) { - Assert.AreEqual(q, n / d); + ClassicAssert.AreEqual(q, n / d); } class AnotherClass diff --git a/src/nunit.analyzers.tests/TestCaseUsage/TestCaseUsageAnalyzerTests.cs b/src/nunit.analyzers.tests/TestCaseUsage/TestCaseUsageAnalyzerTests.cs index 8b38990b..022d9cae 100644 --- a/src/nunit.analyzers.tests/TestCaseUsage/TestCaseUsageAnalyzerTests.cs +++ b/src/nunit.analyzers.tests/TestCaseUsage/TestCaseUsageAnalyzerTests.cs @@ -41,7 +41,8 @@ public void VerifySupportedDiagnostics() AnalyzerIdentifiers.TestCaseParameterTypeMismatchUsage, AnalyzerIdentifiers.TestCaseTooManyArgumentsUsage }; - CollectionAssert.AreEquivalent(expectedIdentifiers, diagnostics.Select(d => d.Id)); + + Assert.That(diagnostics.Select(d => d.Id), Is.EquivalentTo(expectedIdentifiers)); foreach (var diagnostic in diagnostics) { diff --git a/src/nunit.analyzers.tests/TestMethodAccessibilityLevel/TestMethodAccessibilityLevelCodeFixTests.cs b/src/nunit.analyzers.tests/TestMethodAccessibilityLevel/TestMethodAccessibilityLevelCodeFixTests.cs index 87bed0a1..7d54fa35 100644 --- a/src/nunit.analyzers.tests/TestMethodAccessibilityLevel/TestMethodAccessibilityLevelCodeFixTests.cs +++ b/src/nunit.analyzers.tests/TestMethodAccessibilityLevel/TestMethodAccessibilityLevelCodeFixTests.cs @@ -1,4 +1,3 @@ -using System.Collections.Generic; using Gu.Roslyn.Asserts; using Microsoft.CodeAnalysis.CodeFixes; using Microsoft.CodeAnalysis.Diagnostics; @@ -71,11 +70,11 @@ public void FixesDefaultImplicitAccessModifier() public void FixesDefaultImplicitAccessModifierWronglyIndented() { var testCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings($@" - [TestCase(1)] + [TestCase(1)] void ↓TestMethod(int i) {{ }}"); var fixedCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings($@" - [TestCase(1)] + [TestCase(1)] public void TestMethod(int i) {{ }}"); RoslynAssert.CodeFix(analyzer, fix, expectedDiagnostic, testCode, fixedCode); diff --git a/src/nunit.analyzers.tests/TestMethodUsage/TestMethodUsageAnalyzerTests.cs b/src/nunit.analyzers.tests/TestMethodUsage/TestMethodUsageAnalyzerTests.cs index 36d1f175..02fabcd5 100644 --- a/src/nunit.analyzers.tests/TestMethodUsage/TestMethodUsageAnalyzerTests.cs +++ b/src/nunit.analyzers.tests/TestMethodUsage/TestMethodUsageAnalyzerTests.cs @@ -44,7 +44,8 @@ public void VerifySupportedDiagnostics() AnalyzerIdentifiers.TestMethodAsyncExpectedResultAndNonGenricTaskReturnTypeUsage, AnalyzerIdentifiers.SimpleTestMethodHasParameters }; - CollectionAssert.AreEquivalent(expectedIdentifiers, diagnostics.Select(d => d.Id)); + + Assert.That(diagnostics.Select(d => d.Id), Is.EquivalentTo(expectedIdentifiers)); Assert.Multiple(() => { @@ -524,12 +525,12 @@ public void AnalyzeWhenSimpleTestMethodHasParameters() AnalyzerIdentifiers.SimpleTestMethodHasParameters); var testCode = TestUtility.WrapMethodInClassNamespaceAndAddUsings(@" - [↓Test] - [Category(""Test"")] - public void M(int p) - { - Assert.That(p, Is.EqualTo(42)); - }"); + [↓Test] + [Category(""Test"")] + public void M(int p) + { + Assert.That(p, Is.EqualTo(42)); + }"); var message = "The test method has '1' parameter(s), but only '0' argument(s) are supplied by attributes"; RoslynAssert.Diagnostics(analyzer, expectedDiagnostic.WithMessage(message), testCode); diff --git a/src/nunit.analyzers.tests/TestUtility.cs b/src/nunit.analyzers.tests/TestUtility.cs index 35b29d88..c58849be 100644 --- a/src/nunit.analyzers.tests/TestUtility.cs +++ b/src/nunit.analyzers.tests/TestUtility.cs @@ -10,6 +10,12 @@ internal static string WrapClassInNamespaceAndAddUsing(string code, using System; using System.Threading.Tasks; using NUnit.Framework; +#if NUNIT4 +using NUnit.Framework.Legacy; +#else +using ClassicAssert = NUnit.Framework.Assert; +#endif + #pragma warning restore CS8019 {additionalUsings} diff --git a/src/nunit.analyzers.tests/UpdateStringFormatToInterpolatableString/UpdateStringFormatToInterpolatableStringAnalyzerTests.cs b/src/nunit.analyzers.tests/UpdateStringFormatToInterpolatableString/UpdateStringFormatToInterpolatableStringAnalyzerTests.cs new file mode 100644 index 00000000..8f927f2e --- /dev/null +++ b/src/nunit.analyzers.tests/UpdateStringFormatToInterpolatableString/UpdateStringFormatToInterpolatableStringAnalyzerTests.cs @@ -0,0 +1,184 @@ +using System.Collections.Generic; +using System.Linq; +using Gu.Roslyn.Asserts; +using Microsoft.CodeAnalysis.Diagnostics; +using NUnit.Analyzers.Constants; +using NUnit.Analyzers.UpdateStringFormatToInterpolatableString; +using NUnit.Framework; + +namespace NUnit.Analyzers.Tests.UpdateStringFormatToInterpolatableString +{ + [TestFixture] + public sealed class UpdateStringFormatToInterpolatableStringAnalyzerTests + { + private readonly DiagnosticAnalyzer analyzer = new UpdateStringFormatToInterpolatableStringAnalyzer(); +#if !NUNIT4 + private readonly ExpectedDiagnostic diagnostic = ExpectedDiagnostic.Create(AnalyzerIdentifiers.UpdateStringFormatToInterpolatableString); +#endif + + private static IEnumerable NoArgumentsAsserts { get; } = new[] + { + NUnitFrameworkConstants.NameOfAssertPass, + NUnitFrameworkConstants.NameOfAssertFail, + NUnitFrameworkConstants.NameOfAssertIgnore, + NUnitFrameworkConstants.NameOfAssertInconclusive, + }; + + private static IEnumerable OneArgumentsAsserts { get; } = NoArgumentsAsserts.Concat(new[] { NUnitFrameworkConstants.NameOfAssertWarn }); + + [TestCaseSource(nameof(NoArgumentsAsserts))] + public void AnalyzeWhenNoArgumentsAreUsed(string method) + { + var testCode = TestUtility.WrapInTestMethod(@$" + Assert.{method}(); + "); + RoslynAssert.Valid(this.analyzer, testCode); + } + + [TestCaseSource(nameof(OneArgumentsAsserts))] + public void AnalyzeWhenOnlyMessageArgumentIsUsed(string method) + { + var testCode = TestUtility.WrapInTestMethod(@$" + Assert.{method}(""Message""); + "); + RoslynAssert.Valid(this.analyzer, testCode); + } + +#if !NUNIT4 + [TestCaseSource(nameof(OneArgumentsAsserts))] + public void AnalyzeWhenFormatAndArgumentsAreUsed(string method) + { + var testCode = TestUtility.WrapInTestMethod(@$" + ↓Assert.{method}(""Method: {{0}}"", ""{method}""); + "); + RoslynAssert.Diagnostics(this.analyzer, this.diagnostic, testCode); + } + + [TestCaseSource(nameof(OneArgumentsAsserts))] + public void AnalyzeWhenFormatAndArrayArgumentsAreUsed(string method) + { + var testCode = TestUtility.WrapInTestMethod(@$" + var values = new object[] {{ ""{method}"" }}; + ↓Assert.{method}(""Method: {{0}}"", values); + "); + RoslynAssert.Diagnostics(this.analyzer, this.diagnostic, testCode); + } +#endif + + [TestCaseSource(nameof(OneArgumentsAsserts))] + public void AnalyzeWhenFormattableStringIsUsed(string method) + { + var testCode = TestUtility.WrapInTestMethod(@$" + Assert.{method}($""Method: {{""method""}}""); + "); + RoslynAssert.Valid(this.analyzer, testCode); + } + + [Test] + public void AnalyzeAssertBoolWhenNoArgumentsAreUsed() + { + var testCode = TestUtility.WrapInTestMethod(@$" + Assert.That(true); + "); + RoslynAssert.Valid(this.analyzer, testCode); + } + + [Test] + public void AnalyzeAssertBoolWhenOnlyMessageArgumentIsUsed() + { + var testCode = TestUtility.WrapInTestMethod(@$" + Assert.That(false, ""Message""); + "); + RoslynAssert.Valid(this.analyzer, testCode); + } + +#if !NUNIT4 + [Test] + public void AnalyzeAssertBoolWhenFormatAndArgumentsAreUsed() + { + var testCode = TestUtility.WrapInTestMethod(@$" + ↓Assert.That(false, ""Method: {{0}}"", false.ToString()); + "); + RoslynAssert.Diagnostics(this.analyzer, this.diagnostic, testCode); + } +#endif + + [Test] + public void AnalyzeAssertBoolWhenFormattableStringIsUsed() + { + var testCode = TestUtility.WrapInTestMethod(@$" + Assert.That(false, $""Method: {{false}}""); + "); + RoslynAssert.Valid(this.analyzer, testCode); + } + + [Test] + public void AnalyzeAssertThatWhenNoArgumentsAreUsed() + { + var testCode = TestUtility.WrapInTestMethod(@$" + double pi = 3.1415; + Assert.That(pi, Is.EqualTo(3.1415).Within(0.0001)); + "); + RoslynAssert.Valid(this.analyzer, testCode); + } + + [Test] + public void AnalyzeAssertThatWhenOnlyMessageArgumentIsUsed() + { + var testCode = TestUtility.WrapInTestMethod(@$" + double pi = 3.1415; + Assert.That(pi, Is.EqualTo(3.1415).Within(0.0001), ""Message""); + "); + RoslynAssert.Valid(this.analyzer, testCode); + } + +#if !NUNIT4 + [Test] + public void AnalyzeAssertThatWhenFormatAndArgumentsAreUsed() + { + var testCode = TestUtility.WrapInTestMethod(@$" + double pi = 3.1415; + ↓Assert.That(pi, Is.EqualTo(3.1415).Within(0.0001), ""Method: {{0}}"", pi); + "); + RoslynAssert.Diagnostics(this.analyzer, this.diagnostic, testCode); + } +#endif + + [Test] + public void AnalyzeAssertThatWhenFormatStringIsUsed() + { + var testCode = TestUtility.WrapInTestMethod(@$" + double pi = 3.1415; + Assert.That(pi, Is.EqualTo(3.1415).Within(0.0001), $""Method: {{pi}}""); + "); + RoslynAssert.Valid(this.analyzer, testCode); + } + + [Test] + public void AnalyzeAssertDoesNotThrowWhenFormatAndArgumentsAreUsed() + { + var testCode = TestUtility.WrapInTestMethod(@$" + Assert.DoesNotThrow(() => SomeOperation(), ""Expected no exception to be thrown by {{0}}"", nameof(SomeOperation)); + + static void SomeOperation() + {{ + }} + "); + RoslynAssert.Valid(this.analyzer, testCode); + } + + [Test] + public void AnalyzeAssertThrowsWhenFormatAndArgumentsAreUsed() + { + var testCode = TestUtility.WrapInTestMethod(@$" + Assert.Throws(() => SomeOperation(), + ""Expected an InvalidOperationException exception to be thrown by {{0}}"", nameof(SomeOperation)); + + static void SomeOperation() + {{ + }} + "); + RoslynAssert.Valid(this.analyzer, testCode); + } + } +} diff --git a/src/nunit.analyzers.tests/UpdateStringFormatToInterpolatableString/UpdateStringFormatToInterpolatableStringCodeFixTests.cs b/src/nunit.analyzers.tests/UpdateStringFormatToInterpolatableString/UpdateStringFormatToInterpolatableStringCodeFixTests.cs new file mode 100644 index 00000000..179f3103 --- /dev/null +++ b/src/nunit.analyzers.tests/UpdateStringFormatToInterpolatableString/UpdateStringFormatToInterpolatableStringCodeFixTests.cs @@ -0,0 +1,112 @@ +#if !NUNIT4 + +using Gu.Roslyn.Asserts; +using Microsoft.CodeAnalysis.CodeFixes; +using Microsoft.CodeAnalysis.Diagnostics; +using NUnit.Analyzers.Constants; +using NUnit.Analyzers.UpdateStringFormatToInterpolatableString; +using NUnit.Framework; + +namespace NUnit.Analyzers.Tests.UpdateStringFormatToInterpolatableString +{ + [TestFixture] + public sealed class UpdateStringFormatToInterpolatableStringCodeFixTests + { + private static readonly DiagnosticAnalyzer analyzer = new UpdateStringFormatToInterpolatableStringAnalyzer(); + private static readonly CodeFixProvider fix = new UpdateStringFormatToInterpolatableStringCodeFix(); + private static readonly ExpectedDiagnostic expectedDiagnostic = + ExpectedDiagnostic.Create(AnalyzerIdentifiers.UpdateStringFormatToInterpolatableString); + + [Test] + public void VerifyGetFixableDiagnosticIds() + { + var ids = fix.FixableDiagnosticIds; + + Assert.That(ids, Is.EquivalentTo(new[] { AnalyzerIdentifiers.UpdateStringFormatToInterpolatableString })); + } + + [TestCase(NUnitFrameworkConstants.NameOfAssertIgnore)] + public void ConvertWhenNoMinimumParameters(string method) + { + var code = TestUtility.WrapInTestMethod(@$" + ↓Assert.{method}(""Method: {{0}}"", ""{method}""); + "); + var fixedCode = TestUtility.WrapInTestMethod($@" + Assert.{method}($""Method: {{""{method}""}}""); + "); + RoslynAssert.CodeFix(analyzer, fix, expectedDiagnostic, code, fixedCode); + } + + [Test] + public void ConvertWhenMinimumParametersIsOne() + { + var code = TestUtility.WrapInTestMethod(@" + const bool actual = false; + ↓Assert.That(actual, ""Expected actual value to be true, but was: {0}"", actual); + "); + var fixedCode = TestUtility.WrapInTestMethod(@" + const bool actual = false; + Assert.That(actual, $""Expected actual value to be true, but was: {actual}""); + "); + RoslynAssert.CodeFix(analyzer, fix, expectedDiagnostic, code, fixedCode); + } + + [Test] + public void ConvertWhenMinimumParametersIsTwo() + { + var code = TestUtility.WrapInTestMethod(@" + const int actual = 42; + ↓Assert.That(actual, Is.EqualTo(42), ""Expected actual value to be 42, but was: {0} at time {1:HH:mm:ss}"", actual, DateTime.Now); + "); + var fixedCode = TestUtility.WrapInTestMethod(@" + const int actual = 42; + Assert.That(actual, Is.EqualTo(42), $""Expected actual value to be 42, but was: {actual} at time {DateTime.Now:HH:mm:ss}""); + "); + RoslynAssert.CodeFix(analyzer, fix, expectedDiagnostic, code, fixedCode); + } + + // We need to double the backslashes as the text is formatted and we want the code to contain \n and not LF + [TestCase("Passed: {0}")] + [TestCase("Passed: {0} {{")] + [TestCase("Passed: {{{0}}}")] + [TestCase("{{{0}}}")] + [TestCase("Passed: \\\"{0}\\\"")] + [TestCase("Passed:\\n{0}")] + [TestCase("Passed:\\t\\\"{0}\\\"")] + public void TestConvertWithEmbeddedSpecialCharacters(string text) + { + var code = TestUtility.WrapInTestMethod($"↓Assert.Pass(\"{text}\", 42);"); + + string interpolatableText = text.Replace("{0}", "{42}"); + var fixedCode = TestUtility.WrapInTestMethod($"Assert.Pass($\"{interpolatableText}\");"); + + RoslynAssert.CodeFix(analyzer, fix, expectedDiagnostic, code, fixedCode); + } + + [TestCase("")] + [TestCase(":N1")] + [TestCase(",5")] + [TestCase(",-5")] + [TestCase(",5:N1")] + public void TestFormatModifiers(string modifier) + { + string argument = "1.23"; + var code = TestUtility.WrapInTestMethod($"↓Assert.Pass(\"{{0{modifier}}}\", {argument});"); + + var fixedCode = TestUtility.WrapInTestMethod($"Assert.Pass($\"{{{argument}{modifier}}}\");"); + + RoslynAssert.CodeFix(analyzer, fix, expectedDiagnostic, code, fixedCode); + } + + [Test] + public void TestEscapedBraces() + { + var code = TestUtility.WrapInTestMethod("↓Assert.Pass(\"{{{0}}}\", 42);"); + + var fixedCode = TestUtility.WrapInTestMethod("Assert.Pass($\"{{{42}}}\");"); + + RoslynAssert.CodeFix(analyzer, fix, expectedDiagnostic, code, fixedCode); + } + } +} +#endif diff --git a/src/nunit.analyzers.tests/WithinUsage/WithinUsageAnalyzerTests.cs b/src/nunit.analyzers.tests/WithinUsage/WithinUsageAnalyzerTests.cs index 9f74f542..6e0b7285 100644 --- a/src/nunit.analyzers.tests/WithinUsage/WithinUsageAnalyzerTests.cs +++ b/src/nunit.analyzers.tests/WithinUsage/WithinUsageAnalyzerTests.cs @@ -1,5 +1,9 @@ using System; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Linq; using Gu.Roslyn.Asserts; +using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Diagnostics; using NUnit.Analyzers.Constants; using NUnit.Analyzers.WithinUsage; @@ -13,6 +17,17 @@ public class WithinUsageAnalyzerTests private static readonly ExpectedDiagnostic expectedDiagnostic = ExpectedDiagnostic.Create(AnalyzerIdentifiers.WithinIncompatibleTypes); + private Settings settings; + + [OneTimeSetUp] + public void OneTimeSetUp() + { + IEnumerable existingReferences = Settings.Default.MetadataReferences ?? Enumerable.Empty(); + + this.settings = Settings.Default + .WithMetadataReferences(existingReferences.Concat(MetadataReferences.Transitive(typeof(ImmutableArray<>)))); + } + [TestCase(NUnitFrameworkConstants.NameOfIsEqualTo)] [TestCase(NUnitFrameworkConstants.NameOfIsLessThan)] [TestCase(NUnitFrameworkConstants.NameOfIsLessThanOrEqualTo)] @@ -193,7 +208,6 @@ public void AnalyzeWhenAppliedToCollectionsOfInValidTypes() RoslynAssert.Diagnostics(analyzer, expectedDiagnostic, testCode); } -#if !NETFRAMEWORK [Test] public void AnalyzeWhenAppliedToImmutableArrayOfValidTypes() { @@ -203,7 +217,7 @@ public void AnalyzeWhenAppliedToImmutableArrayOfValidTypes() Assert.That(ImmutableArray.Create(value), Is.EqualTo(ImmutableArray.Create(value2)).Within(2));", "using System.Collections.Immutable;"); - RoslynAssert.Valid(analyzer, testCode); + RoslynAssert.Valid(analyzer, testCode, this.settings); } [Test] @@ -215,9 +229,8 @@ public void AnalyzeWhenAppliedToImmutableArrayOfInValidTypes() Assert.That(ImmutableArray.Create(value), Is.EqualTo(ImmutableArray.Create(value2)).↓Within(2));", "using System.Collections.Immutable;"); - RoslynAssert.Diagnostics(analyzer, expectedDiagnostic, testCode); + RoslynAssert.Diagnostics(analyzer, expectedDiagnostic, testCode, this.settings); } -#endif [Test] public void AnalyzeWhenAppliedToChar() @@ -312,5 +325,119 @@ public void Test({type}? a, {type}? b) RoslynAssert.Valid(analyzer, testCode); } + + [TestCase("class")] + [TestCase("struct")] + public void AnalyzeWhenAppliedToUserDefinedType(string kind) + { + string testCode = TestUtility.WrapClassInNamespaceAndAddUsing(@$" + [TestFixture] + public sealed class TestClass + {{ + [Test] + public void TestMethod() + {{ + var instance = new UserDefinedType(1, 1.1, ""1.1""); + + Assert.That(new UserDefinedType(1, 1.2, ""1.1""), Is.EqualTo(instance).Within(0.1)); + }} + + private {kind} UserDefinedType + {{ + public UserDefinedType(int valueA, double valueB, string valueC) + {{ + ValueA = valueA; + ValueB = valueB; + ValueC = valueC; + }} + + public int ValueA {{ get; }} + public double ValueB {{ get; }} + public string ValueC {{ get; }} + }} + }}"); + + RoslynAssert.Valid(analyzer, testCode); + } + + [TestCase("class")] + [TestCase("struct")] + public void AnalyzeWhenAppliedToUserDefinedTypeOverridingEquals(string kind) + { + string testCode = TestUtility.WrapClassInNamespaceAndAddUsing(@$" + [TestFixture] + public sealed class TestClass + {{ + [Test] + public void TestMethod() + {{ + var instance = new UserDefinedType(1, 1.1, ""1.1""); + + Assert.That(new UserDefinedType(1, 1.2, ""1.1""), Is.EqualTo(instance).↓Within(0.1)); + }} + + private {kind} UserDefinedType + {{ + public UserDefinedType(int valueA, double valueB, string valueC) + {{ + ValueA = valueA; + ValueB = valueB; + ValueC = valueC; + }} + + public int ValueA {{ get; }} + public double ValueB {{ get; }} + public string ValueC {{ get; }} + + public override bool Equals(object? obj) + {{ + return obj is UserDefinedType other && + other.ValueA == ValueA && + other.ValueB == ValueB && + other.ValueC == ValueC; + }} + + public override int GetHashCode() + {{ + return ValueA.GetHashCode() ^ ValueB.GetHashCode() ^ ValueC.GetHashCode(); + }} + }} + }}"); + + RoslynAssert.Diagnostics(analyzer, expectedDiagnostic, testCode); + } + + [Test] + public void AnalyzeWhenAppliedToRecord() + { + string testCode = TestUtility.WrapClassInNamespaceAndAddUsing(@" + [TestFixture] + public sealed class TestClass + { + [Test] + public void TestMethod() + { + var instance = new SomeRecord(1, 1.1, ""1.1""); + + Assert.That(new SomeRecord(1, 1.2, ""1.1""), Is.EqualTo(instance).↓Within(0.1)); + } + + private sealed record SomeRecord + { + public SomeRecord(int valueA, double valueB, string valueC) + { + ValueA = valueA; + ValueB = valueB; + ValueC = valueC; + } + + public int ValueA { get; } + public double ValueB { get; } + public string ValueC { get; } + } + }"); + + RoslynAssert.Diagnostics(analyzer, expectedDiagnostic, testCode); + } } } diff --git a/src/nunit.analyzers.tests/WithinUsage/WithinUsageCodeFixTests.cs b/src/nunit.analyzers.tests/WithinUsage/WithinUsageCodeFixTests.cs index b7009f27..34def3b1 100644 --- a/src/nunit.analyzers.tests/WithinUsage/WithinUsageCodeFixTests.cs +++ b/src/nunit.analyzers.tests/WithinUsage/WithinUsageCodeFixTests.cs @@ -73,10 +73,10 @@ public void FixesWithinUsageOnConstraintWithIncompatibleExpectedTypeWithMessage( public void FixesWithinUsageOnConstraintWithIncompatibleExpectedTypeWithMessageAndParam() { var code = TestUtility.WrapInTestMethod( - @"Assert.That(""1"", Is.EqualTo(""1"").↓Within(1), ""message"", Guid.NewGuid());"); + @"Assert.That(""1"", Is.EqualTo(""1"").↓Within(1), ""message"");"); var fixedCode = TestUtility.WrapInTestMethod( - @"Assert.That(""1"", Is.EqualTo(""1""), ""message"", Guid.NewGuid());"); + @"Assert.That(""1"", Is.EqualTo(""1""), ""message"");"); RoslynAssert.CodeFix(analyzer, fix, expectedDiagnostic, code, fixedCode, fixTitle: WithinUsageCodeFix.RemoveWithinDescription); diff --git a/src/nunit.analyzers.tests/nunit.analyzers.tests.csproj b/src/nunit.analyzers.tests/nunit.analyzers.tests.csproj index 8b56be85..15cecccf 100644 --- a/src/nunit.analyzers.tests/nunit.analyzers.tests.csproj +++ b/src/nunit.analyzers.tests/nunit.analyzers.tests.csproj @@ -1,7 +1,12 @@ NUnit.Analyzers.Tests - net7.0;net462 + net6.0;net462 + 3 + + + + $(DefineConstants);NUNIT4 @@ -12,9 +17,16 @@ - - + + + + + + + + + diff --git a/src/nunit.analyzers/BaseAssertionAnalyzer.cs b/src/nunit.analyzers/BaseAssertionAnalyzer.cs index 53cd82f7..82f0e5b6 100644 --- a/src/nunit.analyzers/BaseAssertionAnalyzer.cs +++ b/src/nunit.analyzers/BaseAssertionAnalyzer.cs @@ -1,3 +1,6 @@ +using System; +using System.Collections.Generic; +using System.Linq; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Operations; @@ -11,27 +14,51 @@ public override void Initialize(AnalysisContext context) { context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None); context.EnableConcurrentExecution(); - context.RegisterOperationAction(this.AnalyzeInvocation, OperationKind.Invocation); + context.RegisterCompilationStartAction(this.AnalyzeCompilationStart); } - protected abstract void AnalyzeAssertInvocation(OperationAnalysisContext context, IInvocationOperation assertOperation); + protected virtual void AnalyzeAssertInvocation(OperationAnalysisContext context, IInvocationOperation assertOperation) + { + throw new NotImplementedException($"You must override one of the {nameof(AnalyzeAssertInvocation)} overloads."); + } + + protected virtual void AnalyzeAssertInvocation(Version nunitVersion, OperationAnalysisContext context, IInvocationOperation assertOperation) + { + this.AnalyzeAssertInvocation(context, assertOperation); + } - protected virtual bool IsAssert(IInvocationOperation invocationOperation) + protected virtual bool IsAssert(bool hasClassicAssert, IInvocationOperation invocationOperation) { - return invocationOperation.TargetMethod.ContainingType.IsAssert(); + INamedTypeSymbol containingType = invocationOperation.TargetMethod.ContainingType; + return containingType.IsAssert() || (hasClassicAssert && containingType.IsClassicAssert()); } - private void AnalyzeInvocation(OperationAnalysisContext context) + private void AnalyzeInvocation(Version nunitVersion, OperationAnalysisContext context) { if (context.Operation is not IInvocationOperation invocationOperation) return; - if (!this.IsAssert(invocationOperation)) + if (!this.IsAssert(nunitVersion.Major >= 4, invocationOperation)) return; context.CancellationToken.ThrowIfCancellationRequested(); - this.AnalyzeAssertInvocation(context, invocationOperation); + this.AnalyzeAssertInvocation(nunitVersion, context, invocationOperation); + } + + private void AnalyzeCompilationStart(CompilationStartAnalysisContext context) + { + IEnumerable referencedAssemblies = context.Compilation.ReferencedAssemblyNames; + + AssemblyIdentity? nunit = referencedAssemblies.SingleOrDefault(a => a.Name.Equals("nunit.framework", StringComparison.OrdinalIgnoreCase)); + + if (nunit is null) + { + // Who would use NUnit.Analyzers without NUnit? + return; + } + + context.RegisterOperationAction((context) => this.AnalyzeInvocation(nunit.Version, context), OperationKind.Invocation); } } } diff --git a/src/nunit.analyzers/ClassicAssertionAnalyzer.cs b/src/nunit.analyzers/ClassicAssertionAnalyzer.cs new file mode 100644 index 00000000..5e164d88 --- /dev/null +++ b/src/nunit.analyzers/ClassicAssertionAnalyzer.cs @@ -0,0 +1,16 @@ +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Operations; +using NUnit.Analyzers.Extensions; + +namespace NUnit.Analyzers +{ + public abstract class ClassicAssertionAnalyzer : BaseAssertionAnalyzer + { + protected override bool IsAssert(bool hasClassicAssert, IInvocationOperation invocationOperation) + { + INamedTypeSymbol containingType = invocationOperation.TargetMethod.ContainingType; + + return hasClassicAssert ? containingType.IsClassicAssert() : containingType.IsAssert(); + } + } +} diff --git a/src/nunit.analyzers/ClassicModelAssertUsage/AreNotEqualClassicModelAssertUsageCodeFix.cs b/src/nunit.analyzers/ClassicModelAssertUsage/AreNotEqualClassicModelAssertUsageCodeFix.cs index 66275644..34e1d63d 100644 --- a/src/nunit.analyzers/ClassicModelAssertUsage/AreNotEqualClassicModelAssertUsageCodeFix.cs +++ b/src/nunit.analyzers/ClassicModelAssertUsage/AreNotEqualClassicModelAssertUsageCodeFix.cs @@ -26,7 +26,7 @@ protected override void UpdateArguments(Diagnostic diagnostic, List { - { AnalyzerPropertyKeys.ModelName, invocationSymbol.Name }, - { - AnalyzerPropertyKeys.HasToleranceValue, + [AnalyzerPropertyKeys.ModelName] = invocationSymbol.Name, + [AnalyzerPropertyKeys.HasToleranceValue] = (invocationSymbol.Name == NameOfAssertAreEqual && invocationSymbol.Parameters.Length >= 3 && - invocationSymbol.Parameters[2].Type.SpecialType == SpecialType.System_Double).ToString() - }, - { AnalyzerPropertyKeys.IsGenericMethod, invocationSymbol.IsGenericMethod.ToString() }, + invocationSymbol.Parameters[2].Type.SpecialType == SpecialType.System_Double).ToString(), }.ToImmutableDictionary(); } } diff --git a/src/nunit.analyzers/ClassicModelAssertUsage/ClassicModelAssertUsageCodeFix.cs b/src/nunit.analyzers/ClassicModelAssertUsage/ClassicModelAssertUsageCodeFix.cs index f21ed002..a822e7da 100644 --- a/src/nunit.analyzers/ClassicModelAssertUsage/ClassicModelAssertUsageCodeFix.cs +++ b/src/nunit.analyzers/ClassicModelAssertUsage/ClassicModelAssertUsageCodeFix.cs @@ -7,8 +7,8 @@ using Microsoft.CodeAnalysis.CodeFixes; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; -using NUnit.Analyzers.Constants; using NUnit.Analyzers.Extensions; +using NUnit.Analyzers.Helpers; namespace NUnit.Analyzers.ClassicModelAssertUsage { @@ -17,6 +17,8 @@ public abstract class ClassicModelAssertUsageCodeFix { internal const string TransformToConstraintModelDescription = "Transform to constraint model"; + protected virtual int MinimumNumberOfParameters { get; } = 2; + protected virtual string Title => TransformToConstraintModelDescription; public sealed override FixAllProvider GetFixAllProvider() @@ -36,80 +38,23 @@ public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context) context.CancellationToken.ThrowIfCancellationRequested(); var diagnostic = context.Diagnostics.First(); - var invocationNode = root.FindNode(diagnostic.Location.SourceSpan) as InvocationExpressionSyntax; + var node = root.FindNode(diagnostic.Location.SourceSpan); + var invocationNode = node as InvocationExpressionSyntax; if (invocationNode is null) return; - var invocationIdentifier = diagnostic.Properties[AnalyzerPropertyKeys.ModelName]; - var isGenericMethod = diagnostic.Properties[AnalyzerPropertyKeys.IsGenericMethod] == true.ToString(); - var semanticModel = await context.Document.GetSemanticModelAsync(context.CancellationToken).ConfigureAwait(false); - string? GetUserDefinedImplicitTypeConversion(ExpressionSyntax expression) - { - var typeInfo = semanticModel.GetTypeInfo(expression, context.CancellationToken); - var convertedType = typeInfo.ConvertedType; - if (convertedType is null) - { - return null; - } + // Replace the original ClassicAssert. invocation name into Assert.That + var newInvocationNode = invocationNode.UpdateClassicAssertToAssertThat(out TypeArgumentListSyntax? typeArguments); - var conversion = semanticModel.ClassifyConversion(expression, convertedType); - - if (!conversion.IsUserDefined) - { - return null; - } - - return convertedType.ToString(); - } - - // First, replace the original method invocation name to "That". - var descendantNodes = invocationNode.DescendantNodes(_ => true).ToArray(); - - SyntaxNode methodNode; - TypeArgumentListSyntax? typeArguments; - if (isGenericMethod) - { - methodNode = descendantNodes - .Where(_ => _.IsKind(SyntaxKind.GenericName) && - ((GenericNameSyntax)_).Identifier.Text == invocationIdentifier) - .Single(); - typeArguments = descendantNodes - .Where(_ => _.IsKind(SyntaxKind.TypeArgumentList)) - .Cast() - .First(); - } - else - { - methodNode = descendantNodes - .Where(_ => _.IsKind(SyntaxKind.IdentifierName) && - ((IdentifierNameSyntax)_).Identifier.Text == invocationIdentifier) - .Single(); - typeArguments = null; - } - - var newInvocationNode = invocationNode.ReplaceNode( - methodNode, - SyntaxFactory.IdentifierName(NUnitFrameworkConstants.NameOfAssertThat)); + if (newInvocationNode is null) + return; // Now, replace the arguments. List arguments = invocationNode.ArgumentList.Arguments.ToList(); - ArgumentSyntax CastIfNecessary(ArgumentSyntax argument) - { - string? implicitTypeConversion = GetUserDefinedImplicitTypeConversion(argument.Expression); - if (implicitTypeConversion is null) - return argument; - - // Assert.That only expects objects whilst the classic methods have overloads - // Add an explicit cast operation for the first argument. - return SyntaxFactory.Argument(SyntaxFactory.CastExpression( - SyntaxFactory.ParseTypeName(implicitTypeConversion), - argument.Expression)); - } - // See if we need to cast the arguments when they were using a specific classic overload. arguments[0] = CastIfNecessary(arguments[0]); if (arguments.Count > 1) @@ -121,6 +66,9 @@ ArgumentSyntax CastIfNecessary(ArgumentSyntax argument) else this.UpdateArguments(diagnostic, arguments, typeArguments); + // Do the format spec, params to formattable string conversion + CodeFixHelper.UpdateStringFormatToFormattableString(arguments, this.MinimumNumberOfParameters); + var newArgumentsList = invocationNode.ArgumentList.WithArguments(arguments); newInvocationNode = newInvocationNode.WithArgumentList(newArgumentsList); @@ -133,6 +81,38 @@ ArgumentSyntax CastIfNecessary(ArgumentSyntax argument) this.Title, _ => Task.FromResult(context.Document.WithSyntaxRoot(newRoot)), this.Title), diagnostic); + + ArgumentSyntax CastIfNecessary(ArgumentSyntax argument) + { + string? implicitTypeConversion = GetUserDefinedImplicitTypeConversion(argument.Expression); + if (implicitTypeConversion is null) + return argument; + + // Assert.That only expects objects whilst the classic methods have overloads + // Add an explicit cast operation for the first argument. + return SyntaxFactory.Argument(SyntaxFactory.CastExpression( + SyntaxFactory.ParseTypeName(implicitTypeConversion), + argument.Expression)); + } + + string? GetUserDefinedImplicitTypeConversion(ExpressionSyntax expression) + { + var typeInfo = semanticModel.GetTypeInfo(expression, context.CancellationToken); + var convertedType = typeInfo.ConvertedType; + if (convertedType is null) + { + return null; + } + + var conversion = semanticModel.ClassifyConversion(expression, convertedType); + + if (!conversion.IsUserDefined) + { + return null; + } + + return convertedType.ToString(); + } } protected virtual void UpdateArguments(Diagnostic diagnostic, List arguments, TypeArgumentListSyntax typeArguments) diff --git a/src/nunit.analyzers/ClassicModelAssertUsage/ClassicModelUsageAnalyzerConstants.cs b/src/nunit.analyzers/ClassicModelAssertUsage/ClassicModelUsageAnalyzerConstants.cs index 85eb5015..a95eec1f 100644 --- a/src/nunit.analyzers/ClassicModelAssertUsage/ClassicModelUsageAnalyzerConstants.cs +++ b/src/nunit.analyzers/ClassicModelAssertUsage/ClassicModelUsageAnalyzerConstants.cs @@ -2,100 +2,100 @@ namespace NUnit.Analyzers.ClassicModelAssertUsage { internal static class ClassicModelUsageAnalyzerConstants { - internal const string IsTrueTitle = "Consider using Assert.That(expr, Is.True) instead of Assert.IsTrue(expr)"; - internal const string IsTrueMessage = "Consider using the constraint model, Assert.That(expr, Is.True), instead of the classic model, Assert.IsTrue(expr)"; - internal const string IsTrueDescription = "Consider using the constraint model, Assert.That(expr, Is.True), instead of the classic model, Assert.IsTrue(expr)."; + internal const string IsTrueTitle = "Consider using Assert.That(expr, Is.True) instead of ClassicAssert.IsTrue(expr)"; + internal const string IsTrueMessage = "Consider using the constraint model, Assert.That(expr, Is.True), instead of the classic model, ClassicAssert.IsTrue(expr)"; + internal const string IsTrueDescription = "Consider using the constraint model, Assert.That(expr, Is.True), instead of the classic model, ClassicAssert.IsTrue(expr)."; - internal const string TrueTitle = "Consider using Assert.That(expr, Is.True) instead of Assert.True(expr)"; - internal const string TrueMessage = "Consider using the constraint model, Assert.That(expr, Is.True), instead of the classic model, Assert.True(expr)"; - internal const string TrueDescription = "Consider using the constraint model, Assert.That(expr, Is.True), instead of the classic model, Assert.True(expr)."; + internal const string TrueTitle = "Consider using Assert.That(expr, Is.True) instead of ClassicAssert.True(expr)"; + internal const string TrueMessage = "Consider using the constraint model, Assert.That(expr, Is.True), instead of the classic model, ClassicAssert.True(expr)"; + internal const string TrueDescription = "Consider using the constraint model, Assert.That(expr, Is.True), instead of the classic model, ClassicAssert.True(expr)."; - internal const string IsFalseTitle = "Consider using Assert.That(expr, Is.False) instead of Assert.IsFalse(expr)"; - internal const string IsFalseMessage = "Consider using the constraint model, Assert.That(expr, Is.False), instead of the classic model, Assert.IsFalse(expr)"; - internal const string IsFalseDescription = "Consider using the constraint model, Assert.That(expr, Is.False), instead of the classic model, Assert.IsFalse(expr)."; + internal const string IsFalseTitle = "Consider using Assert.That(expr, Is.False) instead of ClassicAssert.IsFalse(expr)"; + internal const string IsFalseMessage = "Consider using the constraint model, Assert.That(expr, Is.False), instead of the classic model, ClassicAssert.IsFalse(expr)"; + internal const string IsFalseDescription = "Consider using the constraint model, Assert.That(expr, Is.False), instead of the classic model, ClassicAssert.IsFalse(expr)."; - internal const string FalseTitle = "Consider using Assert.That(expr, Is.False) instead of Assert.False(expr)"; - internal const string FalseMessage = "Consider using the constraint model, Assert.That(expr, Is.False), instead of the classic model, Assert.False(expr)"; - internal const string FalseDescription = "Consider using the constraint model, Assert.That(expr, Is.False), instead of the classic model, Assert.False(expr)."; + internal const string FalseTitle = "Consider using Assert.That(expr, Is.False) instead of ClassicAssert.False(expr)"; + internal const string FalseMessage = "Consider using the constraint model, Assert.That(expr, Is.False), instead of the classic model, ClassicAssert.False(expr)"; + internal const string FalseDescription = "Consider using the constraint model, Assert.That(expr, Is.False), instead of the classic model, ClassicAssert.False(expr)."; - internal const string AreEqualTitle = "Consider using Assert.That(actual, Is.EqualTo(expected)) instead of Assert.AreEqual(expected, actual)"; - internal const string AreEqualMessage = "Consider using the constraint model, Assert.That(actual, Is.EqualTo(expected)), instead of the classic model, Assert.AreEqual(expected, actual)"; - internal const string AreEqualDescription = "Consider using the constraint model, Assert.That(actual, Is.EqualTo(expected)), instead of the classic model, Assert.AreEqual(expected, actual)."; + internal const string AreEqualTitle = "Consider using Assert.That(actual, Is.EqualTo(expected)) instead of ClassicAssert.AreEqual(expected, actual)"; + internal const string AreEqualMessage = "Consider using the constraint model, Assert.That(actual, Is.EqualTo(expected)), instead of the classic model, ClassicAssert.AreEqual(expected, actual)"; + internal const string AreEqualDescription = "Consider using the constraint model, Assert.That(actual, Is.EqualTo(expected)), instead of the classic model, ClassicAssert.AreEqual(expected, actual)."; - internal const string AreNotEqualTitle = "Consider using Assert.That(actual, Is.Not.EqualTo(expected)) instead of Assert.AreNotEqual(expected, actual)"; - internal const string AreNotEqualMessage = "Consider using the constraint model, Assert.That(actual, Is.Not.EqualTo(expected)), instead of the classic model, Assert.AreNotEqual(expected, actual)"; - internal const string AreNotEqualDescription = "Consider using the constraint model, Assert.That(actual, Is.Not.EqualTo(expected)), instead of the classic model, Assert.AreNotEqual(expected, actual)."; + internal const string AreNotEqualTitle = "Consider using Assert.That(actual, Is.Not.EqualTo(expected)) instead of ClassicAssert.AreNotEqual(expected, actual)"; + internal const string AreNotEqualMessage = "Consider using the constraint model, Assert.That(actual, Is.Not.EqualTo(expected)), instead of the classic model, ClassicAssert.AreNotEqual(expected, actual)"; + internal const string AreNotEqualDescription = "Consider using the constraint model, Assert.That(actual, Is.Not.EqualTo(expected)), instead of the classic model, ClassicAssert.AreNotEqual(expected, actual)."; - internal const string AreSameTitle = "Consider using Assert.That(actual, Is.SameAs(expected)) instead of Assert.AreSame(expected, actual)"; - internal const string AreSameMessage = "Consider using the constraint model, Assert.That(actual, Is.SameAs(expected)), instead of the classic model, Assert.AreSame(expected, actual)"; - internal const string AreSameDescription = "Consider using the constraint model, Assert.That(actual, Is.SameAs(expected)), instead of the classic model, Assert.AreSame(expected, actual)."; + internal const string AreSameTitle = "Consider using Assert.That(actual, Is.SameAs(expected)) instead of ClassicAssert.AreSame(expected, actual)"; + internal const string AreSameMessage = "Consider using the constraint model, Assert.That(actual, Is.SameAs(expected)), instead of the classic model, ClassicAssert.AreSame(expected, actual)"; + internal const string AreSameDescription = "Consider using the constraint model, Assert.That(actual, Is.SameAs(expected)), instead of the classic model, ClassicAssert.AreSame(expected, actual)."; - internal const string IsNullTitle = "Consider using Assert.That(expr, Is.Null) instead of Assert.IsNull(expr)"; - internal const string IsNullMessage = "Consider using the constraint model, Assert.That(expr, Is.Null), instead of the classic model, Assert.IsNull(expr)"; - internal const string IsNullDescription = "Consider using the constraint model, Assert.That(expr, Is.Null), instead of the classic model, Assert.IsNull(expr)."; + internal const string IsNullTitle = "Consider using Assert.That(expr, Is.Null) instead of ClassicAssert.IsNull(expr)"; + internal const string IsNullMessage = "Consider using the constraint model, Assert.That(expr, Is.Null), instead of the classic model, ClassicAssert.IsNull(expr)"; + internal const string IsNullDescription = "Consider using the constraint model, Assert.That(expr, Is.Null), instead of the classic model, ClassicAssert.IsNull(expr)."; - internal const string NullTitle = "Consider using Assert.That(expr, Is.Null) instead of Assert.Null(expr)"; - internal const string NullMessage = "Consider using the constraint model, Assert.That(expr, Is.Null), instead of the classic model, Assert.Null(expr)"; - internal const string NullDescription = "Consider using the constraint model, Assert.That(expr, Is.Null), instead of the classic model, Assert.Null(expr)."; + internal const string NullTitle = "Consider using Assert.That(expr, Is.Null) instead of ClassicAssert.Null(expr)"; + internal const string NullMessage = "Consider using the constraint model, Assert.That(expr, Is.Null), instead of the classic model, ClassicAssert.Null(expr)"; + internal const string NullDescription = "Consider using the constraint model, Assert.That(expr, Is.Null), instead of the classic model, ClassicAssert.Null(expr)."; - internal const string IsNotNullTitle = "Consider using Assert.That(expr, Is.Not.Null) instead of Assert.IsNotNull(expr)"; - internal const string IsNotNullMessage = "Consider using the constraint model, Assert.That(expr, Is.Not.Null), instead of the classic model, Assert.IsNotNull(expr)"; - internal const string IsNotNullDescription = "Consider using the constraint model, Assert.That(expr, Is.Not.Null), instead of the classic model, Assert.IsNotNull(expr)."; + internal const string IsNotNullTitle = "Consider using Assert.That(expr, Is.Not.Null) instead of ClassicAssert.IsNotNull(expr)"; + internal const string IsNotNullMessage = "Consider using the constraint model, Assert.That(expr, Is.Not.Null), instead of the classic model, ClassicAssert.IsNotNull(expr)"; + internal const string IsNotNullDescription = "Consider using the constraint model, Assert.That(expr, Is.Not.Null), instead of the classic model, ClassicAssert.IsNotNull(expr)."; - internal const string NotNullTitle = "Consider using Assert.That(expr, Is.Not.Null) instead of Assert.NotNull(expr)"; - internal const string NotNullMessage = "Consider using the constraint model, Assert.That(expr, Is.Not.Null), instead of the classic model, Assert.NotNull(expr)"; - internal const string NotNullDescription = "Consider using the constraint model, Assert.That(expr, Is.Not.Null), instead of the classic model, Assert.NotNull(expr)."; + internal const string NotNullTitle = "Consider using Assert.That(expr, Is.Not.Null) instead of ClassicAssert.NotNull(expr)"; + internal const string NotNullMessage = "Consider using the constraint model, Assert.That(expr, Is.Not.Null), instead of the classic model, ClassicAssert.NotNull(expr)"; + internal const string NotNullDescription = "Consider using the constraint model, Assert.That(expr, Is.Not.Null), instead of the classic model, ClassicAssert.NotNull(expr)."; - internal const string GreaterTitle = "Consider using Assert.That(actual, Is.GreaterThan(expected)) instead of Assert.Greater(actual, expected)"; - internal const string GreaterMessage = "Consider using the constraint model, Assert.That(actual, Is.GreaterThan(expected)), instead of the classic model, Assert.Greater(actual, expected)"; - internal const string GreaterDescription = "Consider using the constraint model, Assert.That(actual, Is.GreaterThan(expected)), instead of the classic model, Assert.Greater(actual, expected)."; + internal const string GreaterTitle = "Consider using Assert.That(actual, Is.GreaterThan(expected)) instead of ClassicAssert.Greater(actual, expected)"; + internal const string GreaterMessage = "Consider using the constraint model, Assert.That(actual, Is.GreaterThan(expected)), instead of the classic model, ClassicAssert.Greater(actual, expected)"; + internal const string GreaterDescription = "Consider using the constraint model, Assert.That(actual, Is.GreaterThan(expected)), instead of the classic model, ClassicAssert.Greater(actual, expected)."; - internal const string GreaterOrEqualTitle = "Consider using Assert.That(actual, Is.GreaterThanOrEqualTo(expected)) instead of Assert.GreaterOrEqual(actual, expected)"; - internal const string GreaterOrEqualMessage = "Consider using the constraint model, Assert.That(actual, Is.GreaterThanOrEqualTo(expected)), instead of the classic model, Assert.GreaterOrEqual(actual, expected)"; - internal const string GreaterOrEqualDescription = "Consider using the constraint model, Assert.That(actual, Is.GreaterThanOrEqualTo(expected)), instead of the classic model, Assert.GreaterOrEqual(actual, expected)."; + internal const string GreaterOrEqualTitle = "Consider using Assert.That(actual, Is.GreaterThanOrEqualTo(expected)) instead of ClassicAssert.GreaterOrEqual(actual, expected)"; + internal const string GreaterOrEqualMessage = "Consider using the constraint model, Assert.That(actual, Is.GreaterThanOrEqualTo(expected)), instead of the classic model, ClassicAssert.GreaterOrEqual(actual, expected)"; + internal const string GreaterOrEqualDescription = "Consider using the constraint model, Assert.That(actual, Is.GreaterThanOrEqualTo(expected)), instead of the classic model, ClassicAssert.GreaterOrEqual(actual, expected)."; - internal const string LessTitle = "Consider using Assert.That(actual, Is.LessThan(expected)) instead of Assert.Less(actual, expected)"; - internal const string LessMessage = "Consider using the constraint model, Assert.That(actual, Is.LessThan(expected)), instead of the classic model, Assert.Less(actual, expected)"; - internal const string LessDescription = "Consider using the constraint model, Assert.That(actual, Is.LessThan(expected)), instead of the classic model, Assert.Less(actual, expected)."; + internal const string LessTitle = "Consider using Assert.That(actual, Is.LessThan(expected)) instead of ClassicAssert.Less(actual, expected)"; + internal const string LessMessage = "Consider using the constraint model, Assert.That(actual, Is.LessThan(expected)), instead of the classic model, ClassicAssert.Less(actual, expected)"; + internal const string LessDescription = "Consider using the constraint model, Assert.That(actual, Is.LessThan(expected)), instead of the classic model, ClassicAssert.Less(actual, expected)."; - internal const string LessOrEqualTitle = "Consider using Assert.That(actual, Is.LessThanOrEqualTo(expected)) instead of Assert.LessOrEqual(actual, expected)"; - internal const string LessOrEqualMessage = "Consider using the constraint model, Assert.That(actual, Is.LessThanOrEqualTo(expected)), instead of the classic model, Assert.LessOrEqual(actual, expected)"; - internal const string LessOrEqualDescription = "Consider using the constraint model, Assert.That(actual, Is.LessThanOrEqualTo(expected)), instead of the classic model, Assert.LessOrEqual(actual, expected)."; + internal const string LessOrEqualTitle = "Consider using Assert.That(actual, Is.LessThanOrEqualTo(expected)) instead of ClassicAssert.LessOrEqual(actual, expected)"; + internal const string LessOrEqualMessage = "Consider using the constraint model, Assert.That(actual, Is.LessThanOrEqualTo(expected)), instead of the classic model, ClassicAssert.LessOrEqual(actual, expected)"; + internal const string LessOrEqualDescription = "Consider using the constraint model, Assert.That(actual, Is.LessThanOrEqualTo(expected)), instead of the classic model, ClassicAssert.LessOrEqual(actual, expected)."; - internal const string AreNotSameTitle = "Consider using Assert.That(actual, Is.Not.SameAs(expected)) instead of Assert.AreNotSame(expected, actual)"; - internal const string AreNotSameMessage = "Consider using the constraint model, Assert.That(actual, Is.Not.SameAs(expected)), instead of the classic model, Assert.AreNotSame(expected, actual)"; - internal const string AreNotSameDescription = "Consider using the constraint model, Assert.That(actual, Is.Not.SameAs(expected)), instead of the classic model, Assert.AreNotSame(expected, actual)."; + internal const string AreNotSameTitle = "Consider using Assert.That(actual, Is.Not.SameAs(expected)) instead of ClassicAssert.AreNotSame(expected, actual)"; + internal const string AreNotSameMessage = "Consider using the constraint model, Assert.That(actual, Is.Not.SameAs(expected)), instead of the classic model, ClassicAssert.AreNotSame(expected, actual)"; + internal const string AreNotSameDescription = "Consider using the constraint model, Assert.That(actual, Is.Not.SameAs(expected)), instead of the classic model, ClassicAssert.AreNotSame(expected, actual)."; - internal const string ZeroTitle = "Consider using Assert.That(expr, Is.Zero) instead of Assert.Zero(expr)"; - internal const string ZeroMessage = "Consider using the constraint model, Assert.That(expr, Is.Zero), instead of the classic model, Assert.Zero(expr)"; - internal const string ZeroDescription = "Consider using the constraint model, Assert.That(expr, Is.Zero), instead of the classic model, Assert.Zero(expr)."; + internal const string ZeroTitle = "Consider using Assert.That(expr, Is.Zero) instead of ClassicAssert.Zero(expr)"; + internal const string ZeroMessage = "Consider using the constraint model, Assert.That(expr, Is.Zero), instead of the classic model, ClassicAssert.Zero(expr)"; + internal const string ZeroDescription = "Consider using the constraint model, Assert.That(expr, Is.Zero), instead of the classic model, ClassicAssert.Zero(expr)."; - internal const string NotZeroTitle = "Consider using Assert.That(expr, Is.Not.Zero) instead of Assert.NotZero(expr)"; - internal const string NotZeroMessage = "Consider using the constraint model, Assert.That(expr, Is.Not.Zero), instead of the classic model, Assert.NotZero(expr)"; - internal const string NotZeroDescription = "Consider using the constraint model, Assert.That(expr, Is.Not.Zero), instead of the classic model, Assert.NotZero(expr)."; + internal const string NotZeroTitle = "Consider using Assert.That(expr, Is.Not.Zero) instead of ClassicAssert.NotZero(expr)"; + internal const string NotZeroMessage = "Consider using the constraint model, Assert.That(expr, Is.Not.Zero), instead of the classic model, ClassicAssert.NotZero(expr)"; + internal const string NotZeroDescription = "Consider using the constraint model, Assert.That(expr, Is.Not.Zero), instead of the classic model, ClassicAssert.NotZero(expr)."; - internal const string IsNaNTitle = "Consider using Assert.That(expr, Is.NaN) instead of Assert.IsNaN(expr)"; - internal const string IsNaNMessage = "Consider using the constraint model, Assert.That(expr, Is.NaN), instead of the classic model, Assert.IsNaN(expr)"; - internal const string IsNaNDescription = "Consider using the constraint model, Assert.That(expr, Is.NaN), instead of the classic model, Assert.IsNaN(expr)."; + internal const string IsNaNTitle = "Consider using Assert.That(expr, Is.NaN) instead of ClassicAssert.IsNaN(expr)"; + internal const string IsNaNMessage = "Consider using the constraint model, Assert.That(expr, Is.NaN), instead of the classic model, ClassicAssert.IsNaN(expr)"; + internal const string IsNaNDescription = "Consider using the constraint model, Assert.That(expr, Is.NaN), instead of the classic model, ClassicAssert.IsNaN(expr)."; - internal const string IsEmptyTitle = "Consider using Assert.That(collection, Is.Empty) instead of Assert.IsEmpty(collection)"; - internal const string IsEmptyMessage = "Consider using the constraint model, Assert.That(collection, Is.Empty), instead of the classic model, Assert.IsEmpty(collection)"; - internal const string IsEmptyDescription = "Consider using the constraint model, Assert.That(collection, Is.Empty), instead of the classic model, Assert.IsEmpty(collection)."; + internal const string IsEmptyTitle = "Consider using Assert.That(collection, Is.Empty) instead of ClassicAssert.IsEmpty(collection)"; + internal const string IsEmptyMessage = "Consider using the constraint model, Assert.That(collection, Is.Empty), instead of the classic model, ClassicAssert.IsEmpty(collection)"; + internal const string IsEmptyDescription = "Consider using the constraint model, Assert.That(collection, Is.Empty), instead of the classic model, ClassicAssert.IsEmpty(collection)."; - internal const string IsNotEmptyTitle = "Consider using Assert.That(collection, Is.Not.Empty) instead of Assert.IsNotEmpty(collection)"; - internal const string IsNotEmptyMessage = "Consider using the constraint model, Assert.That(collection, Is.Not.Empty), instead of the classic model, Assert.IsNotEmpty(collection)"; - internal const string IsNotEmptyDescription = "Consider using the constraint model, Assert.That(collection, Is.Not.Empty), instead of the classic model, Assert.IsNotEmpty(collection)."; + internal const string IsNotEmptyTitle = "Consider using Assert.That(collection, Is.Not.Empty) instead of ClassicAssert.IsNotEmpty(collection)"; + internal const string IsNotEmptyMessage = "Consider using the constraint model, Assert.That(collection, Is.Not.Empty), instead of the classic model, ClassicAssert.IsNotEmpty(collection)"; + internal const string IsNotEmptyDescription = "Consider using the constraint model, Assert.That(collection, Is.Not.Empty), instead of the classic model, ClassicAssert.IsNotEmpty(collection)."; - internal const string ContainsTitle = "Consider using Assert.That(collection, Does.Contain(instance)) instead of Assert.Contains(instance, collection)"; - internal const string ContainsMessage = "Consider using the constraint model, Assert.That(collection, Does.Contain(instance)), instead of the classic model, Assert.Contains(instance, collection)"; - internal const string ContainsDescription = "Consider using the constraint model, Assert.That(collection, Does.Contain(instance)), instead of the classic model, Assert.Contains(instance, collection)."; + internal const string ContainsTitle = "Consider using Assert.That(collection, Does.Contain(instance)) instead of ClassicAssert.Contains(instance, collection)"; + internal const string ContainsMessage = "Consider using the constraint model, Assert.That(collection, Does.Contain(instance)), instead of the classic model, ClassicAssert.Contains(instance, collection)"; + internal const string ContainsDescription = "Consider using the constraint model, Assert.That(collection, Does.Contain(instance)), instead of the classic model, ClassicAssert.Contains(instance, collection)."; - internal const string IsInstanceOfTitle = "Consider using Assert.That(actual, Is.InstanceOf(expected)) instead of Assert.IsInstanceOf(expected, actual)"; - internal const string IsInstanceOfMessage = "Consider using the constraint model, Assert.That(actual, Is.InstanceOf(expected)), instead of the classic model, Assert.IsInstanceOf(expected, actual)"; - internal const string IsInstanceOfDescription = "Consider using the constraint model, Assert.That(actual, Is.InstanceOf(expected)), instead of the classic model, Assert.IsInstanceOf(expected, actual)."; + internal const string IsInstanceOfTitle = "Consider using Assert.That(actual, Is.InstanceOf(expected)) instead of ClassicAssert.IsInstanceOf(expected, actual)"; + internal const string IsInstanceOfMessage = "Consider using the constraint model, Assert.That(actual, Is.InstanceOf(expected)), instead of the classic model, ClassicAssert.IsInstanceOf(expected, actual)"; + internal const string IsInstanceOfDescription = "Consider using the constraint model, Assert.That(actual, Is.InstanceOf(expected)), instead of the classic model, ClassicAssert.IsInstanceOf(expected, actual)."; - internal const string IsNotInstanceOfTitle = "Consider using Assert.That(actual, Is.Not.InstanceOf(expected)) instead of Assert.IsNotInstanceOf(expected, actual)"; - internal const string IsNotInstanceOfMessage = "Consider using the constraint model, Assert.That(actual, Is.Not.InstanceOf(expected)), instead of the classic model, Assert.IsNotInstanceOf(expected, actual)"; - internal const string IsNotInstanceOfDescription = "Consider using the constraint model, Assert.That(actual, Is.Not.InstanceOf(expected)), instead of the classic model, Assert.IsNotInstanceOf(expected, actual)."; + internal const string IsNotInstanceOfTitle = "Consider using Assert.That(actual, Is.Not.InstanceOf(expected)) instead of ClassicAssert.IsNotInstanceOf(expected, actual)"; + internal const string IsNotInstanceOfMessage = "Consider using the constraint model, Assert.That(actual, Is.Not.InstanceOf(expected)), instead of the classic model, ClassicAssert.IsNotInstanceOf(expected, actual)"; + internal const string IsNotInstanceOfDescription = "Consider using the constraint model, Assert.That(actual, Is.Not.InstanceOf(expected)), instead of the classic model, ClassicAssert.IsNotInstanceOf(expected, actual)."; } } diff --git a/src/nunit.analyzers/ClassicModelAssertUsage/IsNotNullAndNotNullClassicModelAssertUsageCodeFix.cs b/src/nunit.analyzers/ClassicModelAssertUsage/IsNotNullAndNotNullClassicModelAssertUsageCodeFix.cs index e4ca732c..9d1fc053 100644 --- a/src/nunit.analyzers/ClassicModelAssertUsage/IsNotNullAndNotNullClassicModelAssertUsageCodeFix.cs +++ b/src/nunit.analyzers/ClassicModelAssertUsage/IsNotNullAndNotNullClassicModelAssertUsageCodeFix.cs @@ -27,7 +27,7 @@ protected override void UpdateArguments(Diagnostic diagnostic, List base.Title + Suffix; protected override void UpdateArguments(Diagnostic diagnostic, List arguments) diff --git a/src/nunit.analyzers/CollectionAssertUsage/CollectionAssertUsageAnalyzer.cs b/src/nunit.analyzers/CollectionAssertUsage/CollectionAssertUsageAnalyzer.cs new file mode 100644 index 00000000..6cd1bb4a --- /dev/null +++ b/src/nunit.analyzers/CollectionAssertUsage/CollectionAssertUsageAnalyzer.cs @@ -0,0 +1,92 @@ +using System.Collections.Generic; +using System.Collections.Immutable; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.Operations; +using NUnit.Analyzers.Constants; +using NUnit.Analyzers.Extensions; +using static NUnit.Analyzers.Constants.NUnitFrameworkConstants; + +namespace NUnit.Analyzers.CollectionAssertUsage +{ + [DiagnosticAnalyzer(LanguageNames.CSharp)] + public sealed class CollectionAssertUsageAnalyzer : BaseAssertionAnalyzer + { + internal static readonly ImmutableDictionary OneCollectionParameterAsserts = + new Dictionary + { + { NameOfCollectionAssertAllItemsAreNotNull, $"{NameOfIs}.{NameOfIsAll}.{NameOfIsNot}.{NameOfIsNull}" }, + { NameOfCollectionAssertAllItemsAreUnique, $"{NameOfIs}.{NameOfIsUnique}" }, + { NameOfCollectionAssertIsEmpty, $"{NameOfIs}.{NameOfIsEmpty}" }, + { NameOfCollectionAssertIsNotEmpty, $"{NameOfIs}.{NameOfIsNot}.{NameOfIsEmpty}" }, + { NameOfCollectionAssertIsOrdered, $"{NameOfIs}.{NameOfIsOrdered}" }, + }.ToImmutableDictionary(); + + internal static readonly ImmutableDictionary TwoCollectionParameterAsserts = + new Dictionary + { + { NameOfCollectionAssertAreEqual, $"{NameOfIs}.{NameOfIsEqualTo}(expected).{NameOfEqualConstraintAsCollection}" }, + { NameOfCollectionAssertAreEquivalent, $"{NameOfIs}.{NameOfIsEquivalentTo}(expected)" }, + { NameOfCollectionAssertAreNotEqual, $"{NameOfIs}.{NameOfIsNot}.{NameOfIsEqualTo}(expected).{NameOfEqualConstraintAsCollection}" }, + { NameOfCollectionAssertAreNotEquivalent, $"{NameOfIs}.{NameOfIsNot}.{NameOfIsEquivalentTo}(expected)" }, + { NameOfCollectionAssertIsNotSubsetOf, $"{NameOfIs}.{NameOfIsNot}.{NameOfIsSubsetOf}(expected)" }, + { NameOfCollectionAssertIsSubsetOf, $"{NameOfIs}.{NameOfIsSubsetOf}(expected)" }, + { NameOfCollectionAssertIsNotSupersetOf, $"{NameOfIs}.{NameOfIsNot}.{NameOfIsSupersetOf}(expected)" }, + { NameOfCollectionAssertIsSupersetOf, $"{NameOfIs}.{NameOfIsSupersetOf}(expected)" }, + }.ToImmutableDictionary(); + + internal static readonly ImmutableDictionary CollectionAndItemParameterAsserts = + new Dictionary + { + { NameOfCollectionAssertAllItemsAreInstancesOfType, $"{NameOfIs}.{NameOfIsAll}.{NameOfIsInstanceOf}(expected)" }, + { NameOfCollectionAssertContains, $"{NameOfHas}.{NameOfHasMember}(expected)" }, + { NameOfCollectionAssertDoesNotContain, $"{NameOfHas}.{NameOfHasNo}.{NameOfHasMember}(expected)" }, + }.ToImmutableDictionary(); + + private static readonly DiagnosticDescriptor collectionAssertDescriptor = DiagnosticDescriptorCreator.Create( + id: AnalyzerIdentifiers.CollectionAssertUsage, + title: CollectionAssertUsageConstants.CollectionAssertTitle, + messageFormat: CollectionAssertUsageConstants.CollectionAssertMessage, + category: Categories.Assertion, + defaultSeverity: DiagnosticSeverity.Warning, + description: CollectionAssertUsageConstants.CollectionAssertDescription); + + public override ImmutableArray SupportedDiagnostics { get; } = + ImmutableArray.Create(collectionAssertDescriptor); + + protected override bool IsAssert(bool hasClassicAssert, IInvocationOperation invocationOperation) + { + return invocationOperation.TargetMethod.ContainingType.IsCollectionAssert(); + } + + protected override void AnalyzeAssertInvocation(OperationAnalysisContext context, IInvocationOperation assertOperation) + { + var methodSymbol = assertOperation.TargetMethod; + + if (OneCollectionParameterAsserts.TryGetValue(methodSymbol.Name, out string? constraint) || + TwoCollectionParameterAsserts.TryGetValue(methodSymbol.Name, out constraint) || + CollectionAndItemParameterAsserts.TryGetValue(methodSymbol.Name, out constraint)) + { + var parameters = methodSymbol.Parameters; + string comparerParameterIndex = parameters.Length > 1 && IsIComparer(parameters[1]) ? "1" : + (parameters.Length > 2 && IsIComparer(parameters[2]) ? "2" : "0"); + + context.ReportDiagnostic(Diagnostic.Create( + collectionAssertDescriptor, + assertOperation.Syntax.GetLocation(), + new Dictionary + { + [AnalyzerPropertyKeys.ModelName] = methodSymbol.Name, + [AnalyzerPropertyKeys.ComparerParameterIndex] = comparerParameterIndex, + }.ToImmutableDictionary(), + constraint, + methodSymbol.Name)); + } + } + + private static bool IsIComparer(IParameterSymbol parameterSymbol) + { + return parameterSymbol.Type.Name == "IComparer"; + } + } +} diff --git a/src/nunit.analyzers/CollectionAssertUsage/CollectionAssertUsageCodeFix.cs b/src/nunit.analyzers/CollectionAssertUsage/CollectionAssertUsageCodeFix.cs new file mode 100644 index 00000000..cd932db5 --- /dev/null +++ b/src/nunit.analyzers/CollectionAssertUsage/CollectionAssertUsageCodeFix.cs @@ -0,0 +1,110 @@ +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Composition; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CodeFixes; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using NUnit.Analyzers.ClassicModelAssertUsage; +using NUnit.Analyzers.Constants; +using NUnit.Analyzers.Helpers; +using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory; +using static NUnit.Analyzers.Constants.NUnitFrameworkConstants; + +namespace NUnit.Analyzers.CollectionAssertUsage +{ + [ExportCodeFixProvider(LanguageNames.CSharp)] + [Shared] + internal class CollectionAssertUsageCodeFix : ClassicModelAssertUsageCodeFix + { + internal static readonly ImmutableDictionary CollectionAssertToParameterlessConstraints = + new Dictionary + { + { NameOfCollectionAssertAllItemsAreNotNull, new Constraints(NameOfIs, NameOfIsAll, default(string), NameOfIsNot, NameOfIsNull) }, + { NameOfCollectionAssertAllItemsAreUnique, new Constraints(NameOfIs, NameOfIsUnique, default(string)) }, + { NameOfCollectionAssertIsEmpty, new Constraints(NameOfIs, default(string), default(string), NameOfIsEmpty) }, + { NameOfCollectionAssertIsNotEmpty, new Constraints(NameOfIs, NameOfIsNot, default(string), NameOfIsEmpty) }, + { NameOfCollectionAssertIsOrdered, new Constraints(NameOfIs, NameOfIsOrdered, default(string), default(string)) }, + }.ToImmutableDictionary(); + + internal static readonly ImmutableDictionary CollectionAssertToOneSwappedParameterConstraints = + new Dictionary + { + { NameOfCollectionAssertAreEqual, new Constraints(NameOfIs, default(string), NameOfIsEqualTo, NameOfEqualConstraintAsCollection) }, + { NameOfCollectionAssertAreEquivalent, new Constraints(NameOfIs, default(string), NameOfIsEquivalentTo) }, + { NameOfCollectionAssertAreNotEqual, new Constraints(NameOfIs, NameOfIsNot, NameOfIsEqualTo, NameOfEqualConstraintAsCollection) }, + { NameOfCollectionAssertAreNotEquivalent, new Constraints(NameOfIs, NameOfIsNot, NameOfIsEquivalentTo) }, + }.ToImmutableDictionary(); + + internal static readonly ImmutableDictionary CollectionAssertToOneUnswappedParameterConstraints = + new Dictionary + { + { NameOfCollectionAssertAllItemsAreInstancesOfType, new Constraints(NameOfIs, NameOfIsAll, NameOfIsInstanceOf) }, + { NameOfCollectionAssertContains, new Constraints(NameOfHas, default(string), NameOfHasMember) }, + { NameOfCollectionAssertDoesNotContain, new Constraints(NameOfHas, NameOfHasNo, NameOfHasMember) }, + { NameOfCollectionAssertIsNotSubsetOf, new Constraints(NameOfIs, NameOfIsNot, NameOfIsSubsetOf) }, + { NameOfCollectionAssertIsSubsetOf, new Constraints(NameOfIs, default(string), NameOfIsSubsetOf) }, + { NameOfCollectionAssertIsNotSupersetOf, new Constraints(NameOfIs, NameOfIsNot, NameOfIsSupersetOf) }, + { NameOfCollectionAssertIsSupersetOf, new Constraints(NameOfIs, default(string), NameOfIsSupersetOf) }, + }.ToImmutableDictionary(); + + public override ImmutableArray FixableDiagnosticIds { get; } = ImmutableArray.Create( + AnalyzerIdentifiers.CollectionAssertUsage); + + protected override void UpdateArguments(Diagnostic diagnostic, List arguments) + { + string methodName = diagnostic.Properties[AnalyzerPropertyKeys.ModelName]!; + + int comparerParameterIndex = diagnostic.Properties[AnalyzerPropertyKeys.ComparerParameterIndex] switch + { + "2" => 2, + "1" => 1, + _ => 0, + }; + + ArgumentSyntax? comparerArgument = null; + if (comparerParameterIndex > 0) + { + // Remember 'comparer' parameter to be added as an 'Using' suffix. + comparerArgument = arguments[comparerParameterIndex]; + arguments.RemoveAt(comparerParameterIndex); + } + + if (CollectionAssertToParameterlessConstraints.TryGetValue(methodName, out Constraints? constraints)) + { + arguments.Insert(1, Argument(constraints.CreateConstraint())); + } + else if (CollectionAssertToOneSwappedParameterConstraints.TryGetValue(methodName, out constraints)) + { + arguments.Insert(2, Argument(constraints.CreateConstraint(arguments[0]))); + + // Then we have to remove the 1st argument because that's now in the "constaint" + arguments.RemoveAt(0); + } + else if (CollectionAssertToOneUnswappedParameterConstraints.TryGetValue(methodName, out constraints)) + { + arguments[1] = Argument(constraints.CreateConstraint(arguments[1])); + } + + if (comparerArgument is not null) + { + ExpressionSyntax expression = arguments[1].Expression; + + // We need to drop the 'AsCollection' when using an IComparer. + if (expression is MemberAccessExpressionSyntax memberAccessExpression && + memberAccessExpression.Name.ToString() == NameOfEqualConstraintAsCollection) + { + expression = memberAccessExpression.Expression; + } + + arguments[1] = Argument( + InvocationExpression( + MemberAccessExpression( + SyntaxKind.SimpleMemberAccessExpression, + expression, + IdentifierName(NameOfEqualConstraintUsing)), + ArgumentList(SingletonSeparatedList(comparerArgument)))); + } + } + } +} diff --git a/src/nunit.analyzers/CollectionAssertUsage/CollectionAssertUsageConstants.cs b/src/nunit.analyzers/CollectionAssertUsage/CollectionAssertUsageConstants.cs new file mode 100644 index 00000000..9e132ab0 --- /dev/null +++ b/src/nunit.analyzers/CollectionAssertUsage/CollectionAssertUsageConstants.cs @@ -0,0 +1,9 @@ +namespace NUnit.Analyzers.CollectionAssertUsage +{ + internal class CollectionAssertUsageConstants + { + internal const string CollectionAssertTitle = "Consider using Assert.That(...) instead of CollectionAssert(...)"; + internal const string CollectionAssertMessage = "Consider using the constraint model, Assert.That(...), instead of the classic model, CollectionAssert(...)"; + internal const string CollectionAssertDescription = "Consider using the constraint model, Assert.That(actual, {0}(expected)), instead of the classic model, CollectionAssert.{1}(expected, actual)."; + } +} diff --git a/src/nunit.analyzers/ComparableTypes/ComparableTypesAnalyzer.cs b/src/nunit.analyzers/ComparableTypes/ComparableTypesAnalyzer.cs index db325784..c6e3fd43 100644 --- a/src/nunit.analyzers/ComparableTypes/ComparableTypesAnalyzer.cs +++ b/src/nunit.analyzers/ComparableTypes/ComparableTypesAnalyzer.cs @@ -1,5 +1,4 @@ using System.Collections.Immutable; -using System.Diagnostics; using System.Linq; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; @@ -173,7 +172,7 @@ private static bool IsIComparable(ITypeSymbol typeSymbol) private static bool HasCustomComparer(ConstraintExpressionPart constraintPartExpression) { - return constraintPartExpression.GetSuffixesNames().Any(s => s == NUnitFrameworkConstants.NameOfUsing); + return constraintPartExpression.GetSuffixesNames().Any(s => s == NUnitFrameworkConstants.NameOfEqualConstraintUsing); } } } diff --git a/src/nunit.analyzers/ConstActualValueUsage/ConstActualValueUsageAnalyzer.cs b/src/nunit.analyzers/ConstActualValueUsage/ConstActualValueUsageAnalyzer.cs index 0bdecafe..cdf63d02 100644 --- a/src/nunit.analyzers/ConstActualValueUsage/ConstActualValueUsageAnalyzer.cs +++ b/src/nunit.analyzers/ConstActualValueUsage/ConstActualValueUsageAnalyzer.cs @@ -22,9 +22,10 @@ public class ConstActualValueUsageAnalyzer : BaseAssertionAnalyzer public override ImmutableArray SupportedDiagnostics => ImmutableArray.Create(descriptor); - protected override bool IsAssert(IInvocationOperation invocationOperation) + protected override bool IsAssert(bool hasClassicAssert, IInvocationOperation invocationOperation) { - return invocationOperation.TargetMethod.ContainingType.IsAnyAssert(); + return base.IsAssert(hasClassicAssert, invocationOperation) || + invocationOperation.TargetMethod.ContainingType.IsStringAssert(); } protected override void AnalyzeAssertInvocation(OperationAnalysisContext context, IInvocationOperation assertOperation) diff --git a/src/nunit.analyzers/ConstActualValueUsage/ConstActualValueUsageAnalyzerConstants.cs b/src/nunit.analyzers/ConstActualValueUsage/ConstActualValueUsageAnalyzerConstants.cs index eb65b3c3..77a188db 100644 --- a/src/nunit.analyzers/ConstActualValueUsage/ConstActualValueUsageAnalyzerConstants.cs +++ b/src/nunit.analyzers/ConstActualValueUsage/ConstActualValueUsageAnalyzerConstants.cs @@ -1,5 +1,3 @@ -using System; - namespace NUnit.Analyzers.ConstActualValueUsage { internal static class ConstActualValueUsageAnalyzerConstants diff --git a/src/nunit.analyzers/ConstActualValueUsage/ConstActualValueUsageCodeFix.cs b/src/nunit.analyzers/ConstActualValueUsage/ConstActualValueUsageCodeFix.cs index 335cb444..39b28324 100644 --- a/src/nunit.analyzers/ConstActualValueUsage/ConstActualValueUsageCodeFix.cs +++ b/src/nunit.analyzers/ConstActualValueUsage/ConstActualValueUsageCodeFix.cs @@ -102,11 +102,11 @@ private static bool TryFindArguments(SemanticModel semanticModel, InvocationExpr var methodSymbol = semanticModel.GetSymbolInfo(invocationSyntax).Symbol as IMethodSymbol; - if (methodSymbol is null || !methodSymbol.ContainingType.IsAnyAssert()) + if (methodSymbol is null) return false; - // option 1: Classic assert (e.g. Assert.AreEqual(expected, actual) ) - if ((IsSupportedAssert(methodSymbol) || IsSupportedStringAssert(methodSymbol)) + // option 1: Classic assert (e.g. ClassicAssert.AreEqual(expected, actual) ) + if ((IsSupportedClassicAssert(methodSymbol) || IsSupportedStringAssert(methodSymbol)) && methodSymbol.Parameters.Length >= 2) { expectedArgument = invocationSyntax.ArgumentList.Arguments[0].Expression; @@ -116,7 +116,7 @@ private static bool TryFindArguments(SemanticModel semanticModel, InvocationExpr // option 2: Assert with 'actual' and 'constraint' parameters // (e.g. Assert.That(actual, Is.EqualTo(expected))) - if (methodSymbol.Name == NUnitFrameworkConstants.NameOfAssertThat + if (methodSymbol.ContainingType.IsAssert() && methodSymbol.Name == NUnitFrameworkConstants.NameOfAssertThat && methodSymbol.Parameters.Length >= 2) { actualArgument = invocationSyntax.ArgumentList.Arguments[0].Expression; @@ -151,14 +151,15 @@ private static bool TryFindArguments(SemanticModel semanticModel, InvocationExpr return false; } - private static bool IsSupportedAssert(IMethodSymbol methodSymbol) + private static bool IsSupportedClassicAssert(IMethodSymbol methodSymbol) { - return methodSymbol.ContainingType.Name == NUnitFrameworkConstants.NameOfAssert && SupportedClassicAsserts.Contains(methodSymbol.Name); + return (methodSymbol.ContainingType.IsClassicAssert() || methodSymbol.ContainingType.IsAssert()) && + SupportedClassicAsserts.Contains(methodSymbol.Name); } private static bool IsSupportedStringAssert(IMethodSymbol methodSymbol) { - return methodSymbol.ContainingType.Name == NUnitFrameworkConstants.NameOfStringAssert && SupportedStringAsserts.Contains(methodSymbol.Name); + return methodSymbol.ContainingType.IsStringAssert() && SupportedStringAsserts.Contains(methodSymbol.Name); } } } diff --git a/src/nunit.analyzers/Constants/AnalyzerIdentifiers.cs b/src/nunit.analyzers/Constants/AnalyzerIdentifiers.cs index 91787eb6..19f7a29d 100644 --- a/src/nunit.analyzers/Constants/AnalyzerIdentifiers.cs +++ b/src/nunit.analyzers/Constants/AnalyzerIdentifiers.cs @@ -88,6 +88,9 @@ internal static class AnalyzerIdentifiers internal const string UseAssertMultiple = "NUnit2045"; internal const string UsePropertyConstraint = "NUnit2046"; internal const string WithinIncompatibleTypes = "NUnit2047"; + internal const string StringAssertUsage = "NUnit2048"; + internal const string CollectionAssertUsage = "NUnit2049"; + internal const string UpdateStringFormatToInterpolatableString = "NUnit2050"; #endregion Assertion diff --git a/src/nunit.analyzers/Constants/AnalyzerPropertyKeys.cs b/src/nunit.analyzers/Constants/AnalyzerPropertyKeys.cs index 4867780c..0a4e1056 100644 --- a/src/nunit.analyzers/Constants/AnalyzerPropertyKeys.cs +++ b/src/nunit.analyzers/Constants/AnalyzerPropertyKeys.cs @@ -4,6 +4,7 @@ internal static class AnalyzerPropertyKeys { internal const string HasToleranceValue = nameof(AnalyzerPropertyKeys.HasToleranceValue); internal const string ModelName = nameof(AnalyzerPropertyKeys.ModelName); - internal const string IsGenericMethod = nameof(AnalyzerPropertyKeys.IsGenericMethod); + internal const string MinimumNumberOfArguments = nameof(AnalyzerPropertyKeys.MinimumNumberOfArguments); + internal const string ComparerParameterIndex = nameof(AnalyzerPropertyKeys.ComparerParameterIndex); } } diff --git a/src/nunit.analyzers/Constants/NUnitFrameworkConstants.cs b/src/nunit.analyzers/Constants/NUnitFrameworkConstants.cs index 4f1e9e29..ee52c578 100644 --- a/src/nunit.analyzers/Constants/NUnitFrameworkConstants.cs +++ b/src/nunit.analyzers/Constants/NUnitFrameworkConstants.cs @@ -6,8 +6,6 @@ namespace NUnit.Analyzers.Constants /// public static class NUnitFrameworkConstants { - public const string NameOfEqualConstraintWithin = "Within"; - public const string NameOfIs = "Is"; public const string NameOfIsFalse = "False"; public const string NameOfIsTrue = "True"; @@ -16,10 +14,9 @@ public static class NUnitFrameworkConstants public const string NameOfIsSubsetOf = "SubsetOf"; public const string NameOfIsSupersetOf = "SupersetOf"; public const string NameOfIsNot = "Not"; - public const string NameOfIsNotEqualTo = "EqualTo"; public const string NameOfIsSameAs = "SameAs"; public const string NameOfIsSamePath = "SamePath"; - public const string NameOfNull = "Null"; + public const string NameOfIsNull = "Null"; public const string NameOfIsGreaterThan = "GreaterThan"; public const string NameOfIsGreaterThanOrEqualTo = "GreaterThanOrEqualTo"; public const string NameOfIsLessThan = "LessThan"; @@ -29,6 +26,9 @@ public static class NUnitFrameworkConstants public const string NameOfIsNaN = "NaN"; public const string NameOfIsEmpty = "Empty"; public const string NameOfIsInstanceOf = "InstanceOf"; + public const string NameOfIsAll = "All"; + public const string NameOfIsUnique = "Unique"; + public const string NameOfIsOrdered = "Ordered"; public const string NameOfContains = "Contains"; public const string NameOfContainsItem = "Item"; @@ -38,6 +38,7 @@ public static class NUnitFrameworkConstants public const string NameOfDoesContain = "Contain"; public const string NameOfDoesStartWith = "StartWith"; public const string NameOfDoesEndWith = "EndWith"; + public const string NameOfDoesMatch = "Match"; public const string NameOfHas = "Has"; public const string NameOfHasProperty = "Property"; @@ -46,8 +47,10 @@ public static class NUnitFrameworkConstants public const string NameOfHasMessage = "Message"; public const string NameOfHasInnerException = "InnerException"; public const string NameOfHasNo = "No"; + public const string NameOfHasMember = "Member"; public const string NameOfMultiple = "Multiple"; + public const string NameOfThrows = "Throws"; public const string NameOfThrowsArgumentException = "ArgumentException"; public const string NameOfThrowsArgumentNullException = "ArgumentNullException"; @@ -55,6 +58,13 @@ public static class NUnitFrameworkConstants public const string NameOfThrowsTargetInvocationException = "TargetInvocationException"; public const string NameOfAssert = "Assert"; + + public const string NameOfAssertPass = "Pass"; + public const string NameOfAssertFail = "Fail"; + public const string NameOfAssertWarn = "Warn"; + public const string NameOfAssertIgnore = "Ignore"; + public const string NameOfAssertInconclusive = "Inconclusive"; + public const string NameOfAssertIsTrue = "IsTrue"; public const string NameOfAssertTrue = "True"; public const string NameOfAssertIsFalse = "IsFalse"; @@ -87,16 +97,34 @@ public static class NUnitFrameworkConstants public const string NameOfAssertThrowsAsync = "ThrowsAsync"; public const string NameOfStringAssert = "StringAssert"; - public const string NameOfStringAssertAreEqualIgnoringCase = "AreEqualIgnoringCase"; - public const string NameOfStringAssertAreNotEqualIgnoringCase = "AreNotEqualIgnoringCase"; public const string NameOfStringAssertContains = "Contains"; public const string NameOfStringAssertDoesNotContain = "DoesNotContain"; - public const string NameOfStringAssertDoesNotEndWith = "DoesNotEndWith"; - public const string NameOfStringAssertDoesNotMatch = "DoesNotMatch"; + public const string NameOfStringAssertStartsWith = "StartsWith"; public const string NameOfStringAssertDoesNotStartWith = "DoesNotStartWith"; public const string NameOfStringAssertEndsWith = "EndsWith"; + public const string NameOfStringAssertDoesNotEndWith = "DoesNotEndWith"; + public const string NameOfStringAssertAreEqualIgnoringCase = "AreEqualIgnoringCase"; + public const string NameOfStringAssertAreNotEqualIgnoringCase = "AreNotEqualIgnoringCase"; public const string NameOfStringAssertIsMatch = "IsMatch"; - public const string NameOfStringAssertStartsWith = "StartsWith"; + public const string NameOfStringAssertDoesNotMatch = "DoesNotMatch"; + + public const string NameOfCollectionAssert = "CollectionAssert"; + public const string NameOfCollectionAssertAllItemsAreInstancesOfType = "AllItemsAreInstancesOfType"; + public const string NameOfCollectionAssertAllItemsAreNotNull = "AllItemsAreNotNull"; + public const string NameOfCollectionAssertAllItemsAreUnique = "AllItemsAreUnique"; + public const string NameOfCollectionAssertAreEqual = "AreEqual"; + public const string NameOfCollectionAssertAreEquivalent = "AreEquivalent"; + public const string NameOfCollectionAssertAreNotEqual = "AreNotEqual"; + public const string NameOfCollectionAssertAreNotEquivalent = "AreNotEquivalent"; + public const string NameOfCollectionAssertContains = "Contains"; + public const string NameOfCollectionAssertDoesNotContain = "DoesNotContain"; + public const string NameOfCollectionAssertIsNotSubsetOf = "IsNotSubsetOf"; + public const string NameOfCollectionAssertIsSubsetOf = "IsSubsetOf"; + public const string NameOfCollectionAssertIsNotSupersetOf = "IsNotSupersetOf"; + public const string NameOfCollectionAssertIsSupersetOf = "IsSupersetOf"; + public const string NameOfCollectionAssertIsEmpty = "IsEmpty"; + public const string NameOfCollectionAssertIsNotEmpty = "IsNotEmpty"; + public const string NameOfCollectionAssertIsOrdered = "IsOrdered"; public const string FullNameOfTypeIs = "NUnit.Framework.Is"; public const string FullNameOfTypeTestCaseAttribute = "NUnit.Framework.TestCaseAttribute"; @@ -162,14 +190,14 @@ public static class NUnitFrameworkConstants public const string NameOfConstraintExpressionOr = "Or"; public const string NameOfConstraintExpressionWith = "With"; - public const string NameOfIgnoreCase = "IgnoreCase"; - public const string NameOfUsing = "Using"; + public const string NameOfEqualConstraintIgnoreCase = "IgnoreCase"; + public const string NameOfEqualConstraintUsing = "Using"; + public const string NameOfEqualConstraintWithin = "Within"; + public const string NameOfEqualConstraintAsCollection = "AsCollection"; public const string NUnitFrameworkAssemblyName = "nunit.framework"; - public static readonly string[] AllAsserts = - { - NameOfAssert, NameOfStringAssert - }; + public const string NUnitFrameworkLegacyAssemblyName = "nunit.framework.legacy"; + public const string NameOfClassicAssert = "ClassicAssert"; } } diff --git a/src/nunit.analyzers/ConstraintUsage/BaseConditionConstraintCodeFix.cs b/src/nunit.analyzers/ConstraintUsage/BaseConditionConstraintCodeFix.cs index 345d29d2..406a50ab 100644 --- a/src/nunit.analyzers/ConstraintUsage/BaseConditionConstraintCodeFix.cs +++ b/src/nunit.analyzers/ConstraintUsage/BaseConditionConstraintCodeFix.cs @@ -8,8 +8,8 @@ using Microsoft.CodeAnalysis.CodeFixes; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; -using NUnit.Analyzers.Constants; using NUnit.Analyzers.Extensions; +using NUnit.Analyzers.Helpers; using static NUnit.Analyzers.Constants.NUnitFrameworkConstants; namespace NUnit.Analyzers.ConstraintUsage @@ -46,7 +46,8 @@ public override async Task RegisterCodeFixesAsync(CodeFixContext context) } context.CancellationToken.ThrowIfCancellationRequested(); - var conditionNode = (root.FindNode(context.Span) as ArgumentSyntax)?.Expression; + SyntaxNode node = root.FindNode(context.Span); + var conditionNode = (node as ArgumentSyntax)?.Expression; if (conditionNode is null) return; @@ -73,6 +74,10 @@ public override async Task RegisterCodeFixesAsync(CodeFixContext context) return; var newAssertNode = UpdateAssertNode(assertNode, assertMethod, actual, constraintExpression); + + if (newAssertNode is null) + return; + var newRoot = root.ReplaceNode(assertNode, newAssertNode); var codeAction = CodeAction.Create( @@ -105,12 +110,14 @@ protected virtual (ExpressionSyntax? actual, ExpressionSyntax? constraintExpress SyntaxFactory.ArgumentList(SyntaxFactory.SingletonSeparatedList(SyntaxFactory.Argument(expected)))); } - protected static InvocationExpressionSyntax UpdateAssertNode(InvocationExpressionSyntax assertNode, IMethodSymbol assertMethod, + protected static InvocationExpressionSyntax? UpdateAssertNode(InvocationExpressionSyntax assertNode, IMethodSymbol assertMethod, ExpressionSyntax actual, ExpressionSyntax constraintExpression) { - // Replace Assert method to Assert.That - var newExpression = ((MemberAccessExpressionSyntax)assertNode.Expression) - .WithName(SyntaxFactory.IdentifierName(NameOfAssertThat)); + // Replace the original ClassicAssert. invocation name into Assert.That + var newAssertNode = assertNode.UpdateClassicAssertToAssertThat(out TypeArgumentListSyntax? typeArguments); + + if (newAssertNode is null) + return null; // Replace arguments var hasConstraint = assertNode.GetArgumentExpression(assertMethod, NameOfExpressionParameter) is not null; @@ -127,9 +134,7 @@ protected static InvocationExpressionSyntax UpdateAssertNode(InvocationExpressio var newArgumentsList = assertNode.ArgumentList.WithArguments(newArguments); - return assertNode - .WithExpression(newExpression) - .WithArgumentList(newArgumentsList); + return newAssertNode.WithArgumentList(newArgumentsList); } } } diff --git a/src/nunit.analyzers/ConstraintUsage/ComparisonConstraintUsageCodeFix.cs b/src/nunit.analyzers/ConstraintUsage/ComparisonConstraintUsageCodeFix.cs index 5a7f5b2e..c4566051 100644 --- a/src/nunit.analyzers/ConstraintUsage/ComparisonConstraintUsageCodeFix.cs +++ b/src/nunit.analyzers/ConstraintUsage/ComparisonConstraintUsageCodeFix.cs @@ -2,7 +2,6 @@ using System.Composition; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CodeFixes; -using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; using NUnit.Analyzers.Constants; diff --git a/src/nunit.analyzers/ConstraintUsage/EqualConstraintUsageAnalyzer.cs b/src/nunit.analyzers/ConstraintUsage/EqualConstraintUsageAnalyzer.cs index b68cbbfd..cf5769be 100644 --- a/src/nunit.analyzers/ConstraintUsage/EqualConstraintUsageAnalyzer.cs +++ b/src/nunit.analyzers/ConstraintUsage/EqualConstraintUsageAnalyzer.cs @@ -10,8 +10,8 @@ namespace NUnit.Analyzers.ConstraintUsage [DiagnosticAnalyzer(LanguageNames.CSharp)] public class EqualConstraintUsageAnalyzer : BaseConditionConstraintAnalyzer { - private static readonly string IsEqualTo = $"{NameOfIs}.{NameOfIsEqualTo}"; - private static readonly string IsNotEqualTo = $"{NameOfIs}.{NameOfIsNot}.{NameOfIsEqualTo}"; + private const string IsEqualTo = $"{NameOfIs}.{NameOfIsEqualTo}"; + private const string IsNotEqualTo = $"{NameOfIs}.{NameOfIsNot}.{NameOfIsEqualTo}"; private static readonly DiagnosticDescriptor descriptor = DiagnosticDescriptorCreator.Create( id: AnalyzerIdentifiers.EqualConstraintUsage, diff --git a/src/nunit.analyzers/ConstraintUsage/SomeItemsConstraintUsageAnalyzer.cs b/src/nunit.analyzers/ConstraintUsage/SomeItemsConstraintUsageAnalyzer.cs index 0fa74171..f5a6e68b 100644 --- a/src/nunit.analyzers/ConstraintUsage/SomeItemsConstraintUsageAnalyzer.cs +++ b/src/nunit.analyzers/ConstraintUsage/SomeItemsConstraintUsageAnalyzer.cs @@ -13,8 +13,8 @@ namespace NUnit.Analyzers.ConstraintUsage [DiagnosticAnalyzer(LanguageNames.CSharp)] public class SomeItemsConstraintUsageAnalyzer : BaseConditionConstraintAnalyzer { - private static readonly string DoesContain = $"{NameOfDoes}.{NameOfDoesContain}"; - private static readonly string DoesNotContain = $"{NameOfDoes}.{NameOfDoesNot}.{NameOfDoesContain}"; + private const string DoesContain = $"{NameOfDoes}.{NameOfDoesContain}"; + private const string DoesNotContain = $"{NameOfDoes}.{NameOfDoesNot}.{NameOfDoesContain}"; private static readonly DiagnosticDescriptor descriptor = DiagnosticDescriptorCreator.Create( id: AnalyzerIdentifiers.CollectionContainsConstraintUsage, diff --git a/src/nunit.analyzers/ContainsConstraintWrongActualType/ContainsConstraintWrongActualTypeAnalyzer.cs b/src/nunit.analyzers/ContainsConstraintWrongActualType/ContainsConstraintWrongActualTypeAnalyzer.cs index d152b828..f9602412 100644 --- a/src/nunit.analyzers/ContainsConstraintWrongActualType/ContainsConstraintWrongActualTypeAnalyzer.cs +++ b/src/nunit.analyzers/ContainsConstraintWrongActualType/ContainsConstraintWrongActualTypeAnalyzer.cs @@ -1,5 +1,4 @@ using System.Collections.Immutable; -using System.Linq; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Operations; diff --git a/src/nunit.analyzers/DelegateRequired/DelegateRequiredCodeFix.cs b/src/nunit.analyzers/DelegateRequired/DelegateRequiredCodeFix.cs index 52e175a5..4b45f1dc 100644 --- a/src/nunit.analyzers/DelegateRequired/DelegateRequiredCodeFix.cs +++ b/src/nunit.analyzers/DelegateRequired/DelegateRequiredCodeFix.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Immutable; using System.Linq; using System.Threading.Tasks; diff --git a/src/nunit.analyzers/DiagnosticSuppressors/DereferencePossiblyNullReferenceSuppressor.cs b/src/nunit.analyzers/DiagnosticSuppressors/DereferencePossiblyNullReferenceSuppressor.cs index bec23d11..25d3596c 100644 --- a/src/nunit.analyzers/DiagnosticSuppressors/DereferencePossiblyNullReferenceSuppressor.cs +++ b/src/nunit.analyzers/DiagnosticSuppressors/DereferencePossiblyNullReferenceSuppressor.cs @@ -4,7 +4,6 @@ using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; -using System.Linq.Expressions; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; @@ -17,7 +16,7 @@ namespace NUnit.Analyzers.DiagnosticSuppressors [DiagnosticAnalyzer(LanguageNames.CSharp)] public sealed class DereferencePossiblyNullReferenceSuppressor : DiagnosticSuppressor { - private const string Justification = "Expression was checked in an Assert.NotNull, Assert.IsNotNull or Assert.That call"; + private const string Justification = "Expression was checked in an ClassicAssert.NotNull, ClassicAssert.IsNotNull or Assert.That call"; // Numbers from: https://cezarypiatek.github.io/post/non-nullable-references-in-dotnet-core/ public static ImmutableDictionary SuppressionDescriptors { get; } = @@ -307,7 +306,8 @@ private static bool IsValidatedNotNullByPreviousStatementInSameBlock(string poss private static bool IsValidatedNotNullByExpression(string possibleNullReference, ExpressionSyntax expression) { // Check if this is an Assert for the same symbol - if (AssertHelper.IsAssert(expression, out string member, out ArgumentListSyntax? argumentList)) + if (AssertHelper.IsAssert(expression, out string member, out ArgumentListSyntax? argumentList) || + AssertHelper.IsClassicAssert(expression, out member, out argumentList)) { string firstArgument = argumentList.Arguments.First().Expression.ToString(); @@ -342,7 +342,7 @@ private static bool IsValidatedNotNullByExpression(string possibleNullReference, } } else if (member == NUnitFrameworkConstants.NameOfAssertNotNull || - member == NUnitFrameworkConstants.NameOfAssertIsNotNull) + member == NUnitFrameworkConstants.NameOfAssertIsNotNull) { if (CoveredBy(firstArgument, possibleNullReference)) { @@ -350,7 +350,7 @@ private static bool IsValidatedNotNullByExpression(string possibleNullReference, } } else if (member == NUnitFrameworkConstants.NameOfAssertIsTrue || - member == NUnitFrameworkConstants.NameOfAssertTrue) + member == NUnitFrameworkConstants.NameOfAssertTrue) { if (IsHasValue(firstArgument, possibleNullReference)) { diff --git a/src/nunit.analyzers/EqualToIncompatibleTypes/EqualToIncompatibleTypesAnalyzer.cs b/src/nunit.analyzers/EqualToIncompatibleTypes/EqualToIncompatibleTypesAnalyzer.cs index ed9c38fb..f35a51f4 100644 --- a/src/nunit.analyzers/EqualToIncompatibleTypes/EqualToIncompatibleTypesAnalyzer.cs +++ b/src/nunit.analyzers/EqualToIncompatibleTypes/EqualToIncompatibleTypesAnalyzer.cs @@ -143,7 +143,7 @@ private static void CheckActualVsExpectedOperation(OperationAnalysisContext cont private static bool HasCustomEqualityComparer(ConstraintExpressionPart constraintPartExpression) { - return constraintPartExpression.GetSuffixesNames().Any(s => s == NUnitFrameworkConstants.NameOfUsing); + return constraintPartExpression.GetSuffixesNames().Any(s => s == NUnitFrameworkConstants.NameOfEqualConstraintUsing); } } } diff --git a/src/nunit.analyzers/Extensions/ITypeSymbolExtensions.cs b/src/nunit.analyzers/Extensions/ITypeSymbolExtensions.cs index 1048a7cf..7add9c61 100644 --- a/src/nunit.analyzers/Extensions/ITypeSymbolExtensions.cs +++ b/src/nunit.analyzers/Extensions/ITypeSymbolExtensions.cs @@ -22,15 +22,29 @@ other is not null && internal static bool IsAssert(this ITypeSymbol? @this) { return @this is not null && - @this.ContainingAssembly.Name == NUnitFrameworkConstants.NUnitFrameworkAssemblyName && - @this.Name == NUnitFrameworkConstants.NameOfAssert; + @this.ContainingAssembly.Name is NUnitFrameworkConstants.NUnitFrameworkAssemblyName && + @this.Name is NUnitFrameworkConstants.NameOfAssert; } - internal static bool IsAnyAssert(this ITypeSymbol? @this) + internal static bool IsClassicAssert(this ITypeSymbol? @this) { return @this is not null && - @this.ContainingAssembly.Name == NUnitFrameworkConstants.NUnitFrameworkAssemblyName && - NUnitFrameworkConstants.AllAsserts.Contains(@this.Name); + @this.ContainingAssembly.Name is NUnitFrameworkConstants.NUnitFrameworkLegacyAssemblyName && + @this.Name is NUnitFrameworkConstants.NameOfClassicAssert; + } + + internal static bool IsStringAssert(this ITypeSymbol? @this) + { + return @this is not null && + @this.ContainingAssembly.Name is NUnitFrameworkConstants.NUnitFrameworkLegacyAssemblyName or NUnitFrameworkConstants.NUnitFrameworkAssemblyName && + @this.Name is NUnitFrameworkConstants.NameOfStringAssert; + } + + internal static bool IsCollectionAssert(this ITypeSymbol? @this) + { + return @this is not null && + @this.ContainingAssembly.Name is NUnitFrameworkConstants.NUnitFrameworkLegacyAssemblyName or NUnitFrameworkConstants.NUnitFrameworkAssemblyName && + @this.Name is NUnitFrameworkConstants.NameOfCollectionAssert; } internal static bool IsConstraint(this ITypeSymbol? @this) diff --git a/src/nunit.analyzers/Helpers/AssertHelper.cs b/src/nunit.analyzers/Helpers/AssertHelper.cs index 6c5358c4..2f5de7f1 100644 --- a/src/nunit.analyzers/Helpers/AssertHelper.cs +++ b/src/nunit.analyzers/Helpers/AssertHelper.cs @@ -122,11 +122,26 @@ public static bool IsAssert(ExpressionSyntax? expression, params string[] reques public static bool IsAssert(ExpressionSyntax? expression, out string member, [NotNullWhen(true)] out ArgumentListSyntax? argumentList) + { + return IsAssert(expression, NUnitFrameworkConstants.NameOfAssert, out member, out argumentList); + } + + public static bool IsClassicAssert(ExpressionSyntax? expression, + out string member, + [NotNullWhen(true)] out ArgumentListSyntax? argumentList) + { + return IsAssert(expression, NUnitFrameworkConstants.NameOfClassicAssert, out member, out argumentList); + } + + private static bool IsAssert(ExpressionSyntax? expression, + string nameOfAssert, + out string member, + [NotNullWhen(true)] out ArgumentListSyntax? argumentList) { if (expression is InvocationExpressionSyntax invocationExpression && invocationExpression.Expression is MemberAccessExpressionSyntax memberAccessExpression && memberAccessExpression.Expression is IdentifierNameSyntax identifierName && - identifierName.Identifier.Text == NUnitFrameworkConstants.NameOfAssert) + identifierName.Identifier.Text == nameOfAssert) { member = memberAccessExpression.Name.Identifier.Text; argumentList = invocationExpression.ArgumentList; diff --git a/src/nunit.analyzers/Helpers/CodeFixHelper.cs b/src/nunit.analyzers/Helpers/CodeFixHelper.cs new file mode 100644 index 00000000..f1ac40a5 --- /dev/null +++ b/src/nunit.analyzers/Helpers/CodeFixHelper.cs @@ -0,0 +1,185 @@ +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using NUnit.Analyzers.Constants; + +namespace NUnit.Analyzers.Helpers +{ + internal static class CodeFixHelper + { + public static InvocationExpressionSyntax? UpdateClassicAssertToAssertThat( + this InvocationExpressionSyntax invocationExpression, + out TypeArgumentListSyntax? typeArguments) + { + // Replace the original method invocation name to "That". + var invocationTargetNode = invocationExpression.Expression as MemberAccessExpressionSyntax; + + if (invocationTargetNode is null) + { + typeArguments = null; + return null; + } + + SimpleNameSyntax methodNode = invocationTargetNode.Name; + typeArguments = methodNode is GenericNameSyntax genericNode ? genericNode.TypeArgumentList : null; + + MemberAccessExpressionSyntax newInvocationTargetNode = + SyntaxFactory.MemberAccessExpression(SyntaxKind.SimpleMemberAccessExpression, + SyntaxFactory.IdentifierName(NUnitFrameworkConstants.NameOfAssert), + SyntaxFactory.IdentifierName(NUnitFrameworkConstants.NameOfAssertThat)) + .WithTriviaFrom(invocationTargetNode); + + return invocationExpression.ReplaceNode(invocationTargetNode, newInvocationTargetNode); + } + + /// + /// This is assumed to be arguments for an 'Assert.That(actual, constraint, "...: {0} - {1}", param0, param1)` + /// which needs converting into 'Assert.That(actual, constraint, $"...: {param0} - {param1}"). + /// + /// The arguments passed to the 'Assert' method. + /// The argument needed for the actual method, any more are assumed messages. + public static void UpdateStringFormatToFormattableString(List arguments, int minimumNumberOfArguments = 2) + { + int firstParamsArgument = minimumNumberOfArguments + 1; + + // If only 1 extra argument is passed, it must be a non-formattable message. + if (arguments.Count <= firstParamsArgument) + return; + + ExpressionSyntax formatSpecificationArgument = arguments[minimumNumberOfArguments].Expression; + if (formatSpecificationArgument is not LiteralExpressionSyntax literalExpression) + { + // We only support converting if the format specification is a constant string. + return; + } + + string formatSpecification = literalExpression.Token.ValueText; + + int formatArgumentCount = arguments.Count - firstParamsArgument; + ExpressionSyntax[] formatArguments = new ExpressionSyntax[formatArgumentCount]; + for (int i = 0; i < formatArgumentCount; i++) + { + formatArguments[i] = arguments[firstParamsArgument + i].Expression; + } + + IEnumerable interpolatedStringContent = + UpdateStringFormatToFormattableString(formatSpecification, formatArguments); + + InterpolatedStringExpressionSyntax interpolatedString = SyntaxFactory.InterpolatedStringExpression( + SyntaxFactory.Token(SyntaxKind.InterpolatedStringStartToken), + SyntaxFactory.List(interpolatedStringContent)); + + // Replace format specification argument with interpolated string. + arguments[minimumNumberOfArguments] = SyntaxFactory.Argument(interpolatedString); + + // Delete params arguments. + var nextArgument = minimumNumberOfArguments + 1; + arguments.RemoveRange(nextArgument, arguments.Count - nextArgument); + } + + internal static IEnumerable UpdateStringFormatToFormattableString(string formatSpecification, ExpressionSyntax[] formatArguments) + { + int startIndex = 0; + for (; startIndex < formatSpecification.Length;) + { + int argumentSpecification = formatSpecification.IndexOf('{', startIndex); + if (argumentSpecification < 0) + { + // No more formattable arguments, use remaining text. + string text = formatSpecification.Substring(startIndex, formatSpecification.Length - startIndex); + yield return SyntaxFactory.InterpolatedStringText(InterpolatedStringTextToken(text)); + break; + } + else if (argumentSpecification + 1 < formatSpecification.Length && + formatSpecification[argumentSpecification + 1] == '{') + { + // Special case, double '{' is an escaped '{' and should be treated as text. + argumentSpecification += 2; + string text = formatSpecification.Substring(startIndex, argumentSpecification - startIndex); + yield return SyntaxFactory.InterpolatedStringText(InterpolatedStringTextToken(text)); + startIndex = argumentSpecification; + } + else + { + if (argumentSpecification > startIndex) + { + // Copy text up to the '{' + string text = formatSpecification.Substring(startIndex, argumentSpecification - startIndex); + yield return SyntaxFactory.InterpolatedStringText(InterpolatedStringTextToken(text)); + } + + // Decode argument number + int index = 0; + while (char.IsDigit(formatSpecification[++argumentSpecification])) + { + index = (10 * index) + (formatSpecification[argumentSpecification] - '0'); + } + + int argumentSpecificationEnd = formatSpecification.IndexOf('}', argumentSpecification); + + // Insert appropriate argument + if (index < formatArguments.Length) + { + var formatArgument = formatArguments[index]; + if (formatArgument.DescendantNodesAndSelf(x => true, false) + .OfType() + .Any()) + { + // Colon is not allowed in an Interpolation, wrap expression in parenthesis: (expession). + formatArgument = SyntaxFactory.ParenthesizedExpression(formatArgument); + } + + int argumentAlignmentSpecification = formatSpecification.IndexOf(',', argumentSpecification, argumentSpecificationEnd - argumentSpecification); + int argumentFormatSpecification = formatSpecification.IndexOf(':', argumentSpecification, argumentSpecificationEnd - argumentSpecification); + + InterpolationAlignmentClauseSyntax? interpolationAlignment = null; + InterpolationFormatClauseSyntax? interpolationFormat = null; + + if (argumentAlignmentSpecification > 0) + { + int alignmentSpecificationLength = (argumentFormatSpecification > 0 ? + argumentFormatSpecification : argumentSpecificationEnd) - ++argumentAlignmentSpecification; + string alignmentString = formatSpecification.Substring(argumentAlignmentSpecification, alignmentSpecificationLength); + int.TryParse(alignmentString, NumberStyles.Integer, CultureInfo.InvariantCulture, out int alignment); + + ExpressionSyntax alignmentExpression = alignment >= 0 ? + SyntaxFactory.LiteralExpression(SyntaxKind.NumericLiteralExpression, SyntaxFactory.Literal(alignment)) : + SyntaxFactory.PrefixUnaryExpression(SyntaxKind.UnaryMinusExpression, + SyntaxFactory.LiteralExpression(SyntaxKind.NumericLiteralExpression, SyntaxFactory.Literal(-alignment))); + + interpolationAlignment = SyntaxFactory.InterpolationAlignmentClause( + SyntaxFactory.Token(SyntaxKind.CommaToken), alignmentExpression); + } + + if (argumentFormatSpecification > 0) + { + string formatClause = formatSpecification.Substring(++argumentFormatSpecification, argumentSpecificationEnd - argumentFormatSpecification); + interpolationFormat = SyntaxFactory.InterpolationFormatClause( + SyntaxFactory.Token(SyntaxKind.ColonToken), + InterpolatedStringTextToken(formatClause)); + } + + yield return SyntaxFactory.Interpolation(formatArgument, interpolationAlignment, interpolationFormat); + } + + startIndex = argumentSpecificationEnd + 1; + } + } + } + + private static SyntaxToken InterpolatedStringTextToken(string text) + { + // FormatLiteral doesn't escape double quotes when passing in quote: false + // It does when passing in quote: true but then it also surrounds it with double quotes. + // So we do that replacement ourselves. + string escapedText = SymbolDisplay.FormatLiteral(text, false) + .Replace("\"", "\\\""); + + return SyntaxFactory.Token(SyntaxTriviaList.Empty, SyntaxKind.InterpolatedStringTextToken, + escapedText, text, SyntaxTriviaList.Empty); + } + } +} diff --git a/src/nunit.analyzers/Helpers/Constraints.cs b/src/nunit.analyzers/Helpers/Constraints.cs new file mode 100644 index 00000000..2dc94145 --- /dev/null +++ b/src/nunit.analyzers/Helpers/Constraints.cs @@ -0,0 +1,66 @@ +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; + +using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory; + +namespace NUnit.Analyzers.Helpers +{ + internal sealed class Constraints + { + public Constraints(string staticClass, string? modifier, string? constraintMethod, string? property1 = null, string? property2 = null) + { + this.StaticClass = staticClass; + this.Modifier = modifier; + this.ConstraintMethod = constraintMethod; + this.Property1 = property1; + this.Property2 = property2; + } + + public string StaticClass { get; } + public string? Modifier { get; } + public string? ConstraintMethod { get; } + public string? Property1 { get; } + public string? Property2 { get; } + + public ExpressionSyntax CreateConstraint(ArgumentSyntax? expected = null) + { + ExpressionSyntax expression = IdentifierName(this.StaticClass); + + if (this.Modifier is not null) + { + expression = MemberAccessExpression( + SyntaxKind.SimpleMemberAccessExpression, + expression, + IdentifierName(this.Modifier)); + } + + if (this.ConstraintMethod is not null) + { + expression = InvocationExpression( + MemberAccessExpression( + SyntaxKind.SimpleMemberAccessExpression, + expression, + IdentifierName(this.ConstraintMethod)), + ArgumentList(expected is null ? default : SingletonSeparatedList(expected))); + } + + if (this.Property1 is not null) + { + expression = MemberAccessExpression( + SyntaxKind.SimpleMemberAccessExpression, + expression, + IdentifierName(this.Property1)); + } + + if (this.Property2 is not null) + { + expression = MemberAccessExpression( + SyntaxKind.SimpleMemberAccessExpression, + expression, + IdentifierName(this.Property2)); + } + + return expression; + } + } +} diff --git a/src/nunit.analyzers/IgnoreCaseUsage/IgnoreCaseUsageAnalyzer.cs b/src/nunit.analyzers/IgnoreCaseUsage/IgnoreCaseUsageAnalyzer.cs index 458ca648..9a8296a8 100644 --- a/src/nunit.analyzers/IgnoreCaseUsage/IgnoreCaseUsageAnalyzer.cs +++ b/src/nunit.analyzers/IgnoreCaseUsage/IgnoreCaseUsageAnalyzer.cs @@ -48,7 +48,7 @@ protected override void AnalyzeAssertInvocation(OperationAnalysisContext context // e.g. Is.EqualTo(expected).IgnoreCase // Need to check type of expected - var ignoreCaseSuffix = constraintPart.GetSuffix(NUnitFrameworkConstants.NameOfIgnoreCase) as IPropertyReferenceOperation; + var ignoreCaseSuffix = constraintPart.GetSuffix(NUnitFrameworkConstants.NameOfEqualConstraintIgnoreCase) as IPropertyReferenceOperation; if (ignoreCaseSuffix is null) continue; diff --git a/src/nunit.analyzers/NonTestMethodAccessibilityLevel/NonTestMethodAccessibilityLevelAnalyzer.cs b/src/nunit.analyzers/NonTestMethodAccessibilityLevel/NonTestMethodAccessibilityLevelAnalyzer.cs index 6c825aba..d35fd8cf 100644 --- a/src/nunit.analyzers/NonTestMethodAccessibilityLevel/NonTestMethodAccessibilityLevelAnalyzer.cs +++ b/src/nunit.analyzers/NonTestMethodAccessibilityLevel/NonTestMethodAccessibilityLevelAnalyzer.cs @@ -1,4 +1,3 @@ -using System; using System.Collections.Generic; using System.Collections.Immutable; using System.Linq; diff --git a/src/nunit.analyzers/NullConstraintUsage/NullConstraintUsageAnalyzer.cs b/src/nunit.analyzers/NullConstraintUsage/NullConstraintUsageAnalyzer.cs index b230f64c..cf5d9358 100644 --- a/src/nunit.analyzers/NullConstraintUsage/NullConstraintUsageAnalyzer.cs +++ b/src/nunit.analyzers/NullConstraintUsage/NullConstraintUsageAnalyzer.cs @@ -33,7 +33,7 @@ protected override void AnalyzeAssertInvocation(OperationAnalysisContext context if (!constraintPart.HasIncompatiblePrefixes() && constraintPart.Root is not null && constraintPart.HelperClass?.Name == NUnitFrameworkConstants.NameOfIs - && constraintPart.GetConstraintName() == NUnitFrameworkConstants.NameOfNull) + && constraintPart.GetConstraintName() == NUnitFrameworkConstants.NameOfIsNull) { var actualType = AssertHelper.GetUnwrappedActualType(actualOperation); diff --git a/src/nunit.analyzers/SameAsIncompatibleTypes/SameAsIncompatibleTypesAnalyzer.cs b/src/nunit.analyzers/SameAsIncompatibleTypes/SameAsIncompatibleTypesAnalyzer.cs index 664cb7a7..ad3031b8 100644 --- a/src/nunit.analyzers/SameAsIncompatibleTypes/SameAsIncompatibleTypesAnalyzer.cs +++ b/src/nunit.analyzers/SameAsIncompatibleTypes/SameAsIncompatibleTypesAnalyzer.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Immutable; -using System.Linq; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.Diagnostics; @@ -8,7 +7,6 @@ using NUnit.Analyzers.Constants; using NUnit.Analyzers.Extensions; using NUnit.Analyzers.Helpers; -using NUnit.Analyzers.Operations; namespace NUnit.Analyzers.SameAsIncompatibleTypes { diff --git a/src/nunit.analyzers/SameAsOnValueTypes/SameAsOnValueTypesAnalyzer.cs b/src/nunit.analyzers/SameAsOnValueTypes/SameAsOnValueTypesAnalyzer.cs index 38a5087c..62b5526e 100644 --- a/src/nunit.analyzers/SameAsOnValueTypes/SameAsOnValueTypesAnalyzer.cs +++ b/src/nunit.analyzers/SameAsOnValueTypes/SameAsOnValueTypesAnalyzer.cs @@ -1,13 +1,11 @@ using System; using System.Collections.Immutable; -using System.Linq; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Operations; using NUnit.Analyzers.Constants; using NUnit.Analyzers.Extensions; using NUnit.Analyzers.Helpers; -using NUnit.Analyzers.Operations; namespace NUnit.Analyzers.SameAsOnValueTypes { diff --git a/src/nunit.analyzers/SameAsOnValueTypes/SameAsOnValueTypesCodeFix.cs b/src/nunit.analyzers/SameAsOnValueTypes/SameAsOnValueTypesCodeFix.cs index f89cf9b9..6d6da082 100644 --- a/src/nunit.analyzers/SameAsOnValueTypes/SameAsOnValueTypesCodeFix.cs +++ b/src/nunit.analyzers/SameAsOnValueTypes/SameAsOnValueTypesCodeFix.cs @@ -1,4 +1,3 @@ -using System.Collections.Generic; using System.Collections.Immutable; using System.Composition; using System.Linq; diff --git a/src/nunit.analyzers/SomeItemsIncompatibleTypes/SomeItemsIncompatibleTypesAnalyzer.cs b/src/nunit.analyzers/SomeItemsIncompatibleTypes/SomeItemsIncompatibleTypesAnalyzer.cs index a0fd3f79..18f66087 100644 --- a/src/nunit.analyzers/SomeItemsIncompatibleTypes/SomeItemsIncompatibleTypesAnalyzer.cs +++ b/src/nunit.analyzers/SomeItemsIncompatibleTypes/SomeItemsIncompatibleTypesAnalyzer.cs @@ -1,5 +1,4 @@ using System.Collections.Immutable; -using System.Linq; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Operations; @@ -55,7 +54,7 @@ protected override void AnalyzeAssertInvocation(OperationAnalysisContext context if (elementType is null) continue; - IInvocationOperation? usingInvocation = constraintPart.GetSuffix(NUnitFrameworkConstants.NameOfUsing) as IInvocationOperation; + IInvocationOperation? usingInvocation = constraintPart.GetSuffix(NUnitFrameworkConstants.NameOfEqualConstraintUsing) as IInvocationOperation; if (usingInvocation is not null) { IMethodSymbol target = usingInvocation.TargetMethod; diff --git a/src/nunit.analyzers/StringAssertUsage/StringAssertUsageAnalyzer.cs b/src/nunit.analyzers/StringAssertUsage/StringAssertUsageAnalyzer.cs new file mode 100644 index 00000000..9a064588 --- /dev/null +++ b/src/nunit.analyzers/StringAssertUsage/StringAssertUsageAnalyzer.cs @@ -0,0 +1,64 @@ +using System.Collections.Generic; +using System.Collections.Immutable; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.Operations; +using NUnit.Analyzers.Constants; +using NUnit.Analyzers.Extensions; +using static NUnit.Analyzers.Constants.NUnitFrameworkConstants; + +namespace NUnit.Analyzers.StringAssertUsage +{ + [DiagnosticAnalyzer(LanguageNames.CSharp)] + public sealed class StringAssertUsageAnalyzer : BaseAssertionAnalyzer + { + internal static readonly ImmutableDictionary StringAssertToConstraint = + new Dictionary + { + { NameOfStringAssertContains, $"{NameOfDoes}.{NameOfDoesContain}(expected)" }, + { NameOfStringAssertDoesNotContain, $"{NameOfDoes}.{NameOfDoesNot}.{NameOfDoesContain}(expected)" }, + { NameOfStringAssertStartsWith, $"{NameOfDoes}.{NameOfDoesStartWith}(expected)" }, + { NameOfStringAssertDoesNotStartWith, $"{NameOfDoes}.{NameOfDoesNot}.{NameOfDoesStartWith}(expected)" }, + { NameOfStringAssertEndsWith, $"{NameOfDoes}.{NameOfDoesEndWith}(expected)" }, + { NameOfStringAssertDoesNotEndWith, $"{NameOfDoes}.{NameOfDoesNot}.{NameOfDoesEndWith}(expected)" }, + { NameOfStringAssertAreEqualIgnoringCase, $"{NameOfIs}.{NameOfIsEqualTo}(expected).{NameOfEqualConstraintIgnoreCase}" }, + { NameOfStringAssertAreNotEqualIgnoringCase, $"{NameOfIs}.{NameOfIsNot}.{NameOfIsEqualTo}(expected).{NameOfEqualConstraintIgnoreCase}" }, + { NameOfStringAssertIsMatch, $"{NameOfDoes}.{NameOfDoesMatch}(expected)" }, + { NameOfStringAssertDoesNotMatch, $"{NameOfDoes}.{NameOfDoesNot}.{NameOfDoesMatch}(expected)" }, + }.ToImmutableDictionary(); + + private static readonly DiagnosticDescriptor stringAssertDescriptor = DiagnosticDescriptorCreator.Create( + id: AnalyzerIdentifiers.StringAssertUsage, + title: StringAssertUsageConstants.StringAssertTitle, + messageFormat: StringAssertUsageConstants.StringAssertMessage, + category: Categories.Assertion, + defaultSeverity: DiagnosticSeverity.Warning, + description: StringAssertUsageConstants.StringAssertDescription); + + public override ImmutableArray SupportedDiagnostics { get; } = + ImmutableArray.Create(stringAssertDescriptor); + + protected override bool IsAssert(bool hasClassicAssert, IInvocationOperation invocationOperation) + { + return invocationOperation.TargetMethod.ContainingType.IsStringAssert(); + } + + protected override void AnalyzeAssertInvocation(OperationAnalysisContext context, IInvocationOperation assertOperation) + { + var methodSymbol = assertOperation.TargetMethod; + + if (StringAssertToConstraint.TryGetValue(methodSymbol.Name, out string? constraint)) + { + context.ReportDiagnostic(Diagnostic.Create( + stringAssertDescriptor, + assertOperation.Syntax.GetLocation(), + new Dictionary + { + [AnalyzerPropertyKeys.ModelName] = methodSymbol.Name, + }.ToImmutableDictionary(), + constraint, + methodSymbol.Name)); + } + } + } +} diff --git a/src/nunit.analyzers/StringAssertUsage/StringAssertUsageCodeFix.cs b/src/nunit.analyzers/StringAssertUsage/StringAssertUsageCodeFix.cs new file mode 100644 index 00000000..f9da94a4 --- /dev/null +++ b/src/nunit.analyzers/StringAssertUsage/StringAssertUsageCodeFix.cs @@ -0,0 +1,49 @@ +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Composition; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CodeFixes; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using NUnit.Analyzers.ClassicModelAssertUsage; +using NUnit.Analyzers.Constants; +using NUnit.Analyzers.Helpers; +using static Microsoft.CodeAnalysis.CSharp.SyntaxFactory; +using static NUnit.Analyzers.Constants.NUnitFrameworkConstants; + +namespace NUnit.Analyzers.StringAssertUsage +{ + [ExportCodeFixProvider(LanguageNames.CSharp)] + [Shared] + internal class StringAssertUsageCodeFix : ClassicModelAssertUsageCodeFix + { + private static readonly ImmutableDictionary StringAssertToConstraints = + new Dictionary + { + { NameOfStringAssertContains, new Constraints(NameOfDoes, default(string), NameOfDoesContain) }, + { NameOfStringAssertDoesNotContain, new Constraints(NameOfDoes, NameOfDoesNot, NameOfDoesContain) }, + { NameOfStringAssertStartsWith, new Constraints(NameOfDoes, default(string), NameOfDoesStartWith) }, + { NameOfStringAssertDoesNotStartWith, new Constraints(NameOfDoes, NameOfDoesNot, NameOfDoesStartWith) }, + { NameOfStringAssertEndsWith, new Constraints(NameOfDoes, default(string), NameOfDoesEndWith) }, + { NameOfStringAssertDoesNotEndWith, new Constraints(NameOfDoes, NameOfDoesNot, NameOfDoesEndWith) }, + { NameOfStringAssertAreEqualIgnoringCase, new Constraints(NameOfIs, default(string), NameOfIsEqualTo, NameOfEqualConstraintIgnoreCase) }, + { NameOfStringAssertAreNotEqualIgnoringCase, new Constraints(NameOfIs, NameOfIsNot, NameOfIsEqualTo, NameOfEqualConstraintIgnoreCase) }, + { NameOfStringAssertIsMatch, new Constraints(NameOfDoes, default(string), NameOfDoesMatch) }, + { NameOfStringAssertDoesNotMatch, new Constraints(NameOfDoes, NameOfDoesNot, NameOfDoesMatch) }, + }.ToImmutableDictionary(); + + public override ImmutableArray FixableDiagnosticIds { get; } = ImmutableArray.Create( + AnalyzerIdentifiers.StringAssertUsage); + + protected override void UpdateArguments(Diagnostic diagnostic, List arguments) + { + string methodName = diagnostic.Properties[AnalyzerPropertyKeys.ModelName]!; + if (StringAssertToConstraints.TryGetValue(methodName, out Constraints? constraints)) + { + arguments.Insert(2, Argument(constraints.CreateConstraint(arguments[0]))); + + // Then we have to remove the 1st argument because that's now in the "constaint" + arguments.RemoveAt(0); + } + } + } +} diff --git a/src/nunit.analyzers/StringAssertUsage/StringAssertUsageConstants.cs b/src/nunit.analyzers/StringAssertUsage/StringAssertUsageConstants.cs new file mode 100644 index 00000000..eb518e34 --- /dev/null +++ b/src/nunit.analyzers/StringAssertUsage/StringAssertUsageConstants.cs @@ -0,0 +1,9 @@ +namespace NUnit.Analyzers.StringAssertUsage +{ + internal class StringAssertUsageConstants + { + internal const string StringAssertTitle = "Consider using Assert.That(...) instead of StringAssert(...)"; + internal const string StringAssertMessage = "Consider using the constraint model, Assert.That(...), instead of the classic model, StringAssert(...)"; + internal const string StringAssertDescription = "Consider using the constraint model, Assert.That(actual, {0}(expected)), instead of the classic model, StringAssert.{1}(expected, actual)."; + } +} diff --git a/src/nunit.analyzers/StringConstraintWrongActualType/StringConstraintWrongActualTypeAnalyzer.cs b/src/nunit.analyzers/StringConstraintWrongActualType/StringConstraintWrongActualTypeAnalyzer.cs index 965a7f2b..a7f7fadb 100644 --- a/src/nunit.analyzers/StringConstraintWrongActualType/StringConstraintWrongActualTypeAnalyzer.cs +++ b/src/nunit.analyzers/StringConstraintWrongActualType/StringConstraintWrongActualTypeAnalyzer.cs @@ -1,6 +1,5 @@ using System.Collections.Generic; using System.Collections.Immutable; -using System.Linq; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Diagnostics; using Microsoft.CodeAnalysis.Operations; diff --git a/src/nunit.analyzers/TestCaseSourceUsage/TestCaseSourceUsesStringAnalyzer.cs b/src/nunit.analyzers/TestCaseSourceUsage/TestCaseSourceUsesStringAnalyzer.cs index edfc2154..5e3fa485 100644 --- a/src/nunit.analyzers/TestCaseSourceUsage/TestCaseSourceUsesStringAnalyzer.cs +++ b/src/nunit.analyzers/TestCaseSourceUsage/TestCaseSourceUsesStringAnalyzer.cs @@ -1,6 +1,5 @@ using System.Collections.Immutable; using System.Linq; -using System.Reflection.Metadata; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; diff --git a/src/nunit.analyzers/UpdateStringFormatToInterpolatableString/UpdateStringFormatToInterpolatableStringAnalyzer.cs b/src/nunit.analyzers/UpdateStringFormatToInterpolatableString/UpdateStringFormatToInterpolatableStringAnalyzer.cs new file mode 100644 index 00000000..3f4efa4d --- /dev/null +++ b/src/nunit.analyzers/UpdateStringFormatToInterpolatableString/UpdateStringFormatToInterpolatableStringAnalyzer.cs @@ -0,0 +1,91 @@ +using System; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Globalization; +using System.Linq; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.Diagnostics; +using Microsoft.CodeAnalysis.Operations; +using NUnit.Analyzers.Constants; +using NUnit.Analyzers.Extensions; + +namespace NUnit.Analyzers.UpdateStringFormatToInterpolatableString +{ + [DiagnosticAnalyzer(LanguageNames.CSharp)] + public sealed class UpdateStringFormatToInterpolatableStringAnalyzer : BaseAssertionAnalyzer + { + private static readonly string[] ObsoleteParamsMethods = + { + NUnitFrameworkConstants.NameOfAssertPass, + NUnitFrameworkConstants.NameOfAssertFail, + NUnitFrameworkConstants.NameOfAssertWarn, + NUnitFrameworkConstants.NameOfAssertIgnore, + NUnitFrameworkConstants.NameOfAssertInconclusive, + NUnitFrameworkConstants.NameOfAssertThat, + }; + + private static readonly DiagnosticDescriptor updateStringFormatToInterpolatableString = DiagnosticDescriptorCreator.Create( + id: AnalyzerIdentifiers.UpdateStringFormatToInterpolatableString, + title: UpdateStringFormatToInterpolatableStringConstants.UpdateStringFormatToInterpolatableStringTitle, + messageFormat: UpdateStringFormatToInterpolatableStringConstants.UpdateStringFormatToInterpolatableStringMessage, + category: Categories.Assertion, + defaultSeverity: DiagnosticSeverity.Error, + description: UpdateStringFormatToInterpolatableStringConstants.UpdateStringFormatToInterpolatableStringDescription); + + public override ImmutableArray SupportedDiagnostics => + ImmutableArray.Create(updateStringFormatToInterpolatableString); + + protected override bool IsAssert(bool hasClassicAssert, IInvocationOperation invocationOperation) + { + return invocationOperation.TargetMethod.ContainingType.IsAssert(); + } + + protected override void AnalyzeAssertInvocation(Version nunitVersion, OperationAnalysisContext context, IInvocationOperation assertOperation) + { + if (nunitVersion.Major >= 4) + { + // Too late, this won't work as the method with the `params` parameter doesn't exists + // and won't be resolved by the compiler. + return; + } + + int lastParameterIndex = assertOperation.TargetMethod.Parameters.Length - 1; + if (lastParameterIndex > 0 && assertOperation.TargetMethod.Parameters[lastParameterIndex].IsParams) + { + IArgumentOperation lastArgument = assertOperation.Arguments[lastParameterIndex]; + if (IsNonEmptyParamsArrayArgument(lastArgument)) + { + string methodName = assertOperation.TargetMethod.Name; + + if (!ObsoleteParamsMethods.Contains(methodName)) + { + return; + } + + int minimumNumberOfArguments = lastParameterIndex - 1; + + context.ReportDiagnostic(Diagnostic.Create( + updateStringFormatToInterpolatableString, + assertOperation.Syntax.GetLocation(), + new Dictionary + { + [AnalyzerPropertyKeys.ModelName] = methodName, + [AnalyzerPropertyKeys.MinimumNumberOfArguments] = minimumNumberOfArguments.ToString(CultureInfo.InvariantCulture), + }.ToImmutableDictionary())); + } + } + + static bool IsNonEmptyParamsArrayArgument(IArgumentOperation argument) + { + if (argument.ArgumentKind == ArgumentKind.ParamArray) + { + var value = (IArrayCreationOperation)argument.Value; + return value.Initializer is not null && value.Initializer.ElementValues.Length > 0; + } + + // If it is a reference to an array variable, it is also no good. + return argument.ArgumentKind == ArgumentKind.Explicit; + } + } + } +} diff --git a/src/nunit.analyzers/UpdateStringFormatToInterpolatableString/UpdateStringFormatToInterpolatableStringCodeFix.cs b/src/nunit.analyzers/UpdateStringFormatToInterpolatableString/UpdateStringFormatToInterpolatableStringCodeFix.cs new file mode 100644 index 00000000..07438730 --- /dev/null +++ b/src/nunit.analyzers/UpdateStringFormatToInterpolatableString/UpdateStringFormatToInterpolatableStringCodeFix.cs @@ -0,0 +1,72 @@ +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Composition; +using System.Globalization; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CodeActions; +using Microsoft.CodeAnalysis.CodeFixes; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using NUnit.Analyzers.Constants; +using NUnit.Analyzers.Extensions; +using NUnit.Analyzers.Helpers; + +namespace NUnit.Analyzers.UpdateStringFormatToInterpolatableString +{ + [ExportCodeFixProvider(LanguageNames.CSharp)] + [Shared] + internal class UpdateStringFormatToInterpolatableStringCodeFix : CodeFixProvider + { + internal const string UpdateStringFormatToInterpolatableStringDescription = + "Replace format specification and params with interpolatable string"; + + public override ImmutableArray FixableDiagnosticIds { get; } = ImmutableArray.Create( + AnalyzerIdentifiers.UpdateStringFormatToInterpolatableString); + + public sealed override FixAllProvider GetFixAllProvider() + { + return WellKnownFixAllProviders.BatchFixer; + } + + public override async Task RegisterCodeFixesAsync(CodeFixContext context) + { + var root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false); + var semanticModel = await context.Document.GetSemanticModelAsync(context.CancellationToken).ConfigureAwait(false); + + if (root is null || semanticModel is null) + { + return; + } + + context.CancellationToken.ThrowIfCancellationRequested(); + + var diagnostic = context.Diagnostics.First(); + var node = root.FindNode(diagnostic.Location.SourceSpan); + var invocationNode = node as InvocationExpressionSyntax; + + if (invocationNode is null) + return; + + List arguments = invocationNode.ArgumentList.Arguments.ToList(); + + var minimumNumberOfArguments = int.Parse(diagnostic.Properties[AnalyzerPropertyKeys.MinimumNumberOfArguments]!, CultureInfo.InvariantCulture); + + CodeFixHelper.UpdateStringFormatToFormattableString(arguments, minimumNumberOfArguments); + + var newArgumentsList = invocationNode.ArgumentList.WithArguments(arguments); + var newInvocationNode = invocationNode.WithArgumentList(newArgumentsList); + + context.CancellationToken.ThrowIfCancellationRequested(); + + var newRoot = root.ReplaceNode(invocationNode, newInvocationNode); + + var codeAction = CodeAction.Create( + UpdateStringFormatToInterpolatableStringDescription, + _ => Task.FromResult(context.Document.WithSyntaxRoot(newRoot)), + UpdateStringFormatToInterpolatableStringDescription); + + context.RegisterCodeFix(codeAction, context.Diagnostics); + } + } +} diff --git a/src/nunit.analyzers/UpdateStringFormatToInterpolatableString/UpdateStringFormatToInterpolatableStringConstants.cs b/src/nunit.analyzers/UpdateStringFormatToInterpolatableString/UpdateStringFormatToInterpolatableStringConstants.cs new file mode 100644 index 00000000..b7a6199d --- /dev/null +++ b/src/nunit.analyzers/UpdateStringFormatToInterpolatableString/UpdateStringFormatToInterpolatableStringConstants.cs @@ -0,0 +1,9 @@ +namespace NUnit.Analyzers.UpdateStringFormatToInterpolatableString +{ + internal static class UpdateStringFormatToInterpolatableStringConstants + { + internal const string UpdateStringFormatToInterpolatableStringTitle = "NUnit 4 no longer supports string.Format specification"; + internal const string UpdateStringFormatToInterpolatableStringMessage = "NUnit 4 no longer supports string.Format specification for Assert"; + internal const string UpdateStringFormatToInterpolatableStringDescription = "Replace format specification with interpolated string."; + } +} diff --git a/src/nunit.analyzers/UseAssertMultiple/UseAssertMultipleCodeFix.cs b/src/nunit.analyzers/UseAssertMultiple/UseAssertMultipleCodeFix.cs index 614c9597..88976134 100644 --- a/src/nunit.analyzers/UseAssertMultiple/UseAssertMultipleCodeFix.cs +++ b/src/nunit.analyzers/UseAssertMultiple/UseAssertMultipleCodeFix.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Collections.Immutable; -using System.Composition; using System.Linq; using System.Threading.Tasks; using Microsoft.CodeAnalysis; diff --git a/src/nunit.analyzers/UseCollectionConstraint/UseCollectionConstraintCodeFix.cs b/src/nunit.analyzers/UseCollectionConstraint/UseCollectionConstraintCodeFix.cs index 76fed202..3dddf944 100644 --- a/src/nunit.analyzers/UseCollectionConstraint/UseCollectionConstraintCodeFix.cs +++ b/src/nunit.analyzers/UseCollectionConstraint/UseCollectionConstraintCodeFix.cs @@ -1,9 +1,6 @@ -using System; using System.Collections.Generic; using System.Collections.Immutable; using System.Composition; -using System.Globalization; -using System.Linq; using System.Threading.Tasks; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CodeActions; diff --git a/src/nunit.analyzers/WithinUsage/WithinUsageAnalyzer.cs b/src/nunit.analyzers/WithinUsage/WithinUsageAnalyzer.cs index 09c2e9b3..d610135a 100644 --- a/src/nunit.analyzers/WithinUsage/WithinUsageAnalyzer.cs +++ b/src/nunit.analyzers/WithinUsage/WithinUsageAnalyzer.cs @@ -104,6 +104,9 @@ private static bool IsTypeSupported(ITypeSymbol type, HashSet? chec if (type.SpecialType == SpecialType.System_String) return false; // Even though it implements IEnumerable, it doesn't support Tolerance. + if (type.TypeKind == TypeKind.Enum) + return false; + if (type is IArrayTypeSymbol arrayType && IsTypeSupported(arrayType.ElementType, checkedTypes)) return true; @@ -160,7 +163,8 @@ private static bool IsTypeSupported(ITypeSymbol type, HashSet? chec return true; // Non-generic collections, we have no idea of the actual type used. } - return false; + // If the type overrides Equals, NUnit won't use tolerance + return type.GetMembers("Equals").Length == 0; } } }