From e7ecd89dea658c4fc3f08f05bed2a98d77ac87ea Mon Sep 17 00:00:00 2001 From: Mark Van de Vyver Date: Mon, 28 Mar 2022 16:01:40 +1100 Subject: [PATCH 01/15] Add: State for issue #71 This initial commit contains the state of play immediately after add the example crates: - test-project - test-procmacro-project Other than setting up the workspace references no changes to the example crates have been made. The integration test harness has not yet been implemented. Signed-off-by: Mark Van de Vyver --- test-workspace/Cargo.toml | 7 +++ test-workspace/README.md | 17 +++++++ test-workspace/wrkspc-dev/Cargo.toml | 15 ++++++ test-workspace/wrkspc-dev/src/lib.rs | 5 ++ test-workspace/wrkspc-dev/tests/lib.rs | 4 ++ test-workspace/wrkspc-macro/.gitignore | 3 ++ test-workspace/wrkspc-macro/Cargo.toml | 17 +++++++ test-workspace/wrkspc-macro/src/lib.rs | 50 +++++++++++++++++++ .../tests/expand/attribute.expanded.rs | 4 ++ .../wrkspc-macro/tests/expand/attribute.rs | 5 ++ .../tests/expand/derive.expanded.rs | 4 ++ .../wrkspc-macro/tests/expand/derive.rs | 5 ++ .../tests/expand/macro.expanded.rs | 6 +++ .../wrkspc-macro/tests/expand/macro.rs | 6 +++ test-workspace/wrkspc-macro/tests/tests.rs | 4 ++ test-workspace/wrkspc-test/.gitignore | 2 + test-workspace/wrkspc-test/Cargo.toml | 14 ++++++ test-workspace/wrkspc-test/src/lib.rs | 32 ++++++++++++ .../tests/expand/first.expanded.rs | 5 ++ .../wrkspc-test/tests/expand/first.rs | 6 +++ .../tests/expand/fourth.expanded.rs | 11 ++++ .../wrkspc-test/tests/expand/fourth.rs | 6 +++ .../tests/expand/second.expanded.rs | 9 ++++ .../wrkspc-test/tests/expand/second.rs | 6 +++ .../tests/expand/third.expanded.rs | 10 ++++ .../wrkspc-test/tests/expand/third.rs | 6 +++ .../tests/expand_args/with_args.expanded.rs | 12 +++++ .../tests/expand_args/with_args.rs | 8 +++ .../wrkspc-test/tests/no_expanded/first.rs | 6 +++ .../wrkspc-test/tests/no_expanded/fourth.rs | 6 +++ .../wrkspc-test/tests/no_expanded/second.rs | 6 +++ .../wrkspc-test/tests/no_expanded/third.rs | 6 +++ .../tests/no_expanded_args/with_args.rs | 8 +++ .../wrkspc-test/tests/par_tests_regression.rs | 12 +++++ .../wrkspc-test/tests/pr61/a/test.expanded.rs | 5 ++ .../wrkspc-test/tests/pr61/a/test.rs | 6 +++ .../wrkspc-test/tests/pr61/b/test.expanded.rs | 5 ++ .../wrkspc-test/tests/pr61/b/test.rs | 6 +++ test-workspace/wrkspc-test/tests/tests.rs | 44 ++++++++++++++++ test-workspace/wrkspc/Cargo.toml | 18 +++++++ test-workspace/wrkspc/src/lib.rs | 5 ++ test-workspace/wrkspc/tests/lib.rs | 4 ++ 42 files changed, 416 insertions(+) create mode 100644 test-workspace/Cargo.toml create mode 100644 test-workspace/README.md create mode 100644 test-workspace/wrkspc-dev/Cargo.toml create mode 100644 test-workspace/wrkspc-dev/src/lib.rs create mode 100644 test-workspace/wrkspc-dev/tests/lib.rs create mode 100644 test-workspace/wrkspc-macro/.gitignore create mode 100644 test-workspace/wrkspc-macro/Cargo.toml create mode 100644 test-workspace/wrkspc-macro/src/lib.rs create mode 100644 test-workspace/wrkspc-macro/tests/expand/attribute.expanded.rs create mode 100644 test-workspace/wrkspc-macro/tests/expand/attribute.rs create mode 100644 test-workspace/wrkspc-macro/tests/expand/derive.expanded.rs create mode 100644 test-workspace/wrkspc-macro/tests/expand/derive.rs create mode 100644 test-workspace/wrkspc-macro/tests/expand/macro.expanded.rs create mode 100644 test-workspace/wrkspc-macro/tests/expand/macro.rs create mode 100644 test-workspace/wrkspc-macro/tests/tests.rs create mode 100644 test-workspace/wrkspc-test/.gitignore create mode 100644 test-workspace/wrkspc-test/Cargo.toml create mode 100644 test-workspace/wrkspc-test/src/lib.rs create mode 100644 test-workspace/wrkspc-test/tests/expand/first.expanded.rs create mode 100644 test-workspace/wrkspc-test/tests/expand/first.rs create mode 100644 test-workspace/wrkspc-test/tests/expand/fourth.expanded.rs create mode 100644 test-workspace/wrkspc-test/tests/expand/fourth.rs create mode 100644 test-workspace/wrkspc-test/tests/expand/second.expanded.rs create mode 100644 test-workspace/wrkspc-test/tests/expand/second.rs create mode 100644 test-workspace/wrkspc-test/tests/expand/third.expanded.rs create mode 100644 test-workspace/wrkspc-test/tests/expand/third.rs create mode 100644 test-workspace/wrkspc-test/tests/expand_args/with_args.expanded.rs create mode 100644 test-workspace/wrkspc-test/tests/expand_args/with_args.rs create mode 100644 test-workspace/wrkspc-test/tests/no_expanded/first.rs create mode 100644 test-workspace/wrkspc-test/tests/no_expanded/fourth.rs create mode 100644 test-workspace/wrkspc-test/tests/no_expanded/second.rs create mode 100644 test-workspace/wrkspc-test/tests/no_expanded/third.rs create mode 100644 test-workspace/wrkspc-test/tests/no_expanded_args/with_args.rs create mode 100644 test-workspace/wrkspc-test/tests/par_tests_regression.rs create mode 100644 test-workspace/wrkspc-test/tests/pr61/a/test.expanded.rs create mode 100644 test-workspace/wrkspc-test/tests/pr61/a/test.rs create mode 100644 test-workspace/wrkspc-test/tests/pr61/b/test.expanded.rs create mode 100644 test-workspace/wrkspc-test/tests/pr61/b/test.rs create mode 100644 test-workspace/wrkspc-test/tests/tests.rs create mode 100644 test-workspace/wrkspc/Cargo.toml create mode 100644 test-workspace/wrkspc/src/lib.rs create mode 100644 test-workspace/wrkspc/tests/lib.rs diff --git a/test-workspace/Cargo.toml b/test-workspace/Cargo.toml new file mode 100644 index 0000000..f33c761 --- /dev/null +++ b/test-workspace/Cargo.toml @@ -0,0 +1,7 @@ +[workspace] +members = [ + "wrkspc-dev", + "wrkspc-macro", + "wrkspc-test", + "wrkspc", +] diff --git a/test-workspace/README.md b/test-workspace/README.md new file mode 100644 index 0000000..9a325a6 --- /dev/null +++ b/test-workspace/README.md @@ -0,0 +1,17 @@ +# `test-project` + +This is an example virtual-workspace that contains crates: + +- `wrkspc` +- `wrkspc-dev` +- `wrkspc-macro` +- `wrkspc-test` + +Where each crate is: + +- `wrkspc`: A "Hello world" style library (for release as a crate). +- `wrkspc-dev`: A "Hello world" style library for development (not for release). +- `wrkspc-macro`: The `test-promacro-project` adjusted to fit into the workspace plugin-test harness. +- `wrkspc-test`: The `test-project` adjusted to fit into the workspace plugin-test harness. + +Test harness for integration tests as plugins, is per the [Infinyon/Fluvio](https://www.infinyon.com/blog/2021/04/rust-custom-test-harness/) setup. diff --git a/test-workspace/wrkspc-dev/Cargo.toml b/test-workspace/wrkspc-dev/Cargo.toml new file mode 100644 index 0000000..b23ba1a --- /dev/null +++ b/test-workspace/wrkspc-dev/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "wrkspc-dev" +version = "0.0.0" +authors = ["Mark Van de Vyver "] +license = "Apache-2.0" +edition = "2018" +description = "A development crate in a virtual workspace example" +homepage = "https://github.com/eupn/macrotest" +repository = "https://github.com/eupn/macrotest" +documentation = "https://docs.rs/macrotest" +readme = "README.md" +publish = false + +[dependencies] +wrkspc-macro = { path = "../wrkspc-macro" } diff --git a/test-workspace/wrkspc-dev/src/lib.rs b/test-workspace/wrkspc-dev/src/lib.rs new file mode 100644 index 0000000..2e6a5a8 --- /dev/null +++ b/test-workspace/wrkspc-dev/src/lib.rs @@ -0,0 +1,5 @@ +pub use wrkspc_macro::*; + +pub fn hello() { + println!("Hello Developer World!") +} diff --git a/test-workspace/wrkspc-dev/tests/lib.rs b/test-workspace/wrkspc-dev/tests/lib.rs new file mode 100644 index 0000000..ead8d3b --- /dev/null +++ b/test-workspace/wrkspc-dev/tests/lib.rs @@ -0,0 +1,4 @@ +#[test] +fn wrkspc_test() { + assert_eq!("equal", "equal") +} diff --git a/test-workspace/wrkspc-macro/.gitignore b/test-workspace/wrkspc-macro/.gitignore new file mode 100644 index 0000000..6936990 --- /dev/null +++ b/test-workspace/wrkspc-macro/.gitignore @@ -0,0 +1,3 @@ +/target +**/*.rs.bk +Cargo.lock diff --git a/test-workspace/wrkspc-macro/Cargo.toml b/test-workspace/wrkspc-macro/Cargo.toml new file mode 100644 index 0000000..898594f --- /dev/null +++ b/test-workspace/wrkspc-macro/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "wrkspc-macro" +version = "0.0.0" +authors = ["eupn "] +edition = "2018" +publish = false + +[lib] +proc-macro = true + +[dependencies] +quote = "1" +proc-macro2 = "1.0" +syn = "1.0" + +[dev-dependencies] +macrotest = { path = "../../" } diff --git a/test-workspace/wrkspc-macro/src/lib.rs b/test-workspace/wrkspc-macro/src/lib.rs new file mode 100644 index 0000000..9716db7 --- /dev/null +++ b/test-workspace/wrkspc-macro/src/lib.rs @@ -0,0 +1,50 @@ +extern crate proc_macro; +use proc_macro::TokenStream; + +use quote::quote; +use syn::{parse_macro_input, DeriveInput}; + +/// Example of [function-like procedural macro][1]. +/// +/// [1]: https://doc.rust-lang.org/reference/procedural-macros.html#function-like-procedural-macros +#[proc_macro] +pub fn my_macro(input: TokenStream) -> TokenStream { + let input = parse_macro_input!(input as DeriveInput); + + let tokens = quote! { + #input + + struct Hello; + }; + + tokens.into() +} + +/// Example of user-defined [derive mode macro][1] +/// +/// [1]: https://doc.rust-lang.org/reference/procedural-macros.html#derive-mode-macros +#[proc_macro_derive(MyDerive)] +pub fn my_derive(_input: TokenStream) -> TokenStream { + // Emit test garbage + let tokens = quote! { + struct Hello; + }; + + tokens.into() +} + +/// Example of user-defined [procedural macro attribute][1]. +/// +/// [1]: https://doc.rust-lang.org/reference/procedural-macros.html#attribute-macros +#[proc_macro_attribute] +pub fn my_attribute(_args: TokenStream, input: TokenStream) -> TokenStream { + let input = parse_macro_input!(input as DeriveInput); + + let tokens = quote! { + #input + + struct Hello; + }; + + tokens.into() +} diff --git a/test-workspace/wrkspc-macro/tests/expand/attribute.expanded.rs b/test-workspace/wrkspc-macro/tests/expand/attribute.expanded.rs new file mode 100644 index 0000000..a444bfa --- /dev/null +++ b/test-workspace/wrkspc-macro/tests/expand/attribute.expanded.rs @@ -0,0 +1,4 @@ +#[macro_use] +extern crate wrkspc_macro; +struct Test; +struct Hello; diff --git a/test-workspace/wrkspc-macro/tests/expand/attribute.rs b/test-workspace/wrkspc-macro/tests/expand/attribute.rs new file mode 100644 index 0000000..da39f56 --- /dev/null +++ b/test-workspace/wrkspc-macro/tests/expand/attribute.rs @@ -0,0 +1,5 @@ +#[macro_use] +extern crate wrkspc_macro; + +#[my_attribute] +struct Test; diff --git a/test-workspace/wrkspc-macro/tests/expand/derive.expanded.rs b/test-workspace/wrkspc-macro/tests/expand/derive.expanded.rs new file mode 100644 index 0000000..a444bfa --- /dev/null +++ b/test-workspace/wrkspc-macro/tests/expand/derive.expanded.rs @@ -0,0 +1,4 @@ +#[macro_use] +extern crate wrkspc_macro; +struct Test; +struct Hello; diff --git a/test-workspace/wrkspc-macro/tests/expand/derive.rs b/test-workspace/wrkspc-macro/tests/expand/derive.rs new file mode 100644 index 0000000..da12e8d --- /dev/null +++ b/test-workspace/wrkspc-macro/tests/expand/derive.rs @@ -0,0 +1,5 @@ +#[macro_use] +extern crate wrkspc_macro; + +#[derive(MyDerive)] +struct Test; diff --git a/test-workspace/wrkspc-macro/tests/expand/macro.expanded.rs b/test-workspace/wrkspc-macro/tests/expand/macro.expanded.rs new file mode 100644 index 0000000..b48da90 --- /dev/null +++ b/test-workspace/wrkspc-macro/tests/expand/macro.expanded.rs @@ -0,0 +1,6 @@ +#[macro_use] +extern crate wrkspc_macro; +pub fn main() { + struct Test; + struct Hello; +} diff --git a/test-workspace/wrkspc-macro/tests/expand/macro.rs b/test-workspace/wrkspc-macro/tests/expand/macro.rs new file mode 100644 index 0000000..856c198 --- /dev/null +++ b/test-workspace/wrkspc-macro/tests/expand/macro.rs @@ -0,0 +1,6 @@ +#[macro_use] +extern crate wrkspc_macro; + +pub fn main() { + my_macro! { struct Test; } +} diff --git a/test-workspace/wrkspc-macro/tests/tests.rs b/test-workspace/wrkspc-macro/tests/tests.rs new file mode 100644 index 0000000..fcee1ef --- /dev/null +++ b/test-workspace/wrkspc-macro/tests/tests.rs @@ -0,0 +1,4 @@ +#[test] +pub fn pass() { + macrotest::expand("tests/expand/*.rs"); +} diff --git a/test-workspace/wrkspc-test/.gitignore b/test-workspace/wrkspc-test/.gitignore new file mode 100644 index 0000000..c8f7745 --- /dev/null +++ b/test-workspace/wrkspc-test/.gitignore @@ -0,0 +1,2 @@ +**/target +**/*.rs.bk diff --git a/test-workspace/wrkspc-test/Cargo.toml b/test-workspace/wrkspc-test/Cargo.toml new file mode 100644 index 0000000..a2163ff --- /dev/null +++ b/test-workspace/wrkspc-test/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "wrkspc-test" +version = "0.0.0" +edition = "2018" + +[lib] + +[features] +default = [] + +test-feature = [] + +[dev-dependencies] +macrotest = { path = "../../" } diff --git a/test-workspace/wrkspc-test/src/lib.rs b/test-workspace/wrkspc-test/src/lib.rs new file mode 100644 index 0000000..f39e1bf --- /dev/null +++ b/test-workspace/wrkspc-test/src/lib.rs @@ -0,0 +1,32 @@ +#[macro_export] +macro_rules! test_vec { + () => { + Vec::new() + }; + ( $( $x:expr ),+ ) => { + { + let mut temp_vec = Vec::new(); + $( + temp_vec.push($x); + )* + temp_vec + } + }; +} + +#[cfg(feature = "test-feature")] +#[cfg_attr(feature = "test-feature", macro_export)] +macro_rules! test_feature_vec { + () => { + Vec::new() + }; + ( $( $x:expr ),+ ) => { + { + let mut temp_vec = Vec::new(); + $( + temp_vec.push($x); + )* + temp_vec + } + }; +} \ No newline at end of file diff --git a/test-workspace/wrkspc-test/tests/expand/first.expanded.rs b/test-workspace/wrkspc-test/tests/expand/first.expanded.rs new file mode 100644 index 0000000..584bf25 --- /dev/null +++ b/test-workspace/wrkspc-test/tests/expand/first.expanded.rs @@ -0,0 +1,5 @@ +#[macro_use] +extern crate test_project; +pub fn main() { + Vec::new(); +} diff --git a/test-workspace/wrkspc-test/tests/expand/first.rs b/test-workspace/wrkspc-test/tests/expand/first.rs new file mode 100644 index 0000000..5f3c0eb --- /dev/null +++ b/test-workspace/wrkspc-test/tests/expand/first.rs @@ -0,0 +1,6 @@ +#[macro_use] +extern crate test_project; + +pub fn main() { + test_vec![]; +} diff --git a/test-workspace/wrkspc-test/tests/expand/fourth.expanded.rs b/test-workspace/wrkspc-test/tests/expand/fourth.expanded.rs new file mode 100644 index 0000000..91ad4bd --- /dev/null +++ b/test-workspace/wrkspc-test/tests/expand/fourth.expanded.rs @@ -0,0 +1,11 @@ +#[macro_use] +extern crate test_project; +pub fn main() { + { + let mut temp_vec = Vec::new(); + temp_vec.push(1); + temp_vec.push(2); + temp_vec.push(3); + temp_vec + }; +} diff --git a/test-workspace/wrkspc-test/tests/expand/fourth.rs b/test-workspace/wrkspc-test/tests/expand/fourth.rs new file mode 100644 index 0000000..3c50cc1 --- /dev/null +++ b/test-workspace/wrkspc-test/tests/expand/fourth.rs @@ -0,0 +1,6 @@ +#[macro_use] +extern crate test_project; + +pub fn main() { + test_vec![1, 2, 3]; +} diff --git a/test-workspace/wrkspc-test/tests/expand/second.expanded.rs b/test-workspace/wrkspc-test/tests/expand/second.expanded.rs new file mode 100644 index 0000000..f57dd2f --- /dev/null +++ b/test-workspace/wrkspc-test/tests/expand/second.expanded.rs @@ -0,0 +1,9 @@ +#[macro_use] +extern crate test_project; +pub fn main() { + { + let mut temp_vec = Vec::new(); + temp_vec.push(1); + temp_vec + }; +} diff --git a/test-workspace/wrkspc-test/tests/expand/second.rs b/test-workspace/wrkspc-test/tests/expand/second.rs new file mode 100644 index 0000000..b7d0e43 --- /dev/null +++ b/test-workspace/wrkspc-test/tests/expand/second.rs @@ -0,0 +1,6 @@ +#[macro_use] +extern crate test_project; + +pub fn main() { + test_vec![1]; +} diff --git a/test-workspace/wrkspc-test/tests/expand/third.expanded.rs b/test-workspace/wrkspc-test/tests/expand/third.expanded.rs new file mode 100644 index 0000000..3fba475 --- /dev/null +++ b/test-workspace/wrkspc-test/tests/expand/third.expanded.rs @@ -0,0 +1,10 @@ +#[macro_use] +extern crate test_project; +pub fn main() { + { + let mut temp_vec = Vec::new(); + temp_vec.push(1); + temp_vec.push(2); + temp_vec + }; +} diff --git a/test-workspace/wrkspc-test/tests/expand/third.rs b/test-workspace/wrkspc-test/tests/expand/third.rs new file mode 100644 index 0000000..bc440e0 --- /dev/null +++ b/test-workspace/wrkspc-test/tests/expand/third.rs @@ -0,0 +1,6 @@ +#[macro_use] +extern crate test_project; + +pub fn main() { + test_vec![1, 2]; +} diff --git a/test-workspace/wrkspc-test/tests/expand_args/with_args.expanded.rs b/test-workspace/wrkspc-test/tests/expand_args/with_args.expanded.rs new file mode 100644 index 0000000..1884aa0 --- /dev/null +++ b/test-workspace/wrkspc-test/tests/expand_args/with_args.expanded.rs @@ -0,0 +1,12 @@ +extern crate std; +#[macro_use] +extern crate test_project; +pub fn main() { + { + let mut temp_vec = Vec::new(); + temp_vec.push(1); + temp_vec.push(2); + temp_vec.push(3); + temp_vec + }; +} diff --git a/test-workspace/wrkspc-test/tests/expand_args/with_args.rs b/test-workspace/wrkspc-test/tests/expand_args/with_args.rs new file mode 100644 index 0000000..dc17120 --- /dev/null +++ b/test-workspace/wrkspc-test/tests/expand_args/with_args.rs @@ -0,0 +1,8 @@ +#![cfg(feature = "test-feature")] + +#[macro_use] +extern crate test_project; + +pub fn main() { + test_feature_vec![1, 2, 3]; +} diff --git a/test-workspace/wrkspc-test/tests/no_expanded/first.rs b/test-workspace/wrkspc-test/tests/no_expanded/first.rs new file mode 100644 index 0000000..5f3c0eb --- /dev/null +++ b/test-workspace/wrkspc-test/tests/no_expanded/first.rs @@ -0,0 +1,6 @@ +#[macro_use] +extern crate test_project; + +pub fn main() { + test_vec![]; +} diff --git a/test-workspace/wrkspc-test/tests/no_expanded/fourth.rs b/test-workspace/wrkspc-test/tests/no_expanded/fourth.rs new file mode 100644 index 0000000..3c50cc1 --- /dev/null +++ b/test-workspace/wrkspc-test/tests/no_expanded/fourth.rs @@ -0,0 +1,6 @@ +#[macro_use] +extern crate test_project; + +pub fn main() { + test_vec![1, 2, 3]; +} diff --git a/test-workspace/wrkspc-test/tests/no_expanded/second.rs b/test-workspace/wrkspc-test/tests/no_expanded/second.rs new file mode 100644 index 0000000..b7d0e43 --- /dev/null +++ b/test-workspace/wrkspc-test/tests/no_expanded/second.rs @@ -0,0 +1,6 @@ +#[macro_use] +extern crate test_project; + +pub fn main() { + test_vec![1]; +} diff --git a/test-workspace/wrkspc-test/tests/no_expanded/third.rs b/test-workspace/wrkspc-test/tests/no_expanded/third.rs new file mode 100644 index 0000000..bc440e0 --- /dev/null +++ b/test-workspace/wrkspc-test/tests/no_expanded/third.rs @@ -0,0 +1,6 @@ +#[macro_use] +extern crate test_project; + +pub fn main() { + test_vec![1, 2]; +} diff --git a/test-workspace/wrkspc-test/tests/no_expanded_args/with_args.rs b/test-workspace/wrkspc-test/tests/no_expanded_args/with_args.rs new file mode 100644 index 0000000..dc17120 --- /dev/null +++ b/test-workspace/wrkspc-test/tests/no_expanded_args/with_args.rs @@ -0,0 +1,8 @@ +#![cfg(feature = "test-feature")] + +#[macro_use] +extern crate test_project; + +pub fn main() { + test_feature_vec![1, 2, 3]; +} diff --git a/test-workspace/wrkspc-test/tests/par_tests_regression.rs b/test-workspace/wrkspc-test/tests/par_tests_regression.rs new file mode 100644 index 0000000..7a15ffe --- /dev/null +++ b/test-workspace/wrkspc-test/tests/par_tests_regression.rs @@ -0,0 +1,12 @@ +// The tests were interfering with each other when run in parallel. +// This regression test module will ensure that parallel use case is handled. + +#[test] +pub fn parallel_1() { + macrotest::expand("tests/expand/first.rs"); +} + +#[test] +pub fn parallel_2() { + macrotest::expand("tests/expand/second.rs"); +} diff --git a/test-workspace/wrkspc-test/tests/pr61/a/test.expanded.rs b/test-workspace/wrkspc-test/tests/pr61/a/test.expanded.rs new file mode 100644 index 0000000..584bf25 --- /dev/null +++ b/test-workspace/wrkspc-test/tests/pr61/a/test.expanded.rs @@ -0,0 +1,5 @@ +#[macro_use] +extern crate test_project; +pub fn main() { + Vec::new(); +} diff --git a/test-workspace/wrkspc-test/tests/pr61/a/test.rs b/test-workspace/wrkspc-test/tests/pr61/a/test.rs new file mode 100644 index 0000000..5f3c0eb --- /dev/null +++ b/test-workspace/wrkspc-test/tests/pr61/a/test.rs @@ -0,0 +1,6 @@ +#[macro_use] +extern crate test_project; + +pub fn main() { + test_vec![]; +} diff --git a/test-workspace/wrkspc-test/tests/pr61/b/test.expanded.rs b/test-workspace/wrkspc-test/tests/pr61/b/test.expanded.rs new file mode 100644 index 0000000..584bf25 --- /dev/null +++ b/test-workspace/wrkspc-test/tests/pr61/b/test.expanded.rs @@ -0,0 +1,5 @@ +#[macro_use] +extern crate test_project; +pub fn main() { + Vec::new(); +} diff --git a/test-workspace/wrkspc-test/tests/pr61/b/test.rs b/test-workspace/wrkspc-test/tests/pr61/b/test.rs new file mode 100644 index 0000000..5f3c0eb --- /dev/null +++ b/test-workspace/wrkspc-test/tests/pr61/b/test.rs @@ -0,0 +1,6 @@ +#[macro_use] +extern crate test_project; + +pub fn main() { + test_vec![]; +} diff --git a/test-workspace/wrkspc-test/tests/tests.rs b/test-workspace/wrkspc-test/tests/tests.rs new file mode 100644 index 0000000..a78dc88 --- /dev/null +++ b/test-workspace/wrkspc-test/tests/tests.rs @@ -0,0 +1,44 @@ +#[test] +pub fn pass() { + macrotest::expand("tests/expand/*.rs"); +} + +#[test] +pub fn pass_expect_expanded() { + // If you delete one of the `.expanded.rs` files, this test will fail. + macrotest::expand_without_refresh("tests/expand/*.rs"); +} + +#[test] +#[should_panic] +pub fn fail_expect_expanded() { + // This directory doesn't have expanded files but since they're expected, the test will fail. + macrotest::expand_without_refresh("tests/no_expanded/*.rs"); +} + +#[test] +pub fn pass_args() { + macrotest::expand_args("tests/expand_args/*.rs", &["--features", "test-feature"]); +} + +#[test] +pub fn pass_expect_expanded_args() { + // If you delete one of the `.expanded.rs` files, this test will fail. + macrotest::expand_args("tests/expand_args/*.rs", &["--features", "test-feature"]); +} + +#[test] +#[should_panic] +pub fn fail_expect_expanded_args() { + // This directory doesn't have expanded files but since they're expected, the test will fail. + macrotest::expand_without_refresh_args( + "tests/no_expanded_args/*.rs", + &["--features", "test-feature"], + ); +} + +// https://github.com/eupn/macrotest/pull/61 +#[test] +pub fn pr61() { + macrotest::expand("tests/pr61/*/*.rs"); +} diff --git a/test-workspace/wrkspc/Cargo.toml b/test-workspace/wrkspc/Cargo.toml new file mode 100644 index 0000000..df73d92 --- /dev/null +++ b/test-workspace/wrkspc/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "wrkspc" +version = "0.0.0" +authors = ["Mark Van de Vyver "] +license = "Apache-2.0" +edition = "2018" +description = "A crate in a virtual workspace example" +homepage = "https://github.com/eupn/macrotest" +repository = "https://github.com/eupn/macrotest" +documentation = "https://docs.rs/macrotest" +readme = "README.md" +publish = false + +[dependencies] +wrkspc-macro = { path = "../wrkspc-macro" } + +[dev-dependencies] +wrkspc-dev = { path = "../wrkspc-dev" } diff --git a/test-workspace/wrkspc/src/lib.rs b/test-workspace/wrkspc/src/lib.rs new file mode 100644 index 0000000..2c73804 --- /dev/null +++ b/test-workspace/wrkspc/src/lib.rs @@ -0,0 +1,5 @@ +pub use wrkspc_macro::*; + +pub fn hello() { + println!("Hello World!") +} diff --git a/test-workspace/wrkspc/tests/lib.rs b/test-workspace/wrkspc/tests/lib.rs new file mode 100644 index 0000000..ead8d3b --- /dev/null +++ b/test-workspace/wrkspc/tests/lib.rs @@ -0,0 +1,4 @@ +#[test] +fn wrkspc_test() { + assert_eq!("equal", "equal") +} From 6fee44e6f39ba85a1ffe1945dc6db4d351414f46 Mon Sep 17 00:00:00 2001 From: Mark Van de Vyver Date: Mon, 28 Mar 2022 16:46:06 +1100 Subject: [PATCH 02/15] Evolve: Align folder name to README documentation Signed-off-by: Mark Van de Vyver --- {test-workspace => test-virtual}/Cargo.toml | 0 {test-workspace => test-virtual}/README.md | 0 test-virtual/test.log | 330 ++++++++++++++++++ .../wrkspc-dev/Cargo.toml | 0 .../wrkspc-dev/src/lib.rs | 0 .../wrkspc-dev/tests/lib.rs | 0 .../wrkspc-macro/.gitignore | 0 .../wrkspc-macro/Cargo.toml | 0 .../wrkspc-macro/src/lib.rs | 0 .../tests/expand/attribute.expanded.rs | 0 .../wrkspc-macro/tests/expand/attribute.rs | 0 .../tests/expand/derive.expanded.rs | 0 .../wrkspc-macro/tests/expand/derive.rs | 0 .../tests/expand/macro.expanded.rs | 0 .../wrkspc-macro/tests/expand/macro.rs | 0 .../wrkspc-macro/tests/tests.rs | 0 .../wrkspc-test/.gitignore | 0 .../wrkspc-test/Cargo.toml | 0 .../wrkspc-test/src/lib.rs | 0 .../tests/expand/first.expanded.rs | 0 .../wrkspc-test/tests/expand/first.rs | 0 .../tests/expand/fourth.expanded.rs | 0 .../wrkspc-test/tests/expand/fourth.rs | 0 .../tests/expand/second.expanded.rs | 0 .../wrkspc-test/tests/expand/second.rs | 0 .../tests/expand/third.expanded.rs | 0 .../wrkspc-test/tests/expand/third.rs | 0 .../tests/expand_args/with_args.expanded.rs | 0 .../tests/expand_args/with_args.rs | 0 .../wrkspc-test/tests/no_expanded/first.rs | 0 .../wrkspc-test/tests/no_expanded/fourth.rs | 0 .../wrkspc-test/tests/no_expanded/second.rs | 0 .../wrkspc-test/tests/no_expanded/third.rs | 0 .../tests/no_expanded_args/with_args.rs | 0 .../wrkspc-test/tests/par_tests_regression.rs | 18 + .../wrkspc-test/tests/pr61/a/test.expanded.rs | 0 .../wrkspc-test/tests/pr61/a/test.rs | 0 .../wrkspc-test/tests/pr61/b/test.expanded.rs | 0 .../wrkspc-test/tests/pr61/b/test.rs | 0 .../wrkspc-test/tests/tests.rs | 0 .../wrkspc/Cargo.toml | 0 .../wrkspc/src/lib.rs | 0 .../wrkspc/tests/lib.rs | 0 .../wrkspc-test/tests/par_tests_regression.rs | 12 - 44 files changed, 348 insertions(+), 12 deletions(-) rename {test-workspace => test-virtual}/Cargo.toml (100%) rename {test-workspace => test-virtual}/README.md (100%) create mode 100644 test-virtual/test.log rename {test-workspace => test-virtual}/wrkspc-dev/Cargo.toml (100%) rename {test-workspace => test-virtual}/wrkspc-dev/src/lib.rs (100%) rename {test-workspace => test-virtual}/wrkspc-dev/tests/lib.rs (100%) rename {test-workspace => test-virtual}/wrkspc-macro/.gitignore (100%) rename {test-workspace => test-virtual}/wrkspc-macro/Cargo.toml (100%) rename {test-workspace => test-virtual}/wrkspc-macro/src/lib.rs (100%) rename {test-workspace => test-virtual}/wrkspc-macro/tests/expand/attribute.expanded.rs (100%) rename {test-workspace => test-virtual}/wrkspc-macro/tests/expand/attribute.rs (100%) rename {test-workspace => test-virtual}/wrkspc-macro/tests/expand/derive.expanded.rs (100%) rename {test-workspace => test-virtual}/wrkspc-macro/tests/expand/derive.rs (100%) rename {test-workspace => test-virtual}/wrkspc-macro/tests/expand/macro.expanded.rs (100%) rename {test-workspace => test-virtual}/wrkspc-macro/tests/expand/macro.rs (100%) rename {test-workspace => test-virtual}/wrkspc-macro/tests/tests.rs (100%) rename {test-workspace => test-virtual}/wrkspc-test/.gitignore (100%) rename {test-workspace => test-virtual}/wrkspc-test/Cargo.toml (100%) rename {test-workspace => test-virtual}/wrkspc-test/src/lib.rs (100%) rename {test-workspace => test-virtual}/wrkspc-test/tests/expand/first.expanded.rs (100%) rename {test-workspace => test-virtual}/wrkspc-test/tests/expand/first.rs (100%) rename {test-workspace => test-virtual}/wrkspc-test/tests/expand/fourth.expanded.rs (100%) rename {test-workspace => test-virtual}/wrkspc-test/tests/expand/fourth.rs (100%) rename {test-workspace => test-virtual}/wrkspc-test/tests/expand/second.expanded.rs (100%) rename {test-workspace => test-virtual}/wrkspc-test/tests/expand/second.rs (100%) rename {test-workspace => test-virtual}/wrkspc-test/tests/expand/third.expanded.rs (100%) rename {test-workspace => test-virtual}/wrkspc-test/tests/expand/third.rs (100%) rename {test-workspace => test-virtual}/wrkspc-test/tests/expand_args/with_args.expanded.rs (100%) rename {test-workspace => test-virtual}/wrkspc-test/tests/expand_args/with_args.rs (100%) rename {test-workspace => test-virtual}/wrkspc-test/tests/no_expanded/first.rs (100%) rename {test-workspace => test-virtual}/wrkspc-test/tests/no_expanded/fourth.rs (100%) rename {test-workspace => test-virtual}/wrkspc-test/tests/no_expanded/second.rs (100%) rename {test-workspace => test-virtual}/wrkspc-test/tests/no_expanded/third.rs (100%) rename {test-workspace => test-virtual}/wrkspc-test/tests/no_expanded_args/with_args.rs (100%) create mode 100644 test-virtual/wrkspc-test/tests/par_tests_regression.rs rename {test-workspace => test-virtual}/wrkspc-test/tests/pr61/a/test.expanded.rs (100%) rename {test-workspace => test-virtual}/wrkspc-test/tests/pr61/a/test.rs (100%) rename {test-workspace => test-virtual}/wrkspc-test/tests/pr61/b/test.expanded.rs (100%) rename {test-workspace => test-virtual}/wrkspc-test/tests/pr61/b/test.rs (100%) rename {test-workspace => test-virtual}/wrkspc-test/tests/tests.rs (100%) rename {test-workspace => test-virtual}/wrkspc/Cargo.toml (100%) rename {test-workspace => test-virtual}/wrkspc/src/lib.rs (100%) rename {test-workspace => test-virtual}/wrkspc/tests/lib.rs (100%) delete mode 100644 test-workspace/wrkspc-test/tests/par_tests_regression.rs diff --git a/test-workspace/Cargo.toml b/test-virtual/Cargo.toml similarity index 100% rename from test-workspace/Cargo.toml rename to test-virtual/Cargo.toml diff --git a/test-workspace/README.md b/test-virtual/README.md similarity index 100% rename from test-workspace/README.md rename to test-virtual/README.md diff --git a/test-virtual/test.log b/test-virtual/test.log new file mode 100644 index 0000000..d1e5339 --- /dev/null +++ b/test-virtual/test.log @@ -0,0 +1,330 @@ + Compiling wrkspc-test v0.0.0 (/home/hedge/src/macrotest/test-workspace/wrkspc-test) + Finished test [unoptimized + debuginfo] target(s) in 0.77s + Running unittests (target/debug/deps/wrkspc-1f5332e22b172417) + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running tests/lib.rs (target/debug/deps/lib-d14d9e487073e3b0) + +running 1 test +test wrkspc_test ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running unittests (target/debug/deps/wrkspc_dev-dcbcfc1f695a413e) + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running tests/lib.rs (target/debug/deps/lib-0e97916292bfa7d3) + +running 1 test +test wrkspc_test ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running unittests (target/debug/deps/wrkspc_macro-70169514944d2a9b) + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running tests/tests.rs (target/debug/deps/tests-5608a6cdf865edb7) + +running 1 test +test pass ... Running 3 macro expansion tests + Updating crates.io index + Checking wrkspc-macro-tests v0.0.0 (/home/hedge/src/macrotest/test-workspace/target/tests/wrkspc-macro/macrotest000) + Finished dev [unoptimized + debuginfo] target(s) in 1.88s + +use std::prelude::rust_2018::*; +tests/expand/attribute.rs - ok +tests/expand/derive.rs - ok +tests/expand/macro.rs - ok +ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 3.34s + + Running unittests (target/debug/deps/wrkspc_test-b4113ecf2fdb355b) + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running tests/par_tests_regression.rs (target/debug/deps/par_tests_regression-6dac28f068c6540e) + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + Running tests/tests.rs (target/debug/deps/tests-c5731019421a7315) + +running 7 tests +test fail_expect_expanded - should panic ... Running 4 macro expansion tests + Checking wrkspc-test-tests v0.0.0 (/home/hedge/src/macrotest/test-workspace/target/tests/wrkspc-test/macrotest000) + Finished dev [unoptimized + debuginfo] target(s) in 0.31s + +use std::prelude::rust_2018::*; +tests/no_expanded/first.expanded.rs is expected but not found +tests/no_expanded/fourth.expanded.rs is expected but not found +tests/no_expanded/second.expanded.rs is expected but not found +tests/no_expanded/third.expanded.rs is expected but not found + + + +thread 'main' panicked at '4 of 4 tests failed', /home/hedge/src/macrotest/src/expand.rs:171:9 +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace +ok +test fail_expect_expanded_args - should panic ... Running 1 macro expansion tests + Checking wrkspc-test-tests v0.0.0 (/home/hedge/src/macrotest/test-workspace/target/tests/wrkspc-test/macrotest001) + Finished dev [unoptimized + debuginfo] target(s) in 0.29s + +use std::prelude::rust_2018::*; +tests/no_expanded_args/with_args.expanded.rs is expected but not found + + + +thread 'main' panicked at '1 of 1 tests failed', /home/hedge/src/macrotest/src/expand.rs:171:9 +ok +test pass ... Running 4 macro expansion tests + Checking wrkspc-test-tests v0.0.0 (/home/hedge/src/macrotest/test-workspace/target/tests/wrkspc-test/macrotest002) + Finished dev [unoptimized + debuginfo] target(s) in 0.40s + +use std::prelude::rust_2018::*; +tests/expand/first.rs - different! +Diff [lines: 2 added, 1 removed]: +-------------------------- + #[macro_use] + extern crate test_project; + pub fn main() { ++ Vec::new(); +- (); + } ++ +-------------------------- +tests/expand/fourth.rs - different! +Diff [lines: 8 added, 1 removed]: +-------------------------- + #[macro_use] + extern crate test_project; + pub fn main() { ++ { ++ let mut temp_vec = Vec::new(); ++ temp_vec.push(1); ++ temp_vec.push(2); ++ temp_vec.push(3); ++ temp_vec ++ }; +- (); + } ++ +-------------------------- +tests/expand/second.rs - different! +Diff [lines: 6 added, 1 removed]: +-------------------------- + #[macro_use] + extern crate test_project; + pub fn main() { ++ { ++ let mut temp_vec = Vec::new(); ++ temp_vec.push(1); ++ temp_vec ++ }; +- (); + } ++ +-------------------------- +tests/expand/third.rs - different! +Diff [lines: 7 added, 1 removed]: +-------------------------- + #[macro_use] + extern crate test_project; + pub fn main() { ++ { ++ let mut temp_vec = Vec::new(); ++ temp_vec.push(1); ++ temp_vec.push(2); ++ temp_vec ++ }; +- (); + } ++ +-------------------------- + + + +thread 'main' panicked at '4 of 4 tests failed', /home/hedge/src/macrotest/src/expand.rs:171:9 +FAILED +test pass_args ... Running 1 macro expansion tests + Checking wrkspc-test-tests v0.0.0 (/home/hedge/src/macrotest/test-workspace/target/tests/wrkspc-test/macrotest003) + Finished dev [unoptimized + debuginfo] target(s) in 0.42s + +use std::prelude::rust_2018::*; +tests/expand_args/with_args.rs - different! +Diff [lines: 8 added, 1 removed]: +-------------------------- + extern crate std; + #[macro_use] + extern crate test_project; + pub fn main() { ++ { ++ let mut temp_vec = Vec::new(); ++ temp_vec.push(1); ++ temp_vec.push(2); ++ temp_vec.push(3); ++ temp_vec ++ }; +- (); + } ++ +-------------------------- + + + +thread 'main' panicked at '1 of 1 tests failed', /home/hedge/src/macrotest/src/expand.rs:171:9 +FAILED +test pass_expect_expanded ... Running 4 macro expansion tests + Checking wrkspc-test-tests v0.0.0 (/home/hedge/src/macrotest/test-workspace/target/tests/wrkspc-test/macrotest004) + Finished dev [unoptimized + debuginfo] target(s) in 0.86s + +use std::prelude::rust_2018::*; +tests/expand/first.rs - different! +Diff [lines: 2 added, 1 removed]: +-------------------------- + #[macro_use] + extern crate test_project; + pub fn main() { ++ Vec::new(); +- (); + } ++ +-------------------------- +tests/expand/fourth.rs - different! +Diff [lines: 8 added, 1 removed]: +-------------------------- + #[macro_use] + extern crate test_project; + pub fn main() { ++ { ++ let mut temp_vec = Vec::new(); ++ temp_vec.push(1); ++ temp_vec.push(2); ++ temp_vec.push(3); ++ temp_vec ++ }; +- (); + } ++ +-------------------------- +tests/expand/second.rs - different! +Diff [lines: 6 added, 1 removed]: +-------------------------- + #[macro_use] + extern crate test_project; + pub fn main() { ++ { ++ let mut temp_vec = Vec::new(); ++ temp_vec.push(1); ++ temp_vec ++ }; +- (); + } ++ +-------------------------- +tests/expand/third.rs - different! +Diff [lines: 7 added, 1 removed]: +-------------------------- + #[macro_use] + extern crate test_project; + pub fn main() { ++ { ++ let mut temp_vec = Vec::new(); ++ temp_vec.push(1); ++ temp_vec.push(2); ++ temp_vec ++ }; +- (); + } ++ +-------------------------- + + + +thread 'main' panicked at '4 of 4 tests failed', /home/hedge/src/macrotest/src/expand.rs:171:9 +FAILED +test pass_expect_expanded_args ... Running 1 macro expansion tests + Checking wrkspc-test-tests v0.0.0 (/home/hedge/src/macrotest/test-workspace/target/tests/wrkspc-test/macrotest005) + Finished dev [unoptimized + debuginfo] target(s) in 0.55s + +use std::prelude::rust_2018::*; +tests/expand_args/with_args.rs - different! +Diff [lines: 8 added, 1 removed]: +-------------------------- + extern crate std; + #[macro_use] + extern crate test_project; + pub fn main() { ++ { ++ let mut temp_vec = Vec::new(); ++ temp_vec.push(1); ++ temp_vec.push(2); ++ temp_vec.push(3); ++ temp_vec ++ }; +- (); + } ++ +-------------------------- + + + +thread 'main' panicked at '1 of 1 tests failed', /home/hedge/src/macrotest/src/expand.rs:171:9 +FAILED +test pr61 ... Running 2 macro expansion tests + Checking wrkspc-test-tests v0.0.0 (/home/hedge/src/macrotest/test-workspace/target/tests/wrkspc-test/macrotest006) + Finished dev [unoptimized + debuginfo] target(s) in 0.41s + +use std::prelude::rust_2018::*; +tests/pr61/a/test.rs - different! +Diff [lines: 2 added, 1 removed]: +-------------------------- + #[macro_use] + extern crate test_project; + pub fn main() { ++ Vec::new(); +- (); + } ++ +-------------------------- +tests/pr61/b/test.rs - different! +Diff [lines: 2 added, 1 removed]: +-------------------------- + #[macro_use] + extern crate test_project; + pub fn main() { ++ Vec::new(); +- (); + } ++ +-------------------------- + + + +thread 'main' panicked at '2 of 2 tests failed', /home/hedge/src/macrotest/src/expand.rs:171:9 +FAILED + +failures: + +failures: + pass + pass_args + pass_expect_expanded + pass_expect_expanded_args + pr61 + +test result: FAILED. 2 passed; 5 failed; 0 ignored; 0 measured; 0 filtered out; finished in 26.09s + +error: test failed, to rerun pass '-p wrkspc-test --test tests' diff --git a/test-workspace/wrkspc-dev/Cargo.toml b/test-virtual/wrkspc-dev/Cargo.toml similarity index 100% rename from test-workspace/wrkspc-dev/Cargo.toml rename to test-virtual/wrkspc-dev/Cargo.toml diff --git a/test-workspace/wrkspc-dev/src/lib.rs b/test-virtual/wrkspc-dev/src/lib.rs similarity index 100% rename from test-workspace/wrkspc-dev/src/lib.rs rename to test-virtual/wrkspc-dev/src/lib.rs diff --git a/test-workspace/wrkspc-dev/tests/lib.rs b/test-virtual/wrkspc-dev/tests/lib.rs similarity index 100% rename from test-workspace/wrkspc-dev/tests/lib.rs rename to test-virtual/wrkspc-dev/tests/lib.rs diff --git a/test-workspace/wrkspc-macro/.gitignore b/test-virtual/wrkspc-macro/.gitignore similarity index 100% rename from test-workspace/wrkspc-macro/.gitignore rename to test-virtual/wrkspc-macro/.gitignore diff --git a/test-workspace/wrkspc-macro/Cargo.toml b/test-virtual/wrkspc-macro/Cargo.toml similarity index 100% rename from test-workspace/wrkspc-macro/Cargo.toml rename to test-virtual/wrkspc-macro/Cargo.toml diff --git a/test-workspace/wrkspc-macro/src/lib.rs b/test-virtual/wrkspc-macro/src/lib.rs similarity index 100% rename from test-workspace/wrkspc-macro/src/lib.rs rename to test-virtual/wrkspc-macro/src/lib.rs diff --git a/test-workspace/wrkspc-macro/tests/expand/attribute.expanded.rs b/test-virtual/wrkspc-macro/tests/expand/attribute.expanded.rs similarity index 100% rename from test-workspace/wrkspc-macro/tests/expand/attribute.expanded.rs rename to test-virtual/wrkspc-macro/tests/expand/attribute.expanded.rs diff --git a/test-workspace/wrkspc-macro/tests/expand/attribute.rs b/test-virtual/wrkspc-macro/tests/expand/attribute.rs similarity index 100% rename from test-workspace/wrkspc-macro/tests/expand/attribute.rs rename to test-virtual/wrkspc-macro/tests/expand/attribute.rs diff --git a/test-workspace/wrkspc-macro/tests/expand/derive.expanded.rs b/test-virtual/wrkspc-macro/tests/expand/derive.expanded.rs similarity index 100% rename from test-workspace/wrkspc-macro/tests/expand/derive.expanded.rs rename to test-virtual/wrkspc-macro/tests/expand/derive.expanded.rs diff --git a/test-workspace/wrkspc-macro/tests/expand/derive.rs b/test-virtual/wrkspc-macro/tests/expand/derive.rs similarity index 100% rename from test-workspace/wrkspc-macro/tests/expand/derive.rs rename to test-virtual/wrkspc-macro/tests/expand/derive.rs diff --git a/test-workspace/wrkspc-macro/tests/expand/macro.expanded.rs b/test-virtual/wrkspc-macro/tests/expand/macro.expanded.rs similarity index 100% rename from test-workspace/wrkspc-macro/tests/expand/macro.expanded.rs rename to test-virtual/wrkspc-macro/tests/expand/macro.expanded.rs diff --git a/test-workspace/wrkspc-macro/tests/expand/macro.rs b/test-virtual/wrkspc-macro/tests/expand/macro.rs similarity index 100% rename from test-workspace/wrkspc-macro/tests/expand/macro.rs rename to test-virtual/wrkspc-macro/tests/expand/macro.rs diff --git a/test-workspace/wrkspc-macro/tests/tests.rs b/test-virtual/wrkspc-macro/tests/tests.rs similarity index 100% rename from test-workspace/wrkspc-macro/tests/tests.rs rename to test-virtual/wrkspc-macro/tests/tests.rs diff --git a/test-workspace/wrkspc-test/.gitignore b/test-virtual/wrkspc-test/.gitignore similarity index 100% rename from test-workspace/wrkspc-test/.gitignore rename to test-virtual/wrkspc-test/.gitignore diff --git a/test-workspace/wrkspc-test/Cargo.toml b/test-virtual/wrkspc-test/Cargo.toml similarity index 100% rename from test-workspace/wrkspc-test/Cargo.toml rename to test-virtual/wrkspc-test/Cargo.toml diff --git a/test-workspace/wrkspc-test/src/lib.rs b/test-virtual/wrkspc-test/src/lib.rs similarity index 100% rename from test-workspace/wrkspc-test/src/lib.rs rename to test-virtual/wrkspc-test/src/lib.rs diff --git a/test-workspace/wrkspc-test/tests/expand/first.expanded.rs b/test-virtual/wrkspc-test/tests/expand/first.expanded.rs similarity index 100% rename from test-workspace/wrkspc-test/tests/expand/first.expanded.rs rename to test-virtual/wrkspc-test/tests/expand/first.expanded.rs diff --git a/test-workspace/wrkspc-test/tests/expand/first.rs b/test-virtual/wrkspc-test/tests/expand/first.rs similarity index 100% rename from test-workspace/wrkspc-test/tests/expand/first.rs rename to test-virtual/wrkspc-test/tests/expand/first.rs diff --git a/test-workspace/wrkspc-test/tests/expand/fourth.expanded.rs b/test-virtual/wrkspc-test/tests/expand/fourth.expanded.rs similarity index 100% rename from test-workspace/wrkspc-test/tests/expand/fourth.expanded.rs rename to test-virtual/wrkspc-test/tests/expand/fourth.expanded.rs diff --git a/test-workspace/wrkspc-test/tests/expand/fourth.rs b/test-virtual/wrkspc-test/tests/expand/fourth.rs similarity index 100% rename from test-workspace/wrkspc-test/tests/expand/fourth.rs rename to test-virtual/wrkspc-test/tests/expand/fourth.rs diff --git a/test-workspace/wrkspc-test/tests/expand/second.expanded.rs b/test-virtual/wrkspc-test/tests/expand/second.expanded.rs similarity index 100% rename from test-workspace/wrkspc-test/tests/expand/second.expanded.rs rename to test-virtual/wrkspc-test/tests/expand/second.expanded.rs diff --git a/test-workspace/wrkspc-test/tests/expand/second.rs b/test-virtual/wrkspc-test/tests/expand/second.rs similarity index 100% rename from test-workspace/wrkspc-test/tests/expand/second.rs rename to test-virtual/wrkspc-test/tests/expand/second.rs diff --git a/test-workspace/wrkspc-test/tests/expand/third.expanded.rs b/test-virtual/wrkspc-test/tests/expand/third.expanded.rs similarity index 100% rename from test-workspace/wrkspc-test/tests/expand/third.expanded.rs rename to test-virtual/wrkspc-test/tests/expand/third.expanded.rs diff --git a/test-workspace/wrkspc-test/tests/expand/third.rs b/test-virtual/wrkspc-test/tests/expand/third.rs similarity index 100% rename from test-workspace/wrkspc-test/tests/expand/third.rs rename to test-virtual/wrkspc-test/tests/expand/third.rs diff --git a/test-workspace/wrkspc-test/tests/expand_args/with_args.expanded.rs b/test-virtual/wrkspc-test/tests/expand_args/with_args.expanded.rs similarity index 100% rename from test-workspace/wrkspc-test/tests/expand_args/with_args.expanded.rs rename to test-virtual/wrkspc-test/tests/expand_args/with_args.expanded.rs diff --git a/test-workspace/wrkspc-test/tests/expand_args/with_args.rs b/test-virtual/wrkspc-test/tests/expand_args/with_args.rs similarity index 100% rename from test-workspace/wrkspc-test/tests/expand_args/with_args.rs rename to test-virtual/wrkspc-test/tests/expand_args/with_args.rs diff --git a/test-workspace/wrkspc-test/tests/no_expanded/first.rs b/test-virtual/wrkspc-test/tests/no_expanded/first.rs similarity index 100% rename from test-workspace/wrkspc-test/tests/no_expanded/first.rs rename to test-virtual/wrkspc-test/tests/no_expanded/first.rs diff --git a/test-workspace/wrkspc-test/tests/no_expanded/fourth.rs b/test-virtual/wrkspc-test/tests/no_expanded/fourth.rs similarity index 100% rename from test-workspace/wrkspc-test/tests/no_expanded/fourth.rs rename to test-virtual/wrkspc-test/tests/no_expanded/fourth.rs diff --git a/test-workspace/wrkspc-test/tests/no_expanded/second.rs b/test-virtual/wrkspc-test/tests/no_expanded/second.rs similarity index 100% rename from test-workspace/wrkspc-test/tests/no_expanded/second.rs rename to test-virtual/wrkspc-test/tests/no_expanded/second.rs diff --git a/test-workspace/wrkspc-test/tests/no_expanded/third.rs b/test-virtual/wrkspc-test/tests/no_expanded/third.rs similarity index 100% rename from test-workspace/wrkspc-test/tests/no_expanded/third.rs rename to test-virtual/wrkspc-test/tests/no_expanded/third.rs diff --git a/test-workspace/wrkspc-test/tests/no_expanded_args/with_args.rs b/test-virtual/wrkspc-test/tests/no_expanded_args/with_args.rs similarity index 100% rename from test-workspace/wrkspc-test/tests/no_expanded_args/with_args.rs rename to test-virtual/wrkspc-test/tests/no_expanded_args/with_args.rs diff --git a/test-virtual/wrkspc-test/tests/par_tests_regression.rs b/test-virtual/wrkspc-test/tests/par_tests_regression.rs new file mode 100644 index 0000000..4e66042 --- /dev/null +++ b/test-virtual/wrkspc-test/tests/par_tests_regression.rs @@ -0,0 +1,18 @@ +// The tests were interfering with each other when run in parallel. +// This regression test module will ensure that parallel use case is handled. + +// Suspend parallel test execution while we implement the integration +// test harness. +// +// #[test] +// pub fn parallel_1() { +// macrotest::expand("tests/expand/first.rs"); +// } + +// Suspend parallel test execution while we implement the integration +// test harness. +// +// #[test] +// pub fn parallel_2() { +// macrotest::expand("tests/expand/second.rs"); +// } diff --git a/test-workspace/wrkspc-test/tests/pr61/a/test.expanded.rs b/test-virtual/wrkspc-test/tests/pr61/a/test.expanded.rs similarity index 100% rename from test-workspace/wrkspc-test/tests/pr61/a/test.expanded.rs rename to test-virtual/wrkspc-test/tests/pr61/a/test.expanded.rs diff --git a/test-workspace/wrkspc-test/tests/pr61/a/test.rs b/test-virtual/wrkspc-test/tests/pr61/a/test.rs similarity index 100% rename from test-workspace/wrkspc-test/tests/pr61/a/test.rs rename to test-virtual/wrkspc-test/tests/pr61/a/test.rs diff --git a/test-workspace/wrkspc-test/tests/pr61/b/test.expanded.rs b/test-virtual/wrkspc-test/tests/pr61/b/test.expanded.rs similarity index 100% rename from test-workspace/wrkspc-test/tests/pr61/b/test.expanded.rs rename to test-virtual/wrkspc-test/tests/pr61/b/test.expanded.rs diff --git a/test-workspace/wrkspc-test/tests/pr61/b/test.rs b/test-virtual/wrkspc-test/tests/pr61/b/test.rs similarity index 100% rename from test-workspace/wrkspc-test/tests/pr61/b/test.rs rename to test-virtual/wrkspc-test/tests/pr61/b/test.rs diff --git a/test-workspace/wrkspc-test/tests/tests.rs b/test-virtual/wrkspc-test/tests/tests.rs similarity index 100% rename from test-workspace/wrkspc-test/tests/tests.rs rename to test-virtual/wrkspc-test/tests/tests.rs diff --git a/test-workspace/wrkspc/Cargo.toml b/test-virtual/wrkspc/Cargo.toml similarity index 100% rename from test-workspace/wrkspc/Cargo.toml rename to test-virtual/wrkspc/Cargo.toml diff --git a/test-workspace/wrkspc/src/lib.rs b/test-virtual/wrkspc/src/lib.rs similarity index 100% rename from test-workspace/wrkspc/src/lib.rs rename to test-virtual/wrkspc/src/lib.rs diff --git a/test-workspace/wrkspc/tests/lib.rs b/test-virtual/wrkspc/tests/lib.rs similarity index 100% rename from test-workspace/wrkspc/tests/lib.rs rename to test-virtual/wrkspc/tests/lib.rs diff --git a/test-workspace/wrkspc-test/tests/par_tests_regression.rs b/test-workspace/wrkspc-test/tests/par_tests_regression.rs deleted file mode 100644 index 7a15ffe..0000000 --- a/test-workspace/wrkspc-test/tests/par_tests_regression.rs +++ /dev/null @@ -1,12 +0,0 @@ -// The tests were interfering with each other when run in parallel. -// This regression test module will ensure that parallel use case is handled. - -#[test] -pub fn parallel_1() { - macrotest::expand("tests/expand/first.rs"); -} - -#[test] -pub fn parallel_2() { - macrotest::expand("tests/expand/second.rs"); -} From f67ac0f150765d46476eb7fd5ee4cf11264513af Mon Sep 17 00:00:00 2001 From: Mark Van de Vyver Date: Mon, 28 Mar 2022 17:05:22 +1100 Subject: [PATCH 03/15] Add: Initial Cargo test harness Running: cargo test workspace-tests correctly produces: Running src/main.rs (target/debug/deps/workspace_tests-8bdd65c7ce129a54) Setup Teardown Signed-off-by: Mark Van de Vyver --- test-virtual/wrkspc-test/Cargo.toml | 6 ++++++ test-virtual/wrkspc-test/src/main.rs | 16 ++++++++++++++++ 2 files changed, 22 insertions(+) create mode 100644 test-virtual/wrkspc-test/src/main.rs diff --git a/test-virtual/wrkspc-test/Cargo.toml b/test-virtual/wrkspc-test/Cargo.toml index a2163ff..db44595 100644 --- a/test-virtual/wrkspc-test/Cargo.toml +++ b/test-virtual/wrkspc-test/Cargo.toml @@ -12,3 +12,9 @@ test-feature = [] [dev-dependencies] macrotest = { path = "../../" } +inventory = "0.2.2" + +[[test]] +name = "workspace-tests" +path = "src/main.rs" +harness = false diff --git a/test-virtual/wrkspc-test/src/main.rs b/test-virtual/wrkspc-test/src/main.rs new file mode 100644 index 0000000..c34d6c4 --- /dev/null +++ b/test-virtual/wrkspc-test/src/main.rs @@ -0,0 +1,16 @@ +fn setup() { + println!("Setup") +} + +fn teardown() { + println!("Teardown") +} +fn main() { + // Setup test environment + setup(); + + // TODO: Run the test + + // Teardown test environment + teardown(); +} From 43a6e3d71b81c3ed281289853e346eee2113bd04 Mon Sep 17 00:00:00 2001 From: Mark Van de Vyver Date: Mon, 28 Mar 2022 17:18:47 +1100 Subject: [PATCH 04/15] Add: Test collector Failing tests remain unchanged: failures: pass pass_args pass_expect_expanded pass_expect_expanded_args pr61 Signed-off-by: Mark Van de Vyver --- test-virtual/wrkspc-test/Cargo.toml | 4 +++- test-virtual/wrkspc-test/src/main.rs | 16 +++++++++------- test-virtual/wrkspc-test/src/tests/mod.rs | 7 +++++++ 3 files changed, 19 insertions(+), 8 deletions(-) create mode 100644 test-virtual/wrkspc-test/src/tests/mod.rs diff --git a/test-virtual/wrkspc-test/Cargo.toml b/test-virtual/wrkspc-test/Cargo.toml index db44595..2b11606 100644 --- a/test-virtual/wrkspc-test/Cargo.toml +++ b/test-virtual/wrkspc-test/Cargo.toml @@ -10,9 +10,11 @@ default = [] test-feature = [] +[dependencies] +inventory = "0.2.2" + [dev-dependencies] macrotest = { path = "../../" } -inventory = "0.2.2" [[test]] name = "workspace-tests" diff --git a/test-virtual/wrkspc-test/src/main.rs b/test-virtual/wrkspc-test/src/main.rs index c34d6c4..5aebb39 100644 --- a/test-virtual/wrkspc-test/src/main.rs +++ b/test-virtual/wrkspc-test/src/main.rs @@ -1,16 +1,18 @@ +pub mod tests; + fn setup() { - println!("Setup") + println!("Setup") } fn teardown() { - println!("Teardown") + println!("Teardown") } fn main() { - // Setup test environment - setup(); + // Setup test environment + setup(); - // TODO: Run the test + // TODO: Run the test - // Teardown test environment - teardown(); + // Teardown test environment + teardown(); } diff --git a/test-virtual/wrkspc-test/src/tests/mod.rs b/test-virtual/wrkspc-test/src/tests/mod.rs new file mode 100644 index 0000000..0fed5d8 --- /dev/null +++ b/test-virtual/wrkspc-test/src/tests/mod.rs @@ -0,0 +1,7 @@ +#[derive(Debug)] +pub struct IntegrationTest { + pub name: &'static str, + pub test_fn: fn(), +} + +inventory::collect!(IntegrationTest); From 601d5bbbd4d3038d14851bfce86333e1643e4ea9 Mon Sep 17 00:00:00 2001 From: Mark Van de Vyver Date: Mon, 28 Mar 2022 18:15:47 +1100 Subject: [PATCH 05/15] Add: Edition 2021 to get green Signed-off-by: Mark Van de Vyver --- test-virtual/wrkspc-dev/Cargo.toml | 2 +- test-virtual/wrkspc-macro/Cargo.toml | 4 ++-- test-virtual/wrkspc-test/Cargo.toml | 13 ++++++------- .../wrkspc-test/{src => integration}/main.rs | 0 .../wrkspc-test/{src => integration}/tests/mod.rs | 0 test-virtual/wrkspc/Cargo.toml | 2 +- 6 files changed, 10 insertions(+), 11 deletions(-) rename test-virtual/wrkspc-test/{src => integration}/main.rs (100%) rename test-virtual/wrkspc-test/{src => integration}/tests/mod.rs (100%) diff --git a/test-virtual/wrkspc-dev/Cargo.toml b/test-virtual/wrkspc-dev/Cargo.toml index b23ba1a..53c58e0 100644 --- a/test-virtual/wrkspc-dev/Cargo.toml +++ b/test-virtual/wrkspc-dev/Cargo.toml @@ -3,7 +3,7 @@ name = "wrkspc-dev" version = "0.0.0" authors = ["Mark Van de Vyver "] license = "Apache-2.0" -edition = "2018" +edition = "2021" description = "A development crate in a virtual workspace example" homepage = "https://github.com/eupn/macrotest" repository = "https://github.com/eupn/macrotest" diff --git a/test-virtual/wrkspc-macro/Cargo.toml b/test-virtual/wrkspc-macro/Cargo.toml index 898594f..910e0e4 100644 --- a/test-virtual/wrkspc-macro/Cargo.toml +++ b/test-virtual/wrkspc-macro/Cargo.toml @@ -2,7 +2,7 @@ name = "wrkspc-macro" version = "0.0.0" authors = ["eupn "] -edition = "2018" +edition = "2021" publish = false [lib] @@ -14,4 +14,4 @@ proc-macro2 = "1.0" syn = "1.0" [dev-dependencies] -macrotest = { path = "../../" } +macrotest = { path = "../../../macrotest" } diff --git a/test-virtual/wrkspc-test/Cargo.toml b/test-virtual/wrkspc-test/Cargo.toml index 2b11606..2269b03 100644 --- a/test-virtual/wrkspc-test/Cargo.toml +++ b/test-virtual/wrkspc-test/Cargo.toml @@ -1,7 +1,8 @@ [package] name = "wrkspc-test" version = "0.0.0" -edition = "2018" +edition = "2021" +publish = false [lib] @@ -10,13 +11,11 @@ default = [] test-feature = [] -[dependencies] -inventory = "0.2.2" - [dev-dependencies] -macrotest = { path = "../../" } +macrotest = { path = "../../../macrotest" } +inventory = "0.2.2" [[test]] -name = "workspace-tests" -path = "src/main.rs" +name = "integration-tests" +path = "integration/main.rs" harness = false diff --git a/test-virtual/wrkspc-test/src/main.rs b/test-virtual/wrkspc-test/integration/main.rs similarity index 100% rename from test-virtual/wrkspc-test/src/main.rs rename to test-virtual/wrkspc-test/integration/main.rs diff --git a/test-virtual/wrkspc-test/src/tests/mod.rs b/test-virtual/wrkspc-test/integration/tests/mod.rs similarity index 100% rename from test-virtual/wrkspc-test/src/tests/mod.rs rename to test-virtual/wrkspc-test/integration/tests/mod.rs diff --git a/test-virtual/wrkspc/Cargo.toml b/test-virtual/wrkspc/Cargo.toml index df73d92..16c3e32 100644 --- a/test-virtual/wrkspc/Cargo.toml +++ b/test-virtual/wrkspc/Cargo.toml @@ -3,7 +3,7 @@ name = "wrkspc" version = "0.0.0" authors = ["Mark Van de Vyver "] license = "Apache-2.0" -edition = "2018" +edition = "2021" description = "A crate in a virtual workspace example" homepage = "https://github.com/eupn/macrotest" repository = "https://github.com/eupn/macrotest" From 730f13fba3bafe1532a34f7d6c311cb6ee4c7702 Mon Sep 17 00:00:00 2001 From: Mark Van de Vyver Date: Mon, 28 Mar 2022 18:33:47 +1100 Subject: [PATCH 06/15] Add: Basic test - green Correctly produces: Setup Running basic test Teardown Signed-off-by: Mark Van de Vyver --- test-virtual/wrkspc-test/integration/main.rs | 7 ++++++- test-virtual/wrkspc-test/integration/tests/basic.rs | 10 ++++++++++ test-virtual/wrkspc-test/integration/tests/mod.rs | 2 ++ 3 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 test-virtual/wrkspc-test/integration/tests/basic.rs diff --git a/test-virtual/wrkspc-test/integration/main.rs b/test-virtual/wrkspc-test/integration/main.rs index 5aebb39..75be913 100644 --- a/test-virtual/wrkspc-test/integration/main.rs +++ b/test-virtual/wrkspc-test/integration/main.rs @@ -1,5 +1,7 @@ pub mod tests; +use tests::IntegrationTest; + fn setup() { println!("Setup") } @@ -11,7 +13,10 @@ fn main() { // Setup test environment setup(); - // TODO: Run the test + // Run the tests + for t in inventory::iter:: { + (t.test_fn)() + } // Teardown test environment teardown(); diff --git a/test-virtual/wrkspc-test/integration/tests/basic.rs b/test-virtual/wrkspc-test/integration/tests/basic.rs new file mode 100644 index 0000000..d864bed --- /dev/null +++ b/test-virtual/wrkspc-test/integration/tests/basic.rs @@ -0,0 +1,10 @@ +use super::IntegrationTest; + +fn basic_test() { + println!("Running basic test") +} + +inventory::submit!(IntegrationTest { + name: "basic", + test_fn: basic_test +}); diff --git a/test-virtual/wrkspc-test/integration/tests/mod.rs b/test-virtual/wrkspc-test/integration/tests/mod.rs index 0fed5d8..d22804c 100644 --- a/test-virtual/wrkspc-test/integration/tests/mod.rs +++ b/test-virtual/wrkspc-test/integration/tests/mod.rs @@ -1,3 +1,5 @@ +pub mod basic; + #[derive(Debug)] pub struct IntegrationTest { pub name: &'static str, From a39a7532d173bc8adea0a304352228ad898cef54 Mon Sep 17 00:00:00 2001 From: Mark Van de Vyver Date: Mon, 28 Mar 2022 20:26:37 +1100 Subject: [PATCH 07/15] Add: Minimal reproducible issue #74 Signed-off-by: Mark Van de Vyver --- test-virtual/wrkspc-test/Cargo.toml | 6 +++ test-virtual/wrkspc-test/integration/main.rs | 4 ++ .../wrkspc-test/integration/tests/basic.rs | 8 ++-- .../wrkspc-test/integration/tests/feature.rs | 47 +++++++++++++++++++ .../feature/expanded/with_args.expanded.rs | 12 +++++ .../tests/feature/expanded/with_args.rs | 8 ++++ .../tests/feature/unchanged/with_args.rs | 8 ++++ .../wrkspc-test/integration/tests/mod.rs | 1 + 8 files changed, 90 insertions(+), 4 deletions(-) create mode 100644 test-virtual/wrkspc-test/integration/tests/feature.rs create mode 100644 test-virtual/wrkspc-test/integration/tests/feature/expanded/with_args.expanded.rs create mode 100644 test-virtual/wrkspc-test/integration/tests/feature/expanded/with_args.rs create mode 100644 test-virtual/wrkspc-test/integration/tests/feature/unchanged/with_args.rs diff --git a/test-virtual/wrkspc-test/Cargo.toml b/test-virtual/wrkspc-test/Cargo.toml index 2269b03..06f232f 100644 --- a/test-virtual/wrkspc-test/Cargo.toml +++ b/test-virtual/wrkspc-test/Cargo.toml @@ -19,3 +19,9 @@ inventory = "0.2.2" name = "integration-tests" path = "integration/main.rs" harness = false + +[[test]] +name = "defaults-indev-tokio" +path = "integration/feature.rs" +harness = false +required-features = ["test-feature"] diff --git a/test-virtual/wrkspc-test/integration/main.rs b/test-virtual/wrkspc-test/integration/main.rs index 75be913..a577dcd 100644 --- a/test-virtual/wrkspc-test/integration/main.rs +++ b/test-virtual/wrkspc-test/integration/main.rs @@ -9,6 +9,10 @@ fn setup() { fn teardown() { println!("Teardown") } +// NOTE: +// When this code is in src/main.rs, it is executed by `cargo test -- --list`. +// In such cases you could guard it: +// #[cfg(feature = "integration")] fn main() { // Setup test environment setup(); diff --git a/test-virtual/wrkspc-test/integration/tests/basic.rs b/test-virtual/wrkspc-test/integration/tests/basic.rs index d864bed..b19d347 100644 --- a/test-virtual/wrkspc-test/integration/tests/basic.rs +++ b/test-virtual/wrkspc-test/integration/tests/basic.rs @@ -1,10 +1,10 @@ -use super::IntegrationTest; +use crate::tests::IntegrationTest; fn basic_test() { - println!("Running basic test") + println!("Running basic test") } inventory::submit!(IntegrationTest { - name: "basic", - test_fn: basic_test + name: "basic", + test_fn: basic_test }); diff --git a/test-virtual/wrkspc-test/integration/tests/feature.rs b/test-virtual/wrkspc-test/integration/tests/feature.rs new file mode 100644 index 0000000..6c9cefe --- /dev/null +++ b/test-virtual/wrkspc-test/integration/tests/feature.rs @@ -0,0 +1,47 @@ +use crate::tests::IntegrationTest; + +fn feature_test() { + println!("Running feature test") +} + +inventory::submit!(IntegrationTest { + name: "feature", + test_fn: feature_test +}); + +pub fn pass_args() { + macrotest::expand_args( + "integration/tests/feature/expanded/*.rs", + &["--features", "test-feature"], + ); +} +inventory::submit!(IntegrationTest { + name: "feature", + test_fn: pass_args +}); + +pub fn pass_expect_expanded_args() { + // If you delete one of the `.expanded.rs` files, this test will fail. + macrotest::expand_args( + "integration/tests/feature/expanded/*.rs", + &["--features", "test-feature"], + ); +} +inventory::submit!(IntegrationTest { + name: "feature", + test_fn: feature_test +}); + +// Suspended panicky tests for the moment +// +// pub fn fail_expect_expanded_args() { +// // This directory doesn't have expanded files but since they're expected, the test will fail. +// macrotest::expand_without_refresh_args( +// "integration/tests/feature/unchanged/*.rs", +// &["--features", "test-feature"], +// ); +// } +// inventory::submit!(IntegrationTest { +// name: "feature", +// test_fn: fail_expect_expanded_args +// }); diff --git a/test-virtual/wrkspc-test/integration/tests/feature/expanded/with_args.expanded.rs b/test-virtual/wrkspc-test/integration/tests/feature/expanded/with_args.expanded.rs new file mode 100644 index 0000000..1884aa0 --- /dev/null +++ b/test-virtual/wrkspc-test/integration/tests/feature/expanded/with_args.expanded.rs @@ -0,0 +1,12 @@ +extern crate std; +#[macro_use] +extern crate test_project; +pub fn main() { + { + let mut temp_vec = Vec::new(); + temp_vec.push(1); + temp_vec.push(2); + temp_vec.push(3); + temp_vec + }; +} diff --git a/test-virtual/wrkspc-test/integration/tests/feature/expanded/with_args.rs b/test-virtual/wrkspc-test/integration/tests/feature/expanded/with_args.rs new file mode 100644 index 0000000..dc17120 --- /dev/null +++ b/test-virtual/wrkspc-test/integration/tests/feature/expanded/with_args.rs @@ -0,0 +1,8 @@ +#![cfg(feature = "test-feature")] + +#[macro_use] +extern crate test_project; + +pub fn main() { + test_feature_vec![1, 2, 3]; +} diff --git a/test-virtual/wrkspc-test/integration/tests/feature/unchanged/with_args.rs b/test-virtual/wrkspc-test/integration/tests/feature/unchanged/with_args.rs new file mode 100644 index 0000000..dc17120 --- /dev/null +++ b/test-virtual/wrkspc-test/integration/tests/feature/unchanged/with_args.rs @@ -0,0 +1,8 @@ +#![cfg(feature = "test-feature")] + +#[macro_use] +extern crate test_project; + +pub fn main() { + test_feature_vec![1, 2, 3]; +} diff --git a/test-virtual/wrkspc-test/integration/tests/mod.rs b/test-virtual/wrkspc-test/integration/tests/mod.rs index d22804c..605994e 100644 --- a/test-virtual/wrkspc-test/integration/tests/mod.rs +++ b/test-virtual/wrkspc-test/integration/tests/mod.rs @@ -1,4 +1,5 @@ pub mod basic; +pub mod feature; #[derive(Debug)] pub struct IntegrationTest { From eeab5eccb274d3beb837b67f4869c84793fc2365 Mon Sep 17 00:00:00 2001 From: Mark Van de Vyver Date: Mon, 11 Mar 2024 08:58:26 +1100 Subject: [PATCH 08/15] [Evolve][Doc] Align with upstream project description --- test-virtual/README.md | 5 +- test-virtual/test.log | 316 +++-------------------------------------- 2 files changed, 26 insertions(+), 295 deletions(-) diff --git a/test-virtual/README.md b/test-virtual/README.md index 9a325a6..8e09f59 100644 --- a/test-virtual/README.md +++ b/test-virtual/README.md @@ -1,4 +1,4 @@ -# `test-project` +# `test-virtual` This is an example virtual-workspace that contains crates: @@ -11,7 +11,8 @@ Where each crate is: - `wrkspc`: A "Hello world" style library (for release as a crate). - `wrkspc-dev`: A "Hello world" style library for development (not for release). -- `wrkspc-macro`: The `test-promacro-project` adjusted to fit into the workspace plugin-test harness. +- `wrkspc-macro`: The `test-promacro-project` adjusted to fit into the workspace plugin-test harness. This crate provides a declarative `test_vec![]` macro +to test its expansion under the [tests](tests) directory with [`macrostest`](https://crates.io/crates/macrotest). - `wrkspc-test`: The `test-project` adjusted to fit into the workspace plugin-test harness. Test harness for integration tests as plugins, is per the [Infinyon/Fluvio](https://www.infinyon.com/blog/2021/04/rust-custom-test-harness/) setup. diff --git a/test-virtual/test.log b/test-virtual/test.log index d1e5339..917cd37 100644 --- a/test-virtual/test.log +++ b/test-virtual/test.log @@ -1,330 +1,60 @@ - Compiling wrkspc-test v0.0.0 (/home/hedge/src/macrotest/test-workspace/wrkspc-test) - Finished test [unoptimized + debuginfo] target(s) in 0.77s - Running unittests (target/debug/deps/wrkspc-1f5332e22b172417) + Compiling wrkspc-test v0.0.0 (/home/hedge/src/macrotest/test-virtual/wrkspc-test) + Finished test [unoptimized + debuginfo] target(s) in 1.88s + Running unittests (target/debug/deps/wrkspc-c42e7841a2166c46) running 0 tests test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s - Running tests/lib.rs (target/debug/deps/lib-d14d9e487073e3b0) + Running tests/lib.rs (target/debug/deps/lib-6b376d4406ebc397) -running 1 test -test wrkspc_test ... ok +running 0 tests -test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 1 filtered out; finished in 0.00s - Running unittests (target/debug/deps/wrkspc_dev-dcbcfc1f695a413e) + Running unittests (target/debug/deps/wrkspc_dev-8016f768612e755a) running 0 tests test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s - Running tests/lib.rs (target/debug/deps/lib-0e97916292bfa7d3) + Running tests/lib.rs (target/debug/deps/lib-8059e559b0ae9056) -running 1 test -test wrkspc_test ... ok +running 0 tests -test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 1 filtered out; finished in 0.00s - Running unittests (target/debug/deps/wrkspc_macro-70169514944d2a9b) + Running unittests (target/debug/deps/wrkspc_macro-5238f20639a08243) running 0 tests test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s - Running tests/tests.rs (target/debug/deps/tests-5608a6cdf865edb7) - -running 1 test -test pass ... Running 3 macro expansion tests - Updating crates.io index - Checking wrkspc-macro-tests v0.0.0 (/home/hedge/src/macrotest/test-workspace/target/tests/wrkspc-macro/macrotest000) - Finished dev [unoptimized + debuginfo] target(s) in 1.88s - -use std::prelude::rust_2018::*; -tests/expand/attribute.rs - ok -tests/expand/derive.rs - ok -tests/expand/macro.rs - ok -ok - -test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 3.34s - - Running unittests (target/debug/deps/wrkspc_test-b4113ecf2fdb355b) + Running tests/tests.rs (target/debug/deps/tests-d4e63bc64c0942af) running 0 tests -test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 1 filtered out; finished in 0.00s - Running tests/par_tests_regression.rs (target/debug/deps/par_tests_regression-6dac28f068c6540e) + Running unittests (target/debug/deps/wrkspc_test-86138e2ad1f9ee9c) running 0 tests test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s - Running tests/tests.rs (target/debug/deps/tests-c5731019421a7315) - -running 7 tests -test fail_expect_expanded - should panic ... Running 4 macro expansion tests - Checking wrkspc-test-tests v0.0.0 (/home/hedge/src/macrotest/test-workspace/target/tests/wrkspc-test/macrotest000) - Finished dev [unoptimized + debuginfo] target(s) in 0.31s - -use std::prelude::rust_2018::*; -tests/no_expanded/first.expanded.rs is expected but not found -tests/no_expanded/fourth.expanded.rs is expected but not found -tests/no_expanded/second.expanded.rs is expected but not found -tests/no_expanded/third.expanded.rs is expected but not found - - - -thread 'main' panicked at '4 of 4 tests failed', /home/hedge/src/macrotest/src/expand.rs:171:9 -note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace -ok -test fail_expect_expanded_args - should panic ... Running 1 macro expansion tests - Checking wrkspc-test-tests v0.0.0 (/home/hedge/src/macrotest/test-workspace/target/tests/wrkspc-test/macrotest001) - Finished dev [unoptimized + debuginfo] target(s) in 0.29s - -use std::prelude::rust_2018::*; -tests/no_expanded_args/with_args.expanded.rs is expected but not found - - - -thread 'main' panicked at '1 of 1 tests failed', /home/hedge/src/macrotest/src/expand.rs:171:9 -ok -test pass ... Running 4 macro expansion tests - Checking wrkspc-test-tests v0.0.0 (/home/hedge/src/macrotest/test-workspace/target/tests/wrkspc-test/macrotest002) - Finished dev [unoptimized + debuginfo] target(s) in 0.40s - -use std::prelude::rust_2018::*; -tests/expand/first.rs - different! -Diff [lines: 2 added, 1 removed]: --------------------------- - #[macro_use] - extern crate test_project; - pub fn main() { -+ Vec::new(); -- (); - } -+ --------------------------- -tests/expand/fourth.rs - different! -Diff [lines: 8 added, 1 removed]: --------------------------- - #[macro_use] - extern crate test_project; - pub fn main() { -+ { -+ let mut temp_vec = Vec::new(); -+ temp_vec.push(1); -+ temp_vec.push(2); -+ temp_vec.push(3); -+ temp_vec -+ }; -- (); - } -+ --------------------------- -tests/expand/second.rs - different! -Diff [lines: 6 added, 1 removed]: --------------------------- - #[macro_use] - extern crate test_project; - pub fn main() { -+ { -+ let mut temp_vec = Vec::new(); -+ temp_vec.push(1); -+ temp_vec -+ }; -- (); - } -+ --------------------------- -tests/expand/third.rs - different! -Diff [lines: 7 added, 1 removed]: --------------------------- - #[macro_use] - extern crate test_project; - pub fn main() { -+ { -+ let mut temp_vec = Vec::new(); -+ temp_vec.push(1); -+ temp_vec.push(2); -+ temp_vec -+ }; -- (); - } -+ --------------------------- - - - -thread 'main' panicked at '4 of 4 tests failed', /home/hedge/src/macrotest/src/expand.rs:171:9 -FAILED -test pass_args ... Running 1 macro expansion tests - Checking wrkspc-test-tests v0.0.0 (/home/hedge/src/macrotest/test-workspace/target/tests/wrkspc-test/macrotest003) - Finished dev [unoptimized + debuginfo] target(s) in 0.42s - -use std::prelude::rust_2018::*; -tests/expand_args/with_args.rs - different! -Diff [lines: 8 added, 1 removed]: --------------------------- - extern crate std; - #[macro_use] - extern crate test_project; - pub fn main() { -+ { -+ let mut temp_vec = Vec::new(); -+ temp_vec.push(1); -+ temp_vec.push(2); -+ temp_vec.push(3); -+ temp_vec -+ }; -- (); - } -+ --------------------------- - - - -thread 'main' panicked at '1 of 1 tests failed', /home/hedge/src/macrotest/src/expand.rs:171:9 -FAILED -test pass_expect_expanded ... Running 4 macro expansion tests - Checking wrkspc-test-tests v0.0.0 (/home/hedge/src/macrotest/test-workspace/target/tests/wrkspc-test/macrotest004) - Finished dev [unoptimized + debuginfo] target(s) in 0.86s + Running integration/main.rs (target/debug/deps/integration_tests-3f75cfd9c75954c7) +Setup +Running 1 macro expansion tests + Checking wrkspc-test-tests v0.0.0 (/home/hedge/src/macrotest/test-virtual/target/tests/wrkspc-test/macrotest000) + Finished dev [unoptimized + debuginfo] target(s) in 0.21s use std::prelude::rust_2018::*; -tests/expand/first.rs - different! -Diff [lines: 2 added, 1 removed]: --------------------------- - #[macro_use] - extern crate test_project; - pub fn main() { -+ Vec::new(); -- (); - } -+ --------------------------- -tests/expand/fourth.rs - different! -Diff [lines: 8 added, 1 removed]: --------------------------- - #[macro_use] - extern crate test_project; - pub fn main() { -+ { -+ let mut temp_vec = Vec::new(); -+ temp_vec.push(1); -+ temp_vec.push(2); -+ temp_vec.push(3); -+ temp_vec -+ }; -- (); - } -+ --------------------------- -tests/expand/second.rs - different! -Diff [lines: 6 added, 1 removed]: --------------------------- - #[macro_use] - extern crate test_project; - pub fn main() { -+ { -+ let mut temp_vec = Vec::new(); -+ temp_vec.push(1); -+ temp_vec -+ }; -- (); - } -+ --------------------------- -tests/expand/third.rs - different! -Diff [lines: 7 added, 1 removed]: --------------------------- - #[macro_use] - extern crate test_project; - pub fn main() { -+ { -+ let mut temp_vec = Vec::new(); -+ temp_vec.push(1); -+ temp_vec.push(2); -+ temp_vec -+ }; -- (); - } -+ --------------------------- +Expansion error: +error: Package `wrkspc-test-tests v0.0.0 (/home/hedge/src/macrotest/test-virtual/target/tests/wrkspc-test/macrotest000)` does not have the feature `test-feature` -thread 'main' panicked at '4 of 4 tests failed', /home/hedge/src/macrotest/src/expand.rs:171:9 -FAILED -test pass_expect_expanded_args ... Running 1 macro expansion tests - Checking wrkspc-test-tests v0.0.0 (/home/hedge/src/macrotest/test-workspace/target/tests/wrkspc-test/macrotest005) - Finished dev [unoptimized + debuginfo] target(s) in 0.55s - -use std::prelude::rust_2018::*; -tests/expand_args/with_args.rs - different! -Diff [lines: 8 added, 1 removed]: --------------------------- - extern crate std; - #[macro_use] - extern crate test_project; - pub fn main() { -+ { -+ let mut temp_vec = Vec::new(); -+ temp_vec.push(1); -+ temp_vec.push(2); -+ temp_vec.push(3); -+ temp_vec -+ }; -- (); - } -+ --------------------------- - - thread 'main' panicked at '1 of 1 tests failed', /home/hedge/src/macrotest/src/expand.rs:171:9 -FAILED -test pr61 ... Running 2 macro expansion tests - Checking wrkspc-test-tests v0.0.0 (/home/hedge/src/macrotest/test-workspace/target/tests/wrkspc-test/macrotest006) - Finished dev [unoptimized + debuginfo] target(s) in 0.41s - -use std::prelude::rust_2018::*; -tests/pr61/a/test.rs - different! -Diff [lines: 2 added, 1 removed]: --------------------------- - #[macro_use] - extern crate test_project; - pub fn main() { -+ Vec::new(); -- (); - } -+ --------------------------- -tests/pr61/b/test.rs - different! -Diff [lines: 2 added, 1 removed]: --------------------------- - #[macro_use] - extern crate test_project; - pub fn main() { -+ Vec::new(); -- (); - } -+ --------------------------- - - - -thread 'main' panicked at '2 of 2 tests failed', /home/hedge/src/macrotest/src/expand.rs:171:9 -FAILED - -failures: - -failures: - pass - pass_args - pass_expect_expanded - pass_expect_expanded_args - pr61 - -test result: FAILED. 2 passed; 5 failed; 0 ignored; 0 measured; 0 filtered out; finished in 26.09s - -error: test failed, to rerun pass '-p wrkspc-test --test tests' +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace +error: test failed, to rerun pass '-p wrkspc-test --test integration-tests' From 79b483f5b3054d70531ed6b52bff55fe9571bf29 Mon Sep 17 00:00:00 2001 From: Mark Van de Vyver Date: Mon, 11 Mar 2024 21:54:46 +1100 Subject: [PATCH 09/15] Add new files and update Cargo.toml Signed-off-by: Mark Van de Vyver --- Cargo.toml | 2 +- test-virtual/Cargo.toml | 44 +++- test-virtual/cargo-test.log | 202 ++++++++++++++++++ test-virtual/{wrkspc => }/src/lib.rs | 0 test-virtual/{wrkspc => }/tests/lib.rs | 0 test-virtual/wrkspc-dev/Cargo.toml | 21 +- test-virtual/wrkspc-macro/Cargo.toml | 24 ++- test-virtual/wrkspc-test/Cargo.toml | 31 ++- test-virtual/wrkspc-test/cargo-test.log | 0 .../feature/expanded/with_args.expanded.rs | 12 -- .../tests/feature/unchanged/with_args.rs | 8 - test-virtual/wrkspc-test/src/lib.rs | 10 +- .../wrkspc-test/{integration => src}/main.rs | 5 +- test-virtual/wrkspc-test/src/prelude.rs | 1 + .../{integration => src}/tests/basic.rs | 2 +- .../{integration => src}/tests/feature.rs | 31 ++- .../src/tests/feature/expanded/with_args.rs | 9 + .../feature/unchanged}/with_args.expanded.rs | 1 + .../tests/feature/unchanged}/with_args.rs | 0 .../{integration => src}/tests/mod.rs | 6 + .../tests/expand_args/with_args.rs | 4 +- .../wrkspc-test/tests/no_expanded/first.rs | 2 +- .../wrkspc-test/tests/no_expanded/fourth.rs | 2 +- .../wrkspc-test/tests/no_expanded/second.rs | 2 +- .../wrkspc-test/tests/no_expanded/third.rs | 2 +- .../tests/no_expanded_args/with_args.rs | 2 +- .../wrkspc-test/tests/pr61/a/test.expanded.rs | 2 +- test-virtual/wrkspc-test/tests/pr61/a/test.rs | 2 +- .../wrkspc-test/tests/pr61/b/test.expanded.rs | 2 +- test-virtual/wrkspc-test/tests/pr61/b/test.rs | 2 +- test-virtual/wrkspc-test/tests/tests.rs | 38 ++-- test-virtual/wrkspc/Cargo.toml | 18 -- 32 files changed, 365 insertions(+), 122 deletions(-) create mode 100644 test-virtual/cargo-test.log rename test-virtual/{wrkspc => }/src/lib.rs (100%) rename test-virtual/{wrkspc => }/tests/lib.rs (100%) create mode 100644 test-virtual/wrkspc-test/cargo-test.log delete mode 100644 test-virtual/wrkspc-test/integration/tests/feature/expanded/with_args.expanded.rs delete mode 100644 test-virtual/wrkspc-test/integration/tests/feature/unchanged/with_args.rs rename test-virtual/wrkspc-test/{integration => src}/main.rs (87%) create mode 100644 test-virtual/wrkspc-test/src/prelude.rs rename test-virtual/wrkspc-test/{integration => src}/tests/basic.rs (80%) rename test-virtual/wrkspc-test/{integration => src}/tests/feature.rs (59%) create mode 100644 test-virtual/wrkspc-test/src/tests/feature/expanded/with_args.rs rename test-virtual/wrkspc-test/{tests/expand_args => src/tests/feature/unchanged}/with_args.expanded.rs (92%) rename test-virtual/wrkspc-test/{integration/tests/feature/expanded => src/tests/feature/unchanged}/with_args.rs (100%) rename test-virtual/wrkspc-test/{integration => src}/tests/mod.rs (59%) delete mode 100644 test-virtual/wrkspc/Cargo.toml diff --git a/Cargo.toml b/Cargo.toml index fd3a79c..05e5463 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ name = "macrotest" version = "1.0.9" # remember to update in lib.rs authors = ["eupn "] -edition = "2018" +edition = "2021" rust-version = "1.56" license = "MIT OR Apache-2.0" readme = "README.md" diff --git a/test-virtual/Cargo.toml b/test-virtual/Cargo.toml index f33c761..7d25efd 100644 --- a/test-virtual/Cargo.toml +++ b/test-virtual/Cargo.toml @@ -1,7 +1,49 @@ [workspace] +resolver = "2" members = [ "wrkspc-dev", "wrkspc-macro", "wrkspc-test", - "wrkspc", ] + +[workspace.package] +version = "0.0.0" +authors = ["eupn ", "Mark Van de Vyver "] +license = "Apache-2.0" +edition = "2021" +rust-version = "1.56" +description = "A virtual workspace example for macrotest" +homepage = "https://github.com/eupn/macrotest" +repository = "https://github.com/eupn/macrotest" +documentation = "https://docs.rs/macrotest" +readme = "README.md" +publish = false + +[workspace.dependencies] +wrkspc-dev = { path = "wrkspc-dev" } +wrkspc-macro = { path = "wrkspc-macro" } +wrkspc-test = { path = "wrkspc-test" } + +macrotest = { path = "../" } + +inventory = "0.3" +proc-macro2 = "1.0" +quote = "1" +syn = "2.0" + +[package] +name = "wrkspc" +version.workspace = true +authors.workspace = true +edition.workspace = true +rust-version.workspace = true +description.workspace = true +documentation.workspace = true +homepage.workspace = true +repository.workspace = true +license.workspace = true +readme.workspace = true +publish = false + +[dependencies] +wrkspc-macro.workspace = true diff --git a/test-virtual/cargo-test.log b/test-virtual/cargo-test.log new file mode 100644 index 0000000..28bea78 --- /dev/null +++ b/test-virtual/cargo-test.log @@ -0,0 +1,202 @@ + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s + + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + +Setup +Running basic test +Running 1 macro expansion tests +Running feature test +Teardown + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + +running 4 tests +test pass ... FAILED +test fail_expect_expanded - should panic ... ok +test pr61 ... FAILED +test pass_expect_expanded ... FAILED + +failures: + +---- pass stdout ---- +Running 4 macro expansion tests +tests/expand/first.rs - different! +Diff [lines: 1 added, 1 removed]: +-------------------------- + #[macro_use] + extern crate test_project; + pub fn main() { ++ Vec::new(); +- (); + } + +-------------------------- +tests/expand/fourth.rs - different! +Diff [lines: 7 added, 1 removed]: +-------------------------- + #[macro_use] + extern crate test_project; + pub fn main() { ++ { ++ let mut temp_vec = Vec::new(); ++ temp_vec.push(1); ++ temp_vec.push(2); ++ temp_vec.push(3); ++ temp_vec ++ }; +- (); + } + +-------------------------- +tests/expand/second.rs - different! +Diff [lines: 5 added, 1 removed]: +-------------------------- + #[macro_use] + extern crate test_project; + pub fn main() { ++ { ++ let mut temp_vec = Vec::new(); ++ temp_vec.push(1); ++ temp_vec ++ }; +- (); + } + +-------------------------- +tests/expand/third.rs - different! +Diff [lines: 6 added, 1 removed]: +-------------------------- + #[macro_use] + extern crate test_project; + pub fn main() { ++ { ++ let mut temp_vec = Vec::new(); ++ temp_vec.push(1); ++ temp_vec.push(2); ++ temp_vec ++ }; +- (); + } + +-------------------------- + + + +thread 'pass' panicked at /home/hedge/src/macrotest/src/expand.rs:173:9: +4 of 4 tests failed +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace + +---- pr61 stdout ---- +Running 2 macro expansion tests +tests/pr61/a/test.rs - different! +Diff [lines: 1 added, 1 removed]: +-------------------------- + #[macro_use] + extern crate test_virtual; + pub fn main() { ++ Vec::new(); +- (); + } + +-------------------------- +tests/pr61/b/test.rs - different! +Diff [lines: 1 added, 1 removed]: +-------------------------- + #[macro_use] + extern crate test_virtual; + pub fn main() { ++ Vec::new(); +- (); + } + +-------------------------- + + + +thread 'pr61' panicked at /home/hedge/src/macrotest/src/expand.rs:173:9: +2 of 2 tests failed + +---- pass_expect_expanded stdout ---- +Running 4 macro expansion tests +tests/expand/first.rs - different! +Diff [lines: 1 added, 1 removed]: +-------------------------- + #[macro_use] + extern crate test_project; + pub fn main() { ++ Vec::new(); +- (); + } + +-------------------------- +tests/expand/fourth.rs - different! +Diff [lines: 7 added, 1 removed]: +-------------------------- + #[macro_use] + extern crate test_project; + pub fn main() { ++ { ++ let mut temp_vec = Vec::new(); ++ temp_vec.push(1); ++ temp_vec.push(2); ++ temp_vec.push(3); ++ temp_vec ++ }; +- (); + } + +-------------------------- +tests/expand/second.rs - different! +Diff [lines: 5 added, 1 removed]: +-------------------------- + #[macro_use] + extern crate test_project; + pub fn main() { ++ { ++ let mut temp_vec = Vec::new(); ++ temp_vec.push(1); ++ temp_vec ++ }; +- (); + } + +-------------------------- +tests/expand/third.rs - different! +Diff [lines: 6 added, 1 removed]: +-------------------------- + #[macro_use] + extern crate test_project; + pub fn main() { ++ { ++ let mut temp_vec = Vec::new(); ++ temp_vec.push(1); ++ temp_vec.push(2); ++ temp_vec ++ }; +- (); + } + +-------------------------- + + + +thread 'pass_expect_expanded' panicked at /home/hedge/src/macrotest/src/expand.rs:173:9: +4 of 4 tests failed + + +failures: + pass + pass_expect_expanded + pr61 + +test result: FAILED. 1 passed; 3 failed; 0 ignored; 0 measured; 0 filtered out; finished in 11.20s + diff --git a/test-virtual/wrkspc/src/lib.rs b/test-virtual/src/lib.rs similarity index 100% rename from test-virtual/wrkspc/src/lib.rs rename to test-virtual/src/lib.rs diff --git a/test-virtual/wrkspc/tests/lib.rs b/test-virtual/tests/lib.rs similarity index 100% rename from test-virtual/wrkspc/tests/lib.rs rename to test-virtual/tests/lib.rs diff --git a/test-virtual/wrkspc-dev/Cargo.toml b/test-virtual/wrkspc-dev/Cargo.toml index 53c58e0..d4853c4 100644 --- a/test-virtual/wrkspc-dev/Cargo.toml +++ b/test-virtual/wrkspc-dev/Cargo.toml @@ -1,15 +1,16 @@ [package] name = "wrkspc-dev" -version = "0.0.0" -authors = ["Mark Van de Vyver "] -license = "Apache-2.0" -edition = "2021" -description = "A development crate in a virtual workspace example" -homepage = "https://github.com/eupn/macrotest" -repository = "https://github.com/eupn/macrotest" -documentation = "https://docs.rs/macrotest" -readme = "README.md" +version.workspace = true +authors.workspace = true +edition.workspace = true +rust-version.workspace = true +description.workspace = true +documentation.workspace = true +homepage.workspace = true +repository.workspace = true +license.workspace = true +readme.workspace = true publish = false [dependencies] -wrkspc-macro = { path = "../wrkspc-macro" } +wrkspc-macro.workspace = true diff --git a/test-virtual/wrkspc-macro/Cargo.toml b/test-virtual/wrkspc-macro/Cargo.toml index 910e0e4..03eac12 100644 --- a/test-virtual/wrkspc-macro/Cargo.toml +++ b/test-virtual/wrkspc-macro/Cargo.toml @@ -1,17 +1,25 @@ [package] name = "wrkspc-macro" -version = "0.0.0" -authors = ["eupn "] -edition = "2021" -publish = false +version.workspace = true +authors.workspace = true +edition.workspace = true +rust-version.workspace = true +description.workspace = true +documentation.workspace = true +homepage.workspace = true +repository.workspace = true +license.workspace = true +readme.workspace = true +publish= false [lib] proc-macro = true [dependencies] -quote = "1" -proc-macro2 = "1.0" -syn = "1.0" +proc-macro2.workspace = true +quote.workspace = true +syn.workspace = true [dev-dependencies] -macrotest = { path = "../../../macrotest" } +wrkspc-test.workspace = true +macrotest.workspace = true diff --git a/test-virtual/wrkspc-test/Cargo.toml b/test-virtual/wrkspc-test/Cargo.toml index 06f232f..2a89f3f 100644 --- a/test-virtual/wrkspc-test/Cargo.toml +++ b/test-virtual/wrkspc-test/Cargo.toml @@ -1,27 +1,36 @@ [package] name = "wrkspc-test" -version = "0.0.0" -edition = "2021" + publish = false [lib] +path = "src/lib.rs" + +# [[bin]] +# name = "wrkspc-test" +# path = "src/main.rs" [features] default = [] - test-feature = [] +[dependencies] +wrkspc-dev.workspace = true +wrkspc-macro.workspace = true + +macrotest.workspace = true +inventory.workspace = true + [dev-dependencies] -macrotest = { path = "../../../macrotest" } -inventory = "0.2.2" +wrkspc-dev.workspace = true +wrkspc-macro.workspace = true [[test]] name = "integration-tests" -path = "integration/main.rs" +path = "src/main.rs" harness = false -[[test]] -name = "defaults-indev-tokio" -path = "integration/feature.rs" -harness = false -required-features = ["test-feature"] +# [[test]] +# name = "feature-test" +# path = "src/tests/feature.rs" +# harness = false diff --git a/test-virtual/wrkspc-test/cargo-test.log b/test-virtual/wrkspc-test/cargo-test.log new file mode 100644 index 0000000..e69de29 diff --git a/test-virtual/wrkspc-test/integration/tests/feature/expanded/with_args.expanded.rs b/test-virtual/wrkspc-test/integration/tests/feature/expanded/with_args.expanded.rs deleted file mode 100644 index 1884aa0..0000000 --- a/test-virtual/wrkspc-test/integration/tests/feature/expanded/with_args.expanded.rs +++ /dev/null @@ -1,12 +0,0 @@ -extern crate std; -#[macro_use] -extern crate test_project; -pub fn main() { - { - let mut temp_vec = Vec::new(); - temp_vec.push(1); - temp_vec.push(2); - temp_vec.push(3); - temp_vec - }; -} diff --git a/test-virtual/wrkspc-test/integration/tests/feature/unchanged/with_args.rs b/test-virtual/wrkspc-test/integration/tests/feature/unchanged/with_args.rs deleted file mode 100644 index dc17120..0000000 --- a/test-virtual/wrkspc-test/integration/tests/feature/unchanged/with_args.rs +++ /dev/null @@ -1,8 +0,0 @@ -#![cfg(feature = "test-feature")] - -#[macro_use] -extern crate test_project; - -pub fn main() { - test_feature_vec![1, 2, 3]; -} diff --git a/test-virtual/wrkspc-test/src/lib.rs b/test-virtual/wrkspc-test/src/lib.rs index f39e1bf..f48d3e0 100644 --- a/test-virtual/wrkspc-test/src/lib.rs +++ b/test-virtual/wrkspc-test/src/lib.rs @@ -1,3 +1,8 @@ +pub mod tests; +pub mod prelude; + +pub use prelude::*; + #[macro_export] macro_rules! test_vec { () => { @@ -14,8 +19,7 @@ macro_rules! test_vec { }; } -#[cfg(feature = "test-feature")] -#[cfg_attr(feature = "test-feature", macro_export)] +#[macro_export] macro_rules! test_feature_vec { () => { Vec::new() @@ -29,4 +33,4 @@ macro_rules! test_feature_vec { temp_vec } }; -} \ No newline at end of file +} diff --git a/test-virtual/wrkspc-test/integration/main.rs b/test-virtual/wrkspc-test/src/main.rs similarity index 87% rename from test-virtual/wrkspc-test/integration/main.rs rename to test-virtual/wrkspc-test/src/main.rs index a577dcd..d4f182f 100644 --- a/test-virtual/wrkspc-test/integration/main.rs +++ b/test-virtual/wrkspc-test/src/main.rs @@ -1,6 +1,7 @@ -pub mod tests; +#[macro_use] +extern crate wrkspc_macro; -use tests::IntegrationTest; +pub use crate::prelude::*; fn setup() { println!("Setup") diff --git a/test-virtual/wrkspc-test/src/prelude.rs b/test-virtual/wrkspc-test/src/prelude.rs new file mode 100644 index 0000000..02bc223 --- /dev/null +++ b/test-virtual/wrkspc-test/src/prelude.rs @@ -0,0 +1 @@ +pub use crate::tests::IntegrationTest; diff --git a/test-virtual/wrkspc-test/integration/tests/basic.rs b/test-virtual/wrkspc-test/src/tests/basic.rs similarity index 80% rename from test-virtual/wrkspc-test/integration/tests/basic.rs rename to test-virtual/wrkspc-test/src/tests/basic.rs index b19d347..0df6c90 100644 --- a/test-virtual/wrkspc-test/integration/tests/basic.rs +++ b/test-virtual/wrkspc-test/src/tests/basic.rs @@ -1,4 +1,4 @@ -use crate::tests::IntegrationTest; +use crate::IntegrationTest; fn basic_test() { println!("Running basic test") diff --git a/test-virtual/wrkspc-test/integration/tests/feature.rs b/test-virtual/wrkspc-test/src/tests/feature.rs similarity index 59% rename from test-virtual/wrkspc-test/integration/tests/feature.rs rename to test-virtual/wrkspc-test/src/tests/feature.rs index 6c9cefe..62ea6c2 100644 --- a/test-virtual/wrkspc-test/integration/tests/feature.rs +++ b/test-virtual/wrkspc-test/src/tests/feature.rs @@ -1,4 +1,4 @@ -use crate::tests::IntegrationTest; +pub use crate::prelude::*; fn feature_test() { println!("Running feature test") @@ -10,27 +10,24 @@ inventory::submit!(IntegrationTest { }); pub fn pass_args() { - macrotest::expand_args( - "integration/tests/feature/expanded/*.rs", - &["--features", "test-feature"], - ); + macrotest::expand("src/tests/feature/expanded/*.rs"); } inventory::submit!(IntegrationTest { name: "feature", test_fn: pass_args }); -pub fn pass_expect_expanded_args() { - // If you delete one of the `.expanded.rs` files, this test will fail. - macrotest::expand_args( - "integration/tests/feature/expanded/*.rs", - &["--features", "test-feature"], - ); -} -inventory::submit!(IntegrationTest { - name: "feature", - test_fn: feature_test -}); +// pub fn pass_expect_expanded_args() { +// // If you delete one of the `.expanded.rs` files, this test will fail. +// macrotest::expand_args( +// "integration/tests/feature/expanded/*.rs", +// &["--features", "test-feature"], +// ); +// } +// inventory::submit!(IntegrationTest { +// name: "feature", +// test_fn: pass_expect_expanded_args +// }); // Suspended panicky tests for the moment // @@ -45,3 +42,5 @@ inventory::submit!(IntegrationTest { // name: "feature", // test_fn: fail_expect_expanded_args // }); + +pub fn main() {} diff --git a/test-virtual/wrkspc-test/src/tests/feature/expanded/with_args.rs b/test-virtual/wrkspc-test/src/tests/feature/expanded/with_args.rs new file mode 100644 index 0000000..12128b9 --- /dev/null +++ b/test-virtual/wrkspc-test/src/tests/feature/expanded/with_args.rs @@ -0,0 +1,9 @@ +// #![cfg(feature = "test-feature")] + +#[macro_use] +extern crate wrkspc_macro; + +pub fn main() { + #[my_attribute] + struct Test; +} diff --git a/test-virtual/wrkspc-test/tests/expand_args/with_args.expanded.rs b/test-virtual/wrkspc-test/src/tests/feature/unchanged/with_args.expanded.rs similarity index 92% rename from test-virtual/wrkspc-test/tests/expand_args/with_args.expanded.rs rename to test-virtual/wrkspc-test/src/tests/feature/unchanged/with_args.expanded.rs index 1884aa0..e760c93 100644 --- a/test-virtual/wrkspc-test/tests/expand_args/with_args.expanded.rs +++ b/test-virtual/wrkspc-test/src/tests/feature/unchanged/with_args.expanded.rs @@ -8,5 +8,6 @@ pub fn main() { temp_vec.push(2); temp_vec.push(3); temp_vec + // error }; } diff --git a/test-virtual/wrkspc-test/integration/tests/feature/expanded/with_args.rs b/test-virtual/wrkspc-test/src/tests/feature/unchanged/with_args.rs similarity index 100% rename from test-virtual/wrkspc-test/integration/tests/feature/expanded/with_args.rs rename to test-virtual/wrkspc-test/src/tests/feature/unchanged/with_args.rs diff --git a/test-virtual/wrkspc-test/integration/tests/mod.rs b/test-virtual/wrkspc-test/src/tests/mod.rs similarity index 59% rename from test-virtual/wrkspc-test/integration/tests/mod.rs rename to test-virtual/wrkspc-test/src/tests/mod.rs index 605994e..b6aae4a 100644 --- a/test-virtual/wrkspc-test/integration/tests/mod.rs +++ b/test-virtual/wrkspc-test/src/tests/mod.rs @@ -7,4 +7,10 @@ pub struct IntegrationTest { pub test_fn: fn(), } +// #[derive(Debug)] +// pub struct IntegrationTest { +// pub name: &'static str, +// pub test_fn: fn(), +// } + inventory::collect!(IntegrationTest); diff --git a/test-virtual/wrkspc-test/tests/expand_args/with_args.rs b/test-virtual/wrkspc-test/tests/expand_args/with_args.rs index dc17120..7a78410 100644 --- a/test-virtual/wrkspc-test/tests/expand_args/with_args.rs +++ b/test-virtual/wrkspc-test/tests/expand_args/with_args.rs @@ -1,7 +1,5 @@ -#![cfg(feature = "test-feature")] - #[macro_use] -extern crate test_project; +extern crate wkspc_test; pub fn main() { test_feature_vec![1, 2, 3]; diff --git a/test-virtual/wrkspc-test/tests/no_expanded/first.rs b/test-virtual/wrkspc-test/tests/no_expanded/first.rs index 5f3c0eb..c8a8cdf 100644 --- a/test-virtual/wrkspc-test/tests/no_expanded/first.rs +++ b/test-virtual/wrkspc-test/tests/no_expanded/first.rs @@ -1,5 +1,5 @@ #[macro_use] -extern crate test_project; +extern crate test_virtual; pub fn main() { test_vec![]; diff --git a/test-virtual/wrkspc-test/tests/no_expanded/fourth.rs b/test-virtual/wrkspc-test/tests/no_expanded/fourth.rs index 3c50cc1..82ad356 100644 --- a/test-virtual/wrkspc-test/tests/no_expanded/fourth.rs +++ b/test-virtual/wrkspc-test/tests/no_expanded/fourth.rs @@ -1,5 +1,5 @@ #[macro_use] -extern crate test_project; +extern crate test_virtual; pub fn main() { test_vec![1, 2, 3]; diff --git a/test-virtual/wrkspc-test/tests/no_expanded/second.rs b/test-virtual/wrkspc-test/tests/no_expanded/second.rs index b7d0e43..9f96b62 100644 --- a/test-virtual/wrkspc-test/tests/no_expanded/second.rs +++ b/test-virtual/wrkspc-test/tests/no_expanded/second.rs @@ -1,5 +1,5 @@ #[macro_use] -extern crate test_project; +extern crate test_virtual; pub fn main() { test_vec![1]; diff --git a/test-virtual/wrkspc-test/tests/no_expanded/third.rs b/test-virtual/wrkspc-test/tests/no_expanded/third.rs index bc440e0..2eda910 100644 --- a/test-virtual/wrkspc-test/tests/no_expanded/third.rs +++ b/test-virtual/wrkspc-test/tests/no_expanded/third.rs @@ -1,5 +1,5 @@ #[macro_use] -extern crate test_project; +extern crate test_virtual; pub fn main() { test_vec![1, 2]; diff --git a/test-virtual/wrkspc-test/tests/no_expanded_args/with_args.rs b/test-virtual/wrkspc-test/tests/no_expanded_args/with_args.rs index dc17120..f4b3018 100644 --- a/test-virtual/wrkspc-test/tests/no_expanded_args/with_args.rs +++ b/test-virtual/wrkspc-test/tests/no_expanded_args/with_args.rs @@ -1,7 +1,7 @@ #![cfg(feature = "test-feature")] #[macro_use] -extern crate test_project; +extern crate test_virtual; pub fn main() { test_feature_vec![1, 2, 3]; diff --git a/test-virtual/wrkspc-test/tests/pr61/a/test.expanded.rs b/test-virtual/wrkspc-test/tests/pr61/a/test.expanded.rs index 584bf25..ab55554 100644 --- a/test-virtual/wrkspc-test/tests/pr61/a/test.expanded.rs +++ b/test-virtual/wrkspc-test/tests/pr61/a/test.expanded.rs @@ -1,5 +1,5 @@ #[macro_use] -extern crate test_project; +extern crate test_virtual; pub fn main() { Vec::new(); } diff --git a/test-virtual/wrkspc-test/tests/pr61/a/test.rs b/test-virtual/wrkspc-test/tests/pr61/a/test.rs index 5f3c0eb..c8a8cdf 100644 --- a/test-virtual/wrkspc-test/tests/pr61/a/test.rs +++ b/test-virtual/wrkspc-test/tests/pr61/a/test.rs @@ -1,5 +1,5 @@ #[macro_use] -extern crate test_project; +extern crate test_virtual; pub fn main() { test_vec![]; diff --git a/test-virtual/wrkspc-test/tests/pr61/b/test.expanded.rs b/test-virtual/wrkspc-test/tests/pr61/b/test.expanded.rs index 584bf25..ab55554 100644 --- a/test-virtual/wrkspc-test/tests/pr61/b/test.expanded.rs +++ b/test-virtual/wrkspc-test/tests/pr61/b/test.expanded.rs @@ -1,5 +1,5 @@ #[macro_use] -extern crate test_project; +extern crate test_virtual; pub fn main() { Vec::new(); } diff --git a/test-virtual/wrkspc-test/tests/pr61/b/test.rs b/test-virtual/wrkspc-test/tests/pr61/b/test.rs index 5f3c0eb..c8a8cdf 100644 --- a/test-virtual/wrkspc-test/tests/pr61/b/test.rs +++ b/test-virtual/wrkspc-test/tests/pr61/b/test.rs @@ -1,5 +1,5 @@ #[macro_use] -extern crate test_project; +extern crate test_virtual; pub fn main() { test_vec![]; diff --git a/test-virtual/wrkspc-test/tests/tests.rs b/test-virtual/wrkspc-test/tests/tests.rs index a78dc88..be42fbc 100644 --- a/test-virtual/wrkspc-test/tests/tests.rs +++ b/test-virtual/wrkspc-test/tests/tests.rs @@ -12,30 +12,30 @@ pub fn pass_expect_expanded() { #[test] #[should_panic] pub fn fail_expect_expanded() { - // This directory doesn't have expanded files but since they're expected, the test will fail. + // This directory doesn't have expanded files and since they're expected, the test will fail. macrotest::expand_without_refresh("tests/no_expanded/*.rs"); } -#[test] -pub fn pass_args() { - macrotest::expand_args("tests/expand_args/*.rs", &["--features", "test-feature"]); -} +// #[test] +// pub fn pass_args() { +// macrotest::expand_args("tests/expand_args/*.rs", &["--features", "test-feature"]); +// } -#[test] -pub fn pass_expect_expanded_args() { - // If you delete one of the `.expanded.rs` files, this test will fail. - macrotest::expand_args("tests/expand_args/*.rs", &["--features", "test-feature"]); -} +// #[test] +// pub fn pass_expect_expanded_args() { +// // If you delete one of the `.expanded.rs` files, this test will fail. +// macrotest::expand_args("tests/expand_args/*.rs", &["--features", "test-feature"]); +// } -#[test] -#[should_panic] -pub fn fail_expect_expanded_args() { - // This directory doesn't have expanded files but since they're expected, the test will fail. - macrotest::expand_without_refresh_args( - "tests/no_expanded_args/*.rs", - &["--features", "test-feature"], - ); -} +// #[test] +// #[should_panic] +// pub fn fail_expect_expanded_args() { +// // This directory doesn't have expanded files but since they're expected, the test will fail. +// macrotest::expand_without_refresh_args( +// "tests/no_expanded_args/*.rs", +// &["--features", "test-feature"], +// ); +// } // https://github.com/eupn/macrotest/pull/61 #[test] diff --git a/test-virtual/wrkspc/Cargo.toml b/test-virtual/wrkspc/Cargo.toml deleted file mode 100644 index 16c3e32..0000000 --- a/test-virtual/wrkspc/Cargo.toml +++ /dev/null @@ -1,18 +0,0 @@ -[package] -name = "wrkspc" -version = "0.0.0" -authors = ["Mark Van de Vyver "] -license = "Apache-2.0" -edition = "2021" -description = "A crate in a virtual workspace example" -homepage = "https://github.com/eupn/macrotest" -repository = "https://github.com/eupn/macrotest" -documentation = "https://docs.rs/macrotest" -readme = "README.md" -publish = false - -[dependencies] -wrkspc-macro = { path = "../wrkspc-macro" } - -[dev-dependencies] -wrkspc-dev = { path = "../wrkspc-dev" } From f7c0f65159604062b0f804b66f5e9b44894cd870 Mon Sep 17 00:00:00 2001 From: Mark Van de Vyver Date: Mon, 11 Mar 2024 23:03:36 +1100 Subject: [PATCH 10/15] Add new files and update Cargo.toml Signed-off-by: Mark Van de Vyver --- test-virtual/Cargo.toml | 29 ++- test-virtual/wrkspc-macro/Cargo.toml | 2 +- test-virtual/wrkspc-test/Cargo.toml | 10 +- test-virtual/wrkspc-test/cargo-test.log | 178 ++++++++++++++++++ .../wrkspc-test/src/{main.rs => _main.rs} | 2 - test-virtual/wrkspc-test/src/tests/mod.rs | 6 - test-virtual/wrkspc/Cargo.toml | 26 +++ test-virtual/{ => wrkspc}/src/lib.rs | 0 test-virtual/{ => wrkspc}/tests/lib.rs | 0 9 files changed, 224 insertions(+), 29 deletions(-) rename test-virtual/wrkspc-test/src/{main.rs => _main.rs} (92%) create mode 100644 test-virtual/wrkspc/Cargo.toml rename test-virtual/{ => wrkspc}/src/lib.rs (100%) rename test-virtual/{ => wrkspc}/tests/lib.rs (100%) diff --git a/test-virtual/Cargo.toml b/test-virtual/Cargo.toml index 7d25efd..48cab08 100644 --- a/test-virtual/Cargo.toml +++ b/test-virtual/Cargo.toml @@ -31,19 +31,16 @@ proc-macro2 = "1.0" quote = "1" syn = "2.0" -[package] -name = "wrkspc" -version.workspace = true -authors.workspace = true -edition.workspace = true -rust-version.workspace = true -description.workspace = true -documentation.workspace = true -homepage.workspace = true -repository.workspace = true -license.workspace = true -readme.workspace = true -publish = false - -[dependencies] -wrkspc-macro.workspace = true +# [package] +# name = "wrkspc" +# version.workspace = true +# authors.workspace = true +# edition.workspace = true +# rust-version.workspace = true +# description.workspace = true +# documentation.workspace = true +# homepage.workspace = true +# repository.workspace = true +# license.workspace = true +# readme.workspace = true +# publish = false diff --git a/test-virtual/wrkspc-macro/Cargo.toml b/test-virtual/wrkspc-macro/Cargo.toml index 03eac12..ebe79f0 100644 --- a/test-virtual/wrkspc-macro/Cargo.toml +++ b/test-virtual/wrkspc-macro/Cargo.toml @@ -21,5 +21,5 @@ quote.workspace = true syn.workspace = true [dev-dependencies] -wrkspc-test.workspace = true +# wrkspc-test.workspace = true macrotest.workspace = true diff --git a/test-virtual/wrkspc-test/Cargo.toml b/test-virtual/wrkspc-test/Cargo.toml index 2a89f3f..9f788e0 100644 --- a/test-virtual/wrkspc-test/Cargo.toml +++ b/test-virtual/wrkspc-test/Cargo.toml @@ -24,11 +24,13 @@ inventory.workspace = true [dev-dependencies] wrkspc-dev.workspace = true wrkspc-macro.workspace = true +macrotest.workspace = true +inventory.workspace = true -[[test]] -name = "integration-tests" -path = "src/main.rs" -harness = false +# [[test]] +# name = "integration-tests" +# path = "src/main.rs" +# harness = false # [[test]] # name = "feature-test" diff --git a/test-virtual/wrkspc-test/cargo-test.log b/test-virtual/wrkspc-test/cargo-test.log index e69de29..5b9c660 100644 --- a/test-virtual/wrkspc-test/cargo-test.log +++ b/test-virtual/wrkspc-test/cargo-test.log @@ -0,0 +1,178 @@ + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + +running 1 test +test wrkspc_test ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + +running 1 test +test wrkspc_test ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + +running 1 test +tests/expand/attribute.rs - ok +tests/expand/derive.rs - ok +tests/expand/macro.rs - ok +test pass ... ok + +test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 2.73s + + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + +running 0 tests + +test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s + + +running 4 tests +test pass ... FAILED +test fail_expect_expanded - should panic ... ok +test pr61 ... FAILED +test pass_expect_expanded ... FAILED + +failures: + +---- pass stdout ---- +Running 4 macro expansion tests +Expansion error: +warning: `/home/hedge/src/macrotest/test-virtual/target/tests/wrkspc-test/macrotest000/.cargo/config` is deprecated in favor of `config.toml` +note: if you need to support cargo 1.38 or earlier, you can symlink `config` to `config.toml` +error: failed to parse manifest at `/home/hedge/src/macrotest/test-virtual/target/tests/wrkspc-test/macrotest000/Cargo.toml` +Caused by: + error inheriting `inventory` from workspace root manifest's `workspace.dependencies.inventory` +Caused by: + `workspace.dependencies` was not defined + +Expansion error: +warning: `/home/hedge/src/macrotest/test-virtual/target/tests/wrkspc-test/macrotest000/.cargo/config` is deprecated in favor of `config.toml` +note: if you need to support cargo 1.38 or earlier, you can symlink `config` to `config.toml` +error: failed to parse manifest at `/home/hedge/src/macrotest/test-virtual/target/tests/wrkspc-test/macrotest000/Cargo.toml` +Caused by: + error inheriting `inventory` from workspace root manifest's `workspace.dependencies.inventory` +Caused by: + `workspace.dependencies` was not defined + +Expansion error: +warning: `/home/hedge/src/macrotest/test-virtual/target/tests/wrkspc-test/macrotest000/.cargo/config` is deprecated in favor of `config.toml` +note: if you need to support cargo 1.38 or earlier, you can symlink `config` to `config.toml` +error: failed to parse manifest at `/home/hedge/src/macrotest/test-virtual/target/tests/wrkspc-test/macrotest000/Cargo.toml` +Caused by: + error inheriting `inventory` from workspace root manifest's `workspace.dependencies.inventory` +Caused by: + `workspace.dependencies` was not defined + +Expansion error: +warning: `/home/hedge/src/macrotest/test-virtual/target/tests/wrkspc-test/macrotest000/.cargo/config` is deprecated in favor of `config.toml` +note: if you need to support cargo 1.38 or earlier, you can symlink `config` to `config.toml` +error: failed to parse manifest at `/home/hedge/src/macrotest/test-virtual/target/tests/wrkspc-test/macrotest000/Cargo.toml` +Caused by: + error inheriting `inventory` from workspace root manifest's `workspace.dependencies.inventory` +Caused by: + `workspace.dependencies` was not defined + + + + +thread 'pass' panicked at /home/hedge/src/macrotest/src/expand.rs:173:9: +4 of 4 tests failed +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace + +---- pr61 stdout ---- +Running 2 macro expansion tests +Expansion error: +warning: `/home/hedge/src/macrotest/test-virtual/target/tests/wrkspc-test/macrotest003/.cargo/config` is deprecated in favor of `config.toml` +note: if you need to support cargo 1.38 or earlier, you can symlink `config` to `config.toml` +error: failed to parse manifest at `/home/hedge/src/macrotest/test-virtual/target/tests/wrkspc-test/macrotest003/Cargo.toml` +Caused by: + error inheriting `inventory` from workspace root manifest's `workspace.dependencies.inventory` +Caused by: + `workspace.dependencies` was not defined + +Expansion error: +warning: `/home/hedge/src/macrotest/test-virtual/target/tests/wrkspc-test/macrotest003/.cargo/config` is deprecated in favor of `config.toml` +note: if you need to support cargo 1.38 or earlier, you can symlink `config` to `config.toml` +error: failed to parse manifest at `/home/hedge/src/macrotest/test-virtual/target/tests/wrkspc-test/macrotest003/Cargo.toml` +Caused by: + error inheriting `inventory` from workspace root manifest's `workspace.dependencies.inventory` +Caused by: + `workspace.dependencies` was not defined + + + + +thread 'pr61' panicked at /home/hedge/src/macrotest/src/expand.rs:173:9: +2 of 2 tests failed + +---- pass_expect_expanded stdout ---- +Running 4 macro expansion tests +Expansion error: +warning: `/home/hedge/src/macrotest/test-virtual/target/tests/wrkspc-test/macrotest002/.cargo/config` is deprecated in favor of `config.toml` +note: if you need to support cargo 1.38 or earlier, you can symlink `config` to `config.toml` +error: failed to parse manifest at `/home/hedge/src/macrotest/test-virtual/target/tests/wrkspc-test/macrotest002/Cargo.toml` +Caused by: + error inheriting `inventory` from workspace root manifest's `workspace.dependencies.inventory` +Caused by: + `workspace.dependencies` was not defined + +Expansion error: +warning: `/home/hedge/src/macrotest/test-virtual/target/tests/wrkspc-test/macrotest002/.cargo/config` is deprecated in favor of `config.toml` +note: if you need to support cargo 1.38 or earlier, you can symlink `config` to `config.toml` +error: failed to parse manifest at `/home/hedge/src/macrotest/test-virtual/target/tests/wrkspc-test/macrotest002/Cargo.toml` +Caused by: + error inheriting `inventory` from workspace root manifest's `workspace.dependencies.inventory` +Caused by: + `workspace.dependencies` was not defined + +Expansion error: +warning: `/home/hedge/src/macrotest/test-virtual/target/tests/wrkspc-test/macrotest002/.cargo/config` is deprecated in favor of `config.toml` +note: if you need to support cargo 1.38 or earlier, you can symlink `config` to `config.toml` +error: failed to parse manifest at `/home/hedge/src/macrotest/test-virtual/target/tests/wrkspc-test/macrotest002/Cargo.toml` +Caused by: + error inheriting `inventory` from workspace root manifest's `workspace.dependencies.inventory` +Caused by: + `workspace.dependencies` was not defined + +Expansion error: +warning: `/home/hedge/src/macrotest/test-virtual/target/tests/wrkspc-test/macrotest002/.cargo/config` is deprecated in favor of `config.toml` +note: if you need to support cargo 1.38 or earlier, you can symlink `config` to `config.toml` +error: failed to parse manifest at `/home/hedge/src/macrotest/test-virtual/target/tests/wrkspc-test/macrotest002/Cargo.toml` +Caused by: + error inheriting `inventory` from workspace root manifest's `workspace.dependencies.inventory` +Caused by: + `workspace.dependencies` was not defined + + + + +thread 'pass_expect_expanded' panicked at /home/hedge/src/macrotest/src/expand.rs:173:9: +4 of 4 tests failed + + +failures: + pass + pass_expect_expanded + pr61 + +test result: FAILED. 1 passed; 3 failed; 0 ignored; 0 measured; 0 filtered out; finished in 5.74s + diff --git a/test-virtual/wrkspc-test/src/main.rs b/test-virtual/wrkspc-test/src/_main.rs similarity index 92% rename from test-virtual/wrkspc-test/src/main.rs rename to test-virtual/wrkspc-test/src/_main.rs index d4f182f..ffa5edc 100644 --- a/test-virtual/wrkspc-test/src/main.rs +++ b/test-virtual/wrkspc-test/src/_main.rs @@ -1,5 +1,3 @@ -#[macro_use] -extern crate wrkspc_macro; pub use crate::prelude::*; diff --git a/test-virtual/wrkspc-test/src/tests/mod.rs b/test-virtual/wrkspc-test/src/tests/mod.rs index b6aae4a..605994e 100644 --- a/test-virtual/wrkspc-test/src/tests/mod.rs +++ b/test-virtual/wrkspc-test/src/tests/mod.rs @@ -7,10 +7,4 @@ pub struct IntegrationTest { pub test_fn: fn(), } -// #[derive(Debug)] -// pub struct IntegrationTest { -// pub name: &'static str, -// pub test_fn: fn(), -// } - inventory::collect!(IntegrationTest); diff --git a/test-virtual/wrkspc/Cargo.toml b/test-virtual/wrkspc/Cargo.toml new file mode 100644 index 0000000..cbb4820 --- /dev/null +++ b/test-virtual/wrkspc/Cargo.toml @@ -0,0 +1,26 @@ +[package] +name = "wrkspc" +version.workspace = true +authors.workspace = true +edition.workspace = true +rust-version.workspace = true +description.workspace = true +documentation.workspace = true +homepage.workspace = true +repository.workspace = true +license.workspace = true +readme.workspace = true +publish = false + + +[dependencies] +wrkspc-dev = { path = "wrkspc-dev" } +wrkspc-macro = { path = "wrkspc-macro" } +wrkspc-test = { path = "wrkspc-test" } + +macrotest = { path = "../" } + +inventory = "0.3" +proc-macro2 = "1.0" +quote = "1" +syn = "2.0" diff --git a/test-virtual/src/lib.rs b/test-virtual/wrkspc/src/lib.rs similarity index 100% rename from test-virtual/src/lib.rs rename to test-virtual/wrkspc/src/lib.rs diff --git a/test-virtual/tests/lib.rs b/test-virtual/wrkspc/tests/lib.rs similarity index 100% rename from test-virtual/tests/lib.rs rename to test-virtual/wrkspc/tests/lib.rs From 27b8849b9c89076cc8af59fe5240a3d7454b5d9f Mon Sep 17 00:00:00 2001 From: Mark Van de Vyver Date: Thu, 14 Mar 2024 21:07:13 +1100 Subject: [PATCH 11/15] Working virtual test setup Signed-off-by: Mark Van de Vyver --- .gitignore | 1 + test-virtual/Cargo.toml | 16 +- test-virtual/cargo-test.log | 202 ------------------ test-virtual/test.log | 60 ------ test-virtual/wrkspc-dev/Cargo.toml | 2 + test-virtual/wrkspc-macro/Cargo.toml | 3 + .../tests/expand/attribute.expanded.rs | 1 + .../wrkspc-macro/tests/expand/attribute.rs | 2 + .../tests/expand/derive.expanded.rs | 1 + .../wrkspc-macro/tests/expand/derive.rs | 2 + test-virtual/wrkspc-test/.gitignore | 1 + test-virtual/wrkspc-test/Cargo.toml | 38 ++-- test-virtual/wrkspc-test/all.do | 72 +++++++ test-virtual/wrkspc-test/cargo-test.log | 178 --------------- test-virtual/wrkspc-test/default.do | 34 +++ test-virtual/wrkspc-test/src/_main.rs | 26 --- test-virtual/wrkspc-test/src/lib.rs | 36 ---- test-virtual/wrkspc-test/src/prelude.rs | 1 - test-virtual/wrkspc-test/src/tests/basic.rs | 10 - .../src/tests/expand/attribute.expanded.rs | 5 + .../src/tests/expand/derive.expanded.rs | 5 + .../with_args.rs => expand/macro.expanded.rs} | 5 +- test-virtual/wrkspc-test/src/tests/feature.rs | 46 ---- .../feature/unchanged/with_args.expanded.rs | 13 -- .../src/tests/feature/unchanged/with_args.rs | 8 - test-virtual/wrkspc-test/src/tests/mod.rs | 10 - .../tests/expand/first.expanded.rs | 5 - .../wrkspc-test/tests/expand/first.rs | 6 - .../tests/expand/fourth.expanded.rs | 11 - .../wrkspc-test/tests/expand/fourth.rs | 6 - .../tests/expand/second.expanded.rs | 9 - .../wrkspc-test/tests/expand/second.rs | 6 - .../tests/expand/third.expanded.rs | 10 - .../wrkspc-test/tests/expand/third.rs | 6 - .../tests/expand_args/with_args.rs | 6 - .../wrkspc-test/tests/no_expanded/first.rs | 6 - .../wrkspc-test/tests/no_expanded/fourth.rs | 6 - .../wrkspc-test/tests/no_expanded/second.rs | 6 - .../wrkspc-test/tests/no_expanded/third.rs | 6 - .../tests/no_expanded_args/with_args.rs | 8 - .../wrkspc-test/tests/par_tests_regression.rs | 18 -- .../wrkspc-test/tests/pr61/a/test.expanded.rs | 5 - test-virtual/wrkspc-test/tests/pr61/a/test.rs | 6 - .../wrkspc-test/tests/pr61/b/test.expanded.rs | 5 - test-virtual/wrkspc-test/tests/pr61/b/test.rs | 6 - test-virtual/wrkspc-test/tests/tests.rs | 44 ---- test-virtual/wrkspc/Cargo.toml | 16 +- 47 files changed, 152 insertions(+), 823 deletions(-) delete mode 100644 test-virtual/cargo-test.log delete mode 100644 test-virtual/test.log create mode 100644 test-virtual/wrkspc-test/all.do delete mode 100644 test-virtual/wrkspc-test/cargo-test.log create mode 100644 test-virtual/wrkspc-test/default.do delete mode 100644 test-virtual/wrkspc-test/src/_main.rs delete mode 100644 test-virtual/wrkspc-test/src/lib.rs delete mode 100644 test-virtual/wrkspc-test/src/prelude.rs delete mode 100644 test-virtual/wrkspc-test/src/tests/basic.rs create mode 100644 test-virtual/wrkspc-test/src/tests/expand/attribute.expanded.rs create mode 100644 test-virtual/wrkspc-test/src/tests/expand/derive.expanded.rs rename test-virtual/wrkspc-test/src/tests/{feature/expanded/with_args.rs => expand/macro.expanded.rs} (55%) delete mode 100644 test-virtual/wrkspc-test/src/tests/feature.rs delete mode 100644 test-virtual/wrkspc-test/src/tests/feature/unchanged/with_args.expanded.rs delete mode 100644 test-virtual/wrkspc-test/src/tests/feature/unchanged/with_args.rs delete mode 100644 test-virtual/wrkspc-test/src/tests/mod.rs delete mode 100644 test-virtual/wrkspc-test/tests/expand/first.expanded.rs delete mode 100644 test-virtual/wrkspc-test/tests/expand/first.rs delete mode 100644 test-virtual/wrkspc-test/tests/expand/fourth.expanded.rs delete mode 100644 test-virtual/wrkspc-test/tests/expand/fourth.rs delete mode 100644 test-virtual/wrkspc-test/tests/expand/second.expanded.rs delete mode 100644 test-virtual/wrkspc-test/tests/expand/second.rs delete mode 100644 test-virtual/wrkspc-test/tests/expand/third.expanded.rs delete mode 100644 test-virtual/wrkspc-test/tests/expand/third.rs delete mode 100644 test-virtual/wrkspc-test/tests/expand_args/with_args.rs delete mode 100644 test-virtual/wrkspc-test/tests/no_expanded/first.rs delete mode 100644 test-virtual/wrkspc-test/tests/no_expanded/fourth.rs delete mode 100644 test-virtual/wrkspc-test/tests/no_expanded/second.rs delete mode 100644 test-virtual/wrkspc-test/tests/no_expanded/third.rs delete mode 100644 test-virtual/wrkspc-test/tests/no_expanded_args/with_args.rs delete mode 100644 test-virtual/wrkspc-test/tests/par_tests_regression.rs delete mode 100644 test-virtual/wrkspc-test/tests/pr61/a/test.expanded.rs delete mode 100644 test-virtual/wrkspc-test/tests/pr61/a/test.rs delete mode 100644 test-virtual/wrkspc-test/tests/pr61/b/test.expanded.rs delete mode 100644 test-virtual/wrkspc-test/tests/pr61/b/test.rs delete mode 100644 test-virtual/wrkspc-test/tests/tests.rs diff --git a/.gitignore b/.gitignore index ff23b2d..5c71db3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ **/target **/*.rs.bk +**/.redo Cargo.lock *.iml *.ipr diff --git a/test-virtual/Cargo.toml b/test-virtual/Cargo.toml index 48cab08..f5142a3 100644 --- a/test-virtual/Cargo.toml +++ b/test-virtual/Cargo.toml @@ -1,6 +1,7 @@ [workspace] resolver = "2" members = [ + "wrkspc", "wrkspc-dev", "wrkspc-macro", "wrkspc-test", @@ -20,6 +21,7 @@ readme = "README.md" publish = false [workspace.dependencies] +wrkspc = { path = "wrkspc" } wrkspc-dev = { path = "wrkspc-dev" } wrkspc-macro = { path = "wrkspc-macro" } wrkspc-test = { path = "wrkspc-test" } @@ -30,17 +32,3 @@ inventory = "0.3" proc-macro2 = "1.0" quote = "1" syn = "2.0" - -# [package] -# name = "wrkspc" -# version.workspace = true -# authors.workspace = true -# edition.workspace = true -# rust-version.workspace = true -# description.workspace = true -# documentation.workspace = true -# homepage.workspace = true -# repository.workspace = true -# license.workspace = true -# readme.workspace = true -# publish = false diff --git a/test-virtual/cargo-test.log b/test-virtual/cargo-test.log deleted file mode 100644 index 28bea78..0000000 --- a/test-virtual/cargo-test.log +++ /dev/null @@ -1,202 +0,0 @@ - -running 0 tests - -test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.01s - - -running 0 tests - -test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s - -Setup -Running basic test -Running 1 macro expansion tests -Running feature test -Teardown - -running 0 tests - -test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s - - -running 4 tests -test pass ... FAILED -test fail_expect_expanded - should panic ... ok -test pr61 ... FAILED -test pass_expect_expanded ... FAILED - -failures: - ----- pass stdout ---- -Running 4 macro expansion tests -tests/expand/first.rs - different! -Diff [lines: 1 added, 1 removed]: --------------------------- - #[macro_use] - extern crate test_project; - pub fn main() { -+ Vec::new(); -- (); - } - --------------------------- -tests/expand/fourth.rs - different! -Diff [lines: 7 added, 1 removed]: --------------------------- - #[macro_use] - extern crate test_project; - pub fn main() { -+ { -+ let mut temp_vec = Vec::new(); -+ temp_vec.push(1); -+ temp_vec.push(2); -+ temp_vec.push(3); -+ temp_vec -+ }; -- (); - } - --------------------------- -tests/expand/second.rs - different! -Diff [lines: 5 added, 1 removed]: --------------------------- - #[macro_use] - extern crate test_project; - pub fn main() { -+ { -+ let mut temp_vec = Vec::new(); -+ temp_vec.push(1); -+ temp_vec -+ }; -- (); - } - --------------------------- -tests/expand/third.rs - different! -Diff [lines: 6 added, 1 removed]: --------------------------- - #[macro_use] - extern crate test_project; - pub fn main() { -+ { -+ let mut temp_vec = Vec::new(); -+ temp_vec.push(1); -+ temp_vec.push(2); -+ temp_vec -+ }; -- (); - } - --------------------------- - - - -thread 'pass' panicked at /home/hedge/src/macrotest/src/expand.rs:173:9: -4 of 4 tests failed -note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace - ----- pr61 stdout ---- -Running 2 macro expansion tests -tests/pr61/a/test.rs - different! -Diff [lines: 1 added, 1 removed]: --------------------------- - #[macro_use] - extern crate test_virtual; - pub fn main() { -+ Vec::new(); -- (); - } - --------------------------- -tests/pr61/b/test.rs - different! -Diff [lines: 1 added, 1 removed]: --------------------------- - #[macro_use] - extern crate test_virtual; - pub fn main() { -+ Vec::new(); -- (); - } - --------------------------- - - - -thread 'pr61' panicked at /home/hedge/src/macrotest/src/expand.rs:173:9: -2 of 2 tests failed - ----- pass_expect_expanded stdout ---- -Running 4 macro expansion tests -tests/expand/first.rs - different! -Diff [lines: 1 added, 1 removed]: --------------------------- - #[macro_use] - extern crate test_project; - pub fn main() { -+ Vec::new(); -- (); - } - --------------------------- -tests/expand/fourth.rs - different! -Diff [lines: 7 added, 1 removed]: --------------------------- - #[macro_use] - extern crate test_project; - pub fn main() { -+ { -+ let mut temp_vec = Vec::new(); -+ temp_vec.push(1); -+ temp_vec.push(2); -+ temp_vec.push(3); -+ temp_vec -+ }; -- (); - } - --------------------------- -tests/expand/second.rs - different! -Diff [lines: 5 added, 1 removed]: --------------------------- - #[macro_use] - extern crate test_project; - pub fn main() { -+ { -+ let mut temp_vec = Vec::new(); -+ temp_vec.push(1); -+ temp_vec -+ }; -- (); - } - --------------------------- -tests/expand/third.rs - different! -Diff [lines: 6 added, 1 removed]: --------------------------- - #[macro_use] - extern crate test_project; - pub fn main() { -+ { -+ let mut temp_vec = Vec::new(); -+ temp_vec.push(1); -+ temp_vec.push(2); -+ temp_vec -+ }; -- (); - } - --------------------------- - - - -thread 'pass_expect_expanded' panicked at /home/hedge/src/macrotest/src/expand.rs:173:9: -4 of 4 tests failed - - -failures: - pass - pass_expect_expanded - pr61 - -test result: FAILED. 1 passed; 3 failed; 0 ignored; 0 measured; 0 filtered out; finished in 11.20s - diff --git a/test-virtual/test.log b/test-virtual/test.log deleted file mode 100644 index 917cd37..0000000 --- a/test-virtual/test.log +++ /dev/null @@ -1,60 +0,0 @@ - Compiling wrkspc-test v0.0.0 (/home/hedge/src/macrotest/test-virtual/wrkspc-test) - Finished test [unoptimized + debuginfo] target(s) in 1.88s - Running unittests (target/debug/deps/wrkspc-c42e7841a2166c46) - -running 0 tests - -test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s - - Running tests/lib.rs (target/debug/deps/lib-6b376d4406ebc397) - -running 0 tests - -test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 1 filtered out; finished in 0.00s - - Running unittests (target/debug/deps/wrkspc_dev-8016f768612e755a) - -running 0 tests - -test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s - - Running tests/lib.rs (target/debug/deps/lib-8059e559b0ae9056) - -running 0 tests - -test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 1 filtered out; finished in 0.00s - - Running unittests (target/debug/deps/wrkspc_macro-5238f20639a08243) - -running 0 tests - -test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s - - Running tests/tests.rs (target/debug/deps/tests-d4e63bc64c0942af) - -running 0 tests - -test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 1 filtered out; finished in 0.00s - - Running unittests (target/debug/deps/wrkspc_test-86138e2ad1f9ee9c) - -running 0 tests - -test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s - - Running integration/main.rs (target/debug/deps/integration_tests-3f75cfd9c75954c7) -Setup -Running 1 macro expansion tests - Checking wrkspc-test-tests v0.0.0 (/home/hedge/src/macrotest/test-virtual/target/tests/wrkspc-test/macrotest000) - Finished dev [unoptimized + debuginfo] target(s) in 0.21s - -use std::prelude::rust_2018::*; -Expansion error: -error: Package `wrkspc-test-tests v0.0.0 (/home/hedge/src/macrotest/test-virtual/target/tests/wrkspc-test/macrotest000)` does not have the feature `test-feature` - - - - -thread 'main' panicked at '1 of 1 tests failed', /home/hedge/src/macrotest/src/expand.rs:171:9 -note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace -error: test failed, to rerun pass '-p wrkspc-test --test integration-tests' diff --git a/test-virtual/wrkspc-dev/Cargo.toml b/test-virtual/wrkspc-dev/Cargo.toml index d4853c4..31c84ec 100644 --- a/test-virtual/wrkspc-dev/Cargo.toml +++ b/test-virtual/wrkspc-dev/Cargo.toml @@ -14,3 +14,5 @@ publish = false [dependencies] wrkspc-macro.workspace = true +# inventory.workspace = true +macrotest.workspace = true diff --git a/test-virtual/wrkspc-macro/Cargo.toml b/test-virtual/wrkspc-macro/Cargo.toml index ebe79f0..3d4b9a6 100644 --- a/test-virtual/wrkspc-macro/Cargo.toml +++ b/test-virtual/wrkspc-macro/Cargo.toml @@ -20,6 +20,9 @@ proc-macro2.workspace = true quote.workspace = true syn.workspace = true +# wrkspc-test dependencies become dev-dependencies [dev-dependencies] +wrkspc-dev.workspace = true # wrkspc-test.workspace = true + macrotest.workspace = true diff --git a/test-virtual/wrkspc-macro/tests/expand/attribute.expanded.rs b/test-virtual/wrkspc-macro/tests/expand/attribute.expanded.rs index a444bfa..c37c39c 100644 --- a/test-virtual/wrkspc-macro/tests/expand/attribute.expanded.rs +++ b/test-virtual/wrkspc-macro/tests/expand/attribute.expanded.rs @@ -2,3 +2,4 @@ extern crate wrkspc_macro; struct Test; struct Hello; +fn main() {} diff --git a/test-virtual/wrkspc-macro/tests/expand/attribute.rs b/test-virtual/wrkspc-macro/tests/expand/attribute.rs index da39f56..e9d59bd 100644 --- a/test-virtual/wrkspc-macro/tests/expand/attribute.rs +++ b/test-virtual/wrkspc-macro/tests/expand/attribute.rs @@ -3,3 +3,5 @@ extern crate wrkspc_macro; #[my_attribute] struct Test; + +fn main() {} \ No newline at end of file diff --git a/test-virtual/wrkspc-macro/tests/expand/derive.expanded.rs b/test-virtual/wrkspc-macro/tests/expand/derive.expanded.rs index a444bfa..5a24c70 100644 --- a/test-virtual/wrkspc-macro/tests/expand/derive.expanded.rs +++ b/test-virtual/wrkspc-macro/tests/expand/derive.expanded.rs @@ -2,3 +2,4 @@ extern crate wrkspc_macro; struct Test; struct Hello; +fn main() {} \ No newline at end of file diff --git a/test-virtual/wrkspc-macro/tests/expand/derive.rs b/test-virtual/wrkspc-macro/tests/expand/derive.rs index da12e8d..2424b1c 100644 --- a/test-virtual/wrkspc-macro/tests/expand/derive.rs +++ b/test-virtual/wrkspc-macro/tests/expand/derive.rs @@ -3,3 +3,5 @@ extern crate wrkspc_macro; #[derive(MyDerive)] struct Test; + +fn main() {} \ No newline at end of file diff --git a/test-virtual/wrkspc-test/.gitignore b/test-virtual/wrkspc-test/.gitignore index c8f7745..5d09ab4 100644 --- a/test-virtual/wrkspc-test/.gitignore +++ b/test-virtual/wrkspc-test/.gitignore @@ -1,2 +1,3 @@ **/target **/*.rs.bk +**/.redo diff --git a/test-virtual/wrkspc-test/Cargo.toml b/test-virtual/wrkspc-test/Cargo.toml index 9f788e0..00128a5 100644 --- a/test-virtual/wrkspc-test/Cargo.toml +++ b/test-virtual/wrkspc-test/Cargo.toml @@ -1,38 +1,24 @@ [package] name = "wrkspc-test" +edition = "2021" publish = false -[lib] -path = "src/lib.rs" - -# [[bin]] -# name = "wrkspc-test" -# path = "src/main.rs" - [features] default = [] -test-feature = [] [dependencies] -wrkspc-dev.workspace = true -wrkspc-macro.workspace = true - -macrotest.workspace = true -inventory.workspace = true +wrkspc-macro = { path = "../wrkspc-macro" } [dev-dependencies] -wrkspc-dev.workspace = true -wrkspc-macro.workspace = true -macrotest.workspace = true -inventory.workspace = true - -# [[test]] -# name = "integration-tests" -# path = "src/main.rs" -# harness = false -# [[test]] -# name = "feature-test" -# path = "src/tests/feature.rs" -# harness = false +# Staged files are managed by the redo build system scripts +[[bin]] +name = "attribute" +path = "src/tests/expand/attribute.expanded.rs.staged" +[[bin]] +name = "derive" +path = "src/tests/expand/derive.expanded.rs.staged" +[[bin]] +name = "macro" +path = "src/tests/expand/macro.expanded.rs.staged" diff --git a/test-virtual/wrkspc-test/all.do b/test-virtual/wrkspc-test/all.do new file mode 100644 index 0000000..b367425 --- /dev/null +++ b/test-virtual/wrkspc-test/all.do @@ -0,0 +1,72 @@ +#!/usr/bin/env bash +# +# $1 is the target name, eg. pie.init +# $2 is the same as $1. +# $3 is the temporary output file to create. +# If this script succeeds, redo replaces $1 with $3. +# If this script fails, redo leaves $1 alone. + +set -x + +error_count=0 +error_messages="" + +# shellcheck shell=bash +exec >&2 + +REPO_DIR=$(git rev-parse --show-toplevel) +DEST_DIR="src/tests" + +cargo test --manifest-path ./../wrkspc-macro/Cargo.toml + +# Find files with the extension '.do' within a maximum depth of 2 directories. +# Remove the '.do' extension from the file names. +# Exclude the current script file. +# Finally, trigger the 'redo-ifchange' command for each file. +SELF=$(basename "${0##*/}" .do) +find . -maxdepth 2 -type f -name '*.do' -print0 | \ + xargs -0 echo | \ + sed -e 's/\.do//g' -e "s/\.\/$SELF//g" | \ + sed -e 's/\.do//g' -e "s/\.\/default//g" | \ + xargs redo-ifchange + +while IFS= read -r -d '' file; do + + source_file="${file%.rs}.expanded.rs" + + # Check if there is a corresponding .expanded.rs file + if [ ! -f "$source_file" ]; then + continue + fi + + # Get the relative path of the source file + rel_path=$(realpath --relative-to=${REPO_DIR}/test-virtual/wrkspc-macro/tests $file) + + expanded_file="${rel_path%.rs}.expanded.rs" + expanded_path="${DEST_DIR}/${expanded_file}" + + redo-ifchange "${source_file}" + + # If the source file has changed, redo the expanded file + if [ $? -eq 0 ]; then + redo "${expanded_path}" + if [ $? -eq 1 ]; then + error_count=$((error_count+1)) + error_messages="${error_messages}Error in file: ${source_file}\n" + fi + fi + +# Find all .rs files in the specified directory not ending in .expanded.rs. +# The -print0 option with find and -d '' option with read are used together +# to handle file names that contain spaces, newlines or other special characters. +# The ! -name "*.expanded.rs" is excluding any .rs files that end with .expanded.rs. +# This is important because we only want to process original .rs files, not +# ones that have been expanded. +# Changing this line could result in processing the wrong set of files. +done < <(find "${REPO_DIR}/test-virtual/wrkspc-macro/tests" -type f -name "*.rs" ! -name "*.expanded.rs" -print0) + +# Print all error messages +if [ $error_count -gt 0 ]; then + echo "Errors occurred in the incoming files:\n${error_messages}" >&2 + exit 1 +fi diff --git a/test-virtual/wrkspc-test/cargo-test.log b/test-virtual/wrkspc-test/cargo-test.log deleted file mode 100644 index 5b9c660..0000000 --- a/test-virtual/wrkspc-test/cargo-test.log +++ /dev/null @@ -1,178 +0,0 @@ - -running 0 tests - -test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s - - -running 1 test -test wrkspc_test ... ok - -test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s - - -running 0 tests - -test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s - - -running 1 test -test wrkspc_test ... ok - -test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s - - -running 0 tests - -test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s - - -running 1 test -tests/expand/attribute.rs - ok -tests/expand/derive.rs - ok -tests/expand/macro.rs - ok -test pass ... ok - -test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 2.73s - - -running 0 tests - -test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s - - -running 0 tests - -test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s - - -running 4 tests -test pass ... FAILED -test fail_expect_expanded - should panic ... ok -test pr61 ... FAILED -test pass_expect_expanded ... FAILED - -failures: - ----- pass stdout ---- -Running 4 macro expansion tests -Expansion error: -warning: `/home/hedge/src/macrotest/test-virtual/target/tests/wrkspc-test/macrotest000/.cargo/config` is deprecated in favor of `config.toml` -note: if you need to support cargo 1.38 or earlier, you can symlink `config` to `config.toml` -error: failed to parse manifest at `/home/hedge/src/macrotest/test-virtual/target/tests/wrkspc-test/macrotest000/Cargo.toml` -Caused by: - error inheriting `inventory` from workspace root manifest's `workspace.dependencies.inventory` -Caused by: - `workspace.dependencies` was not defined - -Expansion error: -warning: `/home/hedge/src/macrotest/test-virtual/target/tests/wrkspc-test/macrotest000/.cargo/config` is deprecated in favor of `config.toml` -note: if you need to support cargo 1.38 or earlier, you can symlink `config` to `config.toml` -error: failed to parse manifest at `/home/hedge/src/macrotest/test-virtual/target/tests/wrkspc-test/macrotest000/Cargo.toml` -Caused by: - error inheriting `inventory` from workspace root manifest's `workspace.dependencies.inventory` -Caused by: - `workspace.dependencies` was not defined - -Expansion error: -warning: `/home/hedge/src/macrotest/test-virtual/target/tests/wrkspc-test/macrotest000/.cargo/config` is deprecated in favor of `config.toml` -note: if you need to support cargo 1.38 or earlier, you can symlink `config` to `config.toml` -error: failed to parse manifest at `/home/hedge/src/macrotest/test-virtual/target/tests/wrkspc-test/macrotest000/Cargo.toml` -Caused by: - error inheriting `inventory` from workspace root manifest's `workspace.dependencies.inventory` -Caused by: - `workspace.dependencies` was not defined - -Expansion error: -warning: `/home/hedge/src/macrotest/test-virtual/target/tests/wrkspc-test/macrotest000/.cargo/config` is deprecated in favor of `config.toml` -note: if you need to support cargo 1.38 or earlier, you can symlink `config` to `config.toml` -error: failed to parse manifest at `/home/hedge/src/macrotest/test-virtual/target/tests/wrkspc-test/macrotest000/Cargo.toml` -Caused by: - error inheriting `inventory` from workspace root manifest's `workspace.dependencies.inventory` -Caused by: - `workspace.dependencies` was not defined - - - - -thread 'pass' panicked at /home/hedge/src/macrotest/src/expand.rs:173:9: -4 of 4 tests failed -note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace - ----- pr61 stdout ---- -Running 2 macro expansion tests -Expansion error: -warning: `/home/hedge/src/macrotest/test-virtual/target/tests/wrkspc-test/macrotest003/.cargo/config` is deprecated in favor of `config.toml` -note: if you need to support cargo 1.38 or earlier, you can symlink `config` to `config.toml` -error: failed to parse manifest at `/home/hedge/src/macrotest/test-virtual/target/tests/wrkspc-test/macrotest003/Cargo.toml` -Caused by: - error inheriting `inventory` from workspace root manifest's `workspace.dependencies.inventory` -Caused by: - `workspace.dependencies` was not defined - -Expansion error: -warning: `/home/hedge/src/macrotest/test-virtual/target/tests/wrkspc-test/macrotest003/.cargo/config` is deprecated in favor of `config.toml` -note: if you need to support cargo 1.38 or earlier, you can symlink `config` to `config.toml` -error: failed to parse manifest at `/home/hedge/src/macrotest/test-virtual/target/tests/wrkspc-test/macrotest003/Cargo.toml` -Caused by: - error inheriting `inventory` from workspace root manifest's `workspace.dependencies.inventory` -Caused by: - `workspace.dependencies` was not defined - - - - -thread 'pr61' panicked at /home/hedge/src/macrotest/src/expand.rs:173:9: -2 of 2 tests failed - ----- pass_expect_expanded stdout ---- -Running 4 macro expansion tests -Expansion error: -warning: `/home/hedge/src/macrotest/test-virtual/target/tests/wrkspc-test/macrotest002/.cargo/config` is deprecated in favor of `config.toml` -note: if you need to support cargo 1.38 or earlier, you can symlink `config` to `config.toml` -error: failed to parse manifest at `/home/hedge/src/macrotest/test-virtual/target/tests/wrkspc-test/macrotest002/Cargo.toml` -Caused by: - error inheriting `inventory` from workspace root manifest's `workspace.dependencies.inventory` -Caused by: - `workspace.dependencies` was not defined - -Expansion error: -warning: `/home/hedge/src/macrotest/test-virtual/target/tests/wrkspc-test/macrotest002/.cargo/config` is deprecated in favor of `config.toml` -note: if you need to support cargo 1.38 or earlier, you can symlink `config` to `config.toml` -error: failed to parse manifest at `/home/hedge/src/macrotest/test-virtual/target/tests/wrkspc-test/macrotest002/Cargo.toml` -Caused by: - error inheriting `inventory` from workspace root manifest's `workspace.dependencies.inventory` -Caused by: - `workspace.dependencies` was not defined - -Expansion error: -warning: `/home/hedge/src/macrotest/test-virtual/target/tests/wrkspc-test/macrotest002/.cargo/config` is deprecated in favor of `config.toml` -note: if you need to support cargo 1.38 or earlier, you can symlink `config` to `config.toml` -error: failed to parse manifest at `/home/hedge/src/macrotest/test-virtual/target/tests/wrkspc-test/macrotest002/Cargo.toml` -Caused by: - error inheriting `inventory` from workspace root manifest's `workspace.dependencies.inventory` -Caused by: - `workspace.dependencies` was not defined - -Expansion error: -warning: `/home/hedge/src/macrotest/test-virtual/target/tests/wrkspc-test/macrotest002/.cargo/config` is deprecated in favor of `config.toml` -note: if you need to support cargo 1.38 or earlier, you can symlink `config` to `config.toml` -error: failed to parse manifest at `/home/hedge/src/macrotest/test-virtual/target/tests/wrkspc-test/macrotest002/Cargo.toml` -Caused by: - error inheriting `inventory` from workspace root manifest's `workspace.dependencies.inventory` -Caused by: - `workspace.dependencies` was not defined - - - - -thread 'pass_expect_expanded' panicked at /home/hedge/src/macrotest/src/expand.rs:173:9: -4 of 4 tests failed - - -failures: - pass - pass_expect_expanded - pr61 - -test result: FAILED. 1 passed; 3 failed; 0 ignored; 0 measured; 0 filtered out; finished in 5.74s - diff --git a/test-virtual/wrkspc-test/default.do b/test-virtual/wrkspc-test/default.do new file mode 100644 index 0000000..9b29916 --- /dev/null +++ b/test-virtual/wrkspc-test/default.do @@ -0,0 +1,34 @@ +#!/usr/bin/env bash +set -x + +# Define the source and destination directories +REPO_DIR=$(git rev-parse --show-toplevel) +SRC_DIR="${REPO_DIR}/test-virtual/wrkspc-macro" +DEST_DIR="${REPO_DIR}/test-virtual/wrkspc-test" + +exp_file="${DEST_DIR}/${1}" + +# Use basename to get the filename from the path +bin_file=$(basename "$exp_file") + +# Use cut to remove the .expanded.rs extension +bin_name=$(echo "$bin_file" | cut -f 1 -d '.') + +# Get the relative path of the source file +rel_path=$(realpath --relative-to="${DEST_DIR}/src" $exp_file) +src_file="${SRC_DIR}/${rel_path}" + +if [ -e "${src_file}" ]; then + cp --force "${src_file}" "${exp_file}.staged" + # A source expanded file exists. Build. + cat "${src_file}" >"$3" +else + echo "$0: Fatal: don't know how to build '$1'" >&2 + exit 99 +fi + +cargo build --release --bin "${bin_name}" + +if [ $? -eq 0 ]; then + rm --force "${exp_file}.staged" +fi diff --git a/test-virtual/wrkspc-test/src/_main.rs b/test-virtual/wrkspc-test/src/_main.rs deleted file mode 100644 index ffa5edc..0000000 --- a/test-virtual/wrkspc-test/src/_main.rs +++ /dev/null @@ -1,26 +0,0 @@ - -pub use crate::prelude::*; - -fn setup() { - println!("Setup") -} - -fn teardown() { - println!("Teardown") -} -// NOTE: -// When this code is in src/main.rs, it is executed by `cargo test -- --list`. -// In such cases you could guard it: -// #[cfg(feature = "integration")] -fn main() { - // Setup test environment - setup(); - - // Run the tests - for t in inventory::iter:: { - (t.test_fn)() - } - - // Teardown test environment - teardown(); -} diff --git a/test-virtual/wrkspc-test/src/lib.rs b/test-virtual/wrkspc-test/src/lib.rs deleted file mode 100644 index f48d3e0..0000000 --- a/test-virtual/wrkspc-test/src/lib.rs +++ /dev/null @@ -1,36 +0,0 @@ -pub mod tests; -pub mod prelude; - -pub use prelude::*; - -#[macro_export] -macro_rules! test_vec { - () => { - Vec::new() - }; - ( $( $x:expr ),+ ) => { - { - let mut temp_vec = Vec::new(); - $( - temp_vec.push($x); - )* - temp_vec - } - }; -} - -#[macro_export] -macro_rules! test_feature_vec { - () => { - Vec::new() - }; - ( $( $x:expr ),+ ) => { - { - let mut temp_vec = Vec::new(); - $( - temp_vec.push($x); - )* - temp_vec - } - }; -} diff --git a/test-virtual/wrkspc-test/src/prelude.rs b/test-virtual/wrkspc-test/src/prelude.rs deleted file mode 100644 index 02bc223..0000000 --- a/test-virtual/wrkspc-test/src/prelude.rs +++ /dev/null @@ -1 +0,0 @@ -pub use crate::tests::IntegrationTest; diff --git a/test-virtual/wrkspc-test/src/tests/basic.rs b/test-virtual/wrkspc-test/src/tests/basic.rs deleted file mode 100644 index 0df6c90..0000000 --- a/test-virtual/wrkspc-test/src/tests/basic.rs +++ /dev/null @@ -1,10 +0,0 @@ -use crate::IntegrationTest; - -fn basic_test() { - println!("Running basic test") -} - -inventory::submit!(IntegrationTest { - name: "basic", - test_fn: basic_test -}); diff --git a/test-virtual/wrkspc-test/src/tests/expand/attribute.expanded.rs b/test-virtual/wrkspc-test/src/tests/expand/attribute.expanded.rs new file mode 100644 index 0000000..c37c39c --- /dev/null +++ b/test-virtual/wrkspc-test/src/tests/expand/attribute.expanded.rs @@ -0,0 +1,5 @@ +#[macro_use] +extern crate wrkspc_macro; +struct Test; +struct Hello; +fn main() {} diff --git a/test-virtual/wrkspc-test/src/tests/expand/derive.expanded.rs b/test-virtual/wrkspc-test/src/tests/expand/derive.expanded.rs new file mode 100644 index 0000000..5a24c70 --- /dev/null +++ b/test-virtual/wrkspc-test/src/tests/expand/derive.expanded.rs @@ -0,0 +1,5 @@ +#[macro_use] +extern crate wrkspc_macro; +struct Test; +struct Hello; +fn main() {} \ No newline at end of file diff --git a/test-virtual/wrkspc-test/src/tests/feature/expanded/with_args.rs b/test-virtual/wrkspc-test/src/tests/expand/macro.expanded.rs similarity index 55% rename from test-virtual/wrkspc-test/src/tests/feature/expanded/with_args.rs rename to test-virtual/wrkspc-test/src/tests/expand/macro.expanded.rs index 12128b9..b48da90 100644 --- a/test-virtual/wrkspc-test/src/tests/feature/expanded/with_args.rs +++ b/test-virtual/wrkspc-test/src/tests/expand/macro.expanded.rs @@ -1,9 +1,6 @@ -// #![cfg(feature = "test-feature")] - #[macro_use] extern crate wrkspc_macro; - pub fn main() { - #[my_attribute] struct Test; + struct Hello; } diff --git a/test-virtual/wrkspc-test/src/tests/feature.rs b/test-virtual/wrkspc-test/src/tests/feature.rs deleted file mode 100644 index 62ea6c2..0000000 --- a/test-virtual/wrkspc-test/src/tests/feature.rs +++ /dev/null @@ -1,46 +0,0 @@ -pub use crate::prelude::*; - -fn feature_test() { - println!("Running feature test") -} - -inventory::submit!(IntegrationTest { - name: "feature", - test_fn: feature_test -}); - -pub fn pass_args() { - macrotest::expand("src/tests/feature/expanded/*.rs"); -} -inventory::submit!(IntegrationTest { - name: "feature", - test_fn: pass_args -}); - -// pub fn pass_expect_expanded_args() { -// // If you delete one of the `.expanded.rs` files, this test will fail. -// macrotest::expand_args( -// "integration/tests/feature/expanded/*.rs", -// &["--features", "test-feature"], -// ); -// } -// inventory::submit!(IntegrationTest { -// name: "feature", -// test_fn: pass_expect_expanded_args -// }); - -// Suspended panicky tests for the moment -// -// pub fn fail_expect_expanded_args() { -// // This directory doesn't have expanded files but since they're expected, the test will fail. -// macrotest::expand_without_refresh_args( -// "integration/tests/feature/unchanged/*.rs", -// &["--features", "test-feature"], -// ); -// } -// inventory::submit!(IntegrationTest { -// name: "feature", -// test_fn: fail_expect_expanded_args -// }); - -pub fn main() {} diff --git a/test-virtual/wrkspc-test/src/tests/feature/unchanged/with_args.expanded.rs b/test-virtual/wrkspc-test/src/tests/feature/unchanged/with_args.expanded.rs deleted file mode 100644 index e760c93..0000000 --- a/test-virtual/wrkspc-test/src/tests/feature/unchanged/with_args.expanded.rs +++ /dev/null @@ -1,13 +0,0 @@ -extern crate std; -#[macro_use] -extern crate test_project; -pub fn main() { - { - let mut temp_vec = Vec::new(); - temp_vec.push(1); - temp_vec.push(2); - temp_vec.push(3); - temp_vec - // error - }; -} diff --git a/test-virtual/wrkspc-test/src/tests/feature/unchanged/with_args.rs b/test-virtual/wrkspc-test/src/tests/feature/unchanged/with_args.rs deleted file mode 100644 index dc17120..0000000 --- a/test-virtual/wrkspc-test/src/tests/feature/unchanged/with_args.rs +++ /dev/null @@ -1,8 +0,0 @@ -#![cfg(feature = "test-feature")] - -#[macro_use] -extern crate test_project; - -pub fn main() { - test_feature_vec![1, 2, 3]; -} diff --git a/test-virtual/wrkspc-test/src/tests/mod.rs b/test-virtual/wrkspc-test/src/tests/mod.rs deleted file mode 100644 index 605994e..0000000 --- a/test-virtual/wrkspc-test/src/tests/mod.rs +++ /dev/null @@ -1,10 +0,0 @@ -pub mod basic; -pub mod feature; - -#[derive(Debug)] -pub struct IntegrationTest { - pub name: &'static str, - pub test_fn: fn(), -} - -inventory::collect!(IntegrationTest); diff --git a/test-virtual/wrkspc-test/tests/expand/first.expanded.rs b/test-virtual/wrkspc-test/tests/expand/first.expanded.rs deleted file mode 100644 index 584bf25..0000000 --- a/test-virtual/wrkspc-test/tests/expand/first.expanded.rs +++ /dev/null @@ -1,5 +0,0 @@ -#[macro_use] -extern crate test_project; -pub fn main() { - Vec::new(); -} diff --git a/test-virtual/wrkspc-test/tests/expand/first.rs b/test-virtual/wrkspc-test/tests/expand/first.rs deleted file mode 100644 index 5f3c0eb..0000000 --- a/test-virtual/wrkspc-test/tests/expand/first.rs +++ /dev/null @@ -1,6 +0,0 @@ -#[macro_use] -extern crate test_project; - -pub fn main() { - test_vec![]; -} diff --git a/test-virtual/wrkspc-test/tests/expand/fourth.expanded.rs b/test-virtual/wrkspc-test/tests/expand/fourth.expanded.rs deleted file mode 100644 index 91ad4bd..0000000 --- a/test-virtual/wrkspc-test/tests/expand/fourth.expanded.rs +++ /dev/null @@ -1,11 +0,0 @@ -#[macro_use] -extern crate test_project; -pub fn main() { - { - let mut temp_vec = Vec::new(); - temp_vec.push(1); - temp_vec.push(2); - temp_vec.push(3); - temp_vec - }; -} diff --git a/test-virtual/wrkspc-test/tests/expand/fourth.rs b/test-virtual/wrkspc-test/tests/expand/fourth.rs deleted file mode 100644 index 3c50cc1..0000000 --- a/test-virtual/wrkspc-test/tests/expand/fourth.rs +++ /dev/null @@ -1,6 +0,0 @@ -#[macro_use] -extern crate test_project; - -pub fn main() { - test_vec![1, 2, 3]; -} diff --git a/test-virtual/wrkspc-test/tests/expand/second.expanded.rs b/test-virtual/wrkspc-test/tests/expand/second.expanded.rs deleted file mode 100644 index f57dd2f..0000000 --- a/test-virtual/wrkspc-test/tests/expand/second.expanded.rs +++ /dev/null @@ -1,9 +0,0 @@ -#[macro_use] -extern crate test_project; -pub fn main() { - { - let mut temp_vec = Vec::new(); - temp_vec.push(1); - temp_vec - }; -} diff --git a/test-virtual/wrkspc-test/tests/expand/second.rs b/test-virtual/wrkspc-test/tests/expand/second.rs deleted file mode 100644 index b7d0e43..0000000 --- a/test-virtual/wrkspc-test/tests/expand/second.rs +++ /dev/null @@ -1,6 +0,0 @@ -#[macro_use] -extern crate test_project; - -pub fn main() { - test_vec![1]; -} diff --git a/test-virtual/wrkspc-test/tests/expand/third.expanded.rs b/test-virtual/wrkspc-test/tests/expand/third.expanded.rs deleted file mode 100644 index 3fba475..0000000 --- a/test-virtual/wrkspc-test/tests/expand/third.expanded.rs +++ /dev/null @@ -1,10 +0,0 @@ -#[macro_use] -extern crate test_project; -pub fn main() { - { - let mut temp_vec = Vec::new(); - temp_vec.push(1); - temp_vec.push(2); - temp_vec - }; -} diff --git a/test-virtual/wrkspc-test/tests/expand/third.rs b/test-virtual/wrkspc-test/tests/expand/third.rs deleted file mode 100644 index bc440e0..0000000 --- a/test-virtual/wrkspc-test/tests/expand/third.rs +++ /dev/null @@ -1,6 +0,0 @@ -#[macro_use] -extern crate test_project; - -pub fn main() { - test_vec![1, 2]; -} diff --git a/test-virtual/wrkspc-test/tests/expand_args/with_args.rs b/test-virtual/wrkspc-test/tests/expand_args/with_args.rs deleted file mode 100644 index 7a78410..0000000 --- a/test-virtual/wrkspc-test/tests/expand_args/with_args.rs +++ /dev/null @@ -1,6 +0,0 @@ -#[macro_use] -extern crate wkspc_test; - -pub fn main() { - test_feature_vec![1, 2, 3]; -} diff --git a/test-virtual/wrkspc-test/tests/no_expanded/first.rs b/test-virtual/wrkspc-test/tests/no_expanded/first.rs deleted file mode 100644 index c8a8cdf..0000000 --- a/test-virtual/wrkspc-test/tests/no_expanded/first.rs +++ /dev/null @@ -1,6 +0,0 @@ -#[macro_use] -extern crate test_virtual; - -pub fn main() { - test_vec![]; -} diff --git a/test-virtual/wrkspc-test/tests/no_expanded/fourth.rs b/test-virtual/wrkspc-test/tests/no_expanded/fourth.rs deleted file mode 100644 index 82ad356..0000000 --- a/test-virtual/wrkspc-test/tests/no_expanded/fourth.rs +++ /dev/null @@ -1,6 +0,0 @@ -#[macro_use] -extern crate test_virtual; - -pub fn main() { - test_vec![1, 2, 3]; -} diff --git a/test-virtual/wrkspc-test/tests/no_expanded/second.rs b/test-virtual/wrkspc-test/tests/no_expanded/second.rs deleted file mode 100644 index 9f96b62..0000000 --- a/test-virtual/wrkspc-test/tests/no_expanded/second.rs +++ /dev/null @@ -1,6 +0,0 @@ -#[macro_use] -extern crate test_virtual; - -pub fn main() { - test_vec![1]; -} diff --git a/test-virtual/wrkspc-test/tests/no_expanded/third.rs b/test-virtual/wrkspc-test/tests/no_expanded/third.rs deleted file mode 100644 index 2eda910..0000000 --- a/test-virtual/wrkspc-test/tests/no_expanded/third.rs +++ /dev/null @@ -1,6 +0,0 @@ -#[macro_use] -extern crate test_virtual; - -pub fn main() { - test_vec![1, 2]; -} diff --git a/test-virtual/wrkspc-test/tests/no_expanded_args/with_args.rs b/test-virtual/wrkspc-test/tests/no_expanded_args/with_args.rs deleted file mode 100644 index f4b3018..0000000 --- a/test-virtual/wrkspc-test/tests/no_expanded_args/with_args.rs +++ /dev/null @@ -1,8 +0,0 @@ -#![cfg(feature = "test-feature")] - -#[macro_use] -extern crate test_virtual; - -pub fn main() { - test_feature_vec![1, 2, 3]; -} diff --git a/test-virtual/wrkspc-test/tests/par_tests_regression.rs b/test-virtual/wrkspc-test/tests/par_tests_regression.rs deleted file mode 100644 index 4e66042..0000000 --- a/test-virtual/wrkspc-test/tests/par_tests_regression.rs +++ /dev/null @@ -1,18 +0,0 @@ -// The tests were interfering with each other when run in parallel. -// This regression test module will ensure that parallel use case is handled. - -// Suspend parallel test execution while we implement the integration -// test harness. -// -// #[test] -// pub fn parallel_1() { -// macrotest::expand("tests/expand/first.rs"); -// } - -// Suspend parallel test execution while we implement the integration -// test harness. -// -// #[test] -// pub fn parallel_2() { -// macrotest::expand("tests/expand/second.rs"); -// } diff --git a/test-virtual/wrkspc-test/tests/pr61/a/test.expanded.rs b/test-virtual/wrkspc-test/tests/pr61/a/test.expanded.rs deleted file mode 100644 index ab55554..0000000 --- a/test-virtual/wrkspc-test/tests/pr61/a/test.expanded.rs +++ /dev/null @@ -1,5 +0,0 @@ -#[macro_use] -extern crate test_virtual; -pub fn main() { - Vec::new(); -} diff --git a/test-virtual/wrkspc-test/tests/pr61/a/test.rs b/test-virtual/wrkspc-test/tests/pr61/a/test.rs deleted file mode 100644 index c8a8cdf..0000000 --- a/test-virtual/wrkspc-test/tests/pr61/a/test.rs +++ /dev/null @@ -1,6 +0,0 @@ -#[macro_use] -extern crate test_virtual; - -pub fn main() { - test_vec![]; -} diff --git a/test-virtual/wrkspc-test/tests/pr61/b/test.expanded.rs b/test-virtual/wrkspc-test/tests/pr61/b/test.expanded.rs deleted file mode 100644 index ab55554..0000000 --- a/test-virtual/wrkspc-test/tests/pr61/b/test.expanded.rs +++ /dev/null @@ -1,5 +0,0 @@ -#[macro_use] -extern crate test_virtual; -pub fn main() { - Vec::new(); -} diff --git a/test-virtual/wrkspc-test/tests/pr61/b/test.rs b/test-virtual/wrkspc-test/tests/pr61/b/test.rs deleted file mode 100644 index c8a8cdf..0000000 --- a/test-virtual/wrkspc-test/tests/pr61/b/test.rs +++ /dev/null @@ -1,6 +0,0 @@ -#[macro_use] -extern crate test_virtual; - -pub fn main() { - test_vec![]; -} diff --git a/test-virtual/wrkspc-test/tests/tests.rs b/test-virtual/wrkspc-test/tests/tests.rs deleted file mode 100644 index be42fbc..0000000 --- a/test-virtual/wrkspc-test/tests/tests.rs +++ /dev/null @@ -1,44 +0,0 @@ -#[test] -pub fn pass() { - macrotest::expand("tests/expand/*.rs"); -} - -#[test] -pub fn pass_expect_expanded() { - // If you delete one of the `.expanded.rs` files, this test will fail. - macrotest::expand_without_refresh("tests/expand/*.rs"); -} - -#[test] -#[should_panic] -pub fn fail_expect_expanded() { - // This directory doesn't have expanded files and since they're expected, the test will fail. - macrotest::expand_without_refresh("tests/no_expanded/*.rs"); -} - -// #[test] -// pub fn pass_args() { -// macrotest::expand_args("tests/expand_args/*.rs", &["--features", "test-feature"]); -// } - -// #[test] -// pub fn pass_expect_expanded_args() { -// // If you delete one of the `.expanded.rs` files, this test will fail. -// macrotest::expand_args("tests/expand_args/*.rs", &["--features", "test-feature"]); -// } - -// #[test] -// #[should_panic] -// pub fn fail_expect_expanded_args() { -// // This directory doesn't have expanded files but since they're expected, the test will fail. -// macrotest::expand_without_refresh_args( -// "tests/no_expanded_args/*.rs", -// &["--features", "test-feature"], -// ); -// } - -// https://github.com/eupn/macrotest/pull/61 -#[test] -pub fn pr61() { - macrotest::expand("tests/pr61/*/*.rs"); -} diff --git a/test-virtual/wrkspc/Cargo.toml b/test-virtual/wrkspc/Cargo.toml index cbb4820..68dc4a8 100644 --- a/test-virtual/wrkspc/Cargo.toml +++ b/test-virtual/wrkspc/Cargo.toml @@ -14,13 +14,13 @@ publish = false [dependencies] -wrkspc-dev = { path = "wrkspc-dev" } -wrkspc-macro = { path = "wrkspc-macro" } -wrkspc-test = { path = "wrkspc-test" } +wrkspc-dev.workspace = true +wrkspc-macro.workspace = true +wrkspc-test.workspace = true -macrotest = { path = "../" } +macrotest.workspace = true -inventory = "0.3" -proc-macro2 = "1.0" -quote = "1" -syn = "2.0" +# inventory.workspace = true +proc-macro2.workspace = true +quote.workspace = true +syn.workspace = true From c6c6809533b1e2d5a04fa1d13920491fd9fb7d6d Mon Sep 17 00:00:00 2001 From: Mark Van de Vyver Date: Thu, 14 Mar 2024 21:25:41 +1100 Subject: [PATCH 12/15] Update wrkspc-test to fit into the workspace integrated test harness Signed-off-by: Mark Van de Vyver --- test-virtual/README.md | 2 +- test-virtual/wrkspc-test/all.do | 24 +++++++++++++++--------- test-virtual/wrkspc-test/default.do | 12 +++++++++--- 3 files changed, 25 insertions(+), 13 deletions(-) diff --git a/test-virtual/README.md b/test-virtual/README.md index 8e09f59..bf0dbc8 100644 --- a/test-virtual/README.md +++ b/test-virtual/README.md @@ -13,6 +13,6 @@ Where each crate is: - `wrkspc-dev`: A "Hello world" style library for development (not for release). - `wrkspc-macro`: The `test-promacro-project` adjusted to fit into the workspace plugin-test harness. This crate provides a declarative `test_vec![]` macro to test its expansion under the [tests](tests) directory with [`macrostest`](https://crates.io/crates/macrotest). -- `wrkspc-test`: The `test-project` adjusted to fit into the workspace plugin-test harness. +- `wrkspc-test`: The `test-project` adjusted to fit into the workspace integrated test harness. Test harness for integration tests as plugins, is per the [Infinyon/Fluvio](https://www.infinyon.com/blog/2021/04/rust-custom-test-harness/) setup. diff --git a/test-virtual/wrkspc-test/all.do b/test-virtual/wrkspc-test/all.do index b367425..b441f57 100644 --- a/test-virtual/wrkspc-test/all.do +++ b/test-virtual/wrkspc-test/all.do @@ -3,26 +3,29 @@ # $1 is the target name, eg. pie.init # $2 is the same as $1. # $3 is the temporary output file to create. -# If this script succeeds, redo replaces $1 with $3. -# If this script fails, redo leaves $1 alone. +# If a .do script succeeds, redo replaces $1 with $3. +# If a .do script fails, redo leaves $1 alone. -set -x +# shellcheck shell=bash +#set -x -error_count=0 -error_messages="" +# Exit on error +set -e -# shellcheck shell=bash exec >&2 +error_count=0 +error_messages="" + REPO_DIR=$(git rev-parse --show-toplevel) DEST_DIR="src/tests" -cargo test --manifest-path ./../wrkspc-macro/Cargo.toml +cargo test --manifest-path ./../wrkspc-macro/Cargo.toml &>target/wrkspc-test-test.log # Find files with the extension '.do' within a maximum depth of 2 directories. # Remove the '.do' extension from the file names. # Exclude the current script file. -# Finally, trigger the 'redo-ifchange' command for each file. +# Finally, invoke the 'redo-ifchange' command for each file. SELF=$(basename "${0##*/}" .do) find . -maxdepth 2 -type f -name '*.do' -print0 | \ xargs -0 echo | \ @@ -62,7 +65,10 @@ while IFS= read -r -d '' file; do # The ! -name "*.expanded.rs" is excluding any .rs files that end with .expanded.rs. # This is important because we only want to process original .rs files, not # ones that have been expanded. -# Changing this line could result in processing the wrong set of files. +# +# Use process substitution (`<(command)`) instead of a pipe. +# This will allow the `while` loop to run in the current shell and preserve +# changes to the variables `${error_count}` and `${error_messages}` . done < <(find "${REPO_DIR}/test-virtual/wrkspc-macro/tests" -type f -name "*.rs" ! -name "*.expanded.rs" -print0) # Print all error messages diff --git a/test-virtual/wrkspc-test/default.do b/test-virtual/wrkspc-test/default.do index 9b29916..5fec608 100644 --- a/test-virtual/wrkspc-test/default.do +++ b/test-virtual/wrkspc-test/default.do @@ -1,5 +1,11 @@ #!/usr/bin/env bash -set -x +# shellcheck shell=bash +#set -x + +# Exit on error +set -e + +exec >&2 # Define the source and destination directories REPO_DIR=$(git rev-parse --show-toplevel) @@ -19,15 +25,15 @@ rel_path=$(realpath --relative-to="${DEST_DIR}/src" $exp_file) src_file="${SRC_DIR}/${rel_path}" if [ -e "${src_file}" ]; then - cp --force "${src_file}" "${exp_file}.staged" # A source expanded file exists. Build. + cp --force "${src_file}" "${exp_file}.staged" cat "${src_file}" >"$3" else echo "$0: Fatal: don't know how to build '$1'" >&2 exit 99 fi -cargo build --release --bin "${bin_name}" +cargo build --release --bin "${bin_name}" &>target/wrkspc-test-build.log if [ $? -eq 0 ]; then rm --force "${exp_file}.staged" From 8659fc5e22701c1fe13b678bd7020402ac12b26f Mon Sep 17 00:00:00 2001 From: Mark Van de Vyver Date: Tue, 19 Mar 2024 20:03:54 +1100 Subject: [PATCH 13/15] Remove unused code and update dependencies Signed-off-by: Mark Van de Vyver --- test-virtual/Cargo.toml | 1 - test-virtual/README.md | 87 ++++++++++- test-virtual/TESTCONTAINERS.md | 137 ++++++++++++++++++ test-virtual/wrkspc-macro/tests/attribute.rs | 4 + test-virtual/wrkspc-macro/tests/derive.rs | 4 + .../wrkspc-macro/tests/expand/derive.rs | 2 - test-virtual/wrkspc-macro/tests/macro.rs | 4 + test-virtual/wrkspc-macro/tests/tests.rs | 4 - test-virtual/wrkspc-test/Cargo.toml | 3 +- test-virtual/wrkspc-test/all.do | 79 +++------- test-virtual/wrkspc-test/default.do | 39 ++--- test-virtual/wrkspc-test/default.expand.do | 16 ++ .../src/tests/expand/attribute.expanded.rs | 5 - .../src/tests/expand/derive.expanded.rs | 5 - .../src/tests/expand/macro.expanded.rs | 6 - 15 files changed, 290 insertions(+), 106 deletions(-) create mode 100644 test-virtual/TESTCONTAINERS.md create mode 100644 test-virtual/wrkspc-macro/tests/attribute.rs create mode 100644 test-virtual/wrkspc-macro/tests/derive.rs create mode 100644 test-virtual/wrkspc-macro/tests/macro.rs delete mode 100644 test-virtual/wrkspc-macro/tests/tests.rs create mode 100644 test-virtual/wrkspc-test/default.expand.do diff --git a/test-virtual/Cargo.toml b/test-virtual/Cargo.toml index f5142a3..c5724bb 100644 --- a/test-virtual/Cargo.toml +++ b/test-virtual/Cargo.toml @@ -28,7 +28,6 @@ wrkspc-test = { path = "wrkspc-test" } macrotest = { path = "../" } -inventory = "0.3" proc-macro2 = "1.0" quote = "1" syn = "2.0" diff --git a/test-virtual/README.md b/test-virtual/README.md index bf0dbc8..56c5e02 100644 --- a/test-virtual/README.md +++ b/test-virtual/README.md @@ -7,7 +7,7 @@ This is an example virtual-workspace that contains crates: - `wrkspc-macro` - `wrkspc-test` -Where each crate is: +Where: - `wrkspc`: A "Hello world" style library (for release as a crate). - `wrkspc-dev`: A "Hello world" style library for development (not for release). @@ -15,4 +15,87 @@ Where each crate is: to test its expansion under the [tests](tests) directory with [`macrostest`](https://crates.io/crates/macrotest). - `wrkspc-test`: The `test-project` adjusted to fit into the workspace integrated test harness. -Test harness for integration tests as plugins, is per the [Infinyon/Fluvio](https://www.infinyon.com/blog/2021/04/rust-custom-test-harness/) setup. +The integration test harness, `wkspc-test`, uses [DJB's redo build system](https://cr.yp.to/redo.html), as implemented by [apenwarr](https://github.com/apenwarr/redo/) and as ported to Rust by [zombiezen](https://github.com/zombiezen/redo-rs). + +In this build process `all.do` flows to a generic build step `default.do`. Hence, `all.do` is responsible for iterating over all source files and `default.do` is responsible for processing each individual file. The `default.do` is kept generic by adhering to some naming conventions, shared between the macro and test crates: + +In this setup: + +- `all.do` is the starting point of the build process. +- `default.do` is called by `all.do` for each source file. +- `default.do` processes each file by: + - Extracting the filename from the path using `basename`, resulting in `bin`. + - Removing the `.expanded.rs` extension using `cut`, resulting in `bin`. + +Please note that this is a simplified diagram and the actual build process may involve more steps. + +```mermaid +graph TD + A[all.do] -->|Iterates over all source files| B[default.do] + B --> C{Processes each file} + C -->|1. Extracts filename from path| D[basename] + D --> E[bin] + C -->|2. Removes .expanded.rs extension| F[cut] + F --> G[bin] +``` + +## Containers + +To run Testcontainers-based tests, +you need a Docker-API compatible container runtime, +such as using [Testcontainers Cloud](https://www.testcontainers.cloud/) or installing [Podman](https://podman.io/) or Docker locally. [Testcontainers Desktop](https://testcontainers.com/desktop/) takes care of most of the manual configuration for alternative runtimes. See [Customizing Docker host detection](#customizing-docker-host-detection) for general configuration mechanisms. + +### Podman + +In order to run testcontainers against [podman](https://podman.io/) the env vars bellow should be set + +MacOS: + +```bash +{% raw %} +export DOCKER_HOST=unix://$(podman machine inspect --format '{{.ConnectionInfo.PodmanSocket.Path}}') +export TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE=/var/run/docker.sock +{% endraw %} +``` + +Linux: + +```bash +export DOCKER_HOST=unix://${XDG_RUNTIME_DIR}/podman/podman.sock +``` + +If you're running Podman in rootless mode, ensure to include the following line to disable Ryuk: + +```bash +export TESTCONTAINERS_RYUK_DISABLED=true +``` + +!!! note + Previous to version 1.19.0, `export TESTCONTAINERS_RYUK_PRIVILEGED=true` + was required for rootful mode. Starting with 1.19.0, this is no longer required. + +### Container environment discovery + +Testcontainers will try to connect to a Docker daemon using the following strategies in order: + +- Environment variables: + - `DOCKER_HOST` + - `DOCKER_TLS_VERIFY` + - `DOCKER_CERT_PATH` +- Defaults: + - `DOCKER_HOST=https://localhost:2376` + - `DOCKER_TLS_VERIFY=1` + - `DOCKER_CERT_PATH=~/.docker` +- If Docker Machine is installed, the docker machine environment for the *first* machine found. Docker Machine needs to be on the PATH for this to succeed. +- If you're going to run your tests inside a container, please read [Patterns for running tests inside a docker container](continuous_integration/dind_patterns.md) first. + +### Docker registry authentication + +Testcontainers will try to authenticate to registries with supplied config using the following strategies in order: + +- Environment variables: + - `DOCKER_AUTH_CONFIG` +- Docker config + - At location specified in `DOCKER_CONFIG` or at `{HOME}/.docker/config.json` + +### Customizing Docker host detection diff --git a/test-virtual/TESTCONTAINERS.md b/test-virtual/TESTCONTAINERS.md new file mode 100644 index 0000000..a6fccc4 --- /dev/null +++ b/test-virtual/TESTCONTAINERS.md @@ -0,0 +1,137 @@ +# [Custom configuration](https://github.com/testcontainers/testcontainers-java/blob/main/docs/features/configuration.md) + +You can override some default properties if your environment requires that. + +## Configuration locations + +The configuration will be loaded from multiple locations. Properties are considered in the following order: + +1. Environment variables +2. `.testcontainers.properties` in user's home folder. Example locations: +**Linux:** `/home/myuser/.testcontainers.properties` +**Windows:** `C:/Users/myuser/.testcontainers.properties` +**macOS:** `/Users/myuser/.testcontainers.properties` +3. `testcontainers.properties` on the classpath. + +Note that when using environment variables, configuration property names should be set in upper +case with underscore separators, preceded by `TESTCONTAINERS_` - e.g. `checks.disable` becomes +`TESTCONTAINERS_CHECKS_DISABLE`. + +The classpath `testcontainers.properties` file may exist within the local codebase (e.g. within the `src/test/resources` directory) or within library dependencies that you may have. +Any such configuration files will have their contents merged. +If any keys conflict, the value will be taken on the basis of the first value found in: + +* 'local' classpath (i.e. where the URL of the file on the classpath begins with `file:`), then +* other classpath locations (i.e. JAR files) - considered in _alphabetical order of path_ to provide deterministic ordering. + +## Disabling the startup checks +> +> **checks.disable = [true|false]** + +Before running any containers Testcontainers will perform a set of startup checks to ensure that your environment is configured correctly. Usually they look like this: + +``` + ℹ︎ Checking the system... + ✔ Docker version should be at least 1.6.0 + ✔ File should be mountable + ✔ A port exposed by a docker container should be accessible +``` + +It takes a couple of seconds, but if you want to speed up your tests, you can disable the checks once you have everything configured. Add `checks.disable=true` to your `$HOME/.testcontainers.properties` to completely disable them. + +## Customizing images + +!!! note + This approach is discouraged and deprecated, but is documented for completeness. + Overriding individual image names via configuration may be removed in 2021. + See [Image Name Substitution](./image_name_substitution.md) for other strategies for substituting image names to pull from other registries. + +Testcontainers uses public Docker images to perform different actions like startup checks, VNC recording and others. +Some companies disallow the usage of Docker Hub, but you can override `*.image` properties with your own images from your private registry to workaround that. + +> **ryuk.container.image = testcontainers/ryuk:0.3.3** +> Performs fail-safe cleanup of containers, and always required (unless [Ryuk is disabled](#disabling-ryuk)) + +> **tinyimage.container.image = alpine:3.16** +> Used to check whether images can be pulled at startup, and always required (unless [startup checks are disabled](#disabling-the-startup-checks)) + +> **sshd.container.image = testcontainers/sshd:1.1.0** +> Required if [exposing host ports to containers](./networking.md#exposing-host-ports-to-the-container) + +> **vncrecorder.container.image = testcontainers/vnc-recorder:1.3.0** +> Used by VNC recorder in Testcontainers' Selenium integration + +> **socat.container.image = alpine/socat** +> **compose.container.image = docker/compose:1.8.0** +> Required if using [Docker Compose](../modules/docker_compose.md) + +> **kafka.container.image = confluentinc/cp-kafka** +> Used by KafkaContainer + +> **localstack.container.image = localstack/localstack** +> Used by LocalStack + +> **pulsar.container.image = apachepulsar/pulsar:2.2.0** +> Used by Apache Pulsar + +## Customizing Ryuk resource reaper + +> **ryuk.container.image = testcontainers/ryuk:0.3.3** +> The resource reaper is responsible for container removal and automatic cleanup of dead containers at JVM shutdown + +> **ryuk.container.privileged = true** +> In some environments ryuk must be started in privileged mode to work properly (--privileged flag) + +### Disabling Ryuk + +Ryuk must be started as a privileged container. +If your environment already implements automatic cleanup of containers after the execution, +but does not allow starting privileged containers, you can turn off the Ryuk container by setting +`TESTCONTAINERS_RYUK_DISABLED` **environment variable** to `true`. + +!!!tip + Note that Testcontainers will continue doing the cleanup at JVM's shutdown, unless you `kill -9` your JVM process. + +## Customizing image pull behaviour + +> **pull.pause.timeout = 30** +> By default Testcontainers will abort the pull of an image if the pull appears stalled (no data transferred) for longer than this duration (in seconds). + +## Customizing client ping behaviour + +> **client.ping.timeout = 5** +> Specifies for how long Testcontainers will try to connect to the Docker client to obtain valid info about the client before giving up and trying next strategy, if applicable (in seconds). + +## Customizing Docker host detection + +Testcontainers will attempt to detect the Docker environment and configure everything to work automatically. + +However, sometimes customization is required. Testcontainers will respect the following **environment variables**: + +> **DOCKER_HOST** = unix:///var/run/docker.sock +> See [Docker environment variables](https://docs.docker.com/engine/reference/commandline/cli/#environment-variables) +> +> **TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE** +> Path to Docker's socket. Used by Ryuk, Docker Compose, and a few other containers that need to perform Docker actions. +> Example: `/var/run/docker-alt.sock` +> +> **TESTCONTAINERS_HOST_OVERRIDE** +> Docker's host on which ports are exposed. +> Example: `docker.svc.local` + +For advanced users, the Docker host connection can be configured **via configuration** in `~/.testcontainers.properties`. +Note that these settings require use of the `EnvironmentAndSystemPropertyClientProviderStrategy`. The example below +illustrates usage: + +```properties +docker.client.strategy=org.testcontainers.dockerclient.EnvironmentAndSystemPropertyClientProviderStrategy +docker.host=tcp\://my.docker.host\:1234 # Equivalent to the DOCKER_HOST environment variable. Colons should be escaped. +docker.tls.verify=1 # Equivalent to the DOCKER_TLS_VERIFY environment variable +docker.cert.path=/some/path # Equivalent to the DOCKER_CERT_PATH environment variable +``` + +In addition, you can deactivate this behaviour by specifying: + +```properties +dockerconfig.source=autoIgnoringUserProperties # 'auto' by default +``` diff --git a/test-virtual/wrkspc-macro/tests/attribute.rs b/test-virtual/wrkspc-macro/tests/attribute.rs new file mode 100644 index 0000000..6ab6352 --- /dev/null +++ b/test-virtual/wrkspc-macro/tests/attribute.rs @@ -0,0 +1,4 @@ +#[test] +pub fn expansion() { + macrotest::expand("tests/expand/attribute.rs"); +} \ No newline at end of file diff --git a/test-virtual/wrkspc-macro/tests/derive.rs b/test-virtual/wrkspc-macro/tests/derive.rs new file mode 100644 index 0000000..a370553 --- /dev/null +++ b/test-virtual/wrkspc-macro/tests/derive.rs @@ -0,0 +1,4 @@ +#[test] +pub fn expansion() { + macrotest::expand("tests/expand/derive.rs"); +} \ No newline at end of file diff --git a/test-virtual/wrkspc-macro/tests/expand/derive.rs b/test-virtual/wrkspc-macro/tests/expand/derive.rs index 2424b1c..245d871 100644 --- a/test-virtual/wrkspc-macro/tests/expand/derive.rs +++ b/test-virtual/wrkspc-macro/tests/expand/derive.rs @@ -1,7 +1,5 @@ #[macro_use] extern crate wrkspc_macro; - #[derive(MyDerive)] struct Test; - fn main() {} \ No newline at end of file diff --git a/test-virtual/wrkspc-macro/tests/macro.rs b/test-virtual/wrkspc-macro/tests/macro.rs new file mode 100644 index 0000000..7effd6f --- /dev/null +++ b/test-virtual/wrkspc-macro/tests/macro.rs @@ -0,0 +1,4 @@ +#[test] +pub fn expansion() { + macrotest::expand("tests/expand/macro.rs"); +} \ No newline at end of file diff --git a/test-virtual/wrkspc-macro/tests/tests.rs b/test-virtual/wrkspc-macro/tests/tests.rs deleted file mode 100644 index fcee1ef..0000000 --- a/test-virtual/wrkspc-macro/tests/tests.rs +++ /dev/null @@ -1,4 +0,0 @@ -#[test] -pub fn pass() { - macrotest::expand("tests/expand/*.rs"); -} diff --git a/test-virtual/wrkspc-test/Cargo.toml b/test-virtual/wrkspc-test/Cargo.toml index 00128a5..1eb5041 100644 --- a/test-virtual/wrkspc-test/Cargo.toml +++ b/test-virtual/wrkspc-test/Cargo.toml @@ -12,7 +12,8 @@ wrkspc-macro = { path = "../wrkspc-macro" } [dev-dependencies] -# Staged files are managed by the redo build system scripts +# Staged files are managed by the redo build system scripts. +# After a successful build the .staged extension is removed. [[bin]] name = "attribute" path = "src/tests/expand/attribute.expanded.rs.staged" diff --git a/test-virtual/wrkspc-test/all.do b/test-virtual/wrkspc-test/all.do index b441f57..95af15c 100644 --- a/test-virtual/wrkspc-test/all.do +++ b/test-virtual/wrkspc-test/all.do @@ -1,78 +1,43 @@ #!/usr/bin/env bash -# -# $1 is the target name, eg. pie.init -# $2 is the same as $1. -# $3 is the temporary output file to create. -# If a .do script succeeds, redo replaces $1 with $3. -# If a .do script fails, redo leaves $1 alone. - -# shellcheck shell=bash -#set -x - -# Exit on error -set -e exec >&2 -error_count=0 -error_messages="" - REPO_DIR=$(git rev-parse --show-toplevel) DEST_DIR="src/tests" +MACRO_DIR="test-virtual/wrkspc-macro" -cargo test --manifest-path ./../wrkspc-macro/Cargo.toml &>target/wrkspc-test-test.log +mkdir -p target -# Find files with the extension '.do' within a maximum depth of 2 directories. -# Remove the '.do' extension from the file names. -# Exclude the current script file. -# Finally, invoke the 'redo-ifchange' command for each file. -SELF=$(basename "${0##*/}" .do) -find . -maxdepth 2 -type f -name '*.do' -print0 | \ - xargs -0 echo | \ - sed -e 's/\.do//g' -e "s/\.\/$SELF//g" | \ - sed -e 's/\.do//g' -e "s/\.\/default//g" | \ +# Find .do files, exclude certain ones, remove .do extension, and call redo-ifchange +find . -maxdepth 6 -type f -name '*.do' | \ + grep -vE 'default\.do|all\.do|default\.expand\.do' | \ + sed -r 's/\.do$//' | \ xargs redo-ifchange -while IFS= read -r -d '' file; do - +# Find all .rs files not ending in .expanded.rs +find "${REPO_DIR}/${MACRO_DIR}/tests" -type f -name "*.rs" ! -name "*.expanded.rs" -print0 | while IFS= read -r -d '' file; do source_file="${file%.rs}.expanded.rs" # Check if there is a corresponding .expanded.rs file if [ ! -f "$source_file" ]; then - continue + continue fi - # Get the relative path of the source file - rel_path=$(realpath --relative-to=${REPO_DIR}/test-virtual/wrkspc-macro/tests $file) + redo-ifchange "${source_file}" + + test_name=$(basename "${file}" | cut -f 1 -d '.') + # Invoke virtual target for test_name + redo-ifchange "${test_name}.expand" + + # Get the relative path of the source file + rel_path=$(realpath --relative-to="${REPO_DIR}/${MACRO_DIR}/tests" "$file") expanded_file="${rel_path%.rs}.expanded.rs" expanded_path="${DEST_DIR}/${expanded_file}" - redo-ifchange "${source_file}" - - # If the source file has changed, redo the expanded file - if [ $? -eq 0 ]; then - redo "${expanded_path}" - if [ $? -eq 1 ]; then - error_count=$((error_count+1)) - error_messages="${error_messages}Error in file: ${source_file}\n" - fi + # Fall back to the default.do script + if ! redo-ifchange "${expanded_path}"; then + printf "Error in file: %s\n" "${source_file}" >&2 + exit 1 fi - -# Find all .rs files in the specified directory not ending in .expanded.rs. -# The -print0 option with find and -d '' option with read are used together -# to handle file names that contain spaces, newlines or other special characters. -# The ! -name "*.expanded.rs" is excluding any .rs files that end with .expanded.rs. -# This is important because we only want to process original .rs files, not -# ones that have been expanded. -# -# Use process substitution (`<(command)`) instead of a pipe. -# This will allow the `while` loop to run in the current shell and preserve -# changes to the variables `${error_count}` and `${error_messages}` . -done < <(find "${REPO_DIR}/test-virtual/wrkspc-macro/tests" -type f -name "*.rs" ! -name "*.expanded.rs" -print0) - -# Print all error messages -if [ $error_count -gt 0 ]; then - echo "Errors occurred in the incoming files:\n${error_messages}" >&2 - exit 1 -fi +done \ No newline at end of file diff --git a/test-virtual/wrkspc-test/default.do b/test-virtual/wrkspc-test/default.do index 5fec608..8aae775 100644 --- a/test-virtual/wrkspc-test/default.do +++ b/test-virtual/wrkspc-test/default.do @@ -1,40 +1,33 @@ #!/usr/bin/env bash -# shellcheck shell=bash -#set -x - -# Exit on error -set -e exec >&2 +MACRO_DIR="test-virtual/wrkspc-macro" + # Define the source and destination directories REPO_DIR=$(git rev-parse --show-toplevel) -SRC_DIR="${REPO_DIR}/test-virtual/wrkspc-macro" -DEST_DIR="${REPO_DIR}/test-virtual/wrkspc-test" - -exp_file="${DEST_DIR}/${1}" +SRC_DIR="${REPO_DIR}/${MACRO_DIR}" +DEST_DIR="${REPO_DIR}/zno-test" -# Use basename to get the filename from the path -bin_file=$(basename "$exp_file") +exp_file="${DEST_DIR}/$1" +src_file="${SRC_DIR}/$(realpath --relative-to="${DEST_DIR}/src" "$exp_file")" -# Use cut to remove the .expanded.rs extension -bin_name=$(echo "$bin_file" | cut -f 1 -d '.') +# Get the filename without the extension +bin_name=$(basename "$exp_file" | cut -f 1 -d '.') -# Get the relative path of the source file -rel_path=$(realpath --relative-to="${DEST_DIR}/src" $exp_file) -src_file="${SRC_DIR}/${rel_path}" +# redo when the expanded file changes +redo-ifchange "${src_file}" +# Check if source file exists and copy it to the destination if [ -e "${src_file}" ]; then - # A source expanded file exists. Build. cp --force "${src_file}" "${exp_file}.staged" cat "${src_file}" >"$3" else - echo "$0: Fatal: don't know how to build '$1'" >&2 - exit 99 + echo "$0: Fatal: don't know how to build '$1'" >&2 + exit 99 fi -cargo build --release --bin "${bin_name}" &>target/wrkspc-test-build.log - -if [ $? -eq 0 ]; then +# Build and log +if cargo build --release --bin "${bin_name}" > "target/zno-test-build-${bin_name}.log" 2>&1; then rm --force "${exp_file}.staged" -fi +fi \ No newline at end of file diff --git a/test-virtual/wrkspc-test/default.expand.do b/test-virtual/wrkspc-test/default.expand.do new file mode 100644 index 0000000..013c389 --- /dev/null +++ b/test-virtual/wrkspc-test/default.expand.do @@ -0,0 +1,16 @@ +#!/usr/bin/env bash + +exec >&2 + +MACRO_DIR="test-virtual/wrkspc-macro" + +REPO_DIR=$(git rev-parse --show-toplevel) +SRC_DIR="${REPO_DIR}/${MACRO_DIR}" + +test_name="${1%.*}" + +# Run the test and log the output +cargo test --test "${test_name}" --manifest-path ${SRC_DIR}/Cargo.toml > "target/zno-test-expansion-${test_name}.log" 2>&1 + +# If the newly produced file disappears, we need to redo. +redo-ifchange "${SRC_DIR}/tests/expand/${test_name}.rs" diff --git a/test-virtual/wrkspc-test/src/tests/expand/attribute.expanded.rs b/test-virtual/wrkspc-test/src/tests/expand/attribute.expanded.rs index c37c39c..e69de29 100644 --- a/test-virtual/wrkspc-test/src/tests/expand/attribute.expanded.rs +++ b/test-virtual/wrkspc-test/src/tests/expand/attribute.expanded.rs @@ -1,5 +0,0 @@ -#[macro_use] -extern crate wrkspc_macro; -struct Test; -struct Hello; -fn main() {} diff --git a/test-virtual/wrkspc-test/src/tests/expand/derive.expanded.rs b/test-virtual/wrkspc-test/src/tests/expand/derive.expanded.rs index 5a24c70..e69de29 100644 --- a/test-virtual/wrkspc-test/src/tests/expand/derive.expanded.rs +++ b/test-virtual/wrkspc-test/src/tests/expand/derive.expanded.rs @@ -1,5 +0,0 @@ -#[macro_use] -extern crate wrkspc_macro; -struct Test; -struct Hello; -fn main() {} \ No newline at end of file diff --git a/test-virtual/wrkspc-test/src/tests/expand/macro.expanded.rs b/test-virtual/wrkspc-test/src/tests/expand/macro.expanded.rs index b48da90..e69de29 100644 --- a/test-virtual/wrkspc-test/src/tests/expand/macro.expanded.rs +++ b/test-virtual/wrkspc-test/src/tests/expand/macro.expanded.rs @@ -1,6 +0,0 @@ -#[macro_use] -extern crate wrkspc_macro; -pub fn main() { - struct Test; - struct Hello; -} From f68e01b6008eb7f805fb8ecaa01c494f85434675 Mon Sep 17 00:00:00 2001 From: Mark Van de Vyver Date: Sat, 23 Mar 2024 20:54:11 +1100 Subject: [PATCH 14/15] Add build process diagrams and update file paths Signed-off-by: Mark Van de Vyver --- test-virtual/README.md | 61 +++++++++++++++++-- test-virtual/wrkspc-test/all.do | 5 +- test-virtual/wrkspc-test/default.do | 2 +- .../src/tests/expand/attribute.expanded.rs | 5 ++ .../src/tests/expand/derive.expanded.rs | 5 ++ .../src/tests/expand/macro.expanded.rs | 6 ++ 6 files changed, 75 insertions(+), 9 deletions(-) diff --git a/test-virtual/README.md b/test-virtual/README.md index 56c5e02..c462f8b 100644 --- a/test-virtual/README.md +++ b/test-virtual/README.md @@ -27,16 +27,65 @@ In this setup: - Extracting the filename from the path using `basename`, resulting in `bin`. - Removing the `.expanded.rs` extension using `cut`, resulting in `bin`. -Please note that this is a simplified diagram and the actual build process may involve more steps. +Here's a Mermaid diagram that shows how the build process in `all.do` flows to `default.expand.do` and then to `default.do`. In this first diagram: + +- `all.do` is the starting point of the build process. +- `default.expand.do` is called by `all.do` for each source file. +- `default.expand.do` processes each file by: + - Extracting the filename from the path using `basename`, resulting in `bin_file`. + - Removing the `.expanded.rs` extension using `cut`, resulting in `bin_name`. + - Checking if the .expanded.rs file exists. If it does, it continues processing. If it doesn't, it skips the file. + - Getting the relative path of the source file using `realpath`, resulting in `rel_path`. + - Constructing the path of the expanded file using string concatenation, resulting in `expanded_path`. + - Checking if the source file has changed. If it has, it redoes the expanded file. If it hasn't, it skips the file. + - If redoing the expanded file fails, it increments the error count and records the error message. +- `default.do` is called for each file that is not skipped. + - It copies the source file to the destination, resulting in `exp_file.staged`. + - It builds the file using `cargo build`. If the build succeeds, it removes `exp_file.staged`. ```mermaid graph TD - A[all.do] -->|Iterates over all source files| B[default.do] + A[all.do] -->|Iterates over all source files| B[default.expand.do] B --> C{Processes each file} - C -->|1. Extracts filename from path| D[basename] - D --> E[bin] - C -->|2. Removes .expanded.rs extension| F[cut] - F --> G[bin] + C -->|1. Extracts filename from path| D[Uses basename] + D --> E[bin_file] + C -->|2. Removes .expanded.rs extension| F[Uses cut] + F --> G[bin_name] + C -->|3. Checks if .expanded.rs file exists| H[If file exists] + H -->|Yes| I[Continues processing] + I -->|4. Gets relative path of source file| J[Uses realpath] + J --> K[rel_path] + I -->|5. Constructs path of expanded file| L[Uses string concatenation] + L --> M[expanded_path] + I -->|6. Checks if source file has changed| N[If file has changed] + N -->|Yes| O[Redoes expanded file] + O -->|If redo fails| P[Increments error count and records error message] + P --> Q[error_count and error_messages] + N -->|No| R[Skips file] + R --> S[default.do] + S -->|7. Copies source file to destination| T[Uses cp] + T --> U[exp_file.staged] + S -->|8. Builds with cargo| V[Uses cargo build] + V -->|If build succeeds| W[Removes exp_file.staged] +``` + +The next diagram shows the flow of data in the files between the folders `wkspc-macro` and `wkspc-test`: + +- `wkspc-macro` is the source directory containing the `.rs` to be tested files. +- `all.do` processes each `.rs` file in `wkspc-macro`. +- `default.expand.do` is called by `all.do` for each `.rs` file and generates a corresponding `.expanded.rs` file if the source file has changed. +- The `.expanded.rs` files are placed in the `wkspc-test` directory. +- If redoing the expanded file fails, it records the error message. +- If the build succeeds, it removes `exp_file.staged`. + +```mermaid +graph LR + A[wkspc-macro] -->|Source .rs files| B[all.do] + B -->|Processes each file| C[default.expand.do] + C -->|Generates .expanded.rs files if source file has changed| D[wkspc-test] + D -->|If redo fails| E[Records error message] + E --> F[error_messages] + D -->|If build succeeds| G[Removes exp_file.staged] ``` ## Containers diff --git a/test-virtual/wrkspc-test/all.do b/test-virtual/wrkspc-test/all.do index 95af15c..5ab0c34 100644 --- a/test-virtual/wrkspc-test/all.do +++ b/test-virtual/wrkspc-test/all.do @@ -2,10 +2,11 @@ exec >&2 -REPO_DIR=$(git rev-parse --show-toplevel) -DEST_DIR="src/tests" MACRO_DIR="test-virtual/wrkspc-macro" +REPO_DIR=$(git rev-parse --show-toplevel) +DEST_DIR="${REPO_DIR}/test-virtual/wrkspc-test/src/tests" + mkdir -p target # Find .do files, exclude certain ones, remove .do extension, and call redo-ifchange diff --git a/test-virtual/wrkspc-test/default.do b/test-virtual/wrkspc-test/default.do index 8aae775..0fafc6a 100644 --- a/test-virtual/wrkspc-test/default.do +++ b/test-virtual/wrkspc-test/default.do @@ -7,7 +7,7 @@ MACRO_DIR="test-virtual/wrkspc-macro" # Define the source and destination directories REPO_DIR=$(git rev-parse --show-toplevel) SRC_DIR="${REPO_DIR}/${MACRO_DIR}" -DEST_DIR="${REPO_DIR}/zno-test" +DEST_DIR="${REPO_DIR}/test-virtual/wrkspc-test" exp_file="${DEST_DIR}/$1" src_file="${SRC_DIR}/$(realpath --relative-to="${DEST_DIR}/src" "$exp_file")" diff --git a/test-virtual/wrkspc-test/src/tests/expand/attribute.expanded.rs b/test-virtual/wrkspc-test/src/tests/expand/attribute.expanded.rs index e69de29..c37c39c 100644 --- a/test-virtual/wrkspc-test/src/tests/expand/attribute.expanded.rs +++ b/test-virtual/wrkspc-test/src/tests/expand/attribute.expanded.rs @@ -0,0 +1,5 @@ +#[macro_use] +extern crate wrkspc_macro; +struct Test; +struct Hello; +fn main() {} diff --git a/test-virtual/wrkspc-test/src/tests/expand/derive.expanded.rs b/test-virtual/wrkspc-test/src/tests/expand/derive.expanded.rs index e69de29..5a24c70 100644 --- a/test-virtual/wrkspc-test/src/tests/expand/derive.expanded.rs +++ b/test-virtual/wrkspc-test/src/tests/expand/derive.expanded.rs @@ -0,0 +1,5 @@ +#[macro_use] +extern crate wrkspc_macro; +struct Test; +struct Hello; +fn main() {} \ No newline at end of file diff --git a/test-virtual/wrkspc-test/src/tests/expand/macro.expanded.rs b/test-virtual/wrkspc-test/src/tests/expand/macro.expanded.rs index e69de29..b48da90 100644 --- a/test-virtual/wrkspc-test/src/tests/expand/macro.expanded.rs +++ b/test-virtual/wrkspc-test/src/tests/expand/macro.expanded.rs @@ -0,0 +1,6 @@ +#[macro_use] +extern crate wrkspc_macro; +pub fn main() { + struct Test; + struct Hello; +} From e1f1c3890c573256e3d037c292498c56ee366db7 Mon Sep 17 00:00:00 2001 From: Mark Van de Vyver Date: Sun, 24 Mar 2024 11:53:25 +1100 Subject: [PATCH 15/15] Update test-virtual README.md with integration test template and diagrams Signed-off-by: Mark Van de Vyver --- test-virtual/README.md | 59 +++++++++++++++------------ test-virtual/images/figure-data.png | Bin 0 -> 61164 bytes test-virtual/images/figure-logic.png | Bin 0 -> 80230 bytes 3 files changed, 32 insertions(+), 27 deletions(-) create mode 100644 test-virtual/images/figure-data.png create mode 100644 test-virtual/images/figure-logic.png diff --git a/test-virtual/README.md b/test-virtual/README.md index c462f8b..999fe60 100644 --- a/test-virtual/README.md +++ b/test-virtual/README.md @@ -1,11 +1,14 @@ # `test-virtual` -This is an example virtual-workspace that contains crates: +A convention over configuration template for integration tests of proc-macros, +in a workspace. -- `wrkspc` -- `wrkspc-dev` -- `wrkspc-macro` -- `wrkspc-test` +This example workspace contains crates: + +- `wrkspc`: A library crate. +- `wrkspc-dev`: A development crate. +- `wrkspc-macro`: The Proc-macro crate. +- `wrkspc-test`: Integration tests, and DJB's `redo` build system for `wrkspc-macro`. Where: @@ -27,6 +30,26 @@ In this setup: - Extracting the filename from the path using `basename`, resulting in `bin`. - Removing the `.expanded.rs` extension using `cut`, resulting in `bin`. +The next diagram shows the flow of data in the files between the folders `wkspc-macro` and `wkspc-test`: + +- `wkspc-macro` is the source directory containing the `.rs` to be tested files. +- `all.do` processes each `.rs` file in `wkspc-macro`. +- `default.expand.do` is called by `all.do` for each `.rs` file and generates a corresponding `.expanded.rs` file if the source file has changed. +- The `.expanded.rs` files are placed in the `wkspc-test` directory. +- If redoing the expanded file fails, it records the error message. +- If the build succeeds, it removes `exp_file.staged`. + +[Build data flow](./images/figure-data.png) +|Source .rs files| B[all.do] + B -->|Processes each file| C[default.expand.do] + C -->|Generates .expanded.rs files if source file has changed| D[wkspc-test] + D -->|If redo fails| E[Records error message] + E --> F[error_messages] + D -->|If build succeeds| G[Removes exp_file.staged] +--> + Here's a Mermaid diagram that shows how the build process in `all.do` flows to `default.expand.do` and then to `default.do`. In this first diagram: - `all.do` is the starting point of the build process. @@ -43,8 +66,9 @@ Here's a Mermaid diagram that shows how the build process in `all.do` flows to ` - It copies the source file to the destination, resulting in `exp_file.staged`. - It builds the file using `cargo build`. If the build succeeds, it removes `exp_file.staged`. -```mermaid -graph TD +[Build logic flow](./images/figure-logic.png) +|Iterates over all source files| B[default.expand.do] B --> C{Processes each file} C -->|1. Extracts filename from path| D[Uses basename] @@ -67,26 +91,7 @@ graph TD T --> U[exp_file.staged] S -->|8. Builds with cargo| V[Uses cargo build] V -->|If build succeeds| W[Removes exp_file.staged] -``` - -The next diagram shows the flow of data in the files between the folders `wkspc-macro` and `wkspc-test`: - -- `wkspc-macro` is the source directory containing the `.rs` to be tested files. -- `all.do` processes each `.rs` file in `wkspc-macro`. -- `default.expand.do` is called by `all.do` for each `.rs` file and generates a corresponding `.expanded.rs` file if the source file has changed. -- The `.expanded.rs` files are placed in the `wkspc-test` directory. -- If redoing the expanded file fails, it records the error message. -- If the build succeeds, it removes `exp_file.staged`. - -```mermaid -graph LR - A[wkspc-macro] -->|Source .rs files| B[all.do] - B -->|Processes each file| C[default.expand.do] - C -->|Generates .expanded.rs files if source file has changed| D[wkspc-test] - D -->|If redo fails| E[Records error message] - E --> F[error_messages] - D -->|If build succeeds| G[Removes exp_file.staged] -``` +--> ## Containers diff --git a/test-virtual/images/figure-data.png b/test-virtual/images/figure-data.png new file mode 100644 index 0000000000000000000000000000000000000000..6768227478659ae0c5829287e2a8069ba0c8f030 GIT binary patch literal 61164 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 MkkpfG0d24U1#X#S_5c6? literal 0 HcmV?d00001 diff --git a/test-virtual/images/figure-logic.png b/test-virtual/images/figure-logic.png new file mode 100644 index 0000000000000000000000000000000000000000..df9d32e907d7454a412027d4ec8f7881f4e5bd12 GIT binary patch literal 80230 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 CN-`1v literal 0 HcmV?d00001