/ src / modules / cmdpal / Tests / Microsoft.CmdPal.Ext.Bookmarks.UnitTests / BookmarkResolverTests.Quoted.cs
BookmarkResolverTests.Quoted.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.Collections.Generic;
  7  using System.IO;
  8  using System.Threading.Tasks;
  9  using Microsoft.CmdPal.Ext.Bookmarks.Helpers;
 10  using Microsoft.VisualStudio.TestTools.UnitTesting;
 11  
 12  namespace Microsoft.CmdPal.Ext.Bookmarks.UnitTests;
 13  
 14  public partial class BookmarkResolverTests
 15  {
 16      [DataTestMethod]
 17      [DynamicData(dynamicDataSourceName: nameof(QuotedClassificationData.MixedQuotesScenarios), dynamicDataDeclaringType: typeof(QuotedClassificationData), DynamicDataDisplayName = nameof(FromCase))]
 18      public async Task Quoted_ValidateMixedQuotesScenarios(PlaceholderClassificationCase c) => await RunShared(c: c);
 19  
 20      [DataTestMethod]
 21      [DynamicData(dynamicDataSourceName: nameof(QuotedClassificationData.EscapedQuotes), dynamicDataDeclaringType: typeof(QuotedClassificationData), DynamicDataDisplayName = nameof(FromCase))]
 22      public async Task Quoted_ValidateEscapedQuotes(PlaceholderClassificationCase c) => await RunShared(c: c);
 23  
 24      [DataTestMethod]
 25      [DynamicData(dynamicDataSourceName: nameof(QuotedClassificationData.PartialMalformedQuotes), dynamicDataDeclaringType: typeof(QuotedClassificationData), DynamicDataDisplayName = nameof(FromCase))]
 26      public async Task Quoted_ValidatePartialMalformedQuotes(PlaceholderClassificationCase c) => await RunShared(c: c);
 27  
 28      [DataTestMethod]
 29      [DynamicData(dynamicDataSourceName: nameof(QuotedClassificationData.EnvironmentVariablesWithQuotes), dynamicDataDeclaringType: typeof(QuotedClassificationData), DynamicDataDisplayName = nameof(FromCase))]
 30      public async Task Quoted_ValidateEnvironmentVariablesWithQuotes(PlaceholderClassificationCase c) => await RunShared(c: c);
 31  
 32      [DataTestMethod]
 33      [DynamicData(dynamicDataSourceName: nameof(QuotedClassificationData.ShellProtocolPathsWithQuotes), dynamicDataDeclaringType: typeof(QuotedClassificationData), DynamicDataDisplayName = nameof(FromCase))]
 34      public async Task Quoted_ValidateShellProtocolPathsWithQuotes(PlaceholderClassificationCase c) => await RunShared(c: c);
 35  
 36      [DataTestMethod]
 37      [DynamicData(dynamicDataSourceName: nameof(QuotedClassificationData.CommandFlagsAndOptions), dynamicDataDeclaringType: typeof(QuotedClassificationData), DynamicDataDisplayName = nameof(FromCase))]
 38      public async Task Quoted_ValidateCommandFlagsAndOptions(PlaceholderClassificationCase c) => await RunShared(c: c);
 39  
 40      [DataTestMethod]
 41      [DynamicData(dynamicDataSourceName: nameof(QuotedClassificationData.NetworkPathsUnc), dynamicDataDeclaringType: typeof(QuotedClassificationData), DynamicDataDisplayName = nameof(FromCase))]
 42      public async Task Quoted_ValidateNetworkPathsUnc(PlaceholderClassificationCase c) => await RunShared(c: c);
 43  
 44      [DataTestMethod]
 45      [DynamicData(dynamicDataSourceName: nameof(QuotedClassificationData.RelativePathsWithQuotes), dynamicDataDeclaringType: typeof(QuotedClassificationData), DynamicDataDisplayName = nameof(FromCase))]
 46      public async Task Quoted_ValidateRelativePathsWithQuotes(PlaceholderClassificationCase c) => await RunShared(c: c);
 47  
 48      [DataTestMethod]
 49      [DynamicData(dynamicDataSourceName: nameof(QuotedClassificationData.EmptyAndWhitespaceCases), dynamicDataDeclaringType: typeof(QuotedClassificationData), DynamicDataDisplayName = nameof(FromCase))]
 50      public async Task Quoted_ValidateEmptyAndWhitespaceCases(PlaceholderClassificationCase c) => await RunShared(c: c);
 51  
 52      [DataTestMethod]
 53      [DynamicData(dynamicDataSourceName: nameof(QuotedClassificationData.RealWorldCommandScenarios), dynamicDataDeclaringType: typeof(QuotedClassificationData), DynamicDataDisplayName = nameof(FromCase))]
 54      public async Task Quoted_ValidateRealWorldCommandScenarios(PlaceholderClassificationCase c) => await RunShared(c: c);
 55  
 56      [DataTestMethod]
 57      [DynamicData(dynamicDataSourceName: nameof(QuotedClassificationData.SpecialCharactersInPaths), dynamicDataDeclaringType: typeof(QuotedClassificationData), DynamicDataDisplayName = nameof(FromCase))]
 58      public async Task Quoted_ValidateSpecialCharactersInPaths(PlaceholderClassificationCase c) => await RunShared(c: c);
 59  
 60      [DataTestMethod]
 61      [DynamicData(dynamicDataSourceName: nameof(QuotedClassificationData.QuotedPathsCurrentlyBroken), dynamicDataDeclaringType: typeof(QuotedClassificationData), DynamicDataDisplayName = nameof(FromCase))]
 62      public async Task Quoted_ValidateQuotedPathsCurrentlyBroken(PlaceholderClassificationCase c) => await RunShared(c: c);
 63  
 64      [DataTestMethod]
 65      [DynamicData(dynamicDataSourceName: nameof(QuotedClassificationData.QuotedPathsInCommands), dynamicDataDeclaringType: typeof(QuotedClassificationData), DynamicDataDisplayName = nameof(FromCase))]
 66      public async Task Quoted_ValidateQuotedPathsInCommands(PlaceholderClassificationCase c) => await RunShared(c: c);
 67  
 68      [DataTestMethod]
 69      [DynamicData(dynamicDataSourceName: nameof(QuotedClassificationData.QuotedAumid), dynamicDataDeclaringType: typeof(QuotedClassificationData), DynamicDataDisplayName = nameof(FromCase))]
 70      public async Task Quoted_ValidateQuotedUwpAppAumidCommands(PlaceholderClassificationCase c) => await RunShared(c: c);
 71  
 72      public static class QuotedClassificationData
 73      {
 74          public static IEnumerable<object[]> MixedQuotesScenarios() =>
 75          [
 76              [
 77                  new PlaceholderClassificationCase(
 78                      Name: "Executable with quoted argument",
 79                      Input: "C:\\Windows\\notepad.exe \"C:\\my file.txt\"",
 80                      ExpectSuccess: true,
 81                      ExpectedKind: CommandKind.FileExecutable,
 82                      ExpectedTarget: "C:\\Windows\\notepad.exe",
 83                      ExpectedArguments: "\"C:\\my file.txt\"",
 84                      ExpectedLaunch: LaunchMethod.ShellExecute,
 85                      ExpectedIsPlaceholder: false)
 86              ],
 87              [
 88                  new PlaceholderClassificationCase(
 89                      Name: "App with quoted argument containing spaces",
 90                      Input: "app.exe \"argument with spaces\"",
 91                      ExpectSuccess: true,
 92                      ExpectedKind: CommandKind.Unknown,
 93                      ExpectedTarget: "app.exe",
 94                      ExpectedArguments: "\"argument with spaces\"",
 95                      ExpectedLaunch: LaunchMethod.ShellExecute,
 96                      ExpectedIsPlaceholder: false)
 97              ],
 98              [
 99                  new PlaceholderClassificationCase(
100                      Name: "Tool with input flag and quoted file",
101                      Input: "C:\\tool.exe -input \"data file.txt\"",
102                      ExpectSuccess: true,
103                      ExpectedKind: CommandKind.FileExecutable,
104                      ExpectedTarget: "C:\\tool.exe",
105                      ExpectedArguments: "-input \"data file.txt\"",
106                      ExpectedLaunch: LaunchMethod.ShellExecute,
107                      ExpectedIsPlaceholder: false)
108              ],
109              [
110                  new PlaceholderClassificationCase(
111                      Name: "Multiple quoted arguments after path",
112                      Input: "\"C:\\Program Files\\app.exe\" -file \"C:\\data\\input.txt\" -output \"C:\\results\\output.txt\"",
113                      ExpectSuccess: true,
114                      ExpectedKind: CommandKind.FileExecutable,
115                      ExpectedTarget: "C:\\Program Files\\app.exe",
116                      ExpectedArguments: "-file \"C:\\data\\input.txt\" -output \"C:\\results\\output.txt\"",
117                      ExpectedLaunch: LaunchMethod.ShellExecute,
118                      ExpectedIsPlaceholder: false)
119              ],
120              [
121                  new PlaceholderClassificationCase(
122                      Name: "Command with two quoted paths",
123                      Input: "cmd /c \"C:\\First Path\\tool.exe\" \"C:\\Second Path\\file.txt\"",
124                      ExpectSuccess: true,
125                      ExpectedKind: CommandKind.PathCommand,
126                      ExpectedTarget: "C:\\Windows\\system32\\cmd.EXE",
127                      ExpectedArguments: "/c \"C:\\First Path\\tool.exe\" \"C:\\Second Path\\file.txt\"",
128                      ExpectedLaunch: LaunchMethod.ShellExecute,
129                      ExpectedIsPlaceholder: false)
130              ]
131          ];
132  
133          public static IEnumerable<object[]> EscapedQuotes() =>
134          [
135              [
136                  new PlaceholderClassificationCase(
137                      Name: "Path with escaped quotes in folder name",
138                      Input: "C:\\Windows\\\\\\\"System32\\\\\\\"CatRoot\\\\",
139                      ExpectSuccess: true,
140                      ExpectedKind: CommandKind.Unknown,
141                      ExpectedTarget: "C:\\Windows\\\\\\\"System32\\\\\\\"CatRoot\\\\",
142                      ExpectedLaunch: LaunchMethod.ShellExecute,
143                      ExpectedIsPlaceholder: false)
144              ],
145              [
146                  new PlaceholderClassificationCase(
147                      Name: "Quoted path with trailing escaped quote",
148                      Input: "\"C:\\Windows\\\\\\\"\"",
149                      ExpectSuccess: true,
150                      ExpectedKind: CommandKind.Directory,
151                      ExpectedTarget: "C:\\Windows\\",
152                      ExpectedLaunch: LaunchMethod.ExplorerOpen,
153                      ExpectedIsPlaceholder: false)
154              ]
155          ];
156  
157          public static IEnumerable<object[]> PartialMalformedQuotes() =>
158          [
159              [
160                  new PlaceholderClassificationCase(
161                      Name: "Unclosed quote at start",
162                      Input: "\"C:\\Program Files\\app.exe",
163                      ExpectSuccess: true,
164                      ExpectedKind: CommandKind.FileExecutable,
165                      ExpectedTarget: "C:\\Program Files\\app.exe",
166                      ExpectedLaunch: LaunchMethod.ShellExecute,
167                      ExpectedIsPlaceholder: false)
168              ],
169              [
170                  new PlaceholderClassificationCase(
171                      Name: "Quote in middle of unquoted path",
172                      Input: "C:\\Some\\\"Path\\file.txt",
173                      ExpectSuccess: true,
174                      ExpectedKind: CommandKind.FileDocument,
175                      ExpectedTarget: "C:\\Some\\\"Path\\file.txt",
176                      ExpectedLaunch: LaunchMethod.ShellExecute,
177                      ExpectedIsPlaceholder: false)
178              ],
179              [
180                  new PlaceholderClassificationCase(
181                      Name: "Unclosed quote - never ends",
182                      Input: "\"Starts quoted but never ends",
183                      ExpectSuccess: true,
184                      ExpectedKind: CommandKind.Unknown,
185                      ExpectedTarget: "Starts quoted but never ends",
186                      ExpectedLaunch: LaunchMethod.ShellExecute,
187                      ExpectedIsPlaceholder: false)
188              ]
189          ];
190  
191          public static IEnumerable<object[]> EnvironmentVariablesWithQuotes() =>
192          [
193              [
194                  new PlaceholderClassificationCase(
195                      Name: "Quoted environment variable path with spaces",
196                      Input: "\"%ProgramFiles%\\MyApp\\app.exe\"",
197                      ExpectSuccess: true,
198                      ExpectedKind: CommandKind.FileExecutable,
199                      ExpectedTarget: Path.Combine(path1: Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), "MyApp", "app.exe"),
200                      ExpectedLaunch: LaunchMethod.ShellExecute,
201                      ExpectedIsPlaceholder: false)
202              ],
203              [
204                  new PlaceholderClassificationCase(
205                      Name: "Quoted USERPROFILE with document path",
206                      Input: "\"%USERPROFILE%\\Documents\\file with spaces.txt\"",
207                      ExpectSuccess: true,
208                      ExpectedKind: CommandKind.FileDocument,
209                      ExpectedTarget: Path.Combine(path1: Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "Documents", "file with spaces.txt"),
210                      ExpectedLaunch: LaunchMethod.ShellExecute,
211                      ExpectedIsPlaceholder: false)
212              ],
213              [
214                  new PlaceholderClassificationCase(
215                      Name: "Environment variable with trailing args",
216                      Input: "\"%ProgramFiles%\\App\" with args",
217                      ExpectSuccess: true,
218                      ExpectedKind: CommandKind.Unknown,
219                      ExpectedTarget: Path.Combine(path1: Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), "App"),
220                      ExpectedArguments: "with args",
221                      ExpectedLaunch: LaunchMethod.ShellExecute,
222                      ExpectedIsPlaceholder: false)
223              ],
224              [
225                  new PlaceholderClassificationCase(
226                      Name: "Environment variable with trailing args",
227                      Input: "%ProgramFiles%\\App with args",
228                      ExpectSuccess: true,
229                      ExpectedKind: CommandKind.Unknown,
230                      ExpectedTarget: Path.Combine(path1: Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), "App"),
231                      ExpectedArguments: "with args",
232                      ExpectedLaunch: LaunchMethod.ShellExecute,
233                      ExpectedIsPlaceholder: false)
234              ],
235          ];
236  
237          public static IEnumerable<object[]> ShellProtocolPathsWithQuotes() =>
238          [
239              [
240                  new PlaceholderClassificationCase(
241                      Name: "Quoted shell:Downloads",
242                      Input: "\"shell:Downloads\"",
243                      ExpectSuccess: true,
244                      ExpectedKind: CommandKind.Directory,
245                      ExpectedTarget: Path.Combine(path1: Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "Downloads"),
246                      ExpectedLaunch: LaunchMethod.ExplorerOpen,
247                      ExpectedIsPlaceholder: false)
248              ],
249              [
250                  new PlaceholderClassificationCase(
251                      Name: "Quoted shell:Downloads with subpath",
252                      Input: "\"shell:Downloads\\file.txt\"",
253                      ExpectSuccess: true,
254                      ExpectedKind: CommandKind.FileDocument,
255                      ExpectedTarget: Path.Combine(path1: Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "Downloads", "file.txt"),
256                      ExpectedLaunch: LaunchMethod.ShellExecute,
257                      ExpectedIsPlaceholder: false)
258              ],
259              [
260                  new PlaceholderClassificationCase(
261                      Name: "Shell Desktop with subpath",
262                      Input: "shell:Desktop\\file.txt",
263                      ExpectSuccess: true,
264                      ExpectedKind: CommandKind.FileDocument,
265                      ExpectedTarget: Path.Combine(path1: Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "file.txt"),
266                      ExpectedLaunch: LaunchMethod.ShellExecute,
267                      ExpectedIsPlaceholder: false)
268              ],
269              [
270                  new PlaceholderClassificationCase(
271                      Name: "Quoted shell path with trailing text",
272                      Input: "\"shell:Programs\" extra",
273                      ExpectSuccess: true,
274                      ExpectedKind: CommandKind.Directory,
275                      ExpectedTarget: Path.Combine(paths: Environment.GetFolderPath(Environment.SpecialFolder.Programs)),
276                      ExpectedLaunch: LaunchMethod.ExplorerOpen,
277                      ExpectedIsPlaceholder: false)
278              ]
279          ];
280  
281          public static IEnumerable<object[]> CommandFlagsAndOptions() =>
282          [
283              [
284                  new PlaceholderClassificationCase(
285                      Name: "Path followed by flag with quoted value",
286                      Input: "C:\\app.exe -flag \"value\"",
287                      ExpectSuccess: true,
288                      ExpectedKind: CommandKind.FileExecutable,
289                      ExpectedTarget: "C:\\app.exe",
290                      ExpectedArguments: "-flag \"value\"",
291                      ExpectedLaunch: LaunchMethod.ShellExecute,
292                      ExpectedIsPlaceholder: false)
293              ],
294              [
295                  new PlaceholderClassificationCase(
296                      Name: "Quoted tool with equals-style flag",
297                      Input: "\"C:\\Program Files\\tool.exe\" --input=file.txt",
298                      ExpectSuccess: true,
299                      ExpectedKind: CommandKind.FileExecutable,
300                      ExpectedTarget: "C:\\Program Files\\tool.exe",
301                      ExpectedArguments: "--input=file.txt",
302                      ExpectedLaunch: LaunchMethod.ShellExecute,
303                      ExpectedIsPlaceholder: false)
304              ],
305              [
306                  new PlaceholderClassificationCase(
307                      Name: "Path with slash option and quoted value",
308                      Input: "C:\\tool.exe /option \"quoted value\"",
309                      ExpectSuccess: true,
310                      ExpectedKind: CommandKind.FileExecutable,
311                      ExpectedTarget: "C:\\tool.exe",
312                      ExpectedArguments: "/option \"quoted value\"",
313                      ExpectedLaunch: LaunchMethod.ShellExecute,
314                      ExpectedIsPlaceholder: false)
315              ],
316              [
317                  new PlaceholderClassificationCase(
318                      Name: "Flag before quoted path",
319                      Input: "--path \"C:\\Program Files\\app.exe\"",
320                      ExpectSuccess: true,
321                      ExpectedKind: CommandKind.Unknown,
322                      ExpectedTarget: "--path",
323                      ExpectedArguments: "\"C:\\Program Files\\app.exe\"",
324                      ExpectedLaunch: LaunchMethod.ShellExecute,
325                      ExpectedIsPlaceholder: false)
326              ]
327          ];
328  
329          public static IEnumerable<object[]> NetworkPathsUnc() =>
330          [
331              [
332                  new PlaceholderClassificationCase(
333                      Name: "UNC path unquoted",
334                      Input: "\\\\server\\share\\folder\\file.txt",
335                      ExpectSuccess: true,
336                      ExpectedKind: CommandKind.FileDocument,
337                      ExpectedTarget: "\\\\server\\share\\folder\\file.txt",
338                      ExpectedLaunch: LaunchMethod.ShellExecute,
339                      ExpectedIsPlaceholder: false)
340              ],
341              [
342                  new PlaceholderClassificationCase(
343                      Name: "Quoted UNC path with spaces",
344                      Input: "\"\\\\server\\share with spaces\\file.txt\"",
345                      ExpectSuccess: true,
346                      ExpectedKind: CommandKind.FileDocument,
347                      ExpectedTarget: "\\\\server\\share with spaces\\file.txt",
348                      ExpectedLaunch: LaunchMethod.ShellExecute,
349                      ExpectedIsPlaceholder: false)
350              ],
351              [
352                  new PlaceholderClassificationCase(
353                      Name: "UNC path with trailing args",
354                      Input: "\"\\\\server\\share\\\" with args",
355                      ExpectSuccess: true,
356                      ExpectedKind: CommandKind.Unknown,
357                      ExpectedTarget: "\\\\server\\share\\",
358                      ExpectedArguments: "with args",
359                      ExpectedLaunch: LaunchMethod.ShellExecute,
360                      ExpectedIsPlaceholder: false)
361              ],
362              [
363                  new PlaceholderClassificationCase(
364                      Name: "Quoted UNC app with flag",
365                      Input: "\"\\\\server\\My Share\\app.exe\" --flag",
366                      ExpectSuccess: true,
367                      ExpectedKind: CommandKind.FileExecutable,
368                      ExpectedTarget: "\\\\server\\My Share\\app.exe",
369                      ExpectedArguments: "--flag",
370                      ExpectedLaunch: LaunchMethod.ShellExecute,
371                      ExpectedIsPlaceholder: false)
372              ]
373          ];
374  
375          public static IEnumerable<object[]> RelativePathsWithQuotes() =>
376          [
377              [
378                  new PlaceholderClassificationCase(
379                      Name: "Quoted relative current path",
380                      Input: "\".\\file.txt\"",
381                      ExpectSuccess: true,
382                      ExpectedKind: CommandKind.FileDocument,
383                      ExpectedTarget: Path.GetFullPath(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "file.txt")),
384                      ExpectedLaunch: LaunchMethod.ShellExecute,
385                      ExpectedIsPlaceholder: false)
386              ],
387              [
388                  new PlaceholderClassificationCase(
389                      Name: "Quoted relative parent path",
390                      Input: "\"..\\parent folder\\file.txt\"",
391                      ExpectSuccess: true,
392                      ExpectedKind: CommandKind.FileDocument,
393                      ExpectedTarget: Path.GetFullPath(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "..", "parent folder", "file.txt")),
394                      ExpectedLaunch: LaunchMethod.ShellExecute,
395                      ExpectedIsPlaceholder: false)
396              ],
397              [
398                  new PlaceholderClassificationCase(
399                      Name: "Quoted relative home folder",
400                      Input: "\"~\\current folder\\app.exe\"",
401                      ExpectSuccess: true,
402                      ExpectedKind: CommandKind.FileExecutable,
403                      ExpectedTarget: Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "current folder\\app.exe"),
404                      ExpectedLaunch: LaunchMethod.ShellExecute,
405                      ExpectedIsPlaceholder: false)
406              ]
407          ];
408  
409          public static IEnumerable<object[]> EmptyAndWhitespaceCases() =>
410          [
411              [
412                  new PlaceholderClassificationCase(
413                      Name: "Empty string",
414                      Input: string.Empty,
415                      ExpectSuccess: true,
416                      ExpectedKind: CommandKind.Unknown,
417                      ExpectedTarget: string.Empty,
418                      ExpectedLaunch: LaunchMethod.ShellExecute,
419                      ExpectedIsPlaceholder: false)
420              ],
421              [
422                  new PlaceholderClassificationCase(
423                      Name: "Only whitespace",
424                      Input: "   ",
425                      ExpectSuccess: true,
426                      ExpectedKind: CommandKind.Unknown,
427                      ExpectedTarget: "   ",
428                      ExpectedLaunch: LaunchMethod.ShellExecute,
429                      ExpectedIsPlaceholder: false)
430              ],
431              [
432                  new PlaceholderClassificationCase(
433                      Name: "Just empty quotes",
434                      Input: "\"\"",
435                      ExpectSuccess: true,
436                      ExpectedKind: CommandKind.Unknown,
437                      ExpectedTarget: string.Empty,
438                      ExpectedLaunch: LaunchMethod.ShellExecute,
439                      ExpectedIsPlaceholder: false)
440              ],
441              [
442                  new PlaceholderClassificationCase(
443                      Name: "Quoted single space",
444                      Input: "\" \"",
445                      ExpectSuccess: true,
446                      ExpectedKind: CommandKind.Unknown,
447                      ExpectedTarget: " ",
448                      ExpectedLaunch: LaunchMethod.ShellExecute,
449                      ExpectedIsPlaceholder: false)
450              ]
451          ];
452  
453          public static IEnumerable<object[]> RealWorldCommandScenarios() =>
454          [
455  #if CMDPAL_ENABLE_UNSAFE_TESTS
456              [
457                  new PlaceholderClassificationCase(
458                      Name: "Git clone command with full exe path with quoted path",
459                      Input: "\"C:\\Program Files\\Git\\bin\\git.exe\" clone repo",
460                      ExpectSuccess: true,
461                      ExpectedKind: CommandKind.FileExecutable,
462                      ExpectedTarget: "C:\\Program Files\\Git\\bin\\git.exe",
463                      ExpectedArguments: "clone repo",
464                      ExpectedLaunch: LaunchMethod.ShellExecute,
465                      ExpectedIsPlaceholder: false)
466              ],
467              [
468                  new PlaceholderClassificationCase(
469                      Name: "Git clone command with quoted path",
470                      Input: "git clone repo",
471                      ExpectSuccess: true,
472                      ExpectedKind: CommandKind.PathCommand,
473                      ExpectedTarget: "C:\\Program Files\\Git\\cmd\\git.EXE",
474                      ExpectedArguments: "clone repo",
475                      ExpectedLaunch: LaunchMethod.ShellExecute,
476                      ExpectedIsPlaceholder: false)
477              ],
478              [
479                  new PlaceholderClassificationCase(
480                      Name: "Visual Studio devenv with solution",
481                      Input: "\"C:\\Program Files\\Microsoft Visual Studio\\2022\\Preview\\Common7\\IDE\\devenv.exe\" solution.sln",
482                      ExpectSuccess: true,
483                      ExpectedKind: CommandKind.FileExecutable,
484                      ExpectedTarget: "C:\\Program Files\\Microsoft Visual Studio\\2022\\Preview\\Common7\\IDE\\devenv.exe",
485                      ExpectedArguments: "solution.sln",
486                      ExpectedLaunch: LaunchMethod.ShellExecute,
487                      ExpectedIsPlaceholder: false)
488              ],
489              [
490                  new PlaceholderClassificationCase(
491                      Name: "Double-quoted Windows cmd pattern",
492                      Input: "cmd /c \"\"C:\\Program Files\\app.exe\" arg1 arg2\"",
493                      ExpectSuccess: true,
494                      ExpectedKind: CommandKind.PathCommand,
495                      ExpectedTarget: "C:\\Windows\\system32\\cmd.EXE",
496                      ExpectedLaunch: LaunchMethod.ShellExecute,
497                      ExpectedArguments: "/c \"\"C:\\Program Files\\app.exe\" arg1 arg2\"",
498                      ExpectedIsPlaceholder: false)
499              ],
500  #endif
501              [
502                  new PlaceholderClassificationCase(
503                      Name: "PowerShell script with execution policy",
504                      Input: "powershell -ExecutionPolicy Bypass -File \"C:\\Scripts\\My Script.ps1\" -param \"value\"",
505                      ExpectSuccess: true,
506                      ExpectedKind: CommandKind.PathCommand,
507                      ExpectedTarget: "C:\\WINDOWS\\system32\\WindowsPowerShell\\v1.0\\PowerShell.exe",
508                      ExpectedArguments: "-ExecutionPolicy Bypass -File \"C:\\Scripts\\My Script.ps1\" -param \"value\"",
509                      ExpectedLaunch: LaunchMethod.ShellExecute,
510                      ExpectedIsPlaceholder: false)
511              ],
512          ];
513  
514          public static IEnumerable<object[]> SpecialCharactersInPaths() =>
515          [
516              [
517                  new PlaceholderClassificationCase(
518                      Name: "Quoted path with square brackets",
519                      Input: "\"C:\\Path\\file[1].txt\"",
520                      ExpectSuccess: true,
521                      ExpectedKind: CommandKind.FileDocument,
522                      ExpectedTarget: "C:\\Path\\file[1].txt",
523                      ExpectedLaunch: LaunchMethod.ShellExecute,
524                      ExpectedIsPlaceholder: false)
525              ],
526              [
527                  new PlaceholderClassificationCase(
528                      Name: "Quoted path with parentheses",
529                      Input: "\"C:\\Folder (2)\\app.exe\"",
530                      ExpectSuccess: true,
531                      ExpectedKind: CommandKind.FileExecutable,
532                      ExpectedTarget: "C:\\Folder (2)\\app.exe",
533                      ExpectedLaunch: LaunchMethod.ShellExecute,
534                      ExpectedIsPlaceholder: false)
535              ],
536              [
537                  new PlaceholderClassificationCase(
538                      Name: "Quoted path with hyphens and underscores",
539                      Input: "\"C:\\Path\\file_name-123.txt\"",
540                      ExpectSuccess: true,
541                      ExpectedKind: CommandKind.FileDocument,
542                      ExpectedTarget: "C:\\Path\\file_name-123.txt",
543                      ExpectedLaunch: LaunchMethod.ShellExecute,
544                      ExpectedIsPlaceholder: false)
545              ]
546          ];
547  
548          public static IEnumerable<object[]> QuotedPathsCurrentlyBroken() =>
549          [
550              [
551                  new PlaceholderClassificationCase(
552                      Name: "Quoted path with spaces - complete path",
553                      Input: "\"C:\\Program Files\\MyApp\\app.exe\"",
554                      ExpectSuccess: true,
555                      ExpectedKind: CommandKind.FileExecutable,
556                      ExpectedTarget: "C:\\Program Files\\MyApp\\app.exe",
557                      ExpectedArguments: string.Empty,
558                      ExpectedLaunch: LaunchMethod.ShellExecute,
559                      ExpectedIsPlaceholder: false)
560              ],
561              [
562                  new PlaceholderClassificationCase(
563                      Name: "Quoted path with spaces in user folder",
564                      Input: "\"C:\\Users\\John Doe\\Documents\\file.txt\"",
565                      ExpectSuccess: true,
566                      ExpectedKind: CommandKind.FileDocument,
567                      ExpectedTarget: "C:\\Users\\John Doe\\Documents\\file.txt",
568                      ExpectedArguments: string.Empty,
569                      ExpectedLaunch: LaunchMethod.ShellExecute,
570                      ExpectedIsPlaceholder: false)
571              ],
572              [
573                  new PlaceholderClassificationCase(
574                      Name: "Quoted path with trailing arguments",
575                      Input: "\"C:\\Program Files\\app.exe\" --flag",
576                      ExpectSuccess: true,
577                      ExpectedKind: CommandKind.FileExecutable,
578                      ExpectedTarget: "C:\\Program Files\\app.exe",
579                      ExpectedArguments: "--flag",
580                      ExpectedLaunch: LaunchMethod.ShellExecute,
581                      ExpectedIsPlaceholder: false)
582              ],
583              [
584                  new PlaceholderClassificationCase(
585                      Name: "Quoted path with multiple arguments",
586                      Input: "\"C:\\My Documents\\file.txt\" -output result.txt",
587                      ExpectSuccess: true,
588                      ExpectedKind: CommandKind.FileDocument,
589                      ExpectedTarget: "C:\\My Documents\\file.txt",
590                      ExpectedArguments: "-output result.txt",
591                      ExpectedLaunch: LaunchMethod.ShellExecute,
592                      ExpectedIsPlaceholder: false)
593              ],
594              [
595                  new PlaceholderClassificationCase(
596                      Name: "Quoted path with trailing flag and value",
597                      Input: "\"C:\\Tools\\converter.exe\" input.txt output.txt",
598                      ExpectSuccess: true,
599                      ExpectedKind: CommandKind.FileExecutable,
600                      ExpectedTarget: "C:\\Tools\\converter.exe",
601                      ExpectedArguments: "input.txt output.txt",
602                      ExpectedLaunch: LaunchMethod.ShellExecute,
603                      ExpectedIsPlaceholder: false)
604              ]
605          ];
606  
607          public static IEnumerable<object[]> QuotedPathsInCommands() =>
608          [
609              [
610                  new PlaceholderClassificationCase(
611                      Name: "cmd /c with quoted path",
612                      Input: "cmd /c \"C:\\Program Files\\tool.exe\"",
613                      ExpectSuccess: true,
614                      ExpectedKind: CommandKind.PathCommand,
615                      ExpectedTarget: "C:\\Windows\\system32\\cmd.exe",
616                      ExpectedArguments: "/c \"C:\\Program Files\\tool.exe\"",
617                      ExpectedLaunch: LaunchMethod.ShellExecute,
618                      ExpectedIsPlaceholder: false)
619              ],
620              [
621                  new PlaceholderClassificationCase(
622                      Name: "PowerShell with quoted script path",
623                      Input: "powershell -File \"C:\\Scripts\\my script.ps1\"",
624                      ExpectSuccess: true,
625                      ExpectedKind: CommandKind.PathCommand,
626                      ExpectedTarget: Path.Combine(path1: Environment.GetFolderPath(Environment.SpecialFolder.System), "WindowsPowerShell", "v1.0", path4: "powershell.exe"),
627                      ExpectedArguments: "-File \"C:\\Scripts\\my script.ps1\"",
628                      ExpectedLaunch: LaunchMethod.ShellExecute,
629                      ExpectedIsPlaceholder: false)
630              ],
631              [
632                  new PlaceholderClassificationCase(
633                      Name: "runas with quoted executable",
634                      Input: "runas /user:admin \"C:\\Windows\\System32\\cmd.exe\"",
635                      ExpectSuccess: true,
636                      ExpectedKind: CommandKind.PathCommand,
637                      ExpectedTarget: "C:\\Windows\\system32\\runas.exe",
638                      ExpectedArguments: "/user:admin \"C:\\Windows\\System32\\cmd.exe\"",
639                      ExpectedLaunch: LaunchMethod.ShellExecute,
640                      ExpectedIsPlaceholder: false)
641              ]
642          ];
643  
644          public static IEnumerable<object[]> QuotedAumid() =>
645          [
646              [
647                  new PlaceholderClassificationCase(
648                      Name: "Quoted UWP AUMID via AppsFolder",
649                      Input: "\"shell:AppsFolder\\Microsoft.WindowsTerminal_8wekyb3d8bbwe!App\"",
650                      ExpectSuccess: true,
651                      ExpectedKind: CommandKind.Aumid,
652                      ExpectedTarget: "shell:AppsFolder\\Microsoft.WindowsTerminal_8wekyb3d8bbwe!App",
653                      ExpectedLaunch: LaunchMethod.ActivateAppId,
654                      ExpectedIsPlaceholder: false),
655              ],
656              [
657                  new PlaceholderClassificationCase(
658                      Name: "Quoted UWP AUMID with AppsFolder prefix and argument",
659                      Input: "\"shell:AppsFolder\\Microsoft.WindowsTerminal_8wekyb3d8bbwe!App\" --maximized",
660                      ExpectSuccess: true,
661                      ExpectedKind: CommandKind.Aumid,
662                      ExpectedTarget: "shell:AppsFolder\\Microsoft.WindowsTerminal_8wekyb3d8bbwe!App",
663                      ExpectedArguments: "--maximized",
664                      ExpectedLaunch: LaunchMethod.ActivateAppId,
665                      ExpectedIsPlaceholder: false),
666              ],
667          ];
668      }
669  }