Files
core/test/rust/compiler/database/relation.rs
T
2026-11-03 03:32:07 +00:00

59 lines
1.8 KiB
Rust

use super::{ERROR, packages};
fn check(
body: &str,
) -> Result<dever::compiler::model::Program, dever::syntax::diagnostic::Diagnostic> {
packages(&[
("dever.database", ERROR),
(
"demo.people.model.user",
"type User { name: Text }\nrelation posts = demo.people.model.post.author_id",
),
(
"demo.people.model.post",
"type Post { author_id: model.user.id\ntitle: Text }",
),
("demo.people.app", body),
("demo.people.api", "cmd read = app.read"),
])
}
#[test]
fn relations_are_static_and_propagate_all_models() {
let program = check(
"read() (total: Int) { page = model.user.list({ with = [posts] })\ntotal = page.total }",
)
.unwrap();
assert_eq!(program.models[0].relations.len(), 1);
let operation = &program.functions[0].clauses[0].body[0];
let dever::compiler::model::Statement::Assign { value, .. } = operation else {
panic!()
};
let dever::compiler::model::Node::Database(query, _) = &value.kind else {
panic!()
};
assert_eq!(query.models().collect::<Vec<_>>(), vec![0, 1]);
for option in [
"with = [posts, posts]",
"with = [posts.author]",
"with = [missing]",
] {
assert!(
check(&format!(
"read() (page: model.user.Page) {{ page = model.user.list({{ {option} }}) }}"
))
.is_err()
);
}
}
#[test]
fn streams_cannot_be_used_inside_transactions_or_load_relations() {
for body in [
"transaction read() (total: Int) { rows = model.user.stream()\nclose(rows)\ntotal = 0 }",
"read() (total: Int) { rows = model.user.stream({ with = [posts] })\nclose(rows)\ntotal = 0 }",
] {
assert!(check(body).is_err(), "{body}");
}
}