using ClawdDotNet.Core.Scheduling; using Shouldly; namespace ClawdDotNet.Core.Tests.Scheduling; /// /// Time zones are named differently on Windows and Linux. Task files travel between /// the two — so each side must be able to interpret the other's spelling. /// /// The tests deliberately run on both platforms with the same expectations: exactly /// that is the property we need. /// public sealed class TimeZonesTests { [Theory] [InlineData("Europe/Berlin")] [InlineData("W. Europe Standard Time")] [InlineData("America/New_York")] [InlineData("Eastern Standard Time")] [InlineData("UTC")] public void Both_spellings_can_be_resolved(string id) { TimeZones.TryResolve(id).ShouldNotBeNull(); TimeZones.IsKnown(id).ShouldBeTrue(); } [Fact] public void Both_spellings_mean_the_same_zone() { var iana = TimeZones.TryResolve("Europe/Berlin"); var windows = TimeZones.TryResolve("W. Europe Standard Time"); var summer = new DateTime(2026, 7, 31, 12, 0, 0, DateTimeKind.Utc); iana!.GetUtcOffset(summer).ShouldBe(windows!.GetUtcOffset(summer)); iana.GetUtcOffset(summer).ShouldBe(TimeSpan.FromHours(2)); // CEST } [Theory] [InlineData("Phantasie/Ort")] [InlineData("Nicht Existierende Standard Time")] [InlineData("völliger Unsinn")] public void Unknown_identifiers_are_reported_instead_of_guessed(string id) { TimeZones.TryResolve(id).ShouldBeNull(); TimeZones.IsKnown(id).ShouldBeFalse(); } [Fact] public void Empty_counts_as_valid_because_it_means_no_value() { TimeZones.IsKnown("").ShouldBeTrue(); TimeZones.IsKnown(null).ShouldBeTrue(); TimeZones.IsKnown(" ").ShouldBeTrue(); } [Theory] [InlineData("W. Europe Standard Time", "Europe/Berlin")] [InlineData("Europe/Berlin", "Europe/Berlin")] [InlineData("", "")] public void Normalising_gives_the_IANA_form(string input, string expected) { TimeZones.ToIana(input).ShouldBe(expected); } [Fact] public void An_unconvertible_identifier_stays_unchanged() { // Falsifying would be worse than passing through — that way, in case of doubt, // what originally stood there stays visible. TimeZones.ToIana("Phantasie Standard Time").ShouldBe("Phantasie Standard Time"); } [Fact] public void The_local_zone_is_returned_in_IANA_form() { var local = TimeZones.LocalIanaId; local.ShouldNotBeNullOrWhiteSpace(); TimeZones.IsKnown(local).ShouldBeTrue(); // The actual point: what comes out here is written into task files // and must be readable on the other platform. IANA identifiers contain a // slash, Windows identifiers never — UTC is the exception with neither. if (local != "UTC") local.ShouldContain("/"); } }