use crate::transpiler::errors::check::Check;
use serde_json::Value;
pub struct InvalidApplicationRef {}
impl Check for InvalidApplicationRef {
fn inspect(&self, ast: &Value) -> Vec<String> {
let mut errors = Vec::new();
let commands = ast
.get("program")
.and_then(|p| p.get("commands"))
.and_then(|c| c.as_array())
.expect("failed to get commands");
let refs: Vec<&Value> =
commands.iter().filter_map(|c| c.get("ref")).collect();
let applications: Vec<&Value> = commands
.iter()
.filter_map(|c| c.get("application"))
.collect();
applications.iter().for_each(|a| {
if !refs.contains(a) {
errors.push(format!(
"Invalid application -> {}; Ref `{}` does not exist",
a, a
));
}
});
errors
}
}
#[cfg(test)]
mod tests {
use crate::sample_program::sample_program;
use crate::transpiler::errors::check::Check;
use crate::transpiler::errors::invalid_application_ref::InvalidApplicationRef;
use crate::transpiler::fsl_transpiler::Fslt;
use anyhow::Result;
use hamcrest::{equal_to, is, HamcrestMatcher};
#[test]
fn adds_errors_for_invalid_application_ref() -> Result<()> {
let transpiler =
Fslt::program(sample_program("errors/invalid-application-ref.fsl"));
let errors = InvalidApplicationRef {}.inspect(&transpiler.out());
assert_that!(
errors.first().expect("failed to get first error"),
is(equal_to(
"Invalid application -> \"x\"; Ref `\"x\"` does not exist"
))
);
Ok(())
}
}