// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. use std::collections::BTreeSet; use regorus::*; use anyhow::Result; use test_generator::test_resources; #[derive(serde::Deserialize)] struct File { covered: BTreeSet, not_covered: BTreeSet, } #[derive(serde::Deserialize)] struct TestCase { data: Option, input: Option, modules: Vec, note: String, query: String, skip: Option, report: Vec, } #[derive(serde::Deserialize)] struct YamlTest { cases: Vec, } fn yaml_test_impl(file: &str) -> Result<()> { let yaml_str = std::fs::read_to_string(file)?; let test: YamlTest = serde_yaml::from_str(&yaml_str)?; println!("running {file}"); for case in test.cases.into_iter() { print!("case {} ", case.note); if case.skip == Some(true) { println!("skipped"); continue; } let mut engine = Engine::new(); engine.set_enable_coverage(true); for (idx, rego) in case.modules.iter().enumerate() { engine.add_policy(format!("rego_{idx}"), rego.clone())?; } if let Some(data) = case.data { engine.add_data(data)?; } if let Some(input) = case.input { engine.set_input(input); } let _ = engine.eval_query(case.query.clone(), false)?; let report = engine.get_coverage_report()?; for (idx, file) in case.report.into_iter().enumerate() { assert_eq!(file.not_covered, report.files[idx].not_covered); assert_eq!(file.covered, report.files[idx].covered); } println!("passed"); } Ok(()) } fn yaml_test(file: &str) -> Result<()> { match yaml_test_impl(file) { Ok(_) => Ok(()), Err(e) => { // If Err is returned, it doesn't always get printed by cargo test. // Therefore, panic with the error. panic!("{}", e); } } } #[test_resources("tests/coverage/*.yaml")] fn run(path: &str) { yaml_test(path).unwrap() }