TestNegativeParser_UsingTokenizeHelper uses the tokenizer helper from context_test.go to test SQL strings that should fail to parse.
(t *testing.T)
| 407 | // TestNegativeParser_UsingTokenizeHelper uses the tokenizer helper from context_test.go |
| 408 | // to test SQL strings that should fail to parse. |
| 409 | func TestNegativeParser_SQLStrings(t *testing.T) { |
| 410 | tests := []struct { |
| 411 | name string |
| 412 | sql string |
| 413 | }{ |
| 414 | {"empty string", ""}, |
| 415 | {"just whitespace", " "}, |
| 416 | {"just semicolon", ";"}, |
| 417 | {"SELECT no columns", "SELECT FROM users"}, |
| 418 | {"unclosed string literal", "SELECT 'hello FROM users"}, |
| 419 | {"double FROM", "SELECT * FROM t1 FROM t2"}, |
| 420 | {"ORDER without BY", "SELECT * FROM t ORDER"}, |
| 421 | {"GROUP without BY", "SELECT * FROM t GROUP"}, |
| 422 | {"random keywords", "WHERE FROM SELECT JOIN ON"}, |
| 423 | } |
| 424 | |
| 425 | for _, tt := range tests { |
| 426 | t.Run(tt.name, func(t *testing.T) { |
| 427 | defer func() { |
| 428 | if r := recover(); r != nil { |
| 429 | t.Fatalf("parser panicked on %q: %v", tt.sql, r) |
| 430 | } |
| 431 | }() |
| 432 | |
| 433 | p := GetParser() |
| 434 | defer PutParser(p) |
| 435 | |
| 436 | // Tokenize - may fail, that's fine |
| 437 | tokens := tokenizeForTest(t, tt.sql) |
| 438 | if tokens == nil { |
| 439 | return // tokenization failed, that's a valid outcome |
| 440 | } |
| 441 | |
| 442 | _, _ = p.Parse(tokens) |
| 443 | // No panic is the success criterion |
| 444 | }) |
| 445 | } |
| 446 | } |
| 447 | |
| 448 | // tokenizeForTest tokenizes a SQL string into parser tokens. |
| 449 | // Returns nil if tokenization or conversion fails (valid outcome for negative tests). |