diff --git a/TUnit.Analyzers.CodeFixers/NUnitMigrationCodeFixProvider.cs b/TUnit.Analyzers.CodeFixers/NUnitMigrationCodeFixProvider.cs index 02c5f7a3ab..442329335d 100644 --- a/TUnit.Analyzers.CodeFixers/NUnitMigrationCodeFixProvider.cs +++ b/TUnit.Analyzers.CodeFixers/NUnitMigrationCodeFixProvider.cs @@ -63,9 +63,10 @@ protected override bool IsFrameworkAttribute(string attributeName) { return attributeName switch { - "Test" or "TestCase" or "TestCaseSource" or + "Test" or "TestCase" or "TestCaseSource" or "SetUp" or "TearDown" or "OneTimeSetUp" or "OneTimeTearDown" or - "TestFixture" or "Category" or "Ignore" or "Explicit" or "Apartment" => true, + "TestFixture" or "Category" or "Ignore" or "Explicit" or "Apartment" or + "Platform" or "Theory" or "Description" => true, _ => false }; } diff --git a/TUnit.Analyzers.Tests/NUnitMigrationAnalyzerTests.cs b/TUnit.Analyzers.Tests/NUnitMigrationAnalyzerTests.cs index 2da07ef128..f5e5481478 100644 --- a/TUnit.Analyzers.Tests/NUnitMigrationAnalyzerTests.cs +++ b/TUnit.Analyzers.Tests/NUnitMigrationAnalyzerTests.cs @@ -2474,6 +2474,76 @@ public async Task TestMethod() ); } + [Test] + public async Task NUnit_Platform_Attribute_Removed() + { + await CodeFixer.VerifyCodeFixAsync( + """ + using NUnit.Framework; + + public class MyClass + { + {|#0:[Test]|} + [Platform(Include = "Win")] + public void TestMethod() + { + } + } + """, + Verifier.Diagnostic(Rules.NUnitMigration).WithLocation(0), + """ + using TUnit.Core; + using TUnit.Assertions; + using static TUnit.Assertions.Assert; + using TUnit.Assertions.Extensions; + + public class MyClass + { + [Test] + public void TestMethod() + { + } + } + """, + ConfigureNUnitTest + ); + } + + [Test] + public async Task NUnit_Description_Attribute_Removed() + { + await CodeFixer.VerifyCodeFixAsync( + """ + using NUnit.Framework; + + public class MyClass + { + {|#0:[Test]|} + [Description("This is a test description")] + public void TestMethod() + { + } + } + """, + Verifier.Diagnostic(Rules.NUnitMigration).WithLocation(0), + """ + using TUnit.Core; + using TUnit.Assertions; + using static TUnit.Assertions.Assert; + using TUnit.Assertions.Extensions; + + public class MyClass + { + [Test] + public void TestMethod() + { + } + } + """, + ConfigureNUnitTest + ); + } + [Test] public async Task NUnit_InterfaceImplementation_NotConvertedToAsync() { diff --git a/TUnit.Analyzers/Migrators/Base/MigrationHelpers.cs b/TUnit.Analyzers/Migrators/Base/MigrationHelpers.cs index ed43a8bb46..cb34fe429d 100644 --- a/TUnit.Analyzers/Migrators/Base/MigrationHelpers.cs +++ b/TUnit.Analyzers/Migrators/Base/MigrationHelpers.cs @@ -22,6 +22,7 @@ public static string ConvertTestAttributeName(string attributeName, string frame "NUnit" => attributeName switch { "Test" => "Test", + "Theory" => "Test", // NUnit [Theory] is same as [Test] "TestCase" => "Arguments", "TestCaseSource" => "MethodDataSource", "SetUp" => "Before", @@ -29,6 +30,9 @@ public static string ConvertTestAttributeName(string attributeName, string frame "OneTimeSetUp" => "Before", "OneTimeTearDown" => "After", "TestFixture" => null!, // Remove + "Ignore" => "Skip", // NUnit [Ignore] -> TUnit [Skip] + "Description" => null!, // Remove - no direct equivalent, use [Property] if needed + "Platform" => null!, // Remove - no direct equivalent, use runtime checks "Apartment" => "STAThreadExecutor", // Special handling in attribute rewriter _ => attributeName }, @@ -116,7 +120,7 @@ public static bool ShouldRemoveAttribute(string attributeName, string framework) { return framework switch { - "NUnit" => attributeName is "TestFixture", + "NUnit" => attributeName is "TestFixture" or "Platform" or "Description", "MSTest" => attributeName is "TestClass", _ => false };