diff --git a/Pipeline/Build.cs b/Pipeline/Build.cs index 65bdc27a7..f5452a744 100644 --- a/Pipeline/Build.cs +++ b/Pipeline/Build.cs @@ -20,7 +20,7 @@ partial class Build : NukeBuild /// /// Afterward, you can update the package reference in `Directory.Packages.props` and reset this flag. /// - readonly BuildScope BuildScope = BuildScope.Default; + readonly BuildScope BuildScope = BuildScope.CoreOnly; [Parameter("Configuration to build - Default is 'Debug' (local) or 'Release' (server)")] readonly Configuration Configuration = IsLocalBuild ? Configuration.Debug : Configuration.Release; diff --git a/Source/Testably.Abstractions.Interface/ITimeSystem.cs b/Source/Testably.Abstractions.Interface/ITimeSystem.cs index 9b3ed5fc1..cb959c5a3 100644 --- a/Source/Testably.Abstractions.Interface/ITimeSystem.cs +++ b/Source/Testably.Abstractions.Interface/ITimeSystem.cs @@ -38,4 +38,9 @@ public interface ITimeSystem /// Abstractions for . /// ITimerFactory Timer { get; } + + /// + /// Abstractions for . + /// + ITimeZoneInfo TimeZoneInfo { get; } } diff --git a/Source/Testably.Abstractions.Interface/TimeSystem/ITimeZoneInfo.cs b/Source/Testably.Abstractions.Interface/TimeSystem/ITimeZoneInfo.cs new file mode 100644 index 000000000..d892be813 --- /dev/null +++ b/Source/Testably.Abstractions.Interface/TimeSystem/ITimeZoneInfo.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.ObjectModel; + +namespace Testably.Abstractions.TimeSystem; + +/// +/// Abstractions for . +/// +public interface ITimeZoneInfo : ITimeSystemEntity +{ + /// + TimeZoneInfo Local { get; } + + /// + TimeZoneInfo Utc { get; } + + /// + TimeZoneInfo FindSystemTimeZoneById(string id); + + /// + ReadOnlyCollection GetSystemTimeZones(); +} diff --git a/Source/Testably.Abstractions/RealTimeSystem.cs b/Source/Testably.Abstractions/RealTimeSystem.cs index 1be790d57..3fbd3a179 100644 --- a/Source/Testably.Abstractions/RealTimeSystem.cs +++ b/Source/Testably.Abstractions/RealTimeSystem.cs @@ -23,6 +23,7 @@ public RealTimeSystem() Task = new TaskWrapper(this); Thread = new ThreadWrapper(this); Timer = new TimerFactory(this); + TimeZoneInfo = new TimeZoneInfoWrapper(this); } #region ITimeSystem Members @@ -47,5 +48,8 @@ public RealTimeSystem() /// public ITimerFactory Timer { get; } + /// + public ITimeZoneInfo TimeZoneInfo { get; } + #endregion } diff --git a/Source/Testably.Abstractions/TimeSystem/TimeZoneInfoWrapper.cs b/Source/Testably.Abstractions/TimeSystem/TimeZoneInfoWrapper.cs new file mode 100644 index 000000000..5c259ed5c --- /dev/null +++ b/Source/Testably.Abstractions/TimeSystem/TimeZoneInfoWrapper.cs @@ -0,0 +1,35 @@ +using System; +using System.Collections.ObjectModel; + +namespace Testably.Abstractions.TimeSystem; + +internal sealed class TimeZoneInfoWrapper : ITimeZoneInfo +{ + internal TimeZoneInfoWrapper(RealTimeSystem timeSystem) + { + TimeSystem = timeSystem; + } + + #region ITimeZoneInfo Members + + /// + public TimeZoneInfo Local + => TimeZoneInfo.Local; + + /// + public ITimeSystem TimeSystem { get; } + + /// + public TimeZoneInfo Utc + => TimeZoneInfo.Utc; + + /// + public TimeZoneInfo FindSystemTimeZoneById(string id) + => TimeZoneInfo.FindSystemTimeZoneById(id); + + /// + public ReadOnlyCollection GetSystemTimeZones() + => TimeZoneInfo.GetSystemTimeZones(); + + #endregion +} diff --git a/Tests/Api/Testably.Abstractions.Api.Tests/Expected/Testably.Abstractions_net10.0.txt b/Tests/Api/Testably.Abstractions.Api.Tests/Expected/Testably.Abstractions_net10.0.txt index 62263d28e..da5ef1df4 100644 --- a/Tests/Api/Testably.Abstractions.Api.Tests/Expected/Testably.Abstractions_net10.0.txt +++ b/Tests/Api/Testably.Abstractions.Api.Tests/Expected/Testably.Abstractions_net10.0.txt @@ -31,6 +31,7 @@ namespace Testably.Abstractions public Testably.Abstractions.TimeSystem.IStopwatchFactory Stopwatch { get; } public Testably.Abstractions.TimeSystem.ITask Task { get; } public Testably.Abstractions.TimeSystem.IThread Thread { get; } + public Testably.Abstractions.TimeSystem.ITimeZoneInfo TimeZoneInfo { get; } public Testably.Abstractions.TimeSystem.ITimerFactory Timer { get; } } } \ No newline at end of file diff --git a/Tests/Api/Testably.Abstractions.Api.Tests/Expected/Testably.Abstractions_net6.0.txt b/Tests/Api/Testably.Abstractions.Api.Tests/Expected/Testably.Abstractions_net6.0.txt index d407ba63d..ffd57a9cd 100644 --- a/Tests/Api/Testably.Abstractions.Api.Tests/Expected/Testably.Abstractions_net6.0.txt +++ b/Tests/Api/Testably.Abstractions.Api.Tests/Expected/Testably.Abstractions_net6.0.txt @@ -30,6 +30,7 @@ namespace Testably.Abstractions public Testably.Abstractions.TimeSystem.IStopwatchFactory Stopwatch { get; } public Testably.Abstractions.TimeSystem.ITask Task { get; } public Testably.Abstractions.TimeSystem.IThread Thread { get; } + public Testably.Abstractions.TimeSystem.ITimeZoneInfo TimeZoneInfo { get; } public Testably.Abstractions.TimeSystem.ITimerFactory Timer { get; } } } \ No newline at end of file diff --git a/Tests/Api/Testably.Abstractions.Api.Tests/Expected/Testably.Abstractions_net8.0.txt b/Tests/Api/Testably.Abstractions.Api.Tests/Expected/Testably.Abstractions_net8.0.txt index 3773771e2..87768f232 100644 --- a/Tests/Api/Testably.Abstractions.Api.Tests/Expected/Testably.Abstractions_net8.0.txt +++ b/Tests/Api/Testably.Abstractions.Api.Tests/Expected/Testably.Abstractions_net8.0.txt @@ -31,6 +31,7 @@ namespace Testably.Abstractions public Testably.Abstractions.TimeSystem.IStopwatchFactory Stopwatch { get; } public Testably.Abstractions.TimeSystem.ITask Task { get; } public Testably.Abstractions.TimeSystem.IThread Thread { get; } + public Testably.Abstractions.TimeSystem.ITimeZoneInfo TimeZoneInfo { get; } public Testably.Abstractions.TimeSystem.ITimerFactory Timer { get; } } } \ No newline at end of file diff --git a/Tests/Api/Testably.Abstractions.Api.Tests/Expected/Testably.Abstractions_net9.0.txt b/Tests/Api/Testably.Abstractions.Api.Tests/Expected/Testably.Abstractions_net9.0.txt index 8bd2fd1b4..4ed96274c 100644 --- a/Tests/Api/Testably.Abstractions.Api.Tests/Expected/Testably.Abstractions_net9.0.txt +++ b/Tests/Api/Testably.Abstractions.Api.Tests/Expected/Testably.Abstractions_net9.0.txt @@ -31,6 +31,7 @@ namespace Testably.Abstractions public Testably.Abstractions.TimeSystem.IStopwatchFactory Stopwatch { get; } public Testably.Abstractions.TimeSystem.ITask Task { get; } public Testably.Abstractions.TimeSystem.IThread Thread { get; } + public Testably.Abstractions.TimeSystem.ITimeZoneInfo TimeZoneInfo { get; } public Testably.Abstractions.TimeSystem.ITimerFactory Timer { get; } } } \ No newline at end of file diff --git a/Tests/Api/Testably.Abstractions.Api.Tests/Expected/Testably.Abstractions_netstandard2.0.txt b/Tests/Api/Testably.Abstractions.Api.Tests/Expected/Testably.Abstractions_netstandard2.0.txt index 54f67894e..dbcc82f77 100644 --- a/Tests/Api/Testably.Abstractions.Api.Tests/Expected/Testably.Abstractions_netstandard2.0.txt +++ b/Tests/Api/Testably.Abstractions.Api.Tests/Expected/Testably.Abstractions_netstandard2.0.txt @@ -30,6 +30,7 @@ namespace Testably.Abstractions public Testably.Abstractions.TimeSystem.IStopwatchFactory Stopwatch { get; } public Testably.Abstractions.TimeSystem.ITask Task { get; } public Testably.Abstractions.TimeSystem.IThread Thread { get; } + public Testably.Abstractions.TimeSystem.ITimeZoneInfo TimeZoneInfo { get; } public Testably.Abstractions.TimeSystem.ITimerFactory Timer { get; } } } \ No newline at end of file diff --git a/Tests/Api/Testably.Abstractions.Api.Tests/Expected/Testably.Abstractions_netstandard2.1.txt b/Tests/Api/Testably.Abstractions.Api.Tests/Expected/Testably.Abstractions_netstandard2.1.txt index 9a2eac8ad..2b0baa8b3 100644 --- a/Tests/Api/Testably.Abstractions.Api.Tests/Expected/Testably.Abstractions_netstandard2.1.txt +++ b/Tests/Api/Testably.Abstractions.Api.Tests/Expected/Testably.Abstractions_netstandard2.1.txt @@ -30,6 +30,7 @@ namespace Testably.Abstractions public Testably.Abstractions.TimeSystem.IStopwatchFactory Stopwatch { get; } public Testably.Abstractions.TimeSystem.ITask Task { get; } public Testably.Abstractions.TimeSystem.IThread Thread { get; } + public Testably.Abstractions.TimeSystem.ITimeZoneInfo TimeZoneInfo { get; } public Testably.Abstractions.TimeSystem.ITimerFactory Timer { get; } } } \ No newline at end of file diff --git a/Tests/Api/Testably.Abstractions.Core.Api.Tests/Expected/Testably.Abstractions.Interface_net10.0.txt b/Tests/Api/Testably.Abstractions.Core.Api.Tests/Expected/Testably.Abstractions.Interface_net10.0.txt index 97f9f720d..472f042f3 100644 --- a/Tests/Api/Testably.Abstractions.Core.Api.Tests/Expected/Testably.Abstractions.Interface_net10.0.txt +++ b/Tests/Api/Testably.Abstractions.Core.Api.Tests/Expected/Testably.Abstractions.Interface_net10.0.txt @@ -71,6 +71,7 @@ namespace Testably.Abstractions Testably.Abstractions.TimeSystem.IStopwatchFactory Stopwatch { get; } Testably.Abstractions.TimeSystem.ITask Task { get; } Testably.Abstractions.TimeSystem.IThread Thread { get; } + Testably.Abstractions.TimeSystem.ITimeZoneInfo TimeZoneInfo { get; } Testably.Abstractions.TimeSystem.ITimerFactory Timer { get; } } } @@ -190,6 +191,13 @@ namespace Testably.Abstractions.TimeSystem { Testably.Abstractions.ITimeSystem TimeSystem { get; } } + public interface ITimeZoneInfo : Testably.Abstractions.TimeSystem.ITimeSystemEntity + { + System.TimeZoneInfo Local { get; } + System.TimeZoneInfo Utc { get; } + System.TimeZoneInfo FindSystemTimeZoneById(string id); + System.Collections.ObjectModel.ReadOnlyCollection GetSystemTimeZones(); + } public interface ITimer : System.IAsyncDisposable, System.IDisposable, Testably.Abstractions.TimeSystem.ITimeSystemEntity { bool Change(System.TimeSpan dueTime, System.TimeSpan period); diff --git a/Tests/Api/Testably.Abstractions.Core.Api.Tests/Expected/Testably.Abstractions.Interface_net6.0.txt b/Tests/Api/Testably.Abstractions.Core.Api.Tests/Expected/Testably.Abstractions.Interface_net6.0.txt index d51411606..6e7297252 100644 --- a/Tests/Api/Testably.Abstractions.Core.Api.Tests/Expected/Testably.Abstractions.Interface_net6.0.txt +++ b/Tests/Api/Testably.Abstractions.Core.Api.Tests/Expected/Testably.Abstractions.Interface_net6.0.txt @@ -52,6 +52,7 @@ namespace Testably.Abstractions Testably.Abstractions.TimeSystem.IStopwatchFactory Stopwatch { get; } Testably.Abstractions.TimeSystem.ITask Task { get; } Testably.Abstractions.TimeSystem.IThread Thread { get; } + Testably.Abstractions.TimeSystem.ITimeZoneInfo TimeZoneInfo { get; } Testably.Abstractions.TimeSystem.ITimerFactory Timer { get; } } } @@ -141,6 +142,13 @@ namespace Testably.Abstractions.TimeSystem { Testably.Abstractions.ITimeSystem TimeSystem { get; } } + public interface ITimeZoneInfo : Testably.Abstractions.TimeSystem.ITimeSystemEntity + { + System.TimeZoneInfo Local { get; } + System.TimeZoneInfo Utc { get; } + System.TimeZoneInfo FindSystemTimeZoneById(string id); + System.Collections.ObjectModel.ReadOnlyCollection GetSystemTimeZones(); + } public interface ITimer : System.IAsyncDisposable, System.IDisposable, Testably.Abstractions.TimeSystem.ITimeSystemEntity { bool Change(System.TimeSpan dueTime, System.TimeSpan period); diff --git a/Tests/Api/Testably.Abstractions.Core.Api.Tests/Expected/Testably.Abstractions.Interface_net8.0.txt b/Tests/Api/Testably.Abstractions.Core.Api.Tests/Expected/Testably.Abstractions.Interface_net8.0.txt index d4bec9fed..10f488927 100644 --- a/Tests/Api/Testably.Abstractions.Core.Api.Tests/Expected/Testably.Abstractions.Interface_net8.0.txt +++ b/Tests/Api/Testably.Abstractions.Core.Api.Tests/Expected/Testably.Abstractions.Interface_net8.0.txt @@ -62,6 +62,7 @@ namespace Testably.Abstractions Testably.Abstractions.TimeSystem.IStopwatchFactory Stopwatch { get; } Testably.Abstractions.TimeSystem.ITask Task { get; } Testably.Abstractions.TimeSystem.IThread Thread { get; } + Testably.Abstractions.TimeSystem.ITimeZoneInfo TimeZoneInfo { get; } Testably.Abstractions.TimeSystem.ITimerFactory Timer { get; } } } @@ -172,6 +173,13 @@ namespace Testably.Abstractions.TimeSystem { Testably.Abstractions.ITimeSystem TimeSystem { get; } } + public interface ITimeZoneInfo : Testably.Abstractions.TimeSystem.ITimeSystemEntity + { + System.TimeZoneInfo Local { get; } + System.TimeZoneInfo Utc { get; } + System.TimeZoneInfo FindSystemTimeZoneById(string id); + System.Collections.ObjectModel.ReadOnlyCollection GetSystemTimeZones(); + } public interface ITimer : System.IAsyncDisposable, System.IDisposable, Testably.Abstractions.TimeSystem.ITimeSystemEntity { bool Change(System.TimeSpan dueTime, System.TimeSpan period); diff --git a/Tests/Api/Testably.Abstractions.Core.Api.Tests/Expected/Testably.Abstractions.Interface_net9.0.txt b/Tests/Api/Testably.Abstractions.Core.Api.Tests/Expected/Testably.Abstractions.Interface_net9.0.txt index ed0cf769d..016f7f9c0 100644 --- a/Tests/Api/Testably.Abstractions.Core.Api.Tests/Expected/Testably.Abstractions.Interface_net9.0.txt +++ b/Tests/Api/Testably.Abstractions.Core.Api.Tests/Expected/Testably.Abstractions.Interface_net9.0.txt @@ -64,6 +64,7 @@ namespace Testably.Abstractions Testably.Abstractions.TimeSystem.IStopwatchFactory Stopwatch { get; } Testably.Abstractions.TimeSystem.ITask Task { get; } Testably.Abstractions.TimeSystem.IThread Thread { get; } + Testably.Abstractions.TimeSystem.ITimeZoneInfo TimeZoneInfo { get; } Testably.Abstractions.TimeSystem.ITimerFactory Timer { get; } } } @@ -176,6 +177,13 @@ namespace Testably.Abstractions.TimeSystem { Testably.Abstractions.ITimeSystem TimeSystem { get; } } + public interface ITimeZoneInfo : Testably.Abstractions.TimeSystem.ITimeSystemEntity + { + System.TimeZoneInfo Local { get; } + System.TimeZoneInfo Utc { get; } + System.TimeZoneInfo FindSystemTimeZoneById(string id); + System.Collections.ObjectModel.ReadOnlyCollection GetSystemTimeZones(); + } public interface ITimer : System.IAsyncDisposable, System.IDisposable, Testably.Abstractions.TimeSystem.ITimeSystemEntity { bool Change(System.TimeSpan dueTime, System.TimeSpan period); diff --git a/Tests/Api/Testably.Abstractions.Core.Api.Tests/Expected/Testably.Abstractions.Interface_netstandard2.0.txt b/Tests/Api/Testably.Abstractions.Core.Api.Tests/Expected/Testably.Abstractions.Interface_netstandard2.0.txt index 9bd955d47..2c3d1ba70 100644 --- a/Tests/Api/Testably.Abstractions.Core.Api.Tests/Expected/Testably.Abstractions.Interface_netstandard2.0.txt +++ b/Tests/Api/Testably.Abstractions.Core.Api.Tests/Expected/Testably.Abstractions.Interface_netstandard2.0.txt @@ -39,6 +39,7 @@ namespace Testably.Abstractions Testably.Abstractions.TimeSystem.IStopwatchFactory Stopwatch { get; } Testably.Abstractions.TimeSystem.ITask Task { get; } Testably.Abstractions.TimeSystem.IThread Thread { get; } + Testably.Abstractions.TimeSystem.ITimeZoneInfo TimeZoneInfo { get; } Testably.Abstractions.TimeSystem.ITimerFactory Timer { get; } } } @@ -115,6 +116,13 @@ namespace Testably.Abstractions.TimeSystem { Testably.Abstractions.ITimeSystem TimeSystem { get; } } + public interface ITimeZoneInfo : Testably.Abstractions.TimeSystem.ITimeSystemEntity + { + System.TimeZoneInfo Local { get; } + System.TimeZoneInfo Utc { get; } + System.TimeZoneInfo FindSystemTimeZoneById(string id); + System.Collections.ObjectModel.ReadOnlyCollection GetSystemTimeZones(); + } public interface ITimer : System.IDisposable, Testably.Abstractions.TimeSystem.ITimeSystemEntity { bool Change(System.TimeSpan dueTime, System.TimeSpan period); diff --git a/Tests/Api/Testably.Abstractions.Core.Api.Tests/Expected/Testably.Abstractions.Interface_netstandard2.1.txt b/Tests/Api/Testably.Abstractions.Core.Api.Tests/Expected/Testably.Abstractions.Interface_netstandard2.1.txt index 7c05321e4..6d0f951fa 100644 --- a/Tests/Api/Testably.Abstractions.Core.Api.Tests/Expected/Testably.Abstractions.Interface_netstandard2.1.txt +++ b/Tests/Api/Testably.Abstractions.Core.Api.Tests/Expected/Testably.Abstractions.Interface_netstandard2.1.txt @@ -48,6 +48,7 @@ namespace Testably.Abstractions Testably.Abstractions.TimeSystem.IStopwatchFactory Stopwatch { get; } Testably.Abstractions.TimeSystem.ITask Task { get; } Testably.Abstractions.TimeSystem.IThread Thread { get; } + Testably.Abstractions.TimeSystem.ITimeZoneInfo TimeZoneInfo { get; } Testably.Abstractions.TimeSystem.ITimerFactory Timer { get; } } } @@ -133,6 +134,13 @@ namespace Testably.Abstractions.TimeSystem { Testably.Abstractions.ITimeSystem TimeSystem { get; } } + public interface ITimeZoneInfo : Testably.Abstractions.TimeSystem.ITimeSystemEntity + { + System.TimeZoneInfo Local { get; } + System.TimeZoneInfo Utc { get; } + System.TimeZoneInfo FindSystemTimeZoneById(string id); + System.Collections.ObjectModel.ReadOnlyCollection GetSystemTimeZones(); + } public interface ITimer : System.IAsyncDisposable, System.IDisposable, Testably.Abstractions.TimeSystem.ITimeSystemEntity { bool Change(System.TimeSpan dueTime, System.TimeSpan period); diff --git a/Tests/Testably.Abstractions.Parity.Tests/ParityTests.cs b/Tests/Testably.Abstractions.Parity.Tests/ParityTests.cs index 4ebe8b3d2..8d919441f 100644 --- a/Tests/Testably.Abstractions.Parity.Tests/ParityTests.cs +++ b/Tests/Testably.Abstractions.Parity.Tests/ParityTests.cs @@ -165,6 +165,16 @@ public async Task await That(parityErrors).IsEmpty(); } + [Test] + public async Task ITimeZoneInfo_EnsureParityWith_TimeZoneInfo() + { + List parityErrors = Parity.TimeZoneInfo + .GetErrorsToStaticType( + typeof(TimeZoneInfo)); + + await That(parityErrors).IsEmpty(); + } + [Test] public async Task IZipArchive_EnsureParityWith_ZipArchive() { diff --git a/Tests/Testably.Abstractions.Parity.Tests/TestHelpers/Parity.cs b/Tests/Testably.Abstractions.Parity.Tests/TestHelpers/Parity.cs index 0a120b493..373e885c0 100644 --- a/Tests/Testably.Abstractions.Parity.Tests/TestHelpers/Parity.cs +++ b/Tests/Testably.Abstractions.Parity.Tests/TestHelpers/Parity.cs @@ -3,6 +3,7 @@ using System.Diagnostics; using System.IO; using System.IO.Compression; +using System.Linq; using System.Threading; namespace Testably.Abstractions.Parity.Tests.TestHelpers; @@ -105,6 +106,21 @@ public class Parity ]), ]); + public ParityCheck TimeZoneInfo { get; } = new(excludeMethods: + [ + typeof(TimeZoneInfo).GetMethod(nameof(System.TimeZoneInfo.ClearCachedData)), + typeof(TimeZoneInfo).GetMethod(nameof(System.TimeZoneInfo.FromSerializedString)), + ..typeof(TimeZoneInfo).GetMethods().Where(x => string.Equals(x.Name, nameof(System.TimeZoneInfo.ConvertTime), StringComparison.Ordinal)), + ..typeof(TimeZoneInfo).GetMethods().Where(x => string.Equals(x.Name, nameof(System.TimeZoneInfo.ConvertTimeBySystemTimeZoneId), StringComparison.Ordinal)), + ..typeof(TimeZoneInfo).GetMethods().Where(x => string.Equals(x.Name, nameof(System.TimeZoneInfo.ConvertTimeFromUtc), StringComparison.Ordinal)), + ..typeof(TimeZoneInfo).GetMethods().Where(x => string.Equals(x.Name, nameof(System.TimeZoneInfo.ConvertTimeToUtc), StringComparison.Ordinal)), + ..typeof(TimeZoneInfo).GetMethods().Where(x => string.Equals(x.Name, nameof(System.TimeZoneInfo.CreateCustomTimeZone), StringComparison.Ordinal)), + ..typeof(TimeZoneInfo).GetMethods().Where(x => string.Equals(x.Name, "GetSystemTimeZones", StringComparison.Ordinal) && x.GetParameters().Length > 0), + ..typeof(TimeZoneInfo).GetMethods().Where(x => string.Equals(x.Name, "TryConvertIanaIdToWindowsId", StringComparison.Ordinal)), + ..typeof(TimeZoneInfo).GetMethods().Where(x => string.Equals(x.Name, "TryConvertWindowsIdToIanaId", StringComparison.Ordinal)), + ..typeof(TimeZoneInfo).GetMethods().Where(x => string.Equals(x.Name, "TryFindSystemTimeZoneById", StringComparison.Ordinal)), + ]); + public ParityCheck ZipArchive { get; } = new(); public ParityCheck ZipArchiveEntry { get; } = new(excludeMethods: