From 7ea8e9f215daad2759e8cbfcd04c4d4a570b1859 Mon Sep 17 00:00:00 2001 From: David Peter Date: Sun, 29 Dec 2024 12:46:37 +0100 Subject: [PATCH] Use insta for exporter tests --- Cargo.lock | 26 ++++ Cargo.toml | 5 + src/export/markdown.rs | 273 ----------------------------------------- src/export/mod.rs | 2 + src/export/tests.rs | 204 ++++++++++++++++++++++++++++++ 5 files changed, 237 insertions(+), 273 deletions(-) create mode 100644 src/export/tests.rs diff --git a/Cargo.lock b/Cargo.lock index 2f1a33d..b531e67 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -422,6 +422,7 @@ dependencies = [ "colored", "csv", "indicatif", + "insta", "libc", "nix", "once_cell", @@ -460,6 +461,19 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "insta" +version = "1.41.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e9ffc4d4892617c50a928c52b2961cb5174b6fc6ebf252b2fac9d21955c48b8" +dependencies = [ + "console", + "lazy_static", + "linked-hash-map", + "serde", + "similar", +] + [[package]] name = "instant" version = "0.1.13" @@ -493,6 +507,12 @@ version = "0.2.162" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "18d287de67fe55fd7e1581fe933d965a5a9477b38e949cfa9f8574ef01506398" +[[package]] +name = "linked-hash-map" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" + [[package]] name = "linux-raw-sys" version = "0.4.14" @@ -1006,6 +1026,12 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" +[[package]] +name = "similar" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1de1d4f81173b03af4c0cbed3c898f6bff5b870e4a7f5d6f4057d62a7a4b686e" + [[package]] name = "statistical" version = "1.0.0" diff --git a/Cargo.toml b/Cargo.toml index 494900f..45c25b0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -63,9 +63,14 @@ features = [ [dev-dependencies] approx = "0.5" assert_cmd = "2.0" +insta = { version = "1.41.1", features = ["yaml"] } predicates = "3.0" tempfile = "3.14" +[profile.dev.package] +insta.opt-level = 3 +similar.opt-level = 3 + [build-dependencies] clap = "4.4.12" clap_complete = "4.2.1" diff --git a/src/export/markdown.rs b/src/export/markdown.rs index 05afcca..6333c51 100644 --- a/src/export/markdown.rs +++ b/src/export/markdown.rs @@ -28,9 +28,6 @@ impl MarkupExporter for MarkdownExporter { } } -#[cfg(test)] -use crate::options::SortOrder; - /// Check Markdown-based data row formatting #[test] fn test_markdown_formatter_table_data() { @@ -47,273 +44,3 @@ fn test_markdown_formatter_table_divider() { let divider = formatter.table_divider(&[Alignment::Left, Alignment::Right, Alignment::Left]); assert_eq!(divider, "|:---|---:|:---|\n"); } - -/// Test helper function to create unit-based header and horizontal line -/// independently from the markup functionality for Markdown. -#[cfg(test)] -fn cfg_test_table_header(unit_short_name: String) -> String { - format!( - "| Command | Mean [{unit_short_name}] | Min [{unit_short_name}] | Max [{unit_short_name}] | Relative |\n|:---|---:|---:|---:|---:|\n" - ) -} - -/// Ensure the markdown output includes the table header and the multiple -/// benchmark results as a table. The list of actual times is not included -/// in the output. -/// -/// This also demonstrates that the first entry's units (ms) are used to set -/// the units for all entries when the time unit is not given. -#[test] -fn test_markdown_format_ms() { - use super::Exporter; - use crate::benchmark::benchmark_result::BenchmarkResult; - use std::collections::BTreeMap; - let exporter = MarkdownExporter::default(); - - let timing_results = vec![ - BenchmarkResult { - command: String::from("sleep 0.1"), - command_with_unused_parameters: String::from("sleep 0.1"), - mean: 0.1057, - stddev: Some(0.0016), - median: 0.1057, - user: 0.0009, - system: 0.0011, - min: 0.1023, - max: 0.1080, - times: Some(vec![0.1, 0.1, 0.1]), - memory_usage_byte: None, - exit_codes: vec![Some(0), Some(0), Some(0)], - parameters: BTreeMap::new(), - }, - BenchmarkResult { - command: String::from("sleep 2"), - command_with_unused_parameters: String::from("sleep 2"), - mean: 2.0050, - stddev: Some(0.0020), - median: 2.0050, - user: 0.0009, - system: 0.0012, - min: 2.0020, - max: 2.0080, - times: Some(vec![2.0, 2.0, 2.0]), - memory_usage_byte: None, - exit_codes: vec![Some(0), Some(0), Some(0)], - parameters: BTreeMap::new(), - }, - ]; - - let actual = String::from_utf8( - exporter - .serialize(&timing_results, None, SortOrder::Command) - .unwrap(), - ) - .unwrap(); - let expect = format!( - "{}\ -| `sleep 0.1` | 105.7 ± 1.6 | 102.3 | 108.0 | 1.00 | -| `sleep 2` | 2005.0 ± 2.0 | 2002.0 | 2008.0 | 18.97 ± 0.29 | -", - cfg_test_table_header("ms".to_string()) - ); - - assert_eq!(expect, actual); -} - -/// This (again) demonstrates that the first entry's units (s) are used to set -/// the units for all entries when the time unit is not given. -#[test] -fn test_markdown_format_s() { - use super::Exporter; - use crate::benchmark::benchmark_result::BenchmarkResult; - use std::collections::BTreeMap; - let exporter = MarkdownExporter::default(); - - let timing_results = vec![ - BenchmarkResult { - command: String::from("sleep 2"), - command_with_unused_parameters: String::from("sleep 2"), - mean: 2.0050, - stddev: Some(0.0020), - median: 2.0050, - user: 0.0009, - system: 0.0012, - min: 2.0020, - max: 2.0080, - times: Some(vec![2.0, 2.0, 2.0]), - memory_usage_byte: None, - exit_codes: vec![Some(0), Some(0), Some(0)], - parameters: BTreeMap::new(), - }, - BenchmarkResult { - command: String::from("sleep 0.1"), - command_with_unused_parameters: String::from("sleep 0.1"), - mean: 0.1057, - stddev: Some(0.0016), - median: 0.1057, - user: 0.0009, - system: 0.0011, - min: 0.1023, - max: 0.1080, - times: Some(vec![0.1, 0.1, 0.1]), - memory_usage_byte: None, - exit_codes: vec![Some(0), Some(0), Some(0)], - parameters: BTreeMap::new(), - }, - ]; - - let actual = String::from_utf8( - exporter - .serialize(&timing_results, None, SortOrder::Command) - .unwrap(), - ) - .unwrap(); - let expect = format!( - "{}\ -| `sleep 2` | 2.005 ± 0.002 | 2.002 | 2.008 | 18.97 ± 0.29 | -| `sleep 0.1` | 0.106 ± 0.002 | 0.102 | 0.108 | 1.00 | -", - cfg_test_table_header("s".to_string()) - ); - - assert_eq!(expect, actual); -} - -/// The given time unit (s) is used to set the units for all entries. -#[test] -fn test_markdown_format_time_unit_s() { - use super::Exporter; - use crate::benchmark::benchmark_result::BenchmarkResult; - use crate::util::units::Unit; - use std::collections::BTreeMap; - let exporter = MarkdownExporter::default(); - - let timing_results = vec![ - BenchmarkResult { - command: String::from("sleep 2"), - command_with_unused_parameters: String::from("sleep 2"), - mean: 2.0050, - stddev: Some(0.0020), - median: 2.0050, - user: 0.0009, - system: 0.0012, - min: 2.0020, - max: 2.0080, - times: Some(vec![2.0, 2.0, 2.0]), - memory_usage_byte: None, - exit_codes: vec![Some(0), Some(0), Some(0)], - parameters: BTreeMap::new(), - }, - BenchmarkResult { - command: String::from("sleep 0.1"), - command_with_unused_parameters: String::from("sleep 0.1"), - mean: 0.1057, - stddev: Some(0.0016), - median: 0.1057, - user: 0.0009, - system: 0.0011, - min: 0.1023, - max: 0.1080, - times: Some(vec![0.1, 0.1, 0.1]), - memory_usage_byte: None, - exit_codes: vec![Some(0), Some(0), Some(0)], - parameters: BTreeMap::new(), - }, - ]; - - { - let actual = String::from_utf8( - exporter - .serialize(&timing_results, Some(Unit::Second), SortOrder::Command) - .unwrap(), - ) - .unwrap(); - let expect = format!( - "{}\ -| `sleep 2` | 2.005 ± 0.002 | 2.002 | 2.008 | 18.97 ± 0.29 | -| `sleep 0.1` | 0.106 ± 0.002 | 0.102 | 0.108 | 1.00 | -", - cfg_test_table_header("s".to_string()) - ); - - assert_eq!(expect, actual); - } - - { - let actual = String::from_utf8( - exporter - .serialize(&timing_results, Some(Unit::Second), SortOrder::MeanTime) - .unwrap(), - ) - .unwrap(); - let expect = format!( - "{}\ -| `sleep 0.1` | 0.106 ± 0.002 | 0.102 | 0.108 | 1.00 | -| `sleep 2` | 2.005 ± 0.002 | 2.002 | 2.008 | 18.97 ± 0.29 | -", - cfg_test_table_header("s".to_string()) - ); - - assert_eq!(expect, actual); - } -} - -/// This (again) demonstrates that the given time unit (ms) is used to set -/// the units for all entries. -#[test] -fn test_markdown_format_time_unit_ms() { - use super::Exporter; - use crate::benchmark::benchmark_result::BenchmarkResult; - use crate::util::units::Unit; - use std::collections::BTreeMap; - let exporter = MarkdownExporter::default(); - - let timing_results = vec![ - BenchmarkResult { - command: String::from("sleep 2"), - command_with_unused_parameters: String::from("sleep 2"), - mean: 2.0050, - stddev: Some(0.0020), - median: 2.0050, - user: 0.0009, - system: 0.0012, - min: 2.0020, - max: 2.0080, - times: Some(vec![2.0, 2.0, 2.0]), - memory_usage_byte: None, - exit_codes: vec![Some(0), Some(0), Some(0)], - parameters: BTreeMap::new(), - }, - BenchmarkResult { - command: String::from("sleep 0.1"), - command_with_unused_parameters: String::from("sleep 0.1"), - mean: 0.1057, - stddev: Some(0.0016), - median: 0.1057, - user: 0.0009, - system: 0.0011, - min: 0.1023, - max: 0.1080, - times: Some(vec![0.1, 0.1, 0.1]), - memory_usage_byte: None, - exit_codes: vec![Some(0), Some(0), Some(0)], - parameters: BTreeMap::new(), - }, - ]; - - let actual = String::from_utf8( - exporter - .serialize(&timing_results, Some(Unit::MilliSecond), SortOrder::Command) - .unwrap(), - ) - .unwrap(); - let expect = format!( - "{}\ -| `sleep 2` | 2005.0 ± 2.0 | 2002.0 | 2008.0 | 18.97 ± 0.29 | -| `sleep 0.1` | 105.7 ± 1.6 | 102.3 | 108.0 | 1.00 | -", - cfg_test_table_header("ms".to_string()) - ); - - assert_eq!(expect, actual); -} diff --git a/src/export/mod.rs b/src/export/mod.rs index 4fdab0c..194cad1 100644 --- a/src/export/mod.rs +++ b/src/export/mod.rs @@ -7,6 +7,8 @@ mod json; mod markdown; mod markup; mod orgmode; +#[cfg(test)] +mod tests; use self::asciidoc::AsciidocExporter; use self::csv::CsvExporter; diff --git a/src/export/tests.rs b/src/export/tests.rs new file mode 100644 index 0000000..96a47ae --- /dev/null +++ b/src/export/tests.rs @@ -0,0 +1,204 @@ +use super::Exporter; +use crate::benchmark::benchmark_result::BenchmarkResult; +use crate::util::units::Unit; +use crate::{export::markdown::MarkdownExporter, options::SortOrder}; +use std::collections::BTreeMap; + +fn get_markdown_output( + results: &[BenchmarkResult], + unit: Option, + sort_order: SortOrder, +) -> String { + let exporter = MarkdownExporter::default(); + String::from_utf8(exporter.serialize(results, unit, sort_order).unwrap()).unwrap() +} + +/// Ensure the markdown output includes the table header and the multiple +/// benchmark results as a table. The list of actual times is not included +/// in the output. +/// +/// This also demonstrates that the first entry's units (ms) are used to set +/// the units for all entries when the time unit is not given. +#[test] +fn test_markdown_format_ms() { + let results = [ + BenchmarkResult { + command: String::from("sleep 0.1"), + command_with_unused_parameters: String::from("sleep 0.1"), + mean: 0.1057, + stddev: Some(0.0016), + median: 0.1057, + user: 0.0009, + system: 0.0011, + min: 0.1023, + max: 0.1080, + times: Some(vec![0.1, 0.1, 0.1]), + memory_usage_byte: None, + exit_codes: vec![Some(0), Some(0), Some(0)], + parameters: BTreeMap::new(), + }, + BenchmarkResult { + command: String::from("sleep 2"), + command_with_unused_parameters: String::from("sleep 2"), + mean: 2.0050, + stddev: Some(0.0020), + median: 2.0050, + user: 0.0009, + system: 0.0012, + min: 2.0020, + max: 2.0080, + times: Some(vec![2.0, 2.0, 2.0]), + memory_usage_byte: None, + exit_codes: vec![Some(0), Some(0), Some(0)], + parameters: BTreeMap::new(), + }, + ]; + + insta::assert_snapshot!(get_markdown_output(&results, None, SortOrder::Command), @r#" + | Command | Mean [ms] | Min [ms] | Max [ms] | Relative | + |:---|---:|---:|---:|---:| + | `sleep 0.1` | 105.7 ± 1.6 | 102.3 | 108.0 | 1.00 | + | `sleep 2` | 2005.0 ± 2.0 | 2002.0 | 2008.0 | 18.97 ± 0.29 | + "#); +} + +/// This (again) demonstrates that the first entry's units (s) are used to set +/// the units for all entries when the time unit is not given. +#[test] +fn test_markdown_format_s() { + let results = [ + BenchmarkResult { + command: String::from("sleep 2"), + command_with_unused_parameters: String::from("sleep 2"), + mean: 2.0050, + stddev: Some(0.0020), + median: 2.0050, + user: 0.0009, + system: 0.0012, + min: 2.0020, + max: 2.0080, + times: Some(vec![2.0, 2.0, 2.0]), + memory_usage_byte: None, + exit_codes: vec![Some(0), Some(0), Some(0)], + parameters: BTreeMap::new(), + }, + BenchmarkResult { + command: String::from("sleep 0.1"), + command_with_unused_parameters: String::from("sleep 0.1"), + mean: 0.1057, + stddev: Some(0.0016), + median: 0.1057, + user: 0.0009, + system: 0.0011, + min: 0.1023, + max: 0.1080, + times: Some(vec![0.1, 0.1, 0.1]), + memory_usage_byte: None, + exit_codes: vec![Some(0), Some(0), Some(0)], + parameters: BTreeMap::new(), + }, + ]; + + insta::assert_snapshot!(get_markdown_output(&results, None, SortOrder::Command), @r#" + | Command | Mean [s] | Min [s] | Max [s] | Relative | + |:---|---:|---:|---:|---:| + | `sleep 2` | 2.005 ± 0.002 | 2.002 | 2.008 | 18.97 ± 0.29 | + | `sleep 0.1` | 0.106 ± 0.002 | 0.102 | 0.108 | 1.00 | + "#); +} + +/// The given time unit (s) is used to set the units for all entries. +#[test] +fn test_markdown_format_time_unit_s() { + let results = [ + BenchmarkResult { + command: String::from("sleep 2"), + command_with_unused_parameters: String::from("sleep 2"), + mean: 2.0050, + stddev: Some(0.0020), + median: 2.0050, + user: 0.0009, + system: 0.0012, + min: 2.0020, + max: 2.0080, + times: Some(vec![2.0, 2.0, 2.0]), + memory_usage_byte: None, + exit_codes: vec![Some(0), Some(0), Some(0)], + parameters: BTreeMap::new(), + }, + BenchmarkResult { + command: String::from("sleep 0.1"), + command_with_unused_parameters: String::from("sleep 0.1"), + mean: 0.1057, + stddev: Some(0.0016), + median: 0.1057, + user: 0.0009, + system: 0.0011, + min: 0.1023, + max: 0.1080, + times: Some(vec![0.1, 0.1, 0.1]), + memory_usage_byte: None, + exit_codes: vec![Some(0), Some(0), Some(0)], + parameters: BTreeMap::new(), + }, + ]; + + insta::assert_snapshot!(get_markdown_output(&results, Some(Unit::Second), SortOrder::Command), @r#" + | Command | Mean [s] | Min [s] | Max [s] | Relative | + |:---|---:|---:|---:|---:| + | `sleep 2` | 2.005 ± 0.002 | 2.002 | 2.008 | 18.97 ± 0.29 | + | `sleep 0.1` | 0.106 ± 0.002 | 0.102 | 0.108 | 1.00 | + "#); + + insta::assert_snapshot!(get_markdown_output(&results, Some(Unit::Second), SortOrder::MeanTime), @r#" + | Command | Mean [s] | Min [s] | Max [s] | Relative | + |:---|---:|---:|---:|---:| + | `sleep 0.1` | 0.106 ± 0.002 | 0.102 | 0.108 | 1.00 | + | `sleep 2` | 2.005 ± 0.002 | 2.002 | 2.008 | 18.97 ± 0.29 | + "#); +} + +/// This (again) demonstrates that the given time unit (ms) is used to set +/// the units for all entries. +#[test] +fn test_markdown_format_time_unit_ms() { + let timing_results = [ + BenchmarkResult { + command: String::from("sleep 2"), + command_with_unused_parameters: String::from("sleep 2"), + mean: 2.0050, + stddev: Some(0.0020), + median: 2.0050, + user: 0.0009, + system: 0.0012, + min: 2.0020, + max: 2.0080, + times: Some(vec![2.0, 2.0, 2.0]), + memory_usage_byte: None, + exit_codes: vec![Some(0), Some(0), Some(0)], + parameters: BTreeMap::new(), + }, + BenchmarkResult { + command: String::from("sleep 0.1"), + command_with_unused_parameters: String::from("sleep 0.1"), + mean: 0.1057, + stddev: Some(0.0016), + median: 0.1057, + user: 0.0009, + system: 0.0011, + min: 0.1023, + max: 0.1080, + times: Some(vec![0.1, 0.1, 0.1]), + memory_usage_byte: None, + exit_codes: vec![Some(0), Some(0), Some(0)], + parameters: BTreeMap::new(), + }, + ]; + + insta::assert_snapshot!(get_markdown_output(&timing_results, Some(Unit::MilliSecond), SortOrder::Command), @r#" + | Command | Mean [ms] | Min [ms] | Max [ms] | Relative | + |:---|---:|---:|---:|---:| + | `sleep 2` | 2005.0 ± 2.0 | 2002.0 | 2008.0 | 18.97 ± 0.29 | + | `sleep 0.1` | 105.7 ± 1.6 | 102.3 | 108.0 | 1.00 | + "#); +}