github.com/mithrandie/csvq@v1.18.1/lib/terminal/terminal_test.go (about) 1 package terminal 2 3 import ( 4 "context" 5 "reflect" 6 "testing" 7 8 "github.com/mithrandie/csvq/lib/excmd" 9 "github.com/mithrandie/csvq/lib/parser" 10 "github.com/mithrandie/csvq/lib/query" 11 "github.com/mithrandie/csvq/lib/value" 12 ) 13 14 var promptLoadConfigTests = []struct { 15 Prompt string 16 ContinuousPrompt string 17 ExpectSequence []PromptElement 18 ExpectContinuousSequence []PromptElement 19 Error string 20 }{ 21 { 22 Prompt: "TEST P > ", 23 ContinuousPrompt: "TEST C > ", 24 ExpectSequence: []PromptElement{{Text: "TEST P > ", Type: excmd.FixedString}}, 25 ExpectContinuousSequence: []PromptElement{{Text: "TEST C > ", Type: excmd.FixedString}}, 26 }, 27 { 28 Prompt: "TEST P @ > ", 29 ContinuousPrompt: "TEST C > ", 30 ExpectSequence: nil, 31 ExpectContinuousSequence: nil, 32 Error: "prompt: invalid variable symbol", 33 }, 34 { 35 Prompt: "TEST P > ", 36 ContinuousPrompt: "TEST C @ > ", 37 ExpectSequence: nil, 38 ExpectContinuousSequence: nil, 39 Error: "prompt: invalid variable symbol", 40 }, 41 } 42 43 func TestPrompt_LoadConfig(t *testing.T) { 44 prompt := NewPrompt(query.NewReferenceScope(TestTx)) 45 46 for _, v := range promptLoadConfigTests { 47 TestTx.Environment.InteractiveShell.Prompt = v.Prompt 48 TestTx.Environment.InteractiveShell.ContinuousPrompt = v.ContinuousPrompt 49 50 err := prompt.LoadConfig() 51 if err != nil { 52 if len(v.Error) < 1 { 53 t.Errorf("unexpected error %q for %s, %s", err, v.Prompt, v.ContinuousPrompt) 54 } else if err.Error() != v.Error { 55 t.Errorf("error %q, want error %q for %s, %s", err.Error(), v.Error, v.Prompt, v.ContinuousPrompt) 56 } 57 } else if 0 < len(v.Error) { 58 t.Errorf("no error, want error %q for %s, %s", v.Error, v.Prompt, v.ContinuousPrompt) 59 } 60 61 if !reflect.DeepEqual(prompt.sequence, v.ExpectSequence) { 62 t.Errorf("sequence = %v, want %v for %s, %s", prompt.sequence, v.ExpectSequence, v.Prompt, v.ContinuousPrompt) 63 } 64 if !reflect.DeepEqual(prompt.continuousSequence, v.ExpectContinuousSequence) { 65 t.Errorf("continuous sequence = %v, want %v for %s, %s", prompt.continuousSequence, v.ExpectContinuousSequence, v.Prompt, v.ContinuousPrompt) 66 } 67 } 68 } 69 70 var promptRenderPromptTests = []struct { 71 Sequence []PromptElement 72 UseColor bool 73 Expect string 74 Error string 75 }{ 76 { 77 Sequence: nil, 78 UseColor: false, 79 Expect: DefaultPrompt, 80 }, 81 { 82 Sequence: []PromptElement{ 83 {Text: "\033[32mstr\033[0m", Type: excmd.FixedString}, 84 }, 85 UseColor: true, 86 Expect: "\033[32mstr\033[0m", 87 }, 88 { 89 Sequence: []PromptElement{ 90 {Text: "str", Type: excmd.FixedString}, 91 }, 92 UseColor: true, 93 Expect: "\033[34mstr\033[0m", 94 }, 95 { 96 Sequence: []PromptElement{ 97 {Text: "\033[32mstr\033[0m", Type: excmd.FixedString}, 98 }, 99 UseColor: false, 100 Expect: "str", 101 }, 102 } 103 104 func TestPrompt_RenderPrompt(t *testing.T) { 105 defer func() { 106 TestTx.UseColor(false) 107 initFlag(TestTx.Flags) 108 }() 109 110 prompt := NewPrompt(query.NewReferenceScope(TestTx)) 111 112 for _, v := range promptRenderPromptTests { 113 TestTx.UseColor(v.UseColor) 114 prompt.sequence = v.Sequence 115 result, err := prompt.RenderPrompt(context.Background()) 116 117 if err != nil { 118 if len(v.Error) < 1 { 119 t.Errorf("unexpected error %q for %v", err, v.Sequence) 120 } else if err.Error() != v.Error { 121 t.Errorf("error %q, want error %q for %v", err.Error(), v.Error, v.Sequence) 122 } 123 continue 124 } 125 if 0 < len(v.Error) { 126 t.Errorf("no error, want error %q for %v", v.Error, v.Sequence) 127 continue 128 } 129 130 if result != v.Expect { 131 t.Errorf("result = %q, want %q for %v", result, v.Expect, v.Sequence) 132 } 133 } 134 } 135 136 var promptRenderContinuousPromptTests = []struct { 137 Sequence []PromptElement 138 UseColor bool 139 Expect string 140 Error string 141 }{ 142 { 143 Sequence: nil, 144 UseColor: false, 145 Expect: DefaultContinuousPrompt, 146 }, 147 { 148 Sequence: []PromptElement{ 149 {Text: "\033[32mstr\033[0m", Type: excmd.FixedString}, 150 }, 151 UseColor: true, 152 Expect: "\033[32mstr\033[0m", 153 }, 154 { 155 Sequence: []PromptElement{ 156 {Text: "str", Type: excmd.FixedString}, 157 }, 158 UseColor: true, 159 Expect: "\033[34mstr\033[0m", 160 }, 161 { 162 Sequence: []PromptElement{ 163 {Text: "\033[32mstr\033[0m", Type: excmd.FixedString}, 164 }, 165 UseColor: false, 166 Expect: "str", 167 }, 168 } 169 170 func TestPrompt_RenderContinuousPrompt(t *testing.T) { 171 defer func() { 172 TestTx.UseColor(false) 173 initFlag(TestTx.Flags) 174 }() 175 176 prompt := NewPrompt(query.NewReferenceScope(TestTx)) 177 178 for _, v := range promptRenderContinuousPromptTests { 179 TestTx.UseColor(v.UseColor) 180 prompt.continuousSequence = v.Sequence 181 result, err := prompt.RenderContinuousPrompt(context.Background()) 182 183 if err != nil { 184 if len(v.Error) < 1 { 185 t.Errorf("unexpected error %q for %v", err, v.Sequence) 186 } else if err.Error() != v.Error { 187 t.Errorf("error %q, want error %q for %v", err.Error(), v.Error, v.Sequence) 188 } 189 continue 190 } 191 if 0 < len(v.Error) { 192 t.Errorf("no error, want error %q for %v", v.Error, v.Sequence) 193 continue 194 } 195 196 if result != v.Expect { 197 t.Errorf("result = %q, want %q for %v", result, v.Expect, v.Sequence) 198 } 199 } 200 } 201 202 var promptRenderTests = []struct { 203 Input []PromptElement 204 Expect string 205 Error string 206 }{ 207 { 208 Input: nil, 209 Expect: "", 210 }, 211 { 212 Input: []PromptElement{ 213 {Text: "str", Type: excmd.FixedString}, 214 {Text: "var", Type: excmd.Variable}, 215 {Text: "CSVQ_TEST_ENV", Type: excmd.EnvironmentVariable}, 216 {Text: "VERSION", Type: excmd.RuntimeInformation}, 217 {Text: "@var", Type: excmd.CsvqExpression}, 218 }, 219 Expect: "strabcfoov1.0.0abc", 220 }, 221 { 222 Input: []PromptElement{ 223 {Text: "notexist", Type: excmd.Variable}, 224 }, 225 Error: "prompt: variable @notexist is undeclared", 226 }, 227 { 228 Input: []PromptElement{ 229 {Text: "NOTEXIST", Type: excmd.RuntimeInformation}, 230 }, 231 Error: "prompt: @#NOTEXIST is an unknown runtime information", 232 }, 233 { 234 Input: []PromptElement{ 235 {Text: "invalid invalid", Type: excmd.CsvqExpression}, 236 }, 237 Error: "prompt: syntax error: unexpected token \"invalid\"", 238 }, 239 { 240 Input: []PromptElement{ 241 {Text: "", Type: excmd.CsvqExpression}, 242 }, 243 Expect: "", 244 }, 245 { 246 Input: []PromptElement{ 247 {Text: "print 1;", Type: excmd.CsvqExpression}, 248 }, 249 Error: "prompt: print 1;: cannot evaluate as a value", 250 }, 251 { 252 Input: []PromptElement{ 253 {Text: "1;2", Type: excmd.CsvqExpression}, 254 }, 255 Error: "prompt: 1;2: cannot evaluate as a value", 256 }, 257 { 258 Input: []PromptElement{ 259 {Text: "@notexist", Type: excmd.CsvqExpression}, 260 }, 261 Error: "prompt: variable @notexist is undeclared", 262 }, 263 } 264 265 func TestPrompt_Render(t *testing.T) { 266 scope := query.NewReferenceScope(TestTx) 267 _ = scope.DeclareVariableDirectly(parser.Variable{Name: "var"}, value.NewString("abc")) 268 prompt := NewPrompt(scope) 269 270 for _, v := range promptRenderTests { 271 result, err := prompt.Render(context.Background(), v.Input) 272 273 if err != nil { 274 if len(v.Error) < 1 { 275 t.Errorf("unexpected error %q for %v", err, v.Input) 276 } else if err.Error() != v.Error { 277 t.Errorf("error %q, want error %q for %v", err.Error(), v.Error, v.Input) 278 } 279 continue 280 } 281 if 0 < len(v.Error) { 282 t.Errorf("no error, want error %q for %v", v.Error, v.Input) 283 continue 284 } 285 286 if result != v.Expect { 287 t.Errorf("result = %q, want %q for %v", result, v.Expect, v.Input) 288 } 289 } 290 } 291 292 var promptStripEscapeSequenceTests = []struct { 293 Input string 294 Expect string 295 }{ 296 { 297 Input: "\u001b[34;1m/path/to/working/directory \u001b[33;1m(Uncommitted:2)\u001b[34;1m >\u001b[0m ", 298 Expect: "/path/to/working/directory (Uncommitted:2) > ", 299 }, 300 } 301 302 func TestPrompt_StripEscapeSequence(t *testing.T) { 303 prompt := NewPrompt(query.NewReferenceScope(TestTx)) 304 305 for _, v := range promptStripEscapeSequenceTests { 306 result := prompt.StripEscapeSequence(v.Input) 307 308 if result != v.Expect { 309 t.Errorf("result = %q, want %q for %v", result, v.Expect, v.Input) 310 } 311 } 312 }