Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PROTOTYPE] Implement TestCultureAttribute #4055

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/Adapter/MSTest.TestAdapter/Execution/TestMethodInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ internal TestMethodInfo(
TestMethod = testMethod;
Parent = parent;
TestMethodOptions = testMethodOptions;
TestCultureName = GetAttributes<TestCultureAttribute>(inherit: false).FirstOrDefault()?.CultureName;
}

/// <summary>
Expand Down Expand Up @@ -87,6 +88,8 @@ internal TestMethodInfo(
/// </summary>
internal TestMethodOptions TestMethodOptions { get; }

internal string? TestCultureName { get; }

public Attribute[]? GetAllAttributes(bool inherit) => ReflectHelper.Instance.GetDerivedAttributes<Attribute>(TestMethod, inherit).ToArray();

public TAttributeType[] GetAttributes<TAttributeType>(bool inherit)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,13 @@ public override TestResult[] Execute(ITestMethod testMethod)
TestResult? result = null;
Windows.ApplicationModel.Core.CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(
Windows.UI.Core.CoreDispatcherPriority.Normal,
() => result = testMethod.Invoke(null)).AsTask().GetAwaiter().GetResult();
() =>
{
using (SetCultureForTest(testMethod))
{
result = testMethod.Invoke(null);
}
}).AsTask().GetAwaiter().GetResult();

return [result!];
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

namespace Microsoft.VisualStudio.TestTools.UnitTesting;

/// <summary>
/// Attribute to specify the CultureInfo.CurrentCulture and CultureInfo.CurrentUICulture when running the test.
/// </summary>
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
public sealed class TestCultureAttribute : Attribute
{
/// <summary>
/// Initializes a new instance of the <see cref="TestCultureAttribute"/> class.
/// </summary>
/// <param name="cultureName">
/// The culture to be used for the test. For example, "en-US".
/// </param>
public TestCultureAttribute(string cultureName) => CultureName = cultureName;

/// <summary>
/// Gets the owner.
/// </summary>
public string CultureName { get; }
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System.Globalization;

namespace Microsoft.VisualStudio.TestTools.UnitTesting;

/// <summary>
Expand All @@ -9,6 +11,29 @@
[AttributeUsage(AttributeTargets.Method)]
public class TestMethodAttribute : Attribute
{
private protected readonly struct ScopedCultureDisposable : IDisposable
{
private readonly CultureInfo _previousCulture;
private readonly CultureInfo _previousUICulture;

public ScopedCultureDisposable(string cultureName)
{
_previousCulture = CultureInfo.CurrentCulture;
_previousUICulture = CultureInfo.CurrentUICulture;

var newCulture = new CultureInfo(cultureName);
// TODO: Should we set both? Should we have different attribute? Same attribute with two arguments?
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs to be discussed first.

CultureInfo.CurrentCulture = newCulture;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Important consideration: Validate if that approach is going to work well for tests running in parallel

CultureInfo.CurrentUICulture = newCulture;
}

public void Dispose()
{
CultureInfo.CurrentCulture = _previousCulture;
CultureInfo.CurrentUICulture = _previousUICulture;
}
}

/// <summary>
/// Initializes a new instance of the <see cref="TestMethodAttribute"/> class.
/// </summary>
Expand Down Expand Up @@ -36,5 +61,19 @@
/// <param name="testMethod">The test method to execute.</param>
/// <returns>An array of TestResult objects that represent the outcome(s) of the test.</returns>
/// <remarks>Extensions can override this method to customize running a TestMethod.</remarks>
public virtual TestResult[] Execute(ITestMethod testMethod) => [testMethod.Invoke(null)];
public virtual TestResult[] Execute(ITestMethod testMethod)
{
using (SetCultureForTest(testMethod))
{
return [testMethod.Invoke(null)];
}
}

// TestMethodInfo isn't accessible here :/
// Can we add TestCultureName to the *public* interface?
// Or should we introduce an internal interface ITestMethod2 : ITestMethod :/
Comment on lines +72 to +74
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

private protected static ScopedCultureDisposable? SetCultureForTest(ITestMethod testMethod)
=> testMethod is TestMethodInfo testMethodInfo && testMethodInfo.TestCultureName is { } culture

Check failure on line 76 in src/TestFramework/TestFramework/Attributes/TestMethod/TestMethodAttribute.cs

View check run for this annotation

Azure Pipelines / microsoft.testfx (Build Linux Release)

src/TestFramework/TestFramework/Attributes/TestMethod/TestMethodAttribute.cs#L76

src/TestFramework/TestFramework/Attributes/TestMethod/TestMethodAttribute.cs(76,26): error CS0246: (NETCORE_ENGINEERING_TELEMETRY=Build) The type or namespace name 'TestMethodInfo' could not be found (are you missing a using directive or an assembly reference?)

Check failure on line 76 in src/TestFramework/TestFramework/Attributes/TestMethod/TestMethodAttribute.cs

View check run for this annotation

Azure Pipelines / microsoft.testfx (Build Linux Release)

src/TestFramework/TestFramework/Attributes/TestMethod/TestMethodAttribute.cs#L76

src/TestFramework/TestFramework/Attributes/TestMethod/TestMethodAttribute.cs(76,26): error CS0246: (NETCORE_ENGINEERING_TELEMETRY=Build) The type or namespace name 'TestMethodInfo' could not be found (are you missing a using directive or an assembly reference?)

Check failure on line 76 in src/TestFramework/TestFramework/Attributes/TestMethod/TestMethodAttribute.cs

View check run for this annotation

Azure Pipelines / microsoft.testfx (Build Linux Release)

src/TestFramework/TestFramework/Attributes/TestMethod/TestMethodAttribute.cs#L76

src/TestFramework/TestFramework/Attributes/TestMethod/TestMethodAttribute.cs(76,26): error CS0246: (NETCORE_ENGINEERING_TELEMETRY=Build) The type or namespace name 'TestMethodInfo' could not be found (are you missing a using directive or an assembly reference?)

Check failure on line 76 in src/TestFramework/TestFramework/Attributes/TestMethod/TestMethodAttribute.cs

View check run for this annotation

Azure Pipelines / microsoft.testfx (Build Linux Release)

src/TestFramework/TestFramework/Attributes/TestMethod/TestMethodAttribute.cs#L76

src/TestFramework/TestFramework/Attributes/TestMethod/TestMethodAttribute.cs(76,26): error CS0246: (NETCORE_ENGINEERING_TELEMETRY=Build) The type or namespace name 'TestMethodInfo' could not be found (are you missing a using directive or an assembly reference?)

Check failure on line 76 in src/TestFramework/TestFramework/Attributes/TestMethod/TestMethodAttribute.cs

View check run for this annotation

Azure Pipelines / microsoft.testfx (Build Linux Release)

src/TestFramework/TestFramework/Attributes/TestMethod/TestMethodAttribute.cs#L76

src/TestFramework/TestFramework/Attributes/TestMethod/TestMethodAttribute.cs(76,26): error CS0246: (NETCORE_ENGINEERING_TELEMETRY=Build) The type or namespace name 'TestMethodInfo' could not be found (are you missing a using directive or an assembly reference?)

Check failure on line 76 in src/TestFramework/TestFramework/Attributes/TestMethod/TestMethodAttribute.cs

View check run for this annotation

Azure Pipelines / microsoft.testfx (Build Linux Debug)

src/TestFramework/TestFramework/Attributes/TestMethod/TestMethodAttribute.cs#L76

src/TestFramework/TestFramework/Attributes/TestMethod/TestMethodAttribute.cs(76,26): error CS0246: (NETCORE_ENGINEERING_TELEMETRY=Build) The type or namespace name 'TestMethodInfo' could not be found (are you missing a using directive or an assembly reference?)

Check failure on line 76 in src/TestFramework/TestFramework/Attributes/TestMethod/TestMethodAttribute.cs

View check run for this annotation

Azure Pipelines / microsoft.testfx (Build Linux Debug)

src/TestFramework/TestFramework/Attributes/TestMethod/TestMethodAttribute.cs#L76

src/TestFramework/TestFramework/Attributes/TestMethod/TestMethodAttribute.cs(76,26): error CS0246: (NETCORE_ENGINEERING_TELEMETRY=Build) The type or namespace name 'TestMethodInfo' could not be found (are you missing a using directive or an assembly reference?)

Check failure on line 76 in src/TestFramework/TestFramework/Attributes/TestMethod/TestMethodAttribute.cs

View check run for this annotation

Azure Pipelines / microsoft.testfx (Build Linux Debug)

src/TestFramework/TestFramework/Attributes/TestMethod/TestMethodAttribute.cs#L76

src/TestFramework/TestFramework/Attributes/TestMethod/TestMethodAttribute.cs(76,26): error CS0246: (NETCORE_ENGINEERING_TELEMETRY=Build) The type or namespace name 'TestMethodInfo' could not be found (are you missing a using directive or an assembly reference?)

Check failure on line 76 in src/TestFramework/TestFramework/Attributes/TestMethod/TestMethodAttribute.cs

View check run for this annotation

Azure Pipelines / microsoft.testfx (Build Linux Debug)

src/TestFramework/TestFramework/Attributes/TestMethod/TestMethodAttribute.cs#L76

src/TestFramework/TestFramework/Attributes/TestMethod/TestMethodAttribute.cs(76,26): error CS0246: (NETCORE_ENGINEERING_TELEMETRY=Build) The type or namespace name 'TestMethodInfo' could not be found (are you missing a using directive or an assembly reference?)

Check failure on line 76 in src/TestFramework/TestFramework/Attributes/TestMethod/TestMethodAttribute.cs

View check run for this annotation

Azure Pipelines / microsoft.testfx (Build Linux Debug)

src/TestFramework/TestFramework/Attributes/TestMethod/TestMethodAttribute.cs#L76

src/TestFramework/TestFramework/Attributes/TestMethod/TestMethodAttribute.cs(76,26): error CS0246: (NETCORE_ENGINEERING_TELEMETRY=Build) The type or namespace name 'TestMethodInfo' could not be found (are you missing a using directive or an assembly reference?)

Check failure on line 76 in src/TestFramework/TestFramework/Attributes/TestMethod/TestMethodAttribute.cs

View check run for this annotation

Azure Pipelines / microsoft.testfx

src/TestFramework/TestFramework/Attributes/TestMethod/TestMethodAttribute.cs#L76

src/TestFramework/TestFramework/Attributes/TestMethod/TestMethodAttribute.cs(76,26): error CS0246: (NETCORE_ENGINEERING_TELEMETRY=Build) The type or namespace name 'TestMethodInfo' could not be found (are you missing a using directive or an assembly reference?)

Check failure on line 76 in src/TestFramework/TestFramework/Attributes/TestMethod/TestMethodAttribute.cs

View check run for this annotation

Azure Pipelines / microsoft.testfx

src/TestFramework/TestFramework/Attributes/TestMethod/TestMethodAttribute.cs#L76

src/TestFramework/TestFramework/Attributes/TestMethod/TestMethodAttribute.cs(76,26): error CS0246: (NETCORE_ENGINEERING_TELEMETRY=Build) The type or namespace name 'TestMethodInfo' could not be found (are you missing a using directive or an assembly reference?)

Check failure on line 76 in src/TestFramework/TestFramework/Attributes/TestMethod/TestMethodAttribute.cs

View check run for this annotation

Azure Pipelines / microsoft.testfx

src/TestFramework/TestFramework/Attributes/TestMethod/TestMethodAttribute.cs#L76

src/TestFramework/TestFramework/Attributes/TestMethod/TestMethodAttribute.cs(76,26): error CS0246: (NETCORE_ENGINEERING_TELEMETRY=Build) The type or namespace name 'TestMethodInfo' could not be found (are you missing a using directive or an assembly reference?)

Check failure on line 76 in src/TestFramework/TestFramework/Attributes/TestMethod/TestMethodAttribute.cs

View check run for this annotation

Azure Pipelines / microsoft.testfx

src/TestFramework/TestFramework/Attributes/TestMethod/TestMethodAttribute.cs#L76

src/TestFramework/TestFramework/Attributes/TestMethod/TestMethodAttribute.cs(76,26): error CS0246: (NETCORE_ENGINEERING_TELEMETRY=Build) The type or namespace name 'TestMethodInfo' could not be found (are you missing a using directive or an assembly reference?)
? new ScopedCultureDisposable(culture)
: (ScopedCultureDisposable?)null;
}
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
#nullable enable
Microsoft.VisualStudio.TestTools.UnitTesting.TestCultureAttribute
Microsoft.VisualStudio.TestTools.UnitTesting.TestCultureAttribute.CultureName.get -> string!
Microsoft.VisualStudio.TestTools.UnitTesting.TestCultureAttribute.TestCultureAttribute(string! cultureName) -> void
Loading