| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349 |
- package engine
- import (
- "context"
- "strings"
- "testing"
- )
- // TestComprehensiveSQLSuite tests all kinds of SQL patterns to ensure robustness
- func TestComprehensiveSQLSuite(t *testing.T) {
- engine := NewTestSQLEngine()
- testCases := []struct {
- name string
- sql string
- shouldPanic bool
- shouldError bool
- desc string
- }{
- // =========== BASIC QUERIES ===========
- {
- name: "Basic_Select_All",
- sql: "SELECT * FROM user_events",
- shouldPanic: false,
- shouldError: false,
- desc: "Basic select all columns",
- },
- {
- name: "Basic_Select_Column",
- sql: "SELECT id FROM user_events",
- shouldPanic: false,
- shouldError: false,
- desc: "Basic select single column",
- },
- {
- name: "Basic_Select_Multiple_Columns",
- sql: "SELECT id, status FROM user_events",
- shouldPanic: false,
- shouldError: false,
- desc: "Basic select multiple columns",
- },
- // =========== ARITHMETIC EXPRESSIONS (FIXED) ===========
- {
- name: "Arithmetic_Multiply_FIXED",
- sql: "SELECT id*2 FROM user_events",
- shouldPanic: false, // Fixed: no longer panics
- shouldError: false,
- desc: "FIXED: Arithmetic multiplication works",
- },
- {
- name: "Arithmetic_Add",
- sql: "SELECT id+10 FROM user_events",
- shouldPanic: false,
- shouldError: false,
- desc: "Arithmetic addition works",
- },
- {
- name: "Arithmetic_Subtract",
- sql: "SELECT id-5 FROM user_events",
- shouldPanic: false,
- shouldError: false,
- desc: "Arithmetic subtraction works",
- },
- {
- name: "Arithmetic_Divide",
- sql: "SELECT id/3 FROM user_events",
- shouldPanic: false,
- shouldError: false,
- desc: "Arithmetic division works",
- },
- {
- name: "Arithmetic_Complex",
- sql: "SELECT id*2+10 FROM user_events",
- shouldPanic: false,
- shouldError: false,
- desc: "Complex arithmetic expression works",
- },
- // =========== STRING OPERATIONS ===========
- {
- name: "String_Concatenation",
- sql: "SELECT 'hello' || 'world' FROM user_events",
- shouldPanic: false,
- shouldError: false,
- desc: "String concatenation",
- },
- {
- name: "String_Column_Concat",
- sql: "SELECT status || '_suffix' FROM user_events",
- shouldPanic: false,
- shouldError: false,
- desc: "Column string concatenation",
- },
- // =========== FUNCTIONS ===========
- {
- name: "Function_LENGTH",
- sql: "SELECT LENGTH('hello') FROM user_events",
- shouldPanic: false,
- shouldError: false,
- desc: "LENGTH function with literal",
- },
- {
- name: "Function_LENGTH_Column",
- sql: "SELECT LENGTH(status) FROM user_events",
- shouldPanic: false,
- shouldError: false,
- desc: "LENGTH function with column",
- },
- {
- name: "Function_UPPER",
- sql: "SELECT UPPER('hello') FROM user_events",
- shouldPanic: false,
- shouldError: false,
- desc: "UPPER function",
- },
- {
- name: "Function_Nested",
- sql: "SELECT LENGTH(UPPER('hello')) FROM user_events",
- shouldPanic: false,
- shouldError: false,
- desc: "Nested functions",
- },
- // =========== FUNCTIONS WITH ARITHMETIC ===========
- {
- name: "Function_Arithmetic",
- sql: "SELECT LENGTH('hello') + 10 FROM user_events",
- shouldPanic: false,
- shouldError: false,
- desc: "Function with arithmetic",
- },
- {
- name: "Function_Arithmetic_Complex",
- sql: "SELECT LENGTH(status) * 2 + 5 FROM user_events",
- shouldPanic: false,
- shouldError: false,
- desc: "Function with complex arithmetic",
- },
- // =========== TABLE REFERENCES ===========
- {
- name: "Table_Simple",
- sql: "SELECT * FROM user_events",
- shouldPanic: false,
- shouldError: false,
- desc: "Simple table reference",
- },
- {
- name: "Table_With_Database",
- sql: "SELECT * FROM ecommerce.user_events",
- shouldPanic: false,
- shouldError: false,
- desc: "Table with database qualifier",
- },
- {
- name: "Table_Quoted",
- sql: `SELECT * FROM "user_events"`,
- shouldPanic: false,
- shouldError: false,
- desc: "Quoted table name",
- },
- // =========== WHERE CLAUSES ===========
- {
- name: "Where_Simple",
- sql: "SELECT * FROM user_events WHERE id = 1",
- shouldPanic: false,
- shouldError: false,
- desc: "Simple WHERE clause",
- },
- {
- name: "Where_String",
- sql: "SELECT * FROM user_events WHERE status = 'active'",
- shouldPanic: false,
- shouldError: false,
- desc: "WHERE clause with string",
- },
- // =========== LIMIT/OFFSET ===========
- {
- name: "Limit_Only",
- sql: "SELECT * FROM user_events LIMIT 10",
- shouldPanic: false,
- shouldError: false,
- desc: "LIMIT clause only",
- },
- {
- name: "Limit_Offset",
- sql: "SELECT * FROM user_events LIMIT 10 OFFSET 5",
- shouldPanic: false,
- shouldError: false,
- desc: "LIMIT with OFFSET",
- },
- // =========== DATETIME FUNCTIONS ===========
- {
- name: "DateTime_CURRENT_DATE",
- sql: "SELECT CURRENT_DATE FROM user_events",
- shouldPanic: false,
- shouldError: false,
- desc: "CURRENT_DATE function",
- },
- {
- name: "DateTime_NOW",
- sql: "SELECT NOW() FROM user_events",
- shouldPanic: false,
- shouldError: false,
- desc: "NOW() function",
- },
- {
- name: "DateTime_EXTRACT",
- sql: "SELECT EXTRACT(YEAR FROM CURRENT_DATE) FROM user_events",
- shouldPanic: false,
- shouldError: false,
- desc: "EXTRACT function",
- },
- // =========== EDGE CASES ===========
- {
- name: "Empty_String",
- sql: "SELECT '' FROM user_events",
- shouldPanic: false,
- shouldError: false,
- desc: "Empty string literal",
- },
- {
- name: "Multiple_Spaces",
- sql: "SELECT id FROM user_events",
- shouldPanic: false,
- shouldError: false,
- desc: "Query with multiple spaces",
- },
- {
- name: "Mixed_Case",
- sql: "Select ID from User_Events",
- shouldPanic: false,
- shouldError: false,
- desc: "Mixed case SQL",
- },
- // =========== SHOW STATEMENTS ===========
- {
- name: "Show_Databases",
- sql: "SHOW DATABASES",
- shouldPanic: false,
- shouldError: false,
- desc: "SHOW DATABASES statement",
- },
- {
- name: "Show_Tables",
- sql: "SHOW TABLES",
- shouldPanic: false,
- shouldError: false,
- desc: "SHOW TABLES statement",
- },
- }
- var panicTests []string
- var errorTests []string
- var successTests []string
- for _, tc := range testCases {
- t.Run(tc.name, func(t *testing.T) {
- // Capture panics
- var panicValue interface{}
- func() {
- defer func() {
- if r := recover(); r != nil {
- panicValue = r
- }
- }()
- result, err := engine.ExecuteSQL(context.Background(), tc.sql)
- if tc.shouldPanic {
- if panicValue == nil {
- t.Errorf("FAIL: Expected panic for %s, but query completed normally", tc.desc)
- panicTests = append(panicTests, "FAIL: "+tc.desc)
- return
- } else {
- t.Logf("PASS: EXPECTED PANIC: %s - %v", tc.desc, panicValue)
- panicTests = append(panicTests, "PASS: "+tc.desc+" (reproduced)")
- return
- }
- }
- if panicValue != nil {
- t.Errorf("FAIL: Unexpected panic for %s: %v", tc.desc, panicValue)
- panicTests = append(panicTests, "FAIL: "+tc.desc+" (unexpected panic)")
- return
- }
- if tc.shouldError {
- if err == nil && (result == nil || result.Error == nil) {
- t.Errorf("FAIL: Expected error for %s, but query succeeded", tc.desc)
- errorTests = append(errorTests, "FAIL: "+tc.desc)
- return
- } else {
- t.Logf("PASS: Expected error: %s", tc.desc)
- errorTests = append(errorTests, "PASS: "+tc.desc)
- return
- }
- }
- if err != nil {
- t.Errorf("FAIL: Unexpected error for %s: %v", tc.desc, err)
- errorTests = append(errorTests, "FAIL: "+tc.desc+" (unexpected error)")
- return
- }
- if result != nil && result.Error != nil {
- t.Errorf("FAIL: Unexpected result error for %s: %v", tc.desc, result.Error)
- errorTests = append(errorTests, "FAIL: "+tc.desc+" (unexpected result error)")
- return
- }
- t.Logf("PASS: Success: %s", tc.desc)
- successTests = append(successTests, "PASS: "+tc.desc)
- }()
- })
- }
- // Summary report
- separator := strings.Repeat("=", 80)
- t.Log("\n" + separator)
- t.Log("COMPREHENSIVE SQL TEST SUITE SUMMARY")
- t.Log(separator)
- t.Logf("Total Tests: %d", len(testCases))
- t.Logf("Successful: %d", len(successTests))
- t.Logf("Panics: %d", len(panicTests))
- t.Logf("Errors: %d", len(errorTests))
- t.Log(separator)
- if len(panicTests) > 0 {
- t.Log("\nPANICS TO FIX:")
- for _, test := range panicTests {
- t.Log(" " + test)
- }
- }
- if len(errorTests) > 0 {
- t.Log("\nERRORS TO INVESTIGATE:")
- for _, test := range errorTests {
- t.Log(" " + test)
- }
- }
- }
|