DateTimeTests.cs 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. using System;
  2. using System.Globalization;
  3. using System.Linq;
  4. namespace DesktopClock.Tests;
  5. public class DateTimeTests
  6. {
  7. [Theory]
  8. [InlineData("2024-07-18T12:30:45.123Z", "2024-07-18T12:30:45.456Z", true)] // Different millisecond
  9. [InlineData("2024-07-18T12:30:45.123Z", "2024-07-18T12:30:46.123Z", false)] // Different second
  10. [InlineData("2024-07-18T12:30:45.123Z", "2024-07-18T12:31:45.123Z", false)] // Different minute
  11. [InlineData("2024-07-18T12:30:45.123Z", "2024-07-18T13:30:45.123Z", false)] // Different hour
  12. [InlineData("2024-07-18T12:30:45.123Z", "2024-07-19T12:30:45.123Z", false)] // Different day
  13. [InlineData("2024-07-18T12:30:45.123Z", "2024-08-18T12:30:45.123Z", false)] // Different month
  14. [InlineData("2024-07-18T12:30:45.123Z", "2025-07-18T12:30:45.123Z", false)] // Different year
  15. public void EqualExcludingMilliseconds(string dt1String, string dt2String, bool expected)
  16. {
  17. // Arrange
  18. var dt1 = DateTime.Parse(dt1String);
  19. var dt2 = DateTime.Parse(dt2String);
  20. // Act
  21. var result = dt1.EqualExcludingMillisecond(dt2);
  22. // Assert
  23. Assert.Equal(expected, result);
  24. }
  25. [Fact]
  26. public void EqualExcludingMilliseconds_SameDateTime_ShouldBeTrue()
  27. {
  28. // Arrange
  29. var dt1 = new DateTime(2024, 7, 18, 12, 30, 45, 123);
  30. var dt2 = new DateTime(2024, 7, 18, 12, 30, 45, 123);
  31. // Act
  32. var result = dt1.EqualExcludingMillisecond(dt2);
  33. // Assert
  34. Assert.True(result);
  35. }
  36. [Fact]
  37. public void EqualExcludingMilliseconds_OnlyMillisecondsDiffer_ShouldBeTrue()
  38. {
  39. // Arrange
  40. var dt1 = new DateTime(2024, 7, 18, 12, 30, 45, 0);
  41. var dt2 = new DateTime(2024, 7, 18, 12, 30, 45, 999);
  42. // Act
  43. var result = dt1.EqualExcludingMillisecond(dt2);
  44. // Assert
  45. Assert.True(result);
  46. }
  47. [Fact]
  48. public void EqualExcludingMilliseconds_Reflexive_ShouldBeTrue()
  49. {
  50. // Arrange
  51. var dt = DateTime.Now;
  52. // Act & Assert
  53. Assert.True(dt.EqualExcludingMillisecond(dt));
  54. }
  55. [Fact]
  56. public void EqualExcludingMilliseconds_Symmetric_ShouldWork()
  57. {
  58. // Arrange
  59. var dt1 = new DateTime(2024, 7, 18, 12, 30, 45, 100);
  60. var dt2 = new DateTime(2024, 7, 18, 12, 30, 45, 200);
  61. // Act & Assert
  62. Assert.Equal(dt1.EqualExcludingMillisecond(dt2), dt2.EqualExcludingMillisecond(dt1));
  63. }
  64. [Theory]
  65. [InlineData("2024-07-18 12:30:00", "2024-07-18 12:30:00", 30, true)] // Countdown reached, on interval
  66. [InlineData("2024-07-18 12:30:01", "2024-07-18 12:30:01", 30, true)] // Countdown reached, not on interval
  67. [InlineData("2024-07-18 12:29:00", "2024-07-18 12:30:00", 30, true)] // Not yet reached, on interval
  68. [InlineData("2024-07-18 12:29:01", "2024-07-18 12:30:01", 30, true)] // Not yet reached, on interval
  69. [InlineData("2024-07-18 12:29:02", "2024-07-18 12:30:01", 30, false)] // Not yet reached, not on interval
  70. [InlineData("2024-07-18 12:31:00", "2024-07-18 12:30:00", 30, true)] // Past countdown, on interval
  71. [InlineData("2024-07-18 12:31:02", "2024-07-18 12:30:01", 30, false)] // Past countdown, not on interval
  72. public void IsOnInterval(string nowString, string countdownString, int intervalSeconds, bool expected)
  73. {
  74. // Arrange
  75. var dateTime = DateTime.Parse(nowString);
  76. var countdownTo = DateTime.Parse(countdownString);
  77. var interval = TimeSpan.FromSeconds(intervalSeconds);
  78. // Act
  79. var result = DateTimeUtil.IsNowOrCountdownOnInterval(dateTime, countdownTo, interval);
  80. // Assert
  81. Assert.Equal(expected, result);
  82. }
  83. [Fact]
  84. public void IsOnInterval_DefaultCountdown_ShouldUseNowTimeOfDay()
  85. {
  86. // Arrange - when countdown is default, it uses now.TimeOfDay
  87. var now = new DateTime(2024, 7, 18, 12, 30, 0); // 12:30:00 = 45000 seconds
  88. var countdownTo = default(DateTime);
  89. var interval = TimeSpan.FromMinutes(30); // 1800 seconds
  90. // Act
  91. var result = DateTimeUtil.IsNowOrCountdownOnInterval(now, countdownTo, interval);
  92. // Assert - 45000 % 1800 = 0, so should be on interval
  93. Assert.True(result);
  94. }
  95. [Fact]
  96. public void IsOnInterval_DefaultInterval_ShouldReturnFalseUnlessCountdownReached()
  97. {
  98. // Arrange
  99. var now = new DateTime(2024, 7, 18, 12, 30, 0);
  100. var countdownTo = new DateTime(2024, 7, 18, 12, 35, 0);
  101. var interval = TimeSpan.Zero;
  102. // Act
  103. var result = DateTimeUtil.IsNowOrCountdownOnInterval(now, countdownTo, interval);
  104. // Assert
  105. Assert.False(result);
  106. }
  107. [Fact]
  108. public void IsOnInterval_CountdownReached_ShouldReturnTrue()
  109. {
  110. // Arrange
  111. var now = new DateTime(2024, 7, 18, 12, 30, 45);
  112. var countdownTo = new DateTime(2024, 7, 18, 12, 30, 45);
  113. var interval = TimeSpan.Zero; // No interval
  114. // Act
  115. var result = DateTimeUtil.IsNowOrCountdownOnInterval(now, countdownTo, interval);
  116. // Assert
  117. Assert.True(result);
  118. }
  119. [Theory]
  120. [InlineData("dddd, MMMM dd", "Monday, January 01")]
  121. [InlineData("yyyy-MM-dd", "2024-01-01")]
  122. [InlineData("HH:mm:ss", "00:00:00")]
  123. [InlineData("MMMM dd, yyyy", "January 01, 2024")]
  124. public void FromFormat_CreatesCorrectExample(string format, string expected)
  125. {
  126. // Arrange
  127. var dateTimeOffset = new DateTime(2024, 01, 01);
  128. // Act
  129. var dateFormatExample = DateFormatExample.FromFormat(format, dateTimeOffset, CultureInfo.InvariantCulture);
  130. // Assert
  131. Assert.Equal(format, dateFormatExample.Format);
  132. Assert.Equal(expected, dateFormatExample.Example);
  133. }
  134. [Fact]
  135. public void FromFormat_WithTokenizedFormat_ShouldWork()
  136. {
  137. // Arrange
  138. var dateTimeOffset = new DateTimeOffset(2024, 3, 15, 14, 30, 0, TimeSpan.Zero);
  139. var format = "{ddd}, {MMM dd}, {HH:mm}";
  140. // Act
  141. var dateFormatExample = DateFormatExample.FromFormat(format, dateTimeOffset, CultureInfo.InvariantCulture);
  142. // Assert
  143. Assert.Equal(format, dateFormatExample.Format);
  144. Assert.Equal("Fri, Mar 15, 14:30", dateFormatExample.Example);
  145. }
  146. [Fact]
  147. public void DefaultExamples_ShouldNotBeEmpty()
  148. {
  149. // Assert
  150. Assert.NotEmpty(DateFormatExample.DefaultExamples);
  151. }
  152. [Fact]
  153. public void DefaultExamples_AllShouldHaveFormatAndExample()
  154. {
  155. // Assert
  156. foreach (var example in DateFormatExample.DefaultExamples)
  157. {
  158. Assert.NotNull(example.Format);
  159. Assert.NotEmpty(example.Format);
  160. Assert.NotNull(example.Example);
  161. Assert.NotEmpty(example.Example);
  162. }
  163. }
  164. [Fact]
  165. public void DefaultExamples_ShouldContainCustomFormats()
  166. {
  167. // Assert - check for some expected custom formats
  168. var formats = DateFormatExample.DefaultExamples.Select(e => e.Format).ToList();
  169. Assert.Contains(formats, f => f.Contains("{ddd}"));
  170. Assert.Contains(formats, f => f.Contains("{HH:mm}") || f.Contains("{h:mm tt}"));
  171. }
  172. [Fact]
  173. public void DefaultExamples_ShouldContainStandardFormats()
  174. {
  175. // Assert - check for some expected standard formats
  176. var formats = DateFormatExample.DefaultExamples.Select(e => e.Format).ToList();
  177. Assert.Contains("D", formats); // Long date pattern
  178. Assert.Contains("T", formats); // Long time pattern
  179. Assert.Contains("t", formats); // Short time pattern
  180. }
  181. }