use super::{ERROR, packages}; fn check( body: &str, ) -> Result { 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![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}"); } }