From 947db87217fcaa8b91cd23b9f03c935ee733cfeb Mon Sep 17 00:00:00 2001 From: hishamco Date: Fri, 6 Nov 2020 19:43:03 +0300 Subject: [PATCH 01/10] Introduce CultureScope --- .../Localization/CultureScope.cs | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 src/OrchardCore/OrchardCore.Abstractions/Localization/CultureScope.cs diff --git a/src/OrchardCore/OrchardCore.Abstractions/Localization/CultureScope.cs b/src/OrchardCore/OrchardCore.Abstractions/Localization/CultureScope.cs new file mode 100644 index 00000000000..33af772a286 --- /dev/null +++ b/src/OrchardCore/OrchardCore.Abstractions/Localization/CultureScope.cs @@ -0,0 +1,21 @@ +using System; +using System.Globalization; + +namespace OrchardCore.Localization +{ + public sealed class CultureScope : IDisposable + { + private readonly CultureInfo _currentCulture; + + public CultureScope(CultureInfo culture) + { + _currentCulture = culture; + CultureInfo.CurrentUICulture = culture; + } + + public void Dispose() + { + CultureInfo.CurrentUICulture = _currentCulture; + } + } +} From 1c953cfac9bcac475ea995ed57f25a5432595b97 Mon Sep 17 00:00:00 2001 From: hishamco Date: Fri, 6 Nov 2020 19:43:26 +0300 Subject: [PATCH 02/10] Use CultureScope in AutoroutePartHandler --- .../Handlers/AutoroutePartHandler.cs | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/OrchardCore.Modules/OrchardCore.Autoroute/Handlers/AutoroutePartHandler.cs b/src/OrchardCore.Modules/OrchardCore.Autoroute/Handlers/AutoroutePartHandler.cs index 503f73ed11d..2b731773026 100644 --- a/src/OrchardCore.Modules/OrchardCore.Autoroute/Handlers/AutoroutePartHandler.cs +++ b/src/OrchardCore.Modules/OrchardCore.Autoroute/Handlers/AutoroutePartHandler.cs @@ -21,6 +21,7 @@ using OrchardCore.DisplayManagement.Liquid; using OrchardCore.Environment.Cache; using OrchardCore.Liquid; +using OrchardCore.Localization; using OrchardCore.Settings; using YesSql; @@ -391,19 +392,16 @@ private async Task GenerateContainerPathFromPattern(AutoroutePart part) ContentItem = part.ContentItem }; - // We keep the current culture as a reference for later - var currentCulture = CultureInfo.CurrentUICulture; - - _contentManager ??= _serviceProvider.GetRequiredService(); - var cultureAspect = await _contentManager.PopulateAspectAsync(part.ContentItem, new CultureAspect()); - - CultureInfo.CurrentUICulture = cultureAspect.Culture; + using (var cultureScope = new CultureScope(CultureInfo.CurrentUICulture)) + { + _contentManager ??= _serviceProvider.GetRequiredService(); + var cultureAspect = await _contentManager.PopulateAspectAsync(part.ContentItem, new CultureAspect()); - part.Path = await _liquidTemplateManager.RenderAsync(pattern, NullEncoder.Default, model, - scope => scope.SetValue("ContentItem", model.ContentItem)); + CultureInfo.CurrentUICulture = cultureAspect.Culture; - // We reassign the proper culture to the current execution flow - CultureInfo.CurrentUICulture = currentCulture; + part.Path = await _liquidTemplateManager.RenderAsync(pattern, NullEncoder.Default, model, + scope => scope.SetValue("ContentItem", model.ContentItem)); + } part.Path = part.Path.Replace("\r", String.Empty).Replace("\n", String.Empty); From 878fb28ef5625522799370bf4d345c3a45167838 Mon Sep 17 00:00:00 2001 From: hishamco Date: Fri, 6 Nov 2020 19:51:24 +0300 Subject: [PATCH 03/10] Expose the previous culture --- .../OrchardCore.Abstractions/Localization/CultureScope.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/OrchardCore/OrchardCore.Abstractions/Localization/CultureScope.cs b/src/OrchardCore/OrchardCore.Abstractions/Localization/CultureScope.cs index 33af772a286..a493941031b 100644 --- a/src/OrchardCore/OrchardCore.Abstractions/Localization/CultureScope.cs +++ b/src/OrchardCore/OrchardCore.Abstractions/Localization/CultureScope.cs @@ -5,17 +5,17 @@ namespace OrchardCore.Localization { public sealed class CultureScope : IDisposable { - private readonly CultureInfo _currentCulture; - public CultureScope(CultureInfo culture) { - _currentCulture = culture; + Culture = culture; CultureInfo.CurrentUICulture = culture; } + public CultureInfo Culture { get; private set; } + public void Dispose() { - CultureInfo.CurrentUICulture = _currentCulture; + CultureInfo.CurrentUICulture = Culture; } } } From e65b78574d049bfb9275a47a52a0a91dccb6134f Mon Sep 17 00:00:00 2001 From: hishamco Date: Fri, 6 Nov 2020 23:17:12 +0300 Subject: [PATCH 04/10] Address feedback --- .../Handlers/AutoroutePartHandler.cs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/OrchardCore.Modules/OrchardCore.Autoroute/Handlers/AutoroutePartHandler.cs b/src/OrchardCore.Modules/OrchardCore.Autoroute/Handlers/AutoroutePartHandler.cs index 2b731773026..00f4c240b0b 100644 --- a/src/OrchardCore.Modules/OrchardCore.Autoroute/Handlers/AutoroutePartHandler.cs +++ b/src/OrchardCore.Modules/OrchardCore.Autoroute/Handlers/AutoroutePartHandler.cs @@ -392,13 +392,11 @@ private async Task GenerateContainerPathFromPattern(AutoroutePart part) ContentItem = part.ContentItem }; - using (var cultureScope = new CultureScope(CultureInfo.CurrentUICulture)) - { - _contentManager ??= _serviceProvider.GetRequiredService(); - var cultureAspect = await _contentManager.PopulateAspectAsync(part.ContentItem, new CultureAspect()); - - CultureInfo.CurrentUICulture = cultureAspect.Culture; + _contentManager ??= _serviceProvider.GetRequiredService(); + var cultureAspect = await _contentManager.PopulateAspectAsync(part.ContentItem, new CultureAspect()); + using (var cultureScope = new CultureScope(cultureAspect.Culture)) + { part.Path = await _liquidTemplateManager.RenderAsync(pattern, NullEncoder.Default, model, scope => scope.SetValue("ContentItem", model.ContentItem)); } From 791d93430807daa9e9576d471b95dd86171ed836 Mon Sep 17 00:00:00 2001 From: hishamco Date: Fri, 6 Nov 2020 23:24:58 +0300 Subject: [PATCH 05/10] Simplify the accessibility with Create --- .../OrchardCore.Autoroute/Handlers/AutoroutePartHandler.cs | 2 +- .../OrchardCore.Abstractions/Localization/CultureScope.cs | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/OrchardCore.Modules/OrchardCore.Autoroute/Handlers/AutoroutePartHandler.cs b/src/OrchardCore.Modules/OrchardCore.Autoroute/Handlers/AutoroutePartHandler.cs index 00f4c240b0b..154ed08f9cd 100644 --- a/src/OrchardCore.Modules/OrchardCore.Autoroute/Handlers/AutoroutePartHandler.cs +++ b/src/OrchardCore.Modules/OrchardCore.Autoroute/Handlers/AutoroutePartHandler.cs @@ -395,7 +395,7 @@ private async Task GenerateContainerPathFromPattern(AutoroutePart part) _contentManager ??= _serviceProvider.GetRequiredService(); var cultureAspect = await _contentManager.PopulateAspectAsync(part.ContentItem, new CultureAspect()); - using (var cultureScope = new CultureScope(cultureAspect.Culture)) + using (CultureScope.Create(cultureAspect.Culture)) { part.Path = await _liquidTemplateManager.RenderAsync(pattern, NullEncoder.Default, model, scope => scope.SetValue("ContentItem", model.ContentItem)); diff --git a/src/OrchardCore/OrchardCore.Abstractions/Localization/CultureScope.cs b/src/OrchardCore/OrchardCore.Abstractions/Localization/CultureScope.cs index a493941031b..ebb37b2d54d 100644 --- a/src/OrchardCore/OrchardCore.Abstractions/Localization/CultureScope.cs +++ b/src/OrchardCore/OrchardCore.Abstractions/Localization/CultureScope.cs @@ -5,7 +5,7 @@ namespace OrchardCore.Localization { public sealed class CultureScope : IDisposable { - public CultureScope(CultureInfo culture) + private CultureScope(CultureInfo culture) { Culture = culture; CultureInfo.CurrentUICulture = culture; @@ -13,6 +13,8 @@ public CultureScope(CultureInfo culture) public CultureInfo Culture { get; private set; } + public static CultureScope Create(CultureInfo culture) => new CultureScope(culture); + public void Dispose() { CultureInfo.CurrentUICulture = Culture; From 7013d7f0e396b27de743ae4c85397729bb7fa149 Mon Sep 17 00:00:00 2001 From: hishamco Date: Sat, 7 Nov 2020 00:34:46 +0300 Subject: [PATCH 06/10] Use CultureScope in unit tests --- .../Localization/CultureScope.cs | 31 ++- .../PortableObjectStringLocalizerTests.cs | 182 ++++++++++-------- 2 files changed, 125 insertions(+), 88 deletions(-) diff --git a/src/OrchardCore/OrchardCore.Abstractions/Localization/CultureScope.cs b/src/OrchardCore/OrchardCore.Abstractions/Localization/CultureScope.cs index ebb37b2d54d..ee4c7b672dd 100644 --- a/src/OrchardCore/OrchardCore.Abstractions/Localization/CultureScope.cs +++ b/src/OrchardCore/OrchardCore.Abstractions/Localization/CultureScope.cs @@ -5,19 +5,40 @@ namespace OrchardCore.Localization { public sealed class CultureScope : IDisposable { - private CultureScope(CultureInfo culture) + private readonly CultureInfo _originalCulture; + private readonly CultureInfo _originalUICulture; + + private CultureScope(CultureInfo culture, CultureInfo uiCulture) { Culture = culture; - CultureInfo.CurrentUICulture = culture; + UICulture = uiCulture; + _originalCulture = CultureInfo.CurrentCulture; + _originalUICulture = CultureInfo.CurrentUICulture; + + SetCultures(culture, uiCulture); } - public CultureInfo Culture { get; private set; } + public CultureInfo Culture { get; } + + public CultureInfo UICulture { get; } + + public static CultureScope Create(string culture) => Create(culture, culture); - public static CultureScope Create(CultureInfo culture) => new CultureScope(culture); + public static CultureScope Create(string culture, string uiCulture) + => Create(CultureInfo.GetCultureInfo(culture), CultureInfo.GetCultureInfo(uiCulture)); + + public static CultureScope Create(CultureInfo culture) => Create(culture, culture); + + public static CultureScope Create(CultureInfo culture, CultureInfo uiCulture) => new CultureScope(culture, uiCulture); public void Dispose() { - CultureInfo.CurrentUICulture = Culture; + SetCultures(_originalCulture, _originalUICulture); + } + private static void SetCultures(CultureInfo culture, CultureInfo uiCulture) + { + CultureInfo.CurrentCulture = culture; + CultureInfo.CurrentUICulture = uiCulture; } } } diff --git a/test/OrchardCore.Tests/Localization/PortableObjectStringLocalizerTests.cs b/test/OrchardCore.Tests/Localization/PortableObjectStringLocalizerTests.cs index 6aa8527af15..cb1ce129ffc 100644 --- a/test/OrchardCore.Tests/Localization/PortableObjectStringLocalizerTests.cs +++ b/test/OrchardCore.Tests/Localization/PortableObjectStringLocalizerTests.cs @@ -41,12 +41,13 @@ public void LocalizerReturnsTranslationsFromProvidedDictionary() }); var localizer = new PortableObjectStringLocalizer(null, _localizationManager.Object, true, _logger.Object); + using (CultureScope.Create("cs")) + { - CultureInfo.CurrentUICulture = new CultureInfo("cs"); - - var translation = localizer["ball"]; + var translation = localizer["ball"]; - Assert.Equal("míč", translation); + Assert.Equal("míč", translation); + } } [Fact] @@ -57,12 +58,12 @@ public void LocalizerReturnsOriginalTextIfTranslationsDoesntExistInProvidedDicti }); var localizer = new PortableObjectStringLocalizer(null, _localizationManager.Object, true, _logger.Object); + using (CultureScope.Create("cs")) + { + var translation = localizer["car"]; - CultureInfo.CurrentUICulture = new CultureInfo("cs"); - - var translation = localizer["car"]; - - Assert.Equal("car", translation); + Assert.Equal("car", translation); + } } [Fact] @@ -71,12 +72,12 @@ public void LocalizerReturnsOriginalTextIfDictionaryIsEmpty() SetupDictionary("cs", new CultureDictionaryRecord[] { }); var localizer = new PortableObjectStringLocalizer(null, _localizationManager.Object, true, _logger.Object); + using (CultureScope.Create("cs")) + { + var translation = localizer["car"]; - CultureInfo.CurrentUICulture = new CultureInfo("cs"); - - var translation = localizer["car"]; - - Assert.Equal("car", translation); + Assert.Equal("car", translation); + } } [Fact] @@ -90,12 +91,12 @@ public void LocalizerFallbacksToParentCultureIfTranslationDoesntExistInSpecificC }); var localizer = new PortableObjectStringLocalizer(null, _localizationManager.Object, true, _logger.Object); + using (CultureScope.Create("cs-cz")) + { + var translation = localizer["ball"]; - CultureInfo.CurrentUICulture = new CultureInfo("cs-cz"); - - var translation = localizer["ball"]; - - Assert.Equal("míč", translation); + Assert.Equal("míč", translation); + } } [Fact] @@ -108,12 +109,12 @@ public void LocalizerReturnsTranslationFromSpecificCultureIfItExists() new CultureDictionaryRecord("ball", "balón", "balóny", "balónů") }); var localizer = new PortableObjectStringLocalizer(null, _localizationManager.Object, true, _logger.Object); + using (CultureScope.Create("cs-CZ")) + { + var translation = localizer["ball"]; - CultureInfo.CurrentUICulture = new CultureInfo("cs-CZ"); - - var translation = localizer["ball"]; - - Assert.Equal("balón", translation); + Assert.Equal("balón", translation); + } } [Fact] @@ -123,13 +124,14 @@ public void LocalizerReturnsTranslationWithSpecificContext() new CultureDictionaryRecord("ball", "míč", "míče", "míčů"), new CultureDictionaryRecord("ball", "small", new [] { "míček", "míčky", "míčků" }) }); - var localizer = new PortableObjectStringLocalizer("small", _localizationManager.Object, true, _logger.Object); - - CultureInfo.CurrentUICulture = new CultureInfo("cs"); - var translation = localizer["ball"]; + var localizer = new PortableObjectStringLocalizer("small", _localizationManager.Object, true, _logger.Object); + using (CultureScope.Create("cs")) + { + var translation = localizer["ball"]; - Assert.Equal("míček", translation); + Assert.Equal("míček", translation); + } } [Fact] @@ -140,12 +142,12 @@ public void LocalizerReturnsTranslationWithoutContextIfTranslationWithContextDoe new CultureDictionaryRecord("ball", "big", new [] { "míček", "míčky", "míčků" }) }); var localizer = new PortableObjectStringLocalizer("small", _localizationManager.Object, true, _logger.Object); + using (CultureScope.Create("cs")) + { + var translation = localizer["ball"]; - CultureInfo.CurrentUICulture = new CultureInfo("cs"); - - var translation = localizer["ball"]; - - Assert.Equal("míč", translation); + Assert.Equal("míč", translation); + } } [Fact] @@ -155,12 +157,12 @@ public void LocalizerReturnsFormattedTranslation() new CultureDictionaryRecord("The page (ID:{0}) was deleted.", "Stránka (ID:{0}) byla smazána.") }); var localizer = new PortableObjectStringLocalizer("small", _localizationManager.Object, true, _logger.Object); + using (CultureScope.Create("cs")) + { + var translation = localizer["The page (ID:{0}) was deleted.", 1]; - CultureInfo.CurrentUICulture = new CultureInfo("cs"); - - var translation = localizer["The page (ID:{0}) was deleted.", 1]; - - Assert.Equal("Stránka (ID:1) byla smazána.", translation); + Assert.Equal("Stránka (ID:1) byla smazána.", translation); + } } [Fact] @@ -170,25 +172,26 @@ public void HtmlLocalizerDoesNotFormatTwiceIfFormattedTranslationContainsCurlyBr new CultureDictionaryRecord("The page (ID:{0}) was deleted.", "Stránka (ID:{0}) byla smazána.") }); var localizer = new PortableObjectStringLocalizer("small", _localizationManager.Object, true, _logger.Object); - CultureInfo.CurrentUICulture = new CultureInfo("cs"); - var htmlLocalizer = new PortableObjectHtmlLocalizer(localizer); - var unformatted = htmlLocalizer["The page (ID:{0}) was deleted.", "{1}"]; - - var memStream = new MemoryStream(); - var textWriter = new StreamWriter(memStream); - var textReader = new StreamReader(memStream); + using (CultureScope.Create("cs")) + { + var htmlLocalizer = new PortableObjectHtmlLocalizer(localizer); + var unformatted = htmlLocalizer["The page (ID:{0}) was deleted.", "{1}"]; + var memStream = new MemoryStream(); + var textWriter = new StreamWriter(memStream); + var textReader = new StreamReader(memStream); - unformatted.WriteTo(textWriter, HtmlEncoder.Default); + unformatted.WriteTo(textWriter, HtmlEncoder.Default); - textWriter.Flush(); - memStream.Seek(0, SeekOrigin.Begin); - var formatted = textReader.ReadToEnd(); + textWriter.Flush(); + memStream.Seek(0, SeekOrigin.Begin); + var formatted = textReader.ReadToEnd(); - textWriter.Dispose(); - textReader.Dispose(); - memStream.Dispose(); + textWriter.Dispose(); + textReader.Dispose(); + memStream.Dispose(); - Assert.Equal("Stránka (ID:{1}) byla smazána.", formatted); + Assert.Equal("Stránka (ID:{1}) byla smazána.", formatted); + } } [Theory] @@ -199,11 +202,13 @@ public void LocalizerReturnsOriginalTextForPluralIfTranslationDoesntExist(string SetupDictionary("cs", new[] { new CultureDictionaryRecord("ball", "míč", "míče", "míčů"), }); - var localizer = new PortableObjectStringLocalizer(null, _localizationManager.Object, true, _logger.Object); - CultureInfo.CurrentUICulture = new CultureInfo("cs"); - var translation = localizer.Plural(count, "car", "cars"); - Assert.Equal(expected, translation); + var localizer = new PortableObjectStringLocalizer(null, _localizationManager.Object, true, _logger.Object); + using (CultureScope.Create("cs")) + { + var translation = localizer.Plural(count, "car", "cars"); + Assert.Equal(expected, translation); + } } [Theory] @@ -211,18 +216,18 @@ public void LocalizerReturnsOriginalTextForPluralIfTranslationDoesntExist(string [InlineData("zh-Hans", "球", 2, new string[] { "球" })] public void LocalizerReturnsCorrectTranslationForPluralIfNoPluralFormsSpecified(string culture, string expected, int count, string[] translations) { - var currentCulture = CultureInfo.GetCultureInfo(culture); - CultureInfo.CurrentUICulture = currentCulture; + using (var cultureScope = CultureScope.Create(culture)) + { + // using DefaultPluralRuleProvider to test it returns correct rule + TryGetRuleFromDefaultPluralRuleProvider(cultureScope.Culture, out var rule); + Assert.NotNull(rule); - // using DefaultPluralRuleProvider to test it returns correct rule - TryGetRuleFromDefaultPluralRuleProvider(currentCulture, out var rule); - Assert.NotNull(rule); + SetupDictionary(culture, new[] { new CultureDictionaryRecord("ball", translations), }, rule); + var localizer = new PortableObjectStringLocalizer(null, _localizationManager.Object, true, _logger.Object); + var translation = localizer.Plural(count, "ball", "{0} balls", count); - SetupDictionary(culture, new[] { new CultureDictionaryRecord("ball", translations), }, rule); - var localizer = new PortableObjectStringLocalizer(null, _localizationManager.Object, true, _logger.Object); - var translation = localizer.Plural(count, "ball", "{0} balls", count); - - Assert.Equal(expected, translation); + Assert.Equal(expected, translation); + } } [Theory] @@ -234,11 +239,14 @@ public void LocalizerReturnsTranslationInCorrectPluralForm(string expected, int SetupDictionary("cs", new[] { new CultureDictionaryRecord("ball", "míč", "{0} míče", "{0} míčů"), }); + var localizer = new PortableObjectStringLocalizer(null, _localizationManager.Object, true, _logger.Object); - CultureInfo.CurrentUICulture = new CultureInfo("cs"); - var translation = localizer.Plural(count, "ball", "{0} balls", count); + using (CultureScope.Create("cs")) + { + var translation = localizer.Plural(count, "ball", "{0} balls", count); - Assert.Equal(expected, translation); + Assert.Equal(expected, translation); + } } [Theory] @@ -249,10 +257,12 @@ public void LocalizerReturnsOriginalValuesIfTranslationDoesntExistAndMultiplePlu { SetupDictionary("en", new CultureDictionaryRecord[] { }); var localizer = new PortableObjectStringLocalizer(null, _localizationManager.Object, true, _logger.Object); - CultureInfo.CurrentUICulture = new CultureInfo("en"); - var translation = localizer.Plural(count, new[] { "míč", "{0} míče", "{0} míčů" }, count); + using (CultureScope.Create("en")) + { + var translation = localizer.Plural(count, new[] { "míč", "{0} míče", "{0} míčů" }, count); - Assert.Equal(expected, translation); + Assert.Equal(expected, translation); + } } [Theory] @@ -264,10 +274,12 @@ public void LocalizerReturnsCorrectPluralFormIfMultiplePluraflFormsAreSpecified( new CultureDictionaryRecord("míč", "ball", "{0} balls") }, _enPluralRule); var localizer = new PortableObjectStringLocalizer(null, _localizationManager.Object, true, _logger.Object); - CultureInfo.CurrentUICulture = new CultureInfo("en"); - var translation = localizer.Plural(count, new[] { "míč", "{0} míče", "{0} míčů" }, count); + using (CultureScope.Create("en")) + { + var translation = localizer.Plural(count, new[] { "míč", "{0} míče", "{0} míčů" }, count); - Assert.Equal(expected, translation); + Assert.Equal(expected, translation); + } } [Theory] @@ -280,10 +292,12 @@ public void LocalizerFallBackToParentCultureIfFallBackToParentUICulturesIsTrue(b }, _arPluralRule); SetupDictionary("ar-YE", new CultureDictionaryRecord[] { }, _arPluralRule); var localizer = new PortableObjectStringLocalizer(null, _localizationManager.Object, fallBackToParentCulture, _logger.Object); - CultureInfo.CurrentUICulture = new CultureInfo("ar-YE"); - var translation = localizer[resourceKey]; + using (CultureScope.Create("ar-YE")) + { + var translation = localizer[resourceKey]; - Assert.Equal(expected, translation); + Assert.Equal(expected, translation); + } } [Theory] @@ -303,10 +317,12 @@ public void LocalizerReturnsGetAllStrings(bool includeParentCultures, string[] e }, _arPluralRule); var localizer = new PortableObjectStringLocalizer(null, _localizationManager.Object, false, _logger.Object); - CultureInfo.CurrentUICulture = new CultureInfo("ar-YE"); - var translations = localizer.GetAllStrings(includeParentCultures).Select(l => l.Value).ToArray(); + using (CultureScope.Create("ar-YE")) + { + var translations = localizer.GetAllStrings(includeParentCultures).Select(l => l.Value).ToArray(); - Assert.Equal(expected.Count(), translations.Count()); + Assert.Equal(expected.Count(), translations.Count()); + } } [Fact] From ee0336b16edcbaf7cdae029bee5ebf74dc1fc000 Mon Sep 17 00:00:00 2001 From: hishamco Date: Sat, 7 Nov 2020 01:19:10 +0300 Subject: [PATCH 07/10] Add new line --- .../OrchardCore.Abstractions/Localization/CultureScope.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/OrchardCore/OrchardCore.Abstractions/Localization/CultureScope.cs b/src/OrchardCore/OrchardCore.Abstractions/Localization/CultureScope.cs index ee4c7b672dd..f734c0383de 100644 --- a/src/OrchardCore/OrchardCore.Abstractions/Localization/CultureScope.cs +++ b/src/OrchardCore/OrchardCore.Abstractions/Localization/CultureScope.cs @@ -35,6 +35,7 @@ public void Dispose() { SetCultures(_originalCulture, _originalUICulture); } + private static void SetCultures(CultureInfo culture, CultureInfo uiCulture) { CultureInfo.CurrentCulture = culture; From 7674916941e0e819c85c5c1fb04588b37f70c890 Mon Sep 17 00:00:00 2001 From: hishamco Date: Sat, 7 Nov 2020 10:31:50 +0300 Subject: [PATCH 08/10] Address the feedback --- .../Localization/PortableObjectStringLocalizerTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/OrchardCore.Tests/Localization/PortableObjectStringLocalizerTests.cs b/test/OrchardCore.Tests/Localization/PortableObjectStringLocalizerTests.cs index cb1ce129ffc..fbbd6583634 100644 --- a/test/OrchardCore.Tests/Localization/PortableObjectStringLocalizerTests.cs +++ b/test/OrchardCore.Tests/Localization/PortableObjectStringLocalizerTests.cs @@ -219,7 +219,7 @@ public void LocalizerReturnsCorrectTranslationForPluralIfNoPluralFormsSpecified( using (var cultureScope = CultureScope.Create(culture)) { // using DefaultPluralRuleProvider to test it returns correct rule - TryGetRuleFromDefaultPluralRuleProvider(cultureScope.Culture, out var rule); + TryGetRuleFromDefaultPluralRuleProvider(cultureScope.UICulture, out var rule); Assert.NotNull(rule); SetupDictionary(culture, new[] { new CultureDictionaryRecord("ball", translations), }, rule); From 8f3def6a81d428008cb9f08f19f4b7584450230a Mon Sep 17 00:00:00 2001 From: hishamco Date: Sat, 7 Nov 2020 11:36:15 +0300 Subject: [PATCH 09/10] Add unit tests --- .../Localization/CultureScopeTests.cs | 78 +++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 test/OrchardCore.Tests/Localization/CultureScopeTests.cs diff --git a/test/OrchardCore.Tests/Localization/CultureScopeTests.cs b/test/OrchardCore.Tests/Localization/CultureScopeTests.cs new file mode 100644 index 00000000000..40d2cb29443 --- /dev/null +++ b/test/OrchardCore.Tests/Localization/CultureScopeTests.cs @@ -0,0 +1,78 @@ +using System; +using System.Globalization; +using OrchardCore.Localization; +using Xunit; + +namespace OrchardCore.Tests.Localization +{ + public class CultureScopeTests + { + [Fact] + public void CultureScopeSetUICultureAutomaticallyIfNotSet() + { + // Arrange + var culture = "ar-YE"; + + // Act + using (var cultureScope = CultureScope.Create(culture)) + { + // Assert + Assert.Equal(culture, cultureScope.Culture.Name); + Assert.Equal(culture, cultureScope.UICulture.Name); + } + } + + [Fact] + public void CultureScopeRetreivesBothCultureAndUICulture() + { + // Arrange + var culture = "ar"; + var uiCulture = "ar-YE"; + + // Act + using (var cultureScope = CultureScope.Create(culture, uiCulture)) + { + // Assert + Assert.Equal(culture, cultureScope.Culture.Name); + Assert.Equal(uiCulture, cultureScope.UICulture.Name); + } + } + + [Fact] + public void CultureScopeRetreivesTheOrginalCulturesAfterScopeEnded() + { + // Arrange + var culture = CultureInfo.CurrentCulture; + var uiCulture = CultureInfo.CurrentUICulture; + + // Act + using (var cultureScope = CultureScope.Create("FR")) + { + + } + + // Assert + Assert.Equal(culture, CultureInfo.CurrentCulture); + Assert.Equal(uiCulture, CultureInfo.CurrentUICulture); + } + + [Fact] + public void CultureScopeRetreivesTheOrginalCulturesIfExceptionOccur() + { + // Arrange + var culture = CultureInfo.CurrentCulture; + var uiCulture = CultureInfo.CurrentUICulture; + + // Act & Assert + Assert.ThrowsAsync(() => + { + using (var cultureScope = CultureScope.Create("FR")) + { + throw new Exception("Something goes wrong!!"); + } + }); + Assert.Equal(culture, CultureInfo.CurrentCulture); + Assert.Equal(uiCulture, CultureInfo.CurrentUICulture); + } + } +} From 05e9e7ad3d0194b449bc9e5dd69a1ca810823586 Mon Sep 17 00:00:00 2001 From: hishamco Date: Sat, 7 Nov 2020 11:50:07 +0300 Subject: [PATCH 10/10] Fix typo --- test/OrchardCore.Tests/Localization/CultureScopeTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/OrchardCore.Tests/Localization/CultureScopeTests.cs b/test/OrchardCore.Tests/Localization/CultureScopeTests.cs index 40d2cb29443..5bb20af7b51 100644 --- a/test/OrchardCore.Tests/Localization/CultureScopeTests.cs +++ b/test/OrchardCore.Tests/Localization/CultureScopeTests.cs @@ -57,7 +57,7 @@ public void CultureScopeRetreivesTheOrginalCulturesAfterScopeEnded() } [Fact] - public void CultureScopeRetreivesTheOrginalCulturesIfExceptionOccur() + public void CultureScopeRetreivesTheOrginalCulturesIfExceptionOccurs() { // Arrange var culture = CultureInfo.CurrentCulture;