QueryTests.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 System.Linq; 8 using Microsoft.CmdPal.Ext.TimeDate.Helpers; 9 using Microsoft.CmdPal.Ext.TimeDate.Pages; 10 using Microsoft.CmdPal.Ext.UnitTestBase; 11 using Microsoft.VisualStudio.TestTools.UnitTesting; 12 13 namespace Microsoft.CmdPal.Ext.TimeDate.UnitTests; 14 15 [TestClass] 16 public class QueryTests : CommandPaletteUnitTestBase 17 { 18 private CultureInfo originalCulture; 19 private CultureInfo originalUiCulture; 20 21 [TestInitialize] 22 public void Setup() 23 { 24 // Set culture to 'en-us' 25 originalCulture = CultureInfo.CurrentCulture; 26 CultureInfo.CurrentCulture = new CultureInfo("en-us", false); 27 originalUiCulture = CultureInfo.CurrentUICulture; 28 CultureInfo.CurrentUICulture = new CultureInfo("en-us", false); 29 } 30 31 [TestCleanup] 32 public void CleanUp() 33 { 34 // Set culture to original value 35 CultureInfo.CurrentCulture = originalCulture; 36 CultureInfo.CurrentUICulture = originalUiCulture; 37 } 38 39 [DataTestMethod] 40 [DataRow("time", 1)] // Common time queries should return results 41 [DataRow("date", 1)] // Common date queries should return results 42 [DataRow("now", 1)] // Now should return multiple results 43 [DataRow("current", 1)] // Current should return multiple results 44 [DataRow("year", 1)] // Year-related queries should return results 45 [DataRow("time::10:10:10", 1)] // Specific time format should return results 46 [DataRow("date::10/10/10", 1)] // Specific date format should return results 47 public void CountBasicQueries(string query, int expectedMinResultCount) 48 { 49 // Setup 50 var settings = new Settings(); 51 52 // Act 53 var results = TimeDateCalculator.ExecuteSearch(settings, query); 54 55 // Assert 56 Assert.IsTrue( 57 results.Count >= expectedMinResultCount, 58 $"Expected at least {expectedMinResultCount} results for query '{query}', but got {results.Count}"); 59 } 60 61 [DataTestMethod] 62 [DataRow("time", "time")] 63 [DataRow("date", "date")] 64 [DataRow("year", "year")] 65 [DataRow("now", "now")] 66 [DataRow("year", "year")] 67 public void BasicQueryTest(string input, string expectedMatchTerm) 68 { 69 var settings = new Settings(); 70 var page = new TimeDateExtensionPage(settings); 71 page.UpdateSearchText(string.Empty, input); 72 var resultLists = page.GetItems(); 73 74 var result = Query(input, resultLists); 75 76 Assert.IsNotNull(result); 77 Assert.IsTrue(result.Length > 0, "No items matched the query."); 78 79 var firstItem = result.FirstOrDefault(); 80 Assert.IsNotNull(firstItem, "No items matched the query."); 81 Assert.IsTrue( 82 firstItem.Title.Contains(expectedMatchTerm, System.StringComparison.OrdinalIgnoreCase) || 83 firstItem.Subtitle.Contains(expectedMatchTerm, System.StringComparison.OrdinalIgnoreCase), 84 $"Expected to match '{expectedMatchTerm}' in title or subtitle but got '{firstItem.Title}' - '{firstItem.Subtitle}'"); 85 } 86 87 [DataTestMethod] 88 [DataRow("unix", "Unix epoch time")] 89 [DataRow("unix epoch time in milli", "Unix epoch time in milliseconds")] 90 [DataRow("file", "Windows file time (Int64 number)")] 91 [DataRow("hour", "Hour")] 92 [DataRow("minute", "Minute")] 93 [DataRow("second", "Second")] 94 [DataRow("millisecond", "Millisecond")] 95 [DataRow("day", "Day (Week day)")] 96 [DataRow("day of week", "Day of the week (Week day)")] 97 [DataRow("day of month", "Day of the month")] 98 [DataRow("day of year", "Day of the year")] 99 [DataRow("week of month", "Week of the month")] 100 [DataRow("week of year", "Week of the year (Calendar week, Week number)")] 101 [DataRow("month", "Month")] 102 [DataRow("month of year", "Month of the year")] 103 [DataRow("month and d", "Month and day")] 104 [DataRow("year", "Year")] 105 [DataRow("universal", "Universal time format: YYYY-MM-DD hh:mm:ss")] 106 [DataRow("rfc", "RFC1123")] 107 [DataRow("time::12:30", "Time")] 108 [DataRow("date::10.10.2022", "Date")] 109 [DataRow("time::u1646408119", "Time")] 110 [DataRow("time::ft637820085517321977", "Time")] 111 [DataRow("week day", "Day (Week day)")] 112 [DataRow("cal week", "Week of the year (Calendar week, Week number)")] 113 [DataRow("week num", "Week of the year (Calendar week, Week number)")] 114 [DataRow("days in mo", "Days in month")] 115 [DataRow("Leap y", "Leap year")] 116 public void FormatDateQueryTest(string input, string expectedMatchTerm) 117 { 118 var settings = new Settings(); 119 var page = new TimeDateExtensionPage(settings); 120 page.UpdateSearchText(string.Empty, input); 121 var resultLists = page.GetItems(); 122 123 var firstItem = resultLists.FirstOrDefault(); 124 Assert.IsNotNull(firstItem, "No items matched the query."); 125 Assert.IsTrue( 126 firstItem.Title.Contains(expectedMatchTerm, System.StringComparison.OrdinalIgnoreCase) || 127 firstItem.Subtitle.Contains(expectedMatchTerm, System.StringComparison.OrdinalIgnoreCase), 128 $"Expected to match '{expectedMatchTerm}' in title or subtitle but got '{firstItem.Title}' - '{firstItem.Subtitle}'"); 129 } 130 131 [DataTestMethod] 132 [DataRow("abcdefg")] 133 [DataRow("timmmmeeee")] 134 [DataRow("timtaaaetetaae::u1646408119")] 135 [DataRow("time:eeee")] 136 [DataRow("time::eeee")] 137 [DataRow("time//eeee")] 138 [DataRow("ug1646408119")] // Invalid prefix 139 [DataRow("u9999999999999")] // Unix number + prefix is longer than 12 characters 140 [DataRow("ums999999999999999")] // Unix number in milliseconds + prefix is longer than 17 characters 141 [DataRow("-u99999999999")] // Unix number with wrong placement of - sign 142 [DataRow("+ums9999999999")] // Unix number in milliseconds with wrong placement of + sign 143 [DataRow("0123456")] // Missing prefix 144 [DataRow("ft63782008ab55173dasdas21977")] // Number contains letters 145 [DataRow("ft63782008ab55173dasdas")] // Number contains letters at the end 146 [DataRow("ft12..548")] // Number contains wrong punctuation 147 [DataRow("ft12..54//8")] // Number contains wrong punctuation and other characters 148 [DataRow("time::ft12..54//8")] // Number contains wrong punctuation and other characters 149 [DataRow("ut2ed.5555")] // Number contains letters 150 [DataRow("12..54//8")] // Number contains punctuation and other characters, but no special prefix 151 [DataRow("ft::1288gg8888")] // Number contains delimiter and letters, but no special prefix 152 [DataRow("date::12::55")] 153 [DataRow("date::12:aa:55")] 154 [DataRow("10.aa.22")] 155 [DataRow("12::55")] 156 [DataRow("12:aa:55")] 157 public void InvalidInputShowsErrorResults(string query) 158 { 159 var settings = new Settings(); 160 var page = new TimeDateExtensionPage(settings); 161 page.UpdateSearchText(string.Empty, query); 162 var results = page.GetItems(); 163 164 // Assert 165 Assert.IsNotNull(results, $"Results should not be null for query '{query}'"); 166 Assert.IsTrue(results.Length > 0, $"Query '{query}' should return at least one result"); 167 168 var firstItem = results.FirstOrDefault(); 169 Assert.IsTrue(firstItem.Title.StartsWith("Error: Invalid input", StringComparison.CurrentCulture), $"Query '{query}' should return an error result for invalid input"); 170 } 171 172 [DataTestMethod] 173 [DataRow("")] 174 [DataRow(null)] 175 public void EmptyQueryReturnsAllResults(string input) 176 { 177 var settings = new Settings(); 178 var page = new TimeDateExtensionPage(settings); 179 page.UpdateSearchText("abc", input); 180 var results = page.GetItems(); 181 182 // Assert 183 Assert.IsTrue(results.Length > 0, $"Empty query should return results"); 184 } 185 186 [DataTestMethod] 187 [DataRow("time u", "Time UTC")] 188 [DataRow("now u", "Now UTC")] 189 [DataRow("iso utc", "ISO 8601 UTC")] 190 [DataRow("iso zone", "ISO 8601 with time zone")] 191 [DataRow("iso utc zone", "ISO 8601 UTC with time zone")] 192 public void TimeZoneQuery(string query, string expectedSubtitle) 193 { 194 var settings = new Settings(); 195 var page = new TimeDateExtensionPage(settings); 196 page.UpdateSearchText(string.Empty, query); 197 var resultsList = page.GetItems(); 198 var results = Query(query, resultsList); 199 200 // Assert 201 Assert.IsNotNull(results); 202 var firstResult = results.FirstOrDefault(); 203 Assert.IsTrue(firstResult.Subtitle.StartsWith(expectedSubtitle, StringComparison.CurrentCulture), $"Could not find result with subtitle starting with '{expectedSubtitle}' for query '{query}'"); 204 } 205 206 [DataTestMethod] 207 [DataRow("time::12:30:45", "12:30 PM")] 208 [DataRow("date::2023-12-25", "12/25/2023")] 209 [DataRow("now::u1646408119", "132908817190000000")] 210 public void DelimiterQueriesReturnResults(string query, string expectedResult) 211 { 212 var settings = new Settings(); 213 var page = new TimeDateExtensionPage(settings); 214 page.UpdateSearchText(string.Empty, query); 215 var resultsList = page.GetItems(); 216 217 // Assert 218 Assert.IsNotNull(resultsList); 219 var firstResult = resultsList.FirstOrDefault(); 220 Assert.IsTrue(firstResult.Title.Contains(expectedResult, StringComparison.CurrentCulture), $"Delimiter query '{query}' result not match {expectedResult} current result {firstResult.Title}"); 221 } 222 }