Fix unit tests to run on non-english devices (#289)

* Force en-US for unit tests

* fix some spacing issues after merge

* remove default argument of LocalizationService to fix compilation issue in Release mode
This commit is contained in:
Rudy Huyn
2019-05-14 09:57:58 -07:00
committed by Stephanie Anderl
parent 860d6d3eb2
commit 9f47fe3fc8
11 changed files with 106 additions and 68 deletions

View File

@@ -1,4 +1,4 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
#include "pch.h"
@@ -49,17 +49,34 @@ LocalizationService ^ LocalizationService::GetInstance()
if (s_singletonInstance == nullptr)
{
s_singletonInstance = ref new LocalizationService();
s_singletonInstance = ref new LocalizationService(nullptr);
}
}
return s_singletonInstance;
}
LocalizationService::LocalizationService()
/// <summary>
/// Replace (or create) the single instance of this singleton class by one with the language passed as parameter
/// </summary>
/// <param name="language">RFC-5646 identifier of the language to use</param>
/// <remarks>
/// Should only be used for test purpose
/// </remarks>
void LocalizationService::OverrideWithLanguage(_In_ const wchar_t * const language)
{
m_language = ApplicationLanguages::Languages->GetAt(0);
m_flowDirection =
ResourceContext::GetForCurrentView()->QualifierValues->Lookup(L"LayoutDirection") != L"LTR" ? FlowDirection::RightToLeft : FlowDirection::LeftToRight;
s_singletonInstance = ref new LocalizationService(language);
}
/// <summary>
/// Constructor
/// </summary>
/// <param name="overridedLanguage">RFC-5646 identifier of the language to use, if null, will use the current language of the system</param>
LocalizationService::LocalizationService(_In_ const wchar_t * const overridedLanguage)
{
m_isLanguageOverrided = overridedLanguage != nullptr;
m_language = m_isLanguageOverrided ? ref new Platform::String(overridedLanguage) : ApplicationLanguages::Languages->GetAt(0);
m_flowDirection = ResourceContext::GetForCurrentView()->QualifierValues->Lookup(L"LayoutDirection")
!= L"LTR" ? FlowDirection::RightToLeft : FlowDirection::LeftToRight;
auto resourceLoader = AppResourceProvider::GetInstance();
m_fontFamilyOverride = resourceLoader.GetResourceString(L"LocalizedFontFamilyOverride");
@@ -339,7 +356,7 @@ void LocalizationService::UpdateFontFamilyAndSize(DependencyObject ^ target)
// If successful, returns a formatter that respects the user's regional format settings,
// as configured by running intl.cpl.
DecimalFormatter ^ LocalizationService::GetRegionalSettingsAwareDecimalFormatter()
DecimalFormatter ^ LocalizationService::GetRegionalSettingsAwareDecimalFormatter() const
{
IIterable<String ^> ^ languageIdentifiers = LocalizationService::GetLanguageIdentifiers();
if (languageIdentifiers != nullptr)
@@ -354,7 +371,7 @@ DecimalFormatter ^ LocalizationService::GetRegionalSettingsAwareDecimalFormatter
// as configured by running intl.cpl.
//
// This helper function creates a DateTimeFormatter with a TwentyFour hour clock
DateTimeFormatter ^ LocalizationService::GetRegionalSettingsAwareDateTimeFormatter(_In_ String ^ format)
DateTimeFormatter ^ LocalizationService::GetRegionalSettingsAwareDateTimeFormatter(_In_ String^ format) const
{
IIterable<String ^> ^ languageIdentifiers = LocalizationService::GetLanguageIdentifiers();
if (languageIdentifiers == nullptr)
@@ -367,8 +384,7 @@ DateTimeFormatter ^ LocalizationService::GetRegionalSettingsAwareDateTimeFormatt
// If successful, returns a formatter that respects the user's regional format settings,
// as configured by running intl.cpl.
DateTimeFormatter
^ LocalizationService::GetRegionalSettingsAwareDateTimeFormatter(_In_ String ^ format, _In_ String ^ calendarIdentifier, _In_ String ^ clockIdentifier)
DateTimeFormatter^ LocalizationService::GetRegionalSettingsAwareDateTimeFormatter(_In_ String ^ format, _In_ String ^ calendarIdentifier, _In_ String ^ clockIdentifier) const
{
IIterable<String ^> ^ languageIdentifiers = LocalizationService::GetLanguageIdentifiers();
if (languageIdentifiers == nullptr)
@@ -379,12 +395,12 @@ DateTimeFormatter
return ref new DateTimeFormatter(format, languageIdentifiers, GlobalizationPreferences::HomeGeographicRegion, calendarIdentifier, clockIdentifier);
}
CurrencyFormatter ^ LocalizationService::GetRegionalSettingsAwareCurrencyFormatter()
CurrencyFormatter ^ LocalizationService::GetRegionalSettingsAwareCurrencyFormatter() const
{
String ^ userCurrency =
(GlobalizationPreferences::Currencies->Size > 0) ? GlobalizationPreferences::Currencies->GetAt(0) : StringReference(DefaultCurrencyCode.data());
IIterable<String ^> ^ languageIdentifiers = LocalizationService::GetLanguageIdentifiers();
IIterable<String ^> ^ languageIdentifiers = GetLanguageIdentifiers();
if (languageIdentifiers == nullptr)
{
languageIdentifiers = ApplicationLanguages::Languages;
@@ -398,10 +414,18 @@ CurrencyFormatter ^ LocalizationService::GetRegionalSettingsAwareCurrencyFormatt
return currencyFormatter;
}
IIterable<String ^> ^ LocalizationService::GetLanguageIdentifiers()
IIterable<String ^> ^ LocalizationService::GetLanguageIdentifiers() const
{
WCHAR currentLocale[LOCALE_NAME_MAX_LENGTH] = {};
int result = GetUserDefaultLocaleName(currentLocale, LOCALE_NAME_MAX_LENGTH);
if (m_isLanguageOverrided)
{
auto overridedLanguageList = ref new Vector<String^>();
overridedLanguageList->Append(m_language);
return overridedLanguageList;
}
if (result != 0)
{
// GetUserDefaultLocaleName may return an invalid bcp47 language tag with trailing non-BCP47 friendly characters,

View File

@@ -30,7 +30,9 @@ namespace CalculatorApp
DEPENDENCY_PROPERTY_ATTACHED_WITH_DEFAULT_AND_CALLBACK(LanguageFontType, FontType, LanguageFontType::UIText);
DEPENDENCY_PROPERTY_ATTACHED_WITH_CALLBACK(double, FontSize);
internal : static LocalizationService ^ GetInstance();
internal:
static LocalizationService^ GetInstance();
static void OverrideWithLanguage(_In_ const wchar_t * const language);
Windows::UI::Xaml::FlowDirection GetFlowDirection();
bool IsRtlLayout();
@@ -41,24 +43,24 @@ namespace CalculatorApp
Windows::UI::Text::FontWeight GetFontWeightOverride();
double GetFontScaleFactorOverride(LanguageFontType fontType);
static Windows::Globalization::NumberFormatting::DecimalFormatter ^ GetRegionalSettingsAwareDecimalFormatter();
static Windows::Globalization::DateTimeFormatting::DateTimeFormatter ^ GetRegionalSettingsAwareDateTimeFormatter(_In_ Platform::String ^ format);
static Windows::Globalization::DateTimeFormatting::DateTimeFormatter
^ GetRegionalSettingsAwareDateTimeFormatter(
_In_ Platform::String ^ format,
_In_ Platform::String ^ calendarIdentifier,
_In_ Platform::String ^ clockIdentifier);
Windows::Globalization::NumberFormatting::DecimalFormatter ^ GetRegionalSettingsAwareDecimalFormatter() const;
Windows::Globalization::DateTimeFormatting::DateTimeFormatter ^ GetRegionalSettingsAwareDateTimeFormatter(_In_ Platform::String ^ format) const;
Windows::Globalization::DateTimeFormatting::DateTimeFormatter ^ GetRegionalSettingsAwareDateTimeFormatter(
_In_ Platform::String ^ format,
_In_ Platform::String ^ calendarIdentifier,
_In_ Platform::String ^ clockIdentifier) const;
static Windows::Globalization::NumberFormatting::CurrencyFormatter ^ GetRegionalSettingsAwareCurrencyFormatter();
Windows::Globalization::NumberFormatting::CurrencyFormatter ^ GetRegionalSettingsAwareCurrencyFormatter() const;
static Platform::String ^ GetNarratorReadableToken(Platform::String ^ rawToken);
static Platform::String ^ GetNarratorReadableString(Platform::String ^ rawString);
private:
LocalizationService(_In_ const wchar_t* const overridedLanguage);
Windows::Globalization::Fonts::LanguageFont ^ GetLanguageFont(LanguageFontType fontType);
Windows::UI::Text::FontWeight ParseFontWeight(Platform::String ^ fontWeight);
static Windows::Foundation::Collections::IIterable<Platform::String ^> ^ GetLanguageIdentifiers();
Windows::Foundation::Collections::IIterable<Platform::String ^> ^ GetLanguageIdentifiers() const;
// Attached property callbacks
static void OnFontTypePropertyChanged(Windows::UI::Xaml::DependencyObject ^ target, LanguageFontType oldValue, LanguageFontType newValue);
@@ -72,19 +74,17 @@ namespace CalculatorApp
static std::unordered_map<std::wstring, std::wstring> GetTokenToReadableNameMap();
private:
LocalizationService();
static LocalizationService ^ s_singletonInstance;
Windows::Globalization::Fonts::LanguageFontGroup ^ m_fontGroup;
Platform::String ^ m_language;
Windows::UI::Xaml::FlowDirection m_flowDirection;
bool m_overrideFontApiValues;
Platform::String ^ m_fontFamilyOverride;
Windows::UI::Text::FontWeight m_fontWeightOverride;
double m_uiTextFontScaleFactorOverride;
double m_uiCaptionFontScaleFactorOverride;
Windows::Globalization::Fonts::LanguageFontGroup ^ m_fontGroup;
Platform::String ^ m_language;
Windows::UI::Xaml::FlowDirection m_flowDirection;
bool m_overrideFontApiValues;
Platform::String ^ m_fontFamilyOverride;
bool m_isLanguageOverrided;
Windows::UI::Text::FontWeight m_fontWeightOverride;
double m_uiTextFontScaleFactorOverride;
double m_uiCaptionFontScaleFactorOverride;
};
}

View File

@@ -19,7 +19,7 @@ namespace CalculatorApp
// Use DecimalFormatter as it respects the locale and the user setting
Windows::Globalization::NumberFormatting::DecimalFormatter ^ formatter;
formatter = CalculatorApp::Common::LocalizationService::GetRegionalSettingsAwareDecimalFormatter();
formatter = LocalizationService::GetInstance()->GetRegionalSettingsAwareDecimalFormatter();
formatter->FractionDigits = 0;
formatter->IsDecimalPointAlwaysDisplayed = false;
@@ -61,7 +61,7 @@ namespace CalculatorApp
// Get locale info for List Separator, eg. comma is used in many locales
wchar_t listSeparatorString[4] = L"";
result = ::GetLocaleInfoEx(
LOCALE_NAME_USER_DEFAULT,
m_resolvedName.c_str(),
LOCALE_SLIST,
listSeparatorString,
static_cast<int>(std::size(listSeparatorString))); // Max length of the expected return value is 4
@@ -85,7 +85,7 @@ namespace CalculatorApp
// A value of 0 indicates the symbol follows the currency value.
int currencySymbolPrecedence = 1;
result = GetLocaleInfoEx(
LOCALE_NAME_USER_DEFAULT,
m_resolvedName.c_str(),
LOCALE_IPOSSYMPRECEDES | LOCALE_RETURN_NUMBER,
(LPWSTR)&currencySymbolPrecedence,
sizeof(currencySymbolPrecedence) / sizeof(WCHAR));
@@ -104,14 +104,14 @@ namespace CalculatorApp
// Note: This function returns 0 on failure.
// We'll ignore the failure in that case and the CalendarIdentifier would get set to GregorianCalendar.
CALID calId;
::GetLocaleInfoEx(LOCALE_NAME_USER_DEFAULT, LOCALE_ICALENDARTYPE | LOCALE_RETURN_NUMBER, reinterpret_cast<PWSTR>(&calId), sizeof(calId));
::GetLocaleInfoEx(m_resolvedName.c_str(), LOCALE_ICALENDARTYPE | LOCALE_RETURN_NUMBER, reinterpret_cast<PWSTR>(&calId), sizeof(calId));
m_calendarIdentifier = GetCalendarIdentifierFromCalid(calId);
// Get FirstDayOfWeek Date and Time setting
wchar_t day[80] = L"";
::GetLocaleInfoEx(
LOCALE_NAME_USER_DEFAULT,
m_resolvedName.c_str(),
LOCALE_IFIRSTDAYOFWEEK, // The first day in a week
reinterpret_cast<PWSTR>(day), // Argument is of type PWSTR
static_cast<int>(std::size(day))); // Max return size are 80 characters

View File

@@ -87,7 +87,7 @@ namespace CalculatorApp
}
}
CurrencyDataLoader::CurrencyDataLoader(_In_ unique_ptr<ICurrencyHttpClient> client)
CurrencyDataLoader::CurrencyDataLoader(_In_ unique_ptr<ICurrencyHttpClient> client, const wchar_t * forcedResponseLanguage)
: m_client(move(client))
, m_loadStatus(CurrencyLoadStatus::NotLoaded)
, m_responseLanguage(L"en-US")
@@ -96,9 +96,20 @@ CurrencyDataLoader::CurrencyDataLoader(_In_ unique_ptr<ICurrencyHttpClient> clie
, m_networkManager(ref new NetworkManager())
, m_meteredOverrideSet(false)
{
if (GlobalizationPreferences::Languages->Size > 0)
if (forcedResponseLanguage != nullptr)
{
m_responseLanguage = GlobalizationPreferences::Languages->GetAt(0);
m_responseLanguage = ref new Platform::String(forcedResponseLanguage);
}
else
{
if (GlobalizationPreferences::Languages->Size > 0)
{
m_responseLanguage = GlobalizationPreferences::Languages->GetAt(0);
}
else
{
m_responseLanguage = L"en-US";
}
}
if (m_client != nullptr)
@@ -107,13 +118,14 @@ CurrencyDataLoader::CurrencyDataLoader(_In_ unique_ptr<ICurrencyHttpClient> clie
m_client->SetResponseLanguage(m_responseLanguage);
}
auto localizationService = LocalizationService::GetInstance();
if (CoreWindow::GetForCurrentThread() != nullptr)
{
// Must have a CoreWindow to access the resource context.
m_isRtlLanguage = LocalizationService::GetInstance()->IsRtlLayout();
m_isRtlLanguage = localizationService->IsRtlLayout();
}
m_ratioFormatter = LocalizationService::GetRegionalSettingsAwareDecimalFormatter();
m_ratioFormatter = localizationService->GetRegionalSettingsAwareDecimalFormatter();
m_ratioFormatter->IsGrouped = true;
m_ratioFormatter->IsDecimalPointAlwaysDisplayed = true;
m_ratioFormatter->FractionDigits = FORMATTER_DIGIT_COUNT;

View File

@@ -54,7 +54,7 @@ namespace CalculatorApp
class CurrencyDataLoader : public UCM::IConverterDataLoader, public UCM::ICurrencyConverterDataLoader
{
public:
CurrencyDataLoader(_In_ std::unique_ptr<CalculatorApp::DataLoaders::ICurrencyHttpClient> client);
CurrencyDataLoader(_In_ std::unique_ptr<CalculatorApp::DataLoaders::ICurrencyHttpClient> client, const wchar_t* overrideLanguage = nullptr);
~CurrencyDataLoader();
bool LoadFinished();

View File

@@ -217,7 +217,7 @@ void DateCalculatorViewModel::UpdateStrDateResultAutomationName()
void DateCalculatorViewModel::InitializeDateOutputFormats(_In_ String ^ calendarIdentifier)
{
// Format for Add/Subtract days
m_dateTimeFormatter = LocalizationService::GetRegionalSettingsAwareDateTimeFormatter(
m_dateTimeFormatter = LocalizationService::GetInstance()->GetRegionalSettingsAwareDateTimeFormatter(
L"longdate",
calendarIdentifier,
ClockIdentifiers::TwentyFourHour); // Clock Identifier is not used

View File

@@ -122,14 +122,15 @@ UnitConverterViewModel::UnitConverterViewModel(const shared_ptr<UCM::IUnitConver
, m_isInputBlocked(false)
, m_CurrencyDataLoadFailed(false)
{
auto localizationService = LocalizationService::GetInstance();
m_model->SetViewModelCallback(make_shared<UnitConverterVMCallback>(this));
m_model->SetViewModelCurrencyCallback(make_shared<ViewModelCurrencyCallback>(this));
m_decimalFormatter = LocalizationService::GetRegionalSettingsAwareDecimalFormatter();
m_decimalFormatter = localizationService->GetRegionalSettingsAwareDecimalFormatter();
m_decimalFormatter->FractionDigits = 0;
m_decimalFormatter->IsGrouped = true;
m_decimalSeparator = LocalizationSettings::GetInstance().GetDecimalSeparator();
m_currencyFormatter = LocalizationService::GetRegionalSettingsAwareCurrencyFormatter();
m_currencyFormatter = localizationService->GetRegionalSettingsAwareCurrencyFormatter();
m_currencyFormatter->IsGrouped = true;
m_currencyFormatter->Mode = CurrencyFormatterMode::UseCurrencyCode;
m_currencyFormatter->ApplyRoundingForCurrency(RoundingAlgorithm::RoundHalfDown);