Skip to content

Commit

Permalink
Set thread culture
Browse files Browse the repository at this point in the history
Mocale now sets thread cultures, its been wonky testing this so hopefully its ok
  • Loading branch information
Axemasta committed Mar 4, 2025
1 parent 475a77f commit e47c099
Show file tree
Hide file tree
Showing 6 changed files with 136 additions and 9 deletions.
14 changes: 14 additions & 0 deletions src/Mocale/Managers/LocalizationManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ public async Task<bool> SetCultureAsync(CultureInfo culture)

CurrentCulture = culture;

UpdateThreadCulture(culture);

currentCultureManager.SetActiveCulture(culture);

logger.LogDebug("Updated localization culture to {CultureName}", culture.Name);
Expand Down Expand Up @@ -105,6 +107,8 @@ private Task<bool> InitializeInternal()
.Forget();
}

UpdateThreadCulture(CurrentCulture);

return Task.FromResult(true);
}

Expand Down Expand Up @@ -163,4 +167,14 @@ private async Task<bool> TryLoadInternalAndExternalTranslations(CultureInfo cult

return result.Loaded || localTranslations.Loaded;
}

private static void UpdateThreadCulture(CultureInfo cultureInfo)
{
Thread.CurrentThread.CurrentCulture = cultureInfo;
Thread.CurrentThread.CurrentUICulture = cultureInfo;
CultureInfo.CurrentCulture = cultureInfo;
CultureInfo.CurrentUICulture = cultureInfo;
CultureInfo.DefaultThreadCurrentCulture = cultureInfo;
CultureInfo.DefaultThreadCurrentUICulture = cultureInfo;
}
}
7 changes: 7 additions & 0 deletions tests/Mocale.UnitTests/Collections/CollectionDefinitions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace Mocale.UnitTests.Collections;

[CollectionDefinition(CollectionNames.MocaleLocatorTests, DisableParallelization = true)]
public class MocaleLocatorTestsCollectionDefinition;

[CollectionDefinition(CollectionNames.ThreadCultureTests, DisableParallelization = true)]
public class ThreadCultureTestsCollectionDefinition;
2 changes: 2 additions & 0 deletions tests/Mocale.UnitTests/Collections/CollectionNames.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,6 @@ namespace Mocale.UnitTests.Collections;
public static class CollectionNames
{
public const string MocaleLocatorTests = "MocaleLocatorCollection";

public const string ThreadCultureTests = "ThreadCultureCollection";
}

This file was deleted.

106 changes: 102 additions & 4 deletions tests/Mocale.UnitTests/Managers/LocalizationManagerTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@
using Mocale.Managers;
using Mocale.Models;
using Mocale.Testing;
using Mocale.UnitTests.Collections;

namespace Mocale.UnitTests.Managers;

[Collection(CollectionNames.ThreadCultureTests)]
public class LocalizationManagerTests : FixtureBase<ILocalizationManager>
{
#region Setup
Expand All @@ -22,24 +24,31 @@ public class LocalizationManagerTests : FixtureBase<ILocalizationManager>

public LocalizationManagerTests()
{
mocaleConfiguration = new Mock<IMocaleConfiguration>();

mocaleConfiguration.SetupGet(m => m.UseExternalProvider)
.Returns(true);

configurationManager.SetupGet(m => m.Configuration)
.Returns(mocaleConfiguration.Object);
}

~LocalizationManagerTests()
{
Thread.CurrentThread.CurrentCulture = null!;
Thread.CurrentThread.CurrentUICulture = null!;
CultureInfo.CurrentCulture = null!;
CultureInfo.CurrentUICulture = null!;
CultureInfo.DefaultThreadCurrentCulture = null;
CultureInfo.DefaultThreadCurrentUICulture = null;
}

public override ILocalizationManager CreateSystemUnderTest()
{
return new LocalizationManager(
currentCultureManager.Object,
configurationManager.Object,
logger.Object,
translationResolver.Object,
internalTranslatorManager.Object
);
internalTranslatorManager.Object);
}

#endregion Setup
Expand Down Expand Up @@ -563,6 +572,46 @@ public async Task Initialize_WhenExternalProviderNotEnabledAndLocalProviderLoads
Times.Never());
}

[Fact]
public async Task InitializeAsync_WhenInitialized_ShouldSetThreadCulturesToActiveCulture()
{
// Arrange
currentCultureManager.Setup(m => m.GetActiveCulture())
.Returns(new CultureInfo("it-IT"));

translationResolver.Setup(m => m.LoadLocalTranslations(new CultureInfo("it-IT")))
.Returns(new TranslationLoadResult()
{
Loaded = true,
Localization = new Localization()
{
CultureInfo = new CultureInfo("it-IT"),
Translations = new Dictionary<string, string>()
{
{ "Hello", "Ciao!" }
}
},
Source = TranslationSource.WarmCache,
});

// This doesn't seem to work when tests run in parallel...
// Assert.NotEqual(new CultureInfo("it-IT"), Thread.CurrentThread.CurrentCulture);
// Assert.NotEqual(new CultureInfo("it-IT"), Thread.CurrentThread.CurrentUICulture);
// Assert.NotEqual(new CultureInfo("it-IT"), CultureInfo.CurrentCulture);
// Assert.NotEqual(new CultureInfo("it-IT"), CultureInfo.CurrentUICulture);

// Act
var initialized = await Sut.Initialize();

// Assert
Assert.True(initialized);

Assert.Equivalent(new CultureInfo("it-IT"), Thread.CurrentThread.CurrentCulture);
Assert.Equivalent(new CultureInfo("it-IT"), Thread.CurrentThread.CurrentUICulture);
Assert.Equivalent(new CultureInfo("it-IT"), CultureInfo.CurrentCulture);
Assert.Equivalent(new CultureInfo("it-IT"), CultureInfo.CurrentUICulture);
}

[Fact]
public async Task SetCultureAsync_WhenSomethingThrows_ShouldLogAndReturnFalse()
{
Expand Down Expand Up @@ -956,6 +1005,55 @@ public async Task SetCultureAsync_WhenExternalProviderNotEnabledAndLocalTranslat
internalTranslatorManager.Verify(m => m.RaisePropertyChanged(null), Times.Once);
}

[Fact]
public async Task SetCultureAsync_WhenLoadSuccessful_ShouldUpdateThreadCultures()
{
mocaleConfiguration.SetupGet(m => m.UseExternalProvider)
.Returns(false);

var activeCulture = new CultureInfo("it-IT");

currentCultureManager.Setup(m => m.GetActiveCulture())
.Returns(activeCulture);

var newCulture = new CultureInfo("fr-FR");

var localLoadResult = new TranslationLoadResult()
{
Loaded = true,
Localization = new Localization()
{
CultureInfo = newCulture,
Translations = new Dictionary<string, string>()
{
{ "KeyOne", "Bonjour le monde" },
},
},
Source = TranslationSource.Internal,
};

translationResolver.Setup(m => m.LoadLocalTranslations(newCulture))
.Returns(localLoadResult);

// This doesn't seem to work when tests run in parallel...
// Assert.NotEqual(new CultureInfo("fr-FR"), Thread.CurrentThread.CurrentCulture);
// Assert.NotEqual(new CultureInfo("fr-FR"), Thread.CurrentThread.CurrentUICulture);
// Assert.NotEqual(new CultureInfo("fr-FR"), CultureInfo.CurrentCulture);
// Assert.NotEqual(new CultureInfo("fr-FR"), CultureInfo.CurrentUICulture);

// Act
var loaded = await Sut.SetCultureAsync(newCulture);

// Assert
Assert.True(loaded);
Assert.Equal(newCulture, Sut.CurrentCulture);

Assert.Equivalent(new CultureInfo("fr-FR"), Thread.CurrentThread.CurrentCulture);
Assert.Equivalent(new CultureInfo("fr-FR"), Thread.CurrentThread.CurrentUICulture);
Assert.Equivalent(new CultureInfo("fr-FR"), CultureInfo.CurrentCulture);
Assert.Equivalent(new CultureInfo("fr-FR"), CultureInfo.CurrentUICulture);
}

#endregion Tests
}

12 changes: 11 additions & 1 deletion tests/Mocale.UnitTests/Providers/AppResourceProviderTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@
using Mocale.Exceptions;
using Mocale.Models;
using Mocale.Providers;
using Mocale.UnitTests.Collections;

namespace Mocale.UnitTests.Providers;

[Collection(CollectionNames.ThreadCultureTests)]
public class AppResourceProviderTests : FixtureBase<IInternalLocalizationProvider>
{
#region Setup
Expand Down Expand Up @@ -55,14 +57,22 @@ public void Constructor_WhenAppResourcesTypeIsNull_ShouldThrow()
public void Constructor_WhenAppResourcesTypeIsNotResx_ShouldReturnNull()
{
// Arrange
Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture;
CultureInfo.CurrentCulture = CultureInfo.InvariantCulture;
CultureInfo.CurrentCulture = CultureInfo.InvariantCulture;

appResourcesConfigManager.Setup(m => m.Configuration)
.Returns(new AppResourcesConfig()
{
AppResourcesType = typeof(string),
});

mocaleConfigurationManager.Setup(m => m.Configuration)
.Returns(new MocaleConfiguration());
.Returns(new MocaleConfiguration()
{
DefaultCulture = new CultureInfo("en-GB"),
});

// Act
var values = Sut.GetValuesForCulture(new CultureInfo("en-GB"));
Expand Down

0 comments on commit e47c099

Please sign in to comment.