use serde_json::{json, Value};
use rust_store_core::dialect::{compile_raw_stmt, Backend};
const FIXTURE: &str = include_str!("../../fixtures/host/raw_stmts.json");
#[test]
fn fixture_table_driven() {
let doc: Value = serde_json::from_str(FIXTURE).expect("fixture 应为合法 JSON");
let cases = doc["cases"].as_array().expect("cases 应为数组");
assert!(
cases.len() >= 14,
"覆盖矩阵 ≥14 例,实际 {} 例",
cases.len()
);
for case in cases {
let name = case["name"].as_str().expect("case 缺 name");
let backend = Backend::parse(case["backend"].as_str().expect("case 缺 backend"))
.unwrap_or_else(|e| panic!("[{}] backend 解析失败: {}", name, e));
let is_write = case["isWrite"].as_bool();
let result = compile_raw_stmt(
backend,
case["sql"].as_str().expect("case 缺 sql"),
case["params"].clone(),
is_write,
);
match case["error"].as_str() {
Some(expected_err) => {
let err = result.expect_err(&format!("[{}] 应报错", name));
assert!(
err.contains(expected_err),
"[{}] 错误文案不含 {:?}:{}",
name,
expected_err,
err
);
}
None => {
let stmt = result.unwrap_or_else(|e| panic!("[{}] 应编译成功: {}", name, e));
let expected = &case["expected"];
assert_eq!(
stmt.sql,
expected["sql"].as_str().expect("expected 缺 sql"),
"[{}] sql 不符",
name
);
assert_eq!(
Value::from(stmt.params),
expected["params"],
"[{}] params 不符",
name
);
assert_eq!(
stmt.is_write,
expected["isWrite"].as_bool().expect("expected 缺 isWrite"),
"[{}] isWrite 不符",
name
);
}
}
}
}
#[test]
fn doubled_single_quote_keeps_colon_literal() {
let stmt = compile_raw_stmt(
Backend::Mysql,
"SELECT * FROM t WHERE note = 'it''s :notparam' AND id = :id",
json!({ "id": 7 }),
None,
)
.expect("应编译成功");
assert_eq!(
stmt.sql,
"SELECT * FROM t WHERE note = 'it''s :notparam' AND id = ?"
);
assert_eq!(stmt.params, vec![json!(7)]);
}
#[test]
fn invalid_backend_rejected_by_parse() {
assert!(Backend::parse("oracle").is_err());
}