| 1 | package main |
| 2 | |
| 3 | import ( |
| 4 | "path/filepath" |
| 5 | "strings" |
| 6 | "testing" |
| 7 | ) |
| 8 | |
| 9 | func TestWindowsTerminalIconCandidatePathsPreferPackageBinary(t *testing.T) { |
| 10 | // Use fixed Windows-style roots so the assertion is OS-independent; helpers |
| 11 | // only join path segments and never touch the filesystem. |
| 12 | wtAlias := `C:\Users\x\AppData\Local\Microsoft\WindowsApps\wt.exe` |
| 13 | local := `C:\Users\x\AppData\Local` |
| 14 | programFiles := `C:\Program Files` |
| 15 | |
| 16 | got := windowsTerminalIconCandidatePaths(wtAlias, local, programFiles) |
| 17 | if len(got) < 2 { |
| 18 | t.Fatalf("candidates = %v, want package paths before alias", got) |
| 19 | } |
| 20 | wantFirst := filepath.Join(programFiles, "WindowsApps", "Microsoft.WindowsTerminal_*", "WindowsTerminal.exe") |
| 21 | if got[0] != wantFirst { |
| 22 | t.Fatalf("first candidate = %q, want %q", got[0], wantFirst) |
| 23 | } |
| 24 | // Primary hit must be the Store package under Program Files\WindowsApps, not |
| 25 | // a nested path under the App Execution Alias directory. |
| 26 | if !strings.Contains(got[0], "WindowsApps"+string(filepath.Separator)+"Microsoft.WindowsTerminal_") { |
| 27 | t.Fatalf("first candidate = %q, want Microsoft.WindowsTerminal_* under WindowsApps", got[0]) |
| 28 | } |
| 29 | last := got[len(got)-1] |
| 30 | if last != wtAlias { |
| 31 | t.Fatalf("last candidate = %q, want wt alias %q", last, wtAlias) |
| 32 | } |
| 33 | } |
| 34 | |
| 35 | func TestWindowsConsoleLaunchPlanBypassesCmdAndPreservesMetacharacters(t *testing.T) { |
| 36 | cases := []struct { |
| 37 | name string |
| 38 | target string |
| 39 | workdir string |
| 40 | }{ |
| 41 | {name: "spaces", target: `C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe`, workdir: `C:\Users\demo\My Project`}, |
| 42 | {name: "ampersand", target: `C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe`, workdir: `C:\src\repo&calc`}, |
| 43 | {name: "pipe_parens", target: `C:\Windows\System32\cmd.exe`, workdir: `C:\src\a|b(c)^%d`}, |
| 44 | {name: "command_prompt_is_direct_target", target: `C:\Windows\System32\cmd.exe`, workdir: `D:\work`}, |
| 45 | } |
| 46 | for _, tc := range cases { |
| 47 | t.Run(tc.name, func(t *testing.T) { |
| 48 | plan := planWindowsConsoleLaunch(tc.target, tc.workdir) |
| 49 | if !windowsConsoleLaunchIsDirect(plan) { |
| 50 | t.Fatalf("plan is not a direct ShellExecute open: %+v", plan) |
| 51 | } |
| 52 | if plan.File != tc.target { |
| 53 | t.Fatalf("File = %q, want %q (target binary, not cmd /c start wrapper)", plan.File, tc.target) |
| 54 | } |
| 55 | if plan.Dir != tc.workdir { |
| 56 | t.Fatalf("Dir = %q, want exact workdir (no shell rewriting)", plan.Dir) |
| 57 | } |
| 58 | }) |
| 59 | } |
| 60 | } |
| 61 | |
| 62 | func TestWindowsConsoleLaunchIsDirectRejectsEmptyFile(t *testing.T) { |
| 63 | if windowsConsoleLaunchIsDirect(windowsConsoleLaunch{}) { |
| 64 | t.Fatal("empty plan must not count as direct") |
| 65 | } |
| 66 | } |
| 67 | |
| 68 | func TestPickWindowsTerminalIconSourcePrefersRenderableOverZeroByteAlias(t *testing.T) { |
| 69 | wtAlias := `C:\Users\x\AppData\Local\Microsoft\WindowsApps\wt.exe` |
| 70 | packageBin := `C:\Program Files\WindowsApps\Microsoft.WindowsTerminal_1.0_x64__8wekyb3d8bbwe\WindowsTerminal.exe` |
| 71 | powershell := `C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe` |
| 72 | |
| 73 | t.Run("nonzero_package_wins", func(t *testing.T) { |
| 74 | got := pickWindowsTerminalIconSource([]windowsIconCandidate{ |
| 75 | {Path: wtAlias, Size: 0}, |
| 76 | {Path: packageBin, Size: 1_024_000}, |
| 77 | }, powershell) |
| 78 | if got != packageBin { |
| 79 | t.Fatalf("got %q, want package binary", got) |
| 80 | } |
| 81 | }) |
| 82 | t.Run("renderable_beats_zero_alias", func(t *testing.T) { |
| 83 | // Protected WindowsApps often cannot be globbed; only the zero-byte |
| 84 | // execution alias remains. PowerShell must win so SHGetFileInfo has a |
| 85 | // real PE to extract (blank glyph fix for #6547). |
| 86 | got := pickWindowsTerminalIconSource([]windowsIconCandidate{ |
| 87 | {Path: wtAlias, Size: 0}, |
| 88 | }, powershell) |
| 89 | if got != powershell { |
| 90 | t.Fatalf("got %q, want powershell renderable fallback", got) |
| 91 | } |
| 92 | }) |
| 93 | t.Run("zero_alias_only_without_fallback", func(t *testing.T) { |
| 94 | got := pickWindowsTerminalIconSource([]windowsIconCandidate{ |
| 95 | {Path: wtAlias, Size: 0}, |
| 96 | }, "") |
| 97 | if got != wtAlias { |
| 98 | t.Fatalf("got %q, want alias when no renderable fallback exists", got) |
| 99 | } |
| 100 | }) |
| 101 | t.Run("empty", func(t *testing.T) { |
| 102 | if got := pickWindowsTerminalIconSource(nil, ""); got != "" { |
| 103 | t.Fatalf("got %q, want empty", got) |
| 104 | } |
| 105 | }) |
| 106 | } |
| 107 |