StringParserTests.cs
  1  // Copyright (c) Microsoft Corporation
  2  // The Microsoft Corporation licenses this file to you under the MIT license.
  3  // See the LICENSE file in the project root for more information.
  4  
  5  using System;
  6  using System.Globalization;
  7  using Microsoft.CmdPal.Ext.TimeDate.Helpers;
  8  using Microsoft.VisualStudio.TestTools.UnitTesting;
  9  
 10  namespace Microsoft.CmdPal.Ext.TimeDate.UnitTests;
 11  
 12  [TestClass]
 13  public class StringParserTests
 14  {
 15      private CultureInfo originalCulture;
 16      private CultureInfo originalUiCulture;
 17  
 18      [TestInitialize]
 19      public void Setup()
 20      {
 21          // Set culture to 'en-us'
 22          originalCulture = CultureInfo.CurrentCulture;
 23          CultureInfo.CurrentCulture = new CultureInfo("en-us", false);
 24          originalUiCulture = CultureInfo.CurrentUICulture;
 25          CultureInfo.CurrentUICulture = new CultureInfo("en-us", false);
 26      }
 27  
 28      [DataTestMethod]
 29      [DataRow("10/29/2022 17:05:10", true, "G", "10/29/2022 5:05:10 PM")]
 30      [DataRow("Saturday, October 29, 2022 5:05:10 PM", true, "G", "10/29/2022 5:05:10 PM")]
 31      [DataRow("10/29/2022", true, "d", "10/29/2022")]
 32      [DataRow("Saturday, October 29, 2022", true, "d", "10/29/2022")]
 33      [DataRow("17:05:10", true, "T", "5:05:10 PM")]
 34      [DataRow("5:05:10 PM", true, "T", "5:05:10 PM")]
 35      [DataRow("10456", false, "", "")]
 36      [DataRow("u10456", true, "", "")] // Value is UTC and can be different based on system
 37      [DataRow("u-10456", true, "", "")] // Value is UTC and can be different based on system
 38      [DataRow("u+10456", true, "", "")] // Value is UTC and can be different based on system
 39      [DataRow("ums10456", true, "", "")] // Value is UTC and can be different based on system
 40      [DataRow("ums-10456", true, "", "")] // Value is UTC and can be different based on system
 41      [DataRow("ums+10456", true, "", "")] // Value is UTC and can be different based on system
 42      [DataRow("ft10456", true, "", "")] // Value is UTC and can be different based on system
 43      [DataRow("oa-657434.99999999", true, "G", "1/1/0100 11:59:59 PM")]
 44      [DataRow("oa2958465.99999999", true, "G", "12/31/9999 11:59:59 PM")]
 45      [DataRow("oa-657435", false, "", "")] // Value to low
 46      [DataRow("oa2958466", false, "", "")] // Value to large
 47      [DataRow("exc1.99998843", true, "G", "1/1/1900 11:59:59 PM")]
 48      [DataRow("exc59.99998843", true, "G", "2/28/1900 11:59:59 PM")]
 49      [DataRow("exc61", true, "G", "3/1/1900 12:00:00 AM")]
 50      [DataRow("exc62.99998843", true, "G", "3/2/1900 11:59:59 PM")]
 51      [DataRow("exc2958465.99998843", true, "G", "12/31/9999 11:59:59 PM")]
 52      [DataRow("exc0", false, "", "")] // Day 0 means in Excel 0/1/1900 and this is a fake date.
 53      [DataRow("exc0.99998843", false, "", "")] // Day 0 means in Excel 0/1/1900 and this is a fake date.
 54      [DataRow("exc60.99998843", false, "", "")] // Day 60 means in Excel 2/29/1900 and this is a fake date in Excel which we cannot support.
 55      [DataRow("exc60", false, "", "")] // Day 60 means in Excel 2/29/1900 and this is a fake date in Excel which we cannot support.
 56      [DataRow("exc-1", false, "", "")] // Value to low
 57      [DataRow("exc2958466", false, "", "")] // Value to large
 58      [DataRow("exf0.99998843", true, "G", "1/1/1904 11:59:59 PM")]
 59      [DataRow("exf2957003.99998843", true, "G", "12/31/9999 11:59:59 PM")]
 60      [DataRow("exf-0.5", false, "", "")] // Value to low
 61      [DataRow("exf2957004", false, "", "")] // Value to large
 62      public void ConvertStringToDateTime(string typedString, bool expectedBool, string stringType, string expectedString)
 63      {
 64          // Act
 65          var boolResult = TimeAndDateHelper.ParseStringAsDateTime(in typedString, out DateTime result, out _);
 66  
 67          // Assert
 68          Assert.AreEqual(expectedBool, boolResult);
 69          if (!string.IsNullOrEmpty(expectedString))
 70          {
 71              Assert.AreEqual(expectedString, result.ToString(stringType, CultureInfo.CurrentCulture));
 72          }
 73      }
 74  
 75      [TestMethod]
 76      public void ParseStringAsDateTime_BasicTest()
 77      {
 78          // Test basic string parsing functionality
 79          var testCases = new[]
 80          {
 81              ("2023-12-25", true),
 82              ("12/25/2023", true),
 83              ("invalid date", false),
 84              (string.Empty, false),
 85          };
 86  
 87          foreach (var (input, expectedSuccess) in testCases)
 88          {
 89              // Act
 90              var result = TimeAndDateHelper.ParseStringAsDateTime(in input, out DateTime dateTime, out var errorMessage);
 91  
 92              // Assert
 93              Assert.AreEqual(expectedSuccess, result, $"Failed for input: {input}");
 94              if (!expectedSuccess)
 95              {
 96                  Assert.IsFalse(string.IsNullOrEmpty(errorMessage), $"Error message should not be empty for invalid input: {input}");
 97              }
 98          }
 99      }
100  
101      [TestMethod]
102      public void ParseStringAsDateTime_UnixTimestampTest()
103      {
104          // Test Unix timestamp parsing
105          var unixTimestamp = "u1640995200"; // 2022-01-01 00:00:00 UTC
106  
107          // Act
108          var result = TimeAndDateHelper.ParseStringAsDateTime(in unixTimestamp, out DateTime dateTime, out var errorMessage);
109  
110          // Assert
111          Assert.IsTrue(result, "Unix timestamp parsing should succeed");
112          Assert.IsTrue(string.IsNullOrEmpty(errorMessage), "Error message should be empty for valid Unix timestamp");
113      }
114  
115      [TestMethod]
116      public void ParseStringAsDateTime_FileTimeTest()
117      {
118          // Test Windows file time parsing
119          var fileTime = "ft132857664000000000"; // Some valid file time
120  
121          // Act
122          var result = TimeAndDateHelper.ParseStringAsDateTime(in fileTime, out DateTime dateTime, out var errorMessage);
123  
124          // Assert
125          Assert.IsTrue(result, "File time parsing should succeed");
126      }
127  
128      [TestCleanup]
129      public void CleanUp()
130      {
131          // Set culture to original value
132          CultureInfo.CurrentCulture = originalCulture;
133          CultureInfo.CurrentUICulture = originalUiCulture;
134      }
135  }