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

Refactor localization tests #12499

Merged
merged 5 commits into from
Oct 13, 2022
Merged
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
13 changes: 5 additions & 8 deletions test/OrchardCore.Tests/Localization/CultureDictionaryTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,10 @@ namespace OrchardCore.Tests.Localization
{
public class CultureDictionaryTests
{
private static PluralizationRuleDelegate _arPluralRule = n => (n == 0 ? 0 : n == 1 ? 1 : n == 2 ? 2 : n % 100 >= 3 && n % 100 <= 10 ? 3 : n % 100 >= 11 ? 4 : 5);
private static PluralizationRuleDelegate _csPluralRule = n => ((n == 1) ? 0 : (n >= 2 && n <= 4) ? 1 : 2);

[Fact]
public void MergeAddsRecordToEmptyDictionary()
{
var dictionary = new CultureDictionary("cs", _csPluralRule);
var dictionary = new CultureDictionary("cs", PluralizationRule.Czech);
var record = new CultureDictionaryRecord("ball", "míč", "míče", "míčů");

dictionary.MergeTranslations(new[] { record });
Expand All @@ -24,7 +21,7 @@ public void MergeAddsRecordToEmptyDictionary()
[Fact]
public void MergeOverwritesTranslationsForSameKeys()
{
var dictionary = new CultureDictionary("cs", _csPluralRule);
var dictionary = new CultureDictionary("cs", PluralizationRule.Czech);
var record = new CultureDictionaryRecord("ball", "míč", "míče", "míčů");
var record2 = new CultureDictionaryRecord("ball", "balón", "balóny", "balónů");

Expand All @@ -37,7 +34,7 @@ public void MergeOverwritesTranslationsForSameKeys()
[Fact]
public void IndexerReturnNullIfKeyDoesntExist()
{
var dictionary = new CultureDictionary("cs", _csPluralRule);
var dictionary = new CultureDictionary("cs", PluralizationRule.Czech);
var key = new CultureDictionaryRecordKey("ball");
var translation = dictionary[key];

Expand All @@ -48,7 +45,7 @@ public void IndexerReturnNullIfKeyDoesntExist()
public void IndexerThrowsPluralFormNotFoundExceptionIfSpecifiedPluralFormDoesntExist()
{
// Arrange
var dictionary = new CultureDictionary("cs", _csPluralRule);
var dictionary = new CultureDictionary("cs", PluralizationRule.Czech);
var record = new CultureDictionaryRecord("ball", "míč", "míče");
dictionary.MergeTranslations(new[] { record });

Expand All @@ -64,7 +61,7 @@ public void IndexerThrowsPluralFormNotFoundExceptionIfSpecifiedPluralFormDoesntE
public void EnumerateCultureDictionary()
{
// Arrange
var dictionary = new CultureDictionary("ar", _arPluralRule);
var dictionary = new CultureDictionary("ar", PluralizationRule.Arabic);
dictionary.MergeTranslations(new List<CultureDictionaryRecord>
{
new CultureDictionaryRecord("Hello", "مرحبا"),
Expand Down
1 change: 1 addition & 0 deletions test/OrchardCore.Tests/Localization/CultureScopeTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ await Assert.ThrowsAsync<Exception>(() =>
throw new Exception("Something goes wrong!!");
}
});

Assert.Equal(culture, CultureInfo.CurrentCulture);
Assert.Equal(uiCulture, CultureInfo.CurrentUICulture);
}
Expand Down
15 changes: 9 additions & 6 deletions test/OrchardCore.Tests/Localization/LocalizationManagerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,16 @@ namespace OrchardCore.Tests.Localization
{
public class LocalizationManagerTests
{
private PluralizationRuleDelegate _csPluralRule = n => ((n == 1) ? 0 : (n >= 2 && n <= 4) ? 1 : 2);
private Mock<IPluralRuleProvider> _pluralRuleProvider;
private Mock<ITranslationProvider> _translationProvider;
private IMemoryCache _memoryCache;
private readonly Mock<IPluralRuleProvider> _pluralRuleProvider;
private readonly Mock<ITranslationProvider> _translationProvider;
private readonly IMemoryCache _memoryCache;

public LocalizationManagerTests()
{
var csPluralRule = PluralizationRule.Czech;
_pluralRuleProvider = new Mock<IPluralRuleProvider>();
_pluralRuleProvider.SetupGet(o => o.Order).Returns(0);
_pluralRuleProvider.Setup(o => o.TryGetRule(It.Is<CultureInfo>(culture => culture.Name == "cs"), out _csPluralRule)).Returns(true);
_pluralRuleProvider.Setup(o => o.TryGetRule(It.Is<CultureInfo>(culture => culture.Name == "cs"), out csPluralRule)).Returns(true);

_translationProvider = new Mock<ITranslationProvider>();
_memoryCache = new MemoryCache(new MemoryCacheOptions());
Expand All @@ -30,12 +30,13 @@ public void GetDictionaryReturnsDictionaryWithPluralRuleAndCultureIfNoTranslatio
It.Is<string>(culture => culture == "cs"),
It.IsAny<CultureDictionary>())
);

var manager = new LocalizationManager(new[] { _pluralRuleProvider.Object }, new[] { _translationProvider.Object }, _memoryCache);

var dictionary = manager.GetDictionary(new CultureInfo("cs"));

Assert.Equal("cs", dictionary.CultureName);
Assert.Equal(_csPluralRule, dictionary.PluralRule);
Assert.Equal(PluralizationRule.Czech, dictionary.PluralRule);
}

[Fact]
Expand All @@ -45,6 +46,7 @@ public void GetDictionaryReturnsDictionaryWithTranslationsFromProvider()
_translationProvider
.Setup(o => o.LoadTranslations(It.Is<string>(culture => culture == "cs"), It.IsAny<CultureDictionary>()))
.Callback<string, CultureDictionary>((culture, dictioanry) => dictioanry.MergeTranslations(new[] { dictionaryRecord }));

var manager = new LocalizationManager(new[] { _pluralRuleProvider.Object }, new[] { _translationProvider.Object }, _memoryCache);

var dictionary = manager.GetDictionary(new CultureInfo("cs"));
Expand All @@ -68,6 +70,7 @@ public void GetDictionarySelectsPluralRuleFromProviderWithHigherPriority()
It.Is<string>(culture => culture == "cs"),
It.IsAny<CultureDictionary>())
);

var manager = new LocalizationManager(new[] { _pluralRuleProvider.Object, highPriorityRuleProvider.Object }, new[] { _translationProvider.Object }, _memoryCache);

var dictionary = manager.GetDictionary(new CultureInfo("cs"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,9 @@ public void HtmlNullLocalizerSupportsPlural(string expected, int count, string s
{
var localizer = new NullHtmlLocalizerFactory().Create(typeof(object));

using (var writer = new StringWriter())
{
localizer.Plural(count, singular, plural, arguments).WriteTo(writer, HtmlEncoder.Default);
Assert.Equal(expected, writer.ToString());
}
using var writer = new StringWriter();
localizer.Plural(count, singular, plural, arguments).WriteTo(writer, HtmlEncoder.Default);
Assert.Equal(expected, writer.ToString());
}

[Theory]
Expand Down
12 changes: 12 additions & 0 deletions test/OrchardCore.Tests/Localization/PluralizationRule.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using OrchardCore.Localization;

namespace OrchardCore.Tests.Localization;

public class PluralizationRule
{
public static readonly PluralizationRuleDelegate Czech = n => ((n == 1) ? 0 : (n >= 2 && n <= 4) ? 1 : 2);

public static readonly PluralizationRuleDelegate English = n => (n == 1) ? 0 : 1;

public static readonly PluralizationRuleDelegate Arabic = n => (n == 0 ? 0 : n == 1 ? 1 : n == 2 ? 2 : n % 100 >= 3 && n % 100 <= 10 ? 3 : n % 100 >= 11 ? 4 : 5);
}
4 changes: 2 additions & 2 deletions test/OrchardCore.Tests/Localization/PoParserTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ public void ParseIgnoresPoeditHeader()
// msgstr "Error desconegut del sistema"
var entries = ParseText("PoeditHeader");

Assert.True(entries.Count() == 1);
Assert.True(entries[0].Translations.Count() == 1);
Assert.True(entries.Length == 1);
Assert.True(entries[0].Translations.Length == 1);
}

[Fact]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,8 @@ namespace OrchardCore.Tests.Localization
{
public class PortableObjectStringLocalizerTests
{
private static PluralizationRuleDelegate _csPluralRule = n => ((n == 1) ? 0 : (n >= 2 && n <= 4) ? 1 : 2);
private static PluralizationRuleDelegate _enPluralRule = n => (n == 1) ? 0 : 1;
private static PluralizationRuleDelegate _arPluralRule = n => (n == 0 ? 0 : n == 1 ? 1 : n == 2 ? 2 : n % 100 >= 3 && n % 100 <= 10 ? 3 : n % 100 >= 11 ? 4 : 5);
private Mock<ILocalizationManager> _localizationManager;
private Mock<ILogger> _logger;
private readonly Mock<ILocalizationManager> _localizationManager;
private readonly Mock<ILogger> _logger;

public PortableObjectStringLocalizerTests()
{
Expand Down Expand Up @@ -69,7 +66,7 @@ public void LocalizerReturnsOriginalTextIfTranslationsDoesntExistInProvidedDicti
[Fact]
public void LocalizerReturnsOriginalTextIfDictionaryIsEmpty()
{
SetupDictionary("cs", new CultureDictionaryRecord[] { });
SetupDictionary("cs", Array.Empty<CultureDictionaryRecord>());

var localizer = new PortableObjectStringLocalizer(null, _localizationManager.Object, true, _logger.Object);
using (CultureScope.Create("cs"))
Expand All @@ -86,6 +83,7 @@ public void LocalizerFallbacksToParentCultureIfTranslationDoesntExistInSpecificC
SetupDictionary("cs", new[] {
new CultureDictionaryRecord("ball", "míč", "míče", "míčů")
});

SetupDictionary("cs-CZ", new[] {
new CultureDictionaryRecord("car", "auto", "auta", "aut")
});
Expand All @@ -105,9 +103,11 @@ public void LocalizerReturnsTranslationFromSpecificCultureIfItExists()
SetupDictionary("cs", new[] {
new CultureDictionaryRecord("ball", "míč", "míče", "míčů")
});

SetupDictionary("cs-CZ", new[] {
new CultureDictionaryRecord("ball", "balón", "balóny", "balónů")
});

var localizer = new PortableObjectStringLocalizer(null, _localizationManager.Object, true, _logger.Object);
using (CultureScope.Create("cs-CZ"))
{
Expand Down Expand Up @@ -141,6 +141,7 @@ public void LocalizerReturnsTranslationWithoutContextIfTranslationWithContextDoe
new CultureDictionaryRecord("ball", "míč", "míče", "míčů"),
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"))
{
Expand All @@ -156,6 +157,7 @@ public void LocalizerReturnsFormattedTranslation()
SetupDictionary("cs", new[] {
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"))
{
Expand All @@ -171,6 +173,7 @@ public void HtmlLocalizerDoesNotFormatTwiceIfFormattedTranslationContainsCurlyBr
SetupDictionary("cs", new[] {
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"))
{
Expand Down Expand Up @@ -220,9 +223,11 @@ public void LocalizerReturnsCorrectTranslationForPluralIfNoPluralFormsSpecified(
{
// using DefaultPluralRuleProvider to test it returns correct rule
TryGetRuleFromDefaultPluralRuleProvider(cultureScope.UICulture, 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);

Expand Down Expand Up @@ -255,7 +260,8 @@ public void LocalizerReturnsTranslationInCorrectPluralForm(string expected, int
[InlineData("5 míčů", 5)]
public void LocalizerReturnsOriginalValuesIfTranslationDoesntExistAndMultiplePluraflFormsAreSpecified(string expected, int count)
{
SetupDictionary("en", new CultureDictionaryRecord[] { });
SetupDictionary("en", Array.Empty<CultureDictionaryRecord>());

var localizer = new PortableObjectStringLocalizer(null, _localizationManager.Object, true, _logger.Object);
using (CultureScope.Create("en"))
{
Expand All @@ -270,9 +276,11 @@ public void LocalizerReturnsOriginalValuesIfTranslationDoesntExistAndMultiplePlu
[InlineData("2 balls", 2)]
public void LocalizerReturnsCorrectPluralFormIfMultiplePluraflFormsAreSpecified(string expected, int count)
{
SetupDictionary("en", new CultureDictionaryRecord[] {
SetupDictionary("en", new CultureDictionaryRecord[]
{
new CultureDictionaryRecord("míč", "ball", "{0} balls")
}, _enPluralRule);
}, PluralizationRule.English);

var localizer = new PortableObjectStringLocalizer(null, _localizationManager.Object, true, _logger.Object);
using (CultureScope.Create("en"))
{
Expand All @@ -287,10 +295,13 @@ public void LocalizerReturnsCorrectPluralFormIfMultiplePluraflFormsAreSpecified(
[InlineData(true, "hello", "مرحبا")]
public void LocalizerFallBackToParentCultureIfFallBackToParentUICulturesIsTrue(bool fallBackToParentCulture, string resourceKey, string expected)
{
SetupDictionary("ar", new CultureDictionaryRecord[] {
SetupDictionary("ar", new CultureDictionaryRecord[]
{
new CultureDictionaryRecord("hello", "مرحبا")
}, _arPluralRule);
SetupDictionary("ar-YE", new CultureDictionaryRecord[] { }, _arPluralRule);
}, PluralizationRule.Arabic);

SetupDictionary("ar-YE", Array.Empty<CultureDictionaryRecord>(), PluralizationRule.Arabic);

var localizer = new PortableObjectStringLocalizer(null, _localizationManager.Object, fallBackToParentCulture, _logger.Object);
using (CultureScope.Create("ar-YE"))
{
Expand All @@ -305,23 +316,26 @@ public void LocalizerFallBackToParentCultureIfFallBackToParentUICulturesIsTrue(b
[InlineData(true, new[] { "مدونة", "منتج", "قائمة", "صفحة", "مقالة" })]
public void LocalizerReturnsGetAllStrings(bool includeParentCultures, string[] expected)
{
SetupDictionary("ar", new CultureDictionaryRecord[] {
SetupDictionary("ar", new CultureDictionaryRecord[]
{
new CultureDictionaryRecord("Blog", "مدونة"),
new CultureDictionaryRecord("Menu", "قائمة"),
new CultureDictionaryRecord("Page", "صفحة"),
new CultureDictionaryRecord("Article", "مقالة")
}, _arPluralRule);
SetupDictionary("ar-YE", new CultureDictionaryRecord[] {
}, PluralizationRule.Arabic);

SetupDictionary("ar-YE", new CultureDictionaryRecord[]
{
new CultureDictionaryRecord("Blog", "مدونة"),
new CultureDictionaryRecord("Product", "منتج")
}, _arPluralRule);
}, PluralizationRule.Arabic);

var localizer = new PortableObjectStringLocalizer(null, _localizationManager.Object, false, _logger.Object);
using (CultureScope.Create("ar-YE"))
{
var translations = localizer.GetAllStrings(includeParentCultures).Select(l => l.Value).ToArray();

Assert.Equal(expected.Count(), translations.Count());
Assert.Equal(expected.Length, translations.Length);
}
}

Expand All @@ -347,13 +361,15 @@ public void LocalizerWithContextShouldCallGetDictionaryOncePerCulture(string cul

// Assert
_localizationManager.Verify(lm => lm.GetDictionary(It.IsAny<CultureInfo>()), Times.Exactly(expectedCalls));

Assert.Equal("Hello", translation);
}

private static bool TryGetRuleFromDefaultPluralRuleProvider(CultureInfo culture, out PluralizationRuleDelegate rule)
=> ((IPluralRuleProvider)new DefaultPluralRuleProvider()).TryGetRule(culture, out rule);

private void SetupDictionary(string cultureName, IEnumerable<CultureDictionaryRecord> records)
{
SetupDictionary(cultureName, records, _csPluralRule);
}
=> SetupDictionary(cultureName, records, PluralizationRule.Czech);

private void SetupDictionary(string cultureName, IEnumerable<CultureDictionaryRecord> records, PluralizationRuleDelegate pluralRule)
{
Expand All @@ -363,11 +379,6 @@ private void SetupDictionary(string cultureName, IEnumerable<CultureDictionaryRe
_localizationManager.Setup(o => o.GetDictionary(It.Is<CultureInfo>(c => c.Name == cultureName))).Returns(dictionary);
}

private bool TryGetRuleFromDefaultPluralRuleProvider(CultureInfo culture, out PluralizationRuleDelegate rule)
{
return ((IPluralRuleProvider)new DefaultPluralRuleProvider()).TryGetRule(culture, out rule);
}

public class PortableObjectLocalizationStartup
{
public void ConfigureServices(IServiceCollection services)
Expand Down
23 changes: 1 addition & 22 deletions test/OrchardCore.Tests/OrchardCore.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,6 @@
</ItemGroup>

<ItemGroup>
<None Remove="Localization\PoFiles\EntryWithComments.po" />
<None Remove="Localization\PoFiles\EntryWithContext.po" />
<None Remove="Localization\PoFiles\EntryWithEscapedCharacters.po" />
<None Remove="Localization\PoFiles\EntryWithMultilineText.po" />
<None Remove="Localization\PoFiles\EntryWithoutTranslation.po" />
<None Remove="Localization\PoFiles\EntryWithPlural.po" />
<None Remove="Localization\PoFiles\EntryWithQuotes.po" />
<None Remove="Localization\PoFiles\EntryWithUnclosedQuote.po" />
<None Remove="Localization\PoFiles\MultipleEntries.po" />
<None Remove="Localization\PoFiles\PoeditHeader.po" />
<None Remove="Localization\PoFiles\SimpleEntry.po" />
<None Remove="Apis\Lucene\Recipes\luceneQueryTest.json" />
<None Remove="Modules\OrchardCore.OpenId\RecipeFiles\app-recipe1.json" />
<None Remove="Modules\OrchardCore.OpenId\RecipeFiles\app-recipe2.json" />
Expand All @@ -43,17 +32,7 @@
</ItemGroup>

<ItemGroup>
<EmbeddedResource Include="Localization\PoFiles\EntryWithComments.po" />
<EmbeddedResource Include="Localization\PoFiles\EntryWithContext.po" />
<EmbeddedResource Include="Localization\PoFiles\EntryWithEscapedCharacters.po" />
<EmbeddedResource Include="Localization\PoFiles\EntryWithMultilineText.po" />
<EmbeddedResource Include="Localization\PoFiles\EntryWithoutTranslation.po" />
<EmbeddedResource Include="Localization\PoFiles\EntryWithPlural.po" />
<EmbeddedResource Include="Localization\PoFiles\EntryWithQuotes.po" />
<EmbeddedResource Include="Localization\PoFiles\EntryWithUnclosedQuote.po" />
<EmbeddedResource Include="Localization\PoFiles\MultipleEntries.po" />
<EmbeddedResource Include="Localization\PoFiles\PoeditHeader.po" />
<EmbeddedResource Include="Localization\PoFiles\SimpleEntry.po" />
<EmbeddedResource Include="Localization\PoFiles\*.po" />
<EmbeddedResource Include="Modules\OrchardCore.OpenId\RecipeFiles\app-recipe3.json" />
<EmbeddedResource Include="Modules\OrchardCore.OpenId\RecipeFiles\app-recipe2.json" />
<EmbeddedResource Include="Modules\OrchardCore.OpenId\RecipeFiles\app-recipe1.json" />
Expand Down