Files
fn_registry/cpp/tests/test_sql_parse.cpp

94 lines
3.2 KiB
C++

// Tests for fn_ui::sql_parse / sql_classify (cpp/functions/core/sql_parse).
// Pura: tokeniza SQL multi-statement saltando strings y comentarios, y
// clasifica por keyword inicial.
#define CATCH_CONFIG_MAIN
#include "catch_amalgamated.hpp"
#include "core/sql_parse.h"
using fn_ui::sql_parse;
using fn_ui::sql_classify;
using fn_ui::SqlStmtKind;
TEST_CASE("sql_parse classifies common statements") {
auto stmts = sql_parse("SELECT * FROM t; INSERT INTO t VALUES (1);");
REQUIRE(stmts.size() == 2);
REQUIRE(stmts[0].kind == SqlStmtKind::Select);
REQUIRE(stmts[1].kind == SqlStmtKind::Insert);
}
TEST_CASE("sql_parse handles strings and comments") {
auto stmts = sql_parse("-- comment\nSELECT 'a;b' FROM t; /* x */ DELETE FROM t;");
REQUIRE(stmts.size() == 2);
REQUIRE(stmts[0].kind == SqlStmtKind::Select);
REQUIRE(stmts[1].kind == SqlStmtKind::Delete);
}
TEST_CASE("sql_parse trims and ignores empty") {
auto stmts = sql_parse("; ; SELECT 1;;");
REQUIRE(stmts.size() == 1);
REQUIRE(stmts[0].kind == SqlStmtKind::Select);
}
TEST_CASE("sql_parse: ddl and dcl keywords") {
auto stmts = sql_parse("CREATE TABLE t(a); DROP TABLE t; ALTER TABLE t ADD b; UPDATE t SET a=1;");
REQUIRE(stmts.size() == 4);
REQUIRE(stmts[0].kind == SqlStmtKind::Create);
REQUIRE(stmts[1].kind == SqlStmtKind::Drop);
REQUIRE(stmts[2].kind == SqlStmtKind::Alter);
REQUIRE(stmts[3].kind == SqlStmtKind::Update);
}
TEST_CASE("sql_parse: pragma and explain") {
auto stmts = sql_parse("PRAGMA foreign_keys = ON; EXPLAIN SELECT 1;");
REQUIRE(stmts.size() == 2);
REQUIRE(stmts[0].kind == SqlStmtKind::Pragma);
REQUIRE(stmts[1].kind == SqlStmtKind::Explain);
}
TEST_CASE("sql_parse: WITH clasifica como Select") {
auto stmts = sql_parse("WITH x AS (SELECT 1) SELECT * FROM x;");
REQUIRE(stmts.size() == 1);
REQUIRE(stmts[0].kind == SqlStmtKind::Select);
}
TEST_CASE("sql_parse: case-insensitive y trim") {
auto stmts = sql_parse(" select 1;\n INSERT INTO t VALUES (2);");
REQUIRE(stmts.size() == 2);
REQUIRE(stmts[0].kind == SqlStmtKind::Select);
REQUIRE(stmts[1].kind == SqlStmtKind::Insert);
}
TEST_CASE("sql_parse: line tracking") {
auto stmts = sql_parse("\n\nSELECT 1;\n-- skip\nDELETE FROM t;\n");
REQUIRE(stmts.size() == 2);
REQUIRE(stmts[0].line == 3);
REQUIRE(stmts[1].line == 5);
}
TEST_CASE("sql_parse: ultimo statement sin ;") {
auto stmts = sql_parse("SELECT 1");
REQUIRE(stmts.size() == 1);
REQUIRE(stmts[0].kind == SqlStmtKind::Select);
}
TEST_CASE("sql_classify: standalone") {
REQUIRE(sql_classify("SELECT 1") == SqlStmtKind::Select);
REQUIRE(sql_classify("garbage") == SqlStmtKind::Unknown);
REQUIRE(sql_classify("") == SqlStmtKind::Unknown);
REQUIRE(sql_classify("/* c */ DELETE FROM t") == SqlStmtKind::Delete);
}
TEST_CASE("sql_parse: ; dentro de string no separa") {
auto stmts = sql_parse("SELECT 'a;b;c' FROM t;");
REQUIRE(stmts.size() == 1);
REQUIRE(stmts[0].kind == SqlStmtKind::Select);
}
TEST_CASE("sql_parse: backtick identifier") {
auto stmts = sql_parse("SELECT * FROM `weird;name`;");
REQUIRE(stmts.size() == 1);
REQUIRE(stmts[0].kind == SqlStmtKind::Select);
}