Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.Windows.ApplicationModel.Resources;
using Microsoft.Windows.Globalization;
#else
using System;
using System.ComponentModel;
Expand All @@ -18,6 +19,7 @@
using WEX.TestExecution;
using WEX.TestExecution.Markup;
using Microsoft.Windows.ApplicationModel.Resources;
using Microsoft.Windows.Globalization;
#endif

namespace CommonTestCode
Expand Down Expand Up @@ -585,4 +587,23 @@ public static void NoResourceFileWithContextTest()
Verify.IsNull(resourceCandidate);
}
}

public class ApplicationLanguagesTest
{
public static void PrimaryLanguageOverrideAcceptsEmptyStringTest()
{
ApplicationLanguages.PrimaryLanguageOverride = "fr-FR";
ApplicationLanguages.PrimaryLanguageOverride = "";

Verify.AreEqual(ApplicationLanguages.PrimaryLanguageOverride, "");
Copy link
Contributor

Choose a reason for hiding this comment

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

consider adding a verification that winrt::Windows::Globalization::ApplicationLanguages::PrimaryLanguageOverride is reset for packaged process, as that's what matters.

Copy link
Author

Choose a reason for hiding this comment

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

Thanks! I've added a test

}

public static void PrimaryLanguageOverrideAcceptsNullStringTest()
{
ApplicationLanguages.PrimaryLanguageOverride = "fr-FR";
ApplicationLanguages.PrimaryLanguageOverride = null;

Verify.AreEqual(ApplicationLanguages.PrimaryLanguageOverride, ""); // C# projection of null HSTRING is empty string
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

The tests are added under CommonTestCode. But they don't work for unpackaged test. Ideally they need to be moved to unittests.cs, or add a packaged check.

Copy link
Author

Choose a reason for hiding this comment

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

True, I moved the test code over

}
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ namespace winrt::Microsoft::Windows::Globalization::implementation

void ApplicationLanguages::PrimaryLanguageOverride(hstring const& language)
{
bool isValidLanguageTag = IsWellFormedTag(language.c_str());
bool isValidLanguageTag = language.empty() || IsWellFormedTag(language.c_str());
Copy link
Contributor

Choose a reason for hiding this comment

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

my impression is that winrt::Windows::Globalization::ApplicationLanguages::PrimaryLanguageOverride(language) requires nullptr to reset PrimaryLanguageOverride. Have you verified that the test reached line 53?

Copy link
Author

Choose a reason for hiding this comment

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

In WinRT, an empty HSTRING is equivalent to a nullptr (https://devblogs.microsoft.com/oldnewthing/20160615-00/?p=93675).

So, windows::Globalization::ApplicationLanguages::PrimaryLanguageOverride does accept both nullptr/null and empty string.

Copy link
Author

Choose a reason for hiding this comment

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

Also, it doesn't seem possible for externals to build anything from the Windows App SDK due to missing permissions for the ProjectReunion internal NuGet source. So I was only able to test in my own app.

Copy link
Contributor

Choose a reason for hiding this comment

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

I checked the implementation of winrt::Windows::Globalization::ApplicationLanguages::PrimaryLanguageOverride(language) in OS, and it will reset the override when null is passed in, and fail if empty string is passed in.

Copy link
Author

Choose a reason for hiding this comment

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

In C++/WinRT it is impossible to compare a winrt::hstring to nullptr - the equality operator is explicitly deleted: bool operator==(hstring const& left, std::nullptr_t) = delete;
This is exactly because an empty HSTRING is always represented by a null pointer internally. Please see the blog post by Raymond Chen: https://devblogs.microsoft.com/oldnewthing/20220706-00/?p=106836

Maybe the OS code is not written in C++WinRT and is therefore able to compare with nullptr, but code with C++/WinRT cannot do that.

In C#, WG.ApplicationLanguages.PrimaryLanguageOverride = null; and WG.ApplicationLanguages.PrimaryLanguageOverride = ""; will also both work. You can try in a test app.

Copy link
Contributor

Choose a reason for hiding this comment

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

OS implementation doesn't use C++/WinRT. I assume it works because eventually nullptr is passed to it.


THROW_HR_IF_MSG(E_INVALIDARG, !isValidLanguageTag, "The parameter is incorrect");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

using System;
using Microsoft.Windows.ApplicationModel.Resources;
using Microsoft.Windows.Globalization;
using WEX.Common.Managed;
using WEX.Logging.Interop;
using WEX.TestExecution;
Expand Down Expand Up @@ -165,4 +166,30 @@ public void NoResourceFileWithContextTest()
CommonTestCode.ResourceContextTest.NoResourceFileWithContextTest();
}
}

[TestClass]
public class ApplicationLanguagesTest
{
[TestMethod]
public void PrimaryLanguageOverrideAcceptsEmptyStringTest()
{
CommonTestCode.ApplicationLanguagesTest.PrimaryLanguageOverrideAcceptsEmptyStringTest();
}

[TestMethod]
public void PrimaryLanguageOverrideAcceptsNullStringTest()
{
CommonTestCode.ApplicationLanguagesTest.PrimaryLanguageOverrideAcceptsNullStringTest();
}

[TestMethod]
public void PrimaryLanguageOverrideSetsWindowsValueTest()
{
ApplicationLanguages.PrimaryLanguageOverride = "fr-FR";
Verify.AreEqual(Windows.Globalization.ApplicationLanguages.PrimaryLanguageOverride, "fr-FR");

ApplicationLanguages.PrimaryLanguageOverride = null;
Verify.AreEqual(Windows.Globalization.ApplicationLanguages.PrimaryLanguageOverride, ""); // C# projection of null HSTRING is empty string
}
}
}