diff --git a/src/Humanizer.Tests/ApiApprover/PublicApiApprovalTest.Approve_Public_Api.Net4_8.verified.txt b/src/Humanizer.Tests/ApiApprover/PublicApiApprovalTest.Approve_Public_Api.Net4_8.verified.txt
index cc662617a..91c0fcda2 100644
--- a/src/Humanizer.Tests/ApiApprover/PublicApiApprovalTest.Approve_Public_Api.Net4_8.verified.txt
+++ b/src/Humanizer.Tests/ApiApprover/PublicApiApprovalTest.Approve_Public_Api.Net4_8.verified.txt
@@ -199,16 +199,14 @@ namespace Humanizer
}
public class DefaultFormatter : Humanizer.IFormatter
{
- public DefaultFormatter(System.Globalization.CultureInfo culture) { }
- public DefaultFormatter(string localeCode) { }
+ public DefaultFormatter(System.Globalization.CultureInfo culture, IResources resources) { }
+ public DefaultFormatter(string localeCode, IResources resources) { }
protected System.Globalization.CultureInfo Culture { get; }
public virtual string DataUnitHumanize(Humanizer.DataUnit dataUnit, double count, bool toSymbol = true) { }
public virtual string DateHumanize(Humanizer.TimeUnit timeUnit, Humanizer.Tense timeUnitTense, int unit) { }
public virtual string DateHumanize_Never() { }
public virtual string DateHumanize_Now() { }
- protected virtual string Format(string resourceKey) { }
protected virtual string Format(Humanizer.TimeUnit unit, string resourceKey, int number, bool toWords = false) { }
- protected virtual string GetResourceKey(string resourceKey) { }
protected virtual string GetResourceKey(string resourceKey, int number) { }
protected virtual string NumberToWords(Humanizer.TimeUnit unit, int number, System.Globalization.CultureInfo culture) { }
public virtual string TimeSpanHumanize(Humanizer.TimeUnit timeUnit, int unit, bool toWords = false) { }
@@ -1174,13 +1172,10 @@ namespace Humanizer
{
public static string GetResourceKey(Humanizer.TimeUnit unit, int count = 1, bool toWords = false) { }
}
- public static class TimeUnitSymbol
- {
- public static string GetResourceKey(Humanizer.TimeUnit unit) { }
- }
}
public static class Resources
{
+ public static readonly System.Resources.ResourceManager ResourceManager;
public static string GetResource(string resourceKey, System.Globalization.CultureInfo? culture = null) { }
public static bool TryGetResource(string resourceKey, System.Globalization.CultureInfo? culture, [System.Diagnostics.CodeAnalysis.NotNullWhen(true)] out string? result) { }
}
@@ -1294,4 +1289,194 @@ namespace Humanizer
Abbreviation = 1,
Eifeler = 2,
}
+}
+public interface IResources
+{
+ string Culture { get; }
+ string DataUnitBit { get; }
+ string DataUnitBitSymbol { get; }
+ string DataUnitByte { get; }
+ string DataUnitByteSymbol { get; }
+ string DataUnitGigabyte { get; }
+ string DataUnitGigabyteSymbol { get; }
+ string DataUnitKilobyte { get; }
+ string DataUnitKilobyteSymbol { get; }
+ string DataUnitMegabyte { get; }
+ string DataUnitMegabyteSymbol { get; }
+ string DataUnitTerabyte { get; }
+ string DataUnitTerabyteSymbol { get; }
+ string DateMultipleDaysAgo { get; }
+ string DateMultipleDaysAgoDual { get; }
+ string DateMultipleDaysAgoPaucal { get; }
+ string DateMultipleDaysAgoPlural { get; }
+ string DateMultipleDaysAgoSingular { get; }
+ string DateMultipleDaysFromNow { get; }
+ string DateMultipleDaysFromNowDual { get; }
+ string DateMultipleDaysFromNowPaucal { get; }
+ string DateMultipleDaysFromNowPlural { get; }
+ string DateMultipleDaysFromNowSingular { get; }
+ string DateMultipleHoursAgo { get; }
+ string DateMultipleHoursAgoDual { get; }
+ string DateMultipleHoursAgoPaucal { get; }
+ string DateMultipleHoursAgoPlural { get; }
+ string DateMultipleHoursAgoSingular { get; }
+ string DateMultipleHoursFromNow { get; }
+ string DateMultipleHoursFromNowDual { get; }
+ string DateMultipleHoursFromNowPaucal { get; }
+ string DateMultipleHoursFromNowPlural { get; }
+ string DateMultipleHoursFromNowSingular { get; }
+ string DateMultipleMinutesAgo { get; }
+ string DateMultipleMinutesAgoDual { get; }
+ string DateMultipleMinutesAgoPaucal { get; }
+ string DateMultipleMinutesAgoPlural { get; }
+ string DateMultipleMinutesAgoSingular { get; }
+ string DateMultipleMinutesFromNow { get; }
+ string DateMultipleMinutesFromNowDual { get; }
+ string DateMultipleMinutesFromNowPaucal { get; }
+ string DateMultipleMinutesFromNowPlural { get; }
+ string DateMultipleMinutesFromNowSingular { get; }
+ string DateMultipleMonthsAgo { get; }
+ string DateMultipleMonthsAgoDual { get; }
+ string DateMultipleMonthsAgoPaucal { get; }
+ string DateMultipleMonthsAgoPlural { get; }
+ string DateMultipleMonthsAgoSingular { get; }
+ string DateMultipleMonthsFromNow { get; }
+ string DateMultipleMonthsFromNowDual { get; }
+ string DateMultipleMonthsFromNowPaucal { get; }
+ string DateMultipleMonthsFromNowPlural { get; }
+ string DateMultipleMonthsFromNowSingular { get; }
+ string DateMultipleSecondsAgo { get; }
+ string DateMultipleSecondsAgoDual { get; }
+ string DateMultipleSecondsAgoPaucal { get; }
+ string DateMultipleSecondsAgoPlural { get; }
+ string DateMultipleSecondsAgoSingular { get; }
+ string DateMultipleSecondsFromNow { get; }
+ string DateMultipleSecondsFromNowDual { get; }
+ string DateMultipleSecondsFromNowPaucal { get; }
+ string DateMultipleSecondsFromNowPlural { get; }
+ string DateMultipleSecondsFromNowSingular { get; }
+ string DateMultipleYearsAgo { get; }
+ string DateMultipleYearsAgoDual { get; }
+ string DateMultipleYearsAgoPaucal { get; }
+ string DateMultipleYearsAgoPlural { get; }
+ string DateMultipleYearsAgoSingular { get; }
+ string DateMultipleYearsFromNow { get; }
+ string DateMultipleYearsFromNowDual { get; }
+ string DateMultipleYearsFromNowPaucal { get; }
+ string DateMultipleYearsFromNowPlural { get; }
+ string DateMultipleYearsFromNowSingular { get; }
+ string DateNever { get; }
+ string DateNow { get; }
+ string DateSingleDayAgo { get; }
+ string DateSingleDayFromNow { get; }
+ string DateSingleHourAgo { get; }
+ string DateSingleHourFromNow { get; }
+ string DateSingleMinuteAgo { get; }
+ string DateSingleMinuteFromNow { get; }
+ string DateSingleMonthAgo { get; }
+ string DateSingleMonthFromNow { get; }
+ string DateSingleSecondAgo { get; }
+ string DateSingleSecondFromNow { get; }
+ string DateSingleYearAgo { get; }
+ string DateSingleYearFromNow { get; }
+ string DateTwoDaysAgo { get; }
+ string DateTwoDaysFromNow { get; }
+ string E { get; }
+ string ENE { get; }
+ string ENEShort { get; }
+ string ESE { get; }
+ string ESEShort { get; }
+ string EShort { get; }
+ string N { get; }
+ string NE { get; }
+ string NEShort { get; }
+ string NNE { get; }
+ string NNEShort { get; }
+ string NNW { get; }
+ string NNWShort { get; }
+ string NShort { get; }
+ string NW { get; }
+ string NWShort { get; }
+ string S { get; }
+ string SE { get; }
+ string SEShort { get; }
+ string SSE { get; }
+ string SSEShort { get; }
+ string SSW { get; }
+ string SSWShort { get; }
+ string SShort { get; }
+ string SW { get; }
+ string SWShort { get; }
+ string TimeSpanAge { get; }
+ string TimeSpanMultipleDays { get; }
+ string TimeSpanMultipleDaysDual { get; }
+ string TimeSpanMultipleDaysPaucal { get; }
+ string TimeSpanMultipleDaysPlural { get; }
+ string TimeSpanMultipleDaysSingular { get; }
+ string TimeSpanMultipleHours { get; }
+ string TimeSpanMultipleHoursDual { get; }
+ string TimeSpanMultipleHoursPaucal { get; }
+ string TimeSpanMultipleHoursPlural { get; }
+ string TimeSpanMultipleHoursSingular { get; }
+ string TimeSpanMultipleMilliseconds { get; }
+ string TimeSpanMultipleMillisecondsDual { get; }
+ string TimeSpanMultipleMillisecondsPaucal { get; }
+ string TimeSpanMultipleMillisecondsPlural { get; }
+ string TimeSpanMultipleMillisecondsSingular { get; }
+ string TimeSpanMultipleMinutes { get; }
+ string TimeSpanMultipleMinutesDual { get; }
+ string TimeSpanMultipleMinutesPaucal { get; }
+ string TimeSpanMultipleMinutesPlural { get; }
+ string TimeSpanMultipleMinutesSingular { get; }
+ string TimeSpanMultipleMonths { get; }
+ string TimeSpanMultipleMonthsDual { get; }
+ string TimeSpanMultipleMonthsPaucal { get; }
+ string TimeSpanMultipleMonthsPlural { get; }
+ string TimeSpanMultipleMonthsSingular { get; }
+ string TimeSpanMultipleSeconds { get; }
+ string TimeSpanMultipleSecondsDual { get; }
+ string TimeSpanMultipleSecondsPaucal { get; }
+ string TimeSpanMultipleSecondsPlural { get; }
+ string TimeSpanMultipleSecondsSingular { get; }
+ string TimeSpanMultipleWeeks { get; }
+ string TimeSpanMultipleWeeksDual { get; }
+ string TimeSpanMultipleWeeksPaucal { get; }
+ string TimeSpanMultipleWeeksPlural { get; }
+ string TimeSpanMultipleWeeksSingular { get; }
+ string TimeSpanMultipleYears { get; }
+ string TimeSpanMultipleYearsDual { get; }
+ string TimeSpanMultipleYearsPaucal { get; }
+ string TimeSpanMultipleYearsPlural { get; }
+ string TimeSpanMultipleYearsSingular { get; }
+ string TimeSpanSingleDay { get; }
+ string TimeSpanSingleDayWords { get; }
+ string TimeSpanSingleHour { get; }
+ string TimeSpanSingleHourWords { get; }
+ string TimeSpanSingleMillisecond { get; }
+ string TimeSpanSingleMillisecondWords { get; }
+ string TimeSpanSingleMinute { get; }
+ string TimeSpanSingleMinuteWords { get; }
+ string TimeSpanSingleMonth { get; }
+ string TimeSpanSingleMonthWords { get; }
+ string TimeSpanSingleSecond { get; }
+ string TimeSpanSingleSecondWords { get; }
+ string TimeSpanSingleWeek { get; }
+ string TimeSpanSingleWeekWords { get; }
+ string TimeSpanSingleYear { get; }
+ string TimeSpanSingleYearWords { get; }
+ string TimeSpanZero { get; }
+ string TimeUnitDay { get; }
+ string TimeUnitHour { get; }
+ string TimeUnitMillisecond { get; }
+ string TimeUnitMinute { get; }
+ string TimeUnitMonth { get; }
+ string TimeUnitSecond { get; }
+ string TimeUnitWeek { get; }
+ string TimeUnitYear { get; }
+ string W { get; }
+ string WNW { get; }
+ string WNWShort { get; }
+ string WSW { get; }
+ string WSWShort { get; }
+ string WShort { get; }
}
\ No newline at end of file
diff --git a/src/Humanizer.Tests/Humanizer.Tests.csproj b/src/Humanizer.Tests/Humanizer.Tests.csproj
index cbf5fc457..b1b8a7493 100644
--- a/src/Humanizer.Tests/Humanizer.Tests.csproj
+++ b/src/Humanizer.Tests/Humanizer.Tests.csproj
@@ -1,14 +1,15 @@
- net8.0;net48
+ net48
+
-
+
@@ -16,6 +17,7 @@
PreserveNewest
+
diff --git a/src/Humanizer.Tests/MergeResources.cs b/src/Humanizer.Tests/MergeResources.cs
new file mode 100644
index 000000000..8499ea523
--- /dev/null
+++ b/src/Humanizer.Tests/MergeResources.cs
@@ -0,0 +1,143 @@
+using System.Collections;
+using System.Resources;
+
+public class MergeResources
+{
+ [Fact]
+ public async Task Foo()
+ {
+
+ var cultureInfos = CultureInfo.GetCultures(CultureTypes.AllCultures);
+ var dir = @"C:\Code\Humanizer\src\Humanizer\Resources";
+ foreach (var file in Directory.EnumerateFiles(dir,"*.cs"))
+ {
+ File.Delete(file);
+ }
+ var files = Directory.EnumerateFiles(@"C:\Code\Humanizer\src\Humanizer\Properties", "*.resx").ToList();
+ var invarientFile = @"C:\Code\Humanizer\src\Humanizer\Properties\Resources.resx";
+ var keys = await WriteInvarient(dir, invarientFile);
+ await WriteClass(dir, CultureInfo.InvariantCulture, invarientFile, keys);
+ foreach (var file in files)
+ {
+ if (file.EndsWith("Resources.resx"))
+ {
+ continue;
+ }
+ var culture = Culture(file, cultureInfos);
+
+ await WriteClass(dir, culture, file, keys);
+ }
+ }
+
+ static async Task WriteClass(string dir, CultureInfo culture, string file, List keys)
+ {
+ keys = new(keys);
+ var className = GetClassName(culture);
+ var combine = Path.Combine(dir, $"{className}.cs");
+ using var writer = File.CreateText(combine);
+ await writer.WriteLineAsync(
+ $$"""
+ class {{className}} : IResources
+ {
+ public string Culture => "{{culture.Name}}";
+ public static {{className}} Instance => new();
+ """);
+
+ using var reader = new ResXResourceReader(file);
+ foreach (DictionaryEntry entry in reader)
+ {
+ var key = (string) entry.Key;
+ key = ScrubKey(key);
+ keys.Remove(key);
+ await writer.WriteLineAsync(
+ $$"""
+ public string {{key}} => "{{entry.Value}}";
+ """);
+ }
+
+ if(File.Exists($@"C:\Code\Humanizer\src\Humanizer\Properties\Resources.{culture.Parent.Name}.resx"))
+ {
+ var parentClassName = GetClassName(culture.Parent);
+ foreach (var key in keys)
+ {
+ await writer.WriteLineAsync(
+ $"""
+ public string {key} => {parentClassName}.Instance.{key};
+ """);
+ }
+ }
+ else
+ {
+ foreach (var key in keys)
+ {
+ await writer.WriteLineAsync(
+ $$"""
+ public string {{key}} => InvariantResources.Instance.{{key}};
+ """);
+ }
+ }
+
+ await writer.WriteLineAsync("}");
+ }
+
+ static string GetClassName(CultureInfo culture)
+ {
+ if (Equals(culture, CultureInfo.InvariantCulture))
+ {
+ return $"InvariantResources";
+ }
+
+ var name = culture.DisplayName
+ .Replace(" ","")
+ .Replace(",","")
+ .Replace(")","")
+ .Replace("(","");
+ return $"{name}Resources";
+ }
+
+ static string ScrubKey(string key) =>
+ key
+ .Replace("DateHumanize_", "Date_")
+ .Replace("TimeSpanHumanize_", "TimeSpan_")
+ .Replace("_", "");
+
+ static async Task> WriteInvarient(string dir, string file)
+ {
+ var keys = new List();
+ var combine = Path.Combine(dir, "IResources.cs");
+ using var writer = File.CreateText(combine);
+ await writer.WriteLineAsync(
+ $$"""
+ public interface IResources
+ {
+ public string Culture { get; }
+ """);
+
+ using var reader = new ResXResourceReader(file);
+ foreach (DictionaryEntry entry in reader)
+ {
+ var key = (string) entry.Key;
+ key = ScrubKey(key);
+ await writer.WriteLineAsync(
+ $$"""
+ public string {{key}} { get; }
+ """);
+ keys.Add(key);
+ }
+
+ await writer.WriteLineAsync("}");
+ return keys;
+ }
+
+ static CultureInfo Culture(string file, CultureInfo[] cultureInfos)
+ {
+ if (file == "C:\\Code\\Humanizer\\src\\Humanizer\\Properties\\Resources.resx")
+ {
+ return CultureInfo.InvariantCulture;
+ }
+ var culture = Path
+ .GetFileName(file)
+ .Split('.')[1];
+ return cultureInfos.Single(_ => _.Name == culture);
+ }
+}
\ No newline at end of file
diff --git a/src/Humanizer.Tests/ResourceKeyTests.cs b/src/Humanizer.Tests/ResourceKeyTests.cs
deleted file mode 100644
index 9fbd9d4d7..000000000
--- a/src/Humanizer.Tests/ResourceKeyTests.cs
+++ /dev/null
@@ -1,97 +0,0 @@
-#pragma warning disable xUnit1026 // Theory methods should use all of their parameters
-public class ResourceKeyTests
-{
- [Theory]
- [MemberData(nameof(DateHumanizeResourceKeys))]
- public void DateHumanizeKeysGeneration(int instance, string expected, string actual) =>
- Assert.Equal(expected, actual);
-
- [Theory]
- [MemberData(nameof(TimeSpanHumanizeResourceKeys))]
- public void TimeSpanHumanizeKeysGeneration(int instance, string expected, string actual) =>
- Assert.Equal(expected, actual);
-
- [Theory]
- [MemberData(nameof(DateHumanizeResourceKeys))]
- public void DateHumanizeKeysExistence(int instance, string expectedResourceKey, string generatedResourceKey) =>
- Assert.NotNull(Resources.GetResource(generatedResourceKey));
-
- [Theory]
- [MemberData(nameof(TimeSpanHumanizeResourceKeys))]
- public void TimeSpanHumanizeKeysExistence(int instance, string expectedResourceKey, string generatedResourceKey) =>
- Assert.NotNull(Resources.GetResource(generatedResourceKey));
-
- public static IEnumerable