From ee4020859ac8f7ee61f8d58231763dfb94e7ee5f Mon Sep 17 00:00:00 2001 From: cristi-badila Date: Thu, 4 Dec 2014 15:28:28 +0200 Subject: [PATCH] adds missing resources/tests for the Romanian locale and modifies the RomanianFormatter so as to make it clearer what's happening and remove resource duplication --- release_notes.md | 1 + src/Humanizer.Tests/Humanizer.Tests.csproj | 1 + .../Localisation/ResourcesTests.cs | 8 +- .../Localisation/ro-Ro/DateHumanizeTests.cs | 108 +++++++++++------- .../ro-Ro/TimeSpanHumanizerTests.cs | 85 ++++++++++++++ .../Formatters/RomanianFormatter.cs | 35 ++++-- src/Humanizer/Properties/Resources.ro.resx | 98 +++++++++++++--- 7 files changed, 265 insertions(+), 71 deletions(-) create mode 100644 src/Humanizer.Tests/Localisation/ro-Ro/TimeSpanHumanizerTests.cs diff --git a/release_notes.md b/release_notes.md index d8a365766..a44810d26 100644 --- a/release_notes.md +++ b/release_notes.md @@ -1,4 +1,5 @@ ###In Development + - [#356](https://github.com/MehdiK/Humanizer/pull/356): Added missing values for ro and changed the RomanianFormatter implementation so as to avoid duplicate resources - [#350](https://github.com/MehdiK/Humanizer/pull/350): Added missing values for nl [Commits](https://github.com/MehdiK/Humanizer/compare/v1.31.0...master) diff --git a/src/Humanizer.Tests/Humanizer.Tests.csproj b/src/Humanizer.Tests/Humanizer.Tests.csproj index e557a818e..1201ceecd 100644 --- a/src/Humanizer.Tests/Humanizer.Tests.csproj +++ b/src/Humanizer.Tests/Humanizer.Tests.csproj @@ -106,6 +106,7 @@ + diff --git a/src/Humanizer.Tests/Localisation/ResourcesTests.cs b/src/Humanizer.Tests/Localisation/ResourcesTests.cs index 54f061164..46e3b5636 100644 --- a/src/Humanizer.Tests/Localisation/ResourcesTests.cs +++ b/src/Humanizer.Tests/Localisation/ResourcesTests.cs @@ -11,16 +11,16 @@ public void CanGetCultureSpecificTranslationsWithImplicitCulture() { using (new AmbientCulture("ro")) { - var format = Resources.GetResource("DateHumanize_MultipleYearsAgo_Above20"); - Assert.Equal("acum {0} de ani", format); + var format = Resources.GetResource("DateHumanize_MultipleYearsAgo"); + Assert.Equal("acum {0}{1} ani", format); } } [Fact] public void CanGetCultureSpecificTranslationsWithExplicitCulture() { - var format = Resources.GetResource("DateHumanize_MultipleYearsAgo_Above20", new CultureInfo("ro")); - Assert.Equal("acum {0} de ani", format); + var format = Resources.GetResource("DateHumanize_MultipleYearsAgo", new CultureInfo("ro")); + Assert.Equal("acum {0}{1} ani", format); } } } diff --git a/src/Humanizer.Tests/Localisation/ro-Ro/DateHumanizeTests.cs b/src/Humanizer.Tests/Localisation/ro-Ro/DateHumanizeTests.cs index 859e7dd32..84b3584c3 100644 --- a/src/Humanizer.Tests/Localisation/ro-Ro/DateHumanizeTests.cs +++ b/src/Humanizer.Tests/Localisation/ro-Ro/DateHumanizeTests.cs @@ -1,8 +1,9 @@ using Humanizer.Localisation; -using Xunit; namespace Humanizer.Tests.Localisation.roRo { + using Xunit.Extensions; + /// /// Test that for values bigger than 19 "de" is added between the numeral /// and the time unit: http://ebooks.unibuc.ro/filologie/NForascu-DGLR/numerale.htm. @@ -14,70 +15,93 @@ public DateHumanizeTests() : base("ro-RO") { } - [Fact] - public void RomanianTranslationIsCorrectForThreeHoursAgo() + [Theory] + [InlineData(3, "acum 3 ore")] + [InlineData(20, "acum 20 de ore")] + public void HoursAgo(int hours, string expected) { - DateHumanize.Verify("acum 3 ore", 3, TimeUnit.Hour, Tense.Past); + DateHumanize.Verify(expected, hours, TimeUnit.Hour, Tense.Past); } - [Fact] - public void RomanianTranslationIsCorrectFor20HoursAgo() + [Theory] + [InlineData(19, "acum 19 minute")] + [InlineData(60, "acum o oră")] + [InlineData(44, "acum 44 de minute")] + public void MinutesAgo(int minutes, string expected) { - DateHumanize.Verify("acum 20 de ore", 20, TimeUnit.Hour, Tense.Past); + DateHumanize.Verify(expected, minutes, TimeUnit.Minute, Tense.Past); } - - [Fact] - public void RomanianTranslationIsCorrectFor19MinutesAgo() + + [Theory] + [InlineData(2, "acum 2 secunde")] + [InlineData(59, "acum 59 de secunde")] + public void SecondsAgo(int seconds, string expected) { - DateHumanize.Verify("acum 19 minute", 19, TimeUnit.Minute, Tense.Past); + DateHumanize.Verify(expected, seconds, TimeUnit.Second, Tense.Past); } - - [Fact] - public void RomanianTranslationIsCorrectFor60MinutesAgo() + + [Theory] + [InlineData(10, "acum 10 zile")] + [InlineData(23, "acum 23 de zile")] + public void DaysAgo(int seconds, string expected) { - DateHumanize.Verify("acum o oră", 60, TimeUnit.Minute, Tense.Past); + DateHumanize.Verify(expected, seconds, TimeUnit.Day, Tense.Past); } - - [Fact] - public void RomanianTranslationIsCorrectFor44MinutesAgo() + + [Theory] + [InlineData(119, "acum 119 ani")] + [InlineData(100, "acum 100 de ani")] + public void YearsAgo(int seconds, string expected) { - DateHumanize.Verify("acum 44 de minute", 44, TimeUnit.Minute, Tense.Past); + DateHumanize.Verify(expected, seconds, TimeUnit.Year, Tense.Past); } - - [Fact] - public void RomanianTranslationIsCorrectFor2SecondsAgo() + + [Theory] + [InlineData(1, "acum")] + [InlineData(22, "acum")] + public void MillisecondsAgo(int milliseconds, string expected) { - DateHumanize.Verify("acum 2 secunde", 2, TimeUnit.Second, Tense.Past); + DateHumanize.Verify(expected, milliseconds, TimeUnit.Millisecond, Tense.Past); } - - [Fact] - public void RomanianTranslationIsCorrectFor59SecondsAgo() + + [Theory] + [InlineData(19, "peste 19 secunde")] + [InlineData(21, "peste 21 de secunde")] + public void SecondsFromNow(int seconds, string expected) { - DateHumanize.Verify("acum 59 de secunde", 59, TimeUnit.Second, Tense.Past); + DateHumanize.Verify(expected, seconds, TimeUnit.Second, Tense.Future); } - - [Fact] - public void RomanianTranslationIsCorrectFor10DaysAgo() + + [Theory] + [InlineData(19, "peste 19 minute")] + [InlineData(22, "peste 22 de minute")] + public void MinutesFromNow(int minutes, string expected) { - DateHumanize.Verify("acum 10 zile", 10, TimeUnit.Day, Tense.Past); + DateHumanize.Verify(expected, minutes, TimeUnit.Minute, Tense.Future); } - - [Fact] - public void RomanianTranslationIsCorrectFor23DaysAgo() + + [Theory] + [InlineData(3, "peste 3 ore")] + [InlineData(23, "peste 23 de ore")] + public void HoursFromNow(int hours, string expected) { - DateHumanize.Verify("acum 23 de zile", 23, TimeUnit.Day, Tense.Past); + DateHumanize.Verify(expected, hours, TimeUnit.Hour, Tense.Future); } - [Fact] - public void RomanianTranslationIsCorrectFor119YearsAgo() + [Theory] + [InlineData(5, "peste 5 zile")] + [InlineData(23, "peste 23 de zile")] + public void DaysFromNow(int days, string expected) { - DateHumanize.Verify("acum 119 ani", 119, TimeUnit.Year, Tense.Past); + DateHumanize.Verify(expected, days, TimeUnit.Day, Tense.Future); } - - [Fact] - public void RomanianTranslationIsCorrectFor100YearsAgo() + + [Theory] + [InlineData(5, "peste 5 ani")] + [InlineData(21, "peste 21 de ani")] + public void YearsFromNow(int years, string expected) { - DateHumanize.Verify("acum 100 de ani", 100, TimeUnit.Year, Tense.Past); + DateHumanize.Verify(expected, years, TimeUnit.Year, Tense.Future); } } } \ No newline at end of file diff --git a/src/Humanizer.Tests/Localisation/ro-Ro/TimeSpanHumanizerTests.cs b/src/Humanizer.Tests/Localisation/ro-Ro/TimeSpanHumanizerTests.cs new file mode 100644 index 000000000..d39a59e58 --- /dev/null +++ b/src/Humanizer.Tests/Localisation/ro-Ro/TimeSpanHumanizerTests.cs @@ -0,0 +1,85 @@ +namespace Humanizer.Tests.Localisation.roRo +{ + using System; + + using Xunit; + using Xunit.Extensions; + + /// + /// Test that for values bigger than 19 "de" is added between the numeral + /// and the time unit: http://ebooks.unibuc.ro/filologie/NForascu-DGLR/numerale.htm. + /// There is no test for years since there are only 12 of them in a year. + /// + public class TimeSpanHumanizerTests : AmbientCulture + { + public TimeSpanHumanizerTests() : base("ro-RO") + { + } + + [Theory] + [InlineData(1, "1 milisecundă")] + [InlineData(14, "14 milisecunde")] + [InlineData(21, "21 de milisecunde")] + [InlineData(3000, "3 secunde")] + public void Milliseconds(int millisSeconds, string expected) + { + var actual = TimeSpan.FromMilliseconds(millisSeconds).Humanize(); + Assert.Equal(expected, actual); + } + + [Theory] + [InlineData(1, "1 secundă")] + [InlineData(14, "14 secunde")] + [InlineData(21, "21 de secunde")] + [InlineData(156, "2 minute")] + public void Seconds(int seconds, string expected) + { + var actual = TimeSpan.FromSeconds(seconds).Humanize(); + Assert.Equal(expected, actual); + } + + [Theory] + [InlineData(1, "1 minut")] + [InlineData(14, "14 minute")] + [InlineData(21, "21 de minute")] + [InlineData(156, "2 ore")] + public void Minutes(int minutes, string expected) + { + var actual = TimeSpan.FromMinutes(minutes).Humanize(); + Assert.Equal(expected, actual); + } + + [Theory] + [InlineData(1, "1 oră")] + [InlineData(14, "14 ore")] + [InlineData(21, "21 de ore")] + [InlineData(48, "2 zile")] + public void Hours(int hours, string expected) + { + var actual = TimeSpan.FromHours(hours).Humanize(); + Assert.Equal(expected, actual); + } + + [Theory] + [InlineData(1, "1 zi")] + [InlineData(6, "6 zile")] + [InlineData(7, "1 săptămână")] + [InlineData(14, "2 săptămâni")] + [InlineData(21, "3 săptămâni")] + public void Days(int days, string expected) + { + var actual = TimeSpan.FromDays(days).Humanize(); + Assert.Equal(expected, actual); + } + + [Theory] + [InlineData(1, "1 săptămână")] + [InlineData(14, "14 săptămâni")] + [InlineData(21, "21 de săptămâni")] + public void Weeks(int weeks, string expected) + { + var actual = TimeSpan.FromDays(7 * weeks).Humanize(); + Assert.Equal(expected, actual); + } + } +} \ No newline at end of file diff --git a/src/Humanizer/Localisation/Formatters/RomanianFormatter.cs b/src/Humanizer/Localisation/Formatters/RomanianFormatter.cs index ab0e406e9..362194002 100644 --- a/src/Humanizer/Localisation/Formatters/RomanianFormatter.cs +++ b/src/Humanizer/Localisation/Formatters/RomanianFormatter.cs @@ -1,24 +1,41 @@ namespace Humanizer.Localisation.Formatters { + using System; + using System.Globalization; + internal class RomanianFormatter : DefaultFormatter { - private const string Above20PostFix = "_Above20"; + private const int PrepositionIndicatingDecimals = 2; + private const int MaxNumeralWithNoPreposition = 19; + private const int MinNumeralWithNoPreposition = 1; + private const string PrepositionResourceKey = "UnitPreposition"; + private const string RomanianCultureCode = "ro"; + + private static readonly double Divider = Math.Pow(10, PrepositionIndicatingDecimals); + + private readonly CultureInfo romanianCulture; public RomanianFormatter() - : base("ro") + : base(RomanianCultureCode) { + romanianCulture = new CultureInfo(RomanianCultureCode); } - protected override string GetResourceKey(string resourceKey, int number) + protected override string Format(string resourceKey, int number) { - var mod100 = number%100; + var format = Resources.GetResource(GetResourceKey(resourceKey, number), romanianCulture); + var preposition = ShouldUsePreposition(number) + ? Resources.GetResource(PrepositionResourceKey, romanianCulture) + : string.Empty; - if (0 < mod100 && mod100 < 20) - { - return resourceKey; - } + return format.FormatWith(number, preposition); + } - return resourceKey + Above20PostFix; + private static bool ShouldUsePreposition(int number) + { + var prepositionIndicatingNumeral = Math.Abs(number % Divider); + return prepositionIndicatingNumeral < MinNumeralWithNoPreposition + || prepositionIndicatingNumeral > MaxNumeralWithNoPreposition; } } } diff --git a/src/Humanizer/Properties/Resources.ro.resx b/src/Humanizer/Properties/Resources.ro.resx index 4c61c5524..ba393d2d7 100644 --- a/src/Humanizer/Properties/Resources.ro.resx +++ b/src/Humanizer/Properties/Resources.ro.resx @@ -121,51 +121,117 @@ acum o secundă - acum {0} secunde + acum {0}{1} secunde acum un minut - acum {0} minute + acum {0}{1} minute acum o oră - acum {0} ore + acum {0}{1} ore ieri - acum {0} zile + acum {0}{1} zile acum o lună - acum {0} luni + acum {0}{1} luni acum un an - acum {0} ani + acum {0}{1} ani - - acum {0} de zile + + acum - - acum {0} de ore + + peste {0}{1} zile - - acum {0} de minute + + peste {0}{1} ore - - acum {0} de secunde + + peste {0}{1} minute - - acum {0} de ani + + peste {0}{1} luni + + + peste {0}{1} secunde + + + peste {0}{1} ani + + + mâine + + + peste o oră + + + peste un minut + + + peste o lună + + + peste o secundă + + + peste un an + + + de + + + {0}{1} zile + + + {0}{1} ore + + + {0}{1} milisecunde + + + {0}{1} minute + + + {0}{1} secunde + + + {0}{1} săptămâni + + + 1 zi + + + 1 oră + + + 1 milisecundă + + + 1 minut + + + 1 secundă + + + 1 săptămână + + + niciun timp \ No newline at end of file