diff --git a/Directory.Packages.props b/Directory.Packages.props index 79e723b..a1d7e52 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -1,10 +1,8 @@ - true true - @@ -12,8 +10,8 @@ + - @@ -28,9 +26,11 @@ + + + - diff --git a/Extensions.Test.sln b/Extensions.Test.sln index 6a8fc56..2cce2b5 100644 --- a/Extensions.Test.sln +++ b/Extensions.Test.sln @@ -40,9 +40,15 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NetEvolve.Extensions.MSTest EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NetEvolve.Extensions.XUnit.Tests.PublicApi", "tests\NetEvolve.Extensions.XUnit.Tests.PublicApi\NetEvolve.Extensions.XUnit.Tests.PublicApi.csproj", "{4D92E42D-68F1-4092-BDB7-29F6265C8CEC}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NetEvolve.Extensions.NUnit.Tests.PublicApi", "tests\NetEvolve.Extensions.NUnit.Tests.PublicApi\NetEvolve.Extensions.NUnit.Tests.PublicApi.csproj", "{4F4B90A9-9371-4D13-875B-331468D1E888}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NetEvolve.Extensions.NUnit.Tests.PublicApi", "tests\NetEvolve.Extensions.NUnit.Tests.PublicApi\NetEvolve.Extensions.NUnit.Tests.PublicApi.csproj", "{4F4B90A9-9371-4D13-875B-331468D1E888}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NetEvolve.Extensions.MSTest.Tests.PublicApi", "tests\NetEvolve.Extensions.MSTest.Tests.PublicApi\NetEvolve.Extensions.MSTest.Tests.PublicApi.csproj", "{37815304-2B2A-4EE1-A1A2-A947794ED7A5}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NetEvolve.Extensions.MSTest.Tests.PublicApi", "tests\NetEvolve.Extensions.MSTest.Tests.PublicApi\NetEvolve.Extensions.MSTest.Tests.PublicApi.csproj", "{37815304-2B2A-4EE1-A1A2-A947794ED7A5}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NetEvolve.Extensions.XUnit.V3", "src\NetEvolve.Extensions.XUnit.V3\NetEvolve.Extensions.XUnit.V3.csproj", "{E59DDFAC-7E76-41B8-B347-344E2AB5046C}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NetEvolve.Extensions.XUnit.V3.Tests.Unit", "tests\NetEvolve.Extensions.XUnit.V3.Tests.Unit\NetEvolve.Extensions.XUnit.V3.Tests.Unit.csproj", "{8CB5E4DA-E255-40A2-97FA-834CE0CA7F17}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NetEvolve.Extensions.XUnit.V3.Tests.PublicApi", "tests\NetEvolve.Extensions.XUnit.V3.Tests.PublicApi\NetEvolve.Extensions.XUnit.V3.Tests.PublicApi.csproj", "{852AA7AA-0F8B-4A13-8C56-D86753B3C054}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -86,6 +92,18 @@ Global {37815304-2B2A-4EE1-A1A2-A947794ED7A5}.Debug|Any CPU.Build.0 = Debug|Any CPU {37815304-2B2A-4EE1-A1A2-A947794ED7A5}.Release|Any CPU.ActiveCfg = Release|Any CPU {37815304-2B2A-4EE1-A1A2-A947794ED7A5}.Release|Any CPU.Build.0 = Release|Any CPU + {E59DDFAC-7E76-41B8-B347-344E2AB5046C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E59DDFAC-7E76-41B8-B347-344E2AB5046C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E59DDFAC-7E76-41B8-B347-344E2AB5046C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E59DDFAC-7E76-41B8-B347-344E2AB5046C}.Release|Any CPU.Build.0 = Release|Any CPU + {8CB5E4DA-E255-40A2-97FA-834CE0CA7F17}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8CB5E4DA-E255-40A2-97FA-834CE0CA7F17}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8CB5E4DA-E255-40A2-97FA-834CE0CA7F17}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8CB5E4DA-E255-40A2-97FA-834CE0CA7F17}.Release|Any CPU.Build.0 = Release|Any CPU + {852AA7AA-0F8B-4A13-8C56-D86753B3C054}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {852AA7AA-0F8B-4A13-8C56-D86753B3C054}.Debug|Any CPU.Build.0 = Debug|Any CPU + {852AA7AA-0F8B-4A13-8C56-D86753B3C054}.Release|Any CPU.ActiveCfg = Release|Any CPU + {852AA7AA-0F8B-4A13-8C56-D86753B3C054}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -100,6 +118,9 @@ Global {4D92E42D-68F1-4092-BDB7-29F6265C8CEC} = {D67E420A-2329-4879-B82C-069039603B81} {4F4B90A9-9371-4D13-875B-331468D1E888} = {D67E420A-2329-4879-B82C-069039603B81} {37815304-2B2A-4EE1-A1A2-A947794ED7A5} = {D67E420A-2329-4879-B82C-069039603B81} + {E59DDFAC-7E76-41B8-B347-344E2AB5046C} = {19B4116B-14B4-436F-8A52-E71DB9CFCA7C} + {8CB5E4DA-E255-40A2-97FA-834CE0CA7F17} = {D67E420A-2329-4879-B82C-069039603B81} + {852AA7AA-0F8B-4A13-8C56-D86753B3C054} = {D67E420A-2329-4879-B82C-069039603B81} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {EBB4607C-57F7-4F91-93B2-A444A3D33755} diff --git a/README.md b/README.md index cf4e9fe..50bf3bd 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,8 @@ # NetEvolve.Extensions Compatibility library for solutions using multiple .NET test frameworks. -The following test frameworks are supported - -[NetEvolve.Extensions.MSTest](https://www.nuget.org/packages/NetEvolve.Extensions.MSTest), -[NetEvolve.Extensions.NUnit](https://www.nuget.org/packages/NetEvolve.Extensions.NUnit) & -[NetEvolve.Extensions.XUnit](https://www.nuget.org/packages/NetEvolve.Extensions.XUnit). \ No newline at end of file +The following test frameworks are supported +- [MSTest](https://www.nuget.org/packages/NetEvolve.Extensions.MSTest), +- [NUnit](https://www.nuget.org/packages/NetEvolve.Extensions.NUnit) +- [XUnit](https://www.nuget.org/packages/NetEvolve.Extensions.XUnit) +- [XUnit.V3](https://www.nuget.org/packages/NetEvolve.Extensions.XUnit.V3) \ No newline at end of file diff --git a/src/NetEvolve.Extensions.MSTest/AcceptanceTestAttribute.cs b/src/NetEvolve.Extensions.MSTest/AcceptanceTestAttribute.cs index c30902b..c42b045 100644 --- a/src/NetEvolve.Extensions.MSTest/AcceptanceTestAttribute.cs +++ b/src/NetEvolve.Extensions.MSTest/AcceptanceTestAttribute.cs @@ -1,10 +1,15 @@ namespace NetEvolve.Extensions.MSTest; +using System; using NetEvolve.Extensions.MSTest.Internal; /// /// Attribute used to decorate a test class or method as AcceptanceTest. /// +[AttributeUsage( + AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method, + AllowMultiple = true +)] public sealed class AcceptanceTestAttribute : TestTraitBaseAttribute { /// diff --git a/src/NetEvolve.Extensions.MSTest/ArchitectureTestAttribute.cs b/src/NetEvolve.Extensions.MSTest/ArchitectureTestAttribute.cs index 722b964..3f58ad4 100644 --- a/src/NetEvolve.Extensions.MSTest/ArchitectureTestAttribute.cs +++ b/src/NetEvolve.Extensions.MSTest/ArchitectureTestAttribute.cs @@ -1,10 +1,15 @@ namespace NetEvolve.Extensions.MSTest; +using System; using NetEvolve.Extensions.MSTest.Internal; /// /// Attribute used to decorate a test class or method as ArchitectureTest. /// +[AttributeUsage( + AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method, + AllowMultiple = true +)] public sealed class ArchitectureTestAttribute : TestTraitBaseAttribute { /// diff --git a/src/NetEvolve.Extensions.MSTest/CodedUITestAttribute.cs b/src/NetEvolve.Extensions.MSTest/CodedUITestAttribute.cs index bc59200..75fe975 100644 --- a/src/NetEvolve.Extensions.MSTest/CodedUITestAttribute.cs +++ b/src/NetEvolve.Extensions.MSTest/CodedUITestAttribute.cs @@ -1,10 +1,15 @@ namespace NetEvolve.Extensions.MSTest; +using System; using NetEvolve.Extensions.MSTest.Internal; /// /// Attribute used to decorate a test class or method as CodedUITest. /// +[AttributeUsage( + AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method, + AllowMultiple = true +)] public sealed class CodedUITestAttribute : TestTraitBaseAttribute { /// diff --git a/src/NetEvolve.Extensions.MSTest/EndToEndTestAttribute.cs b/src/NetEvolve.Extensions.MSTest/EndToEndTestAttribute.cs index e58c3f0..ee969c2 100644 --- a/src/NetEvolve.Extensions.MSTest/EndToEndTestAttribute.cs +++ b/src/NetEvolve.Extensions.MSTest/EndToEndTestAttribute.cs @@ -1,10 +1,15 @@ namespace NetEvolve.Extensions.MSTest; +using System; using NetEvolve.Extensions.MSTest.Internal; /// /// Attribute used to decorate a test class or method as EndToEndTest. /// +[AttributeUsage( + AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method, + AllowMultiple = true +)] public sealed class EndToEndTestAttribute : TestTraitBaseAttribute { /// diff --git a/src/NetEvolve.Extensions.MSTest/FunctionalTestAttribute.cs b/src/NetEvolve.Extensions.MSTest/FunctionalTestAttribute.cs index 787c3b5..4a24593 100644 --- a/src/NetEvolve.Extensions.MSTest/FunctionalTestAttribute.cs +++ b/src/NetEvolve.Extensions.MSTest/FunctionalTestAttribute.cs @@ -1,10 +1,15 @@ namespace NetEvolve.Extensions.MSTest; +using System; using NetEvolve.Extensions.MSTest.Internal; /// /// Attribute used to decorate a test class or method as FunctionalTest. /// +[AttributeUsage( + AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method, + AllowMultiple = true +)] public sealed class FunctionalTestAttribute : TestTraitBaseAttribute { /// diff --git a/src/NetEvolve.Extensions.MSTest/IntegrationTestAttribute.cs b/src/NetEvolve.Extensions.MSTest/IntegrationTestAttribute.cs index 3f60540..f7b4f72 100644 --- a/src/NetEvolve.Extensions.MSTest/IntegrationTestAttribute.cs +++ b/src/NetEvolve.Extensions.MSTest/IntegrationTestAttribute.cs @@ -1,10 +1,15 @@ namespace NetEvolve.Extensions.MSTest; +using System; using NetEvolve.Extensions.MSTest.Internal; /// /// Attribute used to decorate a test class or method as IntegrationTest. /// +[AttributeUsage( + AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method, + AllowMultiple = true +)] public sealed class IntegrationTestAttribute : TestTraitBaseAttribute { /// diff --git a/src/NetEvolve.Extensions.MSTest/Internal/TestTraitBaseAttribute.cs b/src/NetEvolve.Extensions.MSTest/Internal/TestTraitBaseAttribute.cs index 0843abc..b339aba 100644 --- a/src/NetEvolve.Extensions.MSTest/Internal/TestTraitBaseAttribute.cs +++ b/src/NetEvolve.Extensions.MSTest/Internal/TestTraitBaseAttribute.cs @@ -10,11 +10,6 @@ "IDE1006:Naming Styles", Justification = "As designed." )] -[AttributeUsage( - AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method, - AllowMultiple = true, - Inherited = true -)] public abstract class TestTraitBaseAttribute : TestCategoryBaseAttribute { /// @@ -22,5 +17,5 @@ public abstract class TestTraitBaseAttribute : TestCategoryBaseAttribute /// protected TestTraitBaseAttribute(string categoryName) - : base() => TestCategories = new List { categoryName }; + : base() => TestCategories = [categoryName]; } diff --git a/src/NetEvolve.Extensions.MSTest/PerformanceTestAttribute.cs b/src/NetEvolve.Extensions.MSTest/PerformanceTestAttribute.cs index e059a5e..005692c 100644 --- a/src/NetEvolve.Extensions.MSTest/PerformanceTestAttribute.cs +++ b/src/NetEvolve.Extensions.MSTest/PerformanceTestAttribute.cs @@ -1,10 +1,15 @@ namespace NetEvolve.Extensions.MSTest; +using System; using NetEvolve.Extensions.MSTest.Internal; /// /// Attribute used to decorate a test class or method as PerformanceTest. /// +[AttributeUsage( + AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method, + AllowMultiple = true +)] public sealed class PerformanceTestAttribute : TestTraitBaseAttribute { /// diff --git a/src/NetEvolve.Extensions.MSTest/PostDeploymentAttribute.cs b/src/NetEvolve.Extensions.MSTest/PostDeploymentAttribute.cs index bca0f60..c58dffb 100644 --- a/src/NetEvolve.Extensions.MSTest/PostDeploymentAttribute.cs +++ b/src/NetEvolve.Extensions.MSTest/PostDeploymentAttribute.cs @@ -1,10 +1,15 @@ namespace NetEvolve.Extensions.MSTest; +using System; using NetEvolve.Extensions.MSTest.Internal; /// /// Attribute used to decorate a test class or method as PostDeployment. /// +[AttributeUsage( + AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method, + AllowMultiple = true +)] public sealed class PostDeploymentAttribute : TestTraitBaseAttribute { /// diff --git a/src/NetEvolve.Extensions.MSTest/PreDeploymentAttribute.cs b/src/NetEvolve.Extensions.MSTest/PreDeploymentAttribute.cs index 1309a2c..f79468d 100644 --- a/src/NetEvolve.Extensions.MSTest/PreDeploymentAttribute.cs +++ b/src/NetEvolve.Extensions.MSTest/PreDeploymentAttribute.cs @@ -1,10 +1,15 @@ namespace NetEvolve.Extensions.MSTest; +using System; using NetEvolve.Extensions.MSTest.Internal; /// /// Attribute used to decorate a test class or method as PreDeployment. /// +[AttributeUsage( + AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method, + AllowMultiple = true +)] public sealed class PreDeploymentAttribute : TestTraitBaseAttribute { /// diff --git a/src/NetEvolve.Extensions.MSTest/README.md b/src/NetEvolve.Extensions.MSTest/README.md index 7a05a75..dea585a 100644 --- a/src/NetEvolve.Extensions.MSTest/README.md +++ b/src/NetEvolve.Extensions.MSTest/README.md @@ -1,10 +1,11 @@ # NetEvolve.Extensions.MSTest Compatibility library for solutions using multiple .NET test frameworks. -The following test frameworks are supported - -[MSTest](https://www.nuget.org/packages/NetEvolve.Extensions.MSTest), -[NUnit](https://www.nuget.org/packages/NetEvolve.Extensions.NUnit) & -[XUnit](https://www.nuget.org/packages/NetEvolve.Extensions.XUnit). +The following test frameworks are supported +- [MSTest](https://www.nuget.org/packages/NetEvolve.Extensions.MSTest), +- [NUnit](https://www.nuget.org/packages/NetEvolve.Extensions.NUnit) +- [XUnit](https://www.nuget.org/packages/NetEvolve.Extensions.XUnit) +- [XUnit.V3](https://www.nuget.org/packages/NetEvolve.Extensions.XUnit.V3) ## Basic functionality diff --git a/src/NetEvolve.Extensions.MSTest/UnitTestAttribute.cs b/src/NetEvolve.Extensions.MSTest/UnitTestAttribute.cs index ad6032c..074e91d 100644 --- a/src/NetEvolve.Extensions.MSTest/UnitTestAttribute.cs +++ b/src/NetEvolve.Extensions.MSTest/UnitTestAttribute.cs @@ -1,10 +1,15 @@ namespace NetEvolve.Extensions.MSTest; +using System; using NetEvolve.Extensions.MSTest.Internal; /// /// Attribute used to decorate a test class or method as UnitTest. /// +[AttributeUsage( + AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method, + AllowMultiple = true +)] public sealed class UnitTestAttribute : TestTraitBaseAttribute { /// diff --git a/src/NetEvolve.Extensions.NUnit/AcceptanceTestAttribute.cs b/src/NetEvolve.Extensions.NUnit/AcceptanceTestAttribute.cs index 0a4be3a..67c6490 100644 --- a/src/NetEvolve.Extensions.NUnit/AcceptanceTestAttribute.cs +++ b/src/NetEvolve.Extensions.NUnit/AcceptanceTestAttribute.cs @@ -1,10 +1,15 @@ namespace NetEvolve.Extensions.NUnit; +using System; using global::NUnit.Framework; /// /// Attribute used to decorate a test class or method as AcceptanceTest. /// +[AttributeUsage( + AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method, + AllowMultiple = true +)] public sealed class AcceptanceTestAttribute : CategoryAttribute { /// diff --git a/src/NetEvolve.Extensions.NUnit/ArchitectureTestAttribute.cs b/src/NetEvolve.Extensions.NUnit/ArchitectureTestAttribute.cs index fec2579..8a594a5 100644 --- a/src/NetEvolve.Extensions.NUnit/ArchitectureTestAttribute.cs +++ b/src/NetEvolve.Extensions.NUnit/ArchitectureTestAttribute.cs @@ -1,10 +1,15 @@ namespace NetEvolve.Extensions.NUnit; +using System; using global::NUnit.Framework; /// /// Attribute used to decorate a test class or method as ArchitectureTest. /// +[AttributeUsage( + AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method, + AllowMultiple = true +)] public sealed class ArchitectureTestAttribute : CategoryAttribute { /// diff --git a/src/NetEvolve.Extensions.NUnit/CodedUITestAttribute.cs b/src/NetEvolve.Extensions.NUnit/CodedUITestAttribute.cs index 5bcf46c..f073e55 100644 --- a/src/NetEvolve.Extensions.NUnit/CodedUITestAttribute.cs +++ b/src/NetEvolve.Extensions.NUnit/CodedUITestAttribute.cs @@ -1,10 +1,15 @@ namespace NetEvolve.Extensions.NUnit; +using System; using global::NUnit.Framework; /// /// Attribute used to decorate a test class or method as CodedUITest. /// +[AttributeUsage( + AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method, + AllowMultiple = true +)] public sealed class CodedUITestAttribute : CategoryAttribute { /// diff --git a/src/NetEvolve.Extensions.NUnit/EndToEndTestAttribute.cs b/src/NetEvolve.Extensions.NUnit/EndToEndTestAttribute.cs index 53dc6d1..1e42369 100644 --- a/src/NetEvolve.Extensions.NUnit/EndToEndTestAttribute.cs +++ b/src/NetEvolve.Extensions.NUnit/EndToEndTestAttribute.cs @@ -1,10 +1,15 @@ namespace NetEvolve.Extensions.NUnit; +using System; using global::NUnit.Framework; /// /// Attribute used to decorate a test class or method as EndToEndTest. /// +[AttributeUsage( + AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method, + AllowMultiple = true +)] public sealed class EndToEndTestAttribute : CategoryAttribute { /// diff --git a/src/NetEvolve.Extensions.NUnit/FunctionalTestAttribute.cs b/src/NetEvolve.Extensions.NUnit/FunctionalTestAttribute.cs index 65acf68..38d73f8 100644 --- a/src/NetEvolve.Extensions.NUnit/FunctionalTestAttribute.cs +++ b/src/NetEvolve.Extensions.NUnit/FunctionalTestAttribute.cs @@ -1,10 +1,15 @@ namespace NetEvolve.Extensions.NUnit; +using System; using global::NUnit.Framework; /// /// Attribute used to decorate a test class or method as FunctionalTest. /// +[AttributeUsage( + AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method, + AllowMultiple = true +)] public sealed class FunctionalTestAttribute : CategoryAttribute { /// diff --git a/src/NetEvolve.Extensions.NUnit/PerformanceTestAttribute.cs b/src/NetEvolve.Extensions.NUnit/PerformanceTestAttribute.cs index 7379632..202acf7 100644 --- a/src/NetEvolve.Extensions.NUnit/PerformanceTestAttribute.cs +++ b/src/NetEvolve.Extensions.NUnit/PerformanceTestAttribute.cs @@ -1,10 +1,15 @@ namespace NetEvolve.Extensions.NUnit; +using System; using global::NUnit.Framework; /// /// Attribute used to decorate a test class or method as PerformanceTest. /// +[AttributeUsage( + AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method, + AllowMultiple = true +)] public sealed class PerformanceTestAttribute : CategoryAttribute { /// diff --git a/src/NetEvolve.Extensions.NUnit/PostDeploymentAttribute.cs b/src/NetEvolve.Extensions.NUnit/PostDeploymentAttribute.cs index 15b7058..8eeef5a 100644 --- a/src/NetEvolve.Extensions.NUnit/PostDeploymentAttribute.cs +++ b/src/NetEvolve.Extensions.NUnit/PostDeploymentAttribute.cs @@ -1,10 +1,15 @@ namespace NetEvolve.Extensions.NUnit; +using System; using global::NUnit.Framework; /// /// Attribute used to decorate a test class or method as PostDeployment. /// +[AttributeUsage( + AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method, + AllowMultiple = true +)] public sealed class PostDeploymentAttribute : CategoryAttribute { /// diff --git a/src/NetEvolve.Extensions.NUnit/PreDeploymentAttribute.cs b/src/NetEvolve.Extensions.NUnit/PreDeploymentAttribute.cs index c1d944c..b549f61 100644 --- a/src/NetEvolve.Extensions.NUnit/PreDeploymentAttribute.cs +++ b/src/NetEvolve.Extensions.NUnit/PreDeploymentAttribute.cs @@ -1,10 +1,15 @@ namespace NetEvolve.Extensions.NUnit; +using System; using global::NUnit.Framework; /// /// Attribute used to decorate a test class or method as PreDeployment. /// +[AttributeUsage( + AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method, + AllowMultiple = true +)] public sealed class PreDeploymentAttribute : CategoryAttribute { /// diff --git a/src/NetEvolve.Extensions.NUnit/README.md b/src/NetEvolve.Extensions.NUnit/README.md index 1909a7f..4e948d5 100644 --- a/src/NetEvolve.Extensions.NUnit/README.md +++ b/src/NetEvolve.Extensions.NUnit/README.md @@ -1,10 +1,11 @@ # NetEvolve.Extensions.NUnit Compatibility library for solutions using multiple .NET test frameworks. -The following test frameworks are supported - -[MSTest](https://www.nuget.org/packages/NetEvolve.Extensions.MSTest), -[NUnit](https://www.nuget.org/packages/NetEvolve.Extensions.NUnit) & -[XUnit](https://www.nuget.org/packages/NetEvolve.Extensions.XUnit). +The following test frameworks are supported +- [MSTest](https://www.nuget.org/packages/NetEvolve.Extensions.MSTest), +- [NUnit](https://www.nuget.org/packages/NetEvolve.Extensions.NUnit) +- [XUnit](https://www.nuget.org/packages/NetEvolve.Extensions.XUnit) +- [XUnit.V3](https://www.nuget.org/packages/NetEvolve.Extensions.XUnit.V3) ## Basic functionality diff --git a/src/NetEvolve.Extensions.NUnit/UnitTestAttribute.cs b/src/NetEvolve.Extensions.NUnit/UnitTestAttribute.cs index e68cd03..85f0ebe 100644 --- a/src/NetEvolve.Extensions.NUnit/UnitTestAttribute.cs +++ b/src/NetEvolve.Extensions.NUnit/UnitTestAttribute.cs @@ -1,10 +1,15 @@ namespace NetEvolve.Extensions.NUnit; +using System; using global::NUnit.Framework; /// /// Attribute used to decorate a test class or method as UnitTest. /// +[AttributeUsage( + AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method, + AllowMultiple = true +)] public sealed class UnitTestAttribute : CategoryAttribute { /// diff --git a/src/NetEvolve.Extensions.XUnit.V3/AcceptanceTestAttribute.cs b/src/NetEvolve.Extensions.XUnit.V3/AcceptanceTestAttribute.cs new file mode 100644 index 0000000..6d0bc3b --- /dev/null +++ b/src/NetEvolve.Extensions.XUnit.V3/AcceptanceTestAttribute.cs @@ -0,0 +1,20 @@ +namespace NetEvolve.Extensions.XUnit.V3; + +using System; +using NetEvolve.Extensions.XUnit.V3.Internal; + +/// +/// Attribute used to decorate a test class or method as AcceptanceTest. +/// +[AttributeUsage( + AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method, + AllowMultiple = true +)] +public sealed class AcceptanceTestAttribute : CategoryTraitBaseAttribute +{ + /// + /// Initializes a new instance of the class. + /// + public AcceptanceTestAttribute() + : base(Internals.AcceptanceTest) { } +} diff --git a/src/NetEvolve.Extensions.XUnit.V3/ArchitectureTestAttribute.cs b/src/NetEvolve.Extensions.XUnit.V3/ArchitectureTestAttribute.cs new file mode 100644 index 0000000..9f3b9e5 --- /dev/null +++ b/src/NetEvolve.Extensions.XUnit.V3/ArchitectureTestAttribute.cs @@ -0,0 +1,20 @@ +namespace NetEvolve.Extensions.XUnit.V3; + +using System; +using NetEvolve.Extensions.XUnit.V3.Internal; + +/// +/// Attribute used to decorate a test class or method as ArchitectureTest. +/// +[AttributeUsage( + AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method, + AllowMultiple = true +)] +public sealed class ArchitectureTestAttribute : CategoryTraitBaseAttribute +{ + /// + /// Initializes a new instance of the class. + /// + public ArchitectureTestAttribute() + : base(Internals.ArchitectureTest) { } +} diff --git a/src/NetEvolve.Extensions.XUnit.V3/BugAttribute.cs b/src/NetEvolve.Extensions.XUnit.V3/BugAttribute.cs new file mode 100644 index 0000000..6077435 --- /dev/null +++ b/src/NetEvolve.Extensions.XUnit.V3/BugAttribute.cs @@ -0,0 +1,31 @@ +namespace NetEvolve.Extensions.XUnit.V3; + +using System; +using NetEvolve.Extensions.XUnit.V3.Internal; + +/// +/// Attribute used to decorate a test class or method as Bug, with optional Id. +/// +[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)] +public sealed class BugAttribute : CategoryWithIdTraitBaseAttribute +{ + /// + /// Initializes a new instance of the class. + /// + public BugAttribute() + : base(Internals.Bug, null) { } + + /// + /// Initializes a new instance of the class. + /// + /// Bug Id + public BugAttribute(string? id) + : base(Internals.Bug, id) { } + + /// + /// Initializes a new instance of the class. + /// + /// Bug Id + public BugAttribute(long id) + : base(Internals.Bug, id) { } +} diff --git a/src/NetEvolve.Extensions.XUnit.V3/CodedUITestAttribute.cs b/src/NetEvolve.Extensions.XUnit.V3/CodedUITestAttribute.cs new file mode 100644 index 0000000..86530a3 --- /dev/null +++ b/src/NetEvolve.Extensions.XUnit.V3/CodedUITestAttribute.cs @@ -0,0 +1,20 @@ +namespace NetEvolve.Extensions.XUnit.V3; + +using System; +using NetEvolve.Extensions.XUnit.V3.Internal; + +/// +/// Attribute used to decorate a test class or method as CodedUITest. +/// +[AttributeUsage( + AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method, + AllowMultiple = true +)] +public sealed class CodedUITestAttribute : CategoryTraitBaseAttribute +{ + /// + /// Initializes a new instance of the class. + /// + public CodedUITestAttribute() + : base(Internals.CodedUITest) { } +} diff --git a/src/NetEvolve.Extensions.XUnit.V3/EndToEndTestAttribute.cs b/src/NetEvolve.Extensions.XUnit.V3/EndToEndTestAttribute.cs new file mode 100644 index 0000000..26804ab --- /dev/null +++ b/src/NetEvolve.Extensions.XUnit.V3/EndToEndTestAttribute.cs @@ -0,0 +1,20 @@ +namespace NetEvolve.Extensions.XUnit.V3; + +using System; +using NetEvolve.Extensions.XUnit.V3.Internal; + +/// +/// Attribute used to decorate a test class or method as EndToEndTest. +/// +[AttributeUsage( + AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method, + AllowMultiple = true +)] +public sealed class EndToEndTestAttribute : CategoryTraitBaseAttribute +{ + /// + /// Initializes a new instance of the class. + /// + public EndToEndTestAttribute() + : base(Internals.EndToEndTest) { } +} diff --git a/src/NetEvolve.Extensions.XUnit.V3/EpicAttribute.cs b/src/NetEvolve.Extensions.XUnit.V3/EpicAttribute.cs new file mode 100644 index 0000000..4099cc5 --- /dev/null +++ b/src/NetEvolve.Extensions.XUnit.V3/EpicAttribute.cs @@ -0,0 +1,31 @@ +namespace NetEvolve.Extensions.XUnit.V3; + +using System; +using NetEvolve.Extensions.XUnit.V3.Internal; + +/// +/// Attribute used to decorate a test class or method as Epic, with optional Id +/// +[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)] +public sealed class EpicAttribute : CategoryWithIdTraitBaseAttribute +{ + /// + /// Initializes a new instance of the class. + /// + public EpicAttribute() + : base(Internals.Epic, null) { } + + /// + /// Initializes a new instance of the class. + /// + /// Bug Id + public EpicAttribute(string? id) + : base(Internals.Epic, id) { } + + /// + /// Initializes a new instance of the class. + /// + /// Bug Id + public EpicAttribute(long id) + : base(Internals.Epic, id) { } +} diff --git a/src/NetEvolve.Extensions.XUnit.V3/FeatureAttribute.cs b/src/NetEvolve.Extensions.XUnit.V3/FeatureAttribute.cs new file mode 100644 index 0000000..963c39c --- /dev/null +++ b/src/NetEvolve.Extensions.XUnit.V3/FeatureAttribute.cs @@ -0,0 +1,31 @@ +namespace NetEvolve.Extensions.XUnit.V3; + +using System; +using NetEvolve.Extensions.XUnit.V3.Internal; + +/// +/// Attribute used to decorate a test class or method as Feature, with optional Id +/// +[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)] +public sealed class FeatureAttribute : CategoryWithIdTraitBaseAttribute +{ + /// + /// Initializes a new instance of the class. + /// + public FeatureAttribute() + : base(Internals.Feature, null) { } + + /// + /// Initializes a new instance of the class. + /// + /// Feature Id + public FeatureAttribute(string? id) + : base(Internals.Feature, id) { } + + /// + /// Initializes a new instance of the class. + /// + /// Feature Id + public FeatureAttribute(long id) + : base(Internals.Feature, id) { } +} diff --git a/src/NetEvolve.Extensions.XUnit.V3/FunctionalTestAttribute.cs b/src/NetEvolve.Extensions.XUnit.V3/FunctionalTestAttribute.cs new file mode 100644 index 0000000..b6e239f --- /dev/null +++ b/src/NetEvolve.Extensions.XUnit.V3/FunctionalTestAttribute.cs @@ -0,0 +1,20 @@ +namespace NetEvolve.Extensions.XUnit.V3; + +using System; +using NetEvolve.Extensions.XUnit.V3.Internal; + +/// +/// Attribute used to decorate a test class or method as FunctionalTest. +/// +[AttributeUsage( + AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method, + AllowMultiple = true +)] +public sealed class FunctionalTestAttribute : CategoryTraitBaseAttribute +{ + /// + /// Initializes a new instance of the class. + /// + public FunctionalTestAttribute() + : base(Internals.FunctionalTest) { } +} diff --git a/src/NetEvolve.Extensions.XUnit.V3/IntegrationTestAttribute.cs b/src/NetEvolve.Extensions.XUnit.V3/IntegrationTestAttribute.cs new file mode 100644 index 0000000..c8927fc --- /dev/null +++ b/src/NetEvolve.Extensions.XUnit.V3/IntegrationTestAttribute.cs @@ -0,0 +1,20 @@ +namespace NetEvolve.Extensions.XUnit.V3; + +using System; +using NetEvolve.Extensions.XUnit.V3.Internal; + +/// +/// Attribute used to decorate a test class or method as IntegrationTest. +/// +[AttributeUsage( + AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method, + AllowMultiple = true +)] +public sealed class IntegrationTestAttribute : CategoryTraitBaseAttribute +{ + /// + /// Initializes a new instance of the class. + /// + public IntegrationTestAttribute() + : base(Internals.IntegrationTest) { } +} diff --git a/src/NetEvolve.Extensions.XUnit.V3/Internal/CategoryTraitBaseAttribute.cs b/src/NetEvolve.Extensions.XUnit.V3/Internal/CategoryTraitBaseAttribute.cs new file mode 100644 index 0000000..290ac68 --- /dev/null +++ b/src/NetEvolve.Extensions.XUnit.V3/Internal/CategoryTraitBaseAttribute.cs @@ -0,0 +1,39 @@ +namespace NetEvolve.Extensions.XUnit.V3.Internal; + +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using Xunit.Internal; +using Xunit.v3; + +/// +/// Abstract class implementation of . +/// Provides property . +/// +[SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "As designed.")] +public abstract class CategoryTraitBaseAttribute : Attribute, ITraitAttribute +{ + /// + /// Gets the category value of the trait. + /// + public string Category { get; } + + /// + /// Initializes a new instance of the class. + /// + /// + protected CategoryTraitBaseAttribute(string category) => Category = category; + + /// + public IReadOnlyCollection> GetTraits() + { + var result = new Dictionary(StringComparer.OrdinalIgnoreCase); + + if (!string.IsNullOrWhiteSpace(Category)) + { + result.Add(Internals.TestCategory, Category); + } + + return result.CastOrToReadOnlyCollection(); + } +} diff --git a/src/NetEvolve.Extensions.XUnit.V3/Internal/CategoryWithIdTraitBaseAttribute.cs b/src/NetEvolve.Extensions.XUnit.V3/Internal/CategoryWithIdTraitBaseAttribute.cs new file mode 100644 index 0000000..f6e4201 --- /dev/null +++ b/src/NetEvolve.Extensions.XUnit.V3/Internal/CategoryWithIdTraitBaseAttribute.cs @@ -0,0 +1,79 @@ +namespace NetEvolve.Extensions.XUnit.V3.Internal; + +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using NetEvolve.Extensions.XUnit.V3; +using Xunit.Internal; +using Xunit.v3; + +/// +/// +/// Abstract class implementation of . +/// Provides basic functionality for category / id based testing. +/// +/// +/// Like: +/// +/// +/// +/// +/// +/// +/// +/// +/// +/// +[SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "As designed.")] +public abstract class CategoryWithIdTraitBaseAttribute : Attribute, ITraitAttribute +{ + /// + /// Gets the category value of the trait. + /// + public string Category { get; } + + /// + /// Gets the Id + /// + public string? Id { get; } + + /// + /// Initializes a new instance of the class. + /// + /// Category + /// Id + protected CategoryWithIdTraitBaseAttribute(string category, string? id) + { + Category = category; + Id = id; + } + + /// + /// Initializes a new instance of the class. + /// + /// Category + /// Id + protected CategoryWithIdTraitBaseAttribute(string category, long id) + { + Category = category; + Id = $"{id}"; + } + + /// + public IReadOnlyCollection> GetTraits() + { + var result = new Dictionary(StringComparer.OrdinalIgnoreCase); + + if (!string.IsNullOrWhiteSpace(Category)) + { + result.Add(Internals.TestCategory, Category); + + if (!string.IsNullOrWhiteSpace(Id)) + { + result.Add(Category, Id); + } + } + + return result.CastOrToReadOnlyCollection(); + } +} diff --git a/src/NetEvolve.Extensions.XUnit.V3/Internal/CultureAttributeBase.cs b/src/NetEvolve.Extensions.XUnit.V3/Internal/CultureAttributeBase.cs new file mode 100644 index 0000000..968eb3d --- /dev/null +++ b/src/NetEvolve.Extensions.XUnit.V3/Internal/CultureAttributeBase.cs @@ -0,0 +1,87 @@ +namespace NetEvolve.Extensions.XUnit.V3.Internal; + +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Reflection; +using System.Threading.Tasks; +using Xunit.v3; + +/// +/// Abstract class implementation of . +/// Provides basic functionality for culture-based testing. +/// +[AttributeUsage( + AttributeTargets.Class | AttributeTargets.Method, + AllowMultiple = true, + Inherited = true +)] +//[TraitDiscoverer(Namespaces.CultureTraitDiscoverer, Namespaces.Assembly)] +#pragma warning disable S3376 // Attribute, EventArgs, and Exception type names should end with the type being extended +#pragma warning disable CA1710 // Identifiers should have correct suffix +public abstract class CultureAttributeBase : Attribute, IBeforeAfterTestAttribute, ITraitAttribute +#pragma warning restore CA1710 // Identifiers should have correct suffix +#pragma warning restore S3376 // Attribute, EventArgs, and Exception type names should end with the type being extended +{ + private readonly CultureInfo _culture; + + private CultureInfo? _originalCulture; + private bool _changed; + + /// + /// Category + /// + public string Category { get; } + + /// + /// Culture + /// + public string Culture { get; } + + /// + protected CultureAttributeBase(string category, string culture) + { + Category = category; + Culture = culture; + _culture = CreateCultureInfo(culture); + } + + /// + public virtual ValueTask After(MethodInfo methodUnderTest, IXunitTest test) + { + if (_changed) + { + _ = SetCulture(_originalCulture!); + } + + return new ValueTask(); + } + + /// + public virtual ValueTask Before(MethodInfo methodUnderTest, IXunitTest test) + { + _originalCulture = CultureInfo.CurrentCulture; + + _changed = SetCulture(_culture); + + return new ValueTask(); + } + + private protected static CultureInfo CreateCultureInfo(string culture) => + new CultureInfo(culture, false); + + private protected virtual bool SetCulture(CultureInfo culture) + { + if (CultureInfo.CurrentCulture != culture) + { + CultureInfo.CurrentCulture = culture; + CultureInfo.DefaultThreadCurrentCulture = culture; + return true; + } + + return false; + } + + /// + public abstract IReadOnlyCollection> GetTraits(); +} diff --git a/src/NetEvolve.Extensions.XUnit.V3/Internals.cs b/src/NetEvolve.Extensions.XUnit.V3/Internals.cs new file mode 100644 index 0000000..5d2d3d7 --- /dev/null +++ b/src/NetEvolve.Extensions.XUnit.V3/Internals.cs @@ -0,0 +1,112 @@ +namespace NetEvolve.Extensions.XUnit.V3; + +/// +/// All internal names +/// +internal static class Internals +{ + /// + /// Id-Property + /// + public const string Id = nameof(Id); + + /// + /// Culture + /// + public const string Culture = nameof(Culture); + + /// + /// UI Culture + /// + public const string UICulture = nameof(UICulture); + + /// + /// Test Category + /// + public const string Category = nameof(Category); + + /// + /// Test Category + /// + public const string TestCategory = nameof(TestCategory); + + /// + /// Bugs + /// + public const string Bug = nameof(Bug); + + /// + /// Epics + /// + public const string Epic = nameof(Epic); + + /// + /// Features + /// + public const string Feature = nameof(Feature); + + /// + /// Issues + /// + public const string Issue = nameof(Issue); + + /// + /// PostDeployments + /// + public const string PostDeployment = nameof(PostDeployment); + + /// + /// PreDeployments + /// + public const string PreDeployment = nameof(PreDeployment); + + /// + /// UnitTests + /// + public const string UnitTest = nameof(UnitTest); + + /// + /// UserStories + /// + public const string UserStory = nameof(UserStory); + + /// + /// WorkItems + /// + public const string WorkItem = nameof(WorkItem); + + /// + /// AcceptanceTests + /// + public const string AcceptanceTest = nameof(AcceptanceTest); + + /// + /// FunctionalTests + /// + public const string FunctionalTest = nameof(FunctionalTest); + + /// + /// IntegrationTests + /// + public const string IntegrationTest = nameof(IntegrationTest); + + /// + /// EndToEndTests + /// + public const string EndToEndTest = nameof(EndToEndTest); + + /// + /// IntegrationTests + /// + public const string PerformanceTest = nameof(PerformanceTest); + + /// + /// ArchitectureTest + /// + public const string ArchitectureTest = nameof(ArchitectureTest); + + /// + /// CodedUITest + /// + public const string CodedUITest = nameof(CodedUITest); +} diff --git a/src/NetEvolve.Extensions.XUnit.V3/IssueAttribute.cs b/src/NetEvolve.Extensions.XUnit.V3/IssueAttribute.cs new file mode 100644 index 0000000..2960130 --- /dev/null +++ b/src/NetEvolve.Extensions.XUnit.V3/IssueAttribute.cs @@ -0,0 +1,31 @@ +namespace NetEvolve.Extensions.XUnit.V3; + +using System; +using NetEvolve.Extensions.XUnit.V3.Internal; + +/// +/// Attribute used to decorate a test class or method as Issue, with optional Id +/// +[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)] +public sealed class IssueAttribute : CategoryWithIdTraitBaseAttribute +{ + /// + /// Initializes a new instance of the class. + /// + public IssueAttribute() + : base(Internals.Issue, null) { } + + /// + /// Initializes a new instance of the class. + /// + /// Issue Id + public IssueAttribute(string? id) + : base(Internals.Issue, id) { } + + /// + /// Initializes a new instance of the class. + /// + /// Issue Id + public IssueAttribute(long id) + : base(Internals.Issue, id) { } +} diff --git a/src/NetEvolve.Extensions.XUnit.V3/NetEvolve.Extensions.XUnit.V3.csproj b/src/NetEvolve.Extensions.XUnit.V3/NetEvolve.Extensions.XUnit.V3.csproj new file mode 100644 index 0000000..37c262b --- /dev/null +++ b/src/NetEvolve.Extensions.XUnit.V3/NetEvolve.Extensions.XUnit.V3.csproj @@ -0,0 +1,14 @@ + + + + netstandard2.0;net6.0 + + $(NoWarn);NU5104 + $(NoWarn);nullable + + + + + + + diff --git a/src/NetEvolve.Extensions.XUnit.V3/PerformanceTestAttribute.cs b/src/NetEvolve.Extensions.XUnit.V3/PerformanceTestAttribute.cs new file mode 100644 index 0000000..5020744 --- /dev/null +++ b/src/NetEvolve.Extensions.XUnit.V3/PerformanceTestAttribute.cs @@ -0,0 +1,20 @@ +namespace NetEvolve.Extensions.XUnit.V3; + +using System; +using NetEvolve.Extensions.XUnit.V3.Internal; + +/// +/// Attribute used to decorate a test class or method as PerformanceTest. +/// +[AttributeUsage( + AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method, + AllowMultiple = true +)] +public sealed class PerformanceTestAttribute : CategoryTraitBaseAttribute +{ + /// + /// Initializes a new instance of the class. + /// + public PerformanceTestAttribute() + : base(Internals.PerformanceTest) { } +} diff --git a/src/NetEvolve.Extensions.XUnit.V3/PostDeploymentAttribute.cs b/src/NetEvolve.Extensions.XUnit.V3/PostDeploymentAttribute.cs new file mode 100644 index 0000000..94a9cd3 --- /dev/null +++ b/src/NetEvolve.Extensions.XUnit.V3/PostDeploymentAttribute.cs @@ -0,0 +1,20 @@ +namespace NetEvolve.Extensions.XUnit.V3; + +using System; +using NetEvolve.Extensions.XUnit.V3.Internal; + +/// +/// Attribute used to decorate a test class or method with TestCategory PostDeployment. +/// +[AttributeUsage( + AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method, + AllowMultiple = true +)] +public sealed class PostDeploymentAttribute : CategoryTraitBaseAttribute +{ + /// + /// Initializes a new instance of the class. + /// + public PostDeploymentAttribute() + : base(Internals.PostDeployment) { } +} diff --git a/src/NetEvolve.Extensions.XUnit.V3/PreDeploymentAttribute.cs b/src/NetEvolve.Extensions.XUnit.V3/PreDeploymentAttribute.cs new file mode 100644 index 0000000..a35e406 --- /dev/null +++ b/src/NetEvolve.Extensions.XUnit.V3/PreDeploymentAttribute.cs @@ -0,0 +1,20 @@ +namespace NetEvolve.Extensions.XUnit.V3; + +using System; +using NetEvolve.Extensions.XUnit.V3.Internal; + +/// +/// Attribute used to decorate a test class or method with TestCategory PreDeployment. +/// +[AttributeUsage( + AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method, + AllowMultiple = true +)] +public sealed class PreDeploymentAttribute : CategoryTraitBaseAttribute +{ + /// + /// Initializes a new instance of the class. + /// + public PreDeploymentAttribute() + : base(Internals.PreDeployment) { } +} diff --git a/src/NetEvolve.Extensions.XUnit.V3/README.md b/src/NetEvolve.Extensions.XUnit.V3/README.md new file mode 100644 index 0000000..0c254e3 --- /dev/null +++ b/src/NetEvolve.Extensions.XUnit.V3/README.md @@ -0,0 +1,48 @@ +# NetEvolve.Extensions.XUnit.V3 + +Compatibility library for solutions using multiple .NET test frameworks. +The following test frameworks are supported +- [MSTest](https://www.nuget.org/packages/NetEvolve.Extensions.MSTest), +- [NUnit](https://www.nuget.org/packages/NetEvolve.Extensions.NUnit) +- [XUnit](https://www.nuget.org/packages/NetEvolve.Extensions.XUnit) +- [XUnit.V3](https://www.nuget.org/packages/NetEvolve.Extensions.XUnit.V3) + +## Basic functionality + +For consistent usage and addressing of use cases like +`dotnet test -c Release --filter TestCategory=IntegrationTest`, +the following attributes are provided in this library in the namespace `NetEvolve.Extensions.XUnit`. + +- `AcceptanceTestAttribute` +- `ArchitectureTestAttribute` +- `BugAttribute` +- `EndToEndTestAttribute` +- `EpicAttribute` +- `FeatureAttribute` +- `FunctionalTestAttribute` +- `IntegrationTestAttribute` +- `IssueAttribute` +- `PerformanceTestAttribute` +- `PostDeploymentTestAttribute` +- `PreDeploymentTestAttribute` +- `UnitTestAttribute` +- `UserStoryAttribute` +- `WorkItemAttribute` + +### Applying +These can be applied on assembly, class or method definitions as follows. + +```cs +[assembly: AcceptanceTest] // Mark all test methods of this assembly as AcceptanceTest + +[AcceptanceTest] // Mark all test methods of this class as AcceptanceTest +public partial class FantasticTest +{ + [Fact] + [AcceptanceTest] // Alternatively, only one method can be selected. + public void I_am_Ironman() + { + Assert.Fail(); + } +} +``` \ No newline at end of file diff --git a/src/NetEvolve.Extensions.XUnit.V3/SetCultureAttribute.cs b/src/NetEvolve.Extensions.XUnit.V3/SetCultureAttribute.cs new file mode 100644 index 0000000..60615ec --- /dev/null +++ b/src/NetEvolve.Extensions.XUnit.V3/SetCultureAttribute.cs @@ -0,0 +1,100 @@ +namespace NetEvolve.Extensions.XUnit.V3; + +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Reflection; +using System.Threading.Tasks; +using NetEvolve.Extensions.XUnit.V3.Internal; +using Xunit.Internal; +using Xunit.v3; + +/// +/// Based on the value passed as culture, the marked test is executed. +/// +[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = false)] +public sealed class SetCultureAttribute : CultureAttributeBase +{ + private readonly CultureInfo _uiCulture; + private CultureInfo? _originalUICulture; + private bool _changed; + + /// + /// UI culture + /// + public string? UICulture { get; } + + /// + /// Initializes a new instance of the class. + /// + public SetCultureAttribute() + : this(string.Empty, string.Empty) { } + + /// + /// Initializes a new instance of the class. + /// + /// Culture to use. + public SetCultureAttribute(string culture) + : this(culture, culture) { } + + /// + /// Initializes a new instance of the class. + /// + /// Culture to use. + /// UI culture to use. + public SetCultureAttribute(string culture, string? uiCulture) + : base("SetCulture", culture) + { + if (string.IsNullOrWhiteSpace(uiCulture)) + { + uiCulture = string.Empty; + } + + _uiCulture = CreateCultureInfo(uiCulture!); + } + + /// + public override async ValueTask After(MethodInfo methodUnderTest, IXunitTest test) + { + await base.After(methodUnderTest, test).ConfigureAwait(false); + + if (_changed) + { + _ = SetUICulture(_originalUICulture!); + } + } + + /// + public override async ValueTask Before(MethodInfo methodUnderTest, IXunitTest test) + { + await base.Before(methodUnderTest, test).ConfigureAwait(false); + + _originalUICulture = CultureInfo.CurrentUICulture; + _changed = SetUICulture(_uiCulture); + } + + private static bool SetUICulture(CultureInfo culture) + { + if (CultureInfo.CurrentUICulture != culture) + { + CultureInfo.CurrentUICulture = culture; + CultureInfo.DefaultThreadCurrentUICulture = culture; + + return true; + } + + return false; + } + + /// + public override IReadOnlyCollection> GetTraits() + { + var result = new Dictionary(StringComparer.OrdinalIgnoreCase) + { + { "SetCulture", Culture }, + { "SetUICulture", Culture }, + }; + + return result.CastOrToReadOnlyList(); + } +} diff --git a/src/NetEvolve.Extensions.XUnit.V3/SetUICultureAttribute.cs b/src/NetEvolve.Extensions.XUnit.V3/SetUICultureAttribute.cs new file mode 100644 index 0000000..9948dc3 --- /dev/null +++ b/src/NetEvolve.Extensions.XUnit.V3/SetUICultureAttribute.cs @@ -0,0 +1,50 @@ +namespace NetEvolve.Extensions.XUnit.V3; + +using System; +using System.Collections.Generic; +using System.Globalization; +using NetEvolve.Extensions.XUnit.V3.Internal; +using Xunit.Internal; + +/// +/// Based on the value passed as UI culture, the marked test is executed. +/// +[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = false)] +public sealed class SetUICultureAttribute : CultureAttributeBase +{ + /// + /// Initializes a new instance of the class. + /// + public SetUICultureAttribute() + : base("SetUICulture", string.Empty) { } + + /// + /// Initializes a new instance of the class. + /// + /// UI culture to use. + public SetUICultureAttribute(string culture) + : base("SetUICulture", culture) { } + + private protected override bool SetCulture(CultureInfo culture) + { + if (CultureInfo.CurrentUICulture != culture) + { + CultureInfo.CurrentUICulture = culture; + CultureInfo.DefaultThreadCurrentUICulture = culture; + return true; + } + + return false; + } + + /// + public override IReadOnlyCollection> GetTraits() + { + var result = new Dictionary(StringComparer.OrdinalIgnoreCase) + { + { "SetUICulture", Culture }, + }; + + return result.CastOrToReadOnlyList(); + } +} diff --git a/src/NetEvolve.Extensions.XUnit.V3/UnitTestAttribute.cs b/src/NetEvolve.Extensions.XUnit.V3/UnitTestAttribute.cs new file mode 100644 index 0000000..02b6fb2 --- /dev/null +++ b/src/NetEvolve.Extensions.XUnit.V3/UnitTestAttribute.cs @@ -0,0 +1,20 @@ +namespace NetEvolve.Extensions.XUnit.V3; + +using System; +using NetEvolve.Extensions.XUnit.V3.Internal; + +/// +/// Attribute used to decorate a test class or method as UnitTest. +/// +[AttributeUsage( + AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method, + AllowMultiple = true +)] +public sealed class UnitTestAttribute : CategoryTraitBaseAttribute +{ + /// + /// Initializes a new instance of the class. + /// + public UnitTestAttribute() + : base(Internals.UnitTest) { } +} diff --git a/src/NetEvolve.Extensions.XUnit.V3/UserStoryAttribute.cs b/src/NetEvolve.Extensions.XUnit.V3/UserStoryAttribute.cs new file mode 100644 index 0000000..6083857 --- /dev/null +++ b/src/NetEvolve.Extensions.XUnit.V3/UserStoryAttribute.cs @@ -0,0 +1,31 @@ +namespace NetEvolve.Extensions.XUnit.V3; + +using System; +using NetEvolve.Extensions.XUnit.V3.Internal; + +/// +/// Attribute used to decorate a test class or method as UserStory, with optional Id +/// +[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)] +public sealed class UserStoryAttribute : CategoryWithIdTraitBaseAttribute +{ + /// + /// Initializes a new instance of the class. + /// + public UserStoryAttribute() + : base(Internals.UserStory, null) { } + + /// + /// Initializes a new instance of the class. + /// + /// UserStory Id + public UserStoryAttribute(string? id) + : base(Internals.UserStory, id) { } + + /// + /// Initializes a new instance of the class. + /// + /// UserStory Id + public UserStoryAttribute(long id) + : base(Internals.UserStory, id) { } +} diff --git a/src/NetEvolve.Extensions.XUnit.V3/WorkItemAttribute.cs b/src/NetEvolve.Extensions.XUnit.V3/WorkItemAttribute.cs new file mode 100644 index 0000000..ab2ace7 --- /dev/null +++ b/src/NetEvolve.Extensions.XUnit.V3/WorkItemAttribute.cs @@ -0,0 +1,31 @@ +namespace NetEvolve.Extensions.XUnit.V3; + +using System; +using NetEvolve.Extensions.XUnit.V3.Internal; + +/// +/// Attribute used to decorate a test class or method as WorkItem, with optional Id +/// +[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)] +public sealed class WorkItemAttribute : CategoryWithIdTraitBaseAttribute +{ + /// + /// Initializes a new instance of the class. + /// + public WorkItemAttribute() + : base(Internals.WorkItem, null) { } + + /// + /// Initializes a new instance of the class. + /// + /// WorkItem Id + public WorkItemAttribute(string? id) + : base(Internals.WorkItem, id) { } + + /// + /// Initializes a new instance of the class. + /// + /// WorkItem Id + public WorkItemAttribute(long id) + : base(Internals.WorkItem, id) { } +} diff --git a/src/NetEvolve.Extensions.XUnit/AcceptanceTestAttribute.cs b/src/NetEvolve.Extensions.XUnit/AcceptanceTestAttribute.cs index 1190a19..3450e5c 100644 --- a/src/NetEvolve.Extensions.XUnit/AcceptanceTestAttribute.cs +++ b/src/NetEvolve.Extensions.XUnit/AcceptanceTestAttribute.cs @@ -1,10 +1,15 @@ namespace NetEvolve.Extensions.XUnit; +using System; using NetEvolve.Extensions.XUnit.Internal; /// /// Attribute used to decorate a test class or method as AcceptanceTest. /// +[AttributeUsage( + AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method, + AllowMultiple = true +)] public sealed class AcceptanceTestAttribute : CategoryTraitBaseAttribute { /// diff --git a/src/NetEvolve.Extensions.XUnit/ArchitectureTestAttribute.cs b/src/NetEvolve.Extensions.XUnit/ArchitectureTestAttribute.cs index 6c8754b..41c7420 100644 --- a/src/NetEvolve.Extensions.XUnit/ArchitectureTestAttribute.cs +++ b/src/NetEvolve.Extensions.XUnit/ArchitectureTestAttribute.cs @@ -1,10 +1,15 @@ namespace NetEvolve.Extensions.XUnit; +using System; using NetEvolve.Extensions.XUnit.Internal; /// /// Attribute used to decorate a test class or method as ArchitectureTest. /// +[AttributeUsage( + AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method, + AllowMultiple = true +)] public sealed class ArchitectureTestAttribute : CategoryTraitBaseAttribute { /// diff --git a/src/NetEvolve.Extensions.XUnit/CodedUITestAttribute.cs b/src/NetEvolve.Extensions.XUnit/CodedUITestAttribute.cs index 63ac6f1..286d8c8 100644 --- a/src/NetEvolve.Extensions.XUnit/CodedUITestAttribute.cs +++ b/src/NetEvolve.Extensions.XUnit/CodedUITestAttribute.cs @@ -1,10 +1,15 @@ namespace NetEvolve.Extensions.XUnit; +using System; using NetEvolve.Extensions.XUnit.Internal; /// /// Attribute used to decorate a test class or method as CodedUITest. /// +[AttributeUsage( + AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method, + AllowMultiple = true +)] public sealed class CodedUITestAttribute : CategoryTraitBaseAttribute { /// diff --git a/src/NetEvolve.Extensions.XUnit/EndToEndTestAttribute.cs b/src/NetEvolve.Extensions.XUnit/EndToEndTestAttribute.cs index ca76a12..59b7d3f 100644 --- a/src/NetEvolve.Extensions.XUnit/EndToEndTestAttribute.cs +++ b/src/NetEvolve.Extensions.XUnit/EndToEndTestAttribute.cs @@ -1,10 +1,15 @@ namespace NetEvolve.Extensions.XUnit; +using System; using NetEvolve.Extensions.XUnit.Internal; /// /// Attribute used to decorate a test class or method as EndToEndTest. /// +[AttributeUsage( + AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method, + AllowMultiple = true +)] public sealed class EndToEndTestAttribute : CategoryTraitBaseAttribute { /// diff --git a/src/NetEvolve.Extensions.XUnit/EpicAttribute.cs b/src/NetEvolve.Extensions.XUnit/EpicAttribute.cs index 5e65fd2..98d35ff 100644 --- a/src/NetEvolve.Extensions.XUnit/EpicAttribute.cs +++ b/src/NetEvolve.Extensions.XUnit/EpicAttribute.cs @@ -1,10 +1,15 @@ namespace NetEvolve.Extensions.XUnit; +using System; using NetEvolve.Extensions.XUnit.Internal; /// /// Attribute used to decorate a test class or method as Epic, with optional Id /// +[AttributeUsage( + AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method, + AllowMultiple = true +)] public sealed class EpicAttribute : CategoryWithIdTraitBaseAttribute { /// diff --git a/src/NetEvolve.Extensions.XUnit/FeatureAttribute.cs b/src/NetEvolve.Extensions.XUnit/FeatureAttribute.cs index 70f6081..b52c887 100644 --- a/src/NetEvolve.Extensions.XUnit/FeatureAttribute.cs +++ b/src/NetEvolve.Extensions.XUnit/FeatureAttribute.cs @@ -1,10 +1,15 @@ namespace NetEvolve.Extensions.XUnit; +using System; using NetEvolve.Extensions.XUnit.Internal; /// /// Attribute used to decorate a test class or method as Feature, with optional Id /// +[AttributeUsage( + AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method, + AllowMultiple = true +)] public sealed class FeatureAttribute : CategoryWithIdTraitBaseAttribute { /// diff --git a/src/NetEvolve.Extensions.XUnit/FunctionalTestAttribute.cs b/src/NetEvolve.Extensions.XUnit/FunctionalTestAttribute.cs index cf59f90..8eaa7a6 100644 --- a/src/NetEvolve.Extensions.XUnit/FunctionalTestAttribute.cs +++ b/src/NetEvolve.Extensions.XUnit/FunctionalTestAttribute.cs @@ -1,10 +1,15 @@ namespace NetEvolve.Extensions.XUnit; +using System; using NetEvolve.Extensions.XUnit.Internal; /// /// Attribute used to decorate a test class or method as FunctionalTest. /// +[AttributeUsage( + AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method, + AllowMultiple = true +)] public sealed class FunctionalTestAttribute : CategoryTraitBaseAttribute { /// diff --git a/src/NetEvolve.Extensions.XUnit/IntegrationTestAttribute.cs b/src/NetEvolve.Extensions.XUnit/IntegrationTestAttribute.cs index a4b727a..ec20cc8 100644 --- a/src/NetEvolve.Extensions.XUnit/IntegrationTestAttribute.cs +++ b/src/NetEvolve.Extensions.XUnit/IntegrationTestAttribute.cs @@ -1,10 +1,15 @@ namespace NetEvolve.Extensions.XUnit; +using System; using NetEvolve.Extensions.XUnit.Internal; /// /// Attribute used to decorate a test class or method as IntegrationTest. /// +[AttributeUsage( + AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method, + AllowMultiple = true +)] public sealed class IntegrationTestAttribute : CategoryTraitBaseAttribute { /// diff --git a/src/NetEvolve.Extensions.XUnit/Internal/CategoryTraitBaseAttribute.cs b/src/NetEvolve.Extensions.XUnit/Internal/CategoryTraitBaseAttribute.cs index f586aed..e0350cc 100644 --- a/src/NetEvolve.Extensions.XUnit/Internal/CategoryTraitBaseAttribute.cs +++ b/src/NetEvolve.Extensions.XUnit/Internal/CategoryTraitBaseAttribute.cs @@ -9,11 +9,6 @@ /// Abstract class implementation of . /// Provides property . /// -[AttributeUsage( - AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method, - AllowMultiple = true, - Inherited = true -)] [TraitDiscoverer(Namespaces.CategoryTraitDiscoverer, Namespaces.Assembly)] [SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "As designed.")] public abstract class CategoryTraitBaseAttribute : Attribute, ITraitAttribute diff --git a/src/NetEvolve.Extensions.XUnit/Internal/CategoryWithIdTraitBaseAttribute.cs b/src/NetEvolve.Extensions.XUnit/Internal/CategoryWithIdTraitBaseAttribute.cs index 23ab439..99de57f 100644 --- a/src/NetEvolve.Extensions.XUnit/Internal/CategoryWithIdTraitBaseAttribute.cs +++ b/src/NetEvolve.Extensions.XUnit/Internal/CategoryWithIdTraitBaseAttribute.cs @@ -21,11 +21,6 @@ /// /// /// -[AttributeUsage( - AttributeTargets.Class | AttributeTargets.Method, - AllowMultiple = true, - Inherited = true -)] [TraitDiscoverer(Namespaces.CategoryTraitDiscoverer, Namespaces.Assembly)] [SuppressMessage("Style", "IDE1006:Naming Styles", Justification = "As designed.")] public abstract class CategoryWithIdTraitBaseAttribute : Attribute, ITraitAttribute diff --git a/src/NetEvolve.Extensions.XUnit/IssueAttribute.cs b/src/NetEvolve.Extensions.XUnit/IssueAttribute.cs index cc1c4cd..bfeaf23 100644 --- a/src/NetEvolve.Extensions.XUnit/IssueAttribute.cs +++ b/src/NetEvolve.Extensions.XUnit/IssueAttribute.cs @@ -1,10 +1,15 @@ namespace NetEvolve.Extensions.XUnit; +using System; using NetEvolve.Extensions.XUnit.Internal; /// /// Attribute used to decorate a test class or method as Issue, with optional Id /// +[AttributeUsage( + AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method, + AllowMultiple = true +)] public sealed class IssueAttribute : CategoryWithIdTraitBaseAttribute { /// diff --git a/src/NetEvolve.Extensions.XUnit/PerformanceTestAttribute.cs b/src/NetEvolve.Extensions.XUnit/PerformanceTestAttribute.cs index 9ed02fb..accaa0a 100644 --- a/src/NetEvolve.Extensions.XUnit/PerformanceTestAttribute.cs +++ b/src/NetEvolve.Extensions.XUnit/PerformanceTestAttribute.cs @@ -1,10 +1,15 @@ namespace NetEvolve.Extensions.XUnit; +using System; using NetEvolve.Extensions.XUnit.Internal; /// /// Attribute used to decorate a test class or method as PerformanceTest. /// +[AttributeUsage( + AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method, + AllowMultiple = true +)] public sealed class PerformanceTestAttribute : CategoryTraitBaseAttribute { /// diff --git a/src/NetEvolve.Extensions.XUnit/PostDeploymentAttribute.cs b/src/NetEvolve.Extensions.XUnit/PostDeploymentAttribute.cs index 7f69ad7..350ed4a 100644 --- a/src/NetEvolve.Extensions.XUnit/PostDeploymentAttribute.cs +++ b/src/NetEvolve.Extensions.XUnit/PostDeploymentAttribute.cs @@ -1,10 +1,15 @@ namespace NetEvolve.Extensions.XUnit; +using System; using NetEvolve.Extensions.XUnit.Internal; /// /// Attribute used to decorate a test class or method with TestCategory PostDeployment. /// +[AttributeUsage( + AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method, + AllowMultiple = true +)] public sealed class PostDeploymentAttribute : CategoryTraitBaseAttribute { /// diff --git a/src/NetEvolve.Extensions.XUnit/PreDeploymentAttribute.cs b/src/NetEvolve.Extensions.XUnit/PreDeploymentAttribute.cs index 6d55f66..06765eb 100644 --- a/src/NetEvolve.Extensions.XUnit/PreDeploymentAttribute.cs +++ b/src/NetEvolve.Extensions.XUnit/PreDeploymentAttribute.cs @@ -1,10 +1,15 @@ namespace NetEvolve.Extensions.XUnit; +using System; using NetEvolve.Extensions.XUnit.Internal; /// /// Attribute used to decorate a test class or method with TestCategory PreDeployment. /// +[AttributeUsage( + AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method, + AllowMultiple = true +)] public sealed class PreDeploymentAttribute : CategoryTraitBaseAttribute { /// diff --git a/src/NetEvolve.Extensions.XUnit/README.md b/src/NetEvolve.Extensions.XUnit/README.md index b3e3009..8bddfcf 100644 --- a/src/NetEvolve.Extensions.XUnit/README.md +++ b/src/NetEvolve.Extensions.XUnit/README.md @@ -1,10 +1,11 @@ # NetEvolve.Extensions.XUnit Compatibility library for solutions using multiple .NET test frameworks. -The following test frameworks are supported - -[MSTest](https://www.nuget.org/packages/NetEvolve.Extensions.MSTest), -[NUnit](https://www.nuget.org/packages/NetEvolve.Extensions.NUnit) & -[XUnit](https://www.nuget.org/packages/NetEvolve.Extensions.XUnit). +The following test frameworks are supported +- [MSTest](https://www.nuget.org/packages/NetEvolve.Extensions.MSTest), +- [NUnit](https://www.nuget.org/packages/NetEvolve.Extensions.NUnit) +- [XUnit](https://www.nuget.org/packages/NetEvolve.Extensions.XUnit) +- [XUnit.V3](https://www.nuget.org/packages/NetEvolve.Extensions.XUnit.V3) ## Basic functionality diff --git a/src/NetEvolve.Extensions.XUnit/UnitTestAttribute.cs b/src/NetEvolve.Extensions.XUnit/UnitTestAttribute.cs index f562e82..7032448 100644 --- a/src/NetEvolve.Extensions.XUnit/UnitTestAttribute.cs +++ b/src/NetEvolve.Extensions.XUnit/UnitTestAttribute.cs @@ -1,10 +1,15 @@ namespace NetEvolve.Extensions.XUnit; +using System; using NetEvolve.Extensions.XUnit.Internal; /// /// Attribute used to decorate a test class or method as UnitTest. /// +[AttributeUsage( + AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method, + AllowMultiple = true +)] public sealed class UnitTestAttribute : CategoryTraitBaseAttribute { /// diff --git a/src/NetEvolve.Extensions.XUnit/UserStoryAttribute.cs b/src/NetEvolve.Extensions.XUnit/UserStoryAttribute.cs index d242e19..779c5d3 100644 --- a/src/NetEvolve.Extensions.XUnit/UserStoryAttribute.cs +++ b/src/NetEvolve.Extensions.XUnit/UserStoryAttribute.cs @@ -1,10 +1,15 @@ namespace NetEvolve.Extensions.XUnit; +using System; using NetEvolve.Extensions.XUnit.Internal; /// /// Attribute used to decorate a test class or method as UserStory, with optional Id /// +[AttributeUsage( + AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method, + AllowMultiple = true +)] public sealed class UserStoryAttribute : CategoryWithIdTraitBaseAttribute { /// diff --git a/src/NetEvolve.Extensions.XUnit/WorkItemAttribute.cs b/src/NetEvolve.Extensions.XUnit/WorkItemAttribute.cs index b74747a..6b8479a 100644 --- a/src/NetEvolve.Extensions.XUnit/WorkItemAttribute.cs +++ b/src/NetEvolve.Extensions.XUnit/WorkItemAttribute.cs @@ -1,10 +1,15 @@ namespace NetEvolve.Extensions.XUnit; +using System; using NetEvolve.Extensions.XUnit.Internal; /// /// Attribute used to decorate a test class or method as WorkItem, with optional Id /// +[AttributeUsage( + AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Method, + AllowMultiple = true +)] public sealed class WorkItemAttribute : CategoryWithIdTraitBaseAttribute { /// diff --git a/tests/NetEvolve.Extensions.MSTest.Tests.PublicApi/Predefined.cs b/tests/NetEvolve.Extensions.MSTest.Tests.PublicApi/Predefined.cs index 4abac83..30eb4ef 100644 --- a/tests/NetEvolve.Extensions.MSTest.Tests.PublicApi/Predefined.cs +++ b/tests/NetEvolve.Extensions.MSTest.Tests.PublicApi/Predefined.cs @@ -23,7 +23,7 @@ public static void Init() } ); - VerifierSettings.AutoVerify(includeBuildServer: false); VerifierSettings.SortPropertiesAlphabetically(); + VerifierSettings.SortJsonObjects(); } } diff --git a/tests/NetEvolve.Extensions.MSTest.Tests.PublicApi/PublicApiTests.cs b/tests/NetEvolve.Extensions.MSTest.Tests.PublicApi/PublicApiTests.cs index d26f608..d32262d 100644 --- a/tests/NetEvolve.Extensions.MSTest.Tests.PublicApi/PublicApiTests.cs +++ b/tests/NetEvolve.Extensions.MSTest.Tests.PublicApi/PublicApiTests.cs @@ -29,6 +29,7 @@ public Task PublicApi_HasNotChanged_Expected() typeof(CLSCompliantAttribute).FullName!, typeof(AssemblyMetadataAttribute).FullName!, typeof(NeutralResourcesLanguageAttribute).FullName!, + typeof(AttributeUsageAttribute).FullName!, ], IncludeTypes = types, }; diff --git a/tests/NetEvolve.Extensions.MSTest.Tests.PublicApi/_snapshots/DotNet6_0/PublicApiTests.PublicApi_HasNotChanged_Expected.verified.txt b/tests/NetEvolve.Extensions.MSTest.Tests.PublicApi/_snapshots/DotNet6_0/PublicApiTests.PublicApi_HasNotChanged_Expected.verified.txt index ea74e0f..b605413 100644 --- a/tests/NetEvolve.Extensions.MSTest.Tests.PublicApi/_snapshots/DotNet6_0/PublicApiTests.PublicApi_HasNotChanged_Expected.verified.txt +++ b/tests/NetEvolve.Extensions.MSTest.Tests.PublicApi/_snapshots/DotNet6_0/PublicApiTests.PublicApi_HasNotChanged_Expected.verified.txt @@ -8,7 +8,6 @@ { public ArchitectureTestAttribute() { } } - [System.AttributeUsage(System.AttributeTargets.Class | System.AttributeTargets.Method, AllowMultiple=true)] public sealed class BugAttribute : NetEvolve.Extensions.MSTest.Internal.TestCategoryWithIdBaseAttribute { public BugAttribute() { } @@ -23,14 +22,12 @@ { public EndToEndTestAttribute() { } } - [System.AttributeUsage(System.AttributeTargets.Class | System.AttributeTargets.Method, AllowMultiple=true)] public sealed class EpicAttribute : NetEvolve.Extensions.MSTest.Internal.TestCategoryWithIdBaseAttribute { public EpicAttribute() { } public EpicAttribute(long id) { } public EpicAttribute(string? id) { } } - [System.AttributeUsage(System.AttributeTargets.Class | System.AttributeTargets.Method, AllowMultiple=true)] public sealed class FeatureAttribute : NetEvolve.Extensions.MSTest.Internal.TestCategoryWithIdBaseAttribute { public FeatureAttribute() { } @@ -45,7 +42,6 @@ { public IntegrationTestAttribute() { } } - [System.AttributeUsage(System.AttributeTargets.Class | System.AttributeTargets.Method, AllowMultiple=true)] public sealed class IssueAttribute : NetEvolve.Extensions.MSTest.Internal.TestCategoryWithIdBaseAttribute { public IssueAttribute() { } @@ -68,14 +64,12 @@ { public UnitTestAttribute() { } } - [System.AttributeUsage(System.AttributeTargets.Class | System.AttributeTargets.Method, AllowMultiple=true)] public sealed class UserStoryAttribute : NetEvolve.Extensions.MSTest.Internal.TestCategoryWithIdBaseAttribute { public UserStoryAttribute() { } public UserStoryAttribute(long id) { } public UserStoryAttribute(string? id) { } } - [System.AttributeUsage(System.AttributeTargets.Class | System.AttributeTargets.Method, AllowMultiple=true)] public sealed class WorkItemAttribute : NetEvolve.Extensions.MSTest.Internal.TestCategoryWithIdBaseAttribute { public WorkItemAttribute() { } @@ -90,7 +84,6 @@ namespace NetEvolve.Extensions.MSTest.Internal protected TestCategoryWithIdBaseAttribute(string categoryName, string? id = null) { } public string? Id { get; } } - [System.AttributeUsage(System.AttributeTargets.Assembly | System.AttributeTargets.Class | System.AttributeTargets.Method, AllowMultiple=true, Inherited=true)] public abstract class TestTraitBaseAttribute : Microsoft.VisualStudio.TestTools.UnitTesting.TestCategoryBaseAttribute { protected TestTraitBaseAttribute(string categoryName) { } diff --git a/tests/NetEvolve.Extensions.MSTest.Tests.PublicApi/_snapshots/DotNet8_0/PublicApiTests.PublicApi_HasNotChanged_Expected.verified.txt b/tests/NetEvolve.Extensions.MSTest.Tests.PublicApi/_snapshots/DotNet8_0/PublicApiTests.PublicApi_HasNotChanged_Expected.verified.txt index ea74e0f..b605413 100644 --- a/tests/NetEvolve.Extensions.MSTest.Tests.PublicApi/_snapshots/DotNet8_0/PublicApiTests.PublicApi_HasNotChanged_Expected.verified.txt +++ b/tests/NetEvolve.Extensions.MSTest.Tests.PublicApi/_snapshots/DotNet8_0/PublicApiTests.PublicApi_HasNotChanged_Expected.verified.txt @@ -8,7 +8,6 @@ { public ArchitectureTestAttribute() { } } - [System.AttributeUsage(System.AttributeTargets.Class | System.AttributeTargets.Method, AllowMultiple=true)] public sealed class BugAttribute : NetEvolve.Extensions.MSTest.Internal.TestCategoryWithIdBaseAttribute { public BugAttribute() { } @@ -23,14 +22,12 @@ { public EndToEndTestAttribute() { } } - [System.AttributeUsage(System.AttributeTargets.Class | System.AttributeTargets.Method, AllowMultiple=true)] public sealed class EpicAttribute : NetEvolve.Extensions.MSTest.Internal.TestCategoryWithIdBaseAttribute { public EpicAttribute() { } public EpicAttribute(long id) { } public EpicAttribute(string? id) { } } - [System.AttributeUsage(System.AttributeTargets.Class | System.AttributeTargets.Method, AllowMultiple=true)] public sealed class FeatureAttribute : NetEvolve.Extensions.MSTest.Internal.TestCategoryWithIdBaseAttribute { public FeatureAttribute() { } @@ -45,7 +42,6 @@ { public IntegrationTestAttribute() { } } - [System.AttributeUsage(System.AttributeTargets.Class | System.AttributeTargets.Method, AllowMultiple=true)] public sealed class IssueAttribute : NetEvolve.Extensions.MSTest.Internal.TestCategoryWithIdBaseAttribute { public IssueAttribute() { } @@ -68,14 +64,12 @@ { public UnitTestAttribute() { } } - [System.AttributeUsage(System.AttributeTargets.Class | System.AttributeTargets.Method, AllowMultiple=true)] public sealed class UserStoryAttribute : NetEvolve.Extensions.MSTest.Internal.TestCategoryWithIdBaseAttribute { public UserStoryAttribute() { } public UserStoryAttribute(long id) { } public UserStoryAttribute(string? id) { } } - [System.AttributeUsage(System.AttributeTargets.Class | System.AttributeTargets.Method, AllowMultiple=true)] public sealed class WorkItemAttribute : NetEvolve.Extensions.MSTest.Internal.TestCategoryWithIdBaseAttribute { public WorkItemAttribute() { } @@ -90,7 +84,6 @@ namespace NetEvolve.Extensions.MSTest.Internal protected TestCategoryWithIdBaseAttribute(string categoryName, string? id = null) { } public string? Id { get; } } - [System.AttributeUsage(System.AttributeTargets.Assembly | System.AttributeTargets.Class | System.AttributeTargets.Method, AllowMultiple=true, Inherited=true)] public abstract class TestTraitBaseAttribute : Microsoft.VisualStudio.TestTools.UnitTesting.TestCategoryBaseAttribute { protected TestTraitBaseAttribute(string categoryName) { } diff --git a/tests/NetEvolve.Extensions.MSTest.Tests.Unit/AttributeTestsBase.cs b/tests/NetEvolve.Extensions.MSTest.Tests.Unit/AttributeTestsBase.cs index 26b7a05..f8099df 100644 --- a/tests/NetEvolve.Extensions.MSTest.Tests.Unit/AttributeTestsBase.cs +++ b/tests/NetEvolve.Extensions.MSTest.Tests.Unit/AttributeTestsBase.cs @@ -36,25 +36,27 @@ protected IEnumerable> GetProperties( if (methodInfo is null) { - return Enumerable.Empty>(); + return []; } var categories = GetTestCategoryBaseAttributes(methodInfo).ToArray(); if (categories.Length == 0) { - categories = categories.Concat(GetTestCategoryBaseAttributes(owningType)).ToArray(); + categories = [.. categories, .. GetTestCategoryBaseAttributes(owningType)]; } if (categories.Length == 0) { - categories = categories - .Concat(GetTestCategoryBaseAttributes(owningType.Module.Assembly)) - .ToArray(); + categories = + [ + .. categories, + .. GetTestCategoryBaseAttributes(owningType.Module.Assembly), + ]; } if (categories.Length == 0) { - return Array.Empty>(); + return []; } return categories @@ -62,7 +64,7 @@ protected IEnumerable> GetProperties( .Distinct(); } - private IEnumerable> GetTestCategoryBaseAttributes( + private static IEnumerable> GetTestCategoryBaseAttributes( Assembly assembly ) { @@ -107,7 +109,7 @@ attribute is TestCategoryWithIdBaseAttribute attributeWithId } } - private IEnumerable> GetTestCategoryBaseAttributes( + private static IEnumerable> GetTestCategoryBaseAttributes( MemberInfo? member ) { diff --git a/tests/NetEvolve.Extensions.MSTest.Tests.Unit/Predefined.cs b/tests/NetEvolve.Extensions.MSTest.Tests.Unit/Predefined.cs index 12bb3d5..d6a6808 100644 --- a/tests/NetEvolve.Extensions.MSTest.Tests.Unit/Predefined.cs +++ b/tests/NetEvolve.Extensions.MSTest.Tests.Unit/Predefined.cs @@ -24,7 +24,7 @@ public static void Init() } ); - VerifierSettings.AutoVerify(includeBuildServer: false); VerifierSettings.SortPropertiesAlphabetically(); + VerifierSettings.SortJsonObjects(); } } diff --git a/tests/NetEvolve.Extensions.NUnit.Tests.PublicApi/Predefined.cs b/tests/NetEvolve.Extensions.NUnit.Tests.PublicApi/Predefined.cs index 53c3d6d..0586666 100644 --- a/tests/NetEvolve.Extensions.NUnit.Tests.PublicApi/Predefined.cs +++ b/tests/NetEvolve.Extensions.NUnit.Tests.PublicApi/Predefined.cs @@ -23,7 +23,7 @@ public static void Init() } ); - VerifierSettings.AutoVerify(includeBuildServer: false); VerifierSettings.SortPropertiesAlphabetically(); + VerifierSettings.SortJsonObjects(); } } diff --git a/tests/NetEvolve.Extensions.NUnit.Tests.PublicApi/PublicApiTests.cs b/tests/NetEvolve.Extensions.NUnit.Tests.PublicApi/PublicApiTests.cs index 0cf339a..cd0e33b 100644 --- a/tests/NetEvolve.Extensions.NUnit.Tests.PublicApi/PublicApiTests.cs +++ b/tests/NetEvolve.Extensions.NUnit.Tests.PublicApi/PublicApiTests.cs @@ -29,6 +29,7 @@ public Task PublicApi_HasNotChanged_Expected() typeof(CLSCompliantAttribute).FullName!, typeof(AssemblyMetadataAttribute).FullName!, typeof(NeutralResourcesLanguageAttribute).FullName!, + typeof(AttributeUsageAttribute).FullName!, ], IncludeTypes = types, }; diff --git a/tests/NetEvolve.Extensions.NUnit.Tests.PublicApi/_snapshots/DotNet6_0/PublicApiTests.PublicApi_HasNotChanged_Expected.verified.txt b/tests/NetEvolve.Extensions.NUnit.Tests.PublicApi/_snapshots/DotNet6_0/PublicApiTests.PublicApi_HasNotChanged_Expected.verified.txt index 01f3cbf..54b9b1f 100644 --- a/tests/NetEvolve.Extensions.NUnit.Tests.PublicApi/_snapshots/DotNet6_0/PublicApiTests.PublicApi_HasNotChanged_Expected.verified.txt +++ b/tests/NetEvolve.Extensions.NUnit.Tests.PublicApi/_snapshots/DotNet6_0/PublicApiTests.PublicApi_HasNotChanged_Expected.verified.txt @@ -8,7 +8,6 @@ { public ArchitectureTestAttribute() { } } - [System.AttributeUsage(System.AttributeTargets.Class | System.AttributeTargets.Method, AllowMultiple=true)] public sealed class BugAttribute : NetEvolve.Extensions.NUnit.Internal.CategoryIdBaseAttribute { public BugAttribute() { } @@ -31,14 +30,12 @@ { public EndToEndTestAttribute() { } } - [System.AttributeUsage(System.AttributeTargets.Class | System.AttributeTargets.Method, AllowMultiple=true)] public sealed class EpicAttribute : NetEvolve.Extensions.NUnit.Internal.CategoryIdBaseAttribute { public EpicAttribute() { } public EpicAttribute(long id) { } public EpicAttribute(string? id) { } } - [System.AttributeUsage(System.AttributeTargets.Class | System.AttributeTargets.Method, AllowMultiple=true)] public sealed class FeatureAttribute : NetEvolve.Extensions.NUnit.Internal.CategoryIdBaseAttribute { public FeatureAttribute() { } @@ -49,19 +46,16 @@ { public FunctionalTestAttribute() { } } - [System.AttributeUsage(System.AttributeTargets.Class | System.AttributeTargets.Method, AllowMultiple=true, Inherited=true)] public sealed class IntegrationTestAttribute : NUnit.Framework.CategoryAttribute { public IntegrationTestAttribute() { } } - [System.AttributeUsage(System.AttributeTargets.Class | System.AttributeTargets.Method, AllowMultiple=true)] public sealed class IssueAttribute : NetEvolve.Extensions.NUnit.Internal.CategoryIdBaseAttribute { public IssueAttribute() { } public IssueAttribute(long id) { } public IssueAttribute(string? id) { } } - [System.AttributeUsage(System.AttributeTargets.Assembly, AllowMultiple=false, Inherited=false)] public sealed class MaxLevelOfParallelismAttribute : NUnit.Framework.PropertyAttribute { public MaxLevelOfParallelismAttribute(int level) { } @@ -82,14 +76,12 @@ { public UnitTestAttribute() { } } - [System.AttributeUsage(System.AttributeTargets.Class | System.AttributeTargets.Method, AllowMultiple=true)] public sealed class UserStoryAttribute : NetEvolve.Extensions.NUnit.Internal.CategoryIdBaseAttribute { public UserStoryAttribute() { } public UserStoryAttribute(long id) { } public UserStoryAttribute(string? id) { } } - [System.AttributeUsage(System.AttributeTargets.Class | System.AttributeTargets.Method, AllowMultiple=true)] public sealed class WorkItemAttribute : NetEvolve.Extensions.NUnit.Internal.CategoryIdBaseAttribute { public WorkItemAttribute() { } diff --git a/tests/NetEvolve.Extensions.NUnit.Tests.PublicApi/_snapshots/DotNet8_0/PublicApiTests.PublicApi_HasNotChanged_Expected.verified.txt b/tests/NetEvolve.Extensions.NUnit.Tests.PublicApi/_snapshots/DotNet8_0/PublicApiTests.PublicApi_HasNotChanged_Expected.verified.txt index 01f3cbf..54b9b1f 100644 --- a/tests/NetEvolve.Extensions.NUnit.Tests.PublicApi/_snapshots/DotNet8_0/PublicApiTests.PublicApi_HasNotChanged_Expected.verified.txt +++ b/tests/NetEvolve.Extensions.NUnit.Tests.PublicApi/_snapshots/DotNet8_0/PublicApiTests.PublicApi_HasNotChanged_Expected.verified.txt @@ -8,7 +8,6 @@ { public ArchitectureTestAttribute() { } } - [System.AttributeUsage(System.AttributeTargets.Class | System.AttributeTargets.Method, AllowMultiple=true)] public sealed class BugAttribute : NetEvolve.Extensions.NUnit.Internal.CategoryIdBaseAttribute { public BugAttribute() { } @@ -31,14 +30,12 @@ { public EndToEndTestAttribute() { } } - [System.AttributeUsage(System.AttributeTargets.Class | System.AttributeTargets.Method, AllowMultiple=true)] public sealed class EpicAttribute : NetEvolve.Extensions.NUnit.Internal.CategoryIdBaseAttribute { public EpicAttribute() { } public EpicAttribute(long id) { } public EpicAttribute(string? id) { } } - [System.AttributeUsage(System.AttributeTargets.Class | System.AttributeTargets.Method, AllowMultiple=true)] public sealed class FeatureAttribute : NetEvolve.Extensions.NUnit.Internal.CategoryIdBaseAttribute { public FeatureAttribute() { } @@ -49,19 +46,16 @@ { public FunctionalTestAttribute() { } } - [System.AttributeUsage(System.AttributeTargets.Class | System.AttributeTargets.Method, AllowMultiple=true, Inherited=true)] public sealed class IntegrationTestAttribute : NUnit.Framework.CategoryAttribute { public IntegrationTestAttribute() { } } - [System.AttributeUsage(System.AttributeTargets.Class | System.AttributeTargets.Method, AllowMultiple=true)] public sealed class IssueAttribute : NetEvolve.Extensions.NUnit.Internal.CategoryIdBaseAttribute { public IssueAttribute() { } public IssueAttribute(long id) { } public IssueAttribute(string? id) { } } - [System.AttributeUsage(System.AttributeTargets.Assembly, AllowMultiple=false, Inherited=false)] public sealed class MaxLevelOfParallelismAttribute : NUnit.Framework.PropertyAttribute { public MaxLevelOfParallelismAttribute(int level) { } @@ -82,14 +76,12 @@ { public UnitTestAttribute() { } } - [System.AttributeUsage(System.AttributeTargets.Class | System.AttributeTargets.Method, AllowMultiple=true)] public sealed class UserStoryAttribute : NetEvolve.Extensions.NUnit.Internal.CategoryIdBaseAttribute { public UserStoryAttribute() { } public UserStoryAttribute(long id) { } public UserStoryAttribute(string? id) { } } - [System.AttributeUsage(System.AttributeTargets.Class | System.AttributeTargets.Method, AllowMultiple=true)] public sealed class WorkItemAttribute : NetEvolve.Extensions.NUnit.Internal.CategoryIdBaseAttribute { public WorkItemAttribute() { } diff --git a/tests/NetEvolve.Extensions.NUnit.Tests.Unit/AttributeTestsBase.cs b/tests/NetEvolve.Extensions.NUnit.Tests.Unit/AttributeTestsBase.cs index 36c7db1..620a19c 100644 --- a/tests/NetEvolve.Extensions.NUnit.Tests.Unit/AttributeTestsBase.cs +++ b/tests/NetEvolve.Extensions.NUnit.Tests.Unit/AttributeTestsBase.cs @@ -19,14 +19,14 @@ [TestFixture] public abstract class AttributeTestsBase { - private static readonly List _excludeKeys = new List - { + private static readonly List _excludeKeys = + [ PropertyNames.AppDomain, PropertyNames.JoinType, PropertyNames.ProcessId, PropertyNames.ProviderStackTrace, PropertyNames.SkipReason, - }; + ]; /// /// Gets the Traits from the given Method name @@ -39,7 +39,7 @@ protected IEnumerable> GetProperties( { if (methodName is null) { - return Enumerable.Empty>(); + return []; } var classType = GetType(); @@ -50,7 +50,7 @@ protected IEnumerable> GetProperties( if (methodInfo is null) { - return Enumerable.Empty>(); + return []; } var test = new DefaultTestCaseBuilder().BuildFrom(new MethodWrapper(classType, methodInfo)); diff --git a/tests/NetEvolve.Extensions.NUnit.Tests.Unit/Predefined.cs b/tests/NetEvolve.Extensions.NUnit.Tests.Unit/Predefined.cs index 103fde4..45924f2 100644 --- a/tests/NetEvolve.Extensions.NUnit.Tests.Unit/Predefined.cs +++ b/tests/NetEvolve.Extensions.NUnit.Tests.Unit/Predefined.cs @@ -24,7 +24,7 @@ public static void Init() } ); - VerifierSettings.AutoVerify(includeBuildServer: false); VerifierSettings.SortPropertiesAlphabetically(); + VerifierSettings.SortJsonObjects(); } } diff --git a/tests/NetEvolve.Extensions.XUnit.Tests.PublicApi/Predefined.cs b/tests/NetEvolve.Extensions.XUnit.Tests.PublicApi/Predefined.cs index 2dde612..b9415af 100644 --- a/tests/NetEvolve.Extensions.XUnit.Tests.PublicApi/Predefined.cs +++ b/tests/NetEvolve.Extensions.XUnit.Tests.PublicApi/Predefined.cs @@ -23,7 +23,7 @@ public static void Init() } ); - VerifierSettings.AutoVerify(includeBuildServer: false); VerifierSettings.SortPropertiesAlphabetically(); + VerifierSettings.SortJsonObjects(); } } diff --git a/tests/NetEvolve.Extensions.XUnit.Tests.PublicApi/PublicApiTests.cs b/tests/NetEvolve.Extensions.XUnit.Tests.PublicApi/PublicApiTests.cs index 52c6738..1ec4421 100644 --- a/tests/NetEvolve.Extensions.XUnit.Tests.PublicApi/PublicApiTests.cs +++ b/tests/NetEvolve.Extensions.XUnit.Tests.PublicApi/PublicApiTests.cs @@ -29,6 +29,7 @@ public Task PublicApi_HasNotChanged_Expected() typeof(CLSCompliantAttribute).FullName!, typeof(AssemblyMetadataAttribute).FullName!, typeof(NeutralResourcesLanguageAttribute).FullName!, + typeof(AttributeUsageAttribute).FullName!, ], IncludeTypes = types, }; diff --git a/tests/NetEvolve.Extensions.XUnit.Tests.PublicApi/_snapshots/DotNet6_0/PublicApiTests.PublicApi_HasNotChanged_Expected.verified.txt b/tests/NetEvolve.Extensions.XUnit.Tests.PublicApi/_snapshots/DotNet6_0/PublicApiTests.PublicApi_HasNotChanged_Expected.verified.txt index 3803386..2c584ac 100644 --- a/tests/NetEvolve.Extensions.XUnit.Tests.PublicApi/_snapshots/DotNet6_0/PublicApiTests.PublicApi_HasNotChanged_Expected.verified.txt +++ b/tests/NetEvolve.Extensions.XUnit.Tests.PublicApi/_snapshots/DotNet6_0/PublicApiTests.PublicApi_HasNotChanged_Expected.verified.txt @@ -8,7 +8,6 @@ { public ArchitectureTestAttribute() { } } - [System.AttributeUsage(System.AttributeTargets.Class | System.AttributeTargets.Method, AllowMultiple=true)] public sealed class BugAttribute : NetEvolve.Extensions.XUnit.Internal.CategoryWithIdTraitBaseAttribute { public BugAttribute() { } @@ -61,7 +60,6 @@ { public PreDeploymentAttribute() { } } - [System.AttributeUsage(System.AttributeTargets.Class | System.AttributeTargets.Method, Inherited=false)] public sealed class SetCultureAttribute : NetEvolve.Extensions.XUnit.Internal.CultureAttributeBase { public SetCultureAttribute() { } @@ -71,7 +69,6 @@ public override void After(System.Reflection.MethodInfo methodUnderTest) { } public override void Before(System.Reflection.MethodInfo methodUnderTest) { } } - [System.AttributeUsage(System.AttributeTargets.Class | System.AttributeTargets.Method, Inherited=false)] public sealed class SetUICultureAttribute : NetEvolve.Extensions.XUnit.Internal.CultureAttributeBase { public SetUICultureAttribute() { } @@ -96,7 +93,6 @@ } namespace NetEvolve.Extensions.XUnit.Internal { - [System.AttributeUsage(System.AttributeTargets.Assembly | System.AttributeTargets.Class | System.AttributeTargets.Method, AllowMultiple=true, Inherited=true)] [Xunit.Sdk.TraitDiscoverer("NetEvolve.Extensions.XUnit.Internal.CategoryTraitDiscoverer", "NetEvolve.Extensions.XUnit")] public abstract class CategoryTraitBaseAttribute : System.Attribute, Xunit.Sdk.ITraitAttribute { @@ -108,7 +104,6 @@ namespace NetEvolve.Extensions.XUnit.Internal public CategoryTraitDiscoverer() { } public override System.Collections.Generic.IEnumerable> GetTraits(Xunit.Abstractions.IAttributeInfo traitAttribute) { } } - [System.AttributeUsage(System.AttributeTargets.Class | System.AttributeTargets.Method, AllowMultiple=true, Inherited=true)] [Xunit.Sdk.TraitDiscoverer("NetEvolve.Extensions.XUnit.Internal.CategoryTraitDiscoverer", "NetEvolve.Extensions.XUnit")] public abstract class CategoryWithIdTraitBaseAttribute : System.Attribute, Xunit.Sdk.ITraitAttribute { @@ -117,7 +112,6 @@ namespace NetEvolve.Extensions.XUnit.Internal public string Category { get; } public string? Id { get; } } - [System.AttributeUsage(System.AttributeTargets.Class | System.AttributeTargets.Method, AllowMultiple=true, Inherited=true)] [Xunit.Sdk.TraitDiscoverer("NetEvolve.Extensions.XUnit.Internal.CultureTraitDiscoverer", "NetEvolve.Extensions.XUnit")] public abstract class CultureAttributeBase : Xunit.Sdk.BeforeAfterTestAttribute, Xunit.Sdk.ITraitAttribute { diff --git a/tests/NetEvolve.Extensions.XUnit.Tests.PublicApi/_snapshots/DotNet8_0/PublicApiTests.PublicApi_HasNotChanged_Expected.verified.txt b/tests/NetEvolve.Extensions.XUnit.Tests.PublicApi/_snapshots/DotNet8_0/PublicApiTests.PublicApi_HasNotChanged_Expected.verified.txt index 3803386..2c584ac 100644 --- a/tests/NetEvolve.Extensions.XUnit.Tests.PublicApi/_snapshots/DotNet8_0/PublicApiTests.PublicApi_HasNotChanged_Expected.verified.txt +++ b/tests/NetEvolve.Extensions.XUnit.Tests.PublicApi/_snapshots/DotNet8_0/PublicApiTests.PublicApi_HasNotChanged_Expected.verified.txt @@ -8,7 +8,6 @@ { public ArchitectureTestAttribute() { } } - [System.AttributeUsage(System.AttributeTargets.Class | System.AttributeTargets.Method, AllowMultiple=true)] public sealed class BugAttribute : NetEvolve.Extensions.XUnit.Internal.CategoryWithIdTraitBaseAttribute { public BugAttribute() { } @@ -61,7 +60,6 @@ { public PreDeploymentAttribute() { } } - [System.AttributeUsage(System.AttributeTargets.Class | System.AttributeTargets.Method, Inherited=false)] public sealed class SetCultureAttribute : NetEvolve.Extensions.XUnit.Internal.CultureAttributeBase { public SetCultureAttribute() { } @@ -71,7 +69,6 @@ public override void After(System.Reflection.MethodInfo methodUnderTest) { } public override void Before(System.Reflection.MethodInfo methodUnderTest) { } } - [System.AttributeUsage(System.AttributeTargets.Class | System.AttributeTargets.Method, Inherited=false)] public sealed class SetUICultureAttribute : NetEvolve.Extensions.XUnit.Internal.CultureAttributeBase { public SetUICultureAttribute() { } @@ -96,7 +93,6 @@ } namespace NetEvolve.Extensions.XUnit.Internal { - [System.AttributeUsage(System.AttributeTargets.Assembly | System.AttributeTargets.Class | System.AttributeTargets.Method, AllowMultiple=true, Inherited=true)] [Xunit.Sdk.TraitDiscoverer("NetEvolve.Extensions.XUnit.Internal.CategoryTraitDiscoverer", "NetEvolve.Extensions.XUnit")] public abstract class CategoryTraitBaseAttribute : System.Attribute, Xunit.Sdk.ITraitAttribute { @@ -108,7 +104,6 @@ namespace NetEvolve.Extensions.XUnit.Internal public CategoryTraitDiscoverer() { } public override System.Collections.Generic.IEnumerable> GetTraits(Xunit.Abstractions.IAttributeInfo traitAttribute) { } } - [System.AttributeUsage(System.AttributeTargets.Class | System.AttributeTargets.Method, AllowMultiple=true, Inherited=true)] [Xunit.Sdk.TraitDiscoverer("NetEvolve.Extensions.XUnit.Internal.CategoryTraitDiscoverer", "NetEvolve.Extensions.XUnit")] public abstract class CategoryWithIdTraitBaseAttribute : System.Attribute, Xunit.Sdk.ITraitAttribute { @@ -117,7 +112,6 @@ namespace NetEvolve.Extensions.XUnit.Internal public string Category { get; } public string? Id { get; } } - [System.AttributeUsage(System.AttributeTargets.Class | System.AttributeTargets.Method, AllowMultiple=true, Inherited=true)] [Xunit.Sdk.TraitDiscoverer("NetEvolve.Extensions.XUnit.Internal.CultureTraitDiscoverer", "NetEvolve.Extensions.XUnit")] public abstract class CultureAttributeBase : Xunit.Sdk.BeforeAfterTestAttribute, Xunit.Sdk.ITraitAttribute { diff --git a/tests/NetEvolve.Extensions.XUnit.Tests.Unit/AttributeTestsBase.cs b/tests/NetEvolve.Extensions.XUnit.Tests.Unit/AttributeTestsBase.cs index 8f3d2d1..0d114b9 100644 --- a/tests/NetEvolve.Extensions.XUnit.Tests.Unit/AttributeTestsBase.cs +++ b/tests/NetEvolve.Extensions.XUnit.Tests.Unit/AttributeTestsBase.cs @@ -25,9 +25,9 @@ protected IEnumerable> GetTraits( [CallerMemberName] string? methodName = null ) { - if (methodName == null) + if (methodName is null) { - return Enumerable.Empty>(); + return []; } var classType = GetType(); @@ -38,7 +38,7 @@ protected IEnumerable> GetTraits( if (methodInfo is null) { - return Enumerable.Empty>(); + return []; } var messageSink = new NullMessageSink(); @@ -73,7 +73,7 @@ IMessageSink messageSink var discovererAttributeData = FindDiscovererAttributeType( traitAttributeType.GetTypeInfo() ); - if (discovererAttributeData == null) + if (discovererAttributeData is null) { continue; } @@ -82,13 +82,13 @@ IMessageSink messageSink messageSink, Reflector.Wrap(discovererAttributeData) ); - if (discoverer == null) + if (discoverer is null) { continue; } var traits = discoverer.GetTraits(Reflector.Wrap(traitAttributeData)); - if (traits != null) + if (traits is not null) { result.AddRange(traits); } @@ -105,7 +105,7 @@ IMessageSink messageSink { result = typeChecking.CustomAttributes.FirstOrDefault(isTraitDiscovererAttribute); typeChecking = traitAttribute.BaseType.GetTypeInfo(); - } while (result == null && typeChecking != null); + } while (result is null && typeChecking is not null); return result; diff --git a/tests/NetEvolve.Extensions.XUnit.Tests.Unit/Predefined.cs b/tests/NetEvolve.Extensions.XUnit.Tests.Unit/Predefined.cs index 7db355c..797ef60 100644 --- a/tests/NetEvolve.Extensions.XUnit.Tests.Unit/Predefined.cs +++ b/tests/NetEvolve.Extensions.XUnit.Tests.Unit/Predefined.cs @@ -24,7 +24,7 @@ public static void Init() } ); - VerifierSettings.AutoVerify(includeBuildServer: false); VerifierSettings.SortPropertiesAlphabetically(); + VerifierSettings.SortJsonObjects(); } } diff --git a/tests/NetEvolve.Extensions.XUnit.V3.Tests.PublicApi/NetEvolve.Extensions.XUnit.V3.Tests.PublicApi.csproj b/tests/NetEvolve.Extensions.XUnit.V3.Tests.PublicApi/NetEvolve.Extensions.XUnit.V3.Tests.PublicApi.csproj new file mode 100644 index 0000000..0f68ce8 --- /dev/null +++ b/tests/NetEvolve.Extensions.XUnit.V3.Tests.PublicApi/NetEvolve.Extensions.XUnit.V3.Tests.PublicApi.csproj @@ -0,0 +1,33 @@ + + + + $(NetEvolve_TestTargetFrameworks) + enable + Exe + + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + + + + + + + diff --git a/tests/NetEvolve.Extensions.XUnit.V3.Tests.PublicApi/Predefined.cs b/tests/NetEvolve.Extensions.XUnit.V3.Tests.PublicApi/Predefined.cs new file mode 100644 index 0000000..eecc879 --- /dev/null +++ b/tests/NetEvolve.Extensions.XUnit.V3.Tests.PublicApi/Predefined.cs @@ -0,0 +1,29 @@ +namespace NetEvolve.Extensions.XUnit.V3.Tests.PublicApi; + +using System.IO; +using System.Runtime.CompilerServices; +using VerifyTests; +using VerifyXunit; + +internal static class Predefined +{ + [ModuleInitializer] + public static void Init() + { + Verifier.DerivePathInfo( + (sourceFile, projectDirectory, type, method) => + { + var directory = Path.Combine( + projectDirectory, + "_snapshots", + Namer.TargetFrameworkNameAndVersion + ); + _ = Directory.CreateDirectory(directory); + return new(directory, type.Name, method.Name); + } + ); + + VerifierSettings.SortPropertiesAlphabetically(); + VerifierSettings.SortJsonObjects(); + } +} diff --git a/tests/NetEvolve.Extensions.XUnit.V3.Tests.PublicApi/PublicApiTests.cs b/tests/NetEvolve.Extensions.XUnit.V3.Tests.PublicApi/PublicApiTests.cs new file mode 100644 index 0000000..92c2e35 --- /dev/null +++ b/tests/NetEvolve.Extensions.XUnit.V3.Tests.PublicApi/PublicApiTests.cs @@ -0,0 +1,52 @@ +namespace NetEvolve.Extensions.XUnit.V3.Tests.PublicApi; + +using System; +using System.ComponentModel; +using System.Linq; +using System.Reflection; +using System.Resources; +using System.Runtime.CompilerServices; +using System.Runtime.Versioning; +using System.Threading.Tasks; +using PublicApiGenerator; + +public class PublicApiTests +{ + [Fact] + public Task PublicApi_HasNotChanged_Expected() + { + var assembly = typeof(AcceptanceTestAttribute).Assembly; + var types = assembly.GetTypes().Where(IsVisibleToIntelliSense).ToArray(); + + var options = new ApiGeneratorOptions + { + ExcludeAttributes = + [ + typeof(InternalsVisibleToAttribute).FullName!, + "System.Runtime.CompilerServices.IsByRefLikeAttribute", + typeof(TargetFrameworkAttribute).FullName!, + typeof(CLSCompliantAttribute).FullName!, + typeof(AssemblyMetadataAttribute).FullName!, + typeof(NeutralResourcesLanguageAttribute).FullName!, + typeof(AttributeUsageAttribute).FullName!, + ], + IncludeTypes = types, + }; + + var publicApi = assembly.GeneratePublicApi(options); + + return Verify(publicApi); + } + + private static bool IsVisibleToIntelliSense(Type type) + { + var browsable = type.GetCustomAttribute(); + if (browsable is null || browsable.Browsable) + { + return true; + } + + var editorBrowsable = type.GetCustomAttribute(); + return editorBrowsable is null || editorBrowsable.State != EditorBrowsableState.Never; + } +} diff --git a/tests/NetEvolve.Extensions.XUnit.V3.Tests.PublicApi/_snapshots/DotNet6_0/PublicApiTests.PublicApi_HasNotChanged_Expected.verified.txt b/tests/NetEvolve.Extensions.XUnit.V3.Tests.PublicApi/_snapshots/DotNet6_0/PublicApiTests.PublicApi_HasNotChanged_Expected.verified.txt new file mode 100644 index 0000000..953dc14 --- /dev/null +++ b/tests/NetEvolve.Extensions.XUnit.V3.Tests.PublicApi/_snapshots/DotNet6_0/PublicApiTests.PublicApi_HasNotChanged_Expected.verified.txt @@ -0,0 +1,121 @@ +namespace NetEvolve.Extensions.XUnit.V3 +{ + public sealed class AcceptanceTestAttribute : NetEvolve.Extensions.XUnit.V3.Internal.CategoryTraitBaseAttribute + { + public AcceptanceTestAttribute() { } + } + public sealed class ArchitectureTestAttribute : NetEvolve.Extensions.XUnit.V3.Internal.CategoryTraitBaseAttribute + { + public ArchitectureTestAttribute() { } + } + public sealed class BugAttribute : NetEvolve.Extensions.XUnit.V3.Internal.CategoryWithIdTraitBaseAttribute + { + public BugAttribute() { } + public BugAttribute(long id) { } + public BugAttribute(string? id) { } + } + public sealed class CodedUITestAttribute : NetEvolve.Extensions.XUnit.V3.Internal.CategoryTraitBaseAttribute + { + public CodedUITestAttribute() { } + } + public sealed class EndToEndTestAttribute : NetEvolve.Extensions.XUnit.V3.Internal.CategoryTraitBaseAttribute + { + public EndToEndTestAttribute() { } + } + public sealed class EpicAttribute : NetEvolve.Extensions.XUnit.V3.Internal.CategoryWithIdTraitBaseAttribute + { + public EpicAttribute() { } + public EpicAttribute(long id) { } + public EpicAttribute(string? id) { } + } + public sealed class FeatureAttribute : NetEvolve.Extensions.XUnit.V3.Internal.CategoryWithIdTraitBaseAttribute + { + public FeatureAttribute() { } + public FeatureAttribute(long id) { } + public FeatureAttribute(string? id) { } + } + public sealed class FunctionalTestAttribute : NetEvolve.Extensions.XUnit.V3.Internal.CategoryTraitBaseAttribute + { + public FunctionalTestAttribute() { } + } + public sealed class IntegrationTestAttribute : NetEvolve.Extensions.XUnit.V3.Internal.CategoryTraitBaseAttribute + { + public IntegrationTestAttribute() { } + } + public sealed class IssueAttribute : NetEvolve.Extensions.XUnit.V3.Internal.CategoryWithIdTraitBaseAttribute + { + public IssueAttribute() { } + public IssueAttribute(long id) { } + public IssueAttribute(string? id) { } + } + public sealed class PerformanceTestAttribute : NetEvolve.Extensions.XUnit.V3.Internal.CategoryTraitBaseAttribute + { + public PerformanceTestAttribute() { } + } + public sealed class PostDeploymentAttribute : NetEvolve.Extensions.XUnit.V3.Internal.CategoryTraitBaseAttribute + { + public PostDeploymentAttribute() { } + } + public sealed class PreDeploymentAttribute : NetEvolve.Extensions.XUnit.V3.Internal.CategoryTraitBaseAttribute + { + public PreDeploymentAttribute() { } + } + public sealed class SetCultureAttribute : NetEvolve.Extensions.XUnit.V3.Internal.CultureAttributeBase + { + public SetCultureAttribute() { } + public SetCultureAttribute(string culture) { } + public SetCultureAttribute(string culture, string? uiCulture) { } + public string? UICulture { get; } + public override System.Threading.Tasks.ValueTask After(System.Reflection.MethodInfo methodUnderTest, Xunit.v3.IXunitTest test) { } + public override System.Threading.Tasks.ValueTask Before(System.Reflection.MethodInfo methodUnderTest, Xunit.v3.IXunitTest test) { } + public override System.Collections.Generic.IReadOnlyCollection> GetTraits() { } + } + public sealed class SetUICultureAttribute : NetEvolve.Extensions.XUnit.V3.Internal.CultureAttributeBase + { + public SetUICultureAttribute() { } + public SetUICultureAttribute(string culture) { } + public override System.Collections.Generic.IReadOnlyCollection> GetTraits() { } + } + public sealed class UnitTestAttribute : NetEvolve.Extensions.XUnit.V3.Internal.CategoryTraitBaseAttribute + { + public UnitTestAttribute() { } + } + public sealed class UserStoryAttribute : NetEvolve.Extensions.XUnit.V3.Internal.CategoryWithIdTraitBaseAttribute + { + public UserStoryAttribute() { } + public UserStoryAttribute(long id) { } + public UserStoryAttribute(string? id) { } + } + public sealed class WorkItemAttribute : NetEvolve.Extensions.XUnit.V3.Internal.CategoryWithIdTraitBaseAttribute + { + public WorkItemAttribute() { } + public WorkItemAttribute(long id) { } + public WorkItemAttribute(string? id) { } + } +} +namespace NetEvolve.Extensions.XUnit.V3.Internal +{ + public abstract class CategoryTraitBaseAttribute : System.Attribute, Xunit.v3.ITraitAttribute + { + protected CategoryTraitBaseAttribute(string category) { } + public string Category { get; } + public System.Collections.Generic.IReadOnlyCollection> GetTraits() { } + } + public abstract class CategoryWithIdTraitBaseAttribute : System.Attribute, Xunit.v3.ITraitAttribute + { + protected CategoryWithIdTraitBaseAttribute(string category, long id) { } + protected CategoryWithIdTraitBaseAttribute(string category, string? id) { } + public string Category { get; } + public string? Id { get; } + public System.Collections.Generic.IReadOnlyCollection> GetTraits() { } + } + public abstract class CultureAttributeBase : System.Attribute, Xunit.v3.IBeforeAfterTestAttribute, Xunit.v3.ITraitAttribute + { + protected CultureAttributeBase(string category, string culture) { } + public string Category { get; } + public string Culture { get; } + public virtual System.Threading.Tasks.ValueTask After(System.Reflection.MethodInfo methodUnderTest, Xunit.v3.IXunitTest test) { } + public virtual System.Threading.Tasks.ValueTask Before(System.Reflection.MethodInfo methodUnderTest, Xunit.v3.IXunitTest test) { } + public abstract System.Collections.Generic.IReadOnlyCollection> GetTraits(); + } +} \ No newline at end of file diff --git a/tests/NetEvolve.Extensions.XUnit.V3.Tests.PublicApi/_snapshots/DotNet8_0/PublicApiTests.PublicApi_HasNotChanged_Expected.verified.txt b/tests/NetEvolve.Extensions.XUnit.V3.Tests.PublicApi/_snapshots/DotNet8_0/PublicApiTests.PublicApi_HasNotChanged_Expected.verified.txt new file mode 100644 index 0000000..953dc14 --- /dev/null +++ b/tests/NetEvolve.Extensions.XUnit.V3.Tests.PublicApi/_snapshots/DotNet8_0/PublicApiTests.PublicApi_HasNotChanged_Expected.verified.txt @@ -0,0 +1,121 @@ +namespace NetEvolve.Extensions.XUnit.V3 +{ + public sealed class AcceptanceTestAttribute : NetEvolve.Extensions.XUnit.V3.Internal.CategoryTraitBaseAttribute + { + public AcceptanceTestAttribute() { } + } + public sealed class ArchitectureTestAttribute : NetEvolve.Extensions.XUnit.V3.Internal.CategoryTraitBaseAttribute + { + public ArchitectureTestAttribute() { } + } + public sealed class BugAttribute : NetEvolve.Extensions.XUnit.V3.Internal.CategoryWithIdTraitBaseAttribute + { + public BugAttribute() { } + public BugAttribute(long id) { } + public BugAttribute(string? id) { } + } + public sealed class CodedUITestAttribute : NetEvolve.Extensions.XUnit.V3.Internal.CategoryTraitBaseAttribute + { + public CodedUITestAttribute() { } + } + public sealed class EndToEndTestAttribute : NetEvolve.Extensions.XUnit.V3.Internal.CategoryTraitBaseAttribute + { + public EndToEndTestAttribute() { } + } + public sealed class EpicAttribute : NetEvolve.Extensions.XUnit.V3.Internal.CategoryWithIdTraitBaseAttribute + { + public EpicAttribute() { } + public EpicAttribute(long id) { } + public EpicAttribute(string? id) { } + } + public sealed class FeatureAttribute : NetEvolve.Extensions.XUnit.V3.Internal.CategoryWithIdTraitBaseAttribute + { + public FeatureAttribute() { } + public FeatureAttribute(long id) { } + public FeatureAttribute(string? id) { } + } + public sealed class FunctionalTestAttribute : NetEvolve.Extensions.XUnit.V3.Internal.CategoryTraitBaseAttribute + { + public FunctionalTestAttribute() { } + } + public sealed class IntegrationTestAttribute : NetEvolve.Extensions.XUnit.V3.Internal.CategoryTraitBaseAttribute + { + public IntegrationTestAttribute() { } + } + public sealed class IssueAttribute : NetEvolve.Extensions.XUnit.V3.Internal.CategoryWithIdTraitBaseAttribute + { + public IssueAttribute() { } + public IssueAttribute(long id) { } + public IssueAttribute(string? id) { } + } + public sealed class PerformanceTestAttribute : NetEvolve.Extensions.XUnit.V3.Internal.CategoryTraitBaseAttribute + { + public PerformanceTestAttribute() { } + } + public sealed class PostDeploymentAttribute : NetEvolve.Extensions.XUnit.V3.Internal.CategoryTraitBaseAttribute + { + public PostDeploymentAttribute() { } + } + public sealed class PreDeploymentAttribute : NetEvolve.Extensions.XUnit.V3.Internal.CategoryTraitBaseAttribute + { + public PreDeploymentAttribute() { } + } + public sealed class SetCultureAttribute : NetEvolve.Extensions.XUnit.V3.Internal.CultureAttributeBase + { + public SetCultureAttribute() { } + public SetCultureAttribute(string culture) { } + public SetCultureAttribute(string culture, string? uiCulture) { } + public string? UICulture { get; } + public override System.Threading.Tasks.ValueTask After(System.Reflection.MethodInfo methodUnderTest, Xunit.v3.IXunitTest test) { } + public override System.Threading.Tasks.ValueTask Before(System.Reflection.MethodInfo methodUnderTest, Xunit.v3.IXunitTest test) { } + public override System.Collections.Generic.IReadOnlyCollection> GetTraits() { } + } + public sealed class SetUICultureAttribute : NetEvolve.Extensions.XUnit.V3.Internal.CultureAttributeBase + { + public SetUICultureAttribute() { } + public SetUICultureAttribute(string culture) { } + public override System.Collections.Generic.IReadOnlyCollection> GetTraits() { } + } + public sealed class UnitTestAttribute : NetEvolve.Extensions.XUnit.V3.Internal.CategoryTraitBaseAttribute + { + public UnitTestAttribute() { } + } + public sealed class UserStoryAttribute : NetEvolve.Extensions.XUnit.V3.Internal.CategoryWithIdTraitBaseAttribute + { + public UserStoryAttribute() { } + public UserStoryAttribute(long id) { } + public UserStoryAttribute(string? id) { } + } + public sealed class WorkItemAttribute : NetEvolve.Extensions.XUnit.V3.Internal.CategoryWithIdTraitBaseAttribute + { + public WorkItemAttribute() { } + public WorkItemAttribute(long id) { } + public WorkItemAttribute(string? id) { } + } +} +namespace NetEvolve.Extensions.XUnit.V3.Internal +{ + public abstract class CategoryTraitBaseAttribute : System.Attribute, Xunit.v3.ITraitAttribute + { + protected CategoryTraitBaseAttribute(string category) { } + public string Category { get; } + public System.Collections.Generic.IReadOnlyCollection> GetTraits() { } + } + public abstract class CategoryWithIdTraitBaseAttribute : System.Attribute, Xunit.v3.ITraitAttribute + { + protected CategoryWithIdTraitBaseAttribute(string category, long id) { } + protected CategoryWithIdTraitBaseAttribute(string category, string? id) { } + public string Category { get; } + public string? Id { get; } + public System.Collections.Generic.IReadOnlyCollection> GetTraits() { } + } + public abstract class CultureAttributeBase : System.Attribute, Xunit.v3.IBeforeAfterTestAttribute, Xunit.v3.ITraitAttribute + { + protected CultureAttributeBase(string category, string culture) { } + public string Category { get; } + public string Culture { get; } + public virtual System.Threading.Tasks.ValueTask After(System.Reflection.MethodInfo methodUnderTest, Xunit.v3.IXunitTest test) { } + public virtual System.Threading.Tasks.ValueTask Before(System.Reflection.MethodInfo methodUnderTest, Xunit.v3.IXunitTest test) { } + public abstract System.Collections.Generic.IReadOnlyCollection> GetTraits(); + } +} \ No newline at end of file diff --git a/tests/NetEvolve.Extensions.XUnit.V3.Tests.Unit/AcceptanceTestAttributeTests.cs b/tests/NetEvolve.Extensions.XUnit.V3.Tests.Unit/AcceptanceTestAttributeTests.cs new file mode 100644 index 0000000..84ef1a4 --- /dev/null +++ b/tests/NetEvolve.Extensions.XUnit.V3.Tests.Unit/AcceptanceTestAttributeTests.cs @@ -0,0 +1,27 @@ +namespace NetEvolve.Extensions.XUnit.V3.Tests.Unit; + +using System; +using System.Diagnostics.CodeAnalysis; +using System.Threading.Tasks; +using Xunit; + +/// +/// Unit tests for . +/// +[ExcludeFromCodeCoverage] +public class AcceptanceTestAttributeTests : AttributeTestsBase +{ + [Theory] + [AcceptanceTest] + [InlineData(nameof(AcceptanceTest_without_parameters))] + [InlineData(nameof(AcceptanceTest_without_or_invalid_parameters))] + public async Task AcceptanceTest_without_or_invalid_parameters(string methodName) + { + var traits = GetTraits(methodName); + + _ = await Verify(traits).UseParameters(methodName); + } + + [AcceptanceTest] + protected void AcceptanceTest_without_parameters() => throw new NotSupportedException(); +} diff --git a/tests/NetEvolve.Extensions.XUnit.V3.Tests.Unit/ArchitectureTestAttributeTests.cs b/tests/NetEvolve.Extensions.XUnit.V3.Tests.Unit/ArchitectureTestAttributeTests.cs new file mode 100644 index 0000000..c72b58e --- /dev/null +++ b/tests/NetEvolve.Extensions.XUnit.V3.Tests.Unit/ArchitectureTestAttributeTests.cs @@ -0,0 +1,27 @@ +namespace NetEvolve.Extensions.XUnit.V3.Tests.Unit; + +using System; +using System.Diagnostics.CodeAnalysis; +using System.Threading.Tasks; +using Xunit; + +/// +/// Unit tests for . +/// +[ExcludeFromCodeCoverage] +public class ArchitectureTestAttributeTests : AttributeTestsBase +{ + [Theory] + [ArchitectureTest] + [InlineData(nameof(ArchitectureTest_without_parameters))] + [InlineData(nameof(ArchitectureTest_without_or_invalid_parameters))] + public async Task ArchitectureTest_without_or_invalid_parameters(string methodName) + { + var traits = GetTraits(methodName); + + _ = await Verify(traits).UseParameters(methodName); + } + + [ArchitectureTest] + protected void ArchitectureTest_without_parameters() => throw new NotSupportedException(); +} diff --git a/tests/NetEvolve.Extensions.XUnit.V3.Tests.Unit/AttributeTestsBase.cs b/tests/NetEvolve.Extensions.XUnit.V3.Tests.Unit/AttributeTestsBase.cs new file mode 100644 index 0000000..c4d02c7 --- /dev/null +++ b/tests/NetEvolve.Extensions.XUnit.V3.Tests.Unit/AttributeTestsBase.cs @@ -0,0 +1,62 @@ +namespace NetEvolve.Extensions.XUnit.V3.Tests.Unit; + +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using System.Reflection; +using System.Runtime.CompilerServices; +using VerifyTests; +using VerifyXunit; +using Xunit.Internal; +using Xunit.Sdk; +using Xunit.v3; + +/// +/// Base class for Trait Attribute tests +/// +[ExcludeFromCodeCoverage] +public abstract class AttributeTestsBase +{ + /// + /// Gets the Traits from the given Method name + /// + /// Name of the caller Method + /// List of + protected IEnumerable> GetTraits( + [CallerMemberName] string? methodName = null + ) + { + if (methodName is null) + { + return []; + } + + var classType = GetType(); + + var methodInfo = classType.GetMethod( + methodName, + BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance + ); + + if (methodInfo is null) + { + return []; + } + + var assemblyTraits = ExtensibilityPointFactory.GetAssemblyTraits(classType.Assembly); + var classTraits = ExtensibilityPointFactory.GetClassTraits(classType, assemblyTraits); + var methodTraits = ExtensibilityPointFactory.GetMethodTraits(methodInfo, classTraits); + + var result = new Dictionary(StringComparer.OrdinalIgnoreCase); + + foreach (var trait in methodTraits) + { + result.Add(trait.Key, string.Join(", ", trait.Value)); + } + + return [.. result]; + } + + protected static SettingsTask Verify(T traits) => Verifier.Verify(traits); +} diff --git a/tests/NetEvolve.Extensions.XUnit.V3.Tests.Unit/BugAttributeTests.cs b/tests/NetEvolve.Extensions.XUnit.V3.Tests.Unit/BugAttributeTests.cs new file mode 100644 index 0000000..759111c --- /dev/null +++ b/tests/NetEvolve.Extensions.XUnit.V3.Tests.Unit/BugAttributeTests.cs @@ -0,0 +1,49 @@ +namespace NetEvolve.Extensions.XUnit.V3.Tests.Unit; + +using System.Diagnostics.CodeAnalysis; +using System.Threading.Tasks; +using Xunit; + +/// +/// Unit tests for . +/// +[ExcludeFromCodeCoverage] +public class BugAttributeTests : AttributeTestsBase +{ + /// + /// Tests the case of methods with without additional information. + /// + [Fact] + [Bug] + [Bug("")] + public async Task Bug_without_Id() + { + var traits = GetTraits(); + + _ = await Verify(traits); + } + + /// + /// Tests the case of methods with with numeric id. + /// + [Fact] + [Bug(123456)] + public async Task Bug_with_LongId() + { + var traits = GetTraits(); + + _ = await Verify(traits); + } + + /// + /// Tests the case of methods with with id. + /// + [Fact] + [Bug("123456")] + public async Task Bug_with_StringId() + { + var traits = GetTraits(); + + _ = await Verify(traits); + } +} diff --git a/tests/NetEvolve.Extensions.XUnit.V3.Tests.Unit/CodedUITestAttributeTests.cs b/tests/NetEvolve.Extensions.XUnit.V3.Tests.Unit/CodedUITestAttributeTests.cs new file mode 100644 index 0000000..57ee773 --- /dev/null +++ b/tests/NetEvolve.Extensions.XUnit.V3.Tests.Unit/CodedUITestAttributeTests.cs @@ -0,0 +1,27 @@ +namespace NetEvolve.Extensions.XUnit.V3.Tests.Unit; + +using System; +using System.Diagnostics.CodeAnalysis; +using System.Threading.Tasks; +using Xunit; + +/// +/// Unit tests for . +/// +[ExcludeFromCodeCoverage] +public class CodedUITestAttributeTests : AttributeTestsBase +{ + [Theory] + [CodedUITest] + [InlineData(nameof(CodedUITest_without_parameters))] + [InlineData(nameof(CodedUITest_without_or_invalid_parameters))] + public async Task CodedUITest_without_or_invalid_parameters(string methodName) + { + var traits = GetTraits(methodName); + + _ = await Verify(traits).UseParameters(methodName); + } + + [CodedUITest] + protected void CodedUITest_without_parameters() => throw new NotSupportedException(); +} diff --git a/tests/NetEvolve.Extensions.XUnit.V3.Tests.Unit/EndToEndTestAttributeTests.cs b/tests/NetEvolve.Extensions.XUnit.V3.Tests.Unit/EndToEndTestAttributeTests.cs new file mode 100644 index 0000000..1212dda --- /dev/null +++ b/tests/NetEvolve.Extensions.XUnit.V3.Tests.Unit/EndToEndTestAttributeTests.cs @@ -0,0 +1,27 @@ +namespace NetEvolve.Extensions.XUnit.V3.Tests.Unit; + +using System; +using System.Diagnostics.CodeAnalysis; +using System.Threading.Tasks; +using Xunit; + +/// +/// Unit tests for . +/// +[ExcludeFromCodeCoverage] +public class EndToEndTestAttributeTests : AttributeTestsBase +{ + [Theory] + [EndToEndTest] + [InlineData(nameof(EndToEndTest_without_parameters))] + [InlineData(nameof(EndToEndTest_without_or_invalid_parameters))] + public async Task EndToEndTest_without_or_invalid_parameters(string methodName) + { + var traits = GetTraits(methodName); + + _ = await Verify(traits).UseParameters(methodName); + } + + [EndToEndTest] + protected void EndToEndTest_without_parameters() => throw new NotSupportedException(); +} diff --git a/tests/NetEvolve.Extensions.XUnit.V3.Tests.Unit/EpicAttributeTests.cs b/tests/NetEvolve.Extensions.XUnit.V3.Tests.Unit/EpicAttributeTests.cs new file mode 100644 index 0000000..b2b23e7 --- /dev/null +++ b/tests/NetEvolve.Extensions.XUnit.V3.Tests.Unit/EpicAttributeTests.cs @@ -0,0 +1,49 @@ +namespace NetEvolve.Extensions.XUnit.V3.Tests.Unit; + +using System.Diagnostics.CodeAnalysis; +using System.Threading.Tasks; +using Xunit; + +/// +/// Unit tests for . +/// +[ExcludeFromCodeCoverage] +public class EpicAttributeTests : AttributeTestsBase +{ + /// + /// Tests the case of methods with without additional information. + /// + [Fact] + [Epic] + [Epic("")] + public async Task Epic_without_Id() + { + var traits = GetTraits(); + + _ = await Verify(traits); + } + + /// + /// Tests the case of methods with with numeric id. + /// + [Fact] + [Epic(123456)] + public async Task Epic_with_LongId() + { + var traits = GetTraits(); + + _ = await Verify(traits); + } + + /// + /// Tests the case of methods with with id. + /// + [Fact] + [Epic("123456")] + public async Task Epic_with_StringId() + { + var traits = GetTraits(); + + _ = await Verify(traits); + } +} diff --git a/tests/NetEvolve.Extensions.XUnit.V3.Tests.Unit/FeatureAttributeTests.cs b/tests/NetEvolve.Extensions.XUnit.V3.Tests.Unit/FeatureAttributeTests.cs new file mode 100644 index 0000000..d02136d --- /dev/null +++ b/tests/NetEvolve.Extensions.XUnit.V3.Tests.Unit/FeatureAttributeTests.cs @@ -0,0 +1,49 @@ +namespace NetEvolve.Extensions.XUnit.V3.Tests.Unit; + +using System.Diagnostics.CodeAnalysis; +using System.Threading.Tasks; +using Xunit; + +/// +/// Unit tests for . +/// +[ExcludeFromCodeCoverage] +public class FeatureAttributeTests : AttributeTestsBase +{ + /// + /// Tests the case of methods with without additional information. + /// + [Fact] + [Feature] + [Feature("")] + public async Task Feature_without_Id() + { + var traits = GetTraits(); + + _ = await Verify(traits); + } + + /// + /// Tests the case of methods with with numeric id. + /// + [Fact] + [Feature(123456)] + public async Task Feature_with_LongId() + { + var traits = GetTraits(); + + _ = await Verify(traits); + } + + /// + /// Tests the case of methods with with id. + /// + [Fact] + [Feature("123456")] + public async Task Feature_with_StringId() + { + var traits = GetTraits(); + + _ = await Verify(traits); + } +} diff --git a/tests/NetEvolve.Extensions.XUnit.V3.Tests.Unit/FunctionalTestAttributeTests.cs b/tests/NetEvolve.Extensions.XUnit.V3.Tests.Unit/FunctionalTestAttributeTests.cs new file mode 100644 index 0000000..5908f8c --- /dev/null +++ b/tests/NetEvolve.Extensions.XUnit.V3.Tests.Unit/FunctionalTestAttributeTests.cs @@ -0,0 +1,27 @@ +namespace NetEvolve.Extensions.XUnit.V3.Tests.Unit; + +using System; +using System.Diagnostics.CodeAnalysis; +using System.Threading.Tasks; +using Xunit; + +/// +/// Unit tests for . +/// +[ExcludeFromCodeCoverage] +public class FunctionalTestAttributeTests : AttributeTestsBase +{ + [Theory] + [FunctionalTest] + [InlineData(nameof(FunctionalTest_without_parameters))] + [InlineData(nameof(FunctionalTest_without_or_invalid_parameters))] + public async Task FunctionalTest_without_or_invalid_parameters(string methodName) + { + var traits = GetTraits(methodName); + + _ = await Verify(traits).UseParameters(methodName); + } + + [FunctionalTest] + protected void FunctionalTest_without_parameters() => throw new NotSupportedException(); +} diff --git a/tests/NetEvolve.Extensions.XUnit.V3.Tests.Unit/IntegrationTestAttributeTests.cs b/tests/NetEvolve.Extensions.XUnit.V3.Tests.Unit/IntegrationTestAttributeTests.cs new file mode 100644 index 0000000..664f22c --- /dev/null +++ b/tests/NetEvolve.Extensions.XUnit.V3.Tests.Unit/IntegrationTestAttributeTests.cs @@ -0,0 +1,27 @@ +namespace NetEvolve.Extensions.XUnit.V3.Tests.Unit; + +using System; +using System.Diagnostics.CodeAnalysis; +using System.Threading.Tasks; +using Xunit; + +/// +/// Unit tests for . +/// +[ExcludeFromCodeCoverage] +public class IntegrationTestAttributeTests : AttributeTestsBase +{ + [Theory] + [IntegrationTest] + [InlineData(nameof(IntegrationTest_without_parameters))] + [InlineData(nameof(IntegrationTest_without_or_invalid_parameters))] + public async Task IntegrationTest_without_or_invalid_parameters(string methodName) + { + var traits = GetTraits(methodName); + + _ = await Verify(traits).UseParameters(methodName); + } + + [IntegrationTest] + protected void IntegrationTest_without_parameters() => throw new NotSupportedException(); +} diff --git a/tests/NetEvolve.Extensions.XUnit.V3.Tests.Unit/IssueAttributeTests.cs b/tests/NetEvolve.Extensions.XUnit.V3.Tests.Unit/IssueAttributeTests.cs new file mode 100644 index 0000000..f54d29d --- /dev/null +++ b/tests/NetEvolve.Extensions.XUnit.V3.Tests.Unit/IssueAttributeTests.cs @@ -0,0 +1,49 @@ +namespace NetEvolve.Extensions.XUnit.V3.Tests.Unit; + +using System.Diagnostics.CodeAnalysis; +using System.Threading.Tasks; +using Xunit; + +/// +/// Unit tests for . +/// +[ExcludeFromCodeCoverage] +public class IssueAttributeTests : AttributeTestsBase +{ + /// + /// Tests the case of methods with without additional information. + /// + [Fact] + [Issue] + [Issue("")] + public async Task Issue_without_Id() + { + var traits = GetTraits(); + + _ = await Verify(traits); + } + + /// + /// Tests the case of methods with with numeric id. + /// + [Fact] + [Issue(123456)] + public async Task Issue_with_LongId() + { + var traits = GetTraits(); + + _ = await Verify(traits); + } + + /// + /// Tests the case of methods with with id. + /// + [Fact] + [Issue("123456")] + public async Task Issue_with_StringId() + { + var traits = GetTraits(); + + _ = await Verify(traits); + } +} diff --git a/tests/NetEvolve.Extensions.XUnit.V3.Tests.Unit/NetEvolve.Extensions.XUnit.V3.Tests.Unit.csproj b/tests/NetEvolve.Extensions.XUnit.V3.Tests.Unit/NetEvolve.Extensions.XUnit.V3.Tests.Unit.csproj new file mode 100644 index 0000000..d3d4752 --- /dev/null +++ b/tests/NetEvolve.Extensions.XUnit.V3.Tests.Unit/NetEvolve.Extensions.XUnit.V3.Tests.Unit.csproj @@ -0,0 +1,24 @@ + + + + $(NetEvolve_TestTargetFrameworks) + Exe + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + diff --git a/tests/NetEvolve.Extensions.XUnit.V3.Tests.Unit/PerformanceTestAttributeTests.cs b/tests/NetEvolve.Extensions.XUnit.V3.Tests.Unit/PerformanceTestAttributeTests.cs new file mode 100644 index 0000000..768ec67 --- /dev/null +++ b/tests/NetEvolve.Extensions.XUnit.V3.Tests.Unit/PerformanceTestAttributeTests.cs @@ -0,0 +1,27 @@ +namespace NetEvolve.Extensions.XUnit.V3.Tests.Unit; + +using System; +using System.Diagnostics.CodeAnalysis; +using System.Threading.Tasks; +using Xunit; + +/// +/// Unit tests for . +/// +[ExcludeFromCodeCoverage] +public class PerformanceTestAttributeTests : AttributeTestsBase +{ + [Theory] + [PerformanceTest] + [InlineData(nameof(PerformanceTest_without_parameters))] + [InlineData(nameof(PerformanceTest_without_or_invalid_parameters))] + public async Task PerformanceTest_without_or_invalid_parameters(string methodName) + { + var traits = GetTraits(methodName); + + _ = await Verify(traits).UseParameters(methodName); + } + + [PerformanceTest] + protected void PerformanceTest_without_parameters() => throw new NotSupportedException(); +} diff --git a/tests/NetEvolve.Extensions.XUnit.V3.Tests.Unit/PostDeploymentAttributeTests.cs b/tests/NetEvolve.Extensions.XUnit.V3.Tests.Unit/PostDeploymentAttributeTests.cs new file mode 100644 index 0000000..cc87c6e --- /dev/null +++ b/tests/NetEvolve.Extensions.XUnit.V3.Tests.Unit/PostDeploymentAttributeTests.cs @@ -0,0 +1,24 @@ +namespace NetEvolve.Extensions.XUnit.V3.Tests.Unit; + +using System.Diagnostics.CodeAnalysis; +using System.Threading.Tasks; +using Xunit; + +/// +/// Unit tests for . +/// +[ExcludeFromCodeCoverage] +public class PostDeploymentAttributeTests : AttributeTestsBase +{ + /// + /// Tests the case of methods with . + /// + [Fact] + [PostDeployment] + public async Task PostDeployment_Expected() + { + var traits = GetTraits(); + + _ = await Verify(traits); + } +} diff --git a/tests/NetEvolve.Extensions.XUnit.V3.Tests.Unit/PreDeploymentAttributeTests.cs b/tests/NetEvolve.Extensions.XUnit.V3.Tests.Unit/PreDeploymentAttributeTests.cs new file mode 100644 index 0000000..baf94fd --- /dev/null +++ b/tests/NetEvolve.Extensions.XUnit.V3.Tests.Unit/PreDeploymentAttributeTests.cs @@ -0,0 +1,24 @@ +namespace NetEvolve.Extensions.XUnit.V3.Tests.Unit; + +using System.Diagnostics.CodeAnalysis; +using System.Threading.Tasks; +using Xunit; + +/// +/// Unit tests for . +/// +[ExcludeFromCodeCoverage] +public class PreDeploymentAttributeTests : AttributeTestsBase +{ + /// + /// Tests the case of methods with . + /// + [Fact] + [PreDeployment] + public async Task PreDeployment_Expected() + { + var traits = GetTraits(); + + _ = await Verify(traits); + } +} diff --git a/tests/NetEvolve.Extensions.XUnit.V3.Tests.Unit/Predefined.cs b/tests/NetEvolve.Extensions.XUnit.V3.Tests.Unit/Predefined.cs new file mode 100644 index 0000000..5218ea9 --- /dev/null +++ b/tests/NetEvolve.Extensions.XUnit.V3.Tests.Unit/Predefined.cs @@ -0,0 +1,30 @@ +namespace NetEvolve.Extensions.XUnit.V3.Tests.Unit; + +using System.IO; +using System.Runtime.CompilerServices; +using VerifyTests; +using VerifyXunit; + +internal static class Predefined +{ + [ModuleInitializer] + public static void Init() + { + Verifier.DerivePathInfo( + (sourceFile, projectDirectory, type, method) => + { + var directory = Path.Combine( + projectDirectory, + "..", + "_snapshots", + Namer.TargetFrameworkNameAndVersion + ); + _ = Directory.CreateDirectory(directory); + return new(directory, type.Name, method.Name); + } + ); + + VerifierSettings.SortPropertiesAlphabetically(); + VerifierSettings.SortJsonObjects(); + } +} diff --git a/tests/NetEvolve.Extensions.XUnit.V3.Tests.Unit/SetCultureAttributeTests.cs b/tests/NetEvolve.Extensions.XUnit.V3.Tests.Unit/SetCultureAttributeTests.cs new file mode 100644 index 0000000..7117037 --- /dev/null +++ b/tests/NetEvolve.Extensions.XUnit.V3.Tests.Unit/SetCultureAttributeTests.cs @@ -0,0 +1,64 @@ +namespace NetEvolve.Extensions.XUnit.V3.Tests.Unit; + +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using System.Threading.Tasks; +using Xunit; + +[ExcludeFromCodeCoverage] +public class SetCultureAttributeTests : AttributeTestsBase +{ + [Fact] + [SetCulture("en")] + public async Task Execute_English() + { + var traits = GetTraits(); + var translations = new Dictionary(StringComparer.OrdinalIgnoreCase) + { + { "Translation", Translations.HelloWorld }, + }; + + _ = await Verify(traits.Union(translations)); + } + + [Fact] + [SetCulture] + public async Task Execute_Invariant() + { + var traits = GetTraits(); + var translations = new Dictionary(StringComparer.OrdinalIgnoreCase) + { + { "Translation", Translations.HelloWorld }, + }; + + _ = await Verify(traits.Union(translations)); + } + + [Fact] + [SetCulture("de")] + public async Task Execute_German() + { + var traits = GetTraits(); + var translations = new Dictionary(StringComparer.OrdinalIgnoreCase) + { + { "Translation", Translations.HelloWorld }, + }; + + _ = await Verify(traits.Union(translations)); + } + + [Fact] + [SetCulture("de-DE")] + public async Task Execute_German_Germany() + { + var traits = GetTraits(); + var translations = new Dictionary(StringComparer.OrdinalIgnoreCase) + { + { "Translation", Translations.HelloWorld }, + }; + + _ = await Verify(traits.Union(translations)); + } +} diff --git a/tests/NetEvolve.Extensions.XUnit.V3.Tests.Unit/SetUICultureAttributeTests.cs b/tests/NetEvolve.Extensions.XUnit.V3.Tests.Unit/SetUICultureAttributeTests.cs new file mode 100644 index 0000000..f02c920 --- /dev/null +++ b/tests/NetEvolve.Extensions.XUnit.V3.Tests.Unit/SetUICultureAttributeTests.cs @@ -0,0 +1,64 @@ +namespace NetEvolve.Extensions.XUnit.V3.Tests.Unit; + +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using System.Threading.Tasks; +using Xunit; + +[ExcludeFromCodeCoverage] +public class SetUICultureAttributeTests : AttributeTestsBase +{ + [Fact(Skip = "Flaky, will deal with this later.")] + [SetUICulture("en")] + public async Task Execute_English() + { + var traits = GetTraits(); + var translations = new Dictionary(StringComparer.OrdinalIgnoreCase) + { + { "Translation", Translations.HelloWorld }, + }; + + _ = await Verify(traits.Union(translations)); + } + + [Fact] + [SetUICulture] + public async Task Execute_Invariant() + { + var traits = GetTraits(); + var translations = new Dictionary(StringComparer.OrdinalIgnoreCase) + { + { "Translation", Translations.HelloWorld }, + }; + + _ = await Verify(traits.Union(translations)); + } + + [Fact(Skip = "Flaky, will deal with this later.")] + [SetUICulture("de")] + public async Task Execute_German() + { + var traits = GetTraits(); + var translations = new Dictionary(StringComparer.OrdinalIgnoreCase) + { + { "Translation", Translations.HelloWorld }, + }; + + _ = await Verify(traits.Union(translations)); + } + + [Fact] + [SetUICulture("de-DE")] + public async Task Execute_German_Germany() + { + var traits = GetTraits(); + var translations = new Dictionary(StringComparer.OrdinalIgnoreCase) + { + { "Translation", Translations.HelloWorld }, + }; + + _ = await Verify(traits.Union(translations)); + } +} diff --git a/tests/NetEvolve.Extensions.XUnit.V3.Tests.Unit/Translations.Designer.cs b/tests/NetEvolve.Extensions.XUnit.V3.Tests.Unit/Translations.Designer.cs new file mode 100644 index 0000000..091ca67 --- /dev/null +++ b/tests/NetEvolve.Extensions.XUnit.V3.Tests.Unit/Translations.Designer.cs @@ -0,0 +1,72 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace NetEvolve.Extensions.XUnit.V3.Tests.Unit { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Translations { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Translations() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("NetEvolve.Extensions.XUnit.V3.Tests.Unit.Translations", typeof(Translations).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to Hello World!. + /// + internal static string HelloWorld { + get { + return ResourceManager.GetString("HelloWorld", resourceCulture); + } + } + } +} diff --git a/tests/NetEvolve.Extensions.XUnit.V3.Tests.Unit/Translations.de.resx b/tests/NetEvolve.Extensions.XUnit.V3.Tests.Unit/Translations.de.resx new file mode 100644 index 0000000..fd4242b --- /dev/null +++ b/tests/NetEvolve.Extensions.XUnit.V3.Tests.Unit/Translations.de.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Hallo Welt! + + \ No newline at end of file diff --git a/tests/NetEvolve.Extensions.XUnit.V3.Tests.Unit/Translations.resx b/tests/NetEvolve.Extensions.XUnit.V3.Tests.Unit/Translations.resx new file mode 100644 index 0000000..f36015b --- /dev/null +++ b/tests/NetEvolve.Extensions.XUnit.V3.Tests.Unit/Translations.resx @@ -0,0 +1,123 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Hello World! + + \ No newline at end of file diff --git a/tests/NetEvolve.Extensions.XUnit.V3.Tests.Unit/UnitTestAttributeTests.cs b/tests/NetEvolve.Extensions.XUnit.V3.Tests.Unit/UnitTestAttributeTests.cs new file mode 100644 index 0000000..f201a8f --- /dev/null +++ b/tests/NetEvolve.Extensions.XUnit.V3.Tests.Unit/UnitTestAttributeTests.cs @@ -0,0 +1,27 @@ +namespace NetEvolve.Extensions.XUnit.V3.Tests.Unit; + +using System; +using System.Diagnostics.CodeAnalysis; +using System.Threading.Tasks; +using Xunit; + +/// +/// Unit tests for . +/// +[ExcludeFromCodeCoverage] +public class UnitTestAttributeTests : AttributeTestsBase +{ + [Theory] + [UnitTest] + [InlineData(nameof(UnitTest_without_parameters))] + [InlineData(nameof(UnitTest_without_or_invalid_parameters))] + public async Task UnitTest_without_or_invalid_parameters(string methodName) + { + var traits = GetTraits(methodName); + + _ = await Verify(traits).UseParameters(methodName); + } + + [UnitTest] + protected void UnitTest_without_parameters() => throw new NotSupportedException(); +} diff --git a/tests/NetEvolve.Extensions.XUnit.V3.Tests.Unit/UserStoryAttributeTests.cs b/tests/NetEvolve.Extensions.XUnit.V3.Tests.Unit/UserStoryAttributeTests.cs new file mode 100644 index 0000000..3d94667 --- /dev/null +++ b/tests/NetEvolve.Extensions.XUnit.V3.Tests.Unit/UserStoryAttributeTests.cs @@ -0,0 +1,49 @@ +namespace NetEvolve.Extensions.XUnit.V3.Tests.Unit; + +using System.Diagnostics.CodeAnalysis; +using System.Threading.Tasks; +using Xunit; + +/// +/// Unit tests for . +/// +[ExcludeFromCodeCoverage] +public class UserStoryAttributeTests : AttributeTestsBase +{ + /// + /// Tests the case of methods with without additional information. + /// + [Fact] + [UserStory] + [UserStory("")] + public async Task UserStory_without_Id() + { + var traits = GetTraits(); + + _ = await Verify(traits); + } + + /// + /// Tests the case of methods with with numeric id. + /// + [Fact] + [UserStory(123456)] + public async Task UserStory_with_LongId() + { + var traits = GetTraits(); + + _ = await Verify(traits); + } + + /// + /// Tests the case of methods with with id. + /// + [Fact] + [UserStory("123456")] + public async Task UserStory_with_StringId() + { + var traits = GetTraits(); + + _ = await Verify(traits); + } +} diff --git a/tests/NetEvolve.Extensions.XUnit.V3.Tests.Unit/WorkItemAttributeTests.cs b/tests/NetEvolve.Extensions.XUnit.V3.Tests.Unit/WorkItemAttributeTests.cs new file mode 100644 index 0000000..8475d12 --- /dev/null +++ b/tests/NetEvolve.Extensions.XUnit.V3.Tests.Unit/WorkItemAttributeTests.cs @@ -0,0 +1,49 @@ +namespace NetEvolve.Extensions.XUnit.V3.Tests.Unit; + +using System.Diagnostics.CodeAnalysis; +using System.Threading.Tasks; +using Xunit; + +/// +/// Unit tests for . +/// +[ExcludeFromCodeCoverage] +public class WorkItemAttributeTests : AttributeTestsBase +{ + /// + /// Tests the case of methods with without additional information. + /// + [Fact] + [WorkItem] + [WorkItem("")] + public async Task WorkItem_without_Id() + { + var traits = GetTraits(); + + _ = await Verify(traits); + } + + /// + /// Tests the case of methods with with numeric id. + /// + [Fact] + [WorkItem(123456)] + public async Task WorkItem_with_LongId() + { + var traits = GetTraits(); + + _ = await Verify(traits); + } + + /// + /// Tests the case of methods with with numeric id. + /// + [Fact] + [WorkItem("123456")] + public async Task WorkItem_with_StringId() + { + var traits = GetTraits(); + + _ = await Verify(traits); + } +}