From afe63a50b65f5fbddb6426337efeea461913953e Mon Sep 17 00:00:00 2001 From: "codebelt-aicia[bot]" Date: Sat, 23 May 2026 14:30:49 +0000 Subject: [PATCH 1/4] V10.0.7/service update --- .../PackageReleaseNotes.txt | 6 ++++ CHANGELOG.md | 4 +++ Directory.Packages.props | 30 +++++++++---------- 3 files changed, 25 insertions(+), 15 deletions(-) diff --git a/.nuget/Codebelt.Extensions.Globalization/PackageReleaseNotes.txt b/.nuget/Codebelt.Extensions.Globalization/PackageReleaseNotes.txt index 42c80f1..9aca67d 100644 --- a/.nuget/Codebelt.Extensions.Globalization/PackageReleaseNotes.txt +++ b/.nuget/Codebelt.Extensions.Globalization/PackageReleaseNotes.txt @@ -1,3 +1,9 @@ +Version: 10.0.7 +Availability: .NET 10, .NET 9 and .NET Standard 2.0 + +# ALM +- CHANGED Dependencies have been upgraded to the latest compatible versions for all supported target frameworks (TFMs) + Version: 10.0.6 Availability: .NET 10, .NET 9 and .NET Standard 2.0 diff --git a/CHANGELOG.md b/CHANGELOG.md index 368e7f7..e8181c5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,10 @@ For more details, please refer to `PackageReleaseNotes.txt` on a per assembly ba > [!NOTE] > Changelog entries prior to version 9.0.1 was migrated from previous versions of Cuemon.Extensions.Globalization. +## [10.0.7] - 2026-05-23 + +This is a service update that focuses on package dependencies. + ## [10.0.6] - 2026-04-18 This is a service update that focuses on package dependencies. diff --git a/Directory.Packages.props b/Directory.Packages.props index d9466ea..3af51a5 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -1,16 +1,16 @@ - - - true - - - - - - - - - - - - + + + true + + + + + + + + + + + + \ No newline at end of file From 59ad418519f0718d0cc027d221b8bf051426bdcd Mon Sep 17 00:00:00 2001 From: gimlichael Date: Sat, 23 May 2026 16:47:19 +0200 Subject: [PATCH 2/4] =?UTF-8?q?=E2=AC=86=EF=B8=8F=20upgrade=20dependencies?= =?UTF-8?q?=20and=20ci=20workflow=20action?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/ci-pipeline.yml | 2 +- Directory.Packages.props | 30 +++++++++++++++--------------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/.github/workflows/ci-pipeline.yml b/.github/workflows/ci-pipeline.yml index 616f6b5..a55efa9 100644 --- a/.github/workflows/ci-pipeline.yml +++ b/.github/workflows/ci-pipeline.yml @@ -139,7 +139,7 @@ jobs: if: github.event_name != 'pull_request' name: call-nuget needs: [build, pack, test_linux, test_windows, sonarcloud, codecov, codeql] - uses: codebeltnet/jobs-nuget-push/.github/workflows/default.yml@v2 + uses: codebeltnet/jobs-nuget-push/.github/workflows/default.yml@v3 with: version: ${{ needs.build.outputs.version }} environment: Production diff --git a/Directory.Packages.props b/Directory.Packages.props index 3af51a5..d42dfff 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -1,16 +1,16 @@ - - - true - - - - - - - - - - - - + + + true + + + + + + + + + + + + \ No newline at end of file From 465bb6d7064994ff32525ba86da11331fee50c37 Mon Sep 17 00:00:00 2001 From: gimlichael Date: Sat, 23 May 2026 16:48:53 +0200 Subject: [PATCH 3/4] =?UTF-8?q?=E2=AC=86=EF=B8=8F=20bump=20nginx=20version?= =?UTF-8?q?=20to=201.31.0-alpine=20in=20Dockerfile?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .docfx/Dockerfile.docfx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.docfx/Dockerfile.docfx b/.docfx/Dockerfile.docfx index 04c49b3..9d42262 100644 --- a/.docfx/Dockerfile.docfx +++ b/.docfx/Dockerfile.docfx @@ -1,4 +1,4 @@ -ARG NGINX_VERSION=1.30.0-alpine +ARG NGINX_VERSION=1.31.0-alpine FROM --platform=$BUILDPLATFORM nginx:${NGINX_VERSION} AS base RUN rm -rf /usr/share/nginx/html/* From 1a32822e9517fbfe291f7bda695d3f96a595d753 Mon Sep 17 00:00:00 2001 From: "aicia[bot]" Date: Sat, 23 May 2026 17:44:22 +0200 Subject: [PATCH 4/4] =?UTF-8?q?=E2=9C=85=20add=20tests=20for=20surrogate?= =?UTF-8?q?=20classes=20and=20extension=20methods?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CultureInfoExtensionsTest.cs | 31 +++++++++++ .../CultureInfoSurrogateTest.cs | 42 ++++++++++++++ .../DateTimeFormatInfoSurrogateTest.cs | 50 +++++++++++++++++ .../NumberFormatInfoSurrogateTest.cs | 55 +++++++++++++++++++ 4 files changed, 178 insertions(+) create mode 100644 test/Codebelt.Extensions.Globalization.Tests/CultureInfoSurrogateTest.cs create mode 100644 test/Codebelt.Extensions.Globalization.Tests/DateTimeFormatInfoSurrogateTest.cs create mode 100644 test/Codebelt.Extensions.Globalization.Tests/NumberFormatInfoSurrogateTest.cs diff --git a/test/Codebelt.Extensions.Globalization.Tests/CultureInfoExtensionsTest.cs b/test/Codebelt.Extensions.Globalization.Tests/CultureInfoExtensionsTest.cs index 2664ba1..84118eb 100644 --- a/test/Codebelt.Extensions.Globalization.Tests/CultureInfoExtensionsTest.cs +++ b/test/Codebelt.Extensions.Globalization.Tests/CultureInfoExtensionsTest.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Globalization; +using System.Linq; using System.Runtime.InteropServices; using Codebelt.Extensions.Xunit; using Xunit; @@ -13,6 +14,36 @@ public CultureInfoExtensionsTest(ITestOutputHelper output) : base(output) { } + [Fact] + public void UseNationalLanguageSupport_ShouldCloneAndEnrich_WhenCultureInfoIsReadOnly() + { + var sut = CultureInfo.GetCultureInfo("fr-FR").UseNationalLanguageSupport(); + + Assert.NotNull(sut); + Assert.NotNull(sut.DateTimeFormat); + Assert.NotNull(sut.NumberFormat); + + TestOutput.WriteLine($"{sut.EnglishName}: ShortDatePattern={sut.DateTimeFormat.ShortDatePattern}"); + } + + [Fact] + public void UseNationalLanguageSupport_ShouldThrowInvalidOperationException_WhenNoSurrogateExists() + { + Assert.Throws(() => new CultureInfo("en").UseNationalLanguageSupport()); + } + + [Fact] + public void UseNationalLanguageSupport_ShouldThrowArgumentNullException_WhenCultureIsNull() + { + Assert.Throws(() => ((CultureInfo)null).UseNationalLanguageSupport()); + } + + [Fact] + public void UseNationalLanguageSupport_ShouldThrowArgumentNullException_WhenCulturesIsNull() + { + Assert.Throws(() => ((IEnumerable)null).UseNationalLanguageSupport().ToList()); + } + [Fact] public void UseNationalLanguageSupport_ShouldHaveDifferentFormattingAsWindowsVariant() { diff --git a/test/Codebelt.Extensions.Globalization.Tests/CultureInfoSurrogateTest.cs b/test/Codebelt.Extensions.Globalization.Tests/CultureInfoSurrogateTest.cs new file mode 100644 index 0000000..e36ca6c --- /dev/null +++ b/test/Codebelt.Extensions.Globalization.Tests/CultureInfoSurrogateTest.cs @@ -0,0 +1,42 @@ +using System.Reflection; +using Codebelt.Extensions.Xunit; +using Xunit; + +namespace Codebelt.Extensions.Globalization +{ + public class CultureInfoSurrogateTest : Test + { + public CultureInfoSurrogateTest(ITestOutputHelper output) : base(output) + { + } + + [Fact] + public void Constructor_ShouldAssignDateTimeAndNumberFormats_WhenSurrogatesAreProvided() + { + var assembly = typeof(CultureInfoExtensions).Assembly; + var cultureInfoSurrogateType = assembly.GetType("Codebelt.Extensions.Globalization.CultureInfoSurrogate"); + var dtfiSurrogateType = assembly.GetType("Codebelt.Extensions.Globalization.DateTimeFormatInfoSurrogate"); + var nfiSurrogateType = assembly.GetType("Codebelt.Extensions.Globalization.NumberFormatInfoSurrogate"); + + var dtSurrogate = System.Activator.CreateInstance(dtfiSurrogateType, nonPublic: true); + var nfSurrogate = System.Activator.CreateInstance(nfiSurrogateType, nonPublic: true); + + var ctor = cultureInfoSurrogateType.GetConstructor( + BindingFlags.Instance | BindingFlags.NonPublic, + null, + new[] { dtfiSurrogateType, nfiSurrogateType }, + null); + + var sut = ctor.Invoke(new[] { dtSurrogate, nfSurrogate }); + + var dateTimeFormatProp = cultureInfoSurrogateType.GetProperty("DateTimeFormat", BindingFlags.Instance | BindingFlags.NonPublic); + var numberFormatProp = cultureInfoSurrogateType.GetProperty("NumberFormat", BindingFlags.Instance | BindingFlags.NonPublic); + + Assert.Same(dtSurrogate, dateTimeFormatProp.GetValue(sut)); + Assert.Same(nfSurrogate, numberFormatProp.GetValue(sut)); + + TestOutput.WriteLine($"DateTimeFormat assigned: {dateTimeFormatProp.GetValue(sut) != null}"); + TestOutput.WriteLine($"NumberFormat assigned: {numberFormatProp.GetValue(sut) != null}"); + } + } +} diff --git a/test/Codebelt.Extensions.Globalization.Tests/DateTimeFormatInfoSurrogateTest.cs b/test/Codebelt.Extensions.Globalization.Tests/DateTimeFormatInfoSurrogateTest.cs new file mode 100644 index 0000000..b85b36f --- /dev/null +++ b/test/Codebelt.Extensions.Globalization.Tests/DateTimeFormatInfoSurrogateTest.cs @@ -0,0 +1,50 @@ +using System; +using System.Globalization; +using System.Reflection; +using Codebelt.Extensions.Xunit; +using Xunit; + +namespace Codebelt.Extensions.Globalization +{ + public class DateTimeFormatInfoSurrogateTest : Test + { + public DateTimeFormatInfoSurrogateTest(ITestOutputHelper output) : base(output) + { + } + + [Fact] + public void Constructor_ShouldCopyAllPropertiesFromDateTimeFormatInfo_WhenDateTimeFormatInfoIsProvided() + { + var assembly = typeof(CultureInfoExtensions).Assembly; + var type = assembly.GetType("Codebelt.Extensions.Globalization.DateTimeFormatInfoSurrogate"); + var ctor = type.GetConstructor( + BindingFlags.Instance | BindingFlags.NonPublic, + null, + new[] { typeof(DateTimeFormatInfo) }, + null); + + var dtfi = new CultureInfo("da-DK", false).DateTimeFormat; + var sut = ctor.Invoke(new object[] { dtfi }); + + Assert.Equal(dtfi.AMDesignator, (string)type.GetProperty("AMDesignator").GetValue(sut)); + Assert.Equal(dtfi.CalendarWeekRule, (CalendarWeekRule)type.GetProperty("CalendarWeekRule").GetValue(sut)); + Assert.Equal(dtfi.DateSeparator, (string)type.GetProperty("DateSeparator").GetValue(sut)); + Assert.Equal(dtfi.FirstDayOfWeek, (DayOfWeek)type.GetProperty("FirstDayOfWeek").GetValue(sut)); + Assert.Equal(dtfi.FullDateTimePattern, (string)type.GetProperty("FullDateTimePattern").GetValue(sut)); + Assert.Equal(dtfi.LongDatePattern, (string)type.GetProperty("LongDatePattern").GetValue(sut)); + Assert.Equal(dtfi.LongTimePattern, (string)type.GetProperty("LongTimePattern").GetValue(sut)); + Assert.Equal(dtfi.MonthDayPattern, (string)type.GetProperty("MonthDayPattern").GetValue(sut)); + Assert.Equal(dtfi.PMDesignator, (string)type.GetProperty("PMDesignator").GetValue(sut)); + Assert.Equal(dtfi.ShortDatePattern, (string)type.GetProperty("ShortDatePattern").GetValue(sut)); + Assert.Equal(dtfi.ShortTimePattern, (string)type.GetProperty("ShortTimePattern").GetValue(sut)); + Assert.Equal(dtfi.TimeSeparator, (string)type.GetProperty("TimeSeparator").GetValue(sut)); + Assert.Equal(dtfi.YearMonthPattern, (string)type.GetProperty("YearMonthPattern").GetValue(sut)); + Assert.Equal(dtfi.ShortestDayNames, (string[])type.GetProperty("ShortestDayNames").GetValue(sut)); + Assert.Equal(dtfi.AbbreviatedDayNames, (string[])type.GetProperty("AbbreviatedDayNames").GetValue(sut)); + Assert.Equal(dtfi.AbbreviatedMonthNames, (string[])type.GetProperty("AbbreviatedMonthNames").GetValue(sut)); + Assert.Equal(dtfi.AbbreviatedMonthGenitiveNames, (string[])type.GetProperty("AbbreviatedMonthGenitiveNames").GetValue(sut)); + + TestOutput.WriteLine($"ShortDatePattern: {(string)type.GetProperty("ShortDatePattern").GetValue(sut)}"); + } + } +} diff --git a/test/Codebelt.Extensions.Globalization.Tests/NumberFormatInfoSurrogateTest.cs b/test/Codebelt.Extensions.Globalization.Tests/NumberFormatInfoSurrogateTest.cs new file mode 100644 index 0000000..1843048 --- /dev/null +++ b/test/Codebelt.Extensions.Globalization.Tests/NumberFormatInfoSurrogateTest.cs @@ -0,0 +1,55 @@ +using System.Globalization; +using System.Reflection; +using Codebelt.Extensions.Xunit; +using Xunit; + +namespace Codebelt.Extensions.Globalization +{ + public class NumberFormatInfoSurrogateTest : Test + { + public NumberFormatInfoSurrogateTest(ITestOutputHelper output) : base(output) + { + } + + [Fact] + public void Constructor_ShouldCopyAllPropertiesFromNumberFormatInfo_WhenNumberFormatInfoIsProvided() + { + var assembly = typeof(CultureInfoExtensions).Assembly; + var type = assembly.GetType("Codebelt.Extensions.Globalization.NumberFormatInfoSurrogate"); + var ctor = type.GetConstructor( + BindingFlags.Instance | BindingFlags.NonPublic, + null, + new[] { typeof(NumberFormatInfo) }, + null); + + var nfi = new CultureInfo("da-DK", false).NumberFormat; + var sut = ctor.Invoke(new object[] { nfi }); + + Assert.Equal(nfi.CurrencyDecimalDigits, (int)type.GetProperty("CurrencyDecimalDigits").GetValue(sut)); + Assert.Equal(nfi.CurrencyDecimalSeparator, (string)type.GetProperty("CurrencyDecimalSeparator").GetValue(sut)); + Assert.Equal(nfi.CurrencyGroupSeparator, (string)type.GetProperty("CurrencyGroupSeparator").GetValue(sut)); + Assert.Equal(nfi.CurrencyNegativePattern, (int)type.GetProperty("CurrencyNegativePattern").GetValue(sut)); + Assert.Equal(nfi.CurrencyPositivePattern, (int)type.GetProperty("CurrencyPositivePattern").GetValue(sut)); + Assert.Equal(nfi.CurrencySymbol, (string)type.GetProperty("CurrencySymbol").GetValue(sut)); + Assert.Equal(nfi.DigitSubstitution, (DigitShapes)type.GetProperty("DigitSubstitution").GetValue(sut)); + Assert.Equal(nfi.NaNSymbol, (string)type.GetProperty("NaNSymbol").GetValue(sut)); + Assert.Equal(nfi.NegativeInfinitySymbol, (string)type.GetProperty("NegativeInfinitySymbol").GetValue(sut)); + Assert.Equal(nfi.NegativeSign, (string)type.GetProperty("NegativeSign").GetValue(sut)); + Assert.Equal(nfi.NumberDecimalDigits, (int)type.GetProperty("NumberDecimalDigits").GetValue(sut)); + Assert.Equal(nfi.NumberDecimalSeparator, (string)type.GetProperty("NumberDecimalSeparator").GetValue(sut)); + Assert.Equal(nfi.NumberGroupSeparator, (string)type.GetProperty("NumberGroupSeparator").GetValue(sut)); + Assert.Equal(nfi.NumberNegativePattern, (int)type.GetProperty("NumberNegativePattern").GetValue(sut)); + Assert.Equal(nfi.PerMilleSymbol, (string)type.GetProperty("PerMilleSymbol").GetValue(sut)); + Assert.Equal(nfi.PercentDecimalDigits, (int)type.GetProperty("PercentDecimalDigits").GetValue(sut)); + Assert.Equal(nfi.PercentDecimalSeparator, (string)type.GetProperty("PercentDecimalSeparator").GetValue(sut)); + Assert.Equal(nfi.PercentGroupSeparator, (string)type.GetProperty("PercentGroupSeparator").GetValue(sut)); + Assert.Equal(nfi.PercentNegativePattern, (int)type.GetProperty("PercentNegativePattern").GetValue(sut)); + Assert.Equal(nfi.PercentPositivePattern, (int)type.GetProperty("PercentPositivePattern").GetValue(sut)); + Assert.Equal(nfi.PercentSymbol, (string)type.GetProperty("PercentSymbol").GetValue(sut)); + Assert.Equal(nfi.PositiveInfinitySymbol, (string)type.GetProperty("PositiveInfinitySymbol").GetValue(sut)); + Assert.Equal(nfi.PositiveSign, (string)type.GetProperty("PositiveSign").GetValue(sut)); + + TestOutput.WriteLine($"CurrencySymbol: {(string)type.GetProperty("CurrencySymbol").GetValue(sut)}"); + } + } +}