From b44c73cf87451c76920709db083013906723af27 Mon Sep 17 00:00:00 2001 From: MSWS Date: Wed, 30 Jul 2025 03:59:53 -0700 Subject: [PATCH] feat: Add IMsgLocalizer and improve localization support ``` Introduce IMsgLocalizer interface and improve localization functionality - Extend `StringLocalizer` to support `IMsg` object localization and implement the new `IMsgLocalizer` interface. - Update `.github/workflows/dotnet.yml` to use newer Actions versions, enable coverage tracking, and generate dynamic coverage badges. - Add `IMsgLocalizer` interface and implement localization indexer in `IMsgLocalizer.cs`. - Update dependency injection in `Startup.cs` to register `IMsgLocalizer` and refine localization services. - Improve tests in `LocaleTest.cs` to validate `IMsgLocalizer` usage, placeholder substitution, and remove redundant assertions. Minor: Adjust `en.yml` formatting by removing unnecessary quotes. ``` --- .github/workflows/dotnet.yml | 9 ++++----- Locale/IMsgLocalizer.cs | 7 +++++++ Locale/StringLocalizer.cs | 4 +++- TTT/Test/Locale/LocaleTest.cs | 17 ++++++++++++----- TTT/Test/Startup.cs | 4 +++- TTT/Test/lang/en.yml | 4 ++-- 6 files changed, 31 insertions(+), 14 deletions(-) create mode 100644 Locale/IMsgLocalizer.cs diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index 03f3503..5ee45ae 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -28,15 +28,15 @@ jobs: - name: Build run: dotnet build --no-restore - + - name: Copy Lang Folder run: | mkdir -p build_output/lang/ cp -r TTT/Test/lang/* build_output/lang/ - + - name: Publish Test Project run: dotnet publish TTT/Test/Test.csproj --no-restore --no-build -o build_output -c Debug - + - uses: actions/upload-artifact@v4 with: name: build_output @@ -61,7 +61,6 @@ jobs: path: build_output - name: Run tests -# run: "dotnet run --no-build --no-restore --project TTT/Test/Test.csproj -- --coverage --coverage-output $GITHUB_WORKSPACE/coverage.xml --coverage-output-format cobertura" run: "dotnet ./build_output/Test.dll --coverage --coverage-output $GITHUB_WORKSPACE/coverage.xml --coverage-output-format cobertura" - name: Code Coverage Summary Report @@ -95,6 +94,6 @@ jobs: valColorRange: ${{ env.CODE_COVERAGE }} maxColorRange: 100 minColorRange: 33 - + - name: Write to Job Summary run: cat code-coverage-results.md >> $GITHUB_STEP_SUMMARY \ No newline at end of file diff --git a/Locale/IMsgLocalizer.cs b/Locale/IMsgLocalizer.cs new file mode 100644 index 0000000..7e9151e --- /dev/null +++ b/Locale/IMsgLocalizer.cs @@ -0,0 +1,7 @@ +using Microsoft.Extensions.Localization; + +namespace TTT.Locale; + +public interface IMsgLocalizer : IStringLocalizer { + string this[IMsg msg] { get; } +} \ No newline at end of file diff --git a/Locale/StringLocalizer.cs b/Locale/StringLocalizer.cs index 82a6878..ea67a4e 100644 --- a/Locale/StringLocalizer.cs +++ b/Locale/StringLocalizer.cs @@ -8,7 +8,7 @@ namespace TTT.Locale; /// A custom implementation of that adds support /// for in-string placeholders like %key% and grammatical pluralization with %s%. /// -public partial class StringLocalizer : IStringLocalizer { +public partial class StringLocalizer : IStringLocalizer, IMsgLocalizer { public static readonly StringLocalizer Instance = new(new JsonLocalizerFactory()); @@ -112,4 +112,6 @@ public partial class StringLocalizer : IStringLocalizer { return value; } + + public string this[IMsg msg] => localizer[msg.Key, msg.Args]; } \ No newline at end of file diff --git a/TTT/Test/Locale/LocaleTest.cs b/TTT/Test/Locale/LocaleTest.cs index dc2a429..e3399ed 100644 --- a/TTT/Test/Locale/LocaleTest.cs +++ b/TTT/Test/Locale/LocaleTest.cs @@ -1,14 +1,21 @@ using Microsoft.Extensions.Localization; +using TTT.Locale; using Xunit; namespace TTT.Test.Locale; -public class LocaleTest(IStringLocalizer localizer) { +public class LocaleTest(IMsgLocalizer localizer) { [Fact] public void Locale_BasicTest() { - var msg = localizer["BASIC_TEST"]; - - Assert.NotNull(msg); - Assert.Equal("Foobar", msg.Value); + var result = localizer[TestMsgs.BASIC_TEST]; + + Assert.Equal("Foobar", result); + } + + [Fact] + public void Locale_Placeholder_Works() { + var msg = localizer[TestMsgs.PLACEHOLDER_TEST("Test")]; + + Assert.Equal("Placeholder: Test", msg); } } \ No newline at end of file diff --git a/TTT/Test/Startup.cs b/TTT/Test/Startup.cs index ffe249a..fd2afc3 100644 --- a/TTT/Test/Startup.cs +++ b/TTT/Test/Startup.cs @@ -29,7 +29,9 @@ public class Startup { services.AddScoped(s => s.GetRequiredService()); services.AddScoped(); services.AddScoped(); - services.AddTransient(); + services.AddScoped(); + services.AddTransient(s + => s.GetRequiredService()); services.AddModBehavior(); services.AddModBehavior(); diff --git a/TTT/Test/lang/en.yml b/TTT/Test/lang/en.yml index 4ee13fb..aec4649 100644 --- a/TTT/Test/lang/en.yml +++ b/TTT/Test/lang/en.yml @@ -1,2 +1,2 @@ -"BASIC_TEST": "Foobar" -"PLACEHOLDER_TEST": "Placeholder: {0}" +BASIC_TEST: "Foobar" +PLACEHOLDER_TEST: "Placeholder: {0}"