diff --git a/src/Humanizer.Tests/AmbientCulture.cs b/src/Humanizer.Tests/AmbientCulture.cs index 4d857cd8d..c99735618 100644 --- a/src/Humanizer.Tests/AmbientCulture.cs +++ b/src/Humanizer.Tests/AmbientCulture.cs @@ -6,11 +6,11 @@ namespace Humanizer.Tests { public class AmbientCulture : IDisposable { - private readonly CultureInfo _culture; + private readonly CultureInfo _callerCulture; public AmbientCulture(CultureInfo culture) { - _culture = Thread.CurrentThread.CurrentUICulture; + _callerCulture = Thread.CurrentThread.CurrentUICulture; Thread.CurrentThread.CurrentCulture = culture; Thread.CurrentThread.CurrentUICulture = culture; } @@ -22,7 +22,8 @@ public AmbientCulture(string cultureName) public void Dispose() { - Thread.CurrentThread.CurrentUICulture = _culture; + Thread.CurrentThread.CurrentCulture = _callerCulture; + Thread.CurrentThread.CurrentUICulture = _callerCulture; } } } \ No newline at end of file diff --git a/src/Humanizer.Tests/DateHumanizeTests.cs b/src/Humanizer.Tests/DateHumanizeTests.cs index 9ff961f2e..9342e47d3 100644 --- a/src/Humanizer.Tests/DateHumanizeTests.cs +++ b/src/Humanizer.Tests/DateHumanizeTests.cs @@ -4,33 +4,8 @@ namespace Humanizer.Tests { - public class DateHumanizeTests + public class DateHumanizeTests : DateHumanizeTestsBase { - static void VerifyWithCurrentDate(string expectedString, TimeSpan deltaFromNow) - { - var utcNow = DateTime.UtcNow; - var localNow = DateTime.Now; - - // feels like the only way to avoid breaking tests because CPU ticks over is to inject the base date - Assert.Equal(expectedString, utcNow.Add(deltaFromNow).Humanize(utcDate: true, dateToCompareAgainst: utcNow)); - Assert.Equal(expectedString, localNow.Add(deltaFromNow).Humanize(utcDate: false, dateToCompareAgainst: localNow)); - } - - static void VerifyWithDateInjection(string expectedString, TimeSpan deltaFromNow) - { - var utcNow = new DateTime(2013, 6, 20, 9, 58, 22, DateTimeKind.Utc); - var now = new DateTime(2013, 6, 20, 11, 58, 22, DateTimeKind.Local); - - Assert.Equal(expectedString, utcNow.Add(deltaFromNow).Humanize(dateToCompareAgainst: utcNow)); - Assert.Equal(expectedString, now.Add(deltaFromNow).Humanize(false, now)); - } - - static void Verify(string expectedString, TimeSpan deltaFromNow) - { - VerifyWithCurrentDate(expectedString, deltaFromNow); - VerifyWithDateInjection(expectedString, deltaFromNow); - } - [Fact] public void OneSecondFromNow() { diff --git a/src/Humanizer.Tests/DateHumanizeTestsBase.cs b/src/Humanizer.Tests/DateHumanizeTestsBase.cs new file mode 100644 index 000000000..706de5b7c --- /dev/null +++ b/src/Humanizer.Tests/DateHumanizeTestsBase.cs @@ -0,0 +1,43 @@ +using System; +using Humanizer.Configuration; +using Humanizer.DistanceOfTimeCalculators; +using Xunit; + +namespace Humanizer.Tests +{ + public abstract class DateHumanizeTestsBase : IDisposable + { + private readonly IDistanceOfTimeInWords previousCalculator; + + protected DateHumanizeTestsBase() + { + previousCalculator = Configurator.DistanceOfTimeInWords; + } + + public void Dispose() + { + Configurator.DistanceOfTimeInWords = previousCalculator; + } + + protected static void Verify(string expectedString, TimeSpan deltaFromNow) + { + VerifyWithCurrentDate(expectedString, deltaFromNow); + VerifyWithDateInjection(expectedString, deltaFromNow); + } + + private static void VerifyWithCurrentDate(string expectedString, TimeSpan deltaFromNow) + { + Assert.Equal(expectedString, DateTime.UtcNow.Add(deltaFromNow).Humanize()); + Assert.Equal(expectedString, DateTime.Now.Add(deltaFromNow).Humanize(false)); + } + + private static void VerifyWithDateInjection(string expectedString, TimeSpan deltaFromNow) + { + var utcNow = new DateTime(2013, 6, 20, 9, 58, 22, DateTimeKind.Utc); + var now = new DateTime(2013, 6, 20, 11, 58, 22, DateTimeKind.Local); + + Assert.Equal(expectedString, utcNow.Add(deltaFromNow).Humanize(dateToCompareAgainst: utcNow)); + Assert.Equal(expectedString, now.Add(deltaFromNow).Humanize(false, now)); + } + } +} \ No newline at end of file diff --git a/src/Humanizer.Tests/DistanceOfTimeCalculators/DefaultPrecisionBoundaries.cs b/src/Humanizer.Tests/DistanceOfTimeCalculators/DefaultPrecisionBoundaries.cs new file mode 100644 index 000000000..c23f033d6 --- /dev/null +++ b/src/Humanizer.Tests/DistanceOfTimeCalculators/DefaultPrecisionBoundaries.cs @@ -0,0 +1,99 @@ +using System; +using Humanizer.DistanceOfTimeCalculators; +using Humanizer.Localisation; +using Xunit; + +namespace Humanizer.Tests.DistanceOfTimeCalculators +{ + public class DefaultPrecisionBoundaries + { + readonly PrecisionBasedDistanceOfTime _calculator = new PrecisionBasedDistanceOfTime(); + + private readonly string justNow = GetJustNow(); + private readonly string secondFromNow = GetResource(TimeUnit.Second, 1); + private readonly string minuteFromNow = GetResource(TimeUnit.Minute, 1); + private readonly string hourFromNow = GetResource(TimeUnit.Hour, 1); + private readonly string dayFromNow = GetResource(TimeUnit.Day, 1); + private readonly string monthFromNow = GetResource(TimeUnit.Month, 1); + private readonly string yearFromNow = GetResource(TimeUnit.Year, 1); + + [Fact] + public void MillisecondsBorder() + { + const int millisecondsBoder = 750; + VerifyBorder(TimeSpan.FromMilliseconds, millisecondsBoder, justNow, secondFromNow); + } + + [Fact] + public void FourtyFiveSecondsBorder() + { + const int secondsBorder = 45; + VerifyBorder(TimeSpan.FromSeconds, secondsBorder, + GetResource(TimeUnit.Second, secondsBorder - 1), + minuteFromNow); + } + + [Fact] + public void FourtyFiveMinutesBorder() + { + const int minutesBorder = 45; + VerifyBorder(TimeSpan.FromMinutes, minutesBorder, + GetResource(TimeUnit.Minute, minutesBorder - 1), + hourFromNow); + } + + [Fact] + public void EighteenHoursBorder() + { + const int hoursBorder = 18; + VerifyBorder(TimeSpan.FromHours, 18, + GetResource(TimeUnit.Hour, hoursBorder - 1), + dayFromNow); + } + + [Fact] + public void TwentyThreeDaysBorder() + { + const int monthBorderInDays = 23; + VerifyBorder(TimeSpan.FromDays, monthBorderInDays, + GetResource(TimeUnit.Day, monthBorderInDays - 1), + monthFromNow); + } + + [Fact] + public void TwoHundredAndFourDaysBorder() + { + const int yearBorderInDays = 274; + VerifyBorder(TimeSpan.FromDays, yearBorderInDays, + GetResource(TimeUnit.Month, 9), + yearFromNow); + } + + private void VerifyBorder(Func timeSpanFunc, int border, string beforeBorder, string afterBorder) + { + var date = DateTime.UtcNow; + var date1 = date.Add(timeSpanFunc(border - 1)); + var date2 = date.Add(timeSpanFunc(border)); + var date3 = date.Add(timeSpanFunc(border + 1)); + + var actual1 = _calculator.Calculate(date1, date); + var actual2 = _calculator.Calculate(date2, date); + var actual3 = _calculator.Calculate(date3, date); + + Assert.Equal(beforeBorder, actual1); + Assert.Equal(afterBorder, actual2); + Assert.Equal(afterBorder, actual3); + } + + private static string GetResource(TimeUnit timeUnit, int count) + { + string resourceKey = ResourceKeys.DateHumanize.GetResourceKey(timeUnit, TimeUnitTense.Future, count); + return Resources.GetResource(resourceKey).FormatWith(count); + } + + private static string GetJustNow() + { + return Resources.GetResource(ResourceKeys.DateHumanize.Now); + } + } +} \ No newline at end of file diff --git a/src/Humanizer.Tests/DistanceOfTimeCalculators/PrecisionBasedDistanceOfTimeTests.cs b/src/Humanizer.Tests/DistanceOfTimeCalculators/PrecisionBasedDistanceOfTimeTests.cs new file mode 100644 index 000000000..47fd24813 --- /dev/null +++ b/src/Humanizer.Tests/DistanceOfTimeCalculators/PrecisionBasedDistanceOfTimeTests.cs @@ -0,0 +1,205 @@ +using System; +using Humanizer.Configuration; +using Humanizer.DistanceOfTimeCalculators; +using Humanizer.Localisation; +using Xunit; + +namespace Humanizer.Tests.DistanceOfTimeCalculators +{ + public class PrecisionBasedDistanceOfTimeTests : DateHumanizeTestsBase + { + public PrecisionBasedDistanceOfTimeTests() + { + Configurator.DistanceOfTimeInWords = new PrecisionBasedDistanceOfTime(); + } + + [Fact] + public void OneSecondFromNow() + { + var oneSecondFromNow = Resources.GetResource(ResourceKeys.DateHumanize.GetResourceKey(TimeUnit.Second, TimeUnitTense.Future)); + Verify(oneSecondFromNow, new TimeSpan(0, 0, 0, 1)); + } + + [Fact] + public void SecondsFromNow() + { + var secsFromNow = string.Format(Resources.GetResource(ResourceKeys.DateHumanize.GetResourceKey(TimeUnit.Second, TimeUnitTense.Future, 10)), 10); + Verify(secsFromNow, new TimeSpan(0, 0, 0, 10)); + } + + [Fact] + public void OneMinuteFromNow() + { + var oneMinFromNow = Resources.GetResource(ResourceKeys.DateHumanize.GetResourceKey(TimeUnit.Minute, TimeUnitTense.Future)); + Verify(oneMinFromNow, new TimeSpan(0, 0, 1, 1)); + } + + [Fact] + public void AFewMinutesFromNow() + { + var minsFromNow = string.Format(Resources.GetResource(ResourceKeys.DateHumanize.GetResourceKey(TimeUnit.Minute, TimeUnitTense.Future, 10)), 10); + Verify(minsFromNow, new TimeSpan(0, 0, 10, 0)); + } + + [Fact] + public void AnHourFromNow() + { + var anHourFromNow = Resources.GetResource(ResourceKeys.DateHumanize.GetResourceKey(TimeUnit.Hour, TimeUnitTense.Future)); + Verify(anHourFromNow, new TimeSpan(0, 1, 10, 0)); + } + + [Fact] + public void HoursFromNow() + { + var hoursFromNow = string.Format(Resources.GetResource(ResourceKeys.DateHumanize.GetResourceKey(TimeUnit.Hour, TimeUnitTense.Future, 10)), 10); + Verify(hoursFromNow, new TimeSpan(0, 10, 0, 0)); + } + + [Fact] + public void Tomorrow() + { + var tomorrow = Resources.GetResource(ResourceKeys.DateHumanize.GetResourceKey(TimeUnit.Day, TimeUnitTense.Future)); + Verify(tomorrow, new TimeSpan(1, 10, 0, 0)); + } + + [Fact] + public void AFewDaysFromNow() + { + var daysFromNow = string.Format(Resources.GetResource(ResourceKeys.DateHumanize.GetResourceKey(TimeUnit.Day, TimeUnitTense.Future, 10)), 10); + Verify(daysFromNow, new TimeSpan(10, 1, 0, 0)); + } + + [Fact] + public void OneMonthFromNow() + { + var oneMonthFromNow = Resources.GetResource(ResourceKeys.DateHumanize.GetResourceKey(TimeUnit.Month, TimeUnitTense.Future)); + Verify(oneMonthFromNow, new TimeSpan(31, 1, 0, 0)); + } + + [Fact] + public void AFewMonthsFromNow() + { + var monthsFromNow = string.Format(Resources.GetResource(ResourceKeys.DateHumanize.GetResourceKey(TimeUnit.Month, TimeUnitTense.Future, 2)), 2); + Verify(monthsFromNow, new TimeSpan(62, 1, 0, 0)); + } + + [Fact] + public void OneYearFromNowIsNotAccureate() + { + var aYearFromNow = Resources.GetResource(ResourceKeys.DateHumanize.GetResourceKey(TimeUnit.Year, TimeUnitTense.Future)); + Verify(aYearFromNow, new TimeSpan(360, 0, 0, 0)); + } + + [Fact] + public void OneYearFromNow() + { + var aYearFromNow = Resources.GetResource(ResourceKeys.DateHumanize.GetResourceKey(TimeUnit.Year, TimeUnitTense.Future)); + Verify(aYearFromNow, new TimeSpan(400, 0, 0, 0)); + } + + [Fact] + public void FewYearsFromNow() + { + var fewYearsFromNow = string.Format(Resources.GetResource(ResourceKeys.DateHumanize.GetResourceKey(TimeUnit.Year, TimeUnitTense.Future, 2)), 2); + Verify(fewYearsFromNow, new TimeSpan(900, 0, 0, 0)); + } + + [Fact] + public void JustNow() + { + var now = Resources.GetResource(ResourceKeys.DateHumanize.Now); + Verify(now, new TimeSpan(0, 0, 0, 0)); + } + + [Fact] + public void OneSecondAgo() + { + var aSecAgo = Resources.GetResource(ResourceKeys.DateHumanize.GetResourceKey(TimeUnit.Second, TimeUnitTense.Past)); + Verify(aSecAgo, new TimeSpan(0, 0, 0, -1)); + } + + [Fact] + public void SecondsAgo() + { + var secondsAgo = string.Format(Resources.GetResource(ResourceKeys.DateHumanize.GetResourceKey(TimeUnit.Second, TimeUnitTense.Past, 10)), 10); + Verify(secondsAgo, new TimeSpan(0, 0, 0, -10)); + } + + [Fact] + public void OneMinuteAgo() + { + var aMinuteAgo = Resources.GetResource(ResourceKeys.DateHumanize.GetResourceKey(TimeUnit.Minute, TimeUnitTense.Past)); + Verify(aMinuteAgo, new TimeSpan(0, 0, -1, -10)); + } + + [Fact] + public void AFewMinutesAgo() + { + var minsAgo = string.Format(Resources.GetResource(ResourceKeys.DateHumanize.GetResourceKey(TimeUnit.Minute, TimeUnitTense.Past, 10)), 10); + Verify(minsAgo, new TimeSpan(0, 0, -10, 0)); + } + + [Fact] + public void AnHourAgo() + { + var anHourAgo = Resources.GetResource(ResourceKeys.DateHumanize.GetResourceKey(TimeUnit.Hour, TimeUnitTense.Past)); + Verify(anHourAgo, new TimeSpan(0, -1, -10, 0)); + } + + [Fact] + public void HoursAgo() + { + var hoursAgo = string.Format(Resources.GetResource(ResourceKeys.DateHumanize.GetResourceKey(TimeUnit.Hour, TimeUnitTense.Past, 10)), 10); + Verify(hoursAgo, new TimeSpan(0, -10, 0, 0)); + } + + [Fact] + public void Yesterday() + { + var yesterday = Resources.GetResource(ResourceKeys.DateHumanize.GetResourceKey(TimeUnit.Day, TimeUnitTense.Past)); + Verify(yesterday, new TimeSpan(-1, -10, 0, 0)); + } + + [Fact] + public void AFewDaysAgo() + { + var fewDaysAgo = string.Format(Resources.GetResource(ResourceKeys.DateHumanize.GetResourceKey(TimeUnit.Day, TimeUnitTense.Past, 10)), 10); + Verify(fewDaysAgo, new TimeSpan(-10, -1, 0, 0)); + } + + [Fact] + public void OneMonthAgo() + { + var aMonthAgo = Resources.GetResource(ResourceKeys.DateHumanize.GetResourceKey(TimeUnit.Month, TimeUnitTense.Past)); + Verify(aMonthAgo, new TimeSpan(-31, -1, 0, 0)); + } + + [Fact] + public void AFewMonthsAgo() + { + var monthsAgo = string.Format(Resources.GetResource(ResourceKeys.DateHumanize.GetResourceKey(TimeUnit.Month, TimeUnitTense.Past, 2)), 2); + Verify(monthsAgo, new TimeSpan(-62, -1, 0, 0)); + } + + [Fact] + public void OneYearAgoIsNotAccureate() + { + var aYearAgo = Resources.GetResource(ResourceKeys.DateHumanize.GetResourceKey(TimeUnit.Year, TimeUnitTense.Past)); + Verify(aYearAgo, new TimeSpan(-360, 0, 0, 0)); + } + + [Fact] + public void OneYearAgo() + { + var aYearAgo = Resources.GetResource(ResourceKeys.DateHumanize.GetResourceKey(TimeUnit.Year, TimeUnitTense.Past)); + Verify(aYearAgo, new TimeSpan(-400, 0, 0, 0)); + } + + [Fact] + public void FewYearsAgo() + { + var yearsAgo = string.Format(Resources.GetResource(ResourceKeys.DateHumanize.GetResourceKey(TimeUnit.Year, TimeUnitTense.Past, 2)), 2); + Verify(yearsAgo, new TimeSpan(-900, 0, 0, 0)); + } + } +} diff --git a/src/Humanizer.Tests/Humanizer.Tests.csproj b/src/Humanizer.Tests/Humanizer.Tests.csproj index 7d6f04165..d281dc9ea 100644 --- a/src/Humanizer.Tests/Humanizer.Tests.csproj +++ b/src/Humanizer.Tests/Humanizer.Tests.csproj @@ -75,6 +75,9 @@ + + + @@ -130,6 +133,7 @@ +