@cryptotaxi247 / kubo / commits / d3a4558f6

test: TestEditorParsing

(cherry picked from commit e44b53a7c9b73dd2b7df514f9633b1c992504d4c)

Marcin Rataj committed Jul 8, 2025 at 18:28 UTC d3a4558f6921bdfcb4f4be2bcab64961dc09d6d4
2 files changed +119 -1
core/commands/config.go
+6 -1
@@ -506,13 +506,18 @@ func setConfig(r repo.Repo, key string, value interface{}) (*ConfigField, error)
506 return getConfig(r, key)
507 }
508
509 +// parseEditorCommand parses the EDITOR environment variable into command and arguments
510 +func parseEditorCommand(editor string) ([]string, error) {
511 + return shlex.Split(editor, true)
512 +}
513 +
514 func editConfig(filename string) error {
515 editor := os.Getenv("EDITOR")
516 if editor == "" {
517 return errors.New("ENV variable $EDITOR not set")
518 }
519
515 - editorAndArgs, err := shlex.Split(editor, true)
520 + editorAndArgs, err := parseEditorCommand(editor)
521 if err != nil {
522 return fmt.Errorf("cannot parse $EDITOR value: %s", err)
523 }
core/commands/config_test.go
+113
@@ -14,3 +14,116 @@ func TestScrubMapInternalDelete(t *testing.T) {
14 t.Errorf("expecting an empty map, got a non-empty map")
15 }
16 }
17 +
18 +func TestEditorParsing(t *testing.T) {
19 + testCases := []struct {
20 + name string
21 + input string
22 + expected []string
23 + hasError bool
24 + }{
25 + {
26 + name: "simple editor",
27 + input: "vim",
28 + expected: []string{"vim"},
29 + hasError: false,
30 + },
31 + {
32 + name: "editor with single flag",
33 + input: "emacs -nw",
34 + expected: []string{"emacs", "-nw"},
35 + hasError: false,
36 + },
37 + {
38 + name: "VS Code with wait flag (issue #9375)",
39 + input: "code --wait",
40 + expected: []string{"code", "--wait"},
41 + hasError: false,
42 + },
43 + {
44 + name: "VS Code with full path and wait flag (issue #9375)",
45 + input: "/opt/homebrew/bin/code --wait",
46 + expected: []string{"/opt/homebrew/bin/code", "--wait"},
47 + hasError: false,
48 + },
49 + {
50 + name: "editor with quoted path containing spaces",
51 + input: "\"/Applications/Visual Studio Code.app/Contents/Resources/app/bin/code\" --wait",
52 + expected: []string{"/Applications/Visual Studio Code.app/Contents/Resources/app/bin/code", "--wait"},
53 + hasError: false,
54 + },
55 + {
56 + name: "sublime text with wait flag",
57 + input: "subl -w",
58 + expected: []string{"subl", "-w"},
59 + hasError: false,
60 + },
61 + {
62 + name: "nano editor",
63 + input: "nano",
64 + expected: []string{"nano"},
65 + hasError: false,
66 + },
67 + {
68 + name: "gedit editor",
69 + input: "gedit",
70 + expected: []string{"gedit"},
71 + hasError: false,
72 + },
73 + {
74 + name: "editor with multiple flags",
75 + input: "vim -c 'set number' -c 'set hlsearch'",
76 + expected: []string{"vim", "-c", "set number", "-c", "set hlsearch"},
77 + hasError: false,
78 + },
79 + {
80 + name: "trailing backslash (POSIX edge case)",
81 + input: "editor\\",
82 + expected: nil,
83 + hasError: true,
84 + },
85 + {
86 + name: "double quoted editor name with spaces",
87 + input: "\"code with spaces\" --wait",
88 + expected: []string{"code with spaces", "--wait"},
89 + hasError: false,
90 + },
91 + {
92 + name: "single quoted editor with flags",
93 + input: "'my editor' -flag",
94 + expected: []string{"my editor", "-flag"},
95 + hasError: false,
96 + },
97 + }
98 +
99 + for _, tc := range testCases {
100 + t.Run(tc.name, func(t *testing.T) {
101 + result, err := parseEditorCommand(tc.input)
102 +
103 + if tc.hasError {
104 + if err == nil {
105 + t.Errorf("Expected error for input '%s', but got none", tc.input)
106 + }
107 + return
108 + }
109 +
110 + if err != nil {
111 + t.Errorf("Unexpected error for input '%s': %v", tc.input, err)
112 + return
113 + }
114 +
115 + if len(result) != len(tc.expected) {
116 + t.Errorf("Expected %d args, got %d for input '%s'", len(tc.expected), len(result), tc.input)
117 + t.Errorf("Expected: %v", tc.expected)
118 + t.Errorf("Got: %v", result)
119 + return
120 + }
121 +
122 + for i, expected := range tc.expected {
123 + if result[i] != expected {
124 + t.Errorf("Expected arg %d to be '%s', got '%s' for input '%s'", i, expected, result[i], tc.input)
125 + }
126 + }
127 + })
128 + }
129 +}