/ src / modules / launcher / Plugins / Microsoft.PowerToys.Run.Plugin.TimeDate.UnitTests / QueryTests.cs
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 9 using Microsoft.VisualStudio.TestTools.UnitTesting; 10 using Moq; 11 using Wox.Infrastructure; 12 using Wox.Plugin; 13 14 namespace Microsoft.PowerToys.Run.Plugin.TimeDate.UnitTests 15 { 16 [TestClass] 17 public class QueryTests 18 { 19 private CultureInfo originalCulture; 20 private CultureInfo originalUiCulture; 21 22 [TestInitialize] 23 public void Setup() 24 { 25 StringMatcher.Instance = new StringMatcher(); 26 27 // Set culture to 'en-us' 28 originalCulture = CultureInfo.CurrentCulture; 29 CultureInfo.CurrentCulture = new CultureInfo("en-us", false); 30 originalUiCulture = CultureInfo.CurrentUICulture; 31 CultureInfo.CurrentUICulture = new CultureInfo("en-us", false); 32 } 33 34 [DataTestMethod] 35 [DataRow("time", 2)] // Setting 'Only Date, Time, Now on global results' is default on 36 [DataRow("date", 2)] // Setting 'Only Date, Time, Now on global results' is default on 37 [DataRow("now", 3)] // Setting 'Only Date, Time, Now on global results' is default on 38 [DataRow("current", 3)] // Setting 'Only Date, Time, Now on global results' is default on 39 [DataRow("year", 0)] // Setting 'Only Date, Time, Now on global results' is default on 40 [DataRow("time::10:10:10", 0)] // Setting 'Only Date, Time, Now on global results' is default on 41 [DataRow("date::10/10/10", 0)] // Setting 'Only Date, Time, Now on global results' is default on 42 public void CountWithoutPluginKeyword(string typedString, int expectedResultCount) 43 { 44 // Setup 45 Mock<Main> main = new(); 46 Query expectedQuery = new(typedString); 47 48 // Act 49 var result = main.Object.Query(expectedQuery).Count; 50 51 // Assert 52 Assert.AreEqual(expectedResultCount, result, "Result depends on default plugin settings!"); 53 } 54 55 [DataTestMethod] 56 [DataRow("(time", 18)] 57 [DataRow("(date", 28)] 58 [DataRow("(year", 8)] 59 [DataRow("(now", 34)] 60 [DataRow("(current", 34)] 61 [DataRow("(", 34)] 62 [DataRow("(now::10:10:10", 1)] // Windows file time 63 [DataRow("(current::10:10:10", 0)] 64 public void CountWithPluginKeyword(string typedString, int expectedResultCount) 65 { 66 // Setup 67 Mock<Main> main = new(); 68 Query expectedQuery = new(typedString, "("); 69 70 // Act 71 var result = main.Object.Query(expectedQuery); 72 73 // Assert 74 Assert.AreEqual(expectedResultCount, result.Count, result.ToString()); 75 } 76 77 [DataTestMethod] 78 [DataRow("time", 2)] // Match if first word is a full word match 79 [DataRow("ime", 0)] // Don't match if first word is not a full match 80 [DataRow("and", 0)] // Don't match for only conjunctions 81 [DataRow("and time", 1)] // match if term is conjunction and other words 82 [DataRow("date and time", 1)] // Match if first word is a full word match 83 [DataRow("ate and time", 0)] // Don't match if first word is not a full word match 84 [DataRow("10/10/10", 0)] // Don't match number only input (Setting 'Only Date, Time, Now on global results' is default on) 85 [DataRow("10:10:10", 0)] // Don't match number only input (Setting 'Only Date, Time, Now on global results' is default on) 86 [DataRow("10 10 10", 0)] // Don't match number only input (Setting 'Only Date, Time, Now on global results' is default on) 87 [DataRow("ft10", 1)] // Don't match number input with prefix (Setting 'Only Date, Time, Now on global results' is default on) => Test behave strange here. 88 public void ValidateBehaviorOnGlobalQueries(string typedString, int expectedResultCount) 89 { 90 // Setup 91 Mock<Main> main = new(); 92 Query expectedQuery = new(typedString); 93 94 // Act 95 var result = main.Object.Query(expectedQuery); 96 97 // Assert 98 Assert.AreEqual(expectedResultCount, result.Count, result.ToString()); 99 } 100 101 [DataTestMethod] 102 [DataRow("(time", "Time -")] 103 [DataRow("(time u", "Time UTC -")] 104 [DataRow("(date", "Date -")] 105 [DataRow("(now", "Now -")] 106 [DataRow("(now u", "Now UTC -")] 107 [DataRow("(unix", "Unix epoch time -")] 108 [DataRow("(unix epoch time in milli", "Unix epoch time in milliseconds -")] 109 [DataRow("(file", "Windows file time (Int64 number) ")] 110 [DataRow("(hour", "Hour -")] 111 [DataRow("(minute", "Minute -")] 112 [DataRow("(second", "Second -")] 113 [DataRow("(millisecond", "Millisecond -")] 114 [DataRow("(day", "Day (Week day) -")] 115 [DataRow("(day of week", "Day of the week (Week day) -")] 116 [DataRow("(day of month", "Day of the month -")] 117 [DataRow("(day of year", "Day of the year -")] 118 [DataRow("(week of month", "Week of the month -")] 119 [DataRow("(week of year", "Week of the year (Calendar week, Week number) -")] 120 [DataRow("(month", "Month -")] 121 [DataRow("(month of year", "Month of the year -")] 122 [DataRow("(month and d", "Month and day -")] 123 [DataRow("(month and y", "Month and year -")] 124 [DataRow("(year", "Year -")] 125 [DataRow("(era", "Era -")] 126 [DataRow("(era a", "Era abbreviation -")] 127 [DataRow("(universal", "Universal time format: YYYY-MM-DD hh:mm:ss -")] 128 [DataRow("(iso", "ISO 8601 -")] 129 [DataRow("(iso utc", "ISO 8601 UTC -")] 130 [DataRow("(iso zone", "ISO 8601 with time zone - ")] 131 [DataRow("(iso utc zone", "ISO 8601 UTC with time zone -")] 132 [DataRow("(rfc", "RFC1123 -")] 133 [DataRow("(time::12:30", "Time -")] 134 [DataRow("(date::10.10.2022", "Date -")] 135 [DataRow("(time::u1646408119", "Time -")] 136 [DataRow("(time::ft637820085517321977", "Time -")] 137 [DataRow("(year", "Era -")] 138 [DataRow("(date", "Era -")] 139 [DataRow("(week day", "Day (Week day) -")] 140 [DataRow("(week day", "Day of the week (Week day) -")] 141 [DataRow("(cal week", "Week of the year (Calendar week, Week number) -")] 142 [DataRow("(week num", "Week of the year (Calendar week, Week number) -")] 143 [DataRow("(days in mo", "Days in month -")] 144 [DataRow("(Leap y", "Leap year -")] 145 public void CanFindFormatResult(string typedString, string expectedResult) 146 { 147 // Setup 148 Mock<Main> main = new(); 149 Query expectedQuery = new(typedString, "("); 150 151 // Act 152 var result = main.Object.Query(expectedQuery).FirstOrDefault(x => x.SubTitle.StartsWith(expectedResult, StringComparison.CurrentCulture)); 153 154 // Assert 155 Assert.IsNotNull(result); 156 Assert.IsTrue(result?.Score >= 1, $"Score: {result?.Score}"); 157 } 158 159 [DataTestMethod] 160 [DataRow("(12:30", "Time -")] 161 [DataRow("(10.10.2022", "Date -")] 162 [DataRow("(u1646408119", "Date and time -")] 163 [DataRow("(u+1646408119", "Date and time -")] 164 [DataRow("(u-1646408119", "Date and time -")] 165 [DataRow("(ums1646408119", "Date and time -")] 166 [DataRow("(ums+1646408119", "Date and time -")] 167 [DataRow("(ums-1646408119", "Date and time -")] 168 [DataRow("(ft637820085517321977", "Date and time -")] 169 public void DateTimeNumberOnlyInput(string typedString, string expectedResult) 170 { 171 // Setup 172 Mock<Main> main = new(); 173 Query expectedQuery = new(typedString, "("); 174 175 // Act 176 var result = main.Object.Query(expectedQuery).FirstOrDefault(x => x.SubTitle.StartsWith(expectedResult, StringComparison.CurrentCulture)); 177 178 // Assert 179 Assert.IsNotNull(result); 180 } 181 182 // [DataRow("(::")] -> Behaves different to PT Run user interface 183 // [DataRow("(time::")] -> Behaves different to PT Run user interface 184 // [DataRow("(::time")] -> Behaves different to PT Run user interface 185 [DataTestMethod] 186 [DataRow("(abcdefg")] 187 [DataRow("(timmmmeeee")] 188 [DataRow("(timtaaaetetaae::u1646408119")] 189 [DataRow("(time:eeee")] 190 [DataRow("(time::eeee")] 191 [DataRow("(time//eeee")] 192 public void InvalidInputNotShowsResults(string typedString) 193 { 194 // Setup 195 Mock<Main> main = new(); 196 Query expectedQuery = new(typedString, "("); 197 198 // Act 199 var result = main.Object.Query(expectedQuery).FirstOrDefault(); 200 201 // Assert 202 Assert.IsNull(result, result?.ToString()); 203 } 204 205 [DataTestMethod] 206 [DataRow("(ug1646408119")] // Invalid prefix 207 [DataRow("(u9999999999999")] // Unix number + prefix is longer than 12 characters 208 [DataRow("(ums999999999999999")] // Unix number in milliseconds + prefix is longer than 17 characters 209 [DataRow("(-u99999999999")] // Unix number with wrong placement of - sign 210 [DataRow("(+ums9999999999")] // Unix number in milliseconds with wrong placement of + sign 211 [DataRow("(0123456")] // Missing prefix 212 [DataRow("(ft63782008ab55173dasdas21977")] // Number contains letters 213 [DataRow("(ft63782008ab55173dasdas")] // Number contains letters at the end 214 [DataRow("(ft12..548")] // Number contains wrong punctuation 215 [DataRow("(ft12..54//8")] // Number contains wrong punctuation and other characters 216 [DataRow("(time::ft12..54//8")] // Number contains wrong punctuation and other characters 217 [DataRow("(ut2ed.5555")] // Number contains letters 218 [DataRow("(12..54//8")] // Number contains punctuation and other characters, but no special prefix 219 [DataRow("(ft::1288gg8888")] // Number contains delimiter and letters, but no special prefix 220 [DataRow("(date::12::55")] 221 [DataRow("(date::12:aa:55")] 222 [DataRow("(10.aa.22")] 223 [DataRow("(12::55")] 224 [DataRow("(12:aa:55")] 225 public void InvalidNumberInputShowsErrorMessage(string typedString) 226 { 227 // Setup 228 Mock<Main> main = new(); 229 Query expectedQuery = new(typedString, "("); 230 231 // Act 232 var result = main.Object.Query(expectedQuery).FirstOrDefault().Title; 233 234 // Assert 235 Assert.IsTrue(result.StartsWith("Error:", StringComparison.CurrentCulture)); 236 } 237 238 [DataTestMethod] 239 [DataRow("(ft1 2..548")] // Input contains space 240 [DataRow("(ft12..54 //8")] // Input contains space 241 [DataRow("(time::ft12..54 //8")] // Input contains space 242 [DataRow("(10.10aa")] // Input contains <Number>.<Number> (Can be part of a date.) 243 [DataRow("(10:10aa")] // Input contains <Number>:<Number> (Can be part of a time.) 244 [DataRow("(10/10aa")] // Input contains <Number>/<Number> (Can be part of a date.) 245 public void InvalidInputNotShowsErrorMessage(string typedString) 246 { 247 // Setup 248 Mock<Main> main = new(); 249 Query expectedQuery = new(typedString, "("); 250 251 // Act 252 var result = main.Object.Query(expectedQuery).FirstOrDefault(); 253 254 // Assert 255 Assert.IsNull(result); 256 } 257 258 [TestCleanup] 259 public void CleanUp() 260 { 261 // Set culture to original value 262 CultureInfo.CurrentCulture = originalCulture; 263 CultureInfo.CurrentUICulture = originalUiCulture; 264 } 265 } 266 }