use crate::error::Result;
use crate::language::compiler::{compile, compile_with_provenance};
use crate::language::parser::parse_str;
use crate::language::types::{Blueprint, NodeSpec, Origin, Routing};
pub fn try_compile(source: &str) -> Result<Vec<Blueprint>> {
let program = parse_str(source)?;
compile(&program)
}
pub fn compile_all(source: &str) -> Vec<Blueprint> {
try_compile(source).expect("source should parse and compile")
}
pub fn blueprint(source: &str) -> Blueprint {
let mut blueprints = compile_all(source);
assert_eq!(
blueprints.len(),
1,
"expected exactly one graph, found {}",
blueprints.len()
);
blueprints.remove(0)
}
pub fn blueprint_with_provenance(source: &str, origin: Origin) -> Blueprint {
let program = parse_str(source).expect("source should parse");
let mut blueprints = compile_with_provenance(&program, origin).expect("source should compile");
assert_eq!(
blueprints.len(),
1,
"expected exactly one graph, found {}",
blueprints.len()
);
blueprints.remove(0)
}
pub fn node<'a>(blueprint: &'a Blueprint, name: &str) -> &'a NodeSpec {
blueprint
.nodes
.iter()
.find(|n| n.name == name)
.unwrap_or_else(|| {
let names: Vec<&str> = blueprint.nodes.iter().map(|n| n.name.as_str()).collect();
panic!("no node `{name}`; nodes are {names:?}")
})
}
pub fn assert_kind(blueprint: &Blueprint, name: &str, kind: &str) {
let actual = &node(blueprint, name).kind;
assert_eq!(actual, kind, "node `{name}` kind");
}
pub fn assert_next(blueprint: &Blueprint, name: &str, target: &str) {
match &node(blueprint, name).routing {
Routing::Next(actual) => assert_eq!(actual, target, "node `{name}` next"),
other => panic!("node `{name}` routing is {other:?}, expected next -> {target}"),
}
}
pub fn assert_terminal(blueprint: &Blueprint, name: &str) {
match &node(blueprint, name).routing {
Routing::Terminal => {}
other => panic!("node `{name}` routing is {other:?}, expected terminal"),
}
}
pub fn assert_route(blueprint: &Blueprint, name: &str, label: &str, target: &str) {
match &node(blueprint, name).routing {
Routing::Conditional(routes) => {
let found = routes.iter().any(|(l, t)| l == label && t == target);
assert!(
found,
"node `{name}` has no route `{label} -> {target}`; routes are {routes:?}"
);
}
other => panic!("node `{name}` routing is {other:?}, expected conditional routes"),
}
}