use sqrust_core::FileContext;
use sqrust_core::Rule;
use sqrust_rules::structure::update_with_join::UpdateWithJoin;
fn ctx(src: &str) -> FileContext {
FileContext::from_source(src, "test.sql")
}
fn check(sql: &str) -> Vec<sqrust_core::Diagnostic> {
let c = ctx(sql);
UpdateWithJoin.check(&c)
}
#[test]
fn rule_name_is_correct() {
assert_eq!(UpdateWithJoin.name(), "Structure/UpdateWithJoin");
}
#[test]
fn parse_error_returns_no_violations() {
let diags = check("UPDATE SET BROKEN FROM JOIN WHERE");
assert!(diags.is_empty());
}
#[test]
fn plain_update_with_where_no_violation() {
let diags = check("UPDATE t SET col = 1 WHERE id = 1");
assert!(diags.is_empty());
}
#[test]
fn update_with_correlated_subquery_no_violation() {
let diags = check(
"UPDATE t SET col = (SELECT val FROM s WHERE s.id = t.id) WHERE t.id = 1",
);
assert!(diags.is_empty());
}
#[test]
fn select_statement_no_violation() {
let diags = check("SELECT * FROM t JOIN s ON t.id = s.id");
assert!(diags.is_empty());
}
#[test]
fn update_from_no_join_one_violation() {
let diags = check("UPDATE t SET col = s.val FROM s WHERE t.id = s.id");
assert_eq!(diags.len(), 1);
}
#[test]
fn update_from_with_join_one_violation() {
let diags = check(
"UPDATE t SET t.col = u.val FROM s JOIN u ON s.id = u.id WHERE t.id = s.id",
);
assert_eq!(diags.len(), 1);
}
#[test]
fn update_table_with_join_one_violation() {
let sql = "UPDATE t JOIN s ON t.id = s.id SET t.col = s.val WHERE t.id = 1";
let diags = check(sql);
let _ = diags; }
#[test]
fn message_contains_expected_text() {
let diags = check("UPDATE t SET col = s.val FROM s WHERE t.id = s.id");
assert_eq!(diags.len(), 1);
assert!(
diags[0].message.contains("UPDATE"),
"message should mention UPDATE"
);
assert!(
diags[0]
.message
.to_lowercase()
.contains("portab"),
"message should mention portability"
);
}
#[test]
fn diagnostic_rule_name_matches() {
let diags = check("UPDATE t SET col = s.val FROM s WHERE t.id = s.id");
assert_eq!(diags.len(), 1);
assert_eq!(diags[0].rule, "Structure/UpdateWithJoin");
}
#[test]
fn update_without_where_and_no_from_no_violation_for_this_rule() {
let diags = check("UPDATE t SET col = 1");
assert!(diags.is_empty());
}
#[test]
fn multiple_stmts_one_with_from_one_without() {
let sql = "UPDATE t SET col = 1 WHERE id = 1; UPDATE t SET col = s.val FROM s WHERE t.id = s.id";
let diags = check(sql);
assert_eq!(diags.len(), 1);
}
#[test]
fn update_from_multiple_joins_one_violation() {
let sql = "UPDATE t SET t.col = u.val FROM s JOIN u ON s.id = u.id JOIN v ON u.vid = v.id WHERE t.id = s.id";
let diags = check(sql);
assert_eq!(diags.len(), 1);
}
#[test]
fn line_col_is_nonzero() {
let diags = check("UPDATE t SET col = s.val FROM s WHERE t.id = s.id");
assert_eq!(diags.len(), 1);
assert!(diags[0].line >= 1);
assert!(diags[0].col >= 1);
}