返回 DeepSeek-Reasonix
external_opener_windows_test.go
根目录 / desktop / external_opener_windows_test.go
1 //go:build windows
2
3 package main
4
5 import (
6 "os"
7 "path/filepath"
8 "strings"
9 "testing"
10 )
11
12 func TestWindowsExternalOpenerIconUsesShellIcon(t *testing.T) {
13 explorer := filepath.Join(os.Getenv("WINDIR"), "explorer.exe")
14 if info, err := os.Stat(explorer); err != nil || info.IsDir() {
15 t.Skip("Windows Explorer executable is unavailable")
16 }
17 got := platformExternalOpenerIconDataURL(externalOpenerSpec{IconSource: explorer})
18 if !strings.HasPrefix(got, "data:image/png;base64,") {
19 t.Fatalf("native Explorer icon = %q, want PNG data URL", got)
20 }
21 }
22
23 func TestWindowsAppPathExecutableEmptyName(t *testing.T) {
24 if got := windowsAppPathExecutable(""); got != "" {
25 t.Fatalf("empty name = %q, want empty", got)
26 }
27 if got := windowsAppPathExecutable(" "); got != "" {
28 t.Fatalf("blank name = %q, want empty", got)
29 }
30 }
31
32 func TestWindowsTerminalIconSourceSkipsZeroByteAliasForPowershell(t *testing.T) {
33 // When only a zero-byte execution alias is visible (package dir unreadable),
34 // IconSource must not stick on the alias — PowerShell is a known renderable
35 // PE that SHGetFileInfo can extract.
36 dir := t.TempDir()
37 alias := filepath.Join(dir, "wt.exe")
38 if err := os.WriteFile(alias, nil, 0o644); err != nil {
39 t.Fatalf("write zero-byte alias: %v", err)
40 }
41 // Point candidate resolution at our temp alias only by calling pick through
42 // the real resolver with overridden env via windowsTerminalIconSource on a
43 // path that will not find package globs, then assert via pick contract.
44 // Direct integration: windowsTerminalIconSource(alias) should return a
45 // non-zero file when powershell is on PATH / System32.
46 got := windowsTerminalIconSource(alias)
47 if got == "" {
48 t.Fatal("icon source empty")
49 }
50 if got == alias {
51 info, err := os.Stat(got)
52 if err != nil {
53 t.Fatalf("stat result: %v", err)
54 }
55 if info.Size() == 0 {
56 t.Fatalf("icon source stayed on zero-byte alias %q; want renderable fallback", got)
57 }
58 }
59 if info, err := os.Stat(got); err != nil || info.IsDir() || info.Size() == 0 {
60 t.Fatalf("icon source %q is not a non-zero file (err=%v)", got, err)
61 }
62 }
63
64 func TestWindowsConsoleLaunchDoesNotInvokeCmdStart(t *testing.T) {
65 // Integration-free: planWindowsConsoleLaunch + ShellExecute path must never
66 // build cmd /c start. The pure helpers test covers special-character dirs;
67 // here we only assert the platform launcher uses that plan shape.
68 ps := firstWindowsExecutable([]string{"powershell.exe"},
69 joinWindowsInstallPath(os.Getenv("WINDIR"), "System32", "WindowsPowerShell", "v1.0", "powershell.exe"))
70 if ps == "" {
71 t.Skip("powershell.exe unavailable")
72 }
73 workdir := filepath.Join(t.TempDir(), "repo&calc")
74 if err := os.MkdirAll(workdir, 0o755); err != nil {
75 t.Fatalf("mkdir workdir: %v", err)
76 }
77 plan := planWindowsConsoleLaunch(ps, workdir)
78 if !windowsConsoleLaunchIsDirect(plan) {
79 t.Fatalf("console plan must be a direct ShellExecute open: %+v", plan)
80 }
81 if plan.File != ps {
82 t.Fatalf("File = %q, want powershell target %q", plan.File, ps)
83 }
84 if plan.Dir != workdir {
85 t.Fatalf("Dir = %q, want %q", plan.Dir, workdir)
86 }
87 // Do not call launchPlatformExternalOpener here: it would open a real
88 // interactive console window in CI. ShellExecute wiring is covered by
89 // openWorkspacePath and compile-time type checks.
90 }
91
91 lines GO