Initial Dever 0.0.1
This commit is contained in:
commit
81233d098c
1479 files changed
+163782
No files matched your search
@@ -0,0 +1,122 @@
|
||||
use super::packages;
|
||||
|
||||
#[test]
|
||||
fn storage_declarations_do_not_reserve_existing_function_names() {
|
||||
for name in ["seed", "index", "unique", "migrate"] {
|
||||
let source = format!("public {name}() (answer: Int) {{ answer = 1 }}");
|
||||
packages(&[("main", &source)]).unwrap();
|
||||
let source = format!("public {name}(value: Int) (answer: Int) {{ answer = value }}");
|
||||
packages(&[("main", &source)]).unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
fn model(extra: &str) -> String {
|
||||
format!(
|
||||
"type Account {{ email: Text(64) unique\nname: Text(16)\namount: Decimal(9, 2) default 0\nstatus: Int default 1 }}\n{extra}"
|
||||
)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn schema_checks_seed_unique_keys_and_composite_indexes() {
|
||||
let source = model(
|
||||
"index(status, created_at)\nunique(email, name)\nseed { { email = \"admin@sample.test\", name = \"Admin\" } }",
|
||||
);
|
||||
let program = packages(&[("demo.account.model", &source)]).unwrap();
|
||||
assert_eq!(program.models[0].indexes.len(), 2);
|
||||
assert_eq!(program.models[0].seeds.len(), 1);
|
||||
assert_eq!(program.models[0].seeds[0].key, [2]);
|
||||
for extra in [
|
||||
"index(missing)",
|
||||
"index(name, name)",
|
||||
"index(name)\nindex(name)",
|
||||
"seed { { name = \"Admin\" } }",
|
||||
"seed { { email = \"a\" } }",
|
||||
"seed { { email = \"a\", name = \"a\", amount = 0.001 } }",
|
||||
"seed { { email = \"a\", name = \"a\", id = 1 } }",
|
||||
"seed {}\nseed {}",
|
||||
"migrate same { drop legacy }\nmigrate same { drop old }",
|
||||
"migrate bad { drop name }",
|
||||
"migrate bad { drop created_at }",
|
||||
"migrate empty {}",
|
||||
] {
|
||||
let source = model(extra);
|
||||
let error = packages(&[("demo.account.model", &source)]).unwrap_err();
|
||||
assert_eq!(error.code, "C014", "{extra}: {error:?}");
|
||||
}
|
||||
for source in [
|
||||
"type Account { first: Text from old\nsecond: Text from old }",
|
||||
"type Account { first: Text from second\nsecond: Text }",
|
||||
"type Account { first: Text from created_at }",
|
||||
] {
|
||||
assert_eq!(
|
||||
packages(&[("demo.account.model", source)])
|
||||
.unwrap_err()
|
||||
.code,
|
||||
"C014"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn migration_sql_tracks_boundaries_and_rejects_unsafe_or_lossy_inputs() {
|
||||
let statement = |sqlite: &str, postgres: &str, values: &str| {
|
||||
let extra = format!(
|
||||
"migrate normalize {{ before {{ sqlite = {}\npostgres = {}\nparameters = {values} }} }}",
|
||||
serde_json::to_string(sqlite).unwrap(),
|
||||
serde_json::to_string(postgres).unwrap()
|
||||
);
|
||||
packages(&[("demo.account.model", &model(&extra))])
|
||||
};
|
||||
statement("/* prefix */ UPDATE demo_account_model SET name = ?1 WHERE name = ?2 AND ';?90' = ';?90'; -- end", "/* nested /* ok */ */ UPDATE demo_account_model SET name = $1 WHERE name = $2 AND $text$;$90$text$ = $text$;$90$text$; -- end", "[\"new\",\"old\"]").unwrap();
|
||||
for sql in [
|
||||
"COMMIT",
|
||||
"SELECT ?1, ?2",
|
||||
"DROP TABLE account",
|
||||
"UPDATE account SET name = ?1; DELETE FROM account WHERE name = ?2",
|
||||
"UPDATE account SET name = ?3 WHERE name = ?2",
|
||||
"UPDATE account SET name = $1 WHERE name = $2",
|
||||
"UPDATE _dever_history SET name = ?1 WHERE name = ?2",
|
||||
"UPDATE sqlite_master SET name = ?1 WHERE name = ?2",
|
||||
"DELETE FROM main.'_dever_history' WHERE name IN (?1,?2)",
|
||||
"UPDATE account SET name = '未闭合",
|
||||
"UPDATE [未闭合 SET name = ?1 WHERE name = ?2",
|
||||
] {
|
||||
let error = statement(
|
||||
sql,
|
||||
"UPDATE account SET name = $1 WHERE name = $2",
|
||||
"[\"new\",\"old\"]",
|
||||
)
|
||||
.unwrap_err();
|
||||
assert_eq!(error.code, "C014", "{sql}: {error:?}");
|
||||
}
|
||||
for sql in [
|
||||
"UPDATE account SET name = $tag$未闭合",
|
||||
"UPDATE account SET name = $$未闭合",
|
||||
"UPDATE pg_catalog.pg_class SET name = $1",
|
||||
] {
|
||||
assert_eq!(
|
||||
statement("UPDATE account SET name = ?1", sql, "[\"new\"]")
|
||||
.unwrap_err()
|
||||
.code,
|
||||
"C014"
|
||||
);
|
||||
}
|
||||
for value in ["1.25", "1e999", "9223372036854775808", "name", "1 + 2"] {
|
||||
assert_eq!(
|
||||
statement(
|
||||
"UPDATE account SET name = ?1",
|
||||
"UPDATE account SET name = $1",
|
||||
&format!("[{value}]")
|
||||
)
|
||||
.unwrap_err()
|
||||
.code,
|
||||
"C014"
|
||||
);
|
||||
}
|
||||
statement(
|
||||
"UPDATE account SET name = ?1 WHERE status = ?2",
|
||||
"UPDATE account SET name = $1 WHERE status = $2",
|
||||
"[\"new\",1e0]",
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
Reference in new issue
Block a user