From ea21e8f1c81eed484f9204d4abce4b7927bcc7e8 Mon Sep 17 00:00:00 2001 From: Manuel Fuchs Date: Tue, 15 Feb 2022 09:30:32 +0100 Subject: [PATCH 1/5] Add assert_contains macro --- .../ruby-sample/tests/integration_test.rs | 7 +-- libcnb-test/src/lib.rs | 1 + libcnb-test/src/macros.rs | 48 +++++++++++++++++++ 3 files changed, 53 insertions(+), 3 deletions(-) create mode 100644 libcnb-test/src/macros.rs diff --git a/examples/ruby-sample/tests/integration_test.rs b/examples/ruby-sample/tests/integration_test.rs index 15fecc3f..71cb5d1c 100644 --- a/examples/ruby-sample/tests/integration_test.rs +++ b/examples/ruby-sample/tests/integration_test.rs @@ -7,6 +7,7 @@ // https://rust-lang.github.io/rust-clippy/stable/index.html #![warn(clippy::pedantic)] +use libcnb_test::assert_contains; use libcnb_test::IntegrationTest; use std::io; use std::io::{Read, Write}; @@ -19,9 +20,9 @@ use std::time::Duration; fn basic() { IntegrationTest::new("heroku/buildpacks:20", "test-fixtures/simple-ruby-app").run_test( |context| { - assert!(context.pack_stdout.contains("---> Ruby Buildpack")); - assert!(context.pack_stdout.contains("---> Installing bundler")); - assert!(context.pack_stdout.contains("---> Installing gems")); + assert_contains!(context.pack_stdout, "---> Ruby Buildpack"); + assert_contains!(context.pack_stdout, "---> Installing bundler"); + assert_contains!(context.pack_stdout, "---> Installing gems"); context.start_container(&[12345], |container| { std::thread::sleep(Duration::from_secs(1)); diff --git a/libcnb-test/src/lib.rs b/libcnb-test/src/lib.rs index ada49695..93de6195 100644 --- a/libcnb-test/src/lib.rs +++ b/libcnb-test/src/lib.rs @@ -10,6 +10,7 @@ mod app; mod build; mod container_context; mod container_port_mapping; +mod macros; mod pack; mod util; diff --git a/libcnb-test/src/macros.rs b/libcnb-test/src/macros.rs new file mode 100644 index 00000000..8acab453 --- /dev/null +++ b/libcnb-test/src/macros.rs @@ -0,0 +1,48 @@ +/// Asserts that `left` contains `right`. +/// +/// Commonly used when asserting `pack` output in integration tests. Expands to a [`str::contains`] +/// call and logs `left` (in unescaped and escaped form) as well as `right` on failure. +/// +/// # Example +/// +/// ``` +/// use libcnb_test::assert_contains; +/// +/// let output = "Hello World!\nHello Integration Test!"; +/// assert_contains!(output, "Integration"); +/// ``` +#[macro_export] +macro_rules! assert_contains { + ($left:expr, $right:expr $(,)?) => {{ + if !$left.contains($right) { + ::std::panic!( + r#"assertion failed: `(left contains right)` +left (unescaped): +{} + +left (escaped): `{:?}` +right: `{:?}`"#, + $left, + $left, + $right, + ) + } + }}; + + ($left:expr, $right:expr, $($arg:tt)+) => {{ + if !$left.contains($right) { + ::std::panic!( + r#"assertion failed: `(left contains right)` +left (unescaped): +{} + +left (escaped): `{:?}` +right: `{:?}`: {}"#, + $left, + $left, + $right, + ::core::format_args!($($arg)+) + ) + } + }}; +} From 0cc9c53d4c8fb793580d8c80ed8f3a16ade2aafd Mon Sep 17 00:00:00 2001 From: Manuel Fuchs Date: Tue, 15 Feb 2022 09:34:35 +0100 Subject: [PATCH 2/5] Update CHANGELOG --- libcnb-test/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/libcnb-test/CHANGELOG.md b/libcnb-test/CHANGELOG.md index 0c1f1655..0edb207b 100644 --- a/libcnb-test/CHANGELOG.md +++ b/libcnb-test/CHANGELOG.md @@ -4,6 +4,7 @@ - `libcnb-test` now cross-compiles and packages all binary targets of the buildpack for an integration test. The main buildpack binary is either the only binary target or the target with the same name as the crate. This feature allows the usage of additional binaries for i.e. execd. ([#314](https://github.com/Malax/libcnb.rs/pull/314)) - Increase minimum supported Rust version from 1.56 to 1.58 ([#318](https://github.com/Malax/libcnb.rs/pull/318)). +- Add `assert_contains!` macro for easier matching of `pack` output in integration tests. ([#322](https://github.com/Malax/libcnb.rs/pull/322)) ## [0.1.1] 2022-02-04 From fb02bb0b520affb9fec4117cb6c72efde65ee403 Mon Sep 17 00:00:00 2001 From: Manuel Fuchs Date: Tue, 15 Feb 2022 15:02:23 +0100 Subject: [PATCH 3/5] Add unit tests for assert_contains --- libcnb-test/src/macros.rs | 68 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/libcnb-test/src/macros.rs b/libcnb-test/src/macros.rs index 8acab453..4ca773c0 100644 --- a/libcnb-test/src/macros.rs +++ b/libcnb-test/src/macros.rs @@ -46,3 +46,71 @@ right: `{:?}`: {}"#, } }}; } + +#[cfg(test)] +mod test { + #[test] + fn simple() { + assert_contains!("Hello World!", "World"); + } + + #[test] + fn simple_with_args() { + assert_contains!("Hello World!", "World", "World must be greeted!"); + } + + #[test] + #[should_panic(expected = "assertion failed: `(left contains right)` +left (unescaped): +foo + +left (escaped): `\"foo\"` +right: `\"bar\"`")] + fn simple_failure() { + assert_contains!("foo", "bar"); + } + + #[test] + #[should_panic(expected = "assertion failed: `(left contains right)` +left (unescaped): +Hello Germany! + +left (escaped): `\"Hello Germany!\"` +right: `\"World\"`: World must be greeted!")] + fn simple_failure_with_args() { + assert_contains!("Hello Germany!", "World", "World must be greeted!"); + } + + #[test] + fn multiline() { + assert_contains!("Hello World!\nFoo\nBar\nBaz", "Bar"); + } + + #[test] + #[should_panic(expected = "assertion failed: `(left contains right)` +left (unescaped): +Hello World! +Foo +Bar +Baz + +left (escaped): `\"Hello World!\\nFoo\\nBar\\nBaz\"` +right: `\"Eggs\"`")] + fn multiline_failure() { + assert_contains!("Hello World!\nFoo\nBar\nBaz", "Eggs"); + } + + #[test] + #[should_panic(expected = "assertion failed: `(left contains right)` +left (unescaped): +Hello World! +Foo +Bar +Baz + +left (escaped): `\"Hello World!\\nFoo\\nBar\\nBaz\"` +right: `\"Eggs\"`: We need eggs!")] + fn multiline_failure_with_args() { + assert_contains!("Hello World!\nFoo\nBar\nBaz", "Eggs", "We need eggs!"); + } +} From c5cc2d920265d7fc3d665766bc15fc50a4a26e88 Mon Sep 17 00:00:00 2001 From: Manuel Fuchs Date: Tue, 15 Feb 2022 15:06:50 +0100 Subject: [PATCH 4/5] Use assert_contains in docs instead of assert --- libcnb-test/README.md | 8 ++++---- libcnb-test/src/lib.rs | 16 ++++++++-------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/libcnb-test/README.md b/libcnb-test/README.md index a0a2d01c..767bb011 100644 --- a/libcnb-test/README.md +++ b/libcnb-test/README.md @@ -15,7 +15,7 @@ Please use the same tag for feature requests. ```rust,no_run // In $CRATE_ROOT/test/integration_test.rs -use libcnb_test::{IntegrationTest, BuildpackReference}; +use libcnb_test::{IntegrationTest, BuildpackReference, assert_contains}; #[test] fn test() { @@ -25,9 +25,9 @@ fn test() { BuildpackReference::Crate, ]) .run_test(|context| { - assert!(context.pack_stdout.contains("---> Maven Buildpack")); - assert!(context.pack_stdout.contains("---> Installing Maven")); - assert!(context.pack_stdout.contains("---> Running mvn package")); + assert_contains!(context.pack_stdout, "---> Maven Buildpack"); + assert_contains!(context.pack_stdout, "---> Installing Maven"); + assert_contains!(context.pack_stdout, "---> Running mvn package"); context.start_container(&[12345], |container| { assert_eq!( diff --git a/libcnb-test/src/lib.rs b/libcnb-test/src/lib.rs index 93de6195..9b57e6f0 100644 --- a/libcnb-test/src/lib.rs +++ b/libcnb-test/src/lib.rs @@ -35,7 +35,7 @@ use std::process::{Command, Stdio}; /// /// # Example /// ```no_run -/// use libcnb_test::{IntegrationTest, BuildpackReference}; +/// use libcnb_test::{IntegrationTest, BuildpackReference, assert_contains}; /// /// # fn call_test_fixture_service(addr: std::net::SocketAddr, payload: &str) -> Result { /// # unimplemented!() @@ -46,9 +46,9 @@ use std::process::{Command, Stdio}; /// BuildpackReference::Crate, /// ]) /// .run_test(|context| { -/// assert!(context.pack_stdout.contains("---> Maven Buildpack")); -/// assert!(context.pack_stdout.contains("---> Installing Maven")); -/// assert!(context.pack_stdout.contains("---> Running mvn package")); +/// assert_contains!(context.pack_stdout, "---> Maven Buildpack"); +/// assert_contains!(context.pack_stdout, "---> Installing Maven"); +/// assert_contains!(context.pack_stdout, "---> Running mvn package"); /// /// context.start_container(&[12345], |container| { /// assert_eq!( @@ -151,13 +151,13 @@ impl IntegrationTest { /// /// # Example /// ```no_run - /// use libcnb_test::IntegrationTest; + /// use libcnb_test::{IntegrationTest, assert_contains}; /// /// IntegrationTest::new("heroku/buildpacks:20", "test-fixtures/app") /// .run_test(|context| { - /// assert!(context.pack_stdout.contains("---> Ruby Buildpack")); - /// assert!(context.pack_stdout.contains("---> Installing bundler")); - /// assert!(context.pack_stdout.contains("---> Installing gems")); + /// assert_contains!(context.pack_stdout, "---> Ruby Buildpack"); + /// assert_contains!(context.pack_stdout, "---> Installing bundler"); + /// assert_contains!(context.pack_stdout, "---> Installing gems"); /// }) /// ``` pub fn run_test(&mut self, f: F) { From fae5895418efa8b3d3493cf683b343bcbb462876 Mon Sep 17 00:00:00 2001 From: Manuel Fuchs Date: Tue, 22 Feb 2022 12:48:55 +0100 Subject: [PATCH 5/5] Replace assert! with assert_contains! --- examples/ruby-sample/tests/integration_test.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/ruby-sample/tests/integration_test.rs b/examples/ruby-sample/tests/integration_test.rs index 71cb5d1c..39b4e18a 100644 --- a/examples/ruby-sample/tests/integration_test.rs +++ b/examples/ruby-sample/tests/integration_test.rs @@ -36,10 +36,10 @@ fn basic() { "!dlroW olleH" ); - assert!(container - .shell_exec("ruby --version") - .stdout - .contains("ruby 2.7.0p0")); + assert_contains!( + container.shell_exec("ruby --version").stdout, + "ruby 2.7.0p0" + ); }); }, );