From 313d441e525e6cf3a7e62d9aadc91b379feed978 Mon Sep 17 00:00:00 2001 From: Techassi Date: Fri, 27 Sep 2024 16:52:08 +0200 Subject: [PATCH 01/13] test: Add default snapshot testing --- Cargo.lock | 89 +++++++++++++++++ Cargo.toml | 15 ++- crates/stackable-versioned-macros/Cargo.toml | 3 + .../fixtures/README.md | 54 +++++++++++ .../fixtures/inputs/default/attribute_enum.rs | 38 ++++++++ .../inputs/default/attribute_struct.rs | 35 +++++++ .../fixtures/inputs/default/basic.rs | 18 ++++ .../fixtures/inputs/default/deprecate_enum.rs | 13 +++ .../inputs/default/deprecate_struct.rs | 13 +++ .../fixtures/inputs/default/rename.rs | 11 +++ .../inputs/default/skip_from_field.rs | 14 +++ ...fault_snapshots@attribute_enum.rs.snap.new | 97 +++++++++++++++++++ ...ult_snapshots@attribute_struct.rs.snap.new | 92 ++++++++++++++++++ ..._test__default_snapshots@basic.rs.snap.new | 93 ++++++++++++++++++ ...fault_snapshots@deprecate_enum.rs.snap.new | 88 +++++++++++++++++ ...ult_snapshots@deprecate_struct.rs.snap.new | 88 +++++++++++++++++ ...test__default_snapshots@rename.rs.snap.new | 48 +++++++++ ...ault_snapshots@skip_from_field.rs.snap.new | 39 ++++++++ crates/stackable-versioned-macros/src/lib.rs | 48 ++++++--- .../src/test_utils.rs | 40 ++++++++ .../tests/default/pass/README.md | 6 -- .../tests/default/pass/attributes_enum.rs | 43 -------- .../tests/default/pass/attributes_struct.rs | 60 ------------ .../tests/default/pass/basic.rs | 43 -------- .../tests/default/pass/deprecate_enum.rs | 16 --- .../tests/default/pass/deprecate_struct.rs | 16 --- .../tests/default/pass/rename.rs | 14 --- .../tests/default/pass/skip_from_version.rs | 28 ------ .../tests/trybuild.rs | 12 --- 29 files changed, 921 insertions(+), 253 deletions(-) create mode 100644 crates/stackable-versioned-macros/fixtures/README.md create mode 100644 crates/stackable-versioned-macros/fixtures/inputs/default/attribute_enum.rs create mode 100644 crates/stackable-versioned-macros/fixtures/inputs/default/attribute_struct.rs create mode 100644 crates/stackable-versioned-macros/fixtures/inputs/default/basic.rs create mode 100644 crates/stackable-versioned-macros/fixtures/inputs/default/deprecate_enum.rs create mode 100644 crates/stackable-versioned-macros/fixtures/inputs/default/deprecate_struct.rs create mode 100644 crates/stackable-versioned-macros/fixtures/inputs/default/rename.rs create mode 100644 crates/stackable-versioned-macros/fixtures/inputs/default/skip_from_field.rs create mode 100644 crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__default_snapshots@attribute_enum.rs.snap.new create mode 100644 crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__default_snapshots@attribute_struct.rs.snap.new create mode 100644 crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__default_snapshots@basic.rs.snap.new create mode 100644 crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__default_snapshots@deprecate_enum.rs.snap.new create mode 100644 crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__default_snapshots@deprecate_struct.rs.snap.new create mode 100644 crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__default_snapshots@rename.rs.snap.new create mode 100644 crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__default_snapshots@skip_from_field.rs.snap.new create mode 100644 crates/stackable-versioned-macros/src/test_utils.rs delete mode 100644 crates/stackable-versioned-macros/tests/default/pass/README.md delete mode 100644 crates/stackable-versioned-macros/tests/default/pass/attributes_enum.rs delete mode 100644 crates/stackable-versioned-macros/tests/default/pass/attributes_struct.rs delete mode 100644 crates/stackable-versioned-macros/tests/default/pass/basic.rs delete mode 100644 crates/stackable-versioned-macros/tests/default/pass/deprecate_enum.rs delete mode 100644 crates/stackable-versioned-macros/tests/default/pass/deprecate_struct.rs delete mode 100644 crates/stackable-versioned-macros/tests/default/pass/rename.rs delete mode 100644 crates/stackable-versioned-macros/tests/default/pass/skip_from_version.rs diff --git a/Cargo.lock b/Cargo.lock index 627b95b87..01d4a3e0e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -393,6 +393,16 @@ dependencies = [ "generic-array", ] +[[package]] +name = "bstr" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40723b8fb387abc38f4f4a37c09073622e41dd12327033091ef8950659e6dc0c" +dependencies = [ + "memchr", + "serde", +] + [[package]] name = "bumpalo" version = "3.16.0" @@ -522,6 +532,18 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "console" +version = "0.15.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4eb" +dependencies = [ + "encode_unicode", + "lazy_static", + "libc", + "windows-sys 0.52.0", +] + [[package]] name = "const-oid" version = "0.9.6" @@ -802,6 +824,12 @@ dependencies = [ "zeroize", ] +[[package]] +name = "encode_unicode" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" + [[package]] name = "encoding_rs" version = "0.8.34" @@ -1059,6 +1087,19 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" +[[package]] +name = "globset" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57da3b9b5b85bd66f31093f8c408b90a74431672542466497dcbdfdc02034be1" +dependencies = [ + "aho-corasick", + "bstr", + "log", + "regex-automata 0.4.7", + "regex-syntax 0.8.4", +] + [[package]] name = "group" version = "0.13.0" @@ -1411,6 +1452,20 @@ dependencies = [ "hashbrown 0.14.5", ] +[[package]] +name = "insta" +version = "1.40.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6593a41c7a73841868772495db7dc1e8ecab43bb5c0b6da2059246c4b506ab60" +dependencies = [ + "console", + "globset", + "lazy_static", + "linked-hash-map", + "similar", + "walkdir", +] + [[package]] name = "instant" version = "0.1.13" @@ -1698,6 +1753,12 @@ version = "0.2.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" +[[package]] +name = "linked-hash-map" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" + [[package]] name = "linux-raw-sys" version = "0.4.14" @@ -2572,6 +2633,15 @@ version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + [[package]] name = "schannel" version = "0.1.24" @@ -2818,6 +2888,12 @@ dependencies = [ "rand_core", ] +[[package]] +name = "similar" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1de1d4f81173b03af4c0cbed3c898f6bff5b870e4a7f5d6f4057d62a7a4b686e" + [[package]] name = "slab" version = "0.4.9" @@ -3008,12 +3084,15 @@ version = "0.3.0" dependencies = [ "convert_case", "darling", + "insta", "itertools 0.13.0", "k8s-openapi", "k8s-version", "kube", + "prettyplease", "proc-macro2", "quote", + "regex", "rstest", "schemars", "serde", @@ -3670,6 +3749,16 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + [[package]] name = "want" version = "0.3.1" diff --git a/Cargo.toml b/Cargo.toml index b3e8c2e14..46b6941a6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,6 +26,7 @@ either = "1.13.0" futures = "0.3.30" futures-util = "0.3.30" indexmap = "2.5" +insta = { version= "1.40", features = ["glob"] } hyper = { version = "1.4.1", features = ["full"] } hyper-util = "0.1.8" itertools = "0.13.0" @@ -41,6 +42,7 @@ opentelemetry-otlp = "0.16.0" opentelemetry-semantic-conventions = "0.15.0" p256 = { version = "0.13.2", features = ["ecdsa"] } pin-project = "1.1.5" +prettyplease = "0.2.22" proc-macro2 = "1.0.86" quote = "1.0.37" rand = "0.8.5" @@ -77,7 +79,12 @@ x509-cert = { version = "0.2.5", features = ["builder"] } zeroize = "1.8.1" # Use O3 in tests to improve the RSA key generation speed in the stackable-certs crate -[profile.test.package.stackable-certs] -opt-level = 3 -[profile.test.package."rsa"] -opt-level = 3 +[profile.test.package] +stackable-certs.opt-level = 3 +rsa.opt-level = 3 + +# Run snapshot testing faster even as a dev dependecy. +# See https://insta.rs/docs/quickstart/#optional-faster-runs +[profile.dev.package] +insta.opt-level = 3 +similar.opt-level = 3 diff --git a/crates/stackable-versioned-macros/Cargo.toml b/crates/stackable-versioned-macros/Cargo.toml index d53750ae1..b640362c0 100644 --- a/crates/stackable-versioned-macros/Cargo.toml +++ b/crates/stackable-versioned-macros/Cargo.toml @@ -38,6 +38,9 @@ syn.workspace = true quote.workspace = true [dev-dependencies] +insta.workspace = true +prettyplease.workspace = true +regex.workspace = true rstest.workspace = true schemars.workspace = true serde.workspace = true diff --git a/crates/stackable-versioned-macros/fixtures/README.md b/crates/stackable-versioned-macros/fixtures/README.md new file mode 100644 index 000000000..e3a8d0eb4 --- /dev/null +++ b/crates/stackable-versioned-macros/fixtures/README.md @@ -0,0 +1,54 @@ +# Snapshot Testing + +This folder contains fixtures for snapshot testing the `#[versioned()]` macro. Snapshot testing is +done using the [insta] crate. It provides a [CLI tool][insta-cli] called `cargo-insta` and a +[VS Code extension][insta-ext]. + +Test inputs and snapshots of the expected output are located in the `fixtures` folder. There are two +inputs to the `#[versioned()]` macro because it is an attribute macro: + +> The first TokenStream is the delimited token tree following the attribute’s name, not including +> the outer delimiters. If the attribute is written as a bare attribute name, the attribute +> TokenStream is empty. The second TokenStream is the rest of the item including other attributes on +> the item. +> +> _(Taken from the [Rust reference][rust-ref])_ + +Because of that, a special delimiter is used in the input files which separates the two inputs while +still enabling developers to write valid Rust code. The delimiter is `// ---\n`. Most of the inner +workings are located in [this file](../src/test_utils.rs). + +```rust +#[versioned( + version(name = "v1alpha1"), + version(name = "v1beta1"), + version(name = "v1") +)] +// --- <- See here! +pub(crate) struct Foo { + #[versioned( + changed(since = "v1beta1", from_name = "jjj", from_type = "u8"), + changed(since = "v1", from_type = "u16"), + )] + bar: usize, + baz: bool, +} +``` + +## Recommended Workflow + +First, add new input files (which automatically get picked up by `insta`) to the `fixtures/inputs` +folder. Make sure the delimiter is placed correctly between the attribute and the container +definition. Next, generate the snapshot files (initially not accepted) by running + +```shell +cargo insta test -p stackable-versioned-macros +``` + +This command will place the new snapshot files in the `fixtures/snapshots` folder. To review them, +run the `cargo insta review` command. Now check these files in. + +[rust-ref]: https://doc.rust-lang.org/reference/procedural-macros.html#attribute-macros +[insta-ext]: https://insta.rs/docs/vscode/ +[insta-cli]: https://insta.rs/docs/cli/ +[insta]: https://insta.rs/ diff --git a/crates/stackable-versioned-macros/fixtures/inputs/default/attribute_enum.rs b/crates/stackable-versioned-macros/fixtures/inputs/default/attribute_enum.rs new file mode 100644 index 000000000..f3b78aa75 --- /dev/null +++ b/crates/stackable-versioned-macros/fixtures/inputs/default/attribute_enum.rs @@ -0,0 +1,38 @@ +#[versioned( + version(name = "v1alpha1"), + version( + name = "v1beta1", + doc = r#" + Additional docs for this version which are purposefully long to + show how manual line wrapping works. \ + Multi-line docs are also supported, as per regular doc-comments. + "# + ), + version(name = "v1beta2"), + version(name = "v1"), + version(name = "v2"), + options(skip(from)) +)] +// --- +#[derive(Default)] +enum Foo { + /// This variant is available in every version (so far). + #[default] + Foo, + + /// Keep the main field docs the same, even after the field is + /// deprecated. + #[versioned(deprecated(since = "v1beta1", note = "gone"))] + DeprecatedBar, + + /// This is for baz + #[versioned(added(since = "v1beta1"))] + // Just to check stackable-versioned deprecation warning appears. + // #[deprecated] + Baz, + + /// This is will keep changing over time. + #[versioned(changed(since = "v1beta1", from_name = "Qoox"))] + #[versioned(changed(since = "v1", from_name = "Qaax"))] + Quux, +} diff --git a/crates/stackable-versioned-macros/fixtures/inputs/default/attribute_struct.rs b/crates/stackable-versioned-macros/fixtures/inputs/default/attribute_struct.rs new file mode 100644 index 000000000..649477dcb --- /dev/null +++ b/crates/stackable-versioned-macros/fixtures/inputs/default/attribute_struct.rs @@ -0,0 +1,35 @@ +#[versioned( + version(name = "v1alpha1"), + version( + name = "v1beta1", + doc = r#" + Additional docs for this version which are purposefully long to + show how manual line wrapping works. \ + Multi-line docs are also supported, as per regular doc-comments. + "# + ), + version(name = "v1beta2"), + version(name = "v1"), + version(name = "v2"), + options(skip(from)) +)] +// --- +/// Test +#[derive(Default)] +struct Foo { + /// This field is available in every version (so far). + foo: String, + + /// Keep the main field docs the same, even after the field is deprecated. + #[versioned(deprecated(since = "v1beta1", note = "gone"))] + deprecated_bar: String, + + /// This is for baz + #[versioned(added(since = "v1beta1"))] + baz: String, + + /// This is will keep changing over time. + #[versioned(changed(since = "v1beta1", from_name = "qoox"))] + #[versioned(changed(since = "v1", from_name = "qaax"))] + quux: String, +} diff --git a/crates/stackable-versioned-macros/fixtures/inputs/default/basic.rs b/crates/stackable-versioned-macros/fixtures/inputs/default/basic.rs new file mode 100644 index 000000000..12ab3e260 --- /dev/null +++ b/crates/stackable-versioned-macros/fixtures/inputs/default/basic.rs @@ -0,0 +1,18 @@ +#[versioned( + version(name = "v1alpha1", deprecated), + version(name = "v1beta1"), + version(name = "v1"), + version(name = "v2"), + version(name = "v3") +)] +// --- +pub(crate) struct Foo { + #[versioned( + changed(since = "v1beta1", from_name = "jjj", from_type = "u8"), + changed(since = "v1", from_type = "u16"), + deprecated(since = "v2", note = "not empty") + )] + /// Test + deprecated_bar: usize, + baz: bool, +} diff --git a/crates/stackable-versioned-macros/fixtures/inputs/default/deprecate_enum.rs b/crates/stackable-versioned-macros/fixtures/inputs/default/deprecate_enum.rs new file mode 100644 index 000000000..af942c1d4 --- /dev/null +++ b/crates/stackable-versioned-macros/fixtures/inputs/default/deprecate_enum.rs @@ -0,0 +1,13 @@ +#[versioned( + version(name = "v1alpha1"), + version(name = "v1beta1"), + version(name = "v1"), + version(name = "v2"), + version(name = "v3") +)] +// --- +enum Foo { + #[versioned(deprecated(since = "v1"))] + DeprecatedBar, + Baz, +} diff --git a/crates/stackable-versioned-macros/fixtures/inputs/default/deprecate_struct.rs b/crates/stackable-versioned-macros/fixtures/inputs/default/deprecate_struct.rs new file mode 100644 index 000000000..b20c25bbd --- /dev/null +++ b/crates/stackable-versioned-macros/fixtures/inputs/default/deprecate_struct.rs @@ -0,0 +1,13 @@ +#[versioned( + version(name = "v1alpha1"), + version(name = "v1beta1"), + version(name = "v1"), + version(name = "v2"), + version(name = "v3") +)] +// --- +struct Foo { + #[versioned(deprecated(since = "v1", note = "gone"))] + deprecated_bar: usize, + baz: bool, +} diff --git a/crates/stackable-versioned-macros/fixtures/inputs/default/rename.rs b/crates/stackable-versioned-macros/fixtures/inputs/default/rename.rs new file mode 100644 index 000000000..4cfb1f0a4 --- /dev/null +++ b/crates/stackable-versioned-macros/fixtures/inputs/default/rename.rs @@ -0,0 +1,11 @@ +#[versioned( + version(name = "v1alpha1"), + version(name = "v1beta1"), + version(name = "v1") +)] +// --- +struct Foo { + #[versioned(changed(since = "v1beta1", from_name = "bat"))] + bar: usize, + baz: bool, +} diff --git a/crates/stackable-versioned-macros/fixtures/inputs/default/skip_from_field.rs b/crates/stackable-versioned-macros/fixtures/inputs/default/skip_from_field.rs new file mode 100644 index 000000000..bb7c6dfe0 --- /dev/null +++ b/crates/stackable-versioned-macros/fixtures/inputs/default/skip_from_field.rs @@ -0,0 +1,14 @@ +#[versioned( + version(name = "v1alpha1"), + version(name = "v1beta1", skip(from)), + version(name = "v1") +)] +// --- +pub struct Foo { + #[versioned( + added(since = "v1beta1"), + deprecated(since = "v1", note = "not needed") + )] + deprecated_bar: usize, + baz: bool, +} diff --git a/crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__default_snapshots@attribute_enum.rs.snap.new b/crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__default_snapshots@attribute_enum.rs.snap.new new file mode 100644 index 000000000..0c4f3e963 --- /dev/null +++ b/crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__default_snapshots@attribute_enum.rs.snap.new @@ -0,0 +1,97 @@ +--- +source: crates/stackable-versioned-macros/src/lib.rs +assertion_line: 518 +expression: formatted +input_file: crates/stackable-versioned-macros/fixtures/inputs/default/attribute_enum.rs +--- +#[automatically_derived] +mod v1alpha1 { + use super::*; + #[derive(Default)] + pub enum Foo { + /// This variant is available in every version (so far). + #[default] + Foo, + /// Keep the main field docs the same, even after the field is + /// deprecated. + Bar, + /// This is will keep changing over time. + Qoox, + } +} +#[automatically_derived] +mod v1beta1 { + use super::*; + /// + ///Additional docs for this version which are purposefully long to + ///show how manual line wrapping works. \ + ///Multi-line docs are also supported, as per regular doc-comments. + #[derive(Default)] + pub enum Foo { + /// This variant is available in every version (so far). + #[default] + Foo, + /// Keep the main field docs the same, even after the field is + /// deprecated. + #[deprecated = "gone"] + DeprecatedBar, + /// This is for baz + Baz, + /// This is will keep changing over time. + Qaax, + } +} +#[automatically_derived] +mod v1beta2 { + use super::*; + #[derive(Default)] + pub enum Foo { + /// This variant is available in every version (so far). + #[default] + Foo, + /// Keep the main field docs the same, even after the field is + /// deprecated. + #[deprecated] + DeprecatedBar, + /// This is for baz + Baz, + /// This is will keep changing over time. + Qaax, + } +} +#[automatically_derived] +mod v1 { + use super::*; + #[derive(Default)] + pub enum Foo { + /// This variant is available in every version (so far). + #[default] + Foo, + /// Keep the main field docs the same, even after the field is + /// deprecated. + #[deprecated] + DeprecatedBar, + /// This is for baz + Baz, + /// This is will keep changing over time. + Quux, + } +} +#[automatically_derived] +mod v2 { + use super::*; + #[derive(Default)] + pub enum Foo { + /// This variant is available in every version (so far). + #[default] + Foo, + /// Keep the main field docs the same, even after the field is + /// deprecated. + #[deprecated] + DeprecatedBar, + /// This is for baz + Baz, + /// This is will keep changing over time. + Quux, + } +} diff --git a/crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__default_snapshots@attribute_struct.rs.snap.new b/crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__default_snapshots@attribute_struct.rs.snap.new new file mode 100644 index 000000000..0bad286a1 --- /dev/null +++ b/crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__default_snapshots@attribute_struct.rs.snap.new @@ -0,0 +1,92 @@ +--- +source: crates/stackable-versioned-macros/src/lib.rs +assertion_line: 518 +expression: formatted +input_file: crates/stackable-versioned-macros/fixtures/inputs/default/attribute_struct.rs +--- +#[automatically_derived] +mod v1alpha1 { + use super::*; + /// Test + #[derive(Default)] + pub struct Foo { + /// This field is available in every version (so far). + pub foo: String, + /// Keep the main field docs the same, even after the field is deprecated. + pub bar: String, + /// This is will keep changing over time. + pub qoox: String, + } +} +#[automatically_derived] +mod v1beta1 { + use super::*; + /// + ///Additional docs for this version which are purposefully long to + ///show how manual line wrapping works. \ + ///Multi-line docs are also supported, as per regular doc-comments. + /// Test + #[derive(Default)] + pub struct Foo { + /// This field is available in every version (so far). + pub foo: String, + /// Keep the main field docs the same, even after the field is deprecated. + #[deprecated = "gone"] + pub deprecated_bar: String, + /// This is for baz + pub baz: String, + /// This is will keep changing over time. + pub qaax: String, + } +} +#[automatically_derived] +mod v1beta2 { + use super::*; + /// Test + #[derive(Default)] + pub struct Foo { + /// This field is available in every version (so far). + pub foo: String, + /// Keep the main field docs the same, even after the field is deprecated. + #[deprecated] + pub deprecated_bar: String, + /// This is for baz + pub baz: String, + /// This is will keep changing over time. + pub qaax: String, + } +} +#[automatically_derived] +mod v1 { + use super::*; + /// Test + #[derive(Default)] + pub struct Foo { + /// This field is available in every version (so far). + pub foo: String, + /// Keep the main field docs the same, even after the field is deprecated. + #[deprecated] + pub deprecated_bar: String, + /// This is for baz + pub baz: String, + /// This is will keep changing over time. + pub quux: String, + } +} +#[automatically_derived] +mod v2 { + use super::*; + /// Test + #[derive(Default)] + pub struct Foo { + /// This field is available in every version (so far). + pub foo: String, + /// Keep the main field docs the same, even after the field is deprecated. + #[deprecated] + pub deprecated_bar: String, + /// This is for baz + pub baz: String, + /// This is will keep changing over time. + pub quux: String, + } +} diff --git a/crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__default_snapshots@basic.rs.snap.new b/crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__default_snapshots@basic.rs.snap.new new file mode 100644 index 000000000..6d8807eb6 --- /dev/null +++ b/crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__default_snapshots@basic.rs.snap.new @@ -0,0 +1,93 @@ +--- +source: crates/stackable-versioned-macros/src/lib.rs +assertion_line: 518 +expression: formatted +input_file: crates/stackable-versioned-macros/fixtures/inputs/default/basic.rs +--- +#[automatically_derived] +#[deprecated = "Version v1alpha1 is deprecated"] +pub(crate) mod v1alpha1 { + use super::*; + pub struct Foo { + /// Test + pub jjj: u8, + pub baz: bool, + } +} +#[automatically_derived] +#[allow(deprecated)] +impl From for v1beta1::Foo { + fn from(__sv_foo: v1alpha1::Foo) -> Self { + Self { + bar: __sv_foo.jjj.into(), + baz: __sv_foo.baz, + } + } +} +#[automatically_derived] +pub(crate) mod v1beta1 { + use super::*; + pub struct Foo { + /// Test + pub bar: u16, + pub baz: bool, + } +} +#[automatically_derived] +impl From for v1::Foo { + fn from(__sv_foo: v1beta1::Foo) -> Self { + Self { + bar: __sv_foo.bar.into(), + baz: __sv_foo.baz, + } + } +} +#[automatically_derived] +pub(crate) mod v1 { + use super::*; + pub struct Foo { + /// Test + pub bar: usize, + pub baz: bool, + } +} +#[automatically_derived] +#[allow(deprecated)] +impl From for v2::Foo { + fn from(__sv_foo: v1::Foo) -> Self { + Self { + deprecated_bar: __sv_foo.bar, + baz: __sv_foo.baz, + } + } +} +#[automatically_derived] +pub(crate) mod v2 { + use super::*; + pub struct Foo { + /// Test + #[deprecated = "not empty"] + pub deprecated_bar: usize, + pub baz: bool, + } +} +#[automatically_derived] +#[allow(deprecated)] +impl From for v3::Foo { + fn from(__sv_foo: v2::Foo) -> Self { + Self { + deprecated_bar: __sv_foo.deprecated_bar, + baz: __sv_foo.baz, + } + } +} +#[automatically_derived] +pub(crate) mod v3 { + use super::*; + pub struct Foo { + /// Test + #[deprecated] + pub deprecated_bar: usize, + pub baz: bool, + } +} diff --git a/crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__default_snapshots@deprecate_enum.rs.snap.new b/crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__default_snapshots@deprecate_enum.rs.snap.new new file mode 100644 index 000000000..1d3e23bae --- /dev/null +++ b/crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__default_snapshots@deprecate_enum.rs.snap.new @@ -0,0 +1,88 @@ +--- +source: crates/stackable-versioned-macros/src/lib.rs +assertion_line: 518 +expression: formatted +input_file: crates/stackable-versioned-macros/fixtures/inputs/default/deprecate_enum.rs +--- +#[automatically_derived] +mod v1alpha1 { + use super::*; + pub enum Foo { + Bar, + Baz, + } +} +#[automatically_derived] +impl From for v1beta1::Foo { + fn from(__sv_foo: v1alpha1::Foo) -> Self { + match __sv_foo { + v1alpha1::Foo::Bar => v1beta1::Foo::Bar, + v1alpha1::Foo::Baz => v1beta1::Foo::Baz, + } + } +} +#[automatically_derived] +mod v1beta1 { + use super::*; + pub enum Foo { + Bar, + Baz, + } +} +#[automatically_derived] +#[allow(deprecated)] +impl From for v1::Foo { + fn from(__sv_foo: v1beta1::Foo) -> Self { + match __sv_foo { + v1beta1::Foo::Bar => v1::Foo::DeprecatedBar, + v1beta1::Foo::Baz => v1::Foo::Baz, + } + } +} +#[automatically_derived] +mod v1 { + use super::*; + pub enum Foo { + #[deprecated] + DeprecatedBar, + Baz, + } +} +#[automatically_derived] +#[allow(deprecated)] +impl From for v2::Foo { + fn from(__sv_foo: v1::Foo) -> Self { + match __sv_foo { + v1::Foo::DeprecatedBar => v2::Foo::DeprecatedBar, + v1::Foo::Baz => v2::Foo::Baz, + } + } +} +#[automatically_derived] +mod v2 { + use super::*; + pub enum Foo { + #[deprecated] + DeprecatedBar, + Baz, + } +} +#[automatically_derived] +#[allow(deprecated)] +impl From for v3::Foo { + fn from(__sv_foo: v2::Foo) -> Self { + match __sv_foo { + v2::Foo::DeprecatedBar => v3::Foo::DeprecatedBar, + v2::Foo::Baz => v3::Foo::Baz, + } + } +} +#[automatically_derived] +mod v3 { + use super::*; + pub enum Foo { + #[deprecated] + DeprecatedBar, + Baz, + } +} diff --git a/crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__default_snapshots@deprecate_struct.rs.snap.new b/crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__default_snapshots@deprecate_struct.rs.snap.new new file mode 100644 index 000000000..05c2700ef --- /dev/null +++ b/crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__default_snapshots@deprecate_struct.rs.snap.new @@ -0,0 +1,88 @@ +--- +source: crates/stackable-versioned-macros/src/lib.rs +assertion_line: 518 +expression: formatted +input_file: crates/stackable-versioned-macros/fixtures/inputs/default/deprecate_struct.rs +--- +#[automatically_derived] +mod v1alpha1 { + use super::*; + pub struct Foo { + pub bar: usize, + pub baz: bool, + } +} +#[automatically_derived] +impl From for v1beta1::Foo { + fn from(__sv_foo: v1alpha1::Foo) -> Self { + Self { + bar: __sv_foo.bar, + baz: __sv_foo.baz, + } + } +} +#[automatically_derived] +mod v1beta1 { + use super::*; + pub struct Foo { + pub bar: usize, + pub baz: bool, + } +} +#[automatically_derived] +#[allow(deprecated)] +impl From for v1::Foo { + fn from(__sv_foo: v1beta1::Foo) -> Self { + Self { + deprecated_bar: __sv_foo.bar, + baz: __sv_foo.baz, + } + } +} +#[automatically_derived] +mod v1 { + use super::*; + pub struct Foo { + #[deprecated = "gone"] + pub deprecated_bar: usize, + pub baz: bool, + } +} +#[automatically_derived] +#[allow(deprecated)] +impl From for v2::Foo { + fn from(__sv_foo: v1::Foo) -> Self { + Self { + deprecated_bar: __sv_foo.deprecated_bar, + baz: __sv_foo.baz, + } + } +} +#[automatically_derived] +mod v2 { + use super::*; + pub struct Foo { + #[deprecated] + pub deprecated_bar: usize, + pub baz: bool, + } +} +#[automatically_derived] +#[allow(deprecated)] +impl From for v3::Foo { + fn from(__sv_foo: v2::Foo) -> Self { + Self { + deprecated_bar: __sv_foo.deprecated_bar, + baz: __sv_foo.baz, + } + } +} +#[automatically_derived] +mod v3 { + use super::*; + pub struct Foo { + #[deprecated] + pub deprecated_bar: usize, + pub baz: bool, + } +} diff --git a/crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__default_snapshots@rename.rs.snap.new b/crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__default_snapshots@rename.rs.snap.new new file mode 100644 index 000000000..7a6392eea --- /dev/null +++ b/crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__default_snapshots@rename.rs.snap.new @@ -0,0 +1,48 @@ +--- +source: crates/stackable-versioned-macros/src/lib.rs +assertion_line: 518 +expression: formatted +input_file: crates/stackable-versioned-macros/fixtures/inputs/default/rename.rs +--- +#[automatically_derived] +mod v1alpha1 { + use super::*; + pub struct Foo { + pub bat: usize, + pub baz: bool, + } +} +#[automatically_derived] +impl From for v1beta1::Foo { + fn from(__sv_foo: v1alpha1::Foo) -> Self { + Self { + bar: __sv_foo.bat, + baz: __sv_foo.baz, + } + } +} +#[automatically_derived] +mod v1beta1 { + use super::*; + pub struct Foo { + pub bar: usize, + pub baz: bool, + } +} +#[automatically_derived] +impl From for v1::Foo { + fn from(__sv_foo: v1beta1::Foo) -> Self { + Self { + bar: __sv_foo.bar, + baz: __sv_foo.baz, + } + } +} +#[automatically_derived] +mod v1 { + use super::*; + pub struct Foo { + pub bar: usize, + pub baz: bool, + } +} diff --git a/crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__default_snapshots@skip_from_field.rs.snap.new b/crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__default_snapshots@skip_from_field.rs.snap.new new file mode 100644 index 000000000..642661f6f --- /dev/null +++ b/crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__default_snapshots@skip_from_field.rs.snap.new @@ -0,0 +1,39 @@ +--- +source: crates/stackable-versioned-macros/src/lib.rs +assertion_line: 518 +expression: formatted +input_file: crates/stackable-versioned-macros/fixtures/inputs/default/skip_from_field.rs +--- +#[automatically_derived] +pub mod v1alpha1 { + use super::*; + pub struct Foo { + pub baz: bool, + } +} +#[automatically_derived] +impl From for v1beta1::Foo { + fn from(__sv_foo: v1alpha1::Foo) -> Self { + Self { + bar: ::std::default::Default::default(), + baz: __sv_foo.baz, + } + } +} +#[automatically_derived] +pub mod v1beta1 { + use super::*; + pub struct Foo { + pub bar: usize, + pub baz: bool, + } +} +#[automatically_derived] +pub mod v1 { + use super::*; + pub struct Foo { + #[deprecated = "not needed"] + pub deprecated_bar: usize, + pub baz: bool, + } +} diff --git a/crates/stackable-versioned-macros/src/lib.rs b/crates/stackable-versioned-macros/src/lib.rs index d5ec7dea9..9515283e1 100644 --- a/crates/stackable-versioned-macros/src/lib.rs +++ b/crates/stackable-versioned-macros/src/lib.rs @@ -4,6 +4,9 @@ use syn::{DeriveInput, Error}; use crate::attrs::common::ContainerAttributes; +#[cfg(test)] +mod test_utils; + mod attrs; mod codegen; mod consts; @@ -473,14 +476,6 @@ println!("{}", serde_yaml::to_string(&merged_crd).unwrap()); /// a cluster scoped. #[proc_macro_attribute] pub fn versioned(attrs: TokenStream, input: TokenStream) -> TokenStream { - let attrs = match NestedMeta::parse_meta_list(attrs.into()) { - Ok(attrs) => match ContainerAttributes::from_list(&attrs) { - Ok(attrs) => attrs, - Err(err) => return err.write_errors().into(), - }, - Err(err) => return darling::Error::from(err).write_errors().into(), - }; - // NOTE (@Techassi): For now, we can just use the DeriveInput type here, // because we only support structs end enums to be versioned. // In the future - if we decide to support modules - this requires @@ -488,8 +483,39 @@ pub fn versioned(attrs: TokenStream, input: TokenStream) -> TokenStream { // use an enum with two variants: Container(DeriveInput) and // Module(ItemMod). let input = syn::parse_macro_input!(input as DeriveInput); + versioned_impl(attrs.into(), input).into() +} + +fn versioned_impl(attrs: proc_macro2::TokenStream, input: DeriveInput) -> proc_macro2::TokenStream { + let attrs = match NestedMeta::parse_meta_list(attrs) { + Ok(attrs) => match ContainerAttributes::from_list(&attrs) { + Ok(attrs) => attrs, + Err(err) => return err.write_errors(), + }, + Err(err) => return darling::Error::from(err).write_errors(), + }; + + codegen::expand(attrs, input).unwrap_or_else(Error::into_compile_error) +} + +#[cfg(test)] +mod test { + use insta::{assert_snapshot, glob}; + + use super::*; + + #[test] + fn default_snapshots() { + let settings = test_utils::set_snapshot_path(); + let _guard = settings.bind_to_scope(); + + glob!("../fixtures/inputs/default", "*.rs", |path| { + let input = std::fs::read_to_string(path).unwrap(); + let (attrs, input) = test_utils::prepare_from_string(input); + let expanded = versioned_impl(attrs, input).to_string(); + let formatted = prettyplease::unparse(&syn::parse_file(&expanded).unwrap()); - codegen::expand(attrs, input) - .unwrap_or_else(Error::into_compile_error) - .into() + assert_snapshot!(formatted); + }); + } } diff --git a/crates/stackable-versioned-macros/src/test_utils.rs b/crates/stackable-versioned-macros/src/test_utils.rs new file mode 100644 index 000000000..baaf20e31 --- /dev/null +++ b/crates/stackable-versioned-macros/src/test_utils.rs @@ -0,0 +1,40 @@ +use std::{path::PathBuf, str::FromStr, sync::LazyLock}; + +use insta::Settings; +use proc_macro2::TokenStream; +use regex::Regex; +use syn::DeriveInput; + +const DELIMITER: &str = "// ---\n"; + +static REGEX: LazyLock = LazyLock::new(|| { + Regex::new(r"#\[versioned\(\n(?P[[:ascii:]]+)\n\)\]") + .expect("failed to compile versioned regex") +}); + +pub(crate) fn prepare_from_string(input: String) -> (TokenStream, DeriveInput) { + let (attrs, input) = input + .split_once(DELIMITER) + .expect("failed to find delimiter"); + + let attrs = REGEX + .captures(attrs) + .unwrap() + .name("args") + .expect("args match group must be available") + .as_str(); + + let attrs = TokenStream::from_str(attrs).expect("attrs must parse as a token stream"); + let input = TokenStream::from_str(input).expect("input mus parse as a token stream"); + let input = syn::parse2(input).expect("input must parse as derive input"); + + (attrs, input) +} + +pub(crate) fn set_snapshot_path() -> Settings { + let dir = std::env::var("CARGO_MANIFEST_DIR").expect("env var CARGO_MANIFEST_DIR must be set"); + let mut settings = Settings::clone_current(); + settings.set_snapshot_path(PathBuf::from(dir).join("fixtures/snapshots")); + + settings +} diff --git a/crates/stackable-versioned-macros/tests/default/pass/README.md b/crates/stackable-versioned-macros/tests/default/pass/README.md deleted file mode 100644 index e928d0edd..000000000 --- a/crates/stackable-versioned-macros/tests/default/pass/README.md +++ /dev/null @@ -1,6 +0,0 @@ -# trybuild good cases - -Code that is expected to compile lives here. Please see the docs in -[tests/trybuild.rs]. - -[tests/trybuild.rs]: ../trybuild.rs diff --git a/crates/stackable-versioned-macros/tests/default/pass/attributes_enum.rs b/crates/stackable-versioned-macros/tests/default/pass/attributes_enum.rs deleted file mode 100644 index ae73085dd..000000000 --- a/crates/stackable-versioned-macros/tests/default/pass/attributes_enum.rs +++ /dev/null @@ -1,43 +0,0 @@ -use stackable_versioned_macros::versioned; - -#[allow(dead_code)] -fn main() { - /// General enum docs that cover all versions. - #[versioned( - version(name = "v1alpha1"), - version( - name = "v1beta1", - doc = r#" - Additional docs for this version which are purposefully long to - show how manual line wrapping works. \ - Multi-line docs are also supported, as per regular doc-comments. - "# - ), - version(name = "v1beta2"), - version(name = "v1"), - version(name = "v2"), - options(skip(from)) - )] - #[derive(Default)] - enum Foo { - /// This variant is available in every version (so far). - #[default] - Foo, - - /// Keep the main field docs the same, even after the field is - /// deprecated. - #[versioned(deprecated(since = "v1beta1", note = "gone"))] - DeprecatedBar, - - /// This is for baz - #[versioned(added(since = "v1beta1"))] - // Just to check stackable-versioned deprecation warning appears. - // #[deprecated] - Baz, - - /// This is will keep changing over time. - #[versioned(changed(since = "v1beta1", from_name = "Qoox"))] - #[versioned(changed(since = "v1", from_name = "Qaax"))] - Quux, - } -} diff --git a/crates/stackable-versioned-macros/tests/default/pass/attributes_struct.rs b/crates/stackable-versioned-macros/tests/default/pass/attributes_struct.rs deleted file mode 100644 index 7790d424e..000000000 --- a/crates/stackable-versioned-macros/tests/default/pass/attributes_struct.rs +++ /dev/null @@ -1,60 +0,0 @@ -use stackable_versioned_macros::versioned; - -fn main() { - /// General struct docs that cover all versions. - #[versioned( - version(name = "v1alpha1"), - version( - name = "v1beta1", - doc = r#" - Additional docs for this version which are purposefully long to - show how manual line wrapping works. \ - Multi-line docs are also supported, as per regular doc-comments. - "# - ), - version(name = "v1beta2"), - version(name = "v1"), - version(name = "v2"), - options(skip(from)) - )] - #[derive(Default)] - struct Foo { - /// This field is available in every version (so far). - foo: String, - - /// Keep the main field docs the same, even after the field is deprecated. - #[versioned(deprecated(since = "v1beta1", note = "gone"))] - deprecated_bar: String, - - /// This is for baz - #[versioned(added(since = "v1beta1"))] - baz: String, - - /// This is will keep changing over time. - #[versioned(changed(since = "v1beta1", from_name = "qoox"))] - #[versioned(changed(since = "v1", from_name = "qaax"))] - quux: String, - } - - let _ = v1alpha1::Foo { - foo: String::from("foo"), - bar: String::from("Hello"), - qoox: String::from("world"), - }; - - #[allow(deprecated)] - let _ = v1beta1::Foo { - foo: String::from("foo"), - deprecated_bar: String::from("Hello"), - baz: String::from("Hello"), - qaax: String::from("World"), - }; - - #[allow(deprecated)] - let _ = v1::Foo { - foo: String::from("foo"), - deprecated_bar: String::from("Hello"), - baz: String::from("Hello"), - quux: String::from("World"), - }; -} diff --git a/crates/stackable-versioned-macros/tests/default/pass/basic.rs b/crates/stackable-versioned-macros/tests/default/pass/basic.rs deleted file mode 100644 index ea86f8814..000000000 --- a/crates/stackable-versioned-macros/tests/default/pass/basic.rs +++ /dev/null @@ -1,43 +0,0 @@ -use stackable_versioned_macros::versioned; - -// To expand the generated code (for debugging and testing), it is recommended -// to first change directory via `cd crates/stackable-versioned` and to then -// run `cargo expand --test basic --all-features`. -#[allow(dead_code)] -#[versioned( - version(name = "v1alpha1", deprecated), - version(name = "v1beta1"), - version(name = "v1"), - version(name = "v2"), - version(name = "v3") -)] -pub(crate) struct Foo { - #[versioned( - changed(since = "v1beta1", from_name = "jjj", from_type = "u8"), - changed(since = "v1", from_type = "u16"), - deprecated(since = "v2", note = "not empty") - )] - /// Test - deprecated_bar: usize, - baz: bool, -} - -fn main() { - #[allow(deprecated)] - let _ = v1alpha1::Foo { jjj: 0, baz: false }; - let _ = v1beta1::Foo { bar: 0, baz: false }; - let _ = v1::Foo { bar: 0, baz: false }; - - #[allow(deprecated)] - let _ = v2::Foo { - deprecated_bar: 0, - baz: false, - }; - - // The latest version (v3) - #[allow(deprecated)] - let _ = v3::Foo { - deprecated_bar: 0, - baz: false, - }; -} diff --git a/crates/stackable-versioned-macros/tests/default/pass/deprecate_enum.rs b/crates/stackable-versioned-macros/tests/default/pass/deprecate_enum.rs deleted file mode 100644 index b19f36b88..000000000 --- a/crates/stackable-versioned-macros/tests/default/pass/deprecate_enum.rs +++ /dev/null @@ -1,16 +0,0 @@ -use stackable_versioned_macros::versioned; - -fn main() { - #[versioned( - version(name = "v1alpha1"), - version(name = "v1beta1"), - version(name = "v1"), - version(name = "v2"), - version(name = "v3") - )] - enum Foo { - #[versioned(deprecated(since = "v1"))] - DeprecatedBar, - Baz, - } -} diff --git a/crates/stackable-versioned-macros/tests/default/pass/deprecate_struct.rs b/crates/stackable-versioned-macros/tests/default/pass/deprecate_struct.rs deleted file mode 100644 index feeafd377..000000000 --- a/crates/stackable-versioned-macros/tests/default/pass/deprecate_struct.rs +++ /dev/null @@ -1,16 +0,0 @@ -use stackable_versioned_macros::versioned; - -fn main() { - #[versioned( - version(name = "v1alpha1"), - version(name = "v1beta1"), - version(name = "v1"), - version(name = "v2"), - version(name = "v3") - )] - struct Foo { - #[versioned(deprecated(since = "v1", note = "gone"))] - deprecated_bar: usize, - baz: bool, - } -} diff --git a/crates/stackable-versioned-macros/tests/default/pass/rename.rs b/crates/stackable-versioned-macros/tests/default/pass/rename.rs deleted file mode 100644 index dac9b7689..000000000 --- a/crates/stackable-versioned-macros/tests/default/pass/rename.rs +++ /dev/null @@ -1,14 +0,0 @@ -use stackable_versioned_macros::versioned; - -fn main() { - #[versioned( - version(name = "v1alpha1"), - version(name = "v1beta1"), - version(name = "v1") - )] - struct Foo { - #[versioned(changed(since = "v1beta1", from_name = "bat"))] - bar: usize, - baz: bool, - } -} diff --git a/crates/stackable-versioned-macros/tests/default/pass/skip_from_version.rs b/crates/stackable-versioned-macros/tests/default/pass/skip_from_version.rs deleted file mode 100644 index 3308dc23b..000000000 --- a/crates/stackable-versioned-macros/tests/default/pass/skip_from_version.rs +++ /dev/null @@ -1,28 +0,0 @@ -use stackable_versioned_macros::versioned; - -#[allow(unused_variables)] -fn main() { - #[versioned( - version(name = "v1alpha1"), - version(name = "v1beta1", skip(from)), - version(name = "v1") - )] - pub struct Foo { - #[versioned( - added(since = "v1beta1"), - deprecated(since = "v1", note = "not needed") - )] - deprecated_bar: usize, - baz: bool, - } - - let foo_v1alpha1 = v1alpha1::Foo { baz: true }; - let foo_v1beta1 = v1beta1::Foo::from(foo_v1alpha1); - - #[allow(deprecated)] - // v1beta1 has no From impl, so we convert it manually - let foo_v1 = v1::Foo { - deprecated_bar: 0, - baz: true, - }; -} diff --git a/crates/stackable-versioned-macros/tests/trybuild.rs b/crates/stackable-versioned-macros/tests/trybuild.rs index fda62dee9..20efdfb9c 100644 --- a/crates/stackable-versioned-macros/tests/trybuild.rs +++ b/crates/stackable-versioned-macros/tests/trybuild.rs @@ -16,17 +16,6 @@ // again but before running tests, otherwise compilation will fail (as expected). #[allow(dead_code)] mod default { - // mod pass { - // // mod attributes_enum; - // // mod attributes_struct; - // // mod basic; - - // // mod deprecate_enum; - // // mod deprecate_struct; - // // mod rename; - // // mod skip_from_version; - // } - // mod fail { // mod deprecate; // mod skip_from_all; @@ -37,7 +26,6 @@ mod default { #[test] fn default_macros() { let t = trybuild::TestCases::new(); - t.pass("tests/default/pass/*.rs"); t.compile_fail("tests/default/fail/*.rs"); } From 94eb9133cbee24d979238892d7a270b3e142d09a Mon Sep 17 00:00:00 2001 From: Techassi Date: Fri, 27 Sep 2024 17:13:02 +0200 Subject: [PATCH 02/13] chore: Accept snapshots --- ...ioned_macros__test__default_snapshots@attribute_enum.rs.snap} | 1 - ...ned_macros__test__default_snapshots@attribute_struct.rs.snap} | 1 - ...ioned_macros__test__default_snapshots@deprecate_enum.rs.snap} | 1 - ...ned_macros__test__default_snapshots@deprecate_struct.rs.snap} | 1 - ...ble_versioned_macros__test__default_snapshots@rename.rs.snap} | 1 - ...oned_macros__test__default_snapshots@skip_from_field.rs.snap} | 1 - 6 files changed, 6 deletions(-) rename crates/stackable-versioned-macros/fixtures/snapshots/{stackable_versioned_macros__test__default_snapshots@attribute_enum.rs.snap.new => stackable_versioned_macros__test__default_snapshots@attribute_enum.rs.snap} (99%) rename crates/stackable-versioned-macros/fixtures/snapshots/{stackable_versioned_macros__test__default_snapshots@attribute_struct.rs.snap.new => stackable_versioned_macros__test__default_snapshots@attribute_struct.rs.snap} (99%) rename crates/stackable-versioned-macros/fixtures/snapshots/{stackable_versioned_macros__test__default_snapshots@deprecate_enum.rs.snap.new => stackable_versioned_macros__test__default_snapshots@deprecate_enum.rs.snap} (98%) rename crates/stackable-versioned-macros/fixtures/snapshots/{stackable_versioned_macros__test__default_snapshots@deprecate_struct.rs.snap.new => stackable_versioned_macros__test__default_snapshots@deprecate_struct.rs.snap} (98%) rename crates/stackable-versioned-macros/fixtures/snapshots/{stackable_versioned_macros__test__default_snapshots@rename.rs.snap.new => stackable_versioned_macros__test__default_snapshots@rename.rs.snap} (97%) rename crates/stackable-versioned-macros/fixtures/snapshots/{stackable_versioned_macros__test__default_snapshots@skip_from_field.rs.snap.new => stackable_versioned_macros__test__default_snapshots@skip_from_field.rs.snap} (97%) diff --git a/crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__default_snapshots@attribute_enum.rs.snap.new b/crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__default_snapshots@attribute_enum.rs.snap similarity index 99% rename from crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__default_snapshots@attribute_enum.rs.snap.new rename to crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__default_snapshots@attribute_enum.rs.snap index 0c4f3e963..32f2162a9 100644 --- a/crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__default_snapshots@attribute_enum.rs.snap.new +++ b/crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__default_snapshots@attribute_enum.rs.snap @@ -1,6 +1,5 @@ --- source: crates/stackable-versioned-macros/src/lib.rs -assertion_line: 518 expression: formatted input_file: crates/stackable-versioned-macros/fixtures/inputs/default/attribute_enum.rs --- diff --git a/crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__default_snapshots@attribute_struct.rs.snap.new b/crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__default_snapshots@attribute_struct.rs.snap similarity index 99% rename from crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__default_snapshots@attribute_struct.rs.snap.new rename to crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__default_snapshots@attribute_struct.rs.snap index 0bad286a1..440311ca7 100644 --- a/crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__default_snapshots@attribute_struct.rs.snap.new +++ b/crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__default_snapshots@attribute_struct.rs.snap @@ -1,6 +1,5 @@ --- source: crates/stackable-versioned-macros/src/lib.rs -assertion_line: 518 expression: formatted input_file: crates/stackable-versioned-macros/fixtures/inputs/default/attribute_struct.rs --- diff --git a/crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__default_snapshots@deprecate_enum.rs.snap.new b/crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__default_snapshots@deprecate_enum.rs.snap similarity index 98% rename from crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__default_snapshots@deprecate_enum.rs.snap.new rename to crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__default_snapshots@deprecate_enum.rs.snap index 1d3e23bae..17503b80c 100644 --- a/crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__default_snapshots@deprecate_enum.rs.snap.new +++ b/crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__default_snapshots@deprecate_enum.rs.snap @@ -1,6 +1,5 @@ --- source: crates/stackable-versioned-macros/src/lib.rs -assertion_line: 518 expression: formatted input_file: crates/stackable-versioned-macros/fixtures/inputs/default/deprecate_enum.rs --- diff --git a/crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__default_snapshots@deprecate_struct.rs.snap.new b/crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__default_snapshots@deprecate_struct.rs.snap similarity index 98% rename from crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__default_snapshots@deprecate_struct.rs.snap.new rename to crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__default_snapshots@deprecate_struct.rs.snap index 05c2700ef..afb5354a1 100644 --- a/crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__default_snapshots@deprecate_struct.rs.snap.new +++ b/crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__default_snapshots@deprecate_struct.rs.snap @@ -1,6 +1,5 @@ --- source: crates/stackable-versioned-macros/src/lib.rs -assertion_line: 518 expression: formatted input_file: crates/stackable-versioned-macros/fixtures/inputs/default/deprecate_struct.rs --- diff --git a/crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__default_snapshots@rename.rs.snap.new b/crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__default_snapshots@rename.rs.snap similarity index 97% rename from crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__default_snapshots@rename.rs.snap.new rename to crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__default_snapshots@rename.rs.snap index 7a6392eea..6e1bc3e84 100644 --- a/crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__default_snapshots@rename.rs.snap.new +++ b/crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__default_snapshots@rename.rs.snap @@ -1,6 +1,5 @@ --- source: crates/stackable-versioned-macros/src/lib.rs -assertion_line: 518 expression: formatted input_file: crates/stackable-versioned-macros/fixtures/inputs/default/rename.rs --- diff --git a/crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__default_snapshots@skip_from_field.rs.snap.new b/crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__default_snapshots@skip_from_field.rs.snap similarity index 97% rename from crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__default_snapshots@skip_from_field.rs.snap.new rename to crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__default_snapshots@skip_from_field.rs.snap index 642661f6f..1b40c6704 100644 --- a/crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__default_snapshots@skip_from_field.rs.snap.new +++ b/crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__default_snapshots@skip_from_field.rs.snap @@ -1,6 +1,5 @@ --- source: crates/stackable-versioned-macros/src/lib.rs -assertion_line: 518 expression: formatted input_file: crates/stackable-versioned-macros/fixtures/inputs/default/skip_from_field.rs --- From cd18ac6781cf5016a2730fcef471ce81084c28e7 Mon Sep 17 00:00:00 2001 From: Techassi Date: Fri, 27 Sep 2024 17:18:05 +0200 Subject: [PATCH 03/13] test: Rename basic snapshot test --- .../fixtures/inputs/default/{basic.rs => basic_struct.rs} | 0 ...ioned_macros__test__default_snapshots@basic_struct.rs.snap} | 3 +-- 2 files changed, 1 insertion(+), 2 deletions(-) rename crates/stackable-versioned-macros/fixtures/inputs/default/{basic.rs => basic_struct.rs} (100%) rename crates/stackable-versioned-macros/fixtures/snapshots/{stackable_versioned_macros__test__default_snapshots@basic.rs.snap.new => stackable_versioned_macros__test__default_snapshots@basic_struct.rs.snap} (98%) diff --git a/crates/stackable-versioned-macros/fixtures/inputs/default/basic.rs b/crates/stackable-versioned-macros/fixtures/inputs/default/basic_struct.rs similarity index 100% rename from crates/stackable-versioned-macros/fixtures/inputs/default/basic.rs rename to crates/stackable-versioned-macros/fixtures/inputs/default/basic_struct.rs diff --git a/crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__default_snapshots@basic.rs.snap.new b/crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__default_snapshots@basic_struct.rs.snap similarity index 98% rename from crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__default_snapshots@basic.rs.snap.new rename to crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__default_snapshots@basic_struct.rs.snap index 6d8807eb6..1de8b2805 100644 --- a/crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__default_snapshots@basic.rs.snap.new +++ b/crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__default_snapshots@basic_struct.rs.snap @@ -1,8 +1,7 @@ --- source: crates/stackable-versioned-macros/src/lib.rs -assertion_line: 518 expression: formatted -input_file: crates/stackable-versioned-macros/fixtures/inputs/default/basic.rs +input_file: crates/stackable-versioned-macros/fixtures/inputs/default/basic_struct.rs --- #[automatically_derived] #[deprecated = "Version v1alpha1 is deprecated"] From 18068e8974a5046d3591db120b7a5f6e8d4f637a Mon Sep 17 00:00:00 2001 From: Techassi Date: Mon, 30 Sep 2024 13:43:24 +0200 Subject: [PATCH 04/13] Update crates/stackable-versioned-macros/fixtures/README.md Co-authored-by: Nick <10092581+NickLarsenNZ@users.noreply.github.com> --- crates/stackable-versioned-macros/fixtures/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/stackable-versioned-macros/fixtures/README.md b/crates/stackable-versioned-macros/fixtures/README.md index e3a8d0eb4..6cfdc5102 100644 --- a/crates/stackable-versioned-macros/fixtures/README.md +++ b/crates/stackable-versioned-macros/fixtures/README.md @@ -46,7 +46,7 @@ cargo insta test -p stackable-versioned-macros ``` This command will place the new snapshot files in the `fixtures/snapshots` folder. To review them, -run the `cargo insta review` command. Now check these files in. +run the `cargo insta review` command, then accept or fix the snapshots. Once all are accepted (ie: no `.new` files remaining), check in the files. [rust-ref]: https://doc.rust-lang.org/reference/procedural-macros.html#attribute-macros [insta-ext]: https://insta.rs/docs/vscode/ From cf1ec2109df582531c984a35468f4b007d2ec4fd Mon Sep 17 00:00:00 2001 From: Techassi Date: Mon, 30 Sep 2024 13:52:44 +0200 Subject: [PATCH 05/13] chore: Update snapshot testing README --- crates/stackable-versioned-macros/fixtures/README.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/crates/stackable-versioned-macros/fixtures/README.md b/crates/stackable-versioned-macros/fixtures/README.md index 6cfdc5102..5bca9aab1 100644 --- a/crates/stackable-versioned-macros/fixtures/README.md +++ b/crates/stackable-versioned-macros/fixtures/README.md @@ -39,14 +39,17 @@ pub(crate) struct Foo { First, add new input files (which automatically get picked up by `insta`) to the `fixtures/inputs` folder. Make sure the delimiter is placed correctly between the attribute and the container -definition. Next, generate the snapshot files (initially not accepted) by running +definition. Doc comments on the container have to be placed after the delimiter. Next, generate the +snapshot files (initially not accepted) by running ```shell cargo insta test -p stackable-versioned-macros ``` -This command will place the new snapshot files in the `fixtures/snapshots` folder. To review them, -run the `cargo insta review` command, then accept or fix the snapshots. Once all are accepted (ie: no `.new` files remaining), check in the files. +This command will place the new snapshot files (with a `.new` extension) in the `fixtures/snapshots` +folder. These new snapshot files must not appear on `main`, but can be shared on branches for +collaboration. To review them, run the `cargo insta review` command, then accept or fix the +snapshots. Once all are accepted (ie: no `.new` files remaining), check in the files. [rust-ref]: https://doc.rust-lang.org/reference/procedural-macros.html#attribute-macros [insta-ext]: https://insta.rs/docs/vscode/ From 64c04c2a4fc930f47b9f16f855767ed233b80930 Mon Sep 17 00:00:00 2001 From: Techassi Date: Mon, 30 Sep 2024 13:53:24 +0200 Subject: [PATCH 06/13] chore: Mark .snap files as generated --- .gitattributes | 1 + 1 file changed, 1 insertion(+) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 000000000..8b75a8c37 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +*.snap linguist-generated From 882d8fadec52f4cd506b14d1ef4c506237f97799 Mon Sep 17 00:00:00 2001 From: Techassi Date: Mon, 30 Sep 2024 14:50:31 +0200 Subject: [PATCH 07/13] chore: Add k8s snapshot test, rework test utils --- Cargo.lock | 1 + crates/stackable-versioned-macros/Cargo.toml | 1 + .../fixtures/inputs/k8s/basic.rs | 21 ++++ ...versioned_macros__test__k8s_snapshots.snap | 115 ++++++++++++++++++ crates/stackable-versioned-macros/src/lib.rs | 21 +++- .../src/test_utils.rs | 56 +++++++-- .../tests/k8s/pass/crd.rs | 31 ----- .../tests/trybuild.rs | 5 - 8 files changed, 199 insertions(+), 52 deletions(-) create mode 100644 crates/stackable-versioned-macros/fixtures/inputs/k8s/basic.rs create mode 100644 crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__k8s_snapshots.snap delete mode 100644 crates/stackable-versioned-macros/tests/k8s/pass/crd.rs diff --git a/Cargo.lock b/Cargo.lock index ba7012620..3612a8a51 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3098,6 +3098,7 @@ dependencies = [ "serde", "serde_json", "serde_yaml", + "snafu 0.8.4", "strum", "syn 2.0.77", "trybuild", diff --git a/crates/stackable-versioned-macros/Cargo.toml b/crates/stackable-versioned-macros/Cargo.toml index b640362c0..1329633ce 100644 --- a/crates/stackable-versioned-macros/Cargo.toml +++ b/crates/stackable-versioned-macros/Cargo.toml @@ -46,4 +46,5 @@ schemars.workspace = true serde.workspace = true serde_json.workspace = true serde_yaml.workspace = true +snafu.workspace = true trybuild.workspace = true diff --git a/crates/stackable-versioned-macros/fixtures/inputs/k8s/basic.rs b/crates/stackable-versioned-macros/fixtures/inputs/k8s/basic.rs new file mode 100644 index 000000000..4e4449a0c --- /dev/null +++ b/crates/stackable-versioned-macros/fixtures/inputs/k8s/basic.rs @@ -0,0 +1,21 @@ +#[versioned( + version(name = "v1alpha1"), + version(name = "v1beta1"), + version(name = "v1"), + k8s( + group = "stackable.tech", + singular = "foo", + plural = "foos", + namespaced, + ) +)] +// --- +#[derive(Clone, Debug, serde::Deserialize, serde::Serialize, schemars::JsonSchema)] +pub struct FooSpec { + #[versioned( + added(since = "v1beta1"), + changed(since = "v1", from_name = "bah", from_type = "u16") + )] + bar: usize, + baz: bool, +} diff --git a/crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__k8s_snapshots.snap b/crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__k8s_snapshots.snap new file mode 100644 index 000000000..6561d0db3 --- /dev/null +++ b/crates/stackable-versioned-macros/fixtures/snapshots/stackable_versioned_macros__test__k8s_snapshots.snap @@ -0,0 +1,115 @@ +--- +source: crates/stackable-versioned-macros/src/lib.rs +expression: formatted +input_file: crates/stackable-versioned-macros/fixtures/inputs/k8s/basic.rs +--- +#[automatically_derived] +pub mod v1alpha1 { + use super::*; + #[derive(Clone, Debug, serde::Deserialize, serde::Serialize, schemars::JsonSchema)] + #[derive(::kube::CustomResource)] + #[kube( + group = "stackable.tech", + version = "v1alpha1", + kind = "Foo", + singular = "foo", + plural = "foos", + namespaced + )] + pub struct FooSpec { + pub baz: bool, + } +} +#[automatically_derived] +impl From for v1beta1::FooSpec { + fn from(__sv_foospec: v1alpha1::FooSpec) -> Self { + Self { + bah: ::std::default::Default::default(), + baz: __sv_foospec.baz, + } + } +} +#[automatically_derived] +pub mod v1beta1 { + use super::*; + #[derive(Clone, Debug, serde::Deserialize, serde::Serialize, schemars::JsonSchema)] + #[derive(::kube::CustomResource)] + #[kube( + group = "stackable.tech", + version = "v1beta1", + kind = "Foo", + singular = "foo", + plural = "foos", + namespaced + )] + pub struct FooSpec { + pub bah: u16, + pub baz: bool, + } +} +#[automatically_derived] +impl From for v1::FooSpec { + fn from(__sv_foospec: v1beta1::FooSpec) -> Self { + Self { + bar: __sv_foospec.bah.into(), + baz: __sv_foospec.baz, + } + } +} +#[automatically_derived] +pub mod v1 { + use super::*; + #[derive(Clone, Debug, serde::Deserialize, serde::Serialize, schemars::JsonSchema)] + #[derive(::kube::CustomResource)] + #[kube( + group = "stackable.tech", + version = "v1", + kind = "Foo", + singular = "foo", + plural = "foos", + namespaced + )] + pub struct FooSpec { + pub bar: usize, + pub baz: bool, + } +} +#[automatically_derived] +pub enum Foo { + V1Alpha1, + V1Beta1, + V1, +} +#[automatically_derived] +impl ::std::fmt::Display for Foo { + fn fmt( + &self, + f: &mut ::std::fmt::Formatter<'_>, + ) -> ::std::result::Result<(), ::std::fmt::Error> { + match self { + Foo::V1Alpha1 => f.write_str("v1alpha1"), + Foo::V1Beta1 => f.write_str("v1beta1"), + Foo::V1 => f.write_str("v1"), + } + } +} +#[automatically_derived] +impl Foo { + /// Generates a merged CRD which contains all versions defined using the + /// `#[versioned()]` macro. + pub fn merged_crd( + stored_apiversion: Self, + ) -> ::std::result::Result< + ::k8s_openapi::apiextensions_apiserver::pkg::apis::apiextensions::v1::CustomResourceDefinition, + ::kube::core::crd::MergeError, + > { + ::kube::core::crd::merge_crds( + vec![ + < v1alpha1::Foo as ::kube::CustomResourceExt > ::crd(), < v1beta1::Foo as + ::kube::CustomResourceExt > ::crd(), < v1::Foo as + ::kube::CustomResourceExt > ::crd() + ], + &stored_apiversion.to_string(), + ) + } +} diff --git a/crates/stackable-versioned-macros/src/lib.rs b/crates/stackable-versioned-macros/src/lib.rs index 9515283e1..6cc0c25ec 100644 --- a/crates/stackable-versioned-macros/src/lib.rs +++ b/crates/stackable-versioned-macros/src/lib.rs @@ -506,15 +506,24 @@ mod test { #[test] fn default_snapshots() { - let settings = test_utils::set_snapshot_path(); - let _guard = settings.bind_to_scope(); + let _settings_guard = test_utils::set_snapshot_path().bind_to_scope(); glob!("../fixtures/inputs/default", "*.rs", |path| { - let input = std::fs::read_to_string(path).unwrap(); - let (attrs, input) = test_utils::prepare_from_string(input); - let expanded = versioned_impl(attrs, input).to_string(); - let formatted = prettyplease::unparse(&syn::parse_file(&expanded).unwrap()); + let formatted = test_utils::expand_from_file(path) + .inspect_err(|err| eprintln!("{err}")) + .unwrap(); + assert_snapshot!(formatted); + }); + } + + #[test] + fn k8s_snapshots() { + let _settings_guard = test_utils::set_snapshot_path().bind_to_scope(); + glob!("../fixtures/inputs/k8s", "*.rs", |path| { + let formatted = test_utils::expand_from_file(path) + .inspect_err(|err| eprintln!("{err}")) + .unwrap(); assert_snapshot!(formatted); }); } diff --git a/crates/stackable-versioned-macros/src/test_utils.rs b/crates/stackable-versioned-macros/src/test_utils.rs index baaf20e31..92dbca906 100644 --- a/crates/stackable-versioned-macros/src/test_utils.rs +++ b/crates/stackable-versioned-macros/src/test_utils.rs @@ -1,10 +1,17 @@ -use std::{path::PathBuf, str::FromStr, sync::LazyLock}; +use std::{ + path::{Path, PathBuf}, + str::FromStr, + sync::LazyLock, +}; use insta::Settings; use proc_macro2::TokenStream; use regex::Regex; +use snafu::{OptionExt, ResultExt, Snafu}; use syn::DeriveInput; +use crate::versioned_impl; + const DELIMITER: &str = "// ---\n"; static REGEX: LazyLock = LazyLock::new(|| { @@ -12,23 +19,52 @@ static REGEX: LazyLock = LazyLock::new(|| { .expect("failed to compile versioned regex") }); -pub(crate) fn prepare_from_string(input: String) -> (TokenStream, DeriveInput) { - let (attrs, input) = input - .split_once(DELIMITER) - .expect("failed to find delimiter"); +#[derive(Debug, Snafu)] +pub(crate) enum Error { + #[snafu(display("failed to read input file"))] + ReadFile { source: std::io::Error }, + + #[snafu(display("failed to find delimiter"))] + MissingDelimiter, + + #[snafu(display("failed to find regex match group"))] + MissingRegexMatchGroup, + + #[snafu(display("failed to parse token stream"))] + ParseTokenStream { source: proc_macro2::LexError }, + + #[snafu(display("failed to parse derive input"))] + ParseDeriveInput { source: syn::Error }, + + #[snafu(display("failed to parse output file"))] + ParseOutputFile { source: syn::Error }, +} + +pub(crate) fn expand_from_file(path: &Path) -> Result { + let input = std::fs::read_to_string(path).context(ReadFileSnafu)?; + let (attrs, input) = prepare_from_string(input)?; + + let expanded = versioned_impl(attrs, input).to_string(); + let parsed = syn::parse_file(&expanded).context(ParseOutputFileSnafu)?; + + Ok(prettyplease::unparse(&parsed)) +} + +fn prepare_from_string(input: String) -> Result<(TokenStream, DeriveInput), Error> { + let (attrs, input) = input.split_once(DELIMITER).context(MissingDelimiterSnafu)?; let attrs = REGEX .captures(attrs) .unwrap() .name("args") - .expect("args match group must be available") + .context(MissingRegexMatchGroupSnafu)? .as_str(); - let attrs = TokenStream::from_str(attrs).expect("attrs must parse as a token stream"); - let input = TokenStream::from_str(input).expect("input mus parse as a token stream"); - let input = syn::parse2(input).expect("input must parse as derive input"); + let attrs = TokenStream::from_str(attrs).context(ParseTokenStreamSnafu)?; + let input = TokenStream::from_str(input).context(ParseTokenStreamSnafu)?; + let input = syn::parse2(input).context(ParseDeriveInputSnafu)?; - (attrs, input) + Ok((attrs, input)) } pub(crate) fn set_snapshot_path() -> Settings { diff --git a/crates/stackable-versioned-macros/tests/k8s/pass/crd.rs b/crates/stackable-versioned-macros/tests/k8s/pass/crd.rs deleted file mode 100644 index 158630f19..000000000 --- a/crates/stackable-versioned-macros/tests/k8s/pass/crd.rs +++ /dev/null @@ -1,31 +0,0 @@ -use schemars::JsonSchema; -use serde::{Deserialize, Serialize}; - -use stackable_versioned_macros::versioned; - -#[allow(deprecated)] -fn main() { - #[versioned( - version(name = "v1alpha1"), - version(name = "v1beta1"), - version(name = "v1"), - k8s( - group = "stackable.tech", - singular = "foo", - plural = "foos", - namespaced, - ) - )] - #[derive(Clone, Debug, Deserialize, Serialize, JsonSchema)] - pub struct FooSpec { - #[versioned( - added(since = "v1beta1"), - changed(since = "v1", from_name = "bah", from_type = "u16") - )] - bar: usize, - baz: bool, - } - - let merged_crd = Foo::merged_crd(Foo::V1).unwrap(); - println!("{}", serde_yaml::to_string(&merged_crd).unwrap()); -} diff --git a/crates/stackable-versioned-macros/tests/trybuild.rs b/crates/stackable-versioned-macros/tests/trybuild.rs index 20efdfb9c..3070189c9 100644 --- a/crates/stackable-versioned-macros/tests/trybuild.rs +++ b/crates/stackable-versioned-macros/tests/trybuild.rs @@ -32,10 +32,6 @@ fn default_macros() { #[cfg(feature = "k8s")] #[allow(dead_code)] mod k8s { - // mod pass { - // mod crd; - // } - // mod fail { // mod crd; // } @@ -45,6 +41,5 @@ mod k8s { #[test] fn k8s_macros() { let t = trybuild::TestCases::new(); - t.pass("tests/k8s/pass/*.rs"); t.compile_fail("tests/k8s/fail/*.rs"); } From ff2fd24fee4e87ee487d1aeee14aa92ad96c0659 Mon Sep 17 00:00:00 2001 From: Techassi Date: Mon, 30 Sep 2024 15:51:33 +0200 Subject: [PATCH 08/13] chore: Move compile-fail tests --- .../fixtures/README.md | 3 ++ .../tests/README.md | 17 ++++++ .../tests/default/{fail => }/changed.rs | 0 .../tests/default/{fail => }/changed.stderr | 0 .../tests/default/{fail => }/deprecate.rs | 0 .../tests/default/{fail => }/deprecate.stderr | 0 .../tests/default/fail/README.md | 6 --- .../tests/default/{fail => }/skip_from_all.rs | 0 .../default/{fail => }/skip_from_all.stderr | 0 .../default/{fail => }/skip_from_version.rs | 0 .../{fail => }/skip_from_version.stderr | 0 .../stackable-versioned-macros/tests/enum.rs | 23 -------- .../stackable-versioned-macros/tests/from.rs | 53 ------------------- .../tests/k8s/{fail => }/crd.rs | 0 .../tests/k8s/{fail => }/crd.stderr | 0 .../tests/trybuild.rs | 16 +++--- 16 files changed, 26 insertions(+), 92 deletions(-) create mode 100644 crates/stackable-versioned-macros/tests/README.md rename crates/stackable-versioned-macros/tests/default/{fail => }/changed.rs (100%) rename crates/stackable-versioned-macros/tests/default/{fail => }/changed.stderr (100%) rename crates/stackable-versioned-macros/tests/default/{fail => }/deprecate.rs (100%) rename crates/stackable-versioned-macros/tests/default/{fail => }/deprecate.stderr (100%) delete mode 100644 crates/stackable-versioned-macros/tests/default/fail/README.md rename crates/stackable-versioned-macros/tests/default/{fail => }/skip_from_all.rs (100%) rename crates/stackable-versioned-macros/tests/default/{fail => }/skip_from_all.stderr (100%) rename crates/stackable-versioned-macros/tests/default/{fail => }/skip_from_version.rs (100%) rename crates/stackable-versioned-macros/tests/default/{fail => }/skip_from_version.stderr (100%) delete mode 100644 crates/stackable-versioned-macros/tests/enum.rs delete mode 100644 crates/stackable-versioned-macros/tests/from.rs rename crates/stackable-versioned-macros/tests/k8s/{fail => }/crd.rs (100%) rename crates/stackable-versioned-macros/tests/k8s/{fail => }/crd.stderr (100%) diff --git a/crates/stackable-versioned-macros/fixtures/README.md b/crates/stackable-versioned-macros/fixtures/README.md index 5bca9aab1..f27b580ea 100644 --- a/crates/stackable-versioned-macros/fixtures/README.md +++ b/crates/stackable-versioned-macros/fixtures/README.md @@ -1,5 +1,8 @@ # Snapshot Testing +> [!NOTE] +> Also see the compile-fail tests, described [here](../tests/README.md). + This folder contains fixtures for snapshot testing the `#[versioned()]` macro. Snapshot testing is done using the [insta] crate. It provides a [CLI tool][insta-cli] called `cargo-insta` and a [VS Code extension][insta-ext]. diff --git a/crates/stackable-versioned-macros/tests/README.md b/crates/stackable-versioned-macros/tests/README.md new file mode 100644 index 000000000..a8d3f7598 --- /dev/null +++ b/crates/stackable-versioned-macros/tests/README.md @@ -0,0 +1,17 @@ +# Compile-Fail Testing + +> [!NOTE] +> Also see the snapshot tests, described [here](../fixtures/README.md). + +This type of testing is part of UI testing. These tests assert two things: First, the code should +**not** compile and secondly should also produce the expected rustc (compiler) error message. For +this type of testing, we use the [`trybuild`][trybuild] crate. + +Tests are currently separated into two folders: `default` and `k8s`. The default test cases don't +require any additional features to be activated. The Kubernetes specific tests require the `k8s` +feature to be enabled. These tests can be run with `cargo test --all-features`. + +Further information about the workflow are described [here][workflow]. + +[workflow]: https://docs.rs/trybuild/latest/trybuild/#workflow +[trybuild]: https://docs.rs/trybuild/latest/trybuild/ diff --git a/crates/stackable-versioned-macros/tests/default/fail/changed.rs b/crates/stackable-versioned-macros/tests/default/changed.rs similarity index 100% rename from crates/stackable-versioned-macros/tests/default/fail/changed.rs rename to crates/stackable-versioned-macros/tests/default/changed.rs diff --git a/crates/stackable-versioned-macros/tests/default/fail/changed.stderr b/crates/stackable-versioned-macros/tests/default/changed.stderr similarity index 100% rename from crates/stackable-versioned-macros/tests/default/fail/changed.stderr rename to crates/stackable-versioned-macros/tests/default/changed.stderr diff --git a/crates/stackable-versioned-macros/tests/default/fail/deprecate.rs b/crates/stackable-versioned-macros/tests/default/deprecate.rs similarity index 100% rename from crates/stackable-versioned-macros/tests/default/fail/deprecate.rs rename to crates/stackable-versioned-macros/tests/default/deprecate.rs diff --git a/crates/stackable-versioned-macros/tests/default/fail/deprecate.stderr b/crates/stackable-versioned-macros/tests/default/deprecate.stderr similarity index 100% rename from crates/stackable-versioned-macros/tests/default/fail/deprecate.stderr rename to crates/stackable-versioned-macros/tests/default/deprecate.stderr diff --git a/crates/stackable-versioned-macros/tests/default/fail/README.md b/crates/stackable-versioned-macros/tests/default/fail/README.md deleted file mode 100644 index d19327a52..000000000 --- a/crates/stackable-versioned-macros/tests/default/fail/README.md +++ /dev/null @@ -1,6 +0,0 @@ -# trybuild bad cases - -Code that is expected to fail lives here along with the expected compiler output -for each case. Please see the docs in [tests/trybuild.rs]. - -[tests/trybuild.rs]: ../trybuild.rs diff --git a/crates/stackable-versioned-macros/tests/default/fail/skip_from_all.rs b/crates/stackable-versioned-macros/tests/default/skip_from_all.rs similarity index 100% rename from crates/stackable-versioned-macros/tests/default/fail/skip_from_all.rs rename to crates/stackable-versioned-macros/tests/default/skip_from_all.rs diff --git a/crates/stackable-versioned-macros/tests/default/fail/skip_from_all.stderr b/crates/stackable-versioned-macros/tests/default/skip_from_all.stderr similarity index 100% rename from crates/stackable-versioned-macros/tests/default/fail/skip_from_all.stderr rename to crates/stackable-versioned-macros/tests/default/skip_from_all.stderr diff --git a/crates/stackable-versioned-macros/tests/default/fail/skip_from_version.rs b/crates/stackable-versioned-macros/tests/default/skip_from_version.rs similarity index 100% rename from crates/stackable-versioned-macros/tests/default/fail/skip_from_version.rs rename to crates/stackable-versioned-macros/tests/default/skip_from_version.rs diff --git a/crates/stackable-versioned-macros/tests/default/fail/skip_from_version.stderr b/crates/stackable-versioned-macros/tests/default/skip_from_version.stderr similarity index 100% rename from crates/stackable-versioned-macros/tests/default/fail/skip_from_version.stderr rename to crates/stackable-versioned-macros/tests/default/skip_from_version.stderr diff --git a/crates/stackable-versioned-macros/tests/enum.rs b/crates/stackable-versioned-macros/tests/enum.rs deleted file mode 100644 index c43b1da1e..000000000 --- a/crates/stackable-versioned-macros/tests/enum.rs +++ /dev/null @@ -1,23 +0,0 @@ -use stackable_versioned_macros::versioned; - -#[test] -fn versioned_enum() { - #[versioned( - version(name = "v1alpha1"), - version(name = "v1beta1", deprecated), - version(name = "v1") - )] - pub enum Foo { - #[versioned(added(since = "v1beta1"), deprecated(since = "v1", note = "bye"))] - DeprecatedBar, - Baz, - } - - let v1alpha1_foo = v1alpha1::Foo::Baz; - #[allow(deprecated)] - let v1beta1_foo = v1beta1::Foo::from(v1alpha1_foo); - let v1_foo = v1::Foo::from(v1beta1_foo); - - // TODO (@Techassi): Forward derive PartialEq - assert!(matches!(v1_foo, v1::Foo::Baz)) -} diff --git a/crates/stackable-versioned-macros/tests/from.rs b/crates/stackable-versioned-macros/tests/from.rs deleted file mode 100644 index 0012743c1..000000000 --- a/crates/stackable-versioned-macros/tests/from.rs +++ /dev/null @@ -1,53 +0,0 @@ -use stackable_versioned_macros::versioned; - -#[allow(deprecated)] -#[test] -fn from() { - #[versioned( - version(name = "v1alpha1"), - version(name = "v1beta1"), - version(name = "v1") - )] - pub struct Foo { - #[versioned( - added(since = "v1beta1"), - deprecated(since = "v1", note = "not needed") - )] - deprecated_bar: usize, - baz: bool, - } - - let foo_v1alpha1 = v1alpha1::Foo { baz: true }; - let foo_v1beta1 = v1beta1::Foo::from(foo_v1alpha1); - let foo_v1 = v1::Foo::from(foo_v1beta1); - - assert_eq!(foo_v1.deprecated_bar, 0); - assert!(foo_v1.baz); -} - -#[test] -fn from_custom_default_fn() { - #[versioned( - version(name = "v1alpha1"), - version(name = "v1beta1"), - version(name = "v1") - )] - pub struct Foo { - #[versioned( - added(since = "v1beta1", default = "default_bar"), - deprecated(since = "v1", note = "not needed") - )] - deprecated_bar: usize, - baz: bool, - } - - fn default_bar() -> usize { - 42 - } - - let foo_v1alpha1 = v1alpha1::Foo { baz: true }; - let foo_v1beta1 = v1beta1::Foo::from(foo_v1alpha1); - - assert_eq!(foo_v1beta1.bar, 42); - assert!(foo_v1beta1.baz); -} diff --git a/crates/stackable-versioned-macros/tests/k8s/fail/crd.rs b/crates/stackable-versioned-macros/tests/k8s/crd.rs similarity index 100% rename from crates/stackable-versioned-macros/tests/k8s/fail/crd.rs rename to crates/stackable-versioned-macros/tests/k8s/crd.rs diff --git a/crates/stackable-versioned-macros/tests/k8s/fail/crd.stderr b/crates/stackable-versioned-macros/tests/k8s/crd.stderr similarity index 100% rename from crates/stackable-versioned-macros/tests/k8s/fail/crd.stderr rename to crates/stackable-versioned-macros/tests/k8s/crd.stderr diff --git a/crates/stackable-versioned-macros/tests/trybuild.rs b/crates/stackable-versioned-macros/tests/trybuild.rs index 3070189c9..7d1e7229a 100644 --- a/crates/stackable-versioned-macros/tests/trybuild.rs +++ b/crates/stackable-versioned-macros/tests/trybuild.rs @@ -16,30 +16,26 @@ // again but before running tests, otherwise compilation will fail (as expected). #[allow(dead_code)] mod default { - // mod fail { - // mod deprecate; - // mod skip_from_all; - // mod skip_from_version; - // } + // mod deprecate; + // mod skip_from_all; + // mod skip_from_version; } #[test] fn default_macros() { let t = trybuild::TestCases::new(); - t.compile_fail("tests/default/fail/*.rs"); + t.compile_fail("tests/default/*.rs"); } #[cfg(feature = "k8s")] #[allow(dead_code)] mod k8s { - // mod fail { - // mod crd; - // } + // mod crd; } #[cfg(feature = "k8s")] #[test] fn k8s_macros() { let t = trybuild::TestCases::new(); - t.compile_fail("tests/k8s/fail/*.rs"); + t.compile_fail("tests/k8s/*.rs"); } From 58b03e7feceaaf0206c98ec09005fce8eab1930e Mon Sep 17 00:00:00 2001 From: Techassi Date: Mon, 30 Sep 2024 15:52:56 +0200 Subject: [PATCH 09/13] test: Add k8s feature gate --- crates/stackable-versioned-macros/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/stackable-versioned-macros/src/lib.rs b/crates/stackable-versioned-macros/src/lib.rs index 6cc0c25ec..469adae82 100644 --- a/crates/stackable-versioned-macros/src/lib.rs +++ b/crates/stackable-versioned-macros/src/lib.rs @@ -516,6 +516,7 @@ mod test { }); } + #[cfg(feature = "k8s")] #[test] fn k8s_snapshots() { let _settings_guard = test_utils::set_snapshot_path().bind_to_scope(); From de30b50d447eed4eac71da43c672ecd994080637 Mon Sep 17 00:00:00 2001 From: Techassi Date: Mon, 30 Sep 2024 16:01:05 +0200 Subject: [PATCH 10/13] test: Update stderr output files --- .../stackable-versioned-macros/tests/default/changed.stderr | 4 ++-- .../tests/default/deprecate.stderr | 2 +- .../tests/default/skip_from_all.stderr | 6 +++--- .../tests/default/skip_from_version.stderr | 6 +++--- crates/stackable-versioned-macros/tests/k8s/crd.stderr | 4 ++-- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/crates/stackable-versioned-macros/tests/default/changed.stderr b/crates/stackable-versioned-macros/tests/default/changed.stderr index a6d0d4070..46ae472a5 100644 --- a/crates/stackable-versioned-macros/tests/default/changed.stderr +++ b/crates/stackable-versioned-macros/tests/default/changed.stderr @@ -1,11 +1,11 @@ error: the previous field name must not start with the deprecation prefix - --> tests/default/fail/changed.rs:11:52 + --> tests/default/changed.rs:11:52 | 11 | changed(since = "v1beta1", from_name = "deprecated_bar"), | ^^^^^^^^^^^^^^^^ error: the previous field name must not start with the deprecation prefix - --> tests/default/fail/changed.rs:12:47 + --> tests/default/changed.rs:12:47 | 12 | changed(since = "v1", from_name = "deprecated_baz") | ^^^^^^^^^^^^^^^^ diff --git a/crates/stackable-versioned-macros/tests/default/deprecate.stderr b/crates/stackable-versioned-macros/tests/default/deprecate.stderr index c18cca62d..ade1a3dd4 100644 --- a/crates/stackable-versioned-macros/tests/default/deprecate.stderr +++ b/crates/stackable-versioned-macros/tests/default/deprecate.stderr @@ -1,5 +1,5 @@ error: deprecation must be done using #[versioned(deprecated(since = "VERSION"))] - --> tests/default/fail/deprecate.rs:10:9 + --> tests/default/deprecate.rs:10:9 | 10 | #[deprecated] | ^ diff --git a/crates/stackable-versioned-macros/tests/default/skip_from_all.stderr b/crates/stackable-versioned-macros/tests/default/skip_from_all.stderr index 622e3266b..5eac53bf3 100644 --- a/crates/stackable-versioned-macros/tests/default/skip_from_all.stderr +++ b/crates/stackable-versioned-macros/tests/default/skip_from_all.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> tests/default/fail/skip_from_all.rs:23:42 + --> tests/default/skip_from_all.rs:23:42 | 23 | let foo_v1beta1 = v1beta1::Foo::from(foo_v1alpha1); | ------------------ ^^^^^^^^^^^^ expected `v1beta1::Foo`, found `v1alpha1::Foo` @@ -8,7 +8,7 @@ error[E0308]: mismatched types | = note: `v1alpha1::Foo` and `v1beta1::Foo` have similar names, but are actually distinct types note: `v1alpha1::Foo` is defined in module `crate::main::v1alpha1` of the current crate - --> tests/default/fail/skip_from_all.rs:4:5 + --> tests/default/skip_from_all.rs:4:5 | 4 | / #[versioned( 5 | | version(name = "v1alpha1"), @@ -18,7 +18,7 @@ note: `v1alpha1::Foo` is defined in module `crate::main::v1alpha1` of the curren 9 | | )] | |______^ note: `v1beta1::Foo` is defined in module `crate::main::v1beta1` of the current crate - --> tests/default/fail/skip_from_all.rs:4:5 + --> tests/default/skip_from_all.rs:4:5 | 4 | / #[versioned( 5 | | version(name = "v1alpha1"), diff --git a/crates/stackable-versioned-macros/tests/default/skip_from_version.stderr b/crates/stackable-versioned-macros/tests/default/skip_from_version.stderr index 0fe75fea1..17a00798e 100644 --- a/crates/stackable-versioned-macros/tests/default/skip_from_version.stderr +++ b/crates/stackable-versioned-macros/tests/default/skip_from_version.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> tests/default/fail/skip_from_version.rs:23:32 + --> tests/default/skip_from_version.rs:23:32 | 23 | let foo_v1 = v1::Foo::from(foo_v1beta1); | ------------- ^^^^^^^^^^^ expected `main::v1::Foo`, found `v1beta1::Foo` @@ -8,7 +8,7 @@ error[E0308]: mismatched types | = note: `v1beta1::Foo` and `main::v1::Foo` have similar names, but are actually distinct types note: `v1beta1::Foo` is defined in module `crate::main::v1beta1` of the current crate - --> tests/default/fail/skip_from_version.rs:4:5 + --> tests/default/skip_from_version.rs:4:5 | 4 | / #[versioned( 5 | | version(name = "v1alpha1"), @@ -17,7 +17,7 @@ note: `v1beta1::Foo` is defined in module `crate::main::v1beta1` of the current 8 | | )] | |______^ note: `main::v1::Foo` is defined in module `crate::main::v1` of the current crate - --> tests/default/fail/skip_from_version.rs:4:5 + --> tests/default/skip_from_version.rs:4:5 | 4 | / #[versioned( 5 | | version(name = "v1alpha1"), diff --git a/crates/stackable-versioned-macros/tests/k8s/crd.stderr b/crates/stackable-versioned-macros/tests/k8s/crd.stderr index 33d671a9a..6ab0bd550 100644 --- a/crates/stackable-versioned-macros/tests/k8s/crd.stderr +++ b/crates/stackable-versioned-macros/tests/k8s/crd.stderr @@ -1,11 +1,11 @@ error: struct name needs to include the `Spec` suffix if Kubernetes features are enabled via `#[versioned(k8s())]` - --> tests/k8s/fail/crd.rs:15:16 + --> tests/k8s/crd.rs:15:16 | 15 | pub struct Foo { | ^^^ error[E0433]: failed to resolve: use of undeclared type `Foo` - --> tests/k8s/fail/crd.rs:24:22 + --> tests/k8s/crd.rs:24:22 | 24 | let merged_crd = Foo::merged_crd("v1").unwrap(); | ^^^ use of undeclared type `Foo` From 45460446b7be0d6ef0a4106b0624cc65028ce36c Mon Sep 17 00:00:00 2001 From: Techassi Date: Mon, 30 Sep 2024 16:02:52 +0200 Subject: [PATCH 11/13] chore: Mark .stderr files as generated --- .gitattributes | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitattributes b/.gitattributes index 8b75a8c37..b22b8ee4a 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1 +1,2 @@ +*.stderr linguist-generated *.snap linguist-generated From 7dbd4d0c96d0f9666a397957ee02ec3f81419c25 Mon Sep 17 00:00:00 2001 From: Techassi Date: Mon, 30 Sep 2024 16:44:31 +0200 Subject: [PATCH 12/13] chore: Add changelog entry --- crates/stackable-versioned/CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/crates/stackable-versioned/CHANGELOG.md b/crates/stackable-versioned/CHANGELOG.md index dbe7d9d11..2158638b3 100644 --- a/crates/stackable-versioned/CHANGELOG.md +++ b/crates/stackable-versioned/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. ## [Unreleased] +### Added + +- Add snapshot tests to verify generated code matches expected output ([#881]). + +[#881]: https://github.com/stackabletech/operator-rs/pull/881 + ## [0.3.0] - 2024-09-26 ### Added From 7bebb3a220c5304af866eaac302299f386195a1b Mon Sep 17 00:00:00 2001 From: Techassi Date: Wed, 2 Oct 2024 10:21:56 +0200 Subject: [PATCH 13/13] chore: Partial revert of ff2fd24 --- .../tests/default/{ => fail}/changed.rs | 0 .../tests/default/{ => fail}/changed.stderr | 4 ++-- .../tests/default/{ => fail}/deprecate.rs | 0 .../tests/default/{ => fail}/deprecate.stderr | 2 +- .../tests/default/{ => fail}/skip_from_all.rs | 0 .../default/{ => fail}/skip_from_all.stderr | 6 +++--- .../default/{ => fail}/skip_from_version.rs | 0 .../default/{ => fail}/skip_from_version.stderr | 6 +++--- .../tests/k8s/{ => fail}/crd.rs | 0 .../tests/k8s/{ => fail}/crd.stderr | 4 ++-- .../stackable-versioned-macros/tests/trybuild.rs | 16 ++++++++++------ 11 files changed, 21 insertions(+), 17 deletions(-) rename crates/stackable-versioned-macros/tests/default/{ => fail}/changed.rs (100%) rename crates/stackable-versioned-macros/tests/default/{ => fail}/changed.stderr (84%) rename crates/stackable-versioned-macros/tests/default/{ => fail}/deprecate.rs (100%) rename crates/stackable-versioned-macros/tests/default/{ => fail}/deprecate.stderr (75%) rename crates/stackable-versioned-macros/tests/default/{ => fail}/skip_from_all.rs (100%) rename crates/stackable-versioned-macros/tests/default/{ => fail}/skip_from_all.stderr (90%) rename crates/stackable-versioned-macros/tests/default/{ => fail}/skip_from_version.rs (100%) rename crates/stackable-versioned-macros/tests/default/{ => fail}/skip_from_version.stderr (88%) rename crates/stackable-versioned-macros/tests/k8s/{ => fail}/crd.rs (100%) rename crates/stackable-versioned-macros/tests/k8s/{ => fail}/crd.stderr (83%) diff --git a/crates/stackable-versioned-macros/tests/default/changed.rs b/crates/stackable-versioned-macros/tests/default/fail/changed.rs similarity index 100% rename from crates/stackable-versioned-macros/tests/default/changed.rs rename to crates/stackable-versioned-macros/tests/default/fail/changed.rs diff --git a/crates/stackable-versioned-macros/tests/default/changed.stderr b/crates/stackable-versioned-macros/tests/default/fail/changed.stderr similarity index 84% rename from crates/stackable-versioned-macros/tests/default/changed.stderr rename to crates/stackable-versioned-macros/tests/default/fail/changed.stderr index 46ae472a5..a6d0d4070 100644 --- a/crates/stackable-versioned-macros/tests/default/changed.stderr +++ b/crates/stackable-versioned-macros/tests/default/fail/changed.stderr @@ -1,11 +1,11 @@ error: the previous field name must not start with the deprecation prefix - --> tests/default/changed.rs:11:52 + --> tests/default/fail/changed.rs:11:52 | 11 | changed(since = "v1beta1", from_name = "deprecated_bar"), | ^^^^^^^^^^^^^^^^ error: the previous field name must not start with the deprecation prefix - --> tests/default/changed.rs:12:47 + --> tests/default/fail/changed.rs:12:47 | 12 | changed(since = "v1", from_name = "deprecated_baz") | ^^^^^^^^^^^^^^^^ diff --git a/crates/stackable-versioned-macros/tests/default/deprecate.rs b/crates/stackable-versioned-macros/tests/default/fail/deprecate.rs similarity index 100% rename from crates/stackable-versioned-macros/tests/default/deprecate.rs rename to crates/stackable-versioned-macros/tests/default/fail/deprecate.rs diff --git a/crates/stackable-versioned-macros/tests/default/deprecate.stderr b/crates/stackable-versioned-macros/tests/default/fail/deprecate.stderr similarity index 75% rename from crates/stackable-versioned-macros/tests/default/deprecate.stderr rename to crates/stackable-versioned-macros/tests/default/fail/deprecate.stderr index ade1a3dd4..c18cca62d 100644 --- a/crates/stackable-versioned-macros/tests/default/deprecate.stderr +++ b/crates/stackable-versioned-macros/tests/default/fail/deprecate.stderr @@ -1,5 +1,5 @@ error: deprecation must be done using #[versioned(deprecated(since = "VERSION"))] - --> tests/default/deprecate.rs:10:9 + --> tests/default/fail/deprecate.rs:10:9 | 10 | #[deprecated] | ^ diff --git a/crates/stackable-versioned-macros/tests/default/skip_from_all.rs b/crates/stackable-versioned-macros/tests/default/fail/skip_from_all.rs similarity index 100% rename from crates/stackable-versioned-macros/tests/default/skip_from_all.rs rename to crates/stackable-versioned-macros/tests/default/fail/skip_from_all.rs diff --git a/crates/stackable-versioned-macros/tests/default/skip_from_all.stderr b/crates/stackable-versioned-macros/tests/default/fail/skip_from_all.stderr similarity index 90% rename from crates/stackable-versioned-macros/tests/default/skip_from_all.stderr rename to crates/stackable-versioned-macros/tests/default/fail/skip_from_all.stderr index 5eac53bf3..622e3266b 100644 --- a/crates/stackable-versioned-macros/tests/default/skip_from_all.stderr +++ b/crates/stackable-versioned-macros/tests/default/fail/skip_from_all.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> tests/default/skip_from_all.rs:23:42 + --> tests/default/fail/skip_from_all.rs:23:42 | 23 | let foo_v1beta1 = v1beta1::Foo::from(foo_v1alpha1); | ------------------ ^^^^^^^^^^^^ expected `v1beta1::Foo`, found `v1alpha1::Foo` @@ -8,7 +8,7 @@ error[E0308]: mismatched types | = note: `v1alpha1::Foo` and `v1beta1::Foo` have similar names, but are actually distinct types note: `v1alpha1::Foo` is defined in module `crate::main::v1alpha1` of the current crate - --> tests/default/skip_from_all.rs:4:5 + --> tests/default/fail/skip_from_all.rs:4:5 | 4 | / #[versioned( 5 | | version(name = "v1alpha1"), @@ -18,7 +18,7 @@ note: `v1alpha1::Foo` is defined in module `crate::main::v1alpha1` of the curren 9 | | )] | |______^ note: `v1beta1::Foo` is defined in module `crate::main::v1beta1` of the current crate - --> tests/default/skip_from_all.rs:4:5 + --> tests/default/fail/skip_from_all.rs:4:5 | 4 | / #[versioned( 5 | | version(name = "v1alpha1"), diff --git a/crates/stackable-versioned-macros/tests/default/skip_from_version.rs b/crates/stackable-versioned-macros/tests/default/fail/skip_from_version.rs similarity index 100% rename from crates/stackable-versioned-macros/tests/default/skip_from_version.rs rename to crates/stackable-versioned-macros/tests/default/fail/skip_from_version.rs diff --git a/crates/stackable-versioned-macros/tests/default/skip_from_version.stderr b/crates/stackable-versioned-macros/tests/default/fail/skip_from_version.stderr similarity index 88% rename from crates/stackable-versioned-macros/tests/default/skip_from_version.stderr rename to crates/stackable-versioned-macros/tests/default/fail/skip_from_version.stderr index 17a00798e..0fe75fea1 100644 --- a/crates/stackable-versioned-macros/tests/default/skip_from_version.stderr +++ b/crates/stackable-versioned-macros/tests/default/fail/skip_from_version.stderr @@ -1,5 +1,5 @@ error[E0308]: mismatched types - --> tests/default/skip_from_version.rs:23:32 + --> tests/default/fail/skip_from_version.rs:23:32 | 23 | let foo_v1 = v1::Foo::from(foo_v1beta1); | ------------- ^^^^^^^^^^^ expected `main::v1::Foo`, found `v1beta1::Foo` @@ -8,7 +8,7 @@ error[E0308]: mismatched types | = note: `v1beta1::Foo` and `main::v1::Foo` have similar names, but are actually distinct types note: `v1beta1::Foo` is defined in module `crate::main::v1beta1` of the current crate - --> tests/default/skip_from_version.rs:4:5 + --> tests/default/fail/skip_from_version.rs:4:5 | 4 | / #[versioned( 5 | | version(name = "v1alpha1"), @@ -17,7 +17,7 @@ note: `v1beta1::Foo` is defined in module `crate::main::v1beta1` of the current 8 | | )] | |______^ note: `main::v1::Foo` is defined in module `crate::main::v1` of the current crate - --> tests/default/skip_from_version.rs:4:5 + --> tests/default/fail/skip_from_version.rs:4:5 | 4 | / #[versioned( 5 | | version(name = "v1alpha1"), diff --git a/crates/stackable-versioned-macros/tests/k8s/crd.rs b/crates/stackable-versioned-macros/tests/k8s/fail/crd.rs similarity index 100% rename from crates/stackable-versioned-macros/tests/k8s/crd.rs rename to crates/stackable-versioned-macros/tests/k8s/fail/crd.rs diff --git a/crates/stackable-versioned-macros/tests/k8s/crd.stderr b/crates/stackable-versioned-macros/tests/k8s/fail/crd.stderr similarity index 83% rename from crates/stackable-versioned-macros/tests/k8s/crd.stderr rename to crates/stackable-versioned-macros/tests/k8s/fail/crd.stderr index 6ab0bd550..33d671a9a 100644 --- a/crates/stackable-versioned-macros/tests/k8s/crd.stderr +++ b/crates/stackable-versioned-macros/tests/k8s/fail/crd.stderr @@ -1,11 +1,11 @@ error: struct name needs to include the `Spec` suffix if Kubernetes features are enabled via `#[versioned(k8s())]` - --> tests/k8s/crd.rs:15:16 + --> tests/k8s/fail/crd.rs:15:16 | 15 | pub struct Foo { | ^^^ error[E0433]: failed to resolve: use of undeclared type `Foo` - --> tests/k8s/crd.rs:24:22 + --> tests/k8s/fail/crd.rs:24:22 | 24 | let merged_crd = Foo::merged_crd("v1").unwrap(); | ^^^ use of undeclared type `Foo` diff --git a/crates/stackable-versioned-macros/tests/trybuild.rs b/crates/stackable-versioned-macros/tests/trybuild.rs index 7d1e7229a..3070189c9 100644 --- a/crates/stackable-versioned-macros/tests/trybuild.rs +++ b/crates/stackable-versioned-macros/tests/trybuild.rs @@ -16,26 +16,30 @@ // again but before running tests, otherwise compilation will fail (as expected). #[allow(dead_code)] mod default { - // mod deprecate; - // mod skip_from_all; - // mod skip_from_version; + // mod fail { + // mod deprecate; + // mod skip_from_all; + // mod skip_from_version; + // } } #[test] fn default_macros() { let t = trybuild::TestCases::new(); - t.compile_fail("tests/default/*.rs"); + t.compile_fail("tests/default/fail/*.rs"); } #[cfg(feature = "k8s")] #[allow(dead_code)] mod k8s { - // mod crd; + // mod fail { + // mod crd; + // } } #[cfg(feature = "k8s")] #[test] fn k8s_macros() { let t = trybuild::TestCases::new(); - t.compile_fail("tests/k8s/*.rs"); + t.compile_fail("tests/k8s/fail/*.rs"); }