diff --git a/TUnit.Analyzers.CodeFixers/MSTestMigrationCodeFixProvider.cs b/TUnit.Analyzers.CodeFixers/MSTestMigrationCodeFixProvider.cs index a636035820..763773508e 100644 --- a/TUnit.Analyzers.CodeFixers/MSTestMigrationCodeFixProvider.cs +++ b/TUnit.Analyzers.CodeFixers/MSTestMigrationCodeFixProvider.cs @@ -283,13 +283,13 @@ protected override bool IsFrameworkAssertionNamespace(string namespaceName) "AreEqual" => ConvertAreEqual(arguments), "AreNotEqual" => ConvertAreNotEqual(arguments), "AreSame" when arguments.Count >= 3 => - CreateTUnitAssertionWithMessage("IsSameReference", arguments[1].Expression, arguments[2].Expression, arguments[0]), + CreateTUnitAssertionWithMessage("IsSameReferenceAs", arguments[1].Expression, arguments[2].Expression, arguments[0]), "AreSame" when arguments.Count >= 2 => - CreateTUnitAssertion("IsSameReference", arguments[1].Expression, arguments[0]), + CreateTUnitAssertion("IsSameReferenceAs", arguments[1].Expression, arguments[0]), "AreNotSame" when arguments.Count >= 3 => - CreateTUnitAssertionWithMessage("IsNotSameReference", arguments[1].Expression, arguments[2].Expression, arguments[0]), + CreateTUnitAssertionWithMessage("IsNotSameReferenceAs", arguments[1].Expression, arguments[2].Expression, arguments[0]), "AreNotSame" when arguments.Count >= 2 => - CreateTUnitAssertion("IsNotSameReference", arguments[1].Expression, arguments[0]), + CreateTUnitAssertion("IsNotSameReferenceAs", arguments[1].Expression, arguments[0]), // 1-arg assertions with message as 2nd param "IsTrue" when arguments.Count >= 2 => diff --git a/TUnit.Analyzers.CodeFixers/NUnitMigrationCodeFixProvider.cs b/TUnit.Analyzers.CodeFixers/NUnitMigrationCodeFixProvider.cs index a81ead26fe..418c582910 100644 --- a/TUnit.Analyzers.CodeFixers/NUnitMigrationCodeFixProvider.cs +++ b/TUnit.Analyzers.CodeFixers/NUnitMigrationCodeFixProvider.cs @@ -662,7 +662,7 @@ private ExpressionSyntax ConvertConstraintToTUnitWithMessage(ExpressionSyntax ac }; } - // Handle Does.Not.StartWith, Does.Not.EndWith, Does.Not.Contain + // Handle Does.Not.StartWith, Does.Not.EndWith, Does.Not.Contain, Does.Not.Match if (memberAccess.Expression is MemberAccessExpressionSyntax doesNotAccess && doesNotAccess.Expression is IdentifierNameSyntax { Identifier.Text: "Does" } && doesNotAccess.Name.Identifier.Text == "Not") @@ -672,6 +672,7 @@ private ExpressionSyntax ConvertConstraintToTUnitWithMessage(ExpressionSyntax ac "StartWith" => CreateTUnitAssertionWithMessage("DoesNotStartWith", actualValue, message, constraint.ArgumentList.Arguments.ToArray()), "EndWith" => CreateTUnitAssertionWithMessage("DoesNotEndWith", actualValue, message, constraint.ArgumentList.Arguments.ToArray()), "Contain" => CreateTUnitAssertionWithMessage("DoesNotContain", actualValue, message, constraint.ArgumentList.Arguments.ToArray()), + "Match" => CreateTUnitAssertionWithMessage("DoesNotMatch", actualValue, message, constraint.ArgumentList.Arguments.ToArray()), _ => CreateTUnitAssertionWithMessage("DoesNotContain", actualValue, message, constraint.ArgumentList.Arguments.ToArray()) }; } @@ -704,13 +705,14 @@ private ExpressionSyntax ConvertConstraintToTUnitWithMessage(ExpressionSyntax ac }; } - // Handle Does.StartWith, Does.EndWith, Contains.Substring + // Handle Does.StartWith, Does.EndWith, Does.Match, Contains.Substring if (memberAccess.Expression is IdentifierNameSyntax { Identifier.Text: "Does" or "Contains" }) { return methodName switch { "StartWith" => CreateTUnitAssertionWithMessage("StartsWith", actualValue, message, constraint.ArgumentList.Arguments.ToArray()), "EndWith" => CreateTUnitAssertionWithMessage("EndsWith", actualValue, message, constraint.ArgumentList.Arguments.ToArray()), + "Match" => CreateTUnitAssertionWithMessage("Matches", actualValue, message, constraint.ArgumentList.Arguments.ToArray()), "Substring" => CreateTUnitAssertionWithMessage("Contains", actualValue, message, constraint.ArgumentList.Arguments.ToArray()), _ => CreateTUnitAssertionWithMessage("IsEqualTo", actualValue, message, SyntaxFactory.Argument(constraint)) }; @@ -729,6 +731,7 @@ private ExpressionSyntax ConvertConstraintToTUnitWithMessage(ExpressionSyntax ac "SameAs" => CreateTUnitAssertionWithMessage("IsSameReferenceAs", actualValue, message, constraint.ArgumentList.Arguments.ToArray()), "InstanceOf" => CreateTUnitAssertionWithMessage("IsAssignableTo", actualValue, message, constraint.ArgumentList.Arguments.ToArray()), "TypeOf" => CreateTUnitAssertionWithMessage("IsTypeOf", actualValue, message, constraint.ArgumentList.Arguments.ToArray()), + "Matches" => CreateTUnitAssertionWithMessage("Matches", actualValue, message, constraint.ArgumentList.Arguments.ToArray()), _ => CreateTUnitAssertionWithMessage("IsEqualTo", actualValue, message, SyntaxFactory.Argument(constraint)) }; } @@ -877,7 +880,7 @@ private ExpressionSyntax ConvertConstraintToTUnit(ExpressionSyntax actualValue, }; } - // Handle Does.Not.StartWith, Does.Not.EndWith, Does.Not.Contain + // Handle Does.Not.StartWith, Does.Not.EndWith, Does.Not.Contain, Does.Not.Match if (memberAccess.Expression is MemberAccessExpressionSyntax doesNotAccess && doesNotAccess.Expression is IdentifierNameSyntax { Identifier.Text: "Does" } && doesNotAccess.Name.Identifier.Text == "Not") @@ -887,6 +890,7 @@ private ExpressionSyntax ConvertConstraintToTUnit(ExpressionSyntax actualValue, "StartWith" => CreateTUnitAssertion("DoesNotStartWith", actualValue, constraint.ArgumentList.Arguments.ToArray()), "EndWith" => CreateTUnitAssertion("DoesNotEndWith", actualValue, constraint.ArgumentList.Arguments.ToArray()), "Contain" => CreateTUnitAssertion("DoesNotContain", actualValue, constraint.ArgumentList.Arguments.ToArray()), + "Match" => CreateTUnitAssertion("DoesNotMatch", actualValue, constraint.ArgumentList.Arguments.ToArray()), _ => CreateTUnitAssertion("DoesNotContain", actualValue, constraint.ArgumentList.Arguments.ToArray()) }; } @@ -901,13 +905,14 @@ private ExpressionSyntax ConvertConstraintToTUnit(ExpressionSyntax actualValue, }; } - // Handle Does.StartWith, Does.EndWith, Contains.Substring + // Handle Does.StartWith, Does.EndWith, Does.Match, Contains.Substring if (memberAccess.Expression is IdentifierNameSyntax { Identifier.Text: "Does" or "Contains" }) { return methodName switch { "StartWith" => CreateTUnitAssertion("StartsWith", actualValue, constraint.ArgumentList.Arguments.ToArray()), "EndWith" => CreateTUnitAssertion("EndsWith", actualValue, constraint.ArgumentList.Arguments.ToArray()), + "Match" => CreateTUnitAssertion("Matches", actualValue, constraint.ArgumentList.Arguments.ToArray()), "Substring" => CreateTUnitAssertion("Contains", actualValue, constraint.ArgumentList.Arguments.ToArray()), _ => CreateTUnitAssertion("IsEqualTo", actualValue, SyntaxFactory.Argument(constraint)) }; diff --git a/TUnit.Analyzers.Tests/MSTestMigrationAnalyzerTests.cs b/TUnit.Analyzers.Tests/MSTestMigrationAnalyzerTests.cs index f4ab66281b..6858434068 100644 --- a/TUnit.Analyzers.Tests/MSTestMigrationAnalyzerTests.cs +++ b/TUnit.Analyzers.Tests/MSTestMigrationAnalyzerTests.cs @@ -686,8 +686,8 @@ public async Task TestReferences() var obj2 = obj1; var obj3 = new object(); - await Assert.That(obj2).IsSameReference(obj1); - await Assert.That(obj3).IsNotSameReference(obj1); + await Assert.That(obj2).IsSameReferenceAs(obj1); + await Assert.That(obj3).IsNotSameReferenceAs(obj1); } } """, diff --git a/TUnit.Analyzers.Tests/NUnitMigrationAnalyzerTests.cs b/TUnit.Analyzers.Tests/NUnitMigrationAnalyzerTests.cs index c07e96f02c..7a2b898dad 100644 --- a/TUnit.Analyzers.Tests/NUnitMigrationAnalyzerTests.cs +++ b/TUnit.Analyzers.Tests/NUnitMigrationAnalyzerTests.cs @@ -886,6 +886,117 @@ public async Task TestMethod() ); } + [Test] + public async Task NUnit_Does_Not_EndWith_Converted() + { + await CodeFixer.VerifyCodeFixAsync( + """ + using NUnit.Framework; + + {|#0:public class MyClass|} + { + [Test] + public void TestMethod() + { + Assert.That("hello world", Does.Not.EndWith("foo")); + } + } + """, + Verifier.Diagnostic(Rules.NUnitMigration).WithLocation(0), + """ + using System.Threading.Tasks; + using TUnit.Core; + using TUnit.Assertions; + using static TUnit.Assertions.Assert; + using TUnit.Assertions.Extensions; + + public class MyClass + { + [Test] + public async Task TestMethod() + { + await Assert.That("hello world").DoesNotEndWith("foo"); + } + } + """, + ConfigureNUnitTest + ); + } + + [Test] + public async Task NUnit_Does_Match_Converted() + { + await CodeFixer.VerifyCodeFixAsync( + """ + using NUnit.Framework; + + {|#0:public class MyClass|} + { + [Test] + public void TestMethod() + { + Assert.That("hello123", Does.Match(@"\d+")); + } + } + """, + Verifier.Diagnostic(Rules.NUnitMigration).WithLocation(0), + """ + using System.Threading.Tasks; + using TUnit.Core; + using TUnit.Assertions; + using static TUnit.Assertions.Assert; + using TUnit.Assertions.Extensions; + + public class MyClass + { + [Test] + public async Task TestMethod() + { + await Assert.That("hello123").Matches(@"\d+"); + } + } + """, + ConfigureNUnitTest + ); + } + + [Test] + public async Task NUnit_Does_Not_Match_Converted() + { + await CodeFixer.VerifyCodeFixAsync( + """ + using NUnit.Framework; + + {|#0:public class MyClass|} + { + [Test] + public void TestMethod() + { + Assert.That("hello", Does.Not.Match(@"\d+")); + } + } + """, + Verifier.Diagnostic(Rules.NUnitMigration).WithLocation(0), + """ + using System.Threading.Tasks; + using TUnit.Core; + using TUnit.Assertions; + using static TUnit.Assertions.Assert; + using TUnit.Assertions.Extensions; + + public class MyClass + { + [Test] + public async Task TestMethod() + { + await Assert.That("hello").DoesNotMatch(@"\d+"); + } + } + """, + ConfigureNUnitTest + ); + } + [Test] public async Task NUnit_AssertionMessage_Converted_To_Because() {