From fc4115b7d7257ca019d0a1d9f15802350d90ab28 Mon Sep 17 00:00:00 2001 From: Christopher Regali Date: Wed, 4 Oct 2023 23:50:59 +0200 Subject: [PATCH] Add json checker --- Cargo.toml | 3 + src/json.rs | 10 ++-- src/report/mod.rs | 60 +++++++++++++++++-- src/report/template.rs | 78 +++++++++++++++++++++++++ tests/integ.rs | 14 +++++ tests/integ/data/json/actual/guy.json | 1 + tests/integ/data/json/expected/guy.json | 1 + tests/integ/json.yml | 7 +++ 8 files changed, 166 insertions(+), 8 deletions(-) create mode 100644 tests/integ/data/json/actual/guy.json create mode 100644 tests/integ/data/json/expected/guy.json create mode 100644 tests/integ/json.yml diff --git a/Cargo.toml b/Cargo.toml index 74e89d1..bf8b82b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -49,6 +49,9 @@ opener = "0.6" anyhow = "1.0" json_diff = {git = "https://github.com/ChrisRega/json-diff"} + + + [dev-dependencies] env_logger = "0.10" tracing = {version = "0.1", default-features = false} diff --git a/src/json.rs b/src/json.rs index a095e07..713b470 100644 --- a/src/json.rs +++ b/src/json.rs @@ -42,10 +42,12 @@ pub(crate) fn compare_files>( .collect(); if !filtered_diff.is_empty() { - let all_diffs_log = filtered_diff.iter().map(|(_, v)| v).join("\n"); - diff.push_detail(DiffDetail::External { - stdout: all_diffs_log, - stderr: String::new(), + let all_diffs_log = filtered_diff + .iter() + .map(|(d, v)| format!("{d}: {v}")) + .join("\n"); + diff.push_detail(DiffDetail::Json { + differences: all_diffs_log, }); diff.error(); diff --git a/src/report/mod.rs b/src/report/mod.rs index 5c9d9c5..dbcda29 100644 --- a/src/report/mod.rs +++ b/src/report/mod.rs @@ -119,7 +119,7 @@ impl Difference { return false; } self.is_error |= other.is_error; - self.detail.extend(other.detail.into_iter()); + self.detail.extend(other.detail); true } } @@ -146,6 +146,9 @@ pub enum DiffDetail { stdout: String, stderr: String, }, + Json { + differences: String, + }, Properties(MetaDataPropertyDiff), Error(String), } @@ -265,7 +268,7 @@ pub(crate) fn write_csv_detail( let columns: Vec = n .into_iter() - .zip(a.into_iter()) + .zip(a) .enumerate() .map(|(col, (n, a))| { let current_pos = Position { col, row }; @@ -500,6 +503,34 @@ pub fn write_external_detail( Ok(Some(detail_path)) } +pub fn write_json_detail( + nominal: impl AsRef, + actual: impl AsRef, + differences: &str, + report_dir: impl AsRef, +) -> Result, Error> { + let detail_path = create_detail_folder(report_dir.as_ref())?; + let detail_file = detail_path.path.join(template::DETAIL_FILENAME); + + let mut tera = Tera::default(); + tera.add_raw_template( + &detail_file.to_string_lossy(), + template::PLAIN_JSON_DETAIL_TEMPLATE, + )?; + + let mut ctx = Context::new(); + ctx.insert("actual", &actual.as_ref().to_string_lossy()); + ctx.insert("nominal", &nominal.as_ref().to_string_lossy()); + ctx.insert("differences", differences); + + let file = fat_io_wrap_std(&detail_file, &File::create)?; + debug!("detail html {:?} created", &detail_file); + + tera.render_to(&detail_file.to_string_lossy(), &ctx, file)?; + + Ok(Some(detail_path)) +} + fn create_error_detail( nominal: impl AsRef, actual: impl AsRef, @@ -628,7 +659,7 @@ pub(crate) fn create_html( &file.nominal_file, &file.actual_file, &diffs, - &config, + config, &sub_folder, ) .unwrap_or_else(|e| log_detail_html_creation_error(&e)) @@ -703,7 +734,7 @@ pub(crate) fn create_html( ) .unwrap_or_else(|e| log_detail_html_creation_error(&e)) } - ComparisonMode::External(_) | ComparisonMode::Json(_) => { + ComparisonMode::External(_) => { if let Some((stdout, stderr)) = file .detail .iter() @@ -725,6 +756,27 @@ pub(crate) fn create_html( None } } + ComparisonMode::Json(_) => { + if let Some(differences) = file + .detail + .iter() + .filter_map(|r| match r { + DiffDetail::Json { differences } => Some(differences), + _ => None, + }) + .next() + { + write_json_detail( + &file.nominal_file, + &file.actual_file, + differences, + &sub_folder, + ) + .unwrap_or_else(|e| log_detail_html_creation_error(&e)) + } else { + None + } + } ComparisonMode::FileProperties(_) => None, //we need only additional columns in the index.html ComparisonMode::Hash(_) => { let diffs: Vec = file diff --git a/src/report/template.rs b/src/report/template.rs index 4ea1c98..cafe67d 100644 --- a/src/report/template.rs +++ b/src/report/template.rs @@ -680,6 +680,84 @@ pub const PLAIN_EXTERNAL_DETAIL_TEMPLATE: &str = r###" + + +"###; + +pub const PLAIN_JSON_DETAIL_TEMPLATE: &str = r###" + + + + + Results + + + + + + +

Compare Result of {{ actual }} and {{ nominal }}

+ + + + + + + + + + + + +
Differences
+{{ differences }} +
+ + "###; diff --git a/tests/integ.rs b/tests/integ.rs index 6e4f84c..0c95158 100644 --- a/tests/integ.rs +++ b/tests/integ.rs @@ -36,3 +36,17 @@ fn images_test() { ) .unwrap()); } + +#[test] +fn json_test() { + let report_dir = + tempfile::tempdir().expect("Could not generate temporary directory for report"); + + assert!(!compare_folders( + "tests/integ/data/json/expected/", + "tests/integ/data/json/actual/", + "tests/integ/json.yml", + report_dir + ) + .unwrap()); +} diff --git a/tests/integ/data/json/actual/guy.json b/tests/integ/data/json/actual/guy.json new file mode 100644 index 0000000..c3fb985 --- /dev/null +++ b/tests/integ/data/json/actual/guy.json @@ -0,0 +1 @@ +{"name":"Takumi", "age":18, "car": "Panda Trueno"} \ No newline at end of file diff --git a/tests/integ/data/json/expected/guy.json b/tests/integ/data/json/expected/guy.json new file mode 100644 index 0000000..74ac4c1 --- /dev/null +++ b/tests/integ/data/json/expected/guy.json @@ -0,0 +1 @@ +{"name":"Keisuke", "age":21, "car": "RX7", "brothers": ["Ryosuke"]} \ No newline at end of file diff --git a/tests/integ/json.yml b/tests/integ/json.yml new file mode 100644 index 0000000..b771bfb --- /dev/null +++ b/tests/integ/json.yml @@ -0,0 +1,7 @@ +rules: + - name: "Compare JSON files" + pattern_include: + - "**/*.json" + Json: + ignore_keys: + - "" \ No newline at end of file