-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Reopen "Fix DueDate.StringDate conversion to and from DateTime." (#41)
* Added FakeLocalTimeZone helper class. The class is used to change the time zone of the tests upon initialization, and resets it back when disposed. * Added more tests for DueDate model. The added tests ensure consistency in StringDate property setter and getter. * Changed date formatting in DueDate.StringDate property. Date is now converted using the round-trip format without milliseconds. Date is also no longer being converted to universal time before formatting. * Made a simple change in floating due date test. DateTimeKind is switched to Unspecified instead of Utc since the due date should be treated as floating. * Fixed date convertion in `DueDate.StringDate` getter. The fix reverts back to depending on `DueDate.Timezone` property to determine the conversion formatting. However, it doesn't convert the `DueDate.Date` value to universal time unless the `DueDate` is intended to be fixed. * Made a simple fix to the "fixed timezone" `DueDate` test. Timezone info was missing for a fixed date. * Fixed CreateNewItem_DueDateIsLocal_DueDateNotChanged test. Since floating due dates are now converted to `Unspecified` date time, the method `ToLocalTime` is no longer used because it assumes the given date as `UTC`. * Replaced DueDate public constructors with static methods. Methods include detailed documentation comments. * Removed redundant checks in DueDate.StringDate getter. Static methods that are used to instantiate DueDates are now in charge of handling different kinds of dates. * Updated tests with new DueDate static methods. * Remove randomization in tests. Fake time zone random selection is replaced by pre-determined custom offset. * Remove unnecessary comments. * Removed unnecessary SuppressFinalize call in DueDateTests.
- Loading branch information
1 parent
1f7f320
commit a90eb4f
Showing
6 changed files
with
276 additions
and
55 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
using System; | ||
using System.Reflection; | ||
|
||
namespace Todoist.Net.Tests.Helpers; | ||
|
||
/// <summary> | ||
/// A helper class that changes the local timezone to a fake timezone provided | ||
/// at initialization, and resets the original local timezone when disposed. | ||
/// </summary> | ||
/// <remarks> | ||
/// See this <see href="https://stackoverflow.com/questions/44413407/mock-the-country-timezone-you-are-running-unit-test-from">SO question</see> for more details. | ||
/// </remarks> | ||
public sealed class FakeLocalTimeZone : IDisposable | ||
{ | ||
|
||
/// <summary> | ||
/// The fake time zone info that has been set as local. | ||
/// </summary> | ||
public TimeZoneInfo FakeTimeZoneInfo { get; } | ||
|
||
|
||
/// <summary> | ||
/// Initializes a new instance of the <see cref="FakeLocalTimeZone"/> class. | ||
/// </summary> | ||
private FakeLocalTimeZone(TimeZoneInfo fakeTimeZoneInfo) | ||
{ | ||
FakeTimeZoneInfo = fakeTimeZoneInfo; | ||
|
||
var info = typeof(TimeZoneInfo).GetField("s_cachedData", BindingFlags.NonPublic | BindingFlags.Static); | ||
var cachedData = info.GetValue(null); | ||
|
||
var field = cachedData.GetType().GetField("_localTimeZone", | ||
BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static | BindingFlags.Instance); | ||
|
||
field.SetValue(cachedData, fakeTimeZoneInfo); | ||
} | ||
|
||
public void Dispose() | ||
{ | ||
TimeZoneInfo.ClearCachedData(); | ||
} | ||
|
||
|
||
/// <summary> | ||
/// Changes the local time zone to the given <paramref name="fakeTimeZoneInfo"/>. | ||
/// </summary> | ||
/// <remarks> | ||
/// Disposal of the returned object resets the local time zone to the original one. | ||
/// </remarks> | ||
/// <param name="fakeTimeZoneInfo">The time zone to set as local until disposal.</param> | ||
/// <returns> | ||
/// A <see cref="FakeLocalTimeZone"/> instance that represents the time zone change, | ||
/// and used to reset it back to original at disposal. | ||
/// </returns> | ||
public static FakeLocalTimeZone ChangeLocalTimeZone(TimeZoneInfo fakeTimeZoneInfo) | ||
{ | ||
return new FakeLocalTimeZone(fakeTimeZoneInfo); | ||
} | ||
|
||
/// <summary> | ||
/// Changes the local time zone to a custom time zone with a <paramref name="baseUtcOffset"/>. | ||
/// </summary> | ||
/// <remarks> | ||
/// Disposal of the returned object resets the local time zone to the original one. | ||
/// </remarks> | ||
/// <param name="baseUtcOffset">UTC offset of the custom time zone.</param> | ||
/// <returns> | ||
/// A <see cref="FakeLocalTimeZone"/> instance that represents the time zone change, | ||
/// and used to reset it back to original at disposal. | ||
/// </returns> | ||
public static FakeLocalTimeZone ChangeLocalTimeZone(TimeSpan baseUtcOffset) | ||
{ | ||
var fakeId = "Fake TimeZone"; | ||
var fakeDisplayName = $"(UTC+{baseUtcOffset:hh':'mm})"; | ||
|
||
var fakeTimeZoneInfo = TimeZoneInfo.CreateCustomTimeZone(fakeId, baseUtcOffset, fakeDisplayName, fakeDisplayName); | ||
|
||
return new FakeLocalTimeZone(fakeTimeZoneInfo); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
using System; | ||
using System.Linq; | ||
|
||
using Todoist.Net.Tests.Extensions; | ||
|
||
using Xunit; | ||
|
||
namespace Todoist.Net.Tests.Helpers; | ||
|
||
[Trait(Constants.TraitName, Constants.UnitTraitValue)] | ||
public class FakeLocalTimeZoneTests | ||
{ | ||
|
||
[Fact] | ||
public void FakeLocalTimeZone_ShouldChangeLocalTimeZoneWithinScope_AndResetItBackOutsideScope() | ||
{ | ||
var fakeTimeZoneOffset = TimeZoneInfo.Local.BaseUtcOffset + TimeSpan.FromHours(2); | ||
var fakeLocalTimeZone = FakeLocalTimeZone.ChangeLocalTimeZone(fakeTimeZoneOffset); | ||
|
||
using (fakeLocalTimeZone) | ||
{ | ||
Assert.Equal(fakeLocalTimeZone.FakeTimeZoneInfo, TimeZoneInfo.Local); | ||
} | ||
Assert.NotEqual(fakeLocalTimeZone.FakeTimeZoneInfo, TimeZoneInfo.Local); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.