From e2e0d82ca27e7e9866cc85ebe68407933a76880d Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Thu, 18 Jun 2026 21:39:24 +0200 Subject: [PATCH 01/31] Draft implement new assert_delegate_components macro --- Cargo.lock | 151 +++++++++++++++++- Cargo.toml | 2 + crates/macros/cgp-macro-core/Cargo.toml | 6 - crates/macros/cgp-macro-lib/Cargo.toml | 15 +- crates/macros/cgp-macro-test-util/Cargo.toml | 21 +++ crates/macros/cgp-macro-test-util/src/lib.rs | 35 ++++ .../macros/cgp-macro-test-util/src/parse.rs | 30 ++++ crates/macros/cgp-macro/Cargo.toml | 3 - crates/macros/cgp-macro/src/lib.rs | 2 - crates/tests/cgp-tests/Cargo.toml | 11 +- .../delegate_components/direct.rs | 5 +- 11 files changed, 254 insertions(+), 27 deletions(-) create mode 100644 crates/macros/cgp-macro-test-util/Cargo.toml create mode 100644 crates/macros/cgp-macro-test-util/src/lib.rs create mode 100644 crates/macros/cgp-macro-test-util/src/parse.rs diff --git a/Cargo.lock b/Cargo.lock index 25bb443f..00340e27 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8,6 +8,18 @@ version = "1.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" +[[package]] +name = "bitflags" +version = "2.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4388bee8683e3d04af747c73422af53102d2bd24d9eadb6cbc100baef4b43f8" + +[[package]] +name = "cfg-if" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" + [[package]] name = "cgp" version = "0.7.0" @@ -184,7 +196,18 @@ version = "0.7.0" dependencies = [ "cgp-macro-core", "itertools", - "prettyplease", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "cgp-macro-test-util" +version = "0.7.0" +dependencies = [ + "cgp-macro-core", + "cgp-macro-lib", + "itertools", "proc-macro2", "quote", "syn", @@ -217,8 +240,13 @@ name = "cgp-tests" version = "0.7.0" dependencies = [ "cgp", + "cgp-macro-test-util", "const_format", "futures", + "insta", + "prettyplease", + "quote", + "syn", ] [[package]] @@ -230,6 +258,17 @@ dependencies = [ "cgp-macro", ] +[[package]] +name = "console" +version = "0.16.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d64e8af5551369d19cf50138de61f1c42074ab970f74e99be916646777f8fc87" +dependencies = [ + "encode_unicode", + "libc", + "windows-sys", +] + [[package]] name = "const_format" version = "0.2.35" @@ -256,6 +295,22 @@ version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" +[[package]] +name = "encode_unicode" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" + +[[package]] +name = "errno" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" +dependencies = [ + "libc", + "windows-sys", +] + [[package]] name = "eyre" version = "0.6.12" @@ -266,6 +321,12 @@ dependencies = [ "once_cell", ] +[[package]] +name = "fastrand" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6" + [[package]] name = "futures" version = "0.3.31" @@ -355,12 +416,35 @@ dependencies = [ "slab", ] +[[package]] +name = "getrandom" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "300e883d756b2e4ec94e02791f39b04b522276138852cfc41d9fb7e904106099" +dependencies = [ + "cfg-if", + "libc", + "r-efi", +] + [[package]] name = "indenter" version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "964de6e86d545b246d84badc0fef527924ace5134f30641c203ef52ba83f58d5" +[[package]] +name = "insta" +version = "1.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86f0f8fee8c926415c58d6ae43a08523a26faccb2323f5e6b644fe7dd4ef6b82" +dependencies = [ + "console", + "once_cell", + "similar", + "tempfile", +] + [[package]] name = "itertools" version = "0.14.0" @@ -370,6 +454,18 @@ dependencies = [ "either", ] +[[package]] +name = "libc" +version = "0.2.186" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" + +[[package]] +name = "linux-raw-sys" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" + [[package]] name = "memchr" version = "2.7.6" @@ -422,6 +518,31 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "r-efi" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" + +[[package]] +name = "rustix" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys", + "windows-sys", +] + +[[package]] +name = "similar" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbbb5d9659141646ae647b42fe094daf6c6192d1620870b449d9557f748b2daa" + [[package]] name = "slab" version = "0.4.12" @@ -439,6 +560,19 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "tempfile" +version = "3.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" +dependencies = [ + "fastrand", + "getrandom", + "once_cell", + "rustix", + "windows-sys", +] + [[package]] name = "unicode-ident" version = "1.0.22" @@ -450,3 +584,18 @@ name = "unicode-xid" version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] diff --git a/Cargo.toml b/Cargo.toml index 15aa0fe3..0da826fe 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,6 +26,7 @@ members = [ "crates/macros/cgp-macro", "crates/macros/cgp-macro-core", "crates/macros/cgp-macro-lib", + "crates/macros/cgp-macro-test-util", "crates/macros/cgp-extra-macro", "crates/macros/cgp-extra-macro-lib", @@ -68,5 +69,6 @@ cgp-async-macro = { version = "0.7.0", path = "./crates/macros/cgp-a cgp-macro = { version = "0.7.0", path = "./crates/macros/cgp-macro" } cgp-macro-core = { version = "0.7.0", path = "./crates/macros/cgp-macro-core" } cgp-macro-lib = { version = "0.7.0", path = "./crates/macros/cgp-macro-lib" } +cgp-macro-test-util = { version = "0.7.0", path = "./crates/macros/cgp-macro-test-util" } cgp-extra-macro = { version = "0.7.0", path = "./crates/macros/cgp-extra-macro" } cgp-extra-macro-lib = { version = "0.7.0", path = "./crates/macros/cgp-extra-macro-lib" } diff --git a/crates/macros/cgp-macro-core/Cargo.toml b/crates/macros/cgp-macro-core/Cargo.toml index 2d69a19d..5e1203ba 100644 --- a/crates/macros/cgp-macro-core/Cargo.toml +++ b/crates/macros/cgp-macro-core/Cargo.toml @@ -7,12 +7,6 @@ repository = { workspace = true } authors = { workspace = true } rust-version = { workspace = true } keywords = { workspace = true } -description = """ - Context-generic programming core component macros implemented as a library. -""" - -[features] -default = [] [dependencies] syn = { version = "2.0.95", features = [ "full", "extra-traits", "visit", "visit-mut" ] } diff --git a/crates/macros/cgp-macro-lib/Cargo.toml b/crates/macros/cgp-macro-lib/Cargo.toml index 44e48059..873be4ff 100644 --- a/crates/macros/cgp-macro-lib/Cargo.toml +++ b/crates/macros/cgp-macro-lib/Cargo.toml @@ -7,18 +7,11 @@ repository = { workspace = true } authors = { workspace = true } rust-version = { workspace = true } keywords = { workspace = true } -description = """ - Context-generic programming core component macros implemented as a library. -""" - -[features] -default = [] [dependencies] -cgp-macro-core = { workspace = true } +cgp-macro-core = { workspace = true } syn = { version = "2.0.95", features = [ "full", "extra-traits", "visit", "visit-mut" ] } -quote = "1.0.38" -proc-macro2 = "1.0.92" -prettyplease = "0.2.27" -itertools = "0.14.0" +quote = { version = "1.0.38" } +proc-macro2 = { version = "1.0.92" } +itertools = { version = "0.14.0" } diff --git a/crates/macros/cgp-macro-test-util/Cargo.toml b/crates/macros/cgp-macro-test-util/Cargo.toml new file mode 100644 index 00000000..69923940 --- /dev/null +++ b/crates/macros/cgp-macro-test-util/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "cgp-macro-test-util" +version = "0.7.0" +edition = { workspace = true } +license = { workspace = true } +repository = { workspace = true } +authors = { workspace = true } +rust-version = { workspace = true } +keywords = { workspace = true } + +[lib] +proc-macro = true + +[dependencies] +cgp-macro-lib = { workspace = true } +cgp-macro-core = { workspace = true } + +syn = { version = "2.0.95", features = [ "full", "extra-traits", "visit", "visit-mut" ] } +quote = { version = "1.0.38" } +proc-macro2 = { version = "1.0.92" } +itertools = { version = "0.14.0" } diff --git a/crates/macros/cgp-macro-test-util/src/lib.rs b/crates/macros/cgp-macro-test-util/src/lib.rs new file mode 100644 index 00000000..4207f117 --- /dev/null +++ b/crates/macros/cgp-macro-test-util/src/lib.rs @@ -0,0 +1,35 @@ +mod parse; + +use proc_macro::TokenStream; +use quote::quote; +use syn::parse2; + +use crate::parse::MacroSnapshot; + +#[proc_macro] +pub fn assert_delegate_components(body: TokenStream) -> TokenStream { + let MacroSnapshot { + test_name, + body, + snapshot, + } = parse2(body.into()).unwrap(); + + let output = + cgp_macro_lib::delegate_components(body).unwrap_or_else(syn::Error::into_compile_error); + + let wrapped = quote! { + #output + + #[test] + fn #test_name() { + insta::assert_snapshot!( + prettyplease::unparse(&syn::parse2(quote::quote! { + #output + }).unwrap()), + @#snapshot, + ); + } + }; + + wrapped.into() +} diff --git a/crates/macros/cgp-macro-test-util/src/parse.rs b/crates/macros/cgp-macro-test-util/src/parse.rs new file mode 100644 index 00000000..63da85ca --- /dev/null +++ b/crates/macros/cgp-macro-test-util/src/parse.rs @@ -0,0 +1,30 @@ +use proc_macro2::TokenStream; +use syn::parse::{Parse, ParseStream}; +use syn::token::{At, Colon, Semi}; +use syn::{Ident, LitStr}; + +pub struct MacroSnapshot { + pub test_name: Ident, + pub body: TokenStream, + pub snapshot: LitStr, +} + +impl Parse for MacroSnapshot { + fn parse(input: ParseStream) -> syn::Result { + let test_name = input.parse()?; + + let _: Colon = input.parse()?; + + let _: At = input.parse()?; + let snapshot = input.parse()?; + let _: Semi = input.parse()?; + + let body = input.parse()?; + + Ok(MacroSnapshot { + test_name, + body, + snapshot, + }) + } +} diff --git a/crates/macros/cgp-macro/Cargo.toml b/crates/macros/cgp-macro/Cargo.toml index 770dd1fd..e3ea2685 100644 --- a/crates/macros/cgp-macro/Cargo.toml +++ b/crates/macros/cgp-macro/Cargo.toml @@ -7,9 +7,6 @@ repository = { workspace = true } authors = { workspace = true } rust-version = { workspace = true } keywords = { workspace = true } -description = """ - Context-generic programming core component macros -""" [lib] proc-macro = true diff --git a/crates/macros/cgp-macro/src/lib.rs b/crates/macros/cgp-macro/src/lib.rs index acc29b0f..72ad7cfd 100644 --- a/crates/macros/cgp-macro/src/lib.rs +++ b/crates/macros/cgp-macro/src/lib.rs @@ -4,8 +4,6 @@ This crate provides the proc macros used for defining CGP components. */ -extern crate proc_macro; - use proc_macro::TokenStream; /** diff --git a/crates/tests/cgp-tests/Cargo.toml b/crates/tests/cgp-tests/Cargo.toml index 11d13ae4..f91bddda 100644 --- a/crates/tests/cgp-tests/Cargo.toml +++ b/crates/tests/cgp-tests/Cargo.toml @@ -12,6 +12,11 @@ description = """ """ [dependencies] -cgp = { workspace = true } -futures = { version = "0.3.31" } -const_format = { version = "0.2.34" } +cgp = { workspace = true } +cgp-macro-test-util = { workspace = true } +quote = { version = "1.0.38" } +futures = { version = "0.3.31" } +const_format = { version = "0.2.34" } +insta = { version = "1.48.0" } +prettyplease = { version = "0.2.37" } +syn = { version = "2.0.95", features = [ "full" ] } diff --git a/crates/tests/cgp-tests/tests/component_tests/delegate_components/direct.rs b/crates/tests/cgp-tests/tests/component_tests/delegate_components/direct.rs index c5017a8b..4d5e835c 100644 --- a/crates/tests/cgp-tests/tests/component_tests/delegate_components/direct.rs +++ b/crates/tests/cgp-tests/tests/component_tests/delegate_components/direct.rs @@ -1,6 +1,9 @@ use cgp::prelude::*; +use cgp_macro_test_util::assert_delegate_components; + +assert_delegate_components! { + expand_foo_component: @""; -delegate_components! { new FooComponents { Index<0>: u64, Index<1>: String, From 01f1b04277a3c794ac3a0d728cf01789d5cf5522 Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Thu, 18 Jun 2026 21:44:17 +0200 Subject: [PATCH 02/31] Add pretty_format helper --- Cargo.lock | 1 + crates/macros/cgp-macro-core/Cargo.toml | 9 +-- .../cgp-macro-core/src/functions/format.rs | 9 +++ .../cgp-macro-core/src/functions/mod.rs | 4 ++ .../src/functions/parse_internal.rs | 57 +------------------ .../cgp-macro-core/src/functions/strip.rs | 55 ++++++++++++++++++ 6 files changed, 76 insertions(+), 59 deletions(-) create mode 100644 crates/macros/cgp-macro-core/src/functions/format.rs create mode 100644 crates/macros/cgp-macro-core/src/functions/strip.rs diff --git a/Cargo.lock b/Cargo.lock index 00340e27..1bc67561 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -185,6 +185,7 @@ name = "cgp-macro-core" version = "0.7.0" dependencies = [ "itertools", + "prettyplease", "proc-macro2", "quote", "syn", diff --git a/crates/macros/cgp-macro-core/Cargo.toml b/crates/macros/cgp-macro-core/Cargo.toml index 5e1203ba..51bf105f 100644 --- a/crates/macros/cgp-macro-core/Cargo.toml +++ b/crates/macros/cgp-macro-core/Cargo.toml @@ -9,7 +9,8 @@ rust-version = { workspace = true } keywords = { workspace = true } [dependencies] -syn = { version = "2.0.95", features = [ "full", "extra-traits", "visit", "visit-mut" ] } -quote = "1.0.38" -proc-macro2 = "1.0.92" -itertools = "0.14.0" +syn = { version = "2.0.95", features = [ "full", "extra-traits", "visit", "visit-mut" ] } +quote = { version = "1.0.38" } +proc-macro2 = { version = "1.0.92" } +itertools = { version = "0.14.0" } +prettyplease = { version = "0.2.37" } diff --git a/crates/macros/cgp-macro-core/src/functions/format.rs b/crates/macros/cgp-macro-core/src/functions/format.rs new file mode 100644 index 00000000..6230bfc1 --- /dev/null +++ b/crates/macros/cgp-macro-core/src/functions/format.rs @@ -0,0 +1,9 @@ +use prettyplease::unparse; +use proc_macro2::TokenStream; +use syn::parse2; + +use crate::functions::strip_macro_prelude; + +pub fn pretty_format(body: TokenStream) -> String { + unparse(&parse2(strip_macro_prelude(body)).unwrap()) +} diff --git a/crates/macros/cgp-macro-core/src/functions/mod.rs b/crates/macros/cgp-macro-core/src/functions/mod.rs index 4f687f53..fcb91b11 100644 --- a/crates/macros/cgp-macro-core/src/functions/mod.rs +++ b/crates/macros/cgp-macro-core/src/functions/mod.rs @@ -1,19 +1,23 @@ mod camel_case; mod delegated_impls; mod field; +mod format; mod generics; mod getter; mod implicits; mod is_provider_params; mod parse_internal; mod snake_case; +mod strip; pub use camel_case::*; pub use delegated_impls::*; pub use field::*; +pub use format::*; pub use generics::*; pub use getter::*; pub use implicits::*; pub use is_provider_params::*; pub use parse_internal::*; pub use snake_case::*; +pub use strip::*; diff --git a/crates/macros/cgp-macro-core/src/functions/parse_internal.rs b/crates/macros/cgp-macro-core/src/functions/parse_internal.rs index 99f82e9c..1583e161 100644 --- a/crates/macros/cgp-macro-core/src/functions/parse_internal.rs +++ b/crates/macros/cgp-macro-core/src/functions/parse_internal.rs @@ -1,10 +1,11 @@ use core::any::type_name; -use proc_macro2::{Group, TokenStream, TokenTree}; +use proc_macro2::TokenStream; use syn::parse::Parse; use syn::spanned::Spanned; use syn::{Error, parse2}; +use crate::functions::strip_macro_prelude; pub use crate::macros::parse_internal; pub fn parse_internal(body: TokenStream) -> Result @@ -23,57 +24,3 @@ where e }) } - -/// Strips the `::cgp::macro_prelude::` prefix from the [`TokenStream`] so the -/// error message shows the more readable, unqualified paths. The replacement is -/// done at the token level, recursing into nested groups. -fn strip_macro_prelude(body: TokenStream) -> TokenStream { - // The prefix `::cgp::macro_prelude::` is made up of the following tokens. - fn is_prefix(tokens: &[TokenTree]) -> bool { - matches!( - tokens, - [ - TokenTree::Punct(p1), - TokenTree::Punct(p2), - TokenTree::Ident(cgp), - TokenTree::Punct(p3), - TokenTree::Punct(p4), - TokenTree::Ident(prelude), - TokenTree::Punct(p5), - TokenTree::Punct(p6), - ] if p1.as_char() == ':' - && p2.as_char() == ':' - && cgp == "cgp" - && p3.as_char() == ':' - && p4.as_char() == ':' - && prelude == "macro_prelude" - && p5.as_char() == ':' - && p6.as_char() == ':' - ) - } - - const PREFIX_LEN: usize = 8; - - let tokens: Vec = body.into_iter().collect(); - let mut output = Vec::with_capacity(tokens.len()); - let mut i = 0; - - while i < tokens.len() { - if is_prefix(&tokens[i..(i + PREFIX_LEN).min(tokens.len())]) { - i += PREFIX_LEN; - } else { - match &tokens[i] { - TokenTree::Group(group) => { - let inner = strip_macro_prelude(group.stream()); - let mut new_group = Group::new(group.delimiter(), inner); - new_group.set_span(group.span()); - output.push(TokenTree::Group(new_group)); - } - other => output.push(other.clone()), - } - i += 1; - } - } - - output.into_iter().collect() -} diff --git a/crates/macros/cgp-macro-core/src/functions/strip.rs b/crates/macros/cgp-macro-core/src/functions/strip.rs new file mode 100644 index 00000000..dfdea642 --- /dev/null +++ b/crates/macros/cgp-macro-core/src/functions/strip.rs @@ -0,0 +1,55 @@ +use proc_macro2::{Group, TokenStream, TokenTree}; + +/// Strips the `::cgp::macro_prelude::` prefix from the [`TokenStream`] so the +/// error message shows the more readable, unqualified paths. The replacement is +/// done at the token level, recursing into nested groups. +pub fn strip_macro_prelude(body: TokenStream) -> TokenStream { + // The prefix `::cgp::macro_prelude::` is made up of the following tokens. + fn is_prefix(tokens: &[TokenTree]) -> bool { + matches!( + tokens, + [ + TokenTree::Punct(p1), + TokenTree::Punct(p2), + TokenTree::Ident(cgp), + TokenTree::Punct(p3), + TokenTree::Punct(p4), + TokenTree::Ident(prelude), + TokenTree::Punct(p5), + TokenTree::Punct(p6), + ] if p1.as_char() == ':' + && p2.as_char() == ':' + && cgp == "cgp" + && p3.as_char() == ':' + && p4.as_char() == ':' + && prelude == "macro_prelude" + && p5.as_char() == ':' + && p6.as_char() == ':' + ) + } + + const PREFIX_LEN: usize = 8; + + let tokens: Vec = body.into_iter().collect(); + let mut output = Vec::with_capacity(tokens.len()); + let mut i = 0; + + while i < tokens.len() { + if is_prefix(&tokens[i..(i + PREFIX_LEN).min(tokens.len())]) { + i += PREFIX_LEN; + } else { + match &tokens[i] { + TokenTree::Group(group) => { + let inner = strip_macro_prelude(group.stream()); + let mut new_group = Group::new(group.delimiter(), inner); + new_group.set_span(group.span()); + output.push(TokenTree::Group(new_group)); + } + other => output.push(other.clone()), + } + i += 1; + } + } + + output.into_iter().collect() +} From 29e4893b0b9ba4e818222e406a9bff1da0a0d9e4 Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Thu, 18 Jun 2026 21:50:24 +0200 Subject: [PATCH 03/31] Use pretty_format in assert_delegate_components --- Cargo.lock | 30 +------------------ .../cgp-macro-core/src/functions/format.rs | 6 ++-- crates/macros/cgp-macro-test-util/src/lib.rs | 7 ++--- crates/tests/cgp-tests/Cargo.toml | 9 ++---- .../.direct.rs.pending-snap | 1 + 5 files changed, 11 insertions(+), 42 deletions(-) create mode 100644 crates/tests/cgp-tests/tests/component_tests/delegate_components/.direct.rs.pending-snap diff --git a/Cargo.lock b/Cargo.lock index 1bc67561..9931708c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -241,13 +241,11 @@ name = "cgp-tests" version = "0.7.0" dependencies = [ "cgp", + "cgp-macro-core", "cgp-macro-test-util", - "const_format", "futures", "insta", - "prettyplease", "quote", - "syn", ] [[package]] @@ -270,26 +268,6 @@ dependencies = [ "windows-sys", ] -[[package]] -name = "const_format" -version = "0.2.35" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7faa7469a93a566e9ccc1c73fe783b4a65c274c5ace346038dca9c39fe0030ad" -dependencies = [ - "const_format_proc_macros", -] - -[[package]] -name = "const_format_proc_macros" -version = "0.2.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d57c2eccfb16dbac1f4e61e206105db5820c9d26c3c472bc17c774259ef7744" -dependencies = [ - "proc-macro2", - "quote", - "unicode-xid", -] - [[package]] name = "either" version = "1.15.0" @@ -580,12 +558,6 @@ version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5" -[[package]] -name = "unicode-xid" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" - [[package]] name = "windows-link" version = "0.2.1" diff --git a/crates/macros/cgp-macro-core/src/functions/format.rs b/crates/macros/cgp-macro-core/src/functions/format.rs index 6230bfc1..a7efd6a8 100644 --- a/crates/macros/cgp-macro-core/src/functions/format.rs +++ b/crates/macros/cgp-macro-core/src/functions/format.rs @@ -4,6 +4,8 @@ use syn::parse2; use crate::functions::strip_macro_prelude; -pub fn pretty_format(body: TokenStream) -> String { - unparse(&parse2(strip_macro_prelude(body)).unwrap()) +pub fn pretty_format(body: TokenStream) -> syn::Result { + let parsed = parse2(strip_macro_prelude(body))?; + let formatted = unparse(&parsed); + Ok(formatted) } diff --git a/crates/macros/cgp-macro-test-util/src/lib.rs b/crates/macros/cgp-macro-test-util/src/lib.rs index 4207f117..3f54d974 100644 --- a/crates/macros/cgp-macro-test-util/src/lib.rs +++ b/crates/macros/cgp-macro-test-util/src/lib.rs @@ -14,8 +14,7 @@ pub fn assert_delegate_components(body: TokenStream) -> TokenStream { snapshot, } = parse2(body.into()).unwrap(); - let output = - cgp_macro_lib::delegate_components(body).unwrap_or_else(syn::Error::into_compile_error); + let output = cgp_macro_lib::delegate_components(body).unwrap(); let wrapped = quote! { #output @@ -23,9 +22,9 @@ pub fn assert_delegate_components(body: TokenStream) -> TokenStream { #[test] fn #test_name() { insta::assert_snapshot!( - prettyplease::unparse(&syn::parse2(quote::quote! { + cgp_macro_core::functions::pretty_format(quote::quote! { #output - }).unwrap()), + }).unwrap(), @#snapshot, ); } diff --git a/crates/tests/cgp-tests/Cargo.toml b/crates/tests/cgp-tests/Cargo.toml index f91bddda..2b9fa727 100644 --- a/crates/tests/cgp-tests/Cargo.toml +++ b/crates/tests/cgp-tests/Cargo.toml @@ -7,16 +7,11 @@ repository = { workspace = true } authors = { workspace = true } rust-version = { workspace = true } keywords = { workspace = true } -description = """ - Context-generic programming meta crate -""" [dependencies] cgp = { workspace = true } +cgp-macro-core = { workspace = true } cgp-macro-test-util = { workspace = true } +insta = { version = "1.48.0" } quote = { version = "1.0.38" } futures = { version = "0.3.31" } -const_format = { version = "0.2.34" } -insta = { version = "1.48.0" } -prettyplease = { version = "0.2.37" } -syn = { version = "2.0.95", features = [ "full" ] } diff --git a/crates/tests/cgp-tests/tests/component_tests/delegate_components/.direct.rs.pending-snap b/crates/tests/cgp-tests/tests/component_tests/delegate_components/.direct.rs.pending-snap new file mode 100644 index 00000000..151748f8 --- /dev/null +++ b/crates/tests/cgp-tests/tests/component_tests/delegate_components/.direct.rs.pending-snap @@ -0,0 +1 @@ +{"run_id":"1781812187-853164386","line":4,"new":{"module_name":"component__component_tests__delegate_components__direct","snapshot_name":"expand_foo_component","metadata":{"source":"crates/tests/cgp-tests/tests/component_tests/delegate_components/direct.rs","assertion_line":4,"expression":"cgp_macro_core :: functions ::\npretty_format(quote :: quote!\n{\n pub struct FooComponents; impl :: cgp :: macro_prelude ::\n DelegateComponent < Index < 0 > > for FooComponents\n { type Delegate = u64; } impl < __Context__, __Params__ > :: cgp ::\n macro_prelude :: IsProviderFor < Index < 0 > , __Context__, __Params__ >\n for FooComponents where u64 : :: cgp :: macro_prelude :: IsProviderFor <\n Index < 0 > , __Context__, __Params__ > {} impl :: cgp :: macro_prelude ::\n DelegateComponent < Index < 1 > > for FooComponents\n { type Delegate = String; } impl < __Context__, __Params__ > :: cgp ::\n macro_prelude :: IsProviderFor < Index < 1 > , __Context__, __Params__ >\n for FooComponents where String : :: cgp :: macro_prelude :: IsProviderFor\n < Index < 1 > , __Context__, __Params__ > {}\n}).unwrap()"},"snapshot":"pub struct FooComponents;\nimpl DelegateComponent> for FooComponents {\n type Delegate = u64;\n}\nimpl<__Context__, __Params__> IsProviderFor, __Context__, __Params__>\nfor FooComponents\nwhere\n u64: IsProviderFor, __Context__, __Params__>,\n{}\nimpl DelegateComponent> for FooComponents {\n type Delegate = String;\n}\nimpl<__Context__, __Params__> IsProviderFor, __Context__, __Params__>\nfor FooComponents\nwhere\n String: IsProviderFor, __Context__, __Params__>,\n{}"},"old":{"module_name":"component__component_tests__delegate_components__direct","metadata":{},"snapshot":""}} From 5afa4b089cb6afd3d0a6efdbbd6ed00286699a78 Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Thu, 18 Jun 2026 22:14:31 +0200 Subject: [PATCH 04/31] Try file-based snapshot --- crates/macros/cgp-macro-test-util/src/lib.rs | 21 ++++++++----------- .../macros/cgp-macro-test-util/src/parse.rs | 15 +++---------- .../.direct.rs.pending-snap | 1 - .../delegate_components/direct.rs | 2 +- 4 files changed, 13 insertions(+), 26 deletions(-) delete mode 100644 crates/tests/cgp-tests/tests/component_tests/delegate_components/.direct.rs.pending-snap diff --git a/crates/macros/cgp-macro-test-util/src/lib.rs b/crates/macros/cgp-macro-test-util/src/lib.rs index 3f54d974..f4be631a 100644 --- a/crates/macros/cgp-macro-test-util/src/lib.rs +++ b/crates/macros/cgp-macro-test-util/src/lib.rs @@ -2,31 +2,28 @@ mod parse; use proc_macro::TokenStream; use quote::quote; -use syn::parse2; +use syn::{LitStr, parse2}; use crate::parse::MacroSnapshot; #[proc_macro] pub fn assert_delegate_components(body: TokenStream) -> TokenStream { - let MacroSnapshot { - test_name, - body, - snapshot, - } = parse2(body.into()).unwrap(); + let MacroSnapshot { test_name, body } = parse2(body.into()).unwrap(); let output = cgp_macro_lib::delegate_components(body).unwrap(); + let test_name_lit = LitStr::new(&test_name.to_string(), test_name.span()); + let wrapped = quote! { #output #[test] fn #test_name() { - insta::assert_snapshot!( - cgp_macro_core::functions::pretty_format(quote::quote! { - #output - }).unwrap(), - @#snapshot, - ); + let output = cgp_macro_core::functions::pretty_format(quote::quote! { + #output + }).unwrap(); + + insta::assert_snapshot!(#test_name_lit, output); } }; diff --git a/crates/macros/cgp-macro-test-util/src/parse.rs b/crates/macros/cgp-macro-test-util/src/parse.rs index 63da85ca..d3ee3698 100644 --- a/crates/macros/cgp-macro-test-util/src/parse.rs +++ b/crates/macros/cgp-macro-test-util/src/parse.rs @@ -1,30 +1,21 @@ use proc_macro2::TokenStream; +use syn::Ident; use syn::parse::{Parse, ParseStream}; -use syn::token::{At, Colon, Semi}; -use syn::{Ident, LitStr}; +use syn::token::Semi; pub struct MacroSnapshot { pub test_name: Ident, pub body: TokenStream, - pub snapshot: LitStr, } impl Parse for MacroSnapshot { fn parse(input: ParseStream) -> syn::Result { let test_name = input.parse()?; - let _: Colon = input.parse()?; - - let _: At = input.parse()?; - let snapshot = input.parse()?; let _: Semi = input.parse()?; let body = input.parse()?; - Ok(MacroSnapshot { - test_name, - body, - snapshot, - }) + Ok(MacroSnapshot { test_name, body }) } } diff --git a/crates/tests/cgp-tests/tests/component_tests/delegate_components/.direct.rs.pending-snap b/crates/tests/cgp-tests/tests/component_tests/delegate_components/.direct.rs.pending-snap deleted file mode 100644 index 151748f8..00000000 --- a/crates/tests/cgp-tests/tests/component_tests/delegate_components/.direct.rs.pending-snap +++ /dev/null @@ -1 +0,0 @@ -{"run_id":"1781812187-853164386","line":4,"new":{"module_name":"component__component_tests__delegate_components__direct","snapshot_name":"expand_foo_component","metadata":{"source":"crates/tests/cgp-tests/tests/component_tests/delegate_components/direct.rs","assertion_line":4,"expression":"cgp_macro_core :: functions ::\npretty_format(quote :: quote!\n{\n pub struct FooComponents; impl :: cgp :: macro_prelude ::\n DelegateComponent < Index < 0 > > for FooComponents\n { type Delegate = u64; } impl < __Context__, __Params__ > :: cgp ::\n macro_prelude :: IsProviderFor < Index < 0 > , __Context__, __Params__ >\n for FooComponents where u64 : :: cgp :: macro_prelude :: IsProviderFor <\n Index < 0 > , __Context__, __Params__ > {} impl :: cgp :: macro_prelude ::\n DelegateComponent < Index < 1 > > for FooComponents\n { type Delegate = String; } impl < __Context__, __Params__ > :: cgp ::\n macro_prelude :: IsProviderFor < Index < 1 > , __Context__, __Params__ >\n for FooComponents where String : :: cgp :: macro_prelude :: IsProviderFor\n < Index < 1 > , __Context__, __Params__ > {}\n}).unwrap()"},"snapshot":"pub struct FooComponents;\nimpl DelegateComponent> for FooComponents {\n type Delegate = u64;\n}\nimpl<__Context__, __Params__> IsProviderFor, __Context__, __Params__>\nfor FooComponents\nwhere\n u64: IsProviderFor, __Context__, __Params__>,\n{}\nimpl DelegateComponent> for FooComponents {\n type Delegate = String;\n}\nimpl<__Context__, __Params__> IsProviderFor, __Context__, __Params__>\nfor FooComponents\nwhere\n String: IsProviderFor, __Context__, __Params__>,\n{}"},"old":{"module_name":"component__component_tests__delegate_components__direct","metadata":{},"snapshot":""}} diff --git a/crates/tests/cgp-tests/tests/component_tests/delegate_components/direct.rs b/crates/tests/cgp-tests/tests/component_tests/delegate_components/direct.rs index 4d5e835c..e571ced8 100644 --- a/crates/tests/cgp-tests/tests/component_tests/delegate_components/direct.rs +++ b/crates/tests/cgp-tests/tests/component_tests/delegate_components/direct.rs @@ -2,7 +2,7 @@ use cgp::prelude::*; use cgp_macro_test_util::assert_delegate_components; assert_delegate_components! { - expand_foo_component: @""; + expand_foo_component; new FooComponents { Index<0>: u64, From 3e8c09701d52cd8909d23189a982962e23aac845 Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Thu, 18 Jun 2026 22:21:41 +0200 Subject: [PATCH 05/31] Inline snapshot now works --- crates/macros/cgp-macro-test-util/src/lib.rs | 15 +++++++----- .../macros/cgp-macro-test-util/src/parse.rs | 24 +++++++++++++++---- .../delegate_components/direct.rs | 23 +++++++++++++++++- 3 files changed, 51 insertions(+), 11 deletions(-) diff --git a/crates/macros/cgp-macro-test-util/src/lib.rs b/crates/macros/cgp-macro-test-util/src/lib.rs index f4be631a..3a6c02c8 100644 --- a/crates/macros/cgp-macro-test-util/src/lib.rs +++ b/crates/macros/cgp-macro-test-util/src/lib.rs @@ -2,28 +2,31 @@ mod parse; use proc_macro::TokenStream; use quote::quote; -use syn::{LitStr, parse2}; +use syn::parse2; use crate::parse::MacroSnapshot; #[proc_macro] pub fn assert_delegate_components(body: TokenStream) -> TokenStream { - let MacroSnapshot { test_name, body } = parse2(body.into()).unwrap(); + let MacroSnapshot { + test_name, + arg_ident, + expr, + body, + } = parse2(body.into()).unwrap(); let output = cgp_macro_lib::delegate_components(body).unwrap(); - let test_name_lit = LitStr::new(&test_name.to_string(), test_name.span()); - let wrapped = quote! { #output #[test] fn #test_name() { - let output = cgp_macro_core::functions::pretty_format(quote::quote! { + let #arg_ident = cgp_macro_core::functions::pretty_format(quote::quote! { #output }).unwrap(); - insta::assert_snapshot!(#test_name_lit, output); + #expr; } }; diff --git a/crates/macros/cgp-macro-test-util/src/parse.rs b/crates/macros/cgp-macro-test-util/src/parse.rs index d3ee3698..2af88f71 100644 --- a/crates/macros/cgp-macro-test-util/src/parse.rs +++ b/crates/macros/cgp-macro-test-util/src/parse.rs @@ -1,10 +1,11 @@ use proc_macro2::TokenStream; -use syn::Ident; use syn::parse::{Parse, ParseStream}; -use syn::token::Semi; +use syn::{Expr, Ident, braced, parenthesized}; pub struct MacroSnapshot { pub test_name: Ident, + pub arg_ident: Ident, + pub expr: Expr, pub body: TokenStream, } @@ -12,10 +13,25 @@ impl Parse for MacroSnapshot { fn parse(input: ParseStream) -> syn::Result { let test_name = input.parse()?; - let _: Semi = input.parse()?; + let arg_ident = { + let arg_body; + parenthesized!(arg_body in input); + arg_body.parse()? + }; + + let expr = { + let expr_body; + braced!(expr_body in input); + expr_body.parse()? + }; let body = input.parse()?; - Ok(MacroSnapshot { test_name, body }) + Ok(MacroSnapshot { + test_name, + arg_ident, + expr, + body, + }) } } diff --git a/crates/tests/cgp-tests/tests/component_tests/delegate_components/direct.rs b/crates/tests/cgp-tests/tests/component_tests/delegate_components/direct.rs index e571ced8..08d93b15 100644 --- a/crates/tests/cgp-tests/tests/component_tests/delegate_components/direct.rs +++ b/crates/tests/cgp-tests/tests/component_tests/delegate_components/direct.rs @@ -1,8 +1,29 @@ use cgp::prelude::*; use cgp_macro_test_util::assert_delegate_components; +use insta::assert_snapshot; assert_delegate_components! { - expand_foo_component; + expand_foo_component(output) { + assert_snapshot!(output, @" + pub struct FooComponents; + impl DelegateComponent> for FooComponents { + type Delegate = u64; + } + impl<__Context__, __Params__> IsProviderFor, __Context__, __Params__> + for FooComponents + where + u64: IsProviderFor, __Context__, __Params__>, + {} + impl DelegateComponent> for FooComponents { + type Delegate = String; + } + impl<__Context__, __Params__> IsProviderFor, __Context__, __Params__> + for FooComponents + where + String: IsProviderFor, __Context__, __Params__>, + {} + ") + } new FooComponents { Index<0>: u64, From d057b3718af75545ed60257a0ac4e86943d553d0 Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Thu, 18 Jun 2026 22:25:54 +0200 Subject: [PATCH 06/31] Put original code first before snapshot --- crates/macros/cgp-macro-test-util/src/parse.rs | 8 ++++++-- .../component_tests/delegate_components/direct.rs | 12 +++++++----- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/crates/macros/cgp-macro-test-util/src/parse.rs b/crates/macros/cgp-macro-test-util/src/parse.rs index 2af88f71..325a272f 100644 --- a/crates/macros/cgp-macro-test-util/src/parse.rs +++ b/crates/macros/cgp-macro-test-util/src/parse.rs @@ -11,6 +11,12 @@ pub struct MacroSnapshot { impl Parse for MacroSnapshot { fn parse(input: ParseStream) -> syn::Result { + let body = { + let body; + braced!(body in input); + body.parse()? + }; + let test_name = input.parse()?; let arg_ident = { @@ -25,8 +31,6 @@ impl Parse for MacroSnapshot { expr_body.parse()? }; - let body = input.parse()?; - Ok(MacroSnapshot { test_name, arg_ident, diff --git a/crates/tests/cgp-tests/tests/component_tests/delegate_components/direct.rs b/crates/tests/cgp-tests/tests/component_tests/delegate_components/direct.rs index 08d93b15..d4b41a5d 100644 --- a/crates/tests/cgp-tests/tests/component_tests/delegate_components/direct.rs +++ b/crates/tests/cgp-tests/tests/component_tests/delegate_components/direct.rs @@ -3,6 +3,13 @@ use cgp_macro_test_util::assert_delegate_components; use insta::assert_snapshot; assert_delegate_components! { + { + new FooComponents { + Index<0>: u64, + Index<1>: String, + } + } + expand_foo_component(output) { assert_snapshot!(output, @" pub struct FooComponents; @@ -24,11 +31,6 @@ assert_delegate_components! { {} ") } - - new FooComponents { - Index<0>: u64, - Index<1>: String, - } } delegate_components! { From aeb39b00e7c89889bb61a3b24758543d566d3808 Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Thu, 18 Jun 2026 22:33:33 +0200 Subject: [PATCH 07/31] Migrate more tests to assert_delegate_components --- .../delegate_components/direct.rs | 42 +++++- .../delegate_components/general.rs | 126 ++++++++++++++---- 2 files changed, 138 insertions(+), 30 deletions(-) diff --git a/crates/tests/cgp-tests/tests/component_tests/delegate_components/direct.rs b/crates/tests/cgp-tests/tests/component_tests/delegate_components/direct.rs index d4b41a5d..27e3bfa3 100644 --- a/crates/tests/cgp-tests/tests/component_tests/delegate_components/direct.rs +++ b/crates/tests/cgp-tests/tests/component_tests/delegate_components/direct.rs @@ -33,12 +33,42 @@ assert_delegate_components! { } } -delegate_components! { - new BarComponents { - Index<0>: - FooComponents, - Index<1> -> - FooComponents, +assert_delegate_components! { + { + new BarComponents { + Index<0>: + FooComponents, + Index<1> -> + FooComponents, + } + } + + expand_bar_component(output) { + assert_snapshot!(output, @" + pub struct BarComponents; + impl DelegateComponent> for BarComponents { + type Delegate = FooComponents; + } + impl<__Context__, __Params__> IsProviderFor, __Context__, __Params__> + for BarComponents + where + FooComponents: IsProviderFor, __Context__, __Params__>, + {} + impl DelegateComponent> for BarComponents + where + FooComponents: DelegateComponent>, + { + type Delegate = >>::Delegate; + } + impl<__Context__, __Params__> IsProviderFor, __Context__, __Params__> + for BarComponents + where + FooComponents: DelegateComponent>, + , + >>::Delegate: IsProviderFor, __Context__, __Params__>, + {} + ") } } diff --git a/crates/tests/cgp-tests/tests/component_tests/delegate_components/general.rs b/crates/tests/cgp-tests/tests/component_tests/delegate_components/general.rs index d7035cbc..72a12694 100644 --- a/crates/tests/cgp-tests/tests/component_tests/delegate_components/general.rs +++ b/crates/tests/cgp-tests/tests/component_tests/delegate_components/general.rs @@ -1,11 +1,10 @@ #![allow(unused)] -use core::marker::PhantomData; +mod test_basic_delegate_components { + use cgp::prelude::DelegateComponent; + use cgp_macro_test_util::assert_delegate_components; + use insta::assert_snapshot; -use cgp::prelude::*; - -#[test] -fn test_basic_delegate_components() { pub struct FooKey; pub struct FooValue; pub struct BarKey; @@ -14,14 +13,45 @@ fn test_basic_delegate_components() { pub struct Components; - delegate_components! { - Components { - FooKey: FooValue, - [ - BarKey, - BazKey, - ]: - BarValue, + assert_delegate_components! { + { + Components { + FooKey: FooValue, + [ + BarKey, + BazKey, + ]: + BarValue, + } + } + + expand_components(output) { + assert_snapshot!(output, @" + impl DelegateComponent for Components { + type Delegate = FooValue; + } + impl<__Context__, __Params__> IsProviderFor + for Components + where + FooValue: IsProviderFor, + {} + impl DelegateComponent for Components { + type Delegate = BarValue; + } + impl<__Context__, __Params__> IsProviderFor + for Components + where + BarValue: IsProviderFor, + {} + impl DelegateComponent for Components { + type Delegate = BarValue; + } + impl<__Context__, __Params__> IsProviderFor + for Components + where + BarValue: IsProviderFor, + {} + ") } } @@ -35,8 +65,13 @@ fn test_basic_delegate_components() { impl CheckDelegates for Components {} } -#[test] -fn test_generic_delegate_components() { +mod test_generic_delegate_components { + use core::marker::PhantomData; + + use cgp::prelude::DelegateComponent; + use cgp_macro_test_util::assert_delegate_components; + use insta::assert_snapshot; + pub struct FooKey(pub PhantomData); pub struct FooValue; pub struct BarKey<'a, T>(pub PhantomData<(&'a (), T)>); @@ -45,15 +80,58 @@ fn test_generic_delegate_components() { pub struct Components; - delegate_components! { - <'a, T1: Clone> - Components { - FooKey: FooValue, - [ - BarKey<'a, T1>, - BazKey, - ]: - BarValue, + assert_delegate_components! { + { + <'a, T1: Clone> + Components { + FooKey: FooValue, + [ + BarKey<'a, T1>, + BazKey, + ]: + BarValue, + } + } + expand_components(output) { + assert_snapshot!(output, @" + impl<'a, T1: Clone> DelegateComponent> for Components { + type Delegate = FooValue; + } + impl< + 'a, + T1: Clone, + __Context__, + __Params__, + > IsProviderFor, __Context__, __Params__> for Components + where + FooValue: IsProviderFor, __Context__, __Params__>, + {} + impl<'a, T1: Clone> DelegateComponent> for Components { + type Delegate = BarValue; + } + impl< + 'a, + T1: Clone, + __Context__, + __Params__, + > IsProviderFor, __Context__, __Params__> for Components + where + BarValue: IsProviderFor, __Context__, __Params__>, + {} + impl<'a, T1: Clone, T2> DelegateComponent> for Components { + type Delegate = BarValue; + } + impl< + 'a, + T1: Clone, + T2, + __Context__, + __Params__, + > IsProviderFor, __Context__, __Params__> for Components + where + BarValue: IsProviderFor, __Context__, __Params__>, + {} + ") } } From 763616eb70be15f552b9781ff10015998b6e3280 Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Thu, 18 Jun 2026 22:34:28 +0200 Subject: [PATCH 08/31] Rename to snapshot_delegate_components --- crates/macros/cgp-macro-test-util/src/lib.rs | 2 +- .../tests/component_tests/delegate_components/direct.rs | 6 +++--- .../tests/component_tests/delegate_components/general.rs | 8 ++++---- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/crates/macros/cgp-macro-test-util/src/lib.rs b/crates/macros/cgp-macro-test-util/src/lib.rs index 3a6c02c8..ae5e8187 100644 --- a/crates/macros/cgp-macro-test-util/src/lib.rs +++ b/crates/macros/cgp-macro-test-util/src/lib.rs @@ -7,7 +7,7 @@ use syn::parse2; use crate::parse::MacroSnapshot; #[proc_macro] -pub fn assert_delegate_components(body: TokenStream) -> TokenStream { +pub fn snapshot_delegate_components(body: TokenStream) -> TokenStream { let MacroSnapshot { test_name, arg_ident, diff --git a/crates/tests/cgp-tests/tests/component_tests/delegate_components/direct.rs b/crates/tests/cgp-tests/tests/component_tests/delegate_components/direct.rs index 27e3bfa3..37ef7789 100644 --- a/crates/tests/cgp-tests/tests/component_tests/delegate_components/direct.rs +++ b/crates/tests/cgp-tests/tests/component_tests/delegate_components/direct.rs @@ -1,8 +1,8 @@ use cgp::prelude::*; -use cgp_macro_test_util::assert_delegate_components; +use cgp_macro_test_util::snapshot_delegate_components; use insta::assert_snapshot; -assert_delegate_components! { +snapshot_delegate_components! { { new FooComponents { Index<0>: u64, @@ -33,7 +33,7 @@ assert_delegate_components! { } } -assert_delegate_components! { +snapshot_delegate_components! { { new BarComponents { Index<0>: diff --git a/crates/tests/cgp-tests/tests/component_tests/delegate_components/general.rs b/crates/tests/cgp-tests/tests/component_tests/delegate_components/general.rs index 72a12694..26a1abad 100644 --- a/crates/tests/cgp-tests/tests/component_tests/delegate_components/general.rs +++ b/crates/tests/cgp-tests/tests/component_tests/delegate_components/general.rs @@ -2,7 +2,7 @@ mod test_basic_delegate_components { use cgp::prelude::DelegateComponent; - use cgp_macro_test_util::assert_delegate_components; + use cgp_macro_test_util::snapshot_delegate_components; use insta::assert_snapshot; pub struct FooKey; @@ -13,7 +13,7 @@ mod test_basic_delegate_components { pub struct Components; - assert_delegate_components! { + snapshot_delegate_components! { { Components { FooKey: FooValue, @@ -69,7 +69,7 @@ mod test_generic_delegate_components { use core::marker::PhantomData; use cgp::prelude::DelegateComponent; - use cgp_macro_test_util::assert_delegate_components; + use cgp_macro_test_util::snapshot_delegate_components; use insta::assert_snapshot; pub struct FooKey(pub PhantomData); @@ -80,7 +80,7 @@ mod test_generic_delegate_components { pub struct Components; - assert_delegate_components! { + snapshot_delegate_components! { { <'a, T1: Clone> Components { From 691f6224c1627a733cb10a96fa15cc4359b08964 Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Thu, 18 Jun 2026 22:35:26 +0200 Subject: [PATCH 09/31] Allow arbitrary expression in body --- crates/macros/cgp-macro-test-util/src/lib.rs | 2 +- crates/macros/cgp-macro-test-util/src/parse.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/macros/cgp-macro-test-util/src/lib.rs b/crates/macros/cgp-macro-test-util/src/lib.rs index ae5e8187..e31b4a7c 100644 --- a/crates/macros/cgp-macro-test-util/src/lib.rs +++ b/crates/macros/cgp-macro-test-util/src/lib.rs @@ -26,7 +26,7 @@ pub fn snapshot_delegate_components(body: TokenStream) -> TokenStream { #output }).unwrap(); - #expr; + #expr } }; diff --git a/crates/macros/cgp-macro-test-util/src/parse.rs b/crates/macros/cgp-macro-test-util/src/parse.rs index 325a272f..ec09e17e 100644 --- a/crates/macros/cgp-macro-test-util/src/parse.rs +++ b/crates/macros/cgp-macro-test-util/src/parse.rs @@ -1,11 +1,11 @@ use proc_macro2::TokenStream; use syn::parse::{Parse, ParseStream}; -use syn::{Expr, Ident, braced, parenthesized}; +use syn::{Ident, braced, parenthesized}; pub struct MacroSnapshot { pub test_name: Ident, pub arg_ident: Ident, - pub expr: Expr, + pub expr: TokenStream, pub body: TokenStream, } From 733b6620fd1603b6125e3ec9399d9b19594518aa Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Thu, 18 Jun 2026 22:39:45 +0200 Subject: [PATCH 10/31] Add MacroSnapshot::wrap_output helper --- crates/macros/cgp-macro-test-util/src/lib.rs | 25 +++---------------- .../macros/cgp-macro-test-util/src/parse.rs | 25 +++++++++++++++++++ 2 files changed, 28 insertions(+), 22 deletions(-) diff --git a/crates/macros/cgp-macro-test-util/src/lib.rs b/crates/macros/cgp-macro-test-util/src/lib.rs index e31b4a7c..96b42063 100644 --- a/crates/macros/cgp-macro-test-util/src/lib.rs +++ b/crates/macros/cgp-macro-test-util/src/lib.rs @@ -1,34 +1,15 @@ mod parse; use proc_macro::TokenStream; -use quote::quote; use syn::parse2; use crate::parse::MacroSnapshot; #[proc_macro] pub fn snapshot_delegate_components(body: TokenStream) -> TokenStream { - let MacroSnapshot { - test_name, - arg_ident, - expr, - body, - } = parse2(body.into()).unwrap(); + let snapshot: MacroSnapshot = parse2(body.into()).unwrap(); - let output = cgp_macro_lib::delegate_components(body).unwrap(); + let output = cgp_macro_lib::delegate_components(snapshot.body.clone()).unwrap(); - let wrapped = quote! { - #output - - #[test] - fn #test_name() { - let #arg_ident = cgp_macro_core::functions::pretty_format(quote::quote! { - #output - }).unwrap(); - - #expr - } - }; - - wrapped.into() + snapshot.wrap_output(output).into() } diff --git a/crates/macros/cgp-macro-test-util/src/parse.rs b/crates/macros/cgp-macro-test-util/src/parse.rs index ec09e17e..c70d48f9 100644 --- a/crates/macros/cgp-macro-test-util/src/parse.rs +++ b/crates/macros/cgp-macro-test-util/src/parse.rs @@ -1,4 +1,5 @@ use proc_macro2::TokenStream; +use quote::quote; use syn::parse::{Parse, ParseStream}; use syn::{Ident, braced, parenthesized}; @@ -9,6 +10,30 @@ pub struct MacroSnapshot { pub body: TokenStream, } +impl MacroSnapshot { + pub fn wrap_output(&self, output: TokenStream) -> TokenStream { + let Self { + test_name, + arg_ident, + expr, + .. + } = self; + + quote! { + #output + + #[test] + fn #test_name() { + let #arg_ident = cgp_macro_core::functions::pretty_format(quote::quote! { + #output + }).unwrap(); + + #expr + } + } + } +} + impl Parse for MacroSnapshot { fn parse(input: ParseStream) -> syn::Result { let body = { From 7f808f76777a6294e1ee1ec74d0ec811ffdde05e Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Thu, 18 Jun 2026 22:48:45 +0200 Subject: [PATCH 11/31] Add snapshot_cgp_component --- crates/macros/cgp-macro-test-util/src/lib.rs | 13 +++ .../macros/cgp-macro-test-util/src/parse.rs | 20 ++++- .../component_tests/cgp_component/constant.rs | 81 ++++++++++++++++++- 3 files changed, 107 insertions(+), 7 deletions(-) diff --git a/crates/macros/cgp-macro-test-util/src/lib.rs b/crates/macros/cgp-macro-test-util/src/lib.rs index 96b42063..7842ece5 100644 --- a/crates/macros/cgp-macro-test-util/src/lib.rs +++ b/crates/macros/cgp-macro-test-util/src/lib.rs @@ -13,3 +13,16 @@ pub fn snapshot_delegate_components(body: TokenStream) -> TokenStream { snapshot.wrap_output(output).into() } + +#[proc_macro] +pub fn snapshot_cgp_component(body: TokenStream) -> TokenStream { + let snapshot: MacroSnapshot = parse2(body.into()).unwrap(); + + let output = cgp_macro_lib::cgp_component( + snapshot.attrs.clone().unwrap().into(), + snapshot.body.clone(), + ) + .unwrap(); + + snapshot.wrap_output(output).into() +} diff --git a/crates/macros/cgp-macro-test-util/src/parse.rs b/crates/macros/cgp-macro-test-util/src/parse.rs index c70d48f9..a9c129d1 100644 --- a/crates/macros/cgp-macro-test-util/src/parse.rs +++ b/crates/macros/cgp-macro-test-util/src/parse.rs @@ -1,13 +1,15 @@ use proc_macro2::TokenStream; use quote::quote; use syn::parse::{Parse, ParseStream}; -use syn::{Ident, braced, parenthesized}; +use syn::token::Pound; +use syn::{Ident, braced, bracketed, parenthesized}; pub struct MacroSnapshot { + pub attrs: Option, + pub body: TokenStream, pub test_name: Ident, pub arg_ident: Ident, pub expr: TokenStream, - pub body: TokenStream, } impl MacroSnapshot { @@ -36,6 +38,17 @@ impl MacroSnapshot { impl Parse for MacroSnapshot { fn parse(input: ParseStream) -> syn::Result { + let attrs = if input.peek(Pound) { + let _: Pound = input.parse()?; + + let attrs_body; + bracketed!(attrs_body in input); + + Some(attrs_body.parse()?) + } else { + None + }; + let body = { let body; braced!(body in input); @@ -57,10 +70,11 @@ impl Parse for MacroSnapshot { }; Ok(MacroSnapshot { + attrs, + body, test_name, arg_ident, expr, - body, }) } } diff --git a/crates/tests/cgp-tests/tests/component_tests/cgp_component/constant.rs b/crates/tests/cgp-tests/tests/component_tests/cgp_component/constant.rs index 1f8e018c..18a82b32 100644 --- a/crates/tests/cgp-tests/tests/component_tests/cgp_component/constant.rs +++ b/crates/tests/cgp-tests/tests/component_tests/cgp_component/constant.rs @@ -1,11 +1,84 @@ use cgp::prelude::*; +use cgp_macro_test_util::snapshot_cgp_component; +use insta::assert_snapshot; -pub fn test_component_with_const() { - #[cgp_component(ConstantGetter)] - pub trait HasConstant { - const CONSTANT: u64; +snapshot_cgp_component! { + #[ConstantGetter] + { + pub trait HasConstant { + const CONSTANT: u64; + } + } + + test_expansion(output) { + assert_snapshot!(output, @" + pub trait HasConstant { + const CONSTANT: u64; + } + impl<__Context__> HasConstant for __Context__ + where + __Context__: ConstantGetter<__Context__>, + { + const CONSTANT: u64 = <__Context__ as ConstantGetter<__Context__>>::CONSTANT; + } + pub trait ConstantGetter< + __Context__, + >: IsProviderFor { + const CONSTANT: u64; + } + impl<__Provider__, __Context__> ConstantGetter<__Context__> for __Provider__ + where + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + ConstantGetterComponent, + >>::Delegate: ConstantGetter<__Context__>, + { + const CONSTANT: u64 = <<__Provider__ as DelegateComponent< + ConstantGetterComponent, + >>::Delegate as ConstantGetter<__Context__>>::CONSTANT; + } + pub struct ConstantGetterComponent; + impl<__Context__> ConstantGetter<__Context__> for UseContext + where + __Context__: HasConstant, + { + const CONSTANT: u64 = <__Context__ as HasConstant>::CONSTANT; + } + impl<__Context__> IsProviderFor for UseContext + where + __Context__: HasConstant, + {} + impl<__Context__, __Components__, __Path__> ConstantGetter<__Context__> + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: ConstantGetter<__Context__>, + { + const CONSTANT: u64 = <<__Components__ as DelegateComponent< + __Path__, + >>::Delegate as ConstantGetter<__Context__>>::CONSTANT; + } + impl< + __Context__, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: IsProviderFor + + ConstantGetter<__Context__>, + {} + ") } +} +pub fn test_component_with_const() { pub struct UseConstant; #[cgp_provider] From a0568d3a810e7dd6e0b7b0560a407fd28714e746 Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Thu, 18 Jun 2026 22:53:10 +0200 Subject: [PATCH 12/31] Add cgp-macro-test-util-lib crate --- Cargo.lock | 13 ++++++++++++- Cargo.toml | 2 ++ .../macros/cgp-macro-test-util-lib/Cargo.toml | 17 +++++++++++++++++ .../macros/cgp-macro-test-util-lib/src/lib.rs | 1 + .../cgp-macro-test-util-lib/src/types/mod.rs | 3 +++ .../src/types/snapshot.rs} | 0 crates/macros/cgp-macro-test-util/Cargo.toml | 6 +++--- crates/macros/cgp-macro-test-util/src/lib.rs | 5 +---- 8 files changed, 39 insertions(+), 8 deletions(-) create mode 100644 crates/macros/cgp-macro-test-util-lib/Cargo.toml create mode 100644 crates/macros/cgp-macro-test-util-lib/src/lib.rs create mode 100644 crates/macros/cgp-macro-test-util-lib/src/types/mod.rs rename crates/macros/{cgp-macro-test-util/src/parse.rs => cgp-macro-test-util-lib/src/types/snapshot.rs} (100%) diff --git a/Cargo.lock b/Cargo.lock index 9931708c..304573fa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -208,7 +208,18 @@ version = "0.7.0" dependencies = [ "cgp-macro-core", "cgp-macro-lib", - "itertools", + "cgp-macro-test-util-lib", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "cgp-macro-test-util-lib" +version = "0.7.0" +dependencies = [ + "cgp-macro-core", + "cgp-macro-lib", "proc-macro2", "quote", "syn", diff --git a/Cargo.toml b/Cargo.toml index 0da826fe..cf5a47e4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,6 +27,7 @@ members = [ "crates/macros/cgp-macro-core", "crates/macros/cgp-macro-lib", "crates/macros/cgp-macro-test-util", + "crates/macros/cgp-macro-test-util-lib", "crates/macros/cgp-extra-macro", "crates/macros/cgp-extra-macro-lib", @@ -70,5 +71,6 @@ cgp-macro = { version = "0.7.0", path = "./crates/macros/cgp-m cgp-macro-core = { version = "0.7.0", path = "./crates/macros/cgp-macro-core" } cgp-macro-lib = { version = "0.7.0", path = "./crates/macros/cgp-macro-lib" } cgp-macro-test-util = { version = "0.7.0", path = "./crates/macros/cgp-macro-test-util" } +cgp-macro-test-util-lib = { version = "0.7.0", path = "./crates/macros/cgp-macro-test-util-lib" } cgp-extra-macro = { version = "0.7.0", path = "./crates/macros/cgp-extra-macro" } cgp-extra-macro-lib = { version = "0.7.0", path = "./crates/macros/cgp-extra-macro-lib" } diff --git a/crates/macros/cgp-macro-test-util-lib/Cargo.toml b/crates/macros/cgp-macro-test-util-lib/Cargo.toml new file mode 100644 index 00000000..dc347f6b --- /dev/null +++ b/crates/macros/cgp-macro-test-util-lib/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "cgp-macro-test-util-lib" +version = "0.7.0" +edition = { workspace = true } +license = { workspace = true } +repository = { workspace = true } +authors = { workspace = true } +rust-version = { workspace = true } +keywords = { workspace = true } + +[dependencies] +cgp-macro-lib = { workspace = true } +cgp-macro-core = { workspace = true } + +syn = { version = "2.0.95" } +quote = { version = "1.0.38" } +proc-macro2 = { version = "1.0.92" } diff --git a/crates/macros/cgp-macro-test-util-lib/src/lib.rs b/crates/macros/cgp-macro-test-util-lib/src/lib.rs new file mode 100644 index 00000000..cd408564 --- /dev/null +++ b/crates/macros/cgp-macro-test-util-lib/src/lib.rs @@ -0,0 +1 @@ +pub mod types; diff --git a/crates/macros/cgp-macro-test-util-lib/src/types/mod.rs b/crates/macros/cgp-macro-test-util-lib/src/types/mod.rs new file mode 100644 index 00000000..a220e775 --- /dev/null +++ b/crates/macros/cgp-macro-test-util-lib/src/types/mod.rs @@ -0,0 +1,3 @@ +mod snapshot; + +pub use snapshot::*; diff --git a/crates/macros/cgp-macro-test-util/src/parse.rs b/crates/macros/cgp-macro-test-util-lib/src/types/snapshot.rs similarity index 100% rename from crates/macros/cgp-macro-test-util/src/parse.rs rename to crates/macros/cgp-macro-test-util-lib/src/types/snapshot.rs diff --git a/crates/macros/cgp-macro-test-util/Cargo.toml b/crates/macros/cgp-macro-test-util/Cargo.toml index 69923940..53c3b094 100644 --- a/crates/macros/cgp-macro-test-util/Cargo.toml +++ b/crates/macros/cgp-macro-test-util/Cargo.toml @@ -12,10 +12,10 @@ keywords = { workspace = true } proc-macro = true [dependencies] -cgp-macro-lib = { workspace = true } -cgp-macro-core = { workspace = true } +cgp-macro-lib = { workspace = true } +cgp-macro-core = { workspace = true } +cgp-macro-test-util-lib = { workspace = true } syn = { version = "2.0.95", features = [ "full", "extra-traits", "visit", "visit-mut" ] } quote = { version = "1.0.38" } proc-macro2 = { version = "1.0.92" } -itertools = { version = "0.14.0" } diff --git a/crates/macros/cgp-macro-test-util/src/lib.rs b/crates/macros/cgp-macro-test-util/src/lib.rs index 7842ece5..16f5585c 100644 --- a/crates/macros/cgp-macro-test-util/src/lib.rs +++ b/crates/macros/cgp-macro-test-util/src/lib.rs @@ -1,10 +1,7 @@ -mod parse; - +use cgp_macro_test_util_lib::types::MacroSnapshot; use proc_macro::TokenStream; use syn::parse2; -use crate::parse::MacroSnapshot; - #[proc_macro] pub fn snapshot_delegate_components(body: TokenStream) -> TokenStream { let snapshot: MacroSnapshot = parse2(body.into()).unwrap(); From e0c27b8586b29a1aafbfca3e53fc1026ff3761bc Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Thu, 18 Jun 2026 23:04:23 +0200 Subject: [PATCH 13/31] Refactor snapshot_delegate_components macro --- .../src/entrypoints/mod.rs | 3 + .../snapshot_delegate_components.rs | 12 +++ .../macros/cgp-macro-test-util-lib/src/lib.rs | 1 + .../src/types/delegate_components.rs | 30 +++++++ .../cgp-macro-test-util-lib/src/types/mod.rs | 2 + .../src/types/snapshot.rs | 25 +----- crates/macros/cgp-macro-test-util/src/lib.rs | 31 ++++--- .../component_tests/cgp_component/constant.rs | 81 +------------------ .../delegate_components/direct.rs | 4 +- .../delegate_components/general.rs | 4 +- 10 files changed, 71 insertions(+), 122 deletions(-) create mode 100644 crates/macros/cgp-macro-test-util-lib/src/entrypoints/mod.rs create mode 100644 crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_delegate_components.rs create mode 100644 crates/macros/cgp-macro-test-util-lib/src/types/delegate_components.rs diff --git a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/mod.rs b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/mod.rs new file mode 100644 index 00000000..a6c07a15 --- /dev/null +++ b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/mod.rs @@ -0,0 +1,3 @@ +mod snapshot_delegate_components; + +pub use snapshot_delegate_components::*; diff --git a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_delegate_components.rs b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_delegate_components.rs new file mode 100644 index 00000000..acbd25c2 --- /dev/null +++ b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_delegate_components.rs @@ -0,0 +1,12 @@ +use proc_macro2::TokenStream; +use syn::parse2; + +use crate::types::AssertDelegateComponents; + +pub fn snapshot_delegate_components(body: TokenStream) -> syn::Result { + let item: AssertDelegateComponents = parse2(body)?; + + let output = cgp_macro_lib::delegate_components(item.body.clone())?; + + Ok(item.snapshot.wrap_output(output)) +} diff --git a/crates/macros/cgp-macro-test-util-lib/src/lib.rs b/crates/macros/cgp-macro-test-util-lib/src/lib.rs index cd408564..d767f807 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/lib.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/lib.rs @@ -1 +1,2 @@ +pub mod entrypoints; pub mod types; diff --git a/crates/macros/cgp-macro-test-util-lib/src/types/delegate_components.rs b/crates/macros/cgp-macro-test-util-lib/src/types/delegate_components.rs new file mode 100644 index 00000000..bcba57a6 --- /dev/null +++ b/crates/macros/cgp-macro-test-util-lib/src/types/delegate_components.rs @@ -0,0 +1,30 @@ +use cgp_macro_core::define_keyword; +use cgp_macro_core::types::keyword::Keyword; +use proc_macro2::TokenStream; +use syn::parse::{Parse, ParseStream}; +use syn::{Token, braced}; + +use crate::types::MacroSnapshot; + +define_keyword!(DelegateComponents, "delegate_components"); + +pub struct AssertDelegateComponents { + pub body: TokenStream, + pub snapshot: MacroSnapshot, +} + +impl Parse for AssertDelegateComponents { + fn parse(input: ParseStream) -> syn::Result { + let _: Keyword = input.parse()?; + let _: Token![!] = input.parse()?; + + let body = { + let body; + braced!(body in input); + body.parse()? + }; + + let snapshot = input.parse()?; + Ok(Self { body, snapshot }) + } +} diff --git a/crates/macros/cgp-macro-test-util-lib/src/types/mod.rs b/crates/macros/cgp-macro-test-util-lib/src/types/mod.rs index a220e775..7176e1b6 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/types/mod.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/types/mod.rs @@ -1,3 +1,5 @@ +mod delegate_components; mod snapshot; +pub use delegate_components::*; pub use snapshot::*; diff --git a/crates/macros/cgp-macro-test-util-lib/src/types/snapshot.rs b/crates/macros/cgp-macro-test-util-lib/src/types/snapshot.rs index a9c129d1..065d7153 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/types/snapshot.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/types/snapshot.rs @@ -1,12 +1,9 @@ use proc_macro2::TokenStream; use quote::quote; use syn::parse::{Parse, ParseStream}; -use syn::token::Pound; -use syn::{Ident, braced, bracketed, parenthesized}; +use syn::{Ident, braced, parenthesized}; pub struct MacroSnapshot { - pub attrs: Option, - pub body: TokenStream, pub test_name: Ident, pub arg_ident: Ident, pub expr: TokenStream, @@ -18,7 +15,6 @@ impl MacroSnapshot { test_name, arg_ident, expr, - .. } = self; quote! { @@ -38,23 +34,6 @@ impl MacroSnapshot { impl Parse for MacroSnapshot { fn parse(input: ParseStream) -> syn::Result { - let attrs = if input.peek(Pound) { - let _: Pound = input.parse()?; - - let attrs_body; - bracketed!(attrs_body in input); - - Some(attrs_body.parse()?) - } else { - None - }; - - let body = { - let body; - braced!(body in input); - body.parse()? - }; - let test_name = input.parse()?; let arg_ident = { @@ -70,8 +49,6 @@ impl Parse for MacroSnapshot { }; Ok(MacroSnapshot { - attrs, - body, test_name, arg_ident, expr, diff --git a/crates/macros/cgp-macro-test-util/src/lib.rs b/crates/macros/cgp-macro-test-util/src/lib.rs index 16f5585c..7d45a1a4 100644 --- a/crates/macros/cgp-macro-test-util/src/lib.rs +++ b/crates/macros/cgp-macro-test-util/src/lib.rs @@ -1,25 +1,22 @@ -use cgp_macro_test_util_lib::types::MacroSnapshot; +use cgp_macro_test_util_lib::entrypoints; use proc_macro::TokenStream; -use syn::parse2; #[proc_macro] pub fn snapshot_delegate_components(body: TokenStream) -> TokenStream { - let snapshot: MacroSnapshot = parse2(body.into()).unwrap(); - - let output = cgp_macro_lib::delegate_components(snapshot.body.clone()).unwrap(); - - snapshot.wrap_output(output).into() + entrypoints::snapshot_delegate_components(body.into()) + .unwrap_or_else(syn::Error::into_compile_error) + .into() } -#[proc_macro] -pub fn snapshot_cgp_component(body: TokenStream) -> TokenStream { - let snapshot: MacroSnapshot = parse2(body.into()).unwrap(); +// #[proc_macro] +// pub fn snapshot_cgp_component(body: TokenStream) -> TokenStream { +// let snapshot: MacroSnapshot = parse2(body.into()).unwrap(); - let output = cgp_macro_lib::cgp_component( - snapshot.attrs.clone().unwrap().into(), - snapshot.body.clone(), - ) - .unwrap(); +// let output = cgp_macro_lib::cgp_component( +// snapshot.attrs.clone().unwrap().into(), +// snapshot.body.clone(), +// ) +// .unwrap(); - snapshot.wrap_output(output).into() -} +// snapshot.wrap_output(output).into() +// } diff --git a/crates/tests/cgp-tests/tests/component_tests/cgp_component/constant.rs b/crates/tests/cgp-tests/tests/component_tests/cgp_component/constant.rs index 18a82b32..1f8e018c 100644 --- a/crates/tests/cgp-tests/tests/component_tests/cgp_component/constant.rs +++ b/crates/tests/cgp-tests/tests/component_tests/cgp_component/constant.rs @@ -1,84 +1,11 @@ use cgp::prelude::*; -use cgp_macro_test_util::snapshot_cgp_component; -use insta::assert_snapshot; -snapshot_cgp_component! { - #[ConstantGetter] - { - pub trait HasConstant { - const CONSTANT: u64; - } - } - - test_expansion(output) { - assert_snapshot!(output, @" - pub trait HasConstant { - const CONSTANT: u64; - } - impl<__Context__> HasConstant for __Context__ - where - __Context__: ConstantGetter<__Context__>, - { - const CONSTANT: u64 = <__Context__ as ConstantGetter<__Context__>>::CONSTANT; - } - pub trait ConstantGetter< - __Context__, - >: IsProviderFor { - const CONSTANT: u64; - } - impl<__Provider__, __Context__> ConstantGetter<__Context__> for __Provider__ - where - __Provider__: DelegateComponent - + IsProviderFor, - <__Provider__ as DelegateComponent< - ConstantGetterComponent, - >>::Delegate: ConstantGetter<__Context__>, - { - const CONSTANT: u64 = <<__Provider__ as DelegateComponent< - ConstantGetterComponent, - >>::Delegate as ConstantGetter<__Context__>>::CONSTANT; - } - pub struct ConstantGetterComponent; - impl<__Context__> ConstantGetter<__Context__> for UseContext - where - __Context__: HasConstant, - { - const CONSTANT: u64 = <__Context__ as HasConstant>::CONSTANT; - } - impl<__Context__> IsProviderFor for UseContext - where - __Context__: HasConstant, - {} - impl<__Context__, __Components__, __Path__> ConstantGetter<__Context__> - for RedirectLookup<__Components__, __Path__> - where - __Components__: DelegateComponent<__Path__>, - <__Components__ as DelegateComponent< - __Path__, - >>::Delegate: ConstantGetter<__Context__>, - { - const CONSTANT: u64 = <<__Components__ as DelegateComponent< - __Path__, - >>::Delegate as ConstantGetter<__Context__>>::CONSTANT; - } - impl< - __Context__, - __Components__, - __Path__, - > IsProviderFor - for RedirectLookup<__Components__, __Path__> - where - __Components__: DelegateComponent<__Path__>, - <__Components__ as DelegateComponent< - __Path__, - >>::Delegate: IsProviderFor - + ConstantGetter<__Context__>, - {} - ") +pub fn test_component_with_const() { + #[cgp_component(ConstantGetter)] + pub trait HasConstant { + const CONSTANT: u64; } -} -pub fn test_component_with_const() { pub struct UseConstant; #[cgp_provider] diff --git a/crates/tests/cgp-tests/tests/component_tests/delegate_components/direct.rs b/crates/tests/cgp-tests/tests/component_tests/delegate_components/direct.rs index 37ef7789..b4f7f312 100644 --- a/crates/tests/cgp-tests/tests/component_tests/delegate_components/direct.rs +++ b/crates/tests/cgp-tests/tests/component_tests/delegate_components/direct.rs @@ -3,7 +3,7 @@ use cgp_macro_test_util::snapshot_delegate_components; use insta::assert_snapshot; snapshot_delegate_components! { - { + delegate_components! { new FooComponents { Index<0>: u64, Index<1>: String, @@ -34,7 +34,7 @@ snapshot_delegate_components! { } snapshot_delegate_components! { - { + delegate_components! { new BarComponents { Index<0>: FooComponents, diff --git a/crates/tests/cgp-tests/tests/component_tests/delegate_components/general.rs b/crates/tests/cgp-tests/tests/component_tests/delegate_components/general.rs index 26a1abad..2a8dc554 100644 --- a/crates/tests/cgp-tests/tests/component_tests/delegate_components/general.rs +++ b/crates/tests/cgp-tests/tests/component_tests/delegate_components/general.rs @@ -14,7 +14,7 @@ mod test_basic_delegate_components { pub struct Components; snapshot_delegate_components! { - { + delegate_components! { Components { FooKey: FooValue, [ @@ -81,7 +81,7 @@ mod test_generic_delegate_components { pub struct Components; snapshot_delegate_components! { - { + delegate_components! { <'a, T1: Clone> Components { FooKey: FooValue, From c178e42eb888e15ebe3ca598f206f55c32120f07 Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Thu, 18 Jun 2026 23:13:53 +0200 Subject: [PATCH 14/31] Add back snapshot_cgp_component --- .../src/entrypoints/mod.rs | 2 + .../src/entrypoints/snapshot_cgp_component.rs | 13 +++++ .../src/types/cgp_component.rs | 49 +++++++++++++++++++ .../src/types/delegate_components.rs | 5 +- .../cgp-macro-test-util-lib/src/types/mod.rs | 2 + crates/macros/cgp-macro-test-util/src/lib.rs | 18 +++---- 6 files changed, 75 insertions(+), 14 deletions(-) create mode 100644 crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_component.rs create mode 100644 crates/macros/cgp-macro-test-util-lib/src/types/cgp_component.rs diff --git a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/mod.rs b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/mod.rs index a6c07a15..9c35ef2f 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/mod.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/mod.rs @@ -1,3 +1,5 @@ +mod snapshot_cgp_component; mod snapshot_delegate_components; +pub use snapshot_cgp_component::*; pub use snapshot_delegate_components::*; diff --git a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_component.rs b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_component.rs new file mode 100644 index 00000000..6381e20a --- /dev/null +++ b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_component.rs @@ -0,0 +1,13 @@ +use proc_macro2::TokenStream; +use quote::ToTokens; +use syn::parse2; + +use crate::types::SnapshotCgpComponent; + +pub fn snapshot_cgp_component(body: TokenStream) -> syn::Result { + let item: SnapshotCgpComponent = parse2(body)?; + + let output = cgp_macro_lib::cgp_component(item.attr, item.body.to_token_stream())?; + + Ok(item.snapshot.wrap_output(output)) +} diff --git a/crates/macros/cgp-macro-test-util-lib/src/types/cgp_component.rs b/crates/macros/cgp-macro-test-util-lib/src/types/cgp_component.rs new file mode 100644 index 00000000..b0ef707b --- /dev/null +++ b/crates/macros/cgp-macro-test-util-lib/src/types/cgp_component.rs @@ -0,0 +1,49 @@ +use cgp_macro_core::define_keyword; +use cgp_macro_core::types::keyword::Keyword; +use proc_macro2::TokenStream; +use syn::parse::{Parse, ParseStream}; +use syn::token::{Paren, Pound}; +use syn::{ItemTrait, braced, bracketed, parenthesized}; + +use crate::types::MacroSnapshot; + +define_keyword!(CgpComponent, "cgp_component"); + +pub struct SnapshotCgpComponent { + pub attr: TokenStream, + pub body: ItemTrait, + pub snapshot: MacroSnapshot, +} + +impl Parse for SnapshotCgpComponent { + fn parse(input: ParseStream) -> syn::Result { + let _: Pound = input.parse()?; + + let attr = { + let outer_body; + bracketed!(outer_body in input); + + let _: Keyword = outer_body.parse()?; + + if input.peek(Paren) { + let inner_body; + parenthesized!(inner_body in outer_body); + input.parse()? + } else { + let inner_body; + braced!(inner_body in outer_body); + input.parse()? + } + }; + + let body = input.parse()?; + + let snapshot = input.parse()?; + + Ok(Self { + attr, + body, + snapshot, + }) + } +} diff --git a/crates/macros/cgp-macro-test-util-lib/src/types/delegate_components.rs b/crates/macros/cgp-macro-test-util-lib/src/types/delegate_components.rs index bcba57a6..f2efe94d 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/types/delegate_components.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/types/delegate_components.rs @@ -1,8 +1,9 @@ use cgp_macro_core::define_keyword; use cgp_macro_core::types::keyword::Keyword; use proc_macro2::TokenStream; +use syn::braced; use syn::parse::{Parse, ParseStream}; -use syn::{Token, braced}; +use syn::token::Not; use crate::types::MacroSnapshot; @@ -16,7 +17,7 @@ pub struct AssertDelegateComponents { impl Parse for AssertDelegateComponents { fn parse(input: ParseStream) -> syn::Result { let _: Keyword = input.parse()?; - let _: Token![!] = input.parse()?; + let _: Not = input.parse()?; let body = { let body; diff --git a/crates/macros/cgp-macro-test-util-lib/src/types/mod.rs b/crates/macros/cgp-macro-test-util-lib/src/types/mod.rs index 7176e1b6..528dd977 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/types/mod.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/types/mod.rs @@ -1,5 +1,7 @@ +mod cgp_component; mod delegate_components; mod snapshot; +pub use cgp_component::*; pub use delegate_components::*; pub use snapshot::*; diff --git a/crates/macros/cgp-macro-test-util/src/lib.rs b/crates/macros/cgp-macro-test-util/src/lib.rs index 7d45a1a4..92233882 100644 --- a/crates/macros/cgp-macro-test-util/src/lib.rs +++ b/crates/macros/cgp-macro-test-util/src/lib.rs @@ -8,15 +8,9 @@ pub fn snapshot_delegate_components(body: TokenStream) -> TokenStream { .into() } -// #[proc_macro] -// pub fn snapshot_cgp_component(body: TokenStream) -> TokenStream { -// let snapshot: MacroSnapshot = parse2(body.into()).unwrap(); - -// let output = cgp_macro_lib::cgp_component( -// snapshot.attrs.clone().unwrap().into(), -// snapshot.body.clone(), -// ) -// .unwrap(); - -// snapshot.wrap_output(output).into() -// } +#[proc_macro] +pub fn snapshot_cgp_component(body: TokenStream) -> TokenStream { + entrypoints::snapshot_cgp_component(body.into()) + .unwrap_or_else(syn::Error::into_compile_error) + .into() +} From 3cddce6ff169d075ab937c51a9b615a7a83f0f05 Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Thu, 18 Jun 2026 23:26:48 +0200 Subject: [PATCH 15/31] Snapshot cgp_component is now working --- .../src/types/cgp_component.rs | 7 +- .../cgp_component/default_impl.rs | 94 +++++++++++++++- .../component_tests/cgp_component/lifetime.rs | 104 +++++++++++++++++- 3 files changed, 195 insertions(+), 10 deletions(-) diff --git a/crates/macros/cgp-macro-test-util-lib/src/types/cgp_component.rs b/crates/macros/cgp-macro-test-util-lib/src/types/cgp_component.rs index b0ef707b..4f90d942 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/types/cgp_component.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/types/cgp_component.rs @@ -25,16 +25,17 @@ impl Parse for SnapshotCgpComponent { let _: Keyword = outer_body.parse()?; - if input.peek(Paren) { + if outer_body.peek(Paren) { let inner_body; parenthesized!(inner_body in outer_body); - input.parse()? + inner_body.parse()? } else { let inner_body; braced!(inner_body in outer_body); - input.parse()? + inner_body.parse()? } }; + // let attr = TokenStream::new(); let body = input.parse()?; diff --git a/crates/tests/cgp-tests/tests/component_tests/cgp_component/default_impl.rs b/crates/tests/cgp-tests/tests/component_tests/cgp_component/default_impl.rs index 0410f390..a5498f37 100644 --- a/crates/tests/cgp-tests/tests/component_tests/cgp_component/default_impl.rs +++ b/crates/tests/cgp-tests/tests/component_tests/cgp_component/default_impl.rs @@ -1,4 +1,6 @@ use cgp::prelude::*; +use cgp_macro_test_util::snapshot_cgp_component; +use insta::assert_snapshot; #[cgp_getter] pub trait HasName { @@ -7,10 +9,94 @@ pub trait HasName { } } -#[cgp_component(Greeter)] -pub trait CanGreet: HasName { - fn greet(&self) -> String { - format!("Hello, {}!", self.name()) +snapshot_cgp_component! { + #[cgp_component(Greeter)] + pub trait CanGreet: HasName { + fn greet(&self) -> String { + format!("Hello, {}!", self.name()) + } + } + + expand_can_greet(output) { + assert_snapshot!(output, @r#" + pub trait CanGreet: HasName { + fn greet(&self) -> String { + format!("Hello, {}!", self.name()) + } + } + impl<__Context__> CanGreet for __Context__ + where + __Context__: HasName, + __Context__: Greeter<__Context__>, + { + fn greet(&self) -> String { + __Context__::greet(self) + } + } + pub trait Greeter<__Context__>: IsProviderFor + where + __Context__: HasName, + { + fn greet(__context__: &__Context__) -> String { + format!("Hello, {}!", __context__.name()) + } + } + impl<__Provider__, __Context__> Greeter<__Context__> for __Provider__ + where + __Context__: HasName, + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + GreeterComponent, + >>::Delegate: Greeter<__Context__>, + { + fn greet(__context__: &__Context__) -> String { + <__Provider__ as DelegateComponent< + GreeterComponent, + >>::Delegate::greet(__context__) + } + } + pub struct GreeterComponent; + impl<__Context__> Greeter<__Context__> for UseContext + where + __Context__: HasName, + __Context__: CanGreet, + { + fn greet(__context__: &__Context__) -> String { + __Context__::greet(__context__) + } + } + impl<__Context__> IsProviderFor for UseContext + where + __Context__: HasName, + __Context__: CanGreet, + {} + impl<__Context__, __Components__, __Path__> Greeter<__Context__> + for RedirectLookup<__Components__, __Path__> + where + __Context__: HasName, + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent<__Path__>>::Delegate: Greeter<__Context__>, + { + fn greet(__context__: &__Context__) -> String { + <__Components__ as DelegateComponent<__Path__>>::Delegate::greet(__context__) + } + } + impl< + __Context__, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Context__: HasName, + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: IsProviderFor + + Greeter<__Context__>, + {} + "#) } } diff --git a/crates/tests/cgp-tests/tests/component_tests/cgp_component/lifetime.rs b/crates/tests/cgp-tests/tests/component_tests/cgp_component/lifetime.rs index af0e4439..fdb6bee3 100644 --- a/crates/tests/cgp-tests/tests/component_tests/cgp_component/lifetime.rs +++ b/crates/tests/cgp-tests/tests/component_tests/cgp_component/lifetime.rs @@ -1,8 +1,106 @@ use cgp::prelude::*; +use cgp_macro_test_util::snapshot_cgp_component; +use insta::assert_snapshot; -#[cgp_component(ReferenceGetter)] -pub trait HasReference<'a, T: 'a + ?Sized> { - fn get_reference(&self) -> &'a T; +snapshot_cgp_component! { + #[cgp_component(ReferenceGetter)] + pub trait HasReference<'a, T: 'a + ?Sized> { + fn get_reference(&self) -> &'a T; + } + + expand_can_greet(output) { + assert_snapshot!(output, @" + pub trait HasReference<'a, T: 'a + ?Sized> { + fn get_reference(&self) -> &'a T; + } + impl<'a, __Context__, T: 'a + ?Sized> HasReference<'a, T> for __Context__ + where + __Context__: ReferenceGetter<'a, __Context__, T>, + { + fn get_reference(&self) -> &'a T { + __Context__::get_reference(self) + } + } + pub trait ReferenceGetter< + 'a, + __Context__, + T: 'a + ?Sized, + >: IsProviderFor, T)> { + fn get_reference(__context__: &__Context__) -> &'a T; + } + impl<'a, __Provider__, __Context__, T: 'a + ?Sized> ReferenceGetter<'a, __Context__, T> + for __Provider__ + where + __Provider__: DelegateComponent + + IsProviderFor, T)>, + <__Provider__ as DelegateComponent< + ReferenceGetterComponent, + >>::Delegate: ReferenceGetter<'a, __Context__, T>, + { + fn get_reference(__context__: &__Context__) -> &'a T { + <__Provider__ as DelegateComponent< + ReferenceGetterComponent, + >>::Delegate::get_reference(__context__) + } + } + pub struct ReferenceGetterComponent; + impl<'a, __Context__, T: 'a + ?Sized> ReferenceGetter<'a, __Context__, T> for UseContext + where + __Context__: HasReference<'a, T>, + { + fn get_reference(__context__: &__Context__) -> &'a T { + __Context__::get_reference(__context__) + } + } + impl< + 'a, + __Context__, + T: 'a + ?Sized, + > IsProviderFor, T)> for UseContext + where + __Context__: HasReference<'a, T>, + {} + impl< + 'a, + __Context__, + T: 'a + ?Sized, + __Components__, + __Path__, + > ReferenceGetter<'a, __Context__, T> for RedirectLookup<__Components__, __Path__> + where + __Path__: ConcatPath>, + __Components__: DelegateComponent< + <__Path__ as ConcatPath>>::Output, + >, + <__Components__ as DelegateComponent< + <__Path__ as ConcatPath>>::Output, + >>::Delegate: ReferenceGetter<'a, __Context__, T>, + { + fn get_reference(__context__: &__Context__) -> &'a T { + <__Components__ as DelegateComponent< + <__Path__ as ConcatPath>>::Output, + >>::Delegate::get_reference(__context__) + } + } + impl< + 'a, + __Context__, + T: 'a + ?Sized, + __Components__, + __Path__, + > IsProviderFor, T)> + for RedirectLookup<__Components__, __Path__> + where + __Path__: ConcatPath>, + __Components__: DelegateComponent< + <__Path__ as ConcatPath>>::Output, + >, + <__Components__ as DelegateComponent< + <__Path__ as ConcatPath>>::Output, + >>::Delegate: ReferenceGetter<'a, __Context__, T>, + {} + ") + } } #[cgp_provider] From 96f6903d20764d58796d86ff6c44ed451b8edb3f Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Fri, 19 Jun 2026 20:43:53 +0200 Subject: [PATCH 16/31] Format output as string inside macro --- Cargo.lock | 2 -- .../src/entrypoints/snapshot_cgp_component.rs | 2 +- .../snapshot_delegate_components.rs | 2 +- .../src/types/snapshot.rs | 19 ++++++++++++------- crates/tests/cgp-tests/Cargo.toml | 2 -- 5 files changed, 14 insertions(+), 13 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 304573fa..2a0207c4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -252,11 +252,9 @@ name = "cgp-tests" version = "0.7.0" dependencies = [ "cgp", - "cgp-macro-core", "cgp-macro-test-util", "futures", "insta", - "quote", ] [[package]] diff --git a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_component.rs b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_component.rs index 6381e20a..1ccd3f9c 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_component.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_component.rs @@ -9,5 +9,5 @@ pub fn snapshot_cgp_component(body: TokenStream) -> syn::Result { let output = cgp_macro_lib::cgp_component(item.attr, item.body.to_token_stream())?; - Ok(item.snapshot.wrap_output(output)) + item.snapshot.wrap_output(output) } diff --git a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_delegate_components.rs b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_delegate_components.rs index acbd25c2..eee7be95 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_delegate_components.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_delegate_components.rs @@ -8,5 +8,5 @@ pub fn snapshot_delegate_components(body: TokenStream) -> syn::Result TokenStream { + pub fn wrap_output(&self, output: TokenStream) -> syn::Result { let Self { test_name, arg_ident, expr, } = self; - quote! { + let output_string = pretty_format(output.clone())?; + let output_literal = LitStr::new(&output_string, output.span()); + + let out = quote! { #output #[test] fn #test_name() { - let #arg_ident = cgp_macro_core::functions::pretty_format(quote::quote! { - #output - }).unwrap(); + let #arg_ident = #output_literal; #expr } - } + }; + + Ok(out) } } diff --git a/crates/tests/cgp-tests/Cargo.toml b/crates/tests/cgp-tests/Cargo.toml index 2b9fa727..1575c261 100644 --- a/crates/tests/cgp-tests/Cargo.toml +++ b/crates/tests/cgp-tests/Cargo.toml @@ -10,8 +10,6 @@ keywords = { workspace = true } [dependencies] cgp = { workspace = true } -cgp-macro-core = { workspace = true } cgp-macro-test-util = { workspace = true } insta = { version = "1.48.0" } -quote = { version = "1.0.38" } futures = { version = "0.3.31" } From 7130ee5a6136c93b2db980451440fefed69d6f38 Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Fri, 19 Jun 2026 20:49:08 +0200 Subject: [PATCH 17/31] Implement `snapshot_cgp_impl!` --- .../src/entrypoints/mod.rs | 2 + .../src/entrypoints/snapshot_cgp_impl.rs | 13 +++ .../src/types/cgp_impl.rs | 50 +++++++++ .../cgp-macro-test-util-lib/src/types/mod.rs | 2 + crates/macros/cgp-macro-test-util/src/lib.rs | 7 ++ .../tests/component_tests/cgp_impl/basic.rs | 105 ++++++++++++++++-- 6 files changed, 172 insertions(+), 7 deletions(-) create mode 100644 crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_impl.rs create mode 100644 crates/macros/cgp-macro-test-util-lib/src/types/cgp_impl.rs diff --git a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/mod.rs b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/mod.rs index 9c35ef2f..c7e21714 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/mod.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/mod.rs @@ -1,5 +1,7 @@ mod snapshot_cgp_component; +mod snapshot_cgp_impl; mod snapshot_delegate_components; pub use snapshot_cgp_component::*; +pub use snapshot_cgp_impl::*; pub use snapshot_delegate_components::*; diff --git a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_impl.rs b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_impl.rs new file mode 100644 index 00000000..46812a57 --- /dev/null +++ b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_impl.rs @@ -0,0 +1,13 @@ +use proc_macro2::TokenStream; +use quote::ToTokens; +use syn::parse2; + +use crate::types::SnapshotCgpImpl; + +pub fn snapshot_cgp_impl(body: TokenStream) -> syn::Result { + let item: SnapshotCgpImpl = parse2(body)?; + + let output = cgp_macro_lib::cgp_impl(item.attr, item.body.to_token_stream())?; + + item.snapshot.wrap_output(output) +} diff --git a/crates/macros/cgp-macro-test-util-lib/src/types/cgp_impl.rs b/crates/macros/cgp-macro-test-util-lib/src/types/cgp_impl.rs new file mode 100644 index 00000000..127721e2 --- /dev/null +++ b/crates/macros/cgp-macro-test-util-lib/src/types/cgp_impl.rs @@ -0,0 +1,50 @@ +use cgp_macro_core::define_keyword; +use cgp_macro_core::types::keyword::Keyword; +use proc_macro2::TokenStream; +use syn::parse::{Parse, ParseStream}; +use syn::token::{Paren, Pound}; +use syn::{ItemImpl, braced, bracketed, parenthesized}; + +use crate::types::MacroSnapshot; + +define_keyword!(CgpImpl, "cgp_impl"); + +pub struct SnapshotCgpImpl { + pub attr: TokenStream, + pub body: ItemImpl, + pub snapshot: MacroSnapshot, +} + +impl Parse for SnapshotCgpImpl { + fn parse(input: ParseStream) -> syn::Result { + let _: Pound = input.parse()?; + + let attr = { + let outer_body; + bracketed!(outer_body in input); + + let _: Keyword = outer_body.parse()?; + + if outer_body.peek(Paren) { + let inner_body; + parenthesized!(inner_body in outer_body); + inner_body.parse()? + } else { + let inner_body; + braced!(inner_body in outer_body); + inner_body.parse()? + } + }; + // let attr = TokenStream::new(); + + let body = input.parse()?; + + let snapshot = input.parse()?; + + Ok(Self { + attr, + body, + snapshot, + }) + } +} diff --git a/crates/macros/cgp-macro-test-util-lib/src/types/mod.rs b/crates/macros/cgp-macro-test-util-lib/src/types/mod.rs index 528dd977..a26e7e7b 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/types/mod.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/types/mod.rs @@ -1,7 +1,9 @@ mod cgp_component; +mod cgp_impl; mod delegate_components; mod snapshot; pub use cgp_component::*; +pub use cgp_impl::*; pub use delegate_components::*; pub use snapshot::*; diff --git a/crates/macros/cgp-macro-test-util/src/lib.rs b/crates/macros/cgp-macro-test-util/src/lib.rs index 92233882..01419c61 100644 --- a/crates/macros/cgp-macro-test-util/src/lib.rs +++ b/crates/macros/cgp-macro-test-util/src/lib.rs @@ -14,3 +14,10 @@ pub fn snapshot_cgp_component(body: TokenStream) -> TokenStream { .unwrap_or_else(syn::Error::into_compile_error) .into() } + +#[proc_macro] +pub fn snapshot_cgp_impl(body: TokenStream) -> TokenStream { + entrypoints::snapshot_cgp_impl(body.into()) + .unwrap_or_else(syn::Error::into_compile_error) + .into() +} diff --git a/crates/tests/cgp-tests/tests/component_tests/cgp_impl/basic.rs b/crates/tests/cgp-tests/tests/component_tests/cgp_impl/basic.rs index b4cfc13f..2051c864 100644 --- a/crates/tests/cgp-tests/tests/component_tests/cgp_impl/basic.rs +++ b/crates/tests/cgp-tests/tests/component_tests/cgp_impl/basic.rs @@ -1,8 +1,85 @@ use cgp::prelude::*; +use cgp_macro_test_util::{snapshot_cgp_component, snapshot_cgp_impl}; +use insta::assert_snapshot; -#[cgp_component(FooProvider)] -pub trait CanDoFoo { - fn foo(&self, value: u32) -> String; +snapshot_cgp_component! { + #[cgp_component(FooProvider)] + pub trait CanDoFoo { + fn foo(&self, value: u32) -> String; + } + + expand_foo_component(output) { + assert_snapshot!(output, @" + pub trait CanDoFoo { + fn foo(&self, value: u32) -> String; + } + impl<__Context__> CanDoFoo for __Context__ + where + __Context__: FooProvider<__Context__>, + { + fn foo(&self, value: u32) -> String { + __Context__::foo(self, value) + } + } + pub trait FooProvider< + __Context__, + >: IsProviderFor { + fn foo(__context__: &__Context__, value: u32) -> String; + } + impl<__Provider__, __Context__> FooProvider<__Context__> for __Provider__ + where + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + FooProviderComponent, + >>::Delegate: FooProvider<__Context__>, + { + fn foo(__context__: &__Context__, value: u32) -> String { + <__Provider__ as DelegateComponent< + FooProviderComponent, + >>::Delegate::foo(__context__, value) + } + } + pub struct FooProviderComponent; + impl<__Context__> FooProvider<__Context__> for UseContext + where + __Context__: CanDoFoo, + { + fn foo(__context__: &__Context__, value: u32) -> String { + __Context__::foo(__context__, value) + } + } + impl<__Context__> IsProviderFor for UseContext + where + __Context__: CanDoFoo, + {} + impl<__Context__, __Components__, __Path__> FooProvider<__Context__> + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent<__Path__>>::Delegate: FooProvider<__Context__>, + { + fn foo(__context__: &__Context__, value: u32) -> String { + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate::foo(__context__, value) + } + } + impl< + __Context__, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: IsProviderFor + + FooProvider<__Context__>, + {} + ") + } } #[cgp_auto_getter] @@ -10,10 +87,24 @@ pub trait HasName { fn name(&self) -> &str; } -#[cgp_impl(new ValueToString)] -impl FooProvider for Context { - fn foo(&self, value: u32) -> String { - value.to_string() +snapshot_cgp_impl! { + #[cgp_impl(new ValueToString)] + impl FooProvider for Context { + fn foo(&self, value: u32) -> String { + value.to_string() + } + } + + expand_value_to_string(output) { + assert_snapshot!(output, @" + impl FooProvider for ValueToString { + fn foo(__context__: &Context, value: u32) -> String { + value.to_string() + } + } + impl IsProviderFor for ValueToString {} + pub struct ValueToString; + ") } } From 499a75f701a7e107f5ae193e36c4b192dbe65cce Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Fri, 19 Jun 2026 21:00:10 +0200 Subject: [PATCH 18/31] Implement `snapshot_cgp_auto_getter!` --- .../src/entrypoints/mod.rs | 2 ++ .../entrypoints/snapshot_cgp_auto_getter.rs | 13 +++++++ .../src/functions/mod.rs | 3 ++ .../src/functions/parse_attribute.rs | 31 ++++++++++++++++ .../macros/cgp-macro-test-util-lib/src/lib.rs | 1 + .../src/types/cgp_auto_getter.rs | 31 ++++++++++++++++ .../src/types/cgp_component.rs | 27 +++----------- .../src/types/cgp_impl.rs | 27 +++----------- .../cgp-macro-test-util-lib/src/types/mod.rs | 2 ++ crates/macros/cgp-macro-test-util/src/lib.rs | 7 ++++ .../tests/component_tests/cgp_impl/basic.rs | 35 ++++++++++++++++--- 11 files changed, 128 insertions(+), 51 deletions(-) create mode 100644 crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_auto_getter.rs create mode 100644 crates/macros/cgp-macro-test-util-lib/src/functions/mod.rs create mode 100644 crates/macros/cgp-macro-test-util-lib/src/functions/parse_attribute.rs create mode 100644 crates/macros/cgp-macro-test-util-lib/src/types/cgp_auto_getter.rs diff --git a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/mod.rs b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/mod.rs index c7e21714..a7ae1fe5 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/mod.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/mod.rs @@ -1,7 +1,9 @@ +mod snapshot_cgp_auto_getter; mod snapshot_cgp_component; mod snapshot_cgp_impl; mod snapshot_delegate_components; +pub use snapshot_cgp_auto_getter::*; pub use snapshot_cgp_component::*; pub use snapshot_cgp_impl::*; pub use snapshot_delegate_components::*; diff --git a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_auto_getter.rs b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_auto_getter.rs new file mode 100644 index 00000000..c626ec9b --- /dev/null +++ b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_auto_getter.rs @@ -0,0 +1,13 @@ +use proc_macro2::TokenStream; +use quote::ToTokens; +use syn::parse2; + +use crate::types::SnapshotCgpAutoGetter; + +pub fn snapshot_cgp_auto_getter(body: TokenStream) -> syn::Result { + let item: SnapshotCgpAutoGetter = parse2(body)?; + + let output = cgp_macro_lib::cgp_auto_getter(item.attr, item.body.to_token_stream())?; + + item.snapshot.wrap_output(output) +} diff --git a/crates/macros/cgp-macro-test-util-lib/src/functions/mod.rs b/crates/macros/cgp-macro-test-util-lib/src/functions/mod.rs new file mode 100644 index 00000000..02ca84e9 --- /dev/null +++ b/crates/macros/cgp-macro-test-util-lib/src/functions/mod.rs @@ -0,0 +1,3 @@ +mod parse_attribute; + +pub use parse_attribute::*; diff --git a/crates/macros/cgp-macro-test-util-lib/src/functions/parse_attribute.rs b/crates/macros/cgp-macro-test-util-lib/src/functions/parse_attribute.rs new file mode 100644 index 00000000..b17019b4 --- /dev/null +++ b/crates/macros/cgp-macro-test-util-lib/src/functions/parse_attribute.rs @@ -0,0 +1,31 @@ +use proc_macro2::TokenStream; +use syn::parse::ParseStream; +use syn::token::Paren; +use syn::{Error, Ident, braced, bracketed, parenthesized}; + +pub fn parse_attribute(expected_keyword: &str, input: ParseStream) -> syn::Result { + let outer_body; + bracketed!(outer_body in input); + + let keyword: Ident = outer_body.parse()?; + if keyword != expected_keyword { + return Err(Error::new( + keyword.span(), + format!("expect attribute with keyword {expected_keyword}, but got {keyword}"), + )); + } + + let body = if outer_body.is_empty() { + TokenStream::new() + } else if outer_body.peek(Paren) { + let inner_body; + parenthesized!(inner_body in outer_body); + inner_body.parse()? + } else { + let inner_body; + braced!(inner_body in outer_body); + inner_body.parse()? + }; + + Ok(body) +} diff --git a/crates/macros/cgp-macro-test-util-lib/src/lib.rs b/crates/macros/cgp-macro-test-util-lib/src/lib.rs index d767f807..632e4687 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/lib.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/lib.rs @@ -1,2 +1,3 @@ pub mod entrypoints; +pub mod functions; pub mod types; diff --git a/crates/macros/cgp-macro-test-util-lib/src/types/cgp_auto_getter.rs b/crates/macros/cgp-macro-test-util-lib/src/types/cgp_auto_getter.rs new file mode 100644 index 00000000..f73bd2a2 --- /dev/null +++ b/crates/macros/cgp-macro-test-util-lib/src/types/cgp_auto_getter.rs @@ -0,0 +1,31 @@ +use proc_macro2::TokenStream; +use syn::ItemTrait; +use syn::parse::{Parse, ParseStream}; +use syn::token::Pound; + +use crate::functions::parse_attribute; +use crate::types::MacroSnapshot; + +pub struct SnapshotCgpAutoGetter { + pub attr: TokenStream, + pub body: ItemTrait, + pub snapshot: MacroSnapshot, +} + +impl Parse for SnapshotCgpAutoGetter { + fn parse(input: ParseStream) -> syn::Result { + let _: Pound = input.parse()?; + + let attr = parse_attribute("cgp_auto_getter", input)?; + + let body = input.parse()?; + + let snapshot = input.parse()?; + + Ok(Self { + attr, + body, + snapshot, + }) + } +} diff --git a/crates/macros/cgp-macro-test-util-lib/src/types/cgp_component.rs b/crates/macros/cgp-macro-test-util-lib/src/types/cgp_component.rs index 4f90d942..522d641f 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/types/cgp_component.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/types/cgp_component.rs @@ -1,14 +1,11 @@ -use cgp_macro_core::define_keyword; -use cgp_macro_core::types::keyword::Keyword; use proc_macro2::TokenStream; +use syn::ItemTrait; use syn::parse::{Parse, ParseStream}; -use syn::token::{Paren, Pound}; -use syn::{ItemTrait, braced, bracketed, parenthesized}; +use syn::token::Pound; +use crate::functions::parse_attribute; use crate::types::MacroSnapshot; -define_keyword!(CgpComponent, "cgp_component"); - pub struct SnapshotCgpComponent { pub attr: TokenStream, pub body: ItemTrait, @@ -19,23 +16,7 @@ impl Parse for SnapshotCgpComponent { fn parse(input: ParseStream) -> syn::Result { let _: Pound = input.parse()?; - let attr = { - let outer_body; - bracketed!(outer_body in input); - - let _: Keyword = outer_body.parse()?; - - if outer_body.peek(Paren) { - let inner_body; - parenthesized!(inner_body in outer_body); - inner_body.parse()? - } else { - let inner_body; - braced!(inner_body in outer_body); - inner_body.parse()? - } - }; - // let attr = TokenStream::new(); + let attr = parse_attribute("cgp_component", input)?; let body = input.parse()?; diff --git a/crates/macros/cgp-macro-test-util-lib/src/types/cgp_impl.rs b/crates/macros/cgp-macro-test-util-lib/src/types/cgp_impl.rs index 127721e2..22b19922 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/types/cgp_impl.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/types/cgp_impl.rs @@ -1,14 +1,11 @@ -use cgp_macro_core::define_keyword; -use cgp_macro_core::types::keyword::Keyword; use proc_macro2::TokenStream; +use syn::ItemImpl; use syn::parse::{Parse, ParseStream}; -use syn::token::{Paren, Pound}; -use syn::{ItemImpl, braced, bracketed, parenthesized}; +use syn::token::Pound; +use crate::functions::parse_attribute; use crate::types::MacroSnapshot; -define_keyword!(CgpImpl, "cgp_impl"); - pub struct SnapshotCgpImpl { pub attr: TokenStream, pub body: ItemImpl, @@ -19,23 +16,7 @@ impl Parse for SnapshotCgpImpl { fn parse(input: ParseStream) -> syn::Result { let _: Pound = input.parse()?; - let attr = { - let outer_body; - bracketed!(outer_body in input); - - let _: Keyword = outer_body.parse()?; - - if outer_body.peek(Paren) { - let inner_body; - parenthesized!(inner_body in outer_body); - inner_body.parse()? - } else { - let inner_body; - braced!(inner_body in outer_body); - inner_body.parse()? - } - }; - // let attr = TokenStream::new(); + let attr = parse_attribute("cgp_impl", input)?; let body = input.parse()?; diff --git a/crates/macros/cgp-macro-test-util-lib/src/types/mod.rs b/crates/macros/cgp-macro-test-util-lib/src/types/mod.rs index a26e7e7b..ed813168 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/types/mod.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/types/mod.rs @@ -1,8 +1,10 @@ +mod cgp_auto_getter; mod cgp_component; mod cgp_impl; mod delegate_components; mod snapshot; +pub use cgp_auto_getter::*; pub use cgp_component::*; pub use cgp_impl::*; pub use delegate_components::*; diff --git a/crates/macros/cgp-macro-test-util/src/lib.rs b/crates/macros/cgp-macro-test-util/src/lib.rs index 01419c61..32ec8a68 100644 --- a/crates/macros/cgp-macro-test-util/src/lib.rs +++ b/crates/macros/cgp-macro-test-util/src/lib.rs @@ -21,3 +21,10 @@ pub fn snapshot_cgp_impl(body: TokenStream) -> TokenStream { .unwrap_or_else(syn::Error::into_compile_error) .into() } + +#[proc_macro] +pub fn snapshot_cgp_auto_getter(body: TokenStream) -> TokenStream { + entrypoints::snapshot_cgp_auto_getter(body.into()) + .unwrap_or_else(syn::Error::into_compile_error) + .into() +} diff --git a/crates/tests/cgp-tests/tests/component_tests/cgp_impl/basic.rs b/crates/tests/cgp-tests/tests/component_tests/cgp_impl/basic.rs index 2051c864..c8b78887 100644 --- a/crates/tests/cgp-tests/tests/component_tests/cgp_impl/basic.rs +++ b/crates/tests/cgp-tests/tests/component_tests/cgp_impl/basic.rs @@ -1,5 +1,4 @@ -use cgp::prelude::*; -use cgp_macro_test_util::{snapshot_cgp_component, snapshot_cgp_impl}; +use cgp_macro_test_util::{snapshot_cgp_auto_getter, snapshot_cgp_component, snapshot_cgp_impl}; use insta::assert_snapshot; snapshot_cgp_component! { @@ -82,9 +81,35 @@ snapshot_cgp_component! { } } -#[cgp_auto_getter] -pub trait HasName { - fn name(&self) -> &str; +snapshot_cgp_auto_getter! { + #[cgp_auto_getter] + pub trait HasName { + fn name(&self) -> &str; + } + + expand_has_name(output) { + assert_snapshot!(output, @" + pub trait HasName { + fn name(&self) -> &str; + } + impl<__Context__> HasName for __Context__ + where + __Context__: HasField< + Symbol<4, Chars<'n', Chars<'a', Chars<'m', Chars<'e', Nil>>>>>, + Value = String, + >, + { + fn name(&self) -> &str { + self.get_field( + ::core::marker::PhantomData::< + Symbol<4, Chars<'n', Chars<'a', Chars<'m', Chars<'e', Nil>>>>>, + >, + ) + .as_str() + } + } + ") + } } snapshot_cgp_impl! { From 38414029e5194f268e9a74ffe6eaab5c5363307c Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Fri, 19 Jun 2026 21:01:46 +0200 Subject: [PATCH 19/31] Move pretty_format to test-util-lib --- Cargo.lock | 2 +- crates/macros/cgp-macro-core/Cargo.toml | 1 - crates/macros/cgp-macro-core/src/functions/mod.rs | 2 -- crates/macros/cgp-macro-test-util-lib/Cargo.toml | 1 + crates/macros/cgp-macro-test-util-lib/src/functions/mod.rs | 2 ++ .../src/functions/pretty_format.rs} | 3 +-- crates/macros/cgp-macro-test-util-lib/src/types/snapshot.rs | 3 ++- 7 files changed, 7 insertions(+), 7 deletions(-) rename crates/macros/{cgp-macro-core/src/functions/format.rs => cgp-macro-test-util-lib/src/functions/pretty_format.rs} (82%) diff --git a/Cargo.lock b/Cargo.lock index 2a0207c4..843ce2ff 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -185,7 +185,6 @@ name = "cgp-macro-core" version = "0.7.0" dependencies = [ "itertools", - "prettyplease", "proc-macro2", "quote", "syn", @@ -220,6 +219,7 @@ version = "0.7.0" dependencies = [ "cgp-macro-core", "cgp-macro-lib", + "prettyplease", "proc-macro2", "quote", "syn", diff --git a/crates/macros/cgp-macro-core/Cargo.toml b/crates/macros/cgp-macro-core/Cargo.toml index 51bf105f..26246f38 100644 --- a/crates/macros/cgp-macro-core/Cargo.toml +++ b/crates/macros/cgp-macro-core/Cargo.toml @@ -13,4 +13,3 @@ syn = { version = "2.0.95", features = [ "full", "extra-traits", quote = { version = "1.0.38" } proc-macro2 = { version = "1.0.92" } itertools = { version = "0.14.0" } -prettyplease = { version = "0.2.37" } diff --git a/crates/macros/cgp-macro-core/src/functions/mod.rs b/crates/macros/cgp-macro-core/src/functions/mod.rs index fcb91b11..cd188782 100644 --- a/crates/macros/cgp-macro-core/src/functions/mod.rs +++ b/crates/macros/cgp-macro-core/src/functions/mod.rs @@ -1,7 +1,6 @@ mod camel_case; mod delegated_impls; mod field; -mod format; mod generics; mod getter; mod implicits; @@ -13,7 +12,6 @@ mod strip; pub use camel_case::*; pub use delegated_impls::*; pub use field::*; -pub use format::*; pub use generics::*; pub use getter::*; pub use implicits::*; diff --git a/crates/macros/cgp-macro-test-util-lib/Cargo.toml b/crates/macros/cgp-macro-test-util-lib/Cargo.toml index dc347f6b..0d30a888 100644 --- a/crates/macros/cgp-macro-test-util-lib/Cargo.toml +++ b/crates/macros/cgp-macro-test-util-lib/Cargo.toml @@ -15,3 +15,4 @@ cgp-macro-core = { workspace = true } syn = { version = "2.0.95" } quote = { version = "1.0.38" } proc-macro2 = { version = "1.0.92" } +prettyplease = { version = "0.2.37" } diff --git a/crates/macros/cgp-macro-test-util-lib/src/functions/mod.rs b/crates/macros/cgp-macro-test-util-lib/src/functions/mod.rs index 02ca84e9..3721114c 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/functions/mod.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/functions/mod.rs @@ -1,3 +1,5 @@ mod parse_attribute; +mod pretty_format; +pub use pretty_format::*; pub use parse_attribute::*; diff --git a/crates/macros/cgp-macro-core/src/functions/format.rs b/crates/macros/cgp-macro-test-util-lib/src/functions/pretty_format.rs similarity index 82% rename from crates/macros/cgp-macro-core/src/functions/format.rs rename to crates/macros/cgp-macro-test-util-lib/src/functions/pretty_format.rs index a7efd6a8..034c11d1 100644 --- a/crates/macros/cgp-macro-core/src/functions/format.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/functions/pretty_format.rs @@ -1,9 +1,8 @@ +use cgp_macro_core::functions::strip_macro_prelude; use prettyplease::unparse; use proc_macro2::TokenStream; use syn::parse2; -use crate::functions::strip_macro_prelude; - pub fn pretty_format(body: TokenStream) -> syn::Result { let parsed = parse2(strip_macro_prelude(body))?; let formatted = unparse(&parsed); diff --git a/crates/macros/cgp-macro-test-util-lib/src/types/snapshot.rs b/crates/macros/cgp-macro-test-util-lib/src/types/snapshot.rs index 7b1a6bce..0981c916 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/types/snapshot.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/types/snapshot.rs @@ -1,10 +1,11 @@ -use cgp_macro_core::functions::pretty_format; use proc_macro2::TokenStream; use quote::quote; use syn::parse::{Parse, ParseStream}; use syn::spanned::Spanned; use syn::{Ident, LitStr, braced, parenthesized}; +use crate::functions::pretty_format; + pub struct MacroSnapshot { pub test_name: Ident, pub arg_ident: Ident, From 419a89484f9796b51c6e208df6c5fdae9a253564 Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Fri, 19 Jun 2026 21:37:40 +0200 Subject: [PATCH 20/31] AI-migrate tests --- .../src/entrypoints/mod.rs | 2 + .../src/entrypoints/snapshot_cgp_getter.rs | 13 + .../src/types/cgp_getter.rs | 31 + .../cgp-macro-test-util-lib/src/types/mod.rs | 2 + crates/macros/cgp-macro-test-util/README.md | 262 ++++++ crates/macros/cgp-macro-test-util/src/lib.rs | 7 + .../cgp-tests/src/namespaces/default_impls.rs | 184 +++- .../tests/cgp-tests/src/tests/async/spawn.rs | 466 +++++++++- .../cgp-tests/src/tests/check_components.rs | 835 +++++++++++++++++- .../tests/delegate_and_check_components.rs | 316 ++++++- .../cgp-tests/src/tests/has_field/chain.rs | 160 +++- .../src/tests/use_delegate/getter.rs | 409 ++++++++- .../tests/cgp_fn_tests/use_provider.rs | 164 +++- .../extensible_data_tests/records/basic.rs | 27 +- .../extensible_data_tests/variants/basic.rs | 27 +- .../extensible_data_tests/variants/shape.rs | 88 +- .../getter_tests/abstract_type/explicit.rs | 272 +++++- .../getter_tests/abstract_type/import.rs | 240 ++++- .../getter_tests/abstract_type/use_type.rs | 240 ++++- .../getter_tests/assoc_type/auto_getter.rs | 38 +- .../tests/getter_tests/assoc_type/getter.rs | 215 ++++- .../assoc_type/self_referential.rs | 192 +++- .../assoc_type/self_referential_auto.rs | 47 +- .../tests/getter_tests/auto_generics.rs | 33 +- .../cgp-tests/tests/getter_tests/clone.rs | 277 +++++- .../cgp-tests/tests/getter_tests/mref.rs | 221 ++++- .../cgp-tests/tests/getter_tests/non_self.rs | 241 ++++- .../tests/getter_tests/non_self_auto.rs | 95 +- .../cgp-tests/tests/getter_tests/option.rs | 220 ++++- .../cgp-tests/tests/getter_tests/slice.rs | 220 ++++- .../cgp-tests/tests/getter_tests/string.rs | 557 +++++++++++- .../tests/handler_tests/computer_macro.rs | 41 +- .../tests/handler_tests/handler_macro.rs | 41 +- .../cgp-tests/tests/handler_tests/pipe.rs | 170 +++- .../tests/handler_tests/producer_macro.rs | 27 +- .../tests/namespace_tests/multi_param.rs | 323 ++++++- .../tests/namespace_tests/namespace.rs | 252 +++++- .../namespace_tests/namespace_macro/basic.rs | 273 +++++- .../namespace_macro/default_impls.rs | 293 +++++- .../namespace_macro/extended_namespace.rs | 189 +++- .../namespace_macro/multi_namespace.rs | 427 ++++++++- .../namespace_macro/symbol_path.rs | 340 ++++++- .../namespace_macro/type_path.rs | 285 +++++- .../cgp-tests/tests/namespace_tests/open.rs | 409 ++++++++- .../tests/namespace_tests/redirect.rs | 180 +++- .../tests/preset_tests/basic/components.rs | 290 +++++- .../tests/preset_tests/basic/contexts.rs | 23 +- .../tests/preset_tests/generics/components.rs | 324 ++++++- .../generics_inheritance/components.rs | 350 +++++++- .../tests/preset_tests/wrapped/context.rs | 47 +- 50 files changed, 9668 insertions(+), 717 deletions(-) create mode 100644 crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_getter.rs create mode 100644 crates/macros/cgp-macro-test-util-lib/src/types/cgp_getter.rs create mode 100644 crates/macros/cgp-macro-test-util/README.md diff --git a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/mod.rs b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/mod.rs index a7ae1fe5..8041c71d 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/mod.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/mod.rs @@ -1,9 +1,11 @@ mod snapshot_cgp_auto_getter; mod snapshot_cgp_component; +mod snapshot_cgp_getter; mod snapshot_cgp_impl; mod snapshot_delegate_components; pub use snapshot_cgp_auto_getter::*; pub use snapshot_cgp_component::*; +pub use snapshot_cgp_getter::*; pub use snapshot_cgp_impl::*; pub use snapshot_delegate_components::*; diff --git a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_getter.rs b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_getter.rs new file mode 100644 index 00000000..e17951f4 --- /dev/null +++ b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_getter.rs @@ -0,0 +1,13 @@ +use proc_macro2::TokenStream; +use quote::ToTokens; +use syn::parse2; + +use crate::types::SnapshotCgpGetter; + +pub fn snapshot_cgp_getter(body: TokenStream) -> syn::Result { + let item: SnapshotCgpGetter = parse2(body)?; + + let output = cgp_macro_lib::cgp_getter(item.attr, item.body.to_token_stream())?; + + item.snapshot.wrap_output(output) +} diff --git a/crates/macros/cgp-macro-test-util-lib/src/types/cgp_getter.rs b/crates/macros/cgp-macro-test-util-lib/src/types/cgp_getter.rs new file mode 100644 index 00000000..8d49fb7c --- /dev/null +++ b/crates/macros/cgp-macro-test-util-lib/src/types/cgp_getter.rs @@ -0,0 +1,31 @@ +use proc_macro2::TokenStream; +use syn::ItemTrait; +use syn::parse::{Parse, ParseStream}; +use syn::token::Pound; + +use crate::functions::parse_attribute; +use crate::types::MacroSnapshot; + +pub struct SnapshotCgpGetter { + pub attr: TokenStream, + pub body: ItemTrait, + pub snapshot: MacroSnapshot, +} + +impl Parse for SnapshotCgpGetter { + fn parse(input: ParseStream) -> syn::Result { + let _: Pound = input.parse()?; + + let attr = parse_attribute("cgp_getter", input)?; + + let body = input.parse()?; + + let snapshot = input.parse()?; + + Ok(Self { + attr, + body, + snapshot, + }) + } +} diff --git a/crates/macros/cgp-macro-test-util-lib/src/types/mod.rs b/crates/macros/cgp-macro-test-util-lib/src/types/mod.rs index ed813168..fec4fc9f 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/types/mod.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/types/mod.rs @@ -1,11 +1,13 @@ mod cgp_auto_getter; mod cgp_component; +mod cgp_getter; mod cgp_impl; mod delegate_components; mod snapshot; pub use cgp_auto_getter::*; pub use cgp_component::*; +pub use cgp_getter::*; pub use cgp_impl::*; pub use delegate_components::*; pub use snapshot::*; diff --git a/crates/macros/cgp-macro-test-util/README.md b/crates/macros/cgp-macro-test-util/README.md new file mode 100644 index 00000000..ff2858e6 --- /dev/null +++ b/crates/macros/cgp-macro-test-util/README.md @@ -0,0 +1,262 @@ +# `cgp-macro-test-util` + +Snapshot-testing macros for the CGP procedural macros. + +This crate exposes a family of `snapshot_*!` procedural macros that make it easy +to write **golden / snapshot tests** for the code generated by the core CGP +macros such as `#[cgp_component]`, `#[cgp_impl]`, `#[cgp_auto_getter]`, +`#[cgp_getter]`, and `delegate_components!`. + +The snapshots are asserted using the [`insta`](https://insta.rs) crate. + +## Why snapshot test the macros? + +The CGP macros generate a fair amount of boilerplate: consumer traits, provider +traits, blanket delegation impls, `IsProviderFor` impls, `UseContext` / +`UseField` / `RedirectLookup` providers, and so on. When we change the macro +internals, it is easy to accidentally change the generated output in an +unintended way. + +A snapshot test pins down the *exact* generated code as a human-readable string. +When the generated code changes, the snapshot test fails and shows a diff, +letting us review the change deliberately (and `cargo insta` makes accepting an +intended change a one-liner). + +Crucially, each snapshot macro does **two** things at once: + +1. It **emits the real generated code** into the surrounding module, exactly as + the underlying CGP macro would. The generated traits, structs, and impls are + therefore live and usable by the rest of the module — you can still wire them + up and assert their runtime behavior. +2. It **generates a `#[test]` function** that captures a pretty-printed string of + that same generated code and asserts it against an inline `insta` snapshot. + +Because of (1), migrating an existing test to a snapshot macro does not lose any +compile-time or runtime coverage — it only *adds* a snapshot assertion on top. + +## Crate layout + +This is the proc-macro crate. It is a thin shell: every macro simply forwards to +the implementation crate [`cgp-macro-test-util-lib`](../cgp-macro-test-util-lib), +which is a normal library crate so that the logic can be unit-tested without the +`proc-macro = true` restriction. + +``` +cgp-macro-test-util/ # proc-macro entry points (#[proc_macro] fns) +└── cgp-macro-test-util-lib/ # the actual implementation + ├── entrypoints/ # one function per macro + ├── types/ # parsers (syn `Parse` impls) + MacroSnapshot + └── functions/ # parse_attribute, pretty_format +``` + +The implementation reuses the real macro logic from `cgp-macro-lib` +(`cgp_macro_lib::cgp_component`, `::cgp_impl`, `::cgp_getter`, etc.), so the +snapshot output is guaranteed to match what the production macros generate. + +## Available macros + +| Snapshot macro | Wraps | +| --------------------------- | --------------------- | +| `snapshot_cgp_component!` | `#[cgp_component]` | +| `snapshot_cgp_impl!` | `#[cgp_impl]` | +| `snapshot_cgp_auto_getter!` | `#[cgp_auto_getter]` | +| `snapshot_cgp_getter!` | `#[cgp_getter]` | +| `snapshot_delegate_components!` | `delegate_components!` | + +## Anatomy of a snapshot invocation + +Every snapshot macro takes two parts: + +1. **The item under test**, written *exactly* as you would normally write the + underlying CGP macro invocation (the attribute plus the `trait` / `impl`, or + the full `delegate_components! { ... }` call). +2. **A test block** of the form: + + ```text + () { + > + } + ``` + + - `` becomes the name of the generated `#[test]` function, so it + must be unique within the module. + - `` is the identifier bound to the pretty-printed `&str` of the + generated code inside the test body. It is conventionally named `output`. + - The body is typically a single `insta::assert_snapshot!(, @"...")` + call with an inline snapshot. + +For example: + +```rust +use cgp::prelude::*; +use cgp_macro_test_util::snapshot_cgp_getter; +use insta::assert_snapshot; + +snapshot_cgp_getter! { + #[cgp_getter] + pub trait HasName { + fn name(&self) -> &str; + } + + expand_has_name(output) { + assert_snapshot!(output, @"...generated code...") + } +} +``` + +This expands to roughly: + +```rust +// (1) the real generated code, identical to what `#[cgp_getter]` produces: +pub trait HasName { /* ... */ } +impl<__Context__> HasName for __Context__ where /* ... */ { /* ... */ } +pub trait NameGetter<__Context__>: /* ... */ { /* ... */ } +pub struct NameGetterComponent; +/* ...UseContext / UseField / UseFields / WithProvider / RedirectLookup impls... */ + +// (2) the generated snapshot test: +#[test] +fn expand_has_name() { + let output = "...pretty-printed generated code..."; + assert_snapshot!(output, @"...generated code..."); +} +``` + +### `snapshot_cgp_component!` + +```rust +snapshot_cgp_component! { + #[cgp_component(Greeter)] + pub trait CanGreet: HasName { + fn greet(&self) -> String; + } + + expand_greeter(output) { + assert_snapshot!(output, @"...") + } +} +``` + +Both the parenthesized form `#[cgp_component(Greeter)]` and the brace form +`#[cgp_component { provider: Greeter, ... }]` are accepted, mirroring the real +macro. + +### `snapshot_cgp_impl!` + +```rust +snapshot_cgp_impl! { + #[cgp_impl(new ValueToString)] + impl FooProvider for Context { + fn foo(&self, value: u32) -> String { + value.to_string() + } + } + + expand_value_to_string(output) { + assert_snapshot!(output, @"...") + } +} +``` + +### `snapshot_cgp_auto_getter!` / `snapshot_cgp_getter!` + +```rust +snapshot_cgp_auto_getter! { + #[cgp_auto_getter] + pub trait HasName { + fn name(&self) -> &str; + } + + expand_has_name(output) { + assert_snapshot!(output, @"...") + } +} +``` + +`snapshot_cgp_getter!` has the identical shape and also accepts the custom +provider name forms `#[cgp_getter(NameGetter)]` and +`#[cgp_getter { provider: ..., name: ... }]`. + +### `snapshot_delegate_components!` + +Here the *whole* `delegate_components! { ... }` invocation is written verbatim, +followed by the test block: + +```rust +snapshot_delegate_components! { + delegate_components! { + new FooComponents { + Index<0>: u64, + Index<1>: String, + } + } + + expand_foo_components(output) { + assert_snapshot!(output, @"...") + } +} +``` + +## Workflow with `insta` + +Write the test with an **empty** inline snapshot first: + +```rust +expand_has_name(output) { + assert_snapshot!(output, @"") +} +``` + +Then let `insta` fill it in: + +```bash +# review interactively +cargo insta test -p cgp-tests --test getter +cargo insta review + +# or accept everything non-interactively +cargo insta test -p cgp-tests --accept + +# or via the env var +INSTA_UPDATE=always cargo test -p cgp-tests +``` + +After the first accept, the inline `@"..."` is populated with the pretty-printed +generated code. On subsequent runs the test fails if the generated code changes, +showing a diff you can re-accept once you've confirmed the change is intended. + +## Migrating existing tests + +When migrating an existing macro test, two situations come up: + +- **Module-level macro use** — wrap the existing `#[cgp_component]` / `#[cgp_impl]` + / `#[cgp_getter]` / `#[cgp_auto_getter]` / `delegate_components!` in the matching + `snapshot_*!` macro and append a test block. Nothing else needs to change, + since the snapshot macro re-emits the same code. + +- **CGP components defined *inside* a test function** — the snapshot macro + generates a `#[test]` function, which cannot be nested inside another function. + So the CGP components must be lifted out of the function body: + + - If the test is **purely compile-time** (it only checks that the wiring + compiles, with no runtime assertions), turn the whole test into an inner + `mod` and place the snapshot macro there. + - If the test has **runtime assertions**, create an inner `mod` that holds the + extracted CGP components wrapped in the snapshot macro, and keep the original + `#[test]` function, now referencing the items from the inner module. This + preserves the runtime coverage while adding the snapshot assertion. + +## Notes / limitations + +- Snapshot macros exist only for the five macros listed above. Other CGP macros + (`#[cgp_type]`, `#[cgp_provider]`, `#[cgp_fn]`, `#[cgp_preset]`, + `check_components!`, `delegate_and_check_components!`, …) are not (yet) + snapshot-wrapped and are left as-is. +- The pretty-printing is done with + [`prettyplease`](https://crates.io/crates/prettyplease), and any + macro-prelude noise is stripped beforehand + (`cgp_macro_core::functions::strip_macro_prelude`), so the snapshot is stable, + readable Rust source. +- The `` must be unique within its module — when a single file + contains several snapshots, give each a distinct name (e.g. `expand_has_name`, + `expand_greeter`). diff --git a/crates/macros/cgp-macro-test-util/src/lib.rs b/crates/macros/cgp-macro-test-util/src/lib.rs index 32ec8a68..9808f8db 100644 --- a/crates/macros/cgp-macro-test-util/src/lib.rs +++ b/crates/macros/cgp-macro-test-util/src/lib.rs @@ -28,3 +28,10 @@ pub fn snapshot_cgp_auto_getter(body: TokenStream) -> TokenStream { .unwrap_or_else(syn::Error::into_compile_error) .into() } + +#[proc_macro] +pub fn snapshot_cgp_getter(body: TokenStream) -> TokenStream { + entrypoints::snapshot_cgp_getter(body.into()) + .unwrap_or_else(syn::Error::into_compile_error) + .into() +} diff --git a/crates/tests/cgp-tests/src/namespaces/default_impls.rs b/crates/tests/cgp-tests/src/namespaces/default_impls.rs index b72ca309..c56a925b 100644 --- a/crates/tests/cgp-tests/src/namespaces/default_impls.rs +++ b/crates/tests/cgp-tests/src/namespaces/default_impls.rs @@ -2,25 +2,152 @@ use core::fmt::Display; use cgp::core::component::DefaultImpls1; use cgp::prelude::*; +use cgp_macro_test_util::{snapshot_cgp_component, snapshot_cgp_impl}; +#[cfg(test)] +use insta::assert_snapshot; -#[cgp_component(ShowImpl)] -#[prefix(@test in DefaultNamespace)] -pub trait Show { - fn show(&self, value: &T) -> String; +snapshot_cgp_component! { + #[cgp_component(ShowImpl)] + #[prefix(@test in DefaultNamespace)] + pub trait Show { + fn show(&self, value: &T) -> String; + } + + expand_show(output) { + assert_snapshot!(output, @" + pub trait Show { + fn show(&self, value: &T) -> String; + } + impl<__Context__, T> Show for __Context__ + where + __Context__: ShowImpl<__Context__, T>, + { + fn show(&self, value: &T) -> String { + __Context__::show(self, value) + } + } + pub trait ShowImpl<__Context__, T>: IsProviderFor { + fn show(__context__: &__Context__, value: &T) -> String; + } + impl<__Provider__, __Context__, T> ShowImpl<__Context__, T> for __Provider__ + where + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + ShowImplComponent, + >>::Delegate: ShowImpl<__Context__, T>, + { + fn show(__context__: &__Context__, value: &T) -> String { + <__Provider__ as DelegateComponent< + ShowImplComponent, + >>::Delegate::show(__context__, value) + } + } + pub struct ShowImplComponent; + impl<__Context__, T> ShowImpl<__Context__, T> for UseContext + where + __Context__: Show, + { + fn show(__context__: &__Context__, value: &T) -> String { + __Context__::show(__context__, value) + } + } + impl<__Context__, T> IsProviderFor for UseContext + where + __Context__: Show, + {} + impl<__Context__, T, __Components__, __Path__> ShowImpl<__Context__, T> + for RedirectLookup<__Components__, __Path__> + where + __Path__: ConcatPath>, + __Components__: DelegateComponent< + <__Path__ as ConcatPath>>::Output, + >, + <__Components__ as DelegateComponent< + <__Path__ as ConcatPath>>::Output, + >>::Delegate: ShowImpl<__Context__, T>, + { + fn show(__context__: &__Context__, value: &T) -> String { + <__Components__ as DelegateComponent< + <__Path__ as ConcatPath>>::Output, + >>::Delegate::show(__context__, value) + } + } + impl< + __Context__, + T, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Path__: ConcatPath>, + __Components__: DelegateComponent< + <__Path__ as ConcatPath>>::Output, + >, + <__Components__ as DelegateComponent< + <__Path__ as ConcatPath>>::Output, + >>::Delegate: IsProviderFor + + ShowImpl<__Context__, T>, + {} + impl<__Components__> DefaultNamespace<__Components__> for ShowImplComponent { + type Delegate = RedirectLookup< + __Components__, + PathCons< + Symbol<4, Chars<'t', Chars<'e', Chars<'s', Chars<'t', Nil>>>>>, + PathCons, + >, + >; + } + ") + } } -#[cgp_impl(new ShowString)] -#[default_impl(String in DefaultImpls1)] -impl ShowImpl { - fn show(&self, value: &String) -> String { - value.clone() +snapshot_cgp_impl! { + #[cgp_impl(new ShowString)] + #[default_impl(String in DefaultImpls1)] + impl ShowImpl { + fn show(&self, value: &String) -> String { + value.clone() + } + } + + expand_show_string(output) { + assert_snapshot!(output, @" + impl<__Context__> ShowImpl<__Context__, String> for ShowString { + fn show(__context__: &__Context__, value: &String) -> String { + value.clone() + } + } + impl<__Context__> IsProviderFor + for ShowString {} + pub struct ShowString; + impl<__Components__> DefaultImpls1 for String { + type Delegate = ShowString; + } + ") } } -#[cgp_impl(new ShowWithDisplay)] -impl ShowImpl { - fn show(&self, value: &T) -> String { - value.to_string() +snapshot_cgp_impl! { + #[cgp_impl(new ShowWithDisplay)] + impl ShowImpl { + fn show(&self, value: &T) -> String { + value.to_string() + } + } + + expand_show_with_display(output) { + assert_snapshot!(output, @" + impl<__Context__, T: Display> ShowImpl<__Context__, T> for ShowWithDisplay { + fn show(__context__: &__Context__, value: &T) -> String { + value.to_string() + } + } + impl<__Context__, T: Display> IsProviderFor + for ShowWithDisplay {} + pub struct ShowWithDisplay; + ") } } @@ -39,10 +166,31 @@ cgp_namespace! { } } -#[cgp_impl(new ShowU32)] -#[default_impl(@test.ShowImplComponent.u32 in ExtendedNamespace)] -impl ShowImpl { - fn show(&self, value: &u32) -> String { - value.to_string() +snapshot_cgp_impl! { + #[cgp_impl(new ShowU32)] + #[default_impl(@test.ShowImplComponent.u32 in ExtendedNamespace)] + impl ShowImpl { + fn show(&self, value: &u32) -> String { + value.to_string() + } + } + + expand_show_u32(output) { + assert_snapshot!(output, @" + impl<__Context__> ShowImpl<__Context__, u32> for ShowU32 { + fn show(__context__: &__Context__, value: &u32) -> String { + value.to_string() + } + } + impl<__Context__> IsProviderFor for ShowU32 {} + pub struct ShowU32; + impl<__Components__> ExtendedNamespace<__Components__> + for PathCons< + Symbol<4, Chars<'t', Chars<'e', Chars<'s', Chars<'t', Nil>>>>>, + PathCons>, + > { + type Delegate = ShowU32; + } + ") } } diff --git a/crates/tests/cgp-tests/src/tests/async/spawn.rs b/crates/tests/cgp-tests/src/tests/async/spawn.rs index d36c3adb..7118855f 100644 --- a/crates/tests/cgp-tests/src/tests/async/spawn.rs +++ b/crates/tests/cgp-tests/src/tests/async/spawn.rs @@ -17,7 +17,9 @@ use cgp::extra::run::{ CanRun, CanSendRun, Runner, RunnerComponent, SendRunner, SendRunnerComponent, }; use cgp::prelude::*; +use cgp_macro_test_util::{snapshot_cgp_component, snapshot_delegate_components}; use futures::executor::block_on; +use insta::assert_snapshot; // A dummy spawn function that has the same signature as tokio::spawn, // requiring the Future to implement Send + 'static. @@ -40,22 +42,330 @@ pub trait HasBarType { type Bar; } -#[cgp_component(FooFetcher)] -#[async_trait] -pub trait CanFetchFoo: HasFooType + HasErrorType { - async fn fetch_foo(&self) -> Result; +snapshot_cgp_component! { + #[cgp_component(FooFetcher)] + #[async_trait] + pub trait CanFetchFoo: HasFooType + HasErrorType { + async fn fetch_foo(&self) -> Result; + } + + expand_can_fetch_foo(output) { + assert_snapshot!(output, @" + #[async_trait] + pub trait CanFetchFoo: HasFooType + HasErrorType { + async fn fetch_foo(&self) -> Result; + } + #[async_trait] + impl<__Context__> CanFetchFoo for __Context__ + where + __Context__: HasFooType + HasErrorType, + __Context__: FooFetcher<__Context__>, + { + async fn fetch_foo(&self) -> Result { + __Context__::fetch_foo(self).await + } + } + #[async_trait] + pub trait FooFetcher<__Context__>: IsProviderFor + where + __Context__: HasFooType + HasErrorType, + { + async fn fetch_foo( + __context__: &__Context__, + ) -> Result<__Context__::Foo, __Context__::Error>; + } + #[async_trait] + impl<__Provider__, __Context__> FooFetcher<__Context__> for __Provider__ + where + __Context__: HasFooType + HasErrorType, + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + FooFetcherComponent, + >>::Delegate: FooFetcher<__Context__>, + { + async fn fetch_foo( + __context__: &__Context__, + ) -> Result<__Context__::Foo, __Context__::Error> { + <__Provider__ as DelegateComponent< + FooFetcherComponent, + >>::Delegate::fetch_foo(__context__) + .await + } + } + pub struct FooFetcherComponent; + #[async_trait] + impl<__Context__> FooFetcher<__Context__> for UseContext + where + __Context__: HasFooType + HasErrorType, + __Context__: CanFetchFoo, + { + async fn fetch_foo( + __context__: &__Context__, + ) -> Result<__Context__::Foo, __Context__::Error> { + __Context__::fetch_foo(__context__).await + } + } + impl<__Context__> IsProviderFor for UseContext + where + __Context__: HasFooType + HasErrorType, + __Context__: CanFetchFoo, + {} + #[async_trait] + impl<__Context__, __Components__, __Path__> FooFetcher<__Context__> + for RedirectLookup<__Components__, __Path__> + where + __Context__: HasFooType + HasErrorType, + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent<__Path__>>::Delegate: FooFetcher<__Context__>, + { + async fn fetch_foo( + __context__: &__Context__, + ) -> Result<__Context__::Foo, __Context__::Error> { + <__Components__ as DelegateComponent<__Path__>>::Delegate::fetch_foo(__context__) + .await + } + } + impl< + __Context__, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Context__: HasFooType + HasErrorType, + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: IsProviderFor + + FooFetcher<__Context__>, + {} + ") + } } -#[cgp_component(BarFetcher)] -#[async_trait] -pub trait CanFetchBar: HasBarType + HasErrorType { - async fn fetch_bar(&self) -> Result; +snapshot_cgp_component! { + #[cgp_component(BarFetcher)] + #[async_trait] + pub trait CanFetchBar: HasBarType + HasErrorType { + async fn fetch_bar(&self) -> Result; + } + + expand_can_fetch_bar(output) { + assert_snapshot!(output, @" + #[async_trait] + pub trait CanFetchBar: HasBarType + HasErrorType { + async fn fetch_bar(&self) -> Result; + } + #[async_trait] + impl<__Context__> CanFetchBar for __Context__ + where + __Context__: HasBarType + HasErrorType, + __Context__: BarFetcher<__Context__>, + { + async fn fetch_bar(&self) -> Result { + __Context__::fetch_bar(self).await + } + } + #[async_trait] + pub trait BarFetcher<__Context__>: IsProviderFor + where + __Context__: HasBarType + HasErrorType, + { + async fn fetch_bar( + __context__: &__Context__, + ) -> Result<__Context__::Bar, __Context__::Error>; + } + #[async_trait] + impl<__Provider__, __Context__> BarFetcher<__Context__> for __Provider__ + where + __Context__: HasBarType + HasErrorType, + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + BarFetcherComponent, + >>::Delegate: BarFetcher<__Context__>, + { + async fn fetch_bar( + __context__: &__Context__, + ) -> Result<__Context__::Bar, __Context__::Error> { + <__Provider__ as DelegateComponent< + BarFetcherComponent, + >>::Delegate::fetch_bar(__context__) + .await + } + } + pub struct BarFetcherComponent; + #[async_trait] + impl<__Context__> BarFetcher<__Context__> for UseContext + where + __Context__: HasBarType + HasErrorType, + __Context__: CanFetchBar, + { + async fn fetch_bar( + __context__: &__Context__, + ) -> Result<__Context__::Bar, __Context__::Error> { + __Context__::fetch_bar(__context__).await + } + } + impl<__Context__> IsProviderFor for UseContext + where + __Context__: HasBarType + HasErrorType, + __Context__: CanFetchBar, + {} + #[async_trait] + impl<__Context__, __Components__, __Path__> BarFetcher<__Context__> + for RedirectLookup<__Components__, __Path__> + where + __Context__: HasBarType + HasErrorType, + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent<__Path__>>::Delegate: BarFetcher<__Context__>, + { + async fn fetch_bar( + __context__: &__Context__, + ) -> Result<__Context__::Bar, __Context__::Error> { + <__Components__ as DelegateComponent<__Path__>>::Delegate::fetch_bar(__context__) + .await + } + } + impl< + __Context__, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Context__: HasBarType + HasErrorType, + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: IsProviderFor + + BarFetcher<__Context__>, + {} + ") + } } -#[cgp_component(FooBarRunner)] -#[async_trait] -pub trait CanRunFooBar: HasFooType + HasBarType + HasErrorType { - async fn run_foo_bar(&self, foo: &Self::Foo, bar: &Self::Bar) -> Result<(), Self::Error>; +snapshot_cgp_component! { + #[cgp_component(FooBarRunner)] + #[async_trait] + pub trait CanRunFooBar: HasFooType + HasBarType + HasErrorType { + async fn run_foo_bar(&self, foo: &Self::Foo, bar: &Self::Bar) -> Result<(), Self::Error>; + } + + expand_can_run_foo_bar(output) { + assert_snapshot!(output, @" + #[async_trait] + pub trait CanRunFooBar: HasFooType + HasBarType + HasErrorType { + async fn run_foo_bar( + &self, + foo: &Self::Foo, + bar: &Self::Bar, + ) -> Result<(), Self::Error>; + } + #[async_trait] + impl<__Context__> CanRunFooBar for __Context__ + where + __Context__: HasFooType + HasBarType + HasErrorType, + __Context__: FooBarRunner<__Context__>, + { + async fn run_foo_bar( + &self, + foo: &Self::Foo, + bar: &Self::Bar, + ) -> Result<(), Self::Error> { + __Context__::run_foo_bar(self, foo, bar).await + } + } + #[async_trait] + pub trait FooBarRunner< + __Context__, + >: IsProviderFor + where + __Context__: HasFooType + HasBarType + HasErrorType, + { + async fn run_foo_bar( + __context__: &__Context__, + foo: &__Context__::Foo, + bar: &__Context__::Bar, + ) -> Result<(), __Context__::Error>; + } + #[async_trait] + impl<__Provider__, __Context__> FooBarRunner<__Context__> for __Provider__ + where + __Context__: HasFooType + HasBarType + HasErrorType, + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + FooBarRunnerComponent, + >>::Delegate: FooBarRunner<__Context__>, + { + async fn run_foo_bar( + __context__: &__Context__, + foo: &__Context__::Foo, + bar: &__Context__::Bar, + ) -> Result<(), __Context__::Error> { + <__Provider__ as DelegateComponent< + FooBarRunnerComponent, + >>::Delegate::run_foo_bar(__context__, foo, bar) + .await + } + } + pub struct FooBarRunnerComponent; + #[async_trait] + impl<__Context__> FooBarRunner<__Context__> for UseContext + where + __Context__: HasFooType + HasBarType + HasErrorType, + __Context__: CanRunFooBar, + { + async fn run_foo_bar( + __context__: &__Context__, + foo: &__Context__::Foo, + bar: &__Context__::Bar, + ) -> Result<(), __Context__::Error> { + __Context__::run_foo_bar(__context__, foo, bar).await + } + } + impl<__Context__> IsProviderFor for UseContext + where + __Context__: HasFooType + HasBarType + HasErrorType, + __Context__: CanRunFooBar, + {} + #[async_trait] + impl<__Context__, __Components__, __Path__> FooBarRunner<__Context__> + for RedirectLookup<__Components__, __Path__> + where + __Context__: HasFooType + HasBarType + HasErrorType, + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent<__Path__>>::Delegate: FooBarRunner<__Context__>, + { + async fn run_foo_bar( + __context__: &__Context__, + foo: &__Context__::Foo, + bar: &__Context__::Bar, + ) -> Result<(), __Context__::Error> { + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate::run_foo_bar(__context__, foo, bar) + .await + } + } + impl< + __Context__, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Context__: HasFooType + HasBarType + HasErrorType, + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: IsProviderFor + + FooBarRunner<__Context__>, + {} + ") + } } // Abstract providers can be implemented without Send bounds @@ -133,26 +443,118 @@ pub struct App; pub struct ActionA; pub struct ActionB; -delegate_components! { - App { - ErrorTypeProviderComponent: - UseType, - [ - FooTypeProviderComponent, - BarTypeProviderComponent, - ]: - UseType<()>, - FooFetcherComponent: - DummyFetchFoo, - BarFetcherComponent: - DummyFetchBar, - FooBarRunnerComponent: - DummyRunFoobar, - RunnerComponent: - UseDelegate, - }>, +snapshot_delegate_components! { + delegate_components! { + App { + ErrorTypeProviderComponent: + UseType, + [ + FooTypeProviderComponent, + BarTypeProviderComponent, + ]: + UseType<()>, + FooFetcherComponent: + DummyFetchFoo, + BarFetcherComponent: + DummyFetchBar, + FooBarRunnerComponent: + DummyRunFoobar, + RunnerComponent: + UseDelegate, + }>, + } + } + + expand_app(output) { + assert_snapshot!(output, @" + pub struct AppRunnerComponents; + impl DelegateComponent for App { + type Delegate = UseType; + } + impl< + __Context__, + __Params__, + > IsProviderFor for App + where + UseType< + Infallible, + >: IsProviderFor, + {} + impl DelegateComponent for App { + type Delegate = UseType<()>; + } + impl< + __Context__, + __Params__, + > IsProviderFor for App + where + UseType<()>: IsProviderFor, + {} + impl DelegateComponent for App { + type Delegate = UseType<()>; + } + impl< + __Context__, + __Params__, + > IsProviderFor for App + where + UseType<()>: IsProviderFor, + {} + impl DelegateComponent for App { + type Delegate = DummyFetchFoo; + } + impl<__Context__, __Params__> IsProviderFor + for App + where + DummyFetchFoo: IsProviderFor, + {} + impl DelegateComponent for App { + type Delegate = DummyFetchBar; + } + impl<__Context__, __Params__> IsProviderFor + for App + where + DummyFetchBar: IsProviderFor, + {} + impl DelegateComponent for App { + type Delegate = DummyRunFoobar; + } + impl< + __Context__, + __Params__, + > IsProviderFor for App + where + DummyRunFoobar: IsProviderFor, + {} + impl DelegateComponent for App { + type Delegate = UseDelegate; + } + impl<__Context__, __Params__> IsProviderFor + for App + where + UseDelegate< + AppRunnerComponents, + >: IsProviderFor, + {} + impl DelegateComponent for AppRunnerComponents { + type Delegate = RunWithFooBar; + } + impl<__Context__, __Params__> IsProviderFor + for AppRunnerComponents + where + RunWithFooBar: IsProviderFor, + {} + impl DelegateComponent for AppRunnerComponents { + type Delegate = SpawnAndRun; + } + impl<__Context__, __Params__> IsProviderFor + for AppRunnerComponents + where + SpawnAndRun: IsProviderFor, + {} + ") } } diff --git a/crates/tests/cgp-tests/src/tests/check_components.rs b/crates/tests/cgp-tests/src/tests/check_components.rs index f32036d1..be605c5e 100644 --- a/crates/tests/cgp-tests/src/tests/check_components.rs +++ b/crates/tests/cgp-tests/src/tests/check_components.rs @@ -1,11 +1,12 @@ #![allow(dead_code)] -use core::marker::PhantomData; +mod basic_check_components { + use core::marker::PhantomData; -use cgp::prelude::*; + use cgp::prelude::*; + use cgp_macro_test_util::snapshot_cgp_getter; + use insta::assert_snapshot; -#[test] -pub fn test_basic_check_components() { #[cgp_type] pub trait HasFooType { type Foo; @@ -16,18 +17,357 @@ pub fn test_basic_check_components() { type Bar; } - #[cgp_getter { - provider: FooGetterAt, - }] - pub trait HasFooAt: HasFooType { - fn foo(&self, _tag: PhantomData) -> &Self::Foo; + snapshot_cgp_getter! { + #[cgp_getter { + provider: FooGetterAt, + }] + pub trait HasFooAt: HasFooType { + fn foo(&self, _tag: PhantomData) -> &Self::Foo; + } + + expand_has_foo_at(output) { + assert_snapshot!(output, @" + pub trait HasFooAt: HasFooType { + fn foo(&self, _tag: PhantomData) -> &Self::Foo; + } + impl<__Context__, I> HasFooAt for __Context__ + where + __Context__: HasFooType, + __Context__: FooGetterAt<__Context__, I>, + { + fn foo(&self, _tag: PhantomData) -> &Self::Foo { + __Context__::foo(self, _tag) + } + } + pub trait FooGetterAt< + __Context__, + I, + >: IsProviderFor + where + __Context__: HasFooType, + { + fn foo(__context__: &__Context__, _tag: PhantomData) -> &__Context__::Foo; + } + impl<__Provider__, __Context__, I> FooGetterAt<__Context__, I> for __Provider__ + where + __Context__: HasFooType, + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + FooGetterAtComponent, + >>::Delegate: FooGetterAt<__Context__, I>, + { + fn foo(__context__: &__Context__, _tag: PhantomData) -> &__Context__::Foo { + <__Provider__ as DelegateComponent< + FooGetterAtComponent, + >>::Delegate::foo(__context__, _tag) + } + } + pub struct FooGetterAtComponent; + impl<__Context__, I> FooGetterAt<__Context__, I> for UseContext + where + __Context__: HasFooType, + __Context__: HasFooAt, + { + fn foo(__context__: &__Context__, _tag: PhantomData) -> &__Context__::Foo { + __Context__::foo(__context__, _tag) + } + } + impl<__Context__, I> IsProviderFor for UseContext + where + __Context__: HasFooType, + __Context__: HasFooAt, + {} + impl<__Context__, I, __Components__, __Path__> FooGetterAt<__Context__, I> + for RedirectLookup<__Components__, __Path__> + where + __Context__: HasFooType, + __Path__: ConcatPath>, + __Components__: DelegateComponent< + <__Path__ as ConcatPath>>::Output, + >, + <__Components__ as DelegateComponent< + <__Path__ as ConcatPath>>::Output, + >>::Delegate: FooGetterAt<__Context__, I>, + { + fn foo(__context__: &__Context__, _tag: PhantomData) -> &__Context__::Foo { + <__Components__ as DelegateComponent< + <__Path__ as ConcatPath>>::Output, + >>::Delegate::foo(__context__, _tag) + } + } + impl< + __Context__, + I, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Context__: HasFooType, + __Path__: ConcatPath>, + __Components__: DelegateComponent< + <__Path__ as ConcatPath>>::Output, + >, + <__Components__ as DelegateComponent< + <__Path__ as ConcatPath>>::Output, + >>::Delegate: IsProviderFor + + FooGetterAt<__Context__, I>, + {} + impl<__Context__, I> FooGetterAt<__Context__, I> for UseFields + where + __Context__: HasFooType, + __Context__: HasField< + Symbol<3, Chars<'f', Chars<'o', Chars<'o', Nil>>>>, + Value = __Context__::Foo, + >, + { + fn foo(__context__: &__Context__, _phantom: PhantomData) -> &__Context__::Foo { + __context__ + .get_field( + ::core::marker::PhantomData::< + Symbol<3, Chars<'f', Chars<'o', Chars<'o', Nil>>>>, + >, + ) + } + } + impl<__Context__, I> IsProviderFor for UseFields + where + __Context__: HasFooType, + __Context__: HasField< + Symbol<3, Chars<'f', Chars<'o', Chars<'o', Nil>>>>, + Value = __Context__::Foo, + >, + {} + impl<__Context__, I, __Tag__> FooGetterAt<__Context__, I> for UseField<__Tag__> + where + __Context__: HasFooType, + __Context__: HasField<__Tag__, Value = __Context__::Foo>, + { + fn foo(__context__: &__Context__, _phantom: PhantomData) -> &__Context__::Foo { + __context__.get_field(::core::marker::PhantomData::<__Tag__>) + } + } + impl<__Context__, I, __Tag__> IsProviderFor + for UseField<__Tag__> + where + __Context__: HasFooType, + __Context__: HasField<__Tag__, Value = __Context__::Foo>, + {} + impl<__Context__, I, __Provider__> FooGetterAt<__Context__, I> + for WithProvider<__Provider__> + where + __Context__: HasFooType, + __Provider__: FieldGetter< + __Context__, + FooGetterAtComponent, + Value = __Context__::Foo, + >, + { + fn foo(__context__: &__Context__, _phantom: PhantomData) -> &__Context__::Foo { + __Provider__::get_field( + __context__, + ::core::marker::PhantomData::, + ) + } + } + impl<__Context__, I, __Provider__> IsProviderFor + for WithProvider<__Provider__> + where + __Context__: HasFooType, + __Provider__: FieldGetter< + __Context__, + FooGetterAtComponent, + Value = __Context__::Foo, + >, + {} + ") + } } - #[cgp_getter { - provider: BarGetterAt, - }] - pub trait HasBarAt: HasBarType { - fn foo(&self, _tag: PhantomData<(I, J)>) -> &Self::Bar; + snapshot_cgp_getter! { + #[cgp_getter { + provider: BarGetterAt, + }] + pub trait HasBarAt: HasBarType { + fn foo(&self, _tag: PhantomData<(I, J)>) -> &Self::Bar; + } + + expand_has_bar_at(output) { + assert_snapshot!(output, @" + pub trait HasBarAt: HasBarType { + fn foo(&self, _tag: PhantomData<(I, J)>) -> &Self::Bar; + } + impl<__Context__, I, J> HasBarAt for __Context__ + where + __Context__: HasBarType, + __Context__: BarGetterAt<__Context__, I, J>, + { + fn foo(&self, _tag: PhantomData<(I, J)>) -> &Self::Bar { + __Context__::foo(self, _tag) + } + } + pub trait BarGetterAt< + __Context__, + I, + J, + >: IsProviderFor + where + __Context__: HasBarType, + { + fn foo(__context__: &__Context__, _tag: PhantomData<(I, J)>) -> &__Context__::Bar; + } + impl<__Provider__, __Context__, I, J> BarGetterAt<__Context__, I, J> for __Provider__ + where + __Context__: HasBarType, + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + BarGetterAtComponent, + >>::Delegate: BarGetterAt<__Context__, I, J>, + { + fn foo(__context__: &__Context__, _tag: PhantomData<(I, J)>) -> &__Context__::Bar { + <__Provider__ as DelegateComponent< + BarGetterAtComponent, + >>::Delegate::foo(__context__, _tag) + } + } + pub struct BarGetterAtComponent; + impl<__Context__, I, J> BarGetterAt<__Context__, I, J> for UseContext + where + __Context__: HasBarType, + __Context__: HasBarAt, + { + fn foo(__context__: &__Context__, _tag: PhantomData<(I, J)>) -> &__Context__::Bar { + __Context__::foo(__context__, _tag) + } + } + impl<__Context__, I, J> IsProviderFor + for UseContext + where + __Context__: HasBarType, + __Context__: HasBarAt, + {} + impl<__Context__, I, J, __Components__, __Path__> BarGetterAt<__Context__, I, J> + for RedirectLookup<__Components__, __Path__> + where + __Context__: HasBarType, + __Path__: ConcatPath>>, + __Components__: DelegateComponent< + <__Path__ as ConcatPath>>>::Output, + >, + <__Components__ as DelegateComponent< + <__Path__ as ConcatPath>>>::Output, + >>::Delegate: BarGetterAt<__Context__, I, J>, + { + fn foo(__context__: &__Context__, _tag: PhantomData<(I, J)>) -> &__Context__::Bar { + <__Components__ as DelegateComponent< + <__Path__ as ConcatPath>>>::Output, + >>::Delegate::foo(__context__, _tag) + } + } + impl< + __Context__, + I, + J, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Context__: HasBarType, + __Path__: ConcatPath>>, + __Components__: DelegateComponent< + <__Path__ as ConcatPath>>>::Output, + >, + <__Components__ as DelegateComponent< + <__Path__ as ConcatPath>>>::Output, + >>::Delegate: IsProviderFor + + BarGetterAt<__Context__, I, J>, + {} + impl<__Context__, I, J> BarGetterAt<__Context__, I, J> for UseFields + where + __Context__: HasBarType, + __Context__: HasField< + Symbol<3, Chars<'f', Chars<'o', Chars<'o', Nil>>>>, + Value = __Context__::Bar, + >, + { + fn foo( + __context__: &__Context__, + _phantom: PhantomData<(I, J)>, + ) -> &__Context__::Bar { + __context__ + .get_field( + ::core::marker::PhantomData::< + Symbol<3, Chars<'f', Chars<'o', Chars<'o', Nil>>>>, + >, + ) + } + } + impl<__Context__, I, J> IsProviderFor + for UseFields + where + __Context__: HasBarType, + __Context__: HasField< + Symbol<3, Chars<'f', Chars<'o', Chars<'o', Nil>>>>, + Value = __Context__::Bar, + >, + {} + impl<__Context__, I, J, __Tag__> BarGetterAt<__Context__, I, J> for UseField<__Tag__> + where + __Context__: HasBarType, + __Context__: HasField<__Tag__, Value = __Context__::Bar>, + { + fn foo( + __context__: &__Context__, + _phantom: PhantomData<(I, J)>, + ) -> &__Context__::Bar { + __context__.get_field(::core::marker::PhantomData::<__Tag__>) + } + } + impl<__Context__, I, J, __Tag__> IsProviderFor + for UseField<__Tag__> + where + __Context__: HasBarType, + __Context__: HasField<__Tag__, Value = __Context__::Bar>, + {} + impl<__Context__, I, J, __Provider__> BarGetterAt<__Context__, I, J> + for WithProvider<__Provider__> + where + __Context__: HasBarType, + __Provider__: FieldGetter< + __Context__, + BarGetterAtComponent, + Value = __Context__::Bar, + >, + { + fn foo( + __context__: &__Context__, + _phantom: PhantomData<(I, J)>, + ) -> &__Context__::Bar { + __Provider__::get_field( + __context__, + ::core::marker::PhantomData::, + ) + } + } + impl< + __Context__, + I, + J, + __Provider__, + > IsProviderFor for WithProvider<__Provider__> + where + __Context__: HasBarType, + __Provider__: FieldGetter< + __Context__, + BarGetterAtComponent, + Value = __Context__::Bar, + >, + {} + ") + } } #[derive(HasField)] @@ -124,8 +464,13 @@ pub fn test_basic_check_components() { } } -#[test] -pub fn test_generic_check_components() { +mod generic_check_components { + use core::marker::PhantomData; + + use cgp::prelude::*; + use cgp_macro_test_util::{snapshot_cgp_getter, snapshot_delegate_components}; + use insta::assert_snapshot; + #[cgp_type] pub trait HasFooType { type Foo; @@ -136,19 +481,379 @@ pub fn test_generic_check_components() { type Bar; } - #[cgp_getter { - provider: FooGetterAt, - }] - pub trait HasFooAt: HasFooType { - fn foo(&self, _tag: PhantomData) -> &Self::Foo; + snapshot_cgp_getter! { + #[cgp_getter { + provider: FooGetterAt, + }] + pub trait HasFooAt: HasFooType { + fn foo(&self, _tag: PhantomData) -> &Self::Foo; + } + + expand_has_foo_at(output) { + assert_snapshot!(output, @" + pub trait HasFooAt: HasFooType { + fn foo(&self, _tag: PhantomData) -> &Self::Foo; + } + impl<__Context__, I: Clone> HasFooAt for __Context__ + where + __Context__: HasFooType, + __Context__: FooGetterAt<__Context__, I>, + { + fn foo(&self, _tag: PhantomData) -> &Self::Foo { + __Context__::foo(self, _tag) + } + } + pub trait FooGetterAt< + __Context__, + I: Clone, + >: IsProviderFor + where + __Context__: HasFooType, + { + fn foo(__context__: &__Context__, _tag: PhantomData) -> &__Context__::Foo; + } + impl<__Provider__, __Context__, I: Clone> FooGetterAt<__Context__, I> for __Provider__ + where + __Context__: HasFooType, + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + FooGetterAtComponent, + >>::Delegate: FooGetterAt<__Context__, I>, + { + fn foo(__context__: &__Context__, _tag: PhantomData) -> &__Context__::Foo { + <__Provider__ as DelegateComponent< + FooGetterAtComponent, + >>::Delegate::foo(__context__, _tag) + } + } + pub struct FooGetterAtComponent; + impl<__Context__, I: Clone> FooGetterAt<__Context__, I> for UseContext + where + __Context__: HasFooType, + __Context__: HasFooAt, + { + fn foo(__context__: &__Context__, _tag: PhantomData) -> &__Context__::Foo { + __Context__::foo(__context__, _tag) + } + } + impl<__Context__, I: Clone> IsProviderFor + for UseContext + where + __Context__: HasFooType, + __Context__: HasFooAt, + {} + impl<__Context__, I: Clone, __Components__, __Path__> FooGetterAt<__Context__, I> + for RedirectLookup<__Components__, __Path__> + where + __Context__: HasFooType, + __Path__: ConcatPath>, + __Components__: DelegateComponent< + <__Path__ as ConcatPath>>::Output, + >, + <__Components__ as DelegateComponent< + <__Path__ as ConcatPath>>::Output, + >>::Delegate: FooGetterAt<__Context__, I>, + { + fn foo(__context__: &__Context__, _tag: PhantomData) -> &__Context__::Foo { + <__Components__ as DelegateComponent< + <__Path__ as ConcatPath>>::Output, + >>::Delegate::foo(__context__, _tag) + } + } + impl< + __Context__, + I: Clone, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Context__: HasFooType, + __Path__: ConcatPath>, + __Components__: DelegateComponent< + <__Path__ as ConcatPath>>::Output, + >, + <__Components__ as DelegateComponent< + <__Path__ as ConcatPath>>::Output, + >>::Delegate: IsProviderFor + + FooGetterAt<__Context__, I>, + {} + impl<__Context__, I: Clone> FooGetterAt<__Context__, I> for UseFields + where + __Context__: HasFooType, + __Context__: HasField< + Symbol<3, Chars<'f', Chars<'o', Chars<'o', Nil>>>>, + Value = __Context__::Foo, + >, + { + fn foo(__context__: &__Context__, _phantom: PhantomData) -> &__Context__::Foo { + __context__ + .get_field( + ::core::marker::PhantomData::< + Symbol<3, Chars<'f', Chars<'o', Chars<'o', Nil>>>>, + >, + ) + } + } + impl<__Context__, I: Clone> IsProviderFor + for UseFields + where + __Context__: HasFooType, + __Context__: HasField< + Symbol<3, Chars<'f', Chars<'o', Chars<'o', Nil>>>>, + Value = __Context__::Foo, + >, + {} + impl<__Context__, I: Clone, __Tag__> FooGetterAt<__Context__, I> for UseField<__Tag__> + where + __Context__: HasFooType, + __Context__: HasField<__Tag__, Value = __Context__::Foo>, + { + fn foo(__context__: &__Context__, _phantom: PhantomData) -> &__Context__::Foo { + __context__.get_field(::core::marker::PhantomData::<__Tag__>) + } + } + impl< + __Context__, + I: Clone, + __Tag__, + > IsProviderFor for UseField<__Tag__> + where + __Context__: HasFooType, + __Context__: HasField<__Tag__, Value = __Context__::Foo>, + {} + impl<__Context__, I: Clone, __Provider__> FooGetterAt<__Context__, I> + for WithProvider<__Provider__> + where + __Context__: HasFooType, + __Provider__: FieldGetter< + __Context__, + FooGetterAtComponent, + Value = __Context__::Foo, + >, + { + fn foo(__context__: &__Context__, _phantom: PhantomData) -> &__Context__::Foo { + __Provider__::get_field( + __context__, + ::core::marker::PhantomData::, + ) + } + } + impl< + __Context__, + I: Clone, + __Provider__, + > IsProviderFor for WithProvider<__Provider__> + where + __Context__: HasFooType, + __Provider__: FieldGetter< + __Context__, + FooGetterAtComponent, + Value = __Context__::Foo, + >, + {} + ") + } } - #[cgp_getter { - name: BarGetterAtComponent, - provider: BarGetterAt, - }] - pub trait HasBarAt: HasBarType { - fn foo(&self, _tag: PhantomData<(I, J)>) -> &Self::Bar; + snapshot_cgp_getter! { + #[cgp_getter { + name: BarGetterAtComponent, + provider: BarGetterAt, + }] + pub trait HasBarAt: HasBarType { + fn foo(&self, _tag: PhantomData<(I, J)>) -> &Self::Bar; + } + + expand_has_bar_at(output) { + assert_snapshot!(output, @" + pub trait HasBarAt: HasBarType { + fn foo(&self, _tag: PhantomData<(I, J)>) -> &Self::Bar; + } + impl<__Context__, I: Clone, J> HasBarAt for __Context__ + where + __Context__: HasBarType, + __Context__: BarGetterAt<__Context__, I, J>, + { + fn foo(&self, _tag: PhantomData<(I, J)>) -> &Self::Bar { + __Context__::foo(self, _tag) + } + } + pub trait BarGetterAt< + __Context__, + I: Clone, + J, + >: IsProviderFor, __Context__, (I, J)> + where + __Context__: HasBarType, + { + fn foo(__context__: &__Context__, _tag: PhantomData<(I, J)>) -> &__Context__::Bar; + } + impl<__Provider__, __Context__, I: Clone, J> BarGetterAt<__Context__, I, J> + for __Provider__ + where + __Context__: HasBarType, + __Provider__: DelegateComponent> + + IsProviderFor, __Context__, (I, J)>, + <__Provider__ as DelegateComponent< + BarGetterAtComponent, + >>::Delegate: BarGetterAt<__Context__, I, J>, + { + fn foo(__context__: &__Context__, _tag: PhantomData<(I, J)>) -> &__Context__::Bar { + <__Provider__ as DelegateComponent< + BarGetterAtComponent, + >>::Delegate::foo(__context__, _tag) + } + } + pub struct BarGetterAtComponent(pub ::core::marker::PhantomData<(I)>); + impl<__Context__, I: Clone, J> BarGetterAt<__Context__, I, J> for UseContext + where + __Context__: HasBarType, + __Context__: HasBarAt, + { + fn foo(__context__: &__Context__, _tag: PhantomData<(I, J)>) -> &__Context__::Bar { + __Context__::foo(__context__, _tag) + } + } + impl< + __Context__, + I: Clone, + J, + > IsProviderFor, __Context__, (I, J)> for UseContext + where + __Context__: HasBarType, + __Context__: HasBarAt, + {} + impl<__Context__, I: Clone, J, __Components__, __Path__> BarGetterAt<__Context__, I, J> + for RedirectLookup<__Components__, __Path__> + where + __Context__: HasBarType, + __Path__: ConcatPath>>, + __Components__: DelegateComponent< + <__Path__ as ConcatPath>>>::Output, + >, + <__Components__ as DelegateComponent< + <__Path__ as ConcatPath>>>::Output, + >>::Delegate: BarGetterAt<__Context__, I, J>, + { + fn foo(__context__: &__Context__, _tag: PhantomData<(I, J)>) -> &__Context__::Bar { + <__Components__ as DelegateComponent< + <__Path__ as ConcatPath>>>::Output, + >>::Delegate::foo(__context__, _tag) + } + } + impl< + __Context__, + I: Clone, + J, + __Components__, + __Path__, + > IsProviderFor, __Context__, (I, J)> + for RedirectLookup<__Components__, __Path__> + where + __Context__: HasBarType, + __Path__: ConcatPath>>, + __Components__: DelegateComponent< + <__Path__ as ConcatPath>>>::Output, + >, + <__Components__ as DelegateComponent< + <__Path__ as ConcatPath>>>::Output, + >>::Delegate: IsProviderFor, __Context__, (I, J)> + + BarGetterAt<__Context__, I, J>, + {} + impl<__Context__, I: Clone, J> BarGetterAt<__Context__, I, J> for UseFields + where + __Context__: HasBarType, + __Context__: HasField< + Symbol<3, Chars<'f', Chars<'o', Chars<'o', Nil>>>>, + Value = __Context__::Bar, + >, + { + fn foo( + __context__: &__Context__, + _phantom: PhantomData<(I, J)>, + ) -> &__Context__::Bar { + __context__ + .get_field( + ::core::marker::PhantomData::< + Symbol<3, Chars<'f', Chars<'o', Chars<'o', Nil>>>>, + >, + ) + } + } + impl< + __Context__, + I: Clone, + J, + > IsProviderFor, __Context__, (I, J)> for UseFields + where + __Context__: HasBarType, + __Context__: HasField< + Symbol<3, Chars<'f', Chars<'o', Chars<'o', Nil>>>>, + Value = __Context__::Bar, + >, + {} + impl<__Context__, I: Clone, J, __Tag__> BarGetterAt<__Context__, I, J> + for UseField<__Tag__> + where + __Context__: HasBarType, + __Context__: HasField<__Tag__, Value = __Context__::Bar>, + { + fn foo( + __context__: &__Context__, + _phantom: PhantomData<(I, J)>, + ) -> &__Context__::Bar { + __context__.get_field(::core::marker::PhantomData::<__Tag__>) + } + } + impl< + __Context__, + I: Clone, + J, + __Tag__, + > IsProviderFor, __Context__, (I, J)> for UseField<__Tag__> + where + __Context__: HasBarType, + __Context__: HasField<__Tag__, Value = __Context__::Bar>, + {} + impl<__Context__, I: Clone, J, __Provider__> BarGetterAt<__Context__, I, J> + for WithProvider<__Provider__> + where + __Context__: HasBarType, + __Provider__: FieldGetter< + __Context__, + BarGetterAtComponent, + Value = __Context__::Bar, + >, + { + fn foo( + __context__: &__Context__, + _phantom: PhantomData<(I, J)>, + ) -> &__Context__::Bar { + __Provider__::get_field( + __context__, + ::core::marker::PhantomData::>, + ) + } + } + impl< + __Context__, + I: Clone, + J, + __Provider__, + > IsProviderFor, __Context__, (I, J)> + for WithProvider<__Provider__> + where + __Context__: HasBarType, + __Provider__: FieldGetter< + __Context__, + BarGetterAtComponent, + Value = __Context__::Bar, + >, + {} + ") + } } #[derive(HasField)] @@ -156,18 +861,70 @@ pub fn test_generic_check_components() { pub dummy: (), } - delegate_components! { - Context { - [ - FooTypeProviderComponent, - BarTypeProviderComponent, - ]: - UseType<()>, - [ - FooGetterAtComponent, - BarGetterAtComponent, - ]: - UseField, + snapshot_delegate_components! { + delegate_components! { + Context { + [ + FooTypeProviderComponent, + BarTypeProviderComponent, + ]: + UseType<()>, + [ + FooGetterAtComponent, + BarGetterAtComponent, + ]: + UseField, + } + } + + expand_context(output) { + assert_snapshot!(output, @r#" + impl DelegateComponent for Context { + type Delegate = UseType<()>; + } + impl< + __Context__, + __Params__, + > IsProviderFor for Context + where + UseType<()>: IsProviderFor, + {} + impl DelegateComponent for Context { + type Delegate = UseType<()>; + } + impl< + __Context__, + __Params__, + > IsProviderFor for Context + where + UseType<()>: IsProviderFor, + {} + impl DelegateComponent for Context { + type Delegate = UseField; + } + impl< + __Context__, + __Params__, + > IsProviderFor for Context + where + UseField< + Symbol!("dummy"), + >: IsProviderFor, + {} + impl DelegateComponent> for Context { + type Delegate = UseField; + } + impl< + I, + __Context__, + __Params__, + > IsProviderFor, __Context__, __Params__> for Context + where + UseField< + Symbol!("dummy"), + >: IsProviderFor, __Context__, __Params__>, + {} + "#) } } diff --git a/crates/tests/cgp-tests/src/tests/delegate_and_check_components.rs b/crates/tests/cgp-tests/src/tests/delegate_and_check_components.rs index b43e2827..8564ef0d 100644 --- a/crates/tests/cgp-tests/src/tests/delegate_and_check_components.rs +++ b/crates/tests/cgp-tests/src/tests/delegate_and_check_components.rs @@ -1,16 +1,164 @@ #![allow(dead_code)] -use cgp::prelude::*; +mod basic_delegate_and_check_components { + use cgp::prelude::*; + use cgp_macro_test_util::snapshot_cgp_getter; + use insta::assert_snapshot; -pub fn test_basic_delegate_and_check_components() { #[cgp_type] pub trait HasNameType { type Name; } - #[cgp_getter] - pub trait HasName: HasNameType { - fn name(&self) -> &Self::Name; + snapshot_cgp_getter! { + #[cgp_getter] + pub trait HasName: HasNameType { + fn name(&self) -> &Self::Name; + } + + expand_has_name(output) { + assert_snapshot!(output, @" + pub trait HasName: HasNameType { + fn name(&self) -> &Self::Name; + } + impl<__Context__> HasName for __Context__ + where + __Context__: HasNameType, + __Context__: NameGetter<__Context__>, + { + fn name(&self) -> &Self::Name { + __Context__::name(self) + } + } + pub trait NameGetter<__Context__>: IsProviderFor + where + __Context__: HasNameType, + { + fn name(__context__: &__Context__) -> &__Context__::Name; + } + impl<__Provider__, __Context__> NameGetter<__Context__> for __Provider__ + where + __Context__: HasNameType, + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + NameGetterComponent, + >>::Delegate: NameGetter<__Context__>, + { + fn name(__context__: &__Context__) -> &__Context__::Name { + <__Provider__ as DelegateComponent< + NameGetterComponent, + >>::Delegate::name(__context__) + } + } + pub struct NameGetterComponent; + impl<__Context__> NameGetter<__Context__> for UseContext + where + __Context__: HasNameType, + __Context__: HasName, + { + fn name(__context__: &__Context__) -> &__Context__::Name { + __Context__::name(__context__) + } + } + impl<__Context__> IsProviderFor for UseContext + where + __Context__: HasNameType, + __Context__: HasName, + {} + impl<__Context__, __Components__, __Path__> NameGetter<__Context__> + for RedirectLookup<__Components__, __Path__> + where + __Context__: HasNameType, + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent<__Path__>>::Delegate: NameGetter<__Context__>, + { + fn name(__context__: &__Context__) -> &__Context__::Name { + <__Components__ as DelegateComponent<__Path__>>::Delegate::name(__context__) + } + } + impl< + __Context__, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Context__: HasNameType, + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: IsProviderFor + + NameGetter<__Context__>, + {} + impl<__Context__> NameGetter<__Context__> for UseFields + where + __Context__: HasNameType, + __Context__: HasField< + Symbol<4, Chars<'n', Chars<'a', Chars<'m', Chars<'e', Nil>>>>>, + Value = __Context__::Name, + >, + { + fn name(__context__: &__Context__) -> &__Context__::Name { + __context__ + .get_field( + ::core::marker::PhantomData::< + Symbol<4, Chars<'n', Chars<'a', Chars<'m', Chars<'e', Nil>>>>>, + >, + ) + } + } + impl<__Context__> IsProviderFor for UseFields + where + __Context__: HasNameType, + __Context__: HasField< + Symbol<4, Chars<'n', Chars<'a', Chars<'m', Chars<'e', Nil>>>>>, + Value = __Context__::Name, + >, + {} + impl<__Context__, __Tag__> NameGetter<__Context__> for UseField<__Tag__> + where + __Context__: HasNameType, + __Context__: HasField<__Tag__, Value = __Context__::Name>, + { + fn name(__context__: &__Context__) -> &__Context__::Name { + __context__.get_field(::core::marker::PhantomData::<__Tag__>) + } + } + impl<__Context__, __Tag__> IsProviderFor + for UseField<__Tag__> + where + __Context__: HasNameType, + __Context__: HasField<__Tag__, Value = __Context__::Name>, + {} + impl<__Context__, __Provider__> NameGetter<__Context__> for WithProvider<__Provider__> + where + __Context__: HasNameType, + __Provider__: FieldGetter< + __Context__, + NameGetterComponent, + Value = __Context__::Name, + >, + { + fn name(__context__: &__Context__) -> &__Context__::Name { + __Provider__::get_field( + __context__, + ::core::marker::PhantomData::, + ) + } + } + impl<__Context__, __Provider__> IsProviderFor + for WithProvider<__Provider__> + where + __Context__: HasNameType, + __Provider__: FieldGetter< + __Context__, + NameGetterComponent, + Value = __Context__::Name, + >, + {} + ") + } } #[derive(HasField)] @@ -27,15 +175,165 @@ pub fn test_basic_delegate_and_check_components() { } } -pub fn test_generic_delegate_and_check_components() { +mod generic_delegate_and_check_components { + use cgp::prelude::*; + use cgp_macro_test_util::snapshot_cgp_getter; + use insta::assert_snapshot; + #[cgp_type] pub trait HasNameType { type Name; } - #[cgp_getter] - pub trait HasName: HasNameType { - fn name(&self) -> &Self::Name; + snapshot_cgp_getter! { + #[cgp_getter] + pub trait HasName: HasNameType { + fn name(&self) -> &Self::Name; + } + + expand_has_name(output) { + assert_snapshot!(output, @" + pub trait HasName: HasNameType { + fn name(&self) -> &Self::Name; + } + impl<__Context__> HasName for __Context__ + where + __Context__: HasNameType, + __Context__: NameGetter<__Context__>, + { + fn name(&self) -> &Self::Name { + __Context__::name(self) + } + } + pub trait NameGetter<__Context__>: IsProviderFor + where + __Context__: HasNameType, + { + fn name(__context__: &__Context__) -> &__Context__::Name; + } + impl<__Provider__, __Context__> NameGetter<__Context__> for __Provider__ + where + __Context__: HasNameType, + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + NameGetterComponent, + >>::Delegate: NameGetter<__Context__>, + { + fn name(__context__: &__Context__) -> &__Context__::Name { + <__Provider__ as DelegateComponent< + NameGetterComponent, + >>::Delegate::name(__context__) + } + } + pub struct NameGetterComponent; + impl<__Context__> NameGetter<__Context__> for UseContext + where + __Context__: HasNameType, + __Context__: HasName, + { + fn name(__context__: &__Context__) -> &__Context__::Name { + __Context__::name(__context__) + } + } + impl<__Context__> IsProviderFor for UseContext + where + __Context__: HasNameType, + __Context__: HasName, + {} + impl<__Context__, __Components__, __Path__> NameGetter<__Context__> + for RedirectLookup<__Components__, __Path__> + where + __Context__: HasNameType, + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent<__Path__>>::Delegate: NameGetter<__Context__>, + { + fn name(__context__: &__Context__) -> &__Context__::Name { + <__Components__ as DelegateComponent<__Path__>>::Delegate::name(__context__) + } + } + impl< + __Context__, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Context__: HasNameType, + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: IsProviderFor + + NameGetter<__Context__>, + {} + impl<__Context__> NameGetter<__Context__> for UseFields + where + __Context__: HasNameType, + __Context__: HasField< + Symbol<4, Chars<'n', Chars<'a', Chars<'m', Chars<'e', Nil>>>>>, + Value = __Context__::Name, + >, + { + fn name(__context__: &__Context__) -> &__Context__::Name { + __context__ + .get_field( + ::core::marker::PhantomData::< + Symbol<4, Chars<'n', Chars<'a', Chars<'m', Chars<'e', Nil>>>>>, + >, + ) + } + } + impl<__Context__> IsProviderFor for UseFields + where + __Context__: HasNameType, + __Context__: HasField< + Symbol<4, Chars<'n', Chars<'a', Chars<'m', Chars<'e', Nil>>>>>, + Value = __Context__::Name, + >, + {} + impl<__Context__, __Tag__> NameGetter<__Context__> for UseField<__Tag__> + where + __Context__: HasNameType, + __Context__: HasField<__Tag__, Value = __Context__::Name>, + { + fn name(__context__: &__Context__) -> &__Context__::Name { + __context__.get_field(::core::marker::PhantomData::<__Tag__>) + } + } + impl<__Context__, __Tag__> IsProviderFor + for UseField<__Tag__> + where + __Context__: HasNameType, + __Context__: HasField<__Tag__, Value = __Context__::Name>, + {} + impl<__Context__, __Provider__> NameGetter<__Context__> for WithProvider<__Provider__> + where + __Context__: HasNameType, + __Provider__: FieldGetter< + __Context__, + NameGetterComponent, + Value = __Context__::Name, + >, + { + fn name(__context__: &__Context__) -> &__Context__::Name { + __Provider__::get_field( + __context__, + ::core::marker::PhantomData::, + ) + } + } + impl<__Context__, __Provider__> IsProviderFor + for WithProvider<__Provider__> + where + __Context__: HasNameType, + __Provider__: FieldGetter< + __Context__, + NameGetterComponent, + Value = __Context__::Name, + >, + {} + ") + } } #[derive(HasField)] diff --git a/crates/tests/cgp-tests/src/tests/has_field/chain.rs b/crates/tests/cgp-tests/src/tests/has_field/chain.rs index 2d6119d9..03721e79 100644 --- a/crates/tests/cgp-tests/src/tests/has_field/chain.rs +++ b/crates/tests/cgp-tests/src/tests/has_field/chain.rs @@ -76,8 +76,12 @@ fn test_chained_getter_with_inner_life() { assert_eq!(name, "test"); } -#[test] -fn test_deeply_nested_getter() { +mod deeply_nested_getter { + use cgp::core::field::impls::ChainGetters; + use cgp::prelude::*; + use cgp_macro_test_util::snapshot_cgp_getter; + use insta::assert_snapshot; + #[derive(HasField)] pub struct A { pub b: B, @@ -103,9 +107,134 @@ fn test_deeply_nested_getter() { pub a: A, } - #[cgp_getter] - pub trait HasName { - fn name(&self) -> &str; + snapshot_cgp_getter! { + #[cgp_getter] + pub trait HasName { + fn name(&self) -> &str; + } + + expand_has_name(output) { + assert_snapshot!(output, @" + pub trait HasName { + fn name(&self) -> &str; + } + impl<__Context__> HasName for __Context__ + where + __Context__: NameGetter<__Context__>, + { + fn name(&self) -> &str { + __Context__::name(self) + } + } + pub trait NameGetter<__Context__>: IsProviderFor { + fn name(__context__: &__Context__) -> &str; + } + impl<__Provider__, __Context__> NameGetter<__Context__> for __Provider__ + where + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + NameGetterComponent, + >>::Delegate: NameGetter<__Context__>, + { + fn name(__context__: &__Context__) -> &str { + <__Provider__ as DelegateComponent< + NameGetterComponent, + >>::Delegate::name(__context__) + } + } + pub struct NameGetterComponent; + impl<__Context__> NameGetter<__Context__> for UseContext + where + __Context__: HasName, + { + fn name(__context__: &__Context__) -> &str { + __Context__::name(__context__) + } + } + impl<__Context__> IsProviderFor for UseContext + where + __Context__: HasName, + {} + impl<__Context__, __Components__, __Path__> NameGetter<__Context__> + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent<__Path__>>::Delegate: NameGetter<__Context__>, + { + fn name(__context__: &__Context__) -> &str { + <__Components__ as DelegateComponent<__Path__>>::Delegate::name(__context__) + } + } + impl< + __Context__, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: IsProviderFor + + NameGetter<__Context__>, + {} + impl<__Context__> NameGetter<__Context__> for UseFields + where + __Context__: HasField< + Symbol<4, Chars<'n', Chars<'a', Chars<'m', Chars<'e', Nil>>>>>, + Value = String, + >, + { + fn name(__context__: &__Context__) -> &str { + __context__ + .get_field( + ::core::marker::PhantomData::< + Symbol<4, Chars<'n', Chars<'a', Chars<'m', Chars<'e', Nil>>>>>, + >, + ) + .as_str() + } + } + impl<__Context__> IsProviderFor for UseFields + where + __Context__: HasField< + Symbol<4, Chars<'n', Chars<'a', Chars<'m', Chars<'e', Nil>>>>>, + Value = String, + >, + {} + impl<__Context__, __Tag__> NameGetter<__Context__> for UseField<__Tag__> + where + __Context__: HasField<__Tag__, Value = String>, + { + fn name(__context__: &__Context__) -> &str { + __context__.get_field(::core::marker::PhantomData::<__Tag__>).as_str() + } + } + impl<__Context__, __Tag__> IsProviderFor + for UseField<__Tag__> + where + __Context__: HasField<__Tag__, Value = String>, + {} + impl<__Context__, __Provider__> NameGetter<__Context__> for WithProvider<__Provider__> + where + __Provider__: FieldGetter<__Context__, NameGetterComponent, Value = String>, + { + fn name(__context__: &__Context__) -> &str { + __Provider__::get_field( + __context__, + ::core::marker::PhantomData::, + ) + .as_str() + } + } + impl<__Context__, __Provider__> IsProviderFor + for WithProvider<__Provider__> + where + __Provider__: FieldGetter<__Context__, NameGetterComponent, Value = String>, + {} + ") + } } delegate_and_check_components! { @@ -121,17 +250,20 @@ fn test_deeply_nested_getter() { } } - let context = MyContext { - a: A { - b: B { - c: C { - d: D { - name: "test".to_owned(), + #[test] + fn test_deeply_nested_getter() { + let context = MyContext { + a: A { + b: B { + c: C { + d: D { + name: "test".to_owned(), + }, }, }, }, - }, - }; + }; - assert_eq!(context.name(), "test"); + assert_eq!(context.name(), "test"); + } } diff --git a/crates/tests/cgp-tests/src/tests/use_delegate/getter.rs b/crates/tests/cgp-tests/src/tests/use_delegate/getter.rs index 01ebf26d..420abf51 100644 --- a/crates/tests/cgp-tests/src/tests/use_delegate/getter.rs +++ b/crates/tests/cgp-tests/src/tests/use_delegate/getter.rs @@ -1,6 +1,8 @@ use core::marker::PhantomData; use cgp::prelude::*; +use cgp_macro_test_util::snapshot_cgp_getter; +use insta::assert_snapshot; pub struct UseDelegate2(pub PhantomData); @@ -15,15 +17,273 @@ pub trait HasFooTypeAt { type Foo; } -#[cgp_getter { - provider: FooGetterAt, - derive_delegate: [ - UseDelegate, - UseDelegate2<(I, J)>, - ], -}] -pub trait HasFooAt: HasFooTypeAt { - fn foo_at(&self, _tag: PhantomData<(I, J)>) -> &Self::Foo; +snapshot_cgp_getter! { + #[cgp_getter { + provider: FooGetterAt, + derive_delegate: [ + UseDelegate, + UseDelegate2<(I, J)>, + ], + }] + pub trait HasFooAt: HasFooTypeAt { + fn foo_at(&self, _tag: PhantomData<(I, J)>) -> &Self::Foo; + } + + expand_has_foo_at(output) { + assert_snapshot!(output, @" + pub trait HasFooAt: HasFooTypeAt { + fn foo_at(&self, _tag: PhantomData<(I, J)>) -> &Self::Foo; + } + impl<__Context__, I, J> HasFooAt for __Context__ + where + __Context__: HasFooTypeAt, + __Context__: FooGetterAt<__Context__, I, J>, + { + fn foo_at(&self, _tag: PhantomData<(I, J)>) -> &Self::Foo { + __Context__::foo_at(self, _tag) + } + } + pub trait FooGetterAt< + __Context__, + I, + J, + >: IsProviderFor + where + __Context__: HasFooTypeAt, + { + fn foo_at(__context__: &__Context__, _tag: PhantomData<(I, J)>) -> &__Context__::Foo; + } + impl<__Provider__, __Context__, I, J> FooGetterAt<__Context__, I, J> for __Provider__ + where + __Context__: HasFooTypeAt, + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + FooGetterAtComponent, + >>::Delegate: FooGetterAt<__Context__, I, J>, + { + fn foo_at( + __context__: &__Context__, + _tag: PhantomData<(I, J)>, + ) -> &__Context__::Foo { + <__Provider__ as DelegateComponent< + FooGetterAtComponent, + >>::Delegate::foo_at(__context__, _tag) + } + } + pub struct FooGetterAtComponent; + impl<__Context__, I, J> FooGetterAt<__Context__, I, J> for UseContext + where + __Context__: HasFooTypeAt, + __Context__: HasFooAt, + { + fn foo_at( + __context__: &__Context__, + _tag: PhantomData<(I, J)>, + ) -> &__Context__::Foo { + __Context__::foo_at(__context__, _tag) + } + } + impl<__Context__, I, J> IsProviderFor + for UseContext + where + __Context__: HasFooTypeAt, + __Context__: HasFooAt, + {} + impl<__Context__, I, J, __Components__, __Path__> FooGetterAt<__Context__, I, J> + for RedirectLookup<__Components__, __Path__> + where + __Context__: HasFooTypeAt, + __Path__: ConcatPath>>, + __Components__: DelegateComponent< + <__Path__ as ConcatPath>>>::Output, + >, + <__Components__ as DelegateComponent< + <__Path__ as ConcatPath>>>::Output, + >>::Delegate: FooGetterAt<__Context__, I, J>, + { + fn foo_at( + __context__: &__Context__, + _tag: PhantomData<(I, J)>, + ) -> &__Context__::Foo { + <__Components__ as DelegateComponent< + <__Path__ as ConcatPath>>>::Output, + >>::Delegate::foo_at(__context__, _tag) + } + } + impl< + __Context__, + I, + J, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Context__: HasFooTypeAt, + __Path__: ConcatPath>>, + __Components__: DelegateComponent< + <__Path__ as ConcatPath>>>::Output, + >, + <__Components__ as DelegateComponent< + <__Path__ as ConcatPath>>>::Output, + >>::Delegate: IsProviderFor + + FooGetterAt<__Context__, I, J>, + {} + impl<__Context__, I, J, __Components__, __Delegate__> FooGetterAt<__Context__, I, J> + for UseDelegate<__Components__> + where + __Context__: HasFooTypeAt, + __Components__: DelegateComponent<(I), Delegate = __Delegate__>, + __Delegate__: FooGetterAt<__Context__, I, J>, + { + fn foo_at( + __context__: &__Context__, + _tag: PhantomData<(I, J)>, + ) -> &__Context__::Foo { + __Delegate__::foo_at(__context__, _tag) + } + } + impl< + __Context__, + I, + J, + __Components__, + __Delegate__, + > IsProviderFor + for UseDelegate<__Components__> + where + __Context__: HasFooTypeAt, + __Components__: DelegateComponent<(I), Delegate = __Delegate__>, + __Delegate__: IsProviderFor + + FooGetterAt<__Context__, I, J>, + {} + impl<__Context__, I, J, __Components__, __Delegate__> FooGetterAt<__Context__, I, J> + for UseDelegate2<__Components__> + where + __Context__: HasFooTypeAt, + __Components__: DelegateComponent<(I, J), Delegate = __Delegate__>, + __Delegate__: FooGetterAt<__Context__, I, J>, + { + fn foo_at( + __context__: &__Context__, + _tag: PhantomData<(I, J)>, + ) -> &__Context__::Foo { + __Delegate__::foo_at(__context__, _tag) + } + } + impl< + __Context__, + I, + J, + __Components__, + __Delegate__, + > IsProviderFor + for UseDelegate2<__Components__> + where + __Context__: HasFooTypeAt, + __Components__: DelegateComponent<(I, J), Delegate = __Delegate__>, + __Delegate__: IsProviderFor + + FooGetterAt<__Context__, I, J>, + {} + impl<__Context__, I, J> FooGetterAt<__Context__, I, J> for UseFields + where + __Context__: HasFooTypeAt, + __Context__: HasField< + Symbol< + 6, + Chars<'f', Chars<'o', Chars<'o', Chars<'_', Chars<'a', Chars<'t', Nil>>>>>>, + >, + Value = __Context__::Foo, + >, + { + fn foo_at( + __context__: &__Context__, + _phantom: PhantomData<(I, J)>, + ) -> &__Context__::Foo { + __context__ + .get_field( + ::core::marker::PhantomData::< + Symbol< + 6, + Chars< + 'f', + Chars< + 'o', + Chars<'o', Chars<'_', Chars<'a', Chars<'t', Nil>>>>, + >, + >, + >, + >, + ) + } + } + impl<__Context__, I, J> IsProviderFor + for UseFields + where + __Context__: HasFooTypeAt, + __Context__: HasField< + Symbol< + 6, + Chars<'f', Chars<'o', Chars<'o', Chars<'_', Chars<'a', Chars<'t', Nil>>>>>>, + >, + Value = __Context__::Foo, + >, + {} + impl<__Context__, I, J, __Tag__> FooGetterAt<__Context__, I, J> for UseField<__Tag__> + where + __Context__: HasFooTypeAt, + __Context__: HasField<__Tag__, Value = __Context__::Foo>, + { + fn foo_at( + __context__: &__Context__, + _phantom: PhantomData<(I, J)>, + ) -> &__Context__::Foo { + __context__.get_field(::core::marker::PhantomData::<__Tag__>) + } + } + impl<__Context__, I, J, __Tag__> IsProviderFor + for UseField<__Tag__> + where + __Context__: HasFooTypeAt, + __Context__: HasField<__Tag__, Value = __Context__::Foo>, + {} + impl<__Context__, I, J, __Provider__> FooGetterAt<__Context__, I, J> + for WithProvider<__Provider__> + where + __Context__: HasFooTypeAt, + __Provider__: FieldGetter< + __Context__, + FooGetterAtComponent, + Value = __Context__::Foo, + >, + { + fn foo_at( + __context__: &__Context__, + _phantom: PhantomData<(I, J)>, + ) -> &__Context__::Foo { + __Provider__::get_field( + __context__, + ::core::marker::PhantomData::, + ) + } + } + impl< + __Context__, + I, + J, + __Provider__, + > IsProviderFor for WithProvider<__Provider__> + where + __Context__: HasFooTypeAt, + __Provider__: FieldGetter< + __Context__, + FooGetterAtComponent, + Value = __Context__::Foo, + >, + {} + ") + } } #[test] @@ -79,28 +339,112 @@ pub fn test_derive_delegate() { assert_eq!(context.foo_at(PhantomData::<(Index<0>, Index<1>)>), "Bar"); } -#[test] -pub fn test_derive_delegate2() { +mod derive_delegate2 { + use core::marker::PhantomData; + + use cgp::prelude::*; + use cgp_macro_test_util::snapshot_delegate_components; + use insta::assert_snapshot; + + use super::*; + #[derive(HasField)] pub struct MyContext { pub foo: u64, pub bar: String, } - delegate_components! { - MyContext { - FooTypeProviderAtComponent: UseDelegate2< - new FooTypes { - (Index<1>, Index<0>): UseType, - (Index<0>, Index<1>): UseType, - } - >, - FooGetterAtComponent: UseDelegate2< - new FooGetters { - (Index<1>, Index<0>): UseField, - (Index<0>, Index<1>): UseField, - } - > + snapshot_delegate_components! { + delegate_components! { + MyContext { + FooTypeProviderAtComponent: UseDelegate2< + new FooTypes { + (Index<1>, Index<0>): UseType, + (Index<0>, Index<1>): UseType, + } + >, + FooGetterAtComponent: UseDelegate2< + new FooGetters { + (Index<1>, Index<0>): UseField, + (Index<0>, Index<1>): UseField, + } + > + } + } + + expand_my_context(output) { + assert_snapshot!(output, @r#" + pub struct FooTypes; + pub struct FooGetters; + impl DelegateComponent for MyContext { + type Delegate = UseDelegate2; + } + impl< + __Context__, + __Params__, + > IsProviderFor for MyContext + where + UseDelegate2< + FooTypes, + >: IsProviderFor, + {} + impl DelegateComponent for MyContext { + type Delegate = UseDelegate2; + } + impl< + __Context__, + __Params__, + > IsProviderFor for MyContext + where + UseDelegate2< + FooGetters, + >: IsProviderFor, + {} + impl DelegateComponent<(Index<1>, Index<0>)> for FooTypes { + type Delegate = UseType; + } + impl< + __Context__, + __Params__, + > IsProviderFor<(Index<1>, Index<0>), __Context__, __Params__> for FooTypes + where + UseType: IsProviderFor<(Index<1>, Index<0>), __Context__, __Params__>, + {} + impl DelegateComponent<(Index<0>, Index<1>)> for FooTypes { + type Delegate = UseType; + } + impl< + __Context__, + __Params__, + > IsProviderFor<(Index<0>, Index<1>), __Context__, __Params__> for FooTypes + where + UseType: IsProviderFor<(Index<0>, Index<1>), __Context__, __Params__>, + {} + impl DelegateComponent<(Index<1>, Index<0>)> for FooGetters { + type Delegate = UseField; + } + impl< + __Context__, + __Params__, + > IsProviderFor<(Index<1>, Index<0>), __Context__, __Params__> for FooGetters + where + UseField< + Symbol!("foo"), + >: IsProviderFor<(Index<1>, Index<0>), __Context__, __Params__>, + {} + impl DelegateComponent<(Index<0>, Index<1>)> for FooGetters { + type Delegate = UseField; + } + impl< + __Context__, + __Params__, + > IsProviderFor<(Index<0>, Index<1>), __Context__, __Params__> for FooGetters + where + UseField< + Symbol!("bar"), + >: IsProviderFor<(Index<0>, Index<1>), __Context__, __Params__>, + {} + "#) } } @@ -113,11 +457,14 @@ pub fn test_derive_delegate2() { } } - let context = MyContext { - foo: 42, - bar: "Bar".into(), - }; + #[test] + pub fn test_derive_delegate2() { + let context = MyContext { + foo: 42, + bar: "Bar".into(), + }; - assert_eq!(context.foo_at(PhantomData::<(Index<1>, Index<0>)>), &42); - assert_eq!(context.foo_at(PhantomData::<(Index<0>, Index<1>)>), "Bar"); + assert_eq!(context.foo_at(PhantomData::<(Index<1>, Index<0>)>), &42); + assert_eq!(context.foo_at(PhantomData::<(Index<0>, Index<1>)>), "Bar"); + } } diff --git a/crates/tests/cgp-tests/tests/cgp_fn_tests/use_provider.rs b/crates/tests/cgp-tests/tests/cgp_fn_tests/use_provider.rs index b6f32b2f..1aec333b 100644 --- a/crates/tests/cgp-tests/tests/cgp_fn_tests/use_provider.rs +++ b/crates/tests/cgp-tests/tests/cgp_fn_tests/use_provider.rs @@ -1,14 +1,164 @@ use cgp::prelude::*; +use cgp_macro_test_util::{snapshot_cgp_component, snapshot_cgp_impl}; +use insta::assert_snapshot; -#[cgp_component(AreaCalculator)] -pub trait CanCalculateArea { - fn area(&self) -> f64; +snapshot_cgp_component! { + #[cgp_component(AreaCalculator)] + pub trait CanCalculateArea { + fn area(&self) -> f64; + } + + expand_can_calculate_area(output) { + assert_snapshot!(output, @" + pub trait CanCalculateArea { + fn area(&self) -> f64; + } + impl<__Context__> CanCalculateArea for __Context__ + where + __Context__: AreaCalculator<__Context__>, + { + fn area(&self) -> f64 { + __Context__::area(self) + } + } + pub trait AreaCalculator< + __Context__, + >: IsProviderFor { + fn area(__context__: &__Context__) -> f64; + } + impl<__Provider__, __Context__> AreaCalculator<__Context__> for __Provider__ + where + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + AreaCalculatorComponent, + >>::Delegate: AreaCalculator<__Context__>, + { + fn area(__context__: &__Context__) -> f64 { + <__Provider__ as DelegateComponent< + AreaCalculatorComponent, + >>::Delegate::area(__context__) + } + } + pub struct AreaCalculatorComponent; + impl<__Context__> AreaCalculator<__Context__> for UseContext + where + __Context__: CanCalculateArea, + { + fn area(__context__: &__Context__) -> f64 { + __Context__::area(__context__) + } + } + impl<__Context__> IsProviderFor for UseContext + where + __Context__: CanCalculateArea, + {} + impl<__Context__, __Components__, __Path__> AreaCalculator<__Context__> + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: AreaCalculator<__Context__>, + { + fn area(__context__: &__Context__) -> f64 { + <__Components__ as DelegateComponent<__Path__>>::Delegate::area(__context__) + } + } + impl< + __Context__, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: IsProviderFor + + AreaCalculator<__Context__>, + {} + ") + } } -#[cgp_impl(new RectangleAreaCalculator)] -impl AreaCalculator { - fn area(&self, #[implicit] width: f64, #[implicit] height: f64) -> f64 { - width * height +snapshot_cgp_impl! { + #[cgp_impl(new RectangleAreaCalculator)] + impl AreaCalculator { + fn area(&self, #[implicit] width: f64, #[implicit] height: f64) -> f64 { + width * height + } + } + + expand_rectangle_area_calculator(output) { + assert_snapshot!(output, @" + impl<__Context__> AreaCalculator<__Context__> for RectangleAreaCalculator + where + __Context__: HasField< + Symbol<5, Chars<'w', Chars<'i', Chars<'d', Chars<'t', Chars<'h', Nil>>>>>>, + Value = f64, + > + + HasField< + Symbol< + 6, + Chars< + 'h', + Chars<'e', Chars<'i', Chars<'g', Chars<'h', Chars<'t', Nil>>>>>, + >, + >, + Value = f64, + >, + { + fn area(__context__: &__Context__) -> f64 { + let width: f64 = __context__ + .get_field( + ::core::marker::PhantomData::< + Symbol< + 5, + Chars<'w', Chars<'i', Chars<'d', Chars<'t', Chars<'h', Nil>>>>>, + >, + >, + ) + .clone(); + let height: f64 = __context__ + .get_field( + ::core::marker::PhantomData::< + Symbol< + 6, + Chars< + 'h', + Chars< + 'e', + Chars<'i', Chars<'g', Chars<'h', Chars<'t', Nil>>>>, + >, + >, + >, + >, + ) + .clone(); + width * height + } + } + impl<__Context__> IsProviderFor + for RectangleAreaCalculator + where + __Context__: HasField< + Symbol<5, Chars<'w', Chars<'i', Chars<'d', Chars<'t', Chars<'h', Nil>>>>>>, + Value = f64, + > + + HasField< + Symbol< + 6, + Chars< + 'h', + Chars<'e', Chars<'i', Chars<'g', Chars<'h', Chars<'t', Nil>>>>>, + >, + >, + Value = f64, + >, + {} + pub struct RectangleAreaCalculator; + ") } } diff --git a/crates/tests/cgp-tests/tests/extensible_data_tests/records/basic.rs b/crates/tests/cgp-tests/tests/extensible_data_tests/records/basic.rs index b92f06ff..0b0e52c0 100644 --- a/crates/tests/cgp-tests/tests/extensible_data_tests/records/basic.rs +++ b/crates/tests/cgp-tests/tests/extensible_data_tests/records/basic.rs @@ -6,6 +6,8 @@ use cgp::core::field::impls::CanBuildFrom; use cgp::extra::dispatch::{BuildAndMerge, BuildAndSetField, BuildWithHandlers}; use cgp::extra::handler::{Computer, Producer, ProducerComponent}; use cgp::prelude::*; +use cgp_macro_test_util::snapshot_delegate_components; +use insta::assert_snapshot; #[derive(Debug, Eq, PartialEq, CgpData)] pub struct FooBarBaz { @@ -82,9 +84,28 @@ pub fn build_baz() -> bool { pub struct App; -delegate_components! { - App { - ErrorTypeProviderComponent: UseType, +snapshot_delegate_components! { + delegate_components! { + App { + ErrorTypeProviderComponent: UseType, + } + } + + expand_app(output) { + assert_snapshot!(output, @" + impl DelegateComponent for App { + type Delegate = UseType; + } + impl< + __Context__, + __Params__, + > IsProviderFor for App + where + UseType< + Infallible, + >: IsProviderFor, + {} + ") } } diff --git a/crates/tests/cgp-tests/tests/extensible_data_tests/variants/basic.rs b/crates/tests/cgp-tests/tests/extensible_data_tests/variants/basic.rs index c546dade..3ebad849 100644 --- a/crates/tests/cgp-tests/tests/extensible_data_tests/variants/basic.rs +++ b/crates/tests/cgp-tests/tests/extensible_data_tests/variants/basic.rs @@ -12,7 +12,9 @@ use cgp::extra::handler::{ Computer, ComputerComponent, ComputerRef, ComputerRefComponent, PromoteAsync, }; use cgp::prelude::*; +use cgp_macro_test_util::snapshot_delegate_components; use futures::executor::block_on; +use insta::assert_snapshot; #[derive(Debug, Eq, PartialEq, CgpData)] pub enum FooBarBaz { @@ -127,9 +129,28 @@ fn test_downcast() { pub struct App; -delegate_components! { - App { - ErrorTypeProviderComponent: UseType, +snapshot_delegate_components! { + delegate_components! { + App { + ErrorTypeProviderComponent: UseType, + } + } + + expand_app(output) { + assert_snapshot!(output, @" + impl DelegateComponent for App { + type Delegate = UseType; + } + impl< + __Context__, + __Params__, + > IsProviderFor for App + where + UseType< + Infallible, + >: IsProviderFor, + {} + ") } } diff --git a/crates/tests/cgp-tests/tests/extensible_data_tests/variants/shape.rs b/crates/tests/cgp-tests/tests/extensible_data_tests/variants/shape.rs index 83c07bb5..782fa19a 100644 --- a/crates/tests/cgp-tests/tests/extensible_data_tests/variants/shape.rs +++ b/crates/tests/cgp-tests/tests/extensible_data_tests/variants/shape.rs @@ -8,6 +8,8 @@ use cgp::extra::dispatch::{ }; use cgp::extra::handler::{NoCode, UseInputDelegate}; use cgp::prelude::*; +use cgp_macro_test_util::snapshot_delegate_components; +use insta::assert_snapshot; #[derive(Debug, PartialEq, CgpData)] pub enum Shape { @@ -187,20 +189,78 @@ fn test_dispatch_contains() { pub struct App; -delegate_components! { - App { - ComputerComponent: UseInputDelegate +snapshot_delegate_components! { + delegate_components! { + App { + ComputerComponent: UseInputDelegate + } + } + + expand_app(output) { + assert_snapshot!(output, @" + pub struct AreaComputers; + impl DelegateComponent for App { + type Delegate = UseInputDelegate; + } + impl<__Context__, __Params__> IsProviderFor + for App + where + UseInputDelegate< + AreaComputers, + >: IsProviderFor, + {} + impl DelegateComponent for AreaComputers { + type Delegate = ComputeArea; + } + impl<__Context__, __Params__> IsProviderFor + for AreaComputers + where + ComputeArea: IsProviderFor, + {} + impl DelegateComponent for AreaComputers { + type Delegate = ComputeArea; + } + impl<__Context__, __Params__> IsProviderFor + for AreaComputers + where + ComputeArea: IsProviderFor, + {} + impl DelegateComponent for AreaComputers { + type Delegate = ComputeArea; + } + impl<__Context__, __Params__> IsProviderFor + for AreaComputers + where + ComputeArea: IsProviderFor, + {} + impl DelegateComponent for AreaComputers { + type Delegate = MatchWithValueHandlers; + } + impl<__Context__, __Params__> IsProviderFor + for AreaComputers + where + MatchWithValueHandlers: IsProviderFor, + {} + impl DelegateComponent for AreaComputers { + type Delegate = MatchWithValueHandlers; + } + impl<__Context__, __Params__> IsProviderFor + for AreaComputers + where + MatchWithValueHandlers: IsProviderFor, + {} + ") } } diff --git a/crates/tests/cgp-tests/tests/getter_tests/abstract_type/explicit.rs b/crates/tests/cgp-tests/tests/getter_tests/abstract_type/explicit.rs index 813b02cb..53276ebd 100644 --- a/crates/tests/cgp-tests/tests/getter_tests/abstract_type/explicit.rs +++ b/crates/tests/cgp-tests/tests/getter_tests/abstract_type/explicit.rs @@ -1,62 +1,242 @@ use cgp::prelude::*; +use cgp_macro_test_util::{snapshot_cgp_auto_getter, snapshot_cgp_getter}; +use insta::assert_snapshot; -#[test] -pub fn test_abstract_type_getter() { - #[cgp_type] - pub trait HasNameType { - type Name; - } +#[cgp_type] +pub trait HasScalarType { + type Scalar: Copy; +} - #[cgp_getter] - pub trait HasName: HasNameType { - fn name(&self) -> &Self::Name; - } +snapshot_cgp_auto_getter! { + #[cgp_auto_getter] + #[extend(HasScalarType)] + pub trait AutoRectangleFields { + fn width(&self) -> Self::Scalar; - #[derive(HasField)] - pub struct App { - pub name: String, + fn height(&self) -> Self::Scalar; } - delegate_components! { - App { - NameTypeProviderComponent: UseType, - NameGetterComponent: UseField, + expand_auto_rectangle_fields(output) { + assert_snapshot!(output, @" + pub trait AutoRectangleFields: HasScalarType { + fn width(&self) -> Self::Scalar; + fn height(&self) -> Self::Scalar; + } + impl<__Context__> AutoRectangleFields for __Context__ + where + __Context__: HasScalarType, + __Context__: HasField< + Symbol<5, Chars<'w', Chars<'i', Chars<'d', Chars<'t', Chars<'h', Nil>>>>>>, + Value = __Context__::Scalar, + >, + __Context__: HasField< + Symbol< + 6, + Chars<'h', Chars<'e', Chars<'i', Chars<'g', Chars<'h', Chars<'t', Nil>>>>>>, + >, + Value = __Context__::Scalar, + >, + { + fn width(&self) -> __Context__::Scalar { + self.get_field( + ::core::marker::PhantomData::< + Symbol< + 5, + Chars<'w', Chars<'i', Chars<'d', Chars<'t', Chars<'h', Nil>>>>>, + >, + >, + ) + .clone() + } + fn height(&self) -> __Context__::Scalar { + self.get_field( + ::core::marker::PhantomData::< + Symbol< + 6, + Chars< + 'h', + Chars< + 'e', + Chars<'i', Chars<'g', Chars<'h', Chars<'t', Nil>>>>, + >, + >, + >, + >, + ) + .clone() + } } + ") } - - let context = App { - name: "Alice".to_owned(), - }; - - assert_eq!(context.name(), "Alice"); } -#[test] -pub fn test_abstract_type_auto_getter() { - #[cgp_type] - pub trait HasNameType { - type Name; - } +snapshot_cgp_getter! { + #[cgp_getter(RectangleFieldsGetter)] + #[extend(HasScalarType)] + pub trait HasRectangleFields { + fn width(&self) -> Self::Scalar; - #[cgp_auto_getter] - pub trait HasName: HasNameType { - fn name(&self) -> &Self::Name; + fn height(&self) -> Self::Scalar; } - #[derive(HasField)] - pub struct App { - pub name: String, - } - - delegate_components! { - App { - NameTypeProviderComponent: UseType, + expand_has_rectangle_fields(output) { + assert_snapshot!(output, @" + pub trait HasRectangleFields: HasScalarType { + fn width(&self) -> Self::Scalar; + fn height(&self) -> Self::Scalar; + } + impl<__Context__> HasRectangleFields for __Context__ + where + __Context__: HasScalarType, + __Context__: RectangleFieldsGetter<__Context__>, + { + fn width(&self) -> Self::Scalar { + __Context__::width(self) + } + fn height(&self) -> Self::Scalar { + __Context__::height(self) + } + } + pub trait RectangleFieldsGetter< + __Context__, + >: IsProviderFor + where + __Context__: HasScalarType, + { + fn width(__context__: &__Context__) -> __Context__::Scalar; + fn height(__context__: &__Context__) -> __Context__::Scalar; + } + impl<__Provider__, __Context__> RectangleFieldsGetter<__Context__> for __Provider__ + where + __Context__: HasScalarType, + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + RectangleFieldsGetterComponent, + >>::Delegate: RectangleFieldsGetter<__Context__>, + { + fn width(__context__: &__Context__) -> __Context__::Scalar { + <__Provider__ as DelegateComponent< + RectangleFieldsGetterComponent, + >>::Delegate::width(__context__) + } + fn height(__context__: &__Context__) -> __Context__::Scalar { + <__Provider__ as DelegateComponent< + RectangleFieldsGetterComponent, + >>::Delegate::height(__context__) + } + } + pub struct RectangleFieldsGetterComponent; + impl<__Context__> RectangleFieldsGetter<__Context__> for UseContext + where + __Context__: HasScalarType, + __Context__: HasRectangleFields, + { + fn width(__context__: &__Context__) -> __Context__::Scalar { + __Context__::width(__context__) + } + fn height(__context__: &__Context__) -> __Context__::Scalar { + __Context__::height(__context__) + } } + impl<__Context__> IsProviderFor + for UseContext + where + __Context__: HasScalarType, + __Context__: HasRectangleFields, + {} + impl<__Context__, __Components__, __Path__> RectangleFieldsGetter<__Context__> + for RedirectLookup<__Components__, __Path__> + where + __Context__: HasScalarType, + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: RectangleFieldsGetter<__Context__>, + { + fn width(__context__: &__Context__) -> __Context__::Scalar { + <__Components__ as DelegateComponent<__Path__>>::Delegate::width(__context__) + } + fn height(__context__: &__Context__) -> __Context__::Scalar { + <__Components__ as DelegateComponent<__Path__>>::Delegate::height(__context__) + } + } + impl< + __Context__, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Context__: HasScalarType, + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: IsProviderFor + + RectangleFieldsGetter<__Context__>, + {} + impl<__Context__> RectangleFieldsGetter<__Context__> for UseFields + where + __Context__: HasScalarType, + __Context__: HasField< + Symbol<5, Chars<'w', Chars<'i', Chars<'d', Chars<'t', Chars<'h', Nil>>>>>>, + Value = __Context__::Scalar, + >, + __Context__: HasField< + Symbol< + 6, + Chars<'h', Chars<'e', Chars<'i', Chars<'g', Chars<'h', Chars<'t', Nil>>>>>>, + >, + Value = __Context__::Scalar, + >, + { + fn width(__context__: &__Context__) -> __Context__::Scalar { + __context__ + .get_field( + ::core::marker::PhantomData::< + Symbol< + 5, + Chars<'w', Chars<'i', Chars<'d', Chars<'t', Chars<'h', Nil>>>>>, + >, + >, + ) + .clone() + } + fn height(__context__: &__Context__) -> __Context__::Scalar { + __context__ + .get_field( + ::core::marker::PhantomData::< + Symbol< + 6, + Chars< + 'h', + Chars< + 'e', + Chars<'i', Chars<'g', Chars<'h', Chars<'t', Nil>>>>, + >, + >, + >, + >, + ) + .clone() + } + } + impl<__Context__> IsProviderFor + for UseFields + where + __Context__: HasScalarType, + __Context__: HasField< + Symbol<5, Chars<'w', Chars<'i', Chars<'d', Chars<'t', Chars<'h', Nil>>>>>>, + Value = __Context__::Scalar, + >, + __Context__: HasField< + Symbol< + 6, + Chars<'h', Chars<'e', Chars<'i', Chars<'g', Chars<'h', Chars<'t', Nil>>>>>>, + >, + Value = __Context__::Scalar, + >, + {} + ") } - - let context = App { - name: "Alice".to_owned(), - }; - - assert_eq!(context.name(), "Alice"); } diff --git a/crates/tests/cgp-tests/tests/getter_tests/abstract_type/import.rs b/crates/tests/cgp-tests/tests/getter_tests/abstract_type/import.rs index 87e1c178..b94a9830 100644 --- a/crates/tests/cgp-tests/tests/getter_tests/abstract_type/import.rs +++ b/crates/tests/cgp-tests/tests/getter_tests/abstract_type/import.rs @@ -1,22 +1,242 @@ use cgp::prelude::*; +use cgp_macro_test_util::{snapshot_cgp_auto_getter, snapshot_cgp_getter}; +use insta::assert_snapshot; #[cgp_type] pub trait HasScalarType { type Scalar: Copy; } -#[cgp_auto_getter] -#[extend(HasScalarType)] -pub trait AutoRectangleFields { - fn width(&self) -> Self::Scalar; +snapshot_cgp_auto_getter! { + #[cgp_auto_getter] + #[use_type(HasScalarType::Scalar)] + pub trait AutoRectangleFields { + fn width(&self) -> Scalar; - fn height(&self) -> Self::Scalar; + fn height(&self) -> Scalar; + } + + expand_auto_rectangle_fields(output) { + assert_snapshot!(output, @" + pub trait AutoRectangleFields: HasScalarType { + fn width(&self) -> ::Scalar; + fn height(&self) -> ::Scalar; + } + impl<__Context__> AutoRectangleFields for __Context__ + where + __Context__: HasScalarType, + __Context__: HasField< + Symbol<5, Chars<'w', Chars<'i', Chars<'d', Chars<'t', Chars<'h', Nil>>>>>>, + Value = <__Context__ as HasScalarType>::Scalar, + >, + __Context__: HasField< + Symbol< + 6, + Chars<'h', Chars<'e', Chars<'i', Chars<'g', Chars<'h', Chars<'t', Nil>>>>>>, + >, + Value = <__Context__ as HasScalarType>::Scalar, + >, + { + fn width(&self) -> <__Context__ as HasScalarType>::Scalar { + self.get_field( + ::core::marker::PhantomData::< + Symbol< + 5, + Chars<'w', Chars<'i', Chars<'d', Chars<'t', Chars<'h', Nil>>>>>, + >, + >, + ) + .clone() + } + fn height(&self) -> <__Context__ as HasScalarType>::Scalar { + self.get_field( + ::core::marker::PhantomData::< + Symbol< + 6, + Chars< + 'h', + Chars< + 'e', + Chars<'i', Chars<'g', Chars<'h', Chars<'t', Nil>>>>, + >, + >, + >, + >, + ) + .clone() + } + } + ") + } } -#[cgp_getter(RectangleFieldsGetter)] -#[extend(HasScalarType)] -pub trait HasRectangleFields { - fn width(&self) -> Self::Scalar; +snapshot_cgp_getter! { + #[cgp_getter(RectangleFieldsGetter)] + #[use_type(HasScalarType::Scalar)] + pub trait HasRectangleFields { + fn width(&self) -> Scalar; + + fn height(&self) -> Scalar; + } - fn height(&self) -> Self::Scalar; + expand_has_rectangle_fields(output) { + assert_snapshot!(output, @" + pub trait HasRectangleFields: HasScalarType { + fn width(&self) -> ::Scalar; + fn height(&self) -> ::Scalar; + } + impl<__Context__> HasRectangleFields for __Context__ + where + __Context__: HasScalarType, + __Context__: RectangleFieldsGetter<__Context__>, + { + fn width(&self) -> ::Scalar { + __Context__::width(self) + } + fn height(&self) -> ::Scalar { + __Context__::height(self) + } + } + pub trait RectangleFieldsGetter< + __Context__, + >: IsProviderFor + where + __Context__: HasScalarType, + { + fn width(__context__: &__Context__) -> <__Context__ as HasScalarType>::Scalar; + fn height(__context__: &__Context__) -> <__Context__ as HasScalarType>::Scalar; + } + impl<__Provider__, __Context__> RectangleFieldsGetter<__Context__> for __Provider__ + where + __Context__: HasScalarType, + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + RectangleFieldsGetterComponent, + >>::Delegate: RectangleFieldsGetter<__Context__>, + { + fn width(__context__: &__Context__) -> <__Context__ as HasScalarType>::Scalar { + <__Provider__ as DelegateComponent< + RectangleFieldsGetterComponent, + >>::Delegate::width(__context__) + } + fn height(__context__: &__Context__) -> <__Context__ as HasScalarType>::Scalar { + <__Provider__ as DelegateComponent< + RectangleFieldsGetterComponent, + >>::Delegate::height(__context__) + } + } + pub struct RectangleFieldsGetterComponent; + impl<__Context__> RectangleFieldsGetter<__Context__> for UseContext + where + __Context__: HasScalarType, + __Context__: HasRectangleFields, + { + fn width(__context__: &__Context__) -> <__Context__ as HasScalarType>::Scalar { + __Context__::width(__context__) + } + fn height(__context__: &__Context__) -> <__Context__ as HasScalarType>::Scalar { + __Context__::height(__context__) + } + } + impl<__Context__> IsProviderFor + for UseContext + where + __Context__: HasScalarType, + __Context__: HasRectangleFields, + {} + impl<__Context__, __Components__, __Path__> RectangleFieldsGetter<__Context__> + for RedirectLookup<__Components__, __Path__> + where + __Context__: HasScalarType, + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: RectangleFieldsGetter<__Context__>, + { + fn width(__context__: &__Context__) -> <__Context__ as HasScalarType>::Scalar { + <__Components__ as DelegateComponent<__Path__>>::Delegate::width(__context__) + } + fn height(__context__: &__Context__) -> <__Context__ as HasScalarType>::Scalar { + <__Components__ as DelegateComponent<__Path__>>::Delegate::height(__context__) + } + } + impl< + __Context__, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Context__: HasScalarType, + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: IsProviderFor + + RectangleFieldsGetter<__Context__>, + {} + impl<__Context__> RectangleFieldsGetter<__Context__> for UseFields + where + __Context__: HasScalarType, + __Context__: HasField< + Symbol<5, Chars<'w', Chars<'i', Chars<'d', Chars<'t', Chars<'h', Nil>>>>>>, + Value = <__Context__ as HasScalarType>::Scalar, + >, + __Context__: HasField< + Symbol< + 6, + Chars<'h', Chars<'e', Chars<'i', Chars<'g', Chars<'h', Chars<'t', Nil>>>>>>, + >, + Value = <__Context__ as HasScalarType>::Scalar, + >, + { + fn width(__context__: &__Context__) -> <__Context__ as HasScalarType>::Scalar { + __context__ + .get_field( + ::core::marker::PhantomData::< + Symbol< + 5, + Chars<'w', Chars<'i', Chars<'d', Chars<'t', Chars<'h', Nil>>>>>, + >, + >, + ) + .clone() + } + fn height(__context__: &__Context__) -> <__Context__ as HasScalarType>::Scalar { + __context__ + .get_field( + ::core::marker::PhantomData::< + Symbol< + 6, + Chars< + 'h', + Chars< + 'e', + Chars<'i', Chars<'g', Chars<'h', Chars<'t', Nil>>>>, + >, + >, + >, + >, + ) + .clone() + } + } + impl<__Context__> IsProviderFor + for UseFields + where + __Context__: HasScalarType, + __Context__: HasField< + Symbol<5, Chars<'w', Chars<'i', Chars<'d', Chars<'t', Chars<'h', Nil>>>>>>, + Value = <__Context__ as HasScalarType>::Scalar, + >, + __Context__: HasField< + Symbol< + 6, + Chars<'h', Chars<'e', Chars<'i', Chars<'g', Chars<'h', Chars<'t', Nil>>>>>>, + >, + Value = <__Context__ as HasScalarType>::Scalar, + >, + {} + ") + } } diff --git a/crates/tests/cgp-tests/tests/getter_tests/abstract_type/use_type.rs b/crates/tests/cgp-tests/tests/getter_tests/abstract_type/use_type.rs index bee751e3..b94a9830 100644 --- a/crates/tests/cgp-tests/tests/getter_tests/abstract_type/use_type.rs +++ b/crates/tests/cgp-tests/tests/getter_tests/abstract_type/use_type.rs @@ -1,22 +1,242 @@ use cgp::prelude::*; +use cgp_macro_test_util::{snapshot_cgp_auto_getter, snapshot_cgp_getter}; +use insta::assert_snapshot; #[cgp_type] pub trait HasScalarType { type Scalar: Copy; } -#[cgp_auto_getter] -#[use_type(HasScalarType::Scalar)] -pub trait AutoRectangleFields { - fn width(&self) -> Scalar; +snapshot_cgp_auto_getter! { + #[cgp_auto_getter] + #[use_type(HasScalarType::Scalar)] + pub trait AutoRectangleFields { + fn width(&self) -> Scalar; - fn height(&self) -> Scalar; + fn height(&self) -> Scalar; + } + + expand_auto_rectangle_fields(output) { + assert_snapshot!(output, @" + pub trait AutoRectangleFields: HasScalarType { + fn width(&self) -> ::Scalar; + fn height(&self) -> ::Scalar; + } + impl<__Context__> AutoRectangleFields for __Context__ + where + __Context__: HasScalarType, + __Context__: HasField< + Symbol<5, Chars<'w', Chars<'i', Chars<'d', Chars<'t', Chars<'h', Nil>>>>>>, + Value = <__Context__ as HasScalarType>::Scalar, + >, + __Context__: HasField< + Symbol< + 6, + Chars<'h', Chars<'e', Chars<'i', Chars<'g', Chars<'h', Chars<'t', Nil>>>>>>, + >, + Value = <__Context__ as HasScalarType>::Scalar, + >, + { + fn width(&self) -> <__Context__ as HasScalarType>::Scalar { + self.get_field( + ::core::marker::PhantomData::< + Symbol< + 5, + Chars<'w', Chars<'i', Chars<'d', Chars<'t', Chars<'h', Nil>>>>>, + >, + >, + ) + .clone() + } + fn height(&self) -> <__Context__ as HasScalarType>::Scalar { + self.get_field( + ::core::marker::PhantomData::< + Symbol< + 6, + Chars< + 'h', + Chars< + 'e', + Chars<'i', Chars<'g', Chars<'h', Chars<'t', Nil>>>>, + >, + >, + >, + >, + ) + .clone() + } + } + ") + } } -#[cgp_getter(RectangleFieldsGetter)] -#[use_type(HasScalarType::Scalar)] -pub trait HasRectangleFields { - fn width(&self) -> Scalar; +snapshot_cgp_getter! { + #[cgp_getter(RectangleFieldsGetter)] + #[use_type(HasScalarType::Scalar)] + pub trait HasRectangleFields { + fn width(&self) -> Scalar; + + fn height(&self) -> Scalar; + } - fn height(&self) -> Scalar; + expand_has_rectangle_fields(output) { + assert_snapshot!(output, @" + pub trait HasRectangleFields: HasScalarType { + fn width(&self) -> ::Scalar; + fn height(&self) -> ::Scalar; + } + impl<__Context__> HasRectangleFields for __Context__ + where + __Context__: HasScalarType, + __Context__: RectangleFieldsGetter<__Context__>, + { + fn width(&self) -> ::Scalar { + __Context__::width(self) + } + fn height(&self) -> ::Scalar { + __Context__::height(self) + } + } + pub trait RectangleFieldsGetter< + __Context__, + >: IsProviderFor + where + __Context__: HasScalarType, + { + fn width(__context__: &__Context__) -> <__Context__ as HasScalarType>::Scalar; + fn height(__context__: &__Context__) -> <__Context__ as HasScalarType>::Scalar; + } + impl<__Provider__, __Context__> RectangleFieldsGetter<__Context__> for __Provider__ + where + __Context__: HasScalarType, + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + RectangleFieldsGetterComponent, + >>::Delegate: RectangleFieldsGetter<__Context__>, + { + fn width(__context__: &__Context__) -> <__Context__ as HasScalarType>::Scalar { + <__Provider__ as DelegateComponent< + RectangleFieldsGetterComponent, + >>::Delegate::width(__context__) + } + fn height(__context__: &__Context__) -> <__Context__ as HasScalarType>::Scalar { + <__Provider__ as DelegateComponent< + RectangleFieldsGetterComponent, + >>::Delegate::height(__context__) + } + } + pub struct RectangleFieldsGetterComponent; + impl<__Context__> RectangleFieldsGetter<__Context__> for UseContext + where + __Context__: HasScalarType, + __Context__: HasRectangleFields, + { + fn width(__context__: &__Context__) -> <__Context__ as HasScalarType>::Scalar { + __Context__::width(__context__) + } + fn height(__context__: &__Context__) -> <__Context__ as HasScalarType>::Scalar { + __Context__::height(__context__) + } + } + impl<__Context__> IsProviderFor + for UseContext + where + __Context__: HasScalarType, + __Context__: HasRectangleFields, + {} + impl<__Context__, __Components__, __Path__> RectangleFieldsGetter<__Context__> + for RedirectLookup<__Components__, __Path__> + where + __Context__: HasScalarType, + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: RectangleFieldsGetter<__Context__>, + { + fn width(__context__: &__Context__) -> <__Context__ as HasScalarType>::Scalar { + <__Components__ as DelegateComponent<__Path__>>::Delegate::width(__context__) + } + fn height(__context__: &__Context__) -> <__Context__ as HasScalarType>::Scalar { + <__Components__ as DelegateComponent<__Path__>>::Delegate::height(__context__) + } + } + impl< + __Context__, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Context__: HasScalarType, + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: IsProviderFor + + RectangleFieldsGetter<__Context__>, + {} + impl<__Context__> RectangleFieldsGetter<__Context__> for UseFields + where + __Context__: HasScalarType, + __Context__: HasField< + Symbol<5, Chars<'w', Chars<'i', Chars<'d', Chars<'t', Chars<'h', Nil>>>>>>, + Value = <__Context__ as HasScalarType>::Scalar, + >, + __Context__: HasField< + Symbol< + 6, + Chars<'h', Chars<'e', Chars<'i', Chars<'g', Chars<'h', Chars<'t', Nil>>>>>>, + >, + Value = <__Context__ as HasScalarType>::Scalar, + >, + { + fn width(__context__: &__Context__) -> <__Context__ as HasScalarType>::Scalar { + __context__ + .get_field( + ::core::marker::PhantomData::< + Symbol< + 5, + Chars<'w', Chars<'i', Chars<'d', Chars<'t', Chars<'h', Nil>>>>>, + >, + >, + ) + .clone() + } + fn height(__context__: &__Context__) -> <__Context__ as HasScalarType>::Scalar { + __context__ + .get_field( + ::core::marker::PhantomData::< + Symbol< + 6, + Chars< + 'h', + Chars< + 'e', + Chars<'i', Chars<'g', Chars<'h', Chars<'t', Nil>>>>, + >, + >, + >, + >, + ) + .clone() + } + } + impl<__Context__> IsProviderFor + for UseFields + where + __Context__: HasScalarType, + __Context__: HasField< + Symbol<5, Chars<'w', Chars<'i', Chars<'d', Chars<'t', Chars<'h', Nil>>>>>>, + Value = <__Context__ as HasScalarType>::Scalar, + >, + __Context__: HasField< + Symbol< + 6, + Chars<'h', Chars<'e', Chars<'i', Chars<'g', Chars<'h', Chars<'t', Nil>>>>>>, + >, + Value = <__Context__ as HasScalarType>::Scalar, + >, + {} + ") + } } diff --git a/crates/tests/cgp-tests/tests/getter_tests/assoc_type/auto_getter.rs b/crates/tests/cgp-tests/tests/getter_tests/assoc_type/auto_getter.rs index ad6c03a5..a44b10e4 100644 --- a/crates/tests/cgp-tests/tests/getter_tests/assoc_type/auto_getter.rs +++ b/crates/tests/cgp-tests/tests/getter_tests/assoc_type/auto_getter.rs @@ -1,12 +1,42 @@ use core::fmt::Display; use cgp::prelude::*; +use cgp_macro_test_util::snapshot_cgp_auto_getter; +use insta::assert_snapshot; -#[cgp_auto_getter] -pub trait HasName { - type Name: Display; +snapshot_cgp_auto_getter! { + #[cgp_auto_getter] + pub trait HasName { + type Name: Display; - fn name(&self) -> &Self::Name; + fn name(&self) -> &Self::Name; + } + + expand_has_name(output) { + assert_snapshot!(output, @" + pub trait HasName { + type Name: Display; + fn name(&self) -> &Self::Name; + } + impl<__Context__, Name> HasName for __Context__ + where + Name: Display, + __Context__: HasField< + Symbol<4, Chars<'n', Chars<'a', Chars<'m', Chars<'e', Nil>>>>>, + Value = Name, + >, + { + type Name = Name; + fn name(&self) -> &Self::Name { + self.get_field( + ::core::marker::PhantomData::< + Symbol<4, Chars<'n', Chars<'a', Chars<'m', Chars<'e', Nil>>>>>, + >, + ) + } + } + ") + } } #[derive(HasField)] diff --git a/crates/tests/cgp-tests/tests/getter_tests/assoc_type/getter.rs b/crates/tests/cgp-tests/tests/getter_tests/assoc_type/getter.rs index 441a4941..da51827d 100644 --- a/crates/tests/cgp-tests/tests/getter_tests/assoc_type/getter.rs +++ b/crates/tests/cgp-tests/tests/getter_tests/assoc_type/getter.rs @@ -1,25 +1,214 @@ -use core::fmt::Display; +use core::ops::Mul; use cgp::prelude::*; +use cgp_macro_test_util::{snapshot_cgp_getter, snapshot_delegate_components}; +use insta::assert_snapshot; -#[cgp_getter] -pub trait HasName { - type Name: Display; +snapshot_cgp_getter! { + #[cgp_getter] + pub trait HasScalar { + type Scalar: Mul + Clone; - fn name(&self) -> &Self::Name; + fn scalar(&self) -> &Self::Scalar; + } + + expand_has_scalar(output) { + assert_snapshot!(output, @" + pub trait HasScalar { + type Scalar: Mul + Clone; + fn scalar(&self) -> &Self::Scalar; + } + impl<__Context__> HasScalar for __Context__ + where + __Context__: ScalarGetter<__Context__>, + { + type Scalar = <__Context__ as ScalarGetter<__Context__>>::Scalar; + fn scalar(&self) -> &Self::Scalar { + __Context__::scalar(self) + } + } + pub trait ScalarGetter< + __Context__, + >: IsProviderFor { + type Scalar: Mul + Clone; + fn scalar(__context__: &__Context__) -> &Self::Scalar; + } + impl<__Provider__, __Context__> ScalarGetter<__Context__> for __Provider__ + where + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + ScalarGetterComponent, + >>::Delegate: ScalarGetter<__Context__>, + { + type Scalar = <<__Provider__ as DelegateComponent< + ScalarGetterComponent, + >>::Delegate as ScalarGetter<__Context__>>::Scalar; + fn scalar(__context__: &__Context__) -> &Self::Scalar { + <__Provider__ as DelegateComponent< + ScalarGetterComponent, + >>::Delegate::scalar(__context__) + } + } + pub struct ScalarGetterComponent; + impl<__Context__> ScalarGetter<__Context__> for UseContext + where + __Context__: HasScalar, + { + type Scalar = <__Context__ as HasScalar>::Scalar; + fn scalar(__context__: &__Context__) -> &Self::Scalar { + __Context__::scalar(__context__) + } + } + impl<__Context__> IsProviderFor for UseContext + where + __Context__: HasScalar, + {} + impl<__Context__, __Components__, __Path__> ScalarGetter<__Context__> + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent<__Path__>>::Delegate: ScalarGetter<__Context__>, + { + type Scalar = <<__Components__ as DelegateComponent< + __Path__, + >>::Delegate as ScalarGetter<__Context__>>::Scalar; + fn scalar(__context__: &__Context__) -> &Self::Scalar { + <__Components__ as DelegateComponent<__Path__>>::Delegate::scalar(__context__) + } + } + impl< + __Context__, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: IsProviderFor + + ScalarGetter<__Context__>, + {} + impl<__Context__, Scalar> ScalarGetter<__Context__> for UseFields + where + Scalar: Mul + Clone, + __Context__: HasField< + Symbol< + 6, + Chars<'s', Chars<'c', Chars<'a', Chars<'l', Chars<'a', Chars<'r', Nil>>>>>>, + >, + Value = Scalar, + >, + { + type Scalar = Scalar; + fn scalar(__context__: &__Context__) -> &Self::Scalar { + __context__ + .get_field( + ::core::marker::PhantomData::< + Symbol< + 6, + Chars< + 's', + Chars< + 'c', + Chars<'a', Chars<'l', Chars<'a', Chars<'r', Nil>>>>, + >, + >, + >, + >, + ) + } + } + impl<__Context__, Scalar> IsProviderFor + for UseFields + where + Scalar: Mul + Clone, + __Context__: HasField< + Symbol< + 6, + Chars<'s', Chars<'c', Chars<'a', Chars<'l', Chars<'a', Chars<'r', Nil>>>>>>, + >, + Value = Scalar, + >, + {} + impl<__Context__, Scalar, __Tag__> ScalarGetter<__Context__> for UseField<__Tag__> + where + Scalar: Mul + Clone, + __Context__: HasField<__Tag__, Value = Scalar>, + { + type Scalar = Scalar; + fn scalar(__context__: &__Context__) -> &Self::Scalar { + __context__.get_field(::core::marker::PhantomData::<__Tag__>) + } + } + impl<__Context__, Scalar, __Tag__> IsProviderFor + for UseField<__Tag__> + where + Scalar: Mul + Clone, + __Context__: HasField<__Tag__, Value = Scalar>, + {} + impl<__Context__, Scalar, __Provider__> ScalarGetter<__Context__> + for WithProvider<__Provider__> + where + Scalar: Mul + Clone, + __Provider__: FieldGetter<__Context__, ScalarGetterComponent, Value = Scalar>, + { + type Scalar = Scalar; + fn scalar(__context__: &__Context__) -> &Self::Scalar { + __Provider__::get_field( + __context__, + ::core::marker::PhantomData::, + ) + } + } + impl< + __Context__, + Scalar, + __Provider__, + > IsProviderFor for WithProvider<__Provider__> + where + Scalar: Mul + Clone, + __Provider__: FieldGetter<__Context__, ScalarGetterComponent, Value = Scalar>, + {} + ") + } } #[derive(HasField)] -pub struct Person { - pub first_name: String, +pub struct App { + pub scalar: f64, } -delegate_components! { - Person { - NameGetterComponent: - UseField, +snapshot_delegate_components! { + delegate_components! { + App { + ScalarGetterComponent: + UseField, + } + } + + expand_app(output) { + assert_snapshot!(output, @r#" + impl DelegateComponent for App { + type Delegate = UseField; + } + impl< + __Context__, + __Params__, + > IsProviderFor for App + where + UseField< + Symbol!("scalar"), + >: IsProviderFor, + {} + "#) } } -pub trait CheckHasName: HasName {} -impl CheckHasName for Person {} +#[test] +fn test_auto_getter_scalar() { + let app = App { scalar: 2.0 }; + + assert_eq!(*app.scalar(), 2.0); +} diff --git a/crates/tests/cgp-tests/tests/getter_tests/assoc_type/self_referential.rs b/crates/tests/cgp-tests/tests/getter_tests/assoc_type/self_referential.rs index e3aa8502..2b112180 100644 --- a/crates/tests/cgp-tests/tests/getter_tests/assoc_type/self_referential.rs +++ b/crates/tests/cgp-tests/tests/getter_tests/assoc_type/self_referential.rs @@ -1,29 +1,187 @@ -use core::ops::Mul; +use core::fmt::Display; use cgp::prelude::*; +use cgp_macro_test_util::{snapshot_cgp_getter, snapshot_delegate_components}; +use insta::assert_snapshot; -#[cgp_getter] -pub trait HasScalar { - type Scalar: Mul + Clone; +snapshot_cgp_getter! { + #[cgp_getter] + pub trait HasName { + type Name: Display; - fn scalar(&self) -> &Self::Scalar; + fn name(&self) -> &Self::Name; + } + + expand_has_name(output) { + assert_snapshot!(output, @" + pub trait HasName { + type Name: Display; + fn name(&self) -> &Self::Name; + } + impl<__Context__> HasName for __Context__ + where + __Context__: NameGetter<__Context__>, + { + type Name = <__Context__ as NameGetter<__Context__>>::Name; + fn name(&self) -> &Self::Name { + __Context__::name(self) + } + } + pub trait NameGetter<__Context__>: IsProviderFor { + type Name: Display; + fn name(__context__: &__Context__) -> &Self::Name; + } + impl<__Provider__, __Context__> NameGetter<__Context__> for __Provider__ + where + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + NameGetterComponent, + >>::Delegate: NameGetter<__Context__>, + { + type Name = <<__Provider__ as DelegateComponent< + NameGetterComponent, + >>::Delegate as NameGetter<__Context__>>::Name; + fn name(__context__: &__Context__) -> &Self::Name { + <__Provider__ as DelegateComponent< + NameGetterComponent, + >>::Delegate::name(__context__) + } + } + pub struct NameGetterComponent; + impl<__Context__> NameGetter<__Context__> for UseContext + where + __Context__: HasName, + { + type Name = <__Context__ as HasName>::Name; + fn name(__context__: &__Context__) -> &Self::Name { + __Context__::name(__context__) + } + } + impl<__Context__> IsProviderFor for UseContext + where + __Context__: HasName, + {} + impl<__Context__, __Components__, __Path__> NameGetter<__Context__> + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent<__Path__>>::Delegate: NameGetter<__Context__>, + { + type Name = <<__Components__ as DelegateComponent< + __Path__, + >>::Delegate as NameGetter<__Context__>>::Name; + fn name(__context__: &__Context__) -> &Self::Name { + <__Components__ as DelegateComponent<__Path__>>::Delegate::name(__context__) + } + } + impl< + __Context__, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: IsProviderFor + + NameGetter<__Context__>, + {} + impl<__Context__, Name> NameGetter<__Context__> for UseFields + where + Name: Display, + __Context__: HasField< + Symbol<4, Chars<'n', Chars<'a', Chars<'m', Chars<'e', Nil>>>>>, + Value = Name, + >, + { + type Name = Name; + fn name(__context__: &__Context__) -> &Self::Name { + __context__ + .get_field( + ::core::marker::PhantomData::< + Symbol<4, Chars<'n', Chars<'a', Chars<'m', Chars<'e', Nil>>>>>, + >, + ) + } + } + impl<__Context__, Name> IsProviderFor for UseFields + where + Name: Display, + __Context__: HasField< + Symbol<4, Chars<'n', Chars<'a', Chars<'m', Chars<'e', Nil>>>>>, + Value = Name, + >, + {} + impl<__Context__, Name, __Tag__> NameGetter<__Context__> for UseField<__Tag__> + where + Name: Display, + __Context__: HasField<__Tag__, Value = Name>, + { + type Name = Name; + fn name(__context__: &__Context__) -> &Self::Name { + __context__.get_field(::core::marker::PhantomData::<__Tag__>) + } + } + impl<__Context__, Name, __Tag__> IsProviderFor + for UseField<__Tag__> + where + Name: Display, + __Context__: HasField<__Tag__, Value = Name>, + {} + impl<__Context__, Name, __Provider__> NameGetter<__Context__> + for WithProvider<__Provider__> + where + Name: Display, + __Provider__: FieldGetter<__Context__, NameGetterComponent, Value = Name>, + { + type Name = Name; + fn name(__context__: &__Context__) -> &Self::Name { + __Provider__::get_field( + __context__, + ::core::marker::PhantomData::, + ) + } + } + impl<__Context__, Name, __Provider__> IsProviderFor + for WithProvider<__Provider__> + where + Name: Display, + __Provider__: FieldGetter<__Context__, NameGetterComponent, Value = Name>, + {} + ") + } } #[derive(HasField)] -pub struct App { - pub scalar: f64, +pub struct Person { + pub first_name: String, } -delegate_components! { - App { - ScalarGetterComponent: - UseField, +snapshot_delegate_components! { + delegate_components! { + Person { + NameGetterComponent: + UseField, + } } -} -#[test] -fn test_auto_getter_scalar() { - let app = App { scalar: 2.0 }; - - assert_eq!(*app.scalar(), 2.0); + expand_person(output) { + assert_snapshot!(output, @r#" + impl DelegateComponent for Person { + type Delegate = UseField; + } + impl<__Context__, __Params__> IsProviderFor + for Person + where + UseField< + Symbol!("first_name"), + >: IsProviderFor, + {} + "#) + } } + +pub trait CheckHasName: HasName {} +impl CheckHasName for Person {} diff --git a/crates/tests/cgp-tests/tests/getter_tests/assoc_type/self_referential_auto.rs b/crates/tests/cgp-tests/tests/getter_tests/assoc_type/self_referential_auto.rs index b054d784..58d82337 100644 --- a/crates/tests/cgp-tests/tests/getter_tests/assoc_type/self_referential_auto.rs +++ b/crates/tests/cgp-tests/tests/getter_tests/assoc_type/self_referential_auto.rs @@ -1,12 +1,51 @@ use core::ops::Mul; use cgp::prelude::*; +use cgp_macro_test_util::snapshot_cgp_auto_getter; +use insta::assert_snapshot; -#[cgp_auto_getter] -pub trait HasScalarType { - type Scalar: Mul + Clone; +snapshot_cgp_auto_getter! { + #[cgp_auto_getter] + pub trait HasScalarType { + type Scalar: Mul + Clone; - fn scalar(&self) -> &Self::Scalar; + fn scalar(&self) -> &Self::Scalar; + } + + expand_has_scalar_type(output) { + assert_snapshot!(output, @" + pub trait HasScalarType { + type Scalar: Mul + Clone; + fn scalar(&self) -> &Self::Scalar; + } + impl<__Context__, Scalar> HasScalarType for __Context__ + where + Scalar: Mul + Clone, + __Context__: HasField< + Symbol< + 6, + Chars<'s', Chars<'c', Chars<'a', Chars<'l', Chars<'a', Chars<'r', Nil>>>>>>, + >, + Value = Scalar, + >, + { + type Scalar = Scalar; + fn scalar(&self) -> &Self::Scalar { + self.get_field( + ::core::marker::PhantomData::< + Symbol< + 6, + Chars< + 's', + Chars<'c', Chars<'a', Chars<'l', Chars<'a', Chars<'r', Nil>>>>>, + >, + >, + >, + ) + } + } + ") + } } #[derive(HasField)] diff --git a/crates/tests/cgp-tests/tests/getter_tests/auto_generics.rs b/crates/tests/cgp-tests/tests/getter_tests/auto_generics.rs index e38595f3..32295db4 100644 --- a/crates/tests/cgp-tests/tests/getter_tests/auto_generics.rs +++ b/crates/tests/cgp-tests/tests/getter_tests/auto_generics.rs @@ -1,8 +1,35 @@ use cgp::prelude::*; +use cgp_macro_test_util::snapshot_cgp_auto_getter; +use insta::assert_snapshot; -#[cgp_auto_getter] -pub trait HasFoo { - fn foo(&self, _tag: PhantomData) -> &Foo; +snapshot_cgp_auto_getter! { + #[cgp_auto_getter] + pub trait HasFoo { + fn foo(&self, _tag: PhantomData) -> &Foo; + } + + expand_has_foo(output) { + assert_snapshot!(output, @" + pub trait HasFoo { + fn foo(&self, _tag: PhantomData) -> &Foo; + } + impl<__Context__, Foo> HasFoo for __Context__ + where + __Context__: HasField< + Symbol<3, Chars<'f', Chars<'o', Chars<'o', Nil>>>>, + Value = Foo, + >, + { + fn foo(&self, _phantom: PhantomData) -> &Foo { + self.get_field( + ::core::marker::PhantomData::< + Symbol<3, Chars<'f', Chars<'o', Chars<'o', Nil>>>>, + >, + ) + } + } + ") + } } #[derive(HasField)] diff --git a/crates/tests/cgp-tests/tests/getter_tests/clone.rs b/crates/tests/cgp-tests/tests/getter_tests/clone.rs index d01b2118..22a39eb3 100644 --- a/crates/tests/cgp-tests/tests/getter_tests/clone.rs +++ b/crates/tests/cgp-tests/tests/getter_tests/clone.rs @@ -1,15 +1,164 @@ -use cgp::prelude::*; +mod clone_getter { + use cgp::prelude::*; + use cgp_macro_test_util::{snapshot_cgp_getter, snapshot_delegate_components}; + use insta::assert_snapshot; -#[test] -pub fn test_clone_getter() { #[cgp_type] pub trait HasNameType { type Name; } - #[cgp_getter] - pub trait HasName: HasNameType { - fn name(&self) -> Self::Name; + snapshot_cgp_getter! { + #[cgp_getter] + pub trait HasName: HasNameType { + fn name(&self) -> Self::Name; + } + + expand_has_name(output) { + assert_snapshot!(output, @" + pub trait HasName: HasNameType { + fn name(&self) -> Self::Name; + } + impl<__Context__> HasName for __Context__ + where + __Context__: HasNameType, + __Context__: NameGetter<__Context__>, + { + fn name(&self) -> Self::Name { + __Context__::name(self) + } + } + pub trait NameGetter<__Context__>: IsProviderFor + where + __Context__: HasNameType, + { + fn name(__context__: &__Context__) -> __Context__::Name; + } + impl<__Provider__, __Context__> NameGetter<__Context__> for __Provider__ + where + __Context__: HasNameType, + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + NameGetterComponent, + >>::Delegate: NameGetter<__Context__>, + { + fn name(__context__: &__Context__) -> __Context__::Name { + <__Provider__ as DelegateComponent< + NameGetterComponent, + >>::Delegate::name(__context__) + } + } + pub struct NameGetterComponent; + impl<__Context__> NameGetter<__Context__> for UseContext + where + __Context__: HasNameType, + __Context__: HasName, + { + fn name(__context__: &__Context__) -> __Context__::Name { + __Context__::name(__context__) + } + } + impl<__Context__> IsProviderFor for UseContext + where + __Context__: HasNameType, + __Context__: HasName, + {} + impl<__Context__, __Components__, __Path__> NameGetter<__Context__> + for RedirectLookup<__Components__, __Path__> + where + __Context__: HasNameType, + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent<__Path__>>::Delegate: NameGetter<__Context__>, + { + fn name(__context__: &__Context__) -> __Context__::Name { + <__Components__ as DelegateComponent<__Path__>>::Delegate::name(__context__) + } + } + impl< + __Context__, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Context__: HasNameType, + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: IsProviderFor + + NameGetter<__Context__>, + {} + impl<__Context__> NameGetter<__Context__> for UseFields + where + __Context__: HasNameType, + __Context__: HasField< + Symbol<4, Chars<'n', Chars<'a', Chars<'m', Chars<'e', Nil>>>>>, + Value = __Context__::Name, + >, + { + fn name(__context__: &__Context__) -> __Context__::Name { + __context__ + .get_field( + ::core::marker::PhantomData::< + Symbol<4, Chars<'n', Chars<'a', Chars<'m', Chars<'e', Nil>>>>>, + >, + ) + .clone() + } + } + impl<__Context__> IsProviderFor for UseFields + where + __Context__: HasNameType, + __Context__: HasField< + Symbol<4, Chars<'n', Chars<'a', Chars<'m', Chars<'e', Nil>>>>>, + Value = __Context__::Name, + >, + {} + impl<__Context__, __Tag__> NameGetter<__Context__> for UseField<__Tag__> + where + __Context__: HasNameType, + __Context__: HasField<__Tag__, Value = __Context__::Name>, + { + fn name(__context__: &__Context__) -> __Context__::Name { + __context__.get_field(::core::marker::PhantomData::<__Tag__>).clone() + } + } + impl<__Context__, __Tag__> IsProviderFor + for UseField<__Tag__> + where + __Context__: HasNameType, + __Context__: HasField<__Tag__, Value = __Context__::Name>, + {} + impl<__Context__, __Provider__> NameGetter<__Context__> for WithProvider<__Provider__> + where + __Context__: HasNameType, + __Provider__: FieldGetter< + __Context__, + NameGetterComponent, + Value = __Context__::Name, + >, + { + fn name(__context__: &__Context__) -> __Context__::Name { + __Provider__::get_field( + __context__, + ::core::marker::PhantomData::, + ) + .clone() + } + } + impl<__Context__, __Provider__> IsProviderFor + for WithProvider<__Provider__> + where + __Context__: HasNameType, + __Provider__: FieldGetter< + __Context__, + NameGetterComponent, + Value = __Context__::Name, + >, + {} + ") + } } #[derive(HasField)] @@ -17,28 +166,90 @@ pub fn test_clone_getter() { pub name: &'static str, } - delegate_components! { - App { - NameTypeProviderComponent: UseType<&'static str>, - NameGetterComponent: UseField, + snapshot_delegate_components! { + delegate_components! { + App { + NameTypeProviderComponent: UseType<&'static str>, + NameGetterComponent: UseField, + } + } + + expand_app(output) { + assert_snapshot!(output, @r#" + impl DelegateComponent for App { + type Delegate = UseType<&'static str>; + } + impl< + __Context__, + __Params__, + > IsProviderFor for App + where + UseType< + &'static str, + >: IsProviderFor, + {} + impl DelegateComponent for App { + type Delegate = UseField; + } + impl<__Context__, __Params__> IsProviderFor + for App + where + UseField< + Symbol!("name"), + >: IsProviderFor, + {} + "#) } } - let context = App { name: "Alice" }; + #[test] + pub fn test_clone_getter() { + let context = App { name: "Alice" }; - assert_eq!(context.name(), "Alice"); + assert_eq!(context.name(), "Alice"); + } } -#[test] -pub fn test_clone_auto_getter() { +mod clone_auto_getter { + use cgp::prelude::*; + use cgp_macro_test_util::{snapshot_cgp_auto_getter, snapshot_delegate_components}; + use insta::assert_snapshot; + #[cgp_type] pub trait HasNameType { type Name; } - #[cgp_auto_getter] - pub trait HasName: HasNameType { - fn name(&self) -> Self::Name; + snapshot_cgp_auto_getter! { + #[cgp_auto_getter] + pub trait HasName: HasNameType { + fn name(&self) -> Self::Name; + } + + expand_has_name(output) { + assert_snapshot!(output, @" + pub trait HasName: HasNameType { + fn name(&self) -> Self::Name; + } + impl<__Context__> HasName for __Context__ + where + __Context__: HasNameType, + __Context__: HasField< + Symbol<4, Chars<'n', Chars<'a', Chars<'m', Chars<'e', Nil>>>>>, + Value = __Context__::Name, + >, + { + fn name(&self) -> __Context__::Name { + self.get_field( + ::core::marker::PhantomData::< + Symbol<4, Chars<'n', Chars<'a', Chars<'m', Chars<'e', Nil>>>>>, + >, + ) + .clone() + } + } + ") + } } #[derive(HasField)] @@ -46,13 +257,35 @@ pub fn test_clone_auto_getter() { pub name: &'static str, } - delegate_components! { - App { - NameTypeProviderComponent: UseType<&'static str>, + snapshot_delegate_components! { + delegate_components! { + App { + NameTypeProviderComponent: UseType<&'static str>, + } + } + + expand_app(output) { + assert_snapshot!(output, @" + impl DelegateComponent for App { + type Delegate = UseType<&'static str>; + } + impl< + __Context__, + __Params__, + > IsProviderFor for App + where + UseType< + &'static str, + >: IsProviderFor, + {} + ") } } - let context = App { name: "Alice" }; + #[test] + pub fn test_clone_auto_getter() { + let context = App { name: "Alice" }; - assert_eq!(context.name(), "Alice"); + assert_eq!(context.name(), "Alice"); + } } diff --git a/crates/tests/cgp-tests/tests/getter_tests/mref.rs b/crates/tests/cgp-tests/tests/getter_tests/mref.rs index 24645185..1c6552d7 100644 --- a/crates/tests/cgp-tests/tests/getter_tests/mref.rs +++ b/crates/tests/cgp-tests/tests/getter_tests/mref.rs @@ -1,11 +1,139 @@ -use cgp::core::field::types::MRef; -use cgp::prelude::*; - -#[test] -pub fn test_mref_getter() { - #[cgp_getter] - pub trait HasFoo { - fn foo(&self) -> MRef<'_, String>; +mod mref_getter { + use cgp::core::field::types::MRef; + use cgp::prelude::*; + use cgp_macro_test_util::{snapshot_cgp_getter, snapshot_delegate_components}; + use insta::assert_snapshot; + + snapshot_cgp_getter! { + #[cgp_getter] + pub trait HasFoo { + fn foo(&self) -> MRef<'_, String>; + } + + expand_has_foo(output) { + assert_snapshot!(output, @" + pub trait HasFoo { + fn foo(&self) -> MRef<'_, String>; + } + impl<__Context__> HasFoo for __Context__ + where + __Context__: FooGetter<__Context__>, + { + fn foo(&self) -> MRef<'_, String> { + __Context__::foo(self) + } + } + pub trait FooGetter<__Context__>: IsProviderFor { + fn foo(__context__: &__Context__) -> MRef<'_, String>; + } + impl<__Provider__, __Context__> FooGetter<__Context__> for __Provider__ + where + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + FooGetterComponent, + >>::Delegate: FooGetter<__Context__>, + { + fn foo(__context__: &__Context__) -> MRef<'_, String> { + <__Provider__ as DelegateComponent< + FooGetterComponent, + >>::Delegate::foo(__context__) + } + } + pub struct FooGetterComponent; + impl<__Context__> FooGetter<__Context__> for UseContext + where + __Context__: HasFoo, + { + fn foo(__context__: &__Context__) -> MRef<'_, String> { + __Context__::foo(__context__) + } + } + impl<__Context__> IsProviderFor for UseContext + where + __Context__: HasFoo, + {} + impl<__Context__, __Components__, __Path__> FooGetter<__Context__> + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent<__Path__>>::Delegate: FooGetter<__Context__>, + { + fn foo(__context__: &__Context__) -> MRef<'_, String> { + <__Components__ as DelegateComponent<__Path__>>::Delegate::foo(__context__) + } + } + impl< + __Context__, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: IsProviderFor + + FooGetter<__Context__>, + {} + impl<__Context__> FooGetter<__Context__> for UseFields + where + __Context__: HasField< + Symbol<3, Chars<'f', Chars<'o', Chars<'o', Nil>>>>, + Value = String, + >, + { + fn foo(__context__: &__Context__) -> MRef<'_, String> { + MRef::Ref( + __context__ + .get_field( + ::core::marker::PhantomData::< + Symbol<3, Chars<'f', Chars<'o', Chars<'o', Nil>>>>, + >, + ), + ) + } + } + impl<__Context__> IsProviderFor for UseFields + where + __Context__: HasField< + Symbol<3, Chars<'f', Chars<'o', Chars<'o', Nil>>>>, + Value = String, + >, + {} + impl<__Context__, __Tag__> FooGetter<__Context__> for UseField<__Tag__> + where + __Context__: HasField<__Tag__, Value = String>, + { + fn foo(__context__: &__Context__) -> MRef<'_, String> { + MRef::Ref(__context__.get_field(::core::marker::PhantomData::<__Tag__>)) + } + } + impl<__Context__, __Tag__> IsProviderFor + for UseField<__Tag__> + where + __Context__: HasField<__Tag__, Value = String>, + {} + impl<__Context__, __Provider__> FooGetter<__Context__> for WithProvider<__Provider__> + where + __Provider__: FieldGetter<__Context__, FooGetterComponent, Value = String>, + { + fn foo(__context__: &__Context__) -> MRef<'_, String> { + MRef::Ref( + __Provider__::get_field( + __context__, + ::core::marker::PhantomData::, + ), + ) + } + } + impl<__Context__, __Provider__> IsProviderFor + for WithProvider<__Provider__> + where + __Provider__: FieldGetter<__Context__, FooGetterComponent, Value = String>, + {} + ") + } } #[derive(HasField)] @@ -13,22 +141,72 @@ pub fn test_mref_getter() { pub bar: String, } - delegate_components! { - App { - FooGetterComponent: UseField, + snapshot_delegate_components! { + delegate_components! { + App { + FooGetterComponent: UseField, + } + } + + expand_app(output) { + assert_snapshot!(output, @r#" + impl DelegateComponent for App { + type Delegate = UseField; + } + impl<__Context__, __Params__> IsProviderFor + for App + where + UseField: IsProviderFor, + {} + "#) } } - let context = App { bar: "foo".into() }; + #[test] + pub fn test_mref_getter() { + let context = App { bar: "foo".into() }; - assert_eq!(context.foo().as_ref(), "foo"); + assert_eq!(context.foo().as_ref(), "foo"); + } } -#[test] -pub fn test_mref_auto_getter() { - #[cgp_auto_getter] - pub trait HasFoo { - fn foo(&self) -> MRef<'_, String>; +mod mref_auto_getter { + use cgp::core::field::types::MRef; + use cgp::prelude::*; + use cgp_macro_test_util::snapshot_cgp_auto_getter; + use insta::assert_snapshot; + + snapshot_cgp_auto_getter! { + #[cgp_auto_getter] + pub trait HasFoo { + fn foo(&self) -> MRef<'_, String>; + } + + expand_has_foo(output) { + assert_snapshot!(output, @" + pub trait HasFoo { + fn foo(&self) -> MRef<'_, String>; + } + impl<__Context__> HasFoo for __Context__ + where + __Context__: HasField< + Symbol<3, Chars<'f', Chars<'o', Chars<'o', Nil>>>>, + Value = String, + >, + { + fn foo(&self) -> MRef<'_, String> { + MRef::Ref( + self + .get_field( + ::core::marker::PhantomData::< + Symbol<3, Chars<'f', Chars<'o', Chars<'o', Nil>>>>, + >, + ), + ) + } + } + ") + } } #[derive(HasField)] @@ -36,7 +214,10 @@ pub fn test_mref_auto_getter() { pub foo: String, } - let context = App { foo: "foo".into() }; + #[test] + pub fn test_mref_auto_getter() { + let context = App { foo: "foo".into() }; - assert_eq!(context.foo().as_ref(), "foo"); + assert_eq!(context.foo().as_ref(), "foo"); + } } diff --git a/crates/tests/cgp-tests/tests/getter_tests/non_self.rs b/crates/tests/cgp-tests/tests/getter_tests/non_self.rs index fdb576b4..079a1af7 100644 --- a/crates/tests/cgp-tests/tests/getter_tests/non_self.rs +++ b/crates/tests/cgp-tests/tests/getter_tests/non_self.rs @@ -1,4 +1,6 @@ use cgp::prelude::*; +use cgp_macro_test_util::{snapshot_cgp_getter, snapshot_delegate_components}; +use insta::assert_snapshot; #[cgp_type] pub trait HasFooType { @@ -10,9 +12,187 @@ pub trait HasBarType { type Bar; } -#[cgp_getter] -pub trait HasFooBar: HasFooType + HasBarType { - fn foo_bar(foo: &Self::Foo) -> &Self::Bar; +snapshot_cgp_getter! { + #[cgp_getter] + pub trait HasFooBar: HasFooType + HasBarType { + fn foo_bar(foo: &Self::Foo) -> &Self::Bar; + } + + expand_has_foo_bar(output) { + assert_snapshot!(output, @" + pub trait HasFooBar: HasFooType + HasBarType { + fn foo_bar(foo: &Self::Foo) -> &Self::Bar; + } + impl<__Context__> HasFooBar for __Context__ + where + __Context__: HasFooType + HasBarType, + __Context__: FooBarGetter<__Context__>, + { + fn foo_bar(foo: &Self::Foo) -> &Self::Bar { + __Context__::foo_bar(foo) + } + } + pub trait FooBarGetter< + __Context__, + >: IsProviderFor + where + __Context__: HasFooType + HasBarType, + { + fn foo_bar(foo: &__Context__::Foo) -> &__Context__::Bar; + } + impl<__Provider__, __Context__> FooBarGetter<__Context__> for __Provider__ + where + __Context__: HasFooType + HasBarType, + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + FooBarGetterComponent, + >>::Delegate: FooBarGetter<__Context__>, + { + fn foo_bar(foo: &__Context__::Foo) -> &__Context__::Bar { + <__Provider__ as DelegateComponent< + FooBarGetterComponent, + >>::Delegate::foo_bar(foo) + } + } + pub struct FooBarGetterComponent; + impl<__Context__> FooBarGetter<__Context__> for UseContext + where + __Context__: HasFooType + HasBarType, + __Context__: HasFooBar, + { + fn foo_bar(foo: &__Context__::Foo) -> &__Context__::Bar { + __Context__::foo_bar(foo) + } + } + impl<__Context__> IsProviderFor for UseContext + where + __Context__: HasFooType + HasBarType, + __Context__: HasFooBar, + {} + impl<__Context__, __Components__, __Path__> FooBarGetter<__Context__> + for RedirectLookup<__Components__, __Path__> + where + __Context__: HasFooType + HasBarType, + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent<__Path__>>::Delegate: FooBarGetter<__Context__>, + { + fn foo_bar(foo: &__Context__::Foo) -> &__Context__::Bar { + <__Components__ as DelegateComponent<__Path__>>::Delegate::foo_bar(foo) + } + } + impl< + __Context__, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Context__: HasFooType + HasBarType, + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: IsProviderFor + + FooBarGetter<__Context__>, + {} + impl<__Context__> FooBarGetter<__Context__> for UseFields + where + __Context__: HasFooType + HasBarType, + __Context__::Foo: HasField< + Symbol< + 7, + Chars< + 'f', + Chars< + 'o', + Chars<'o', Chars<'_', Chars<'b', Chars<'a', Chars<'r', Nil>>>>>, + >, + >, + >, + Value = __Context__::Bar, + >, + { + fn foo_bar(__context__: &__Context__::Foo) -> &__Context__::Bar { + __context__ + .get_field( + ::core::marker::PhantomData::< + Symbol< + 7, + Chars< + 'f', + Chars< + 'o', + Chars< + 'o', + Chars<'_', Chars<'b', Chars<'a', Chars<'r', Nil>>>>, + >, + >, + >, + >, + >, + ) + } + } + impl<__Context__> IsProviderFor for UseFields + where + __Context__: HasFooType + HasBarType, + __Context__::Foo: HasField< + Symbol< + 7, + Chars< + 'f', + Chars< + 'o', + Chars<'o', Chars<'_', Chars<'b', Chars<'a', Chars<'r', Nil>>>>>, + >, + >, + >, + Value = __Context__::Bar, + >, + {} + impl<__Context__, __Tag__> FooBarGetter<__Context__> for UseField<__Tag__> + where + __Context__: HasFooType + HasBarType, + __Context__::Foo: HasField<__Tag__, Value = __Context__::Bar>, + { + fn foo_bar(__context__: &__Context__::Foo) -> &__Context__::Bar { + __context__.get_field(::core::marker::PhantomData::<__Tag__>) + } + } + impl<__Context__, __Tag__> IsProviderFor + for UseField<__Tag__> + where + __Context__: HasFooType + HasBarType, + __Context__::Foo: HasField<__Tag__, Value = __Context__::Bar>, + {} + impl<__Context__, __Provider__> FooBarGetter<__Context__> for WithProvider<__Provider__> + where + __Context__: HasFooType + HasBarType, + __Provider__: FieldGetter< + __Context__::Foo, + FooBarGetterComponent, + Value = __Context__::Bar, + >, + { + fn foo_bar(__context__: &__Context__::Foo) -> &__Context__::Bar { + __Provider__::get_field( + __context__, + ::core::marker::PhantomData::, + ) + } + } + impl<__Context__, __Provider__> IsProviderFor + for WithProvider<__Provider__> + where + __Context__: HasFooType + HasBarType, + __Provider__: FieldGetter< + __Context__::Foo, + FooBarGetterComponent, + Value = __Context__::Bar, + >, + {} + ") + } } pub struct App; @@ -22,14 +202,53 @@ pub struct Foo { pub bar: u32, } -delegate_components! { - App { - FooTypeProviderComponent: - UseType, - BarTypeProviderComponent: - UseType, - FooBarGetterComponent: - UseField, +snapshot_delegate_components! { + delegate_components! { + App { + FooTypeProviderComponent: + UseType, + BarTypeProviderComponent: + UseType, + FooBarGetterComponent: + UseField, + } + } + + expand_app(output) { + assert_snapshot!(output, @r#" + impl DelegateComponent for App { + type Delegate = UseType; + } + impl< + __Context__, + __Params__, + > IsProviderFor for App + where + UseType: IsProviderFor, + {} + impl DelegateComponent for App { + type Delegate = UseType; + } + impl< + __Context__, + __Params__, + > IsProviderFor for App + where + UseType: IsProviderFor, + {} + impl DelegateComponent for App { + type Delegate = UseField; + } + impl< + __Context__, + __Params__, + > IsProviderFor for App + where + UseField< + Symbol!("bar"), + >: IsProviderFor, + {} + "#) } } diff --git a/crates/tests/cgp-tests/tests/getter_tests/non_self_auto.rs b/crates/tests/cgp-tests/tests/getter_tests/non_self_auto.rs index 69affce1..836d4a8d 100644 --- a/crates/tests/cgp-tests/tests/getter_tests/non_self_auto.rs +++ b/crates/tests/cgp-tests/tests/getter_tests/non_self_auto.rs @@ -1,4 +1,6 @@ use cgp::prelude::*; +use cgp_macro_test_util::{snapshot_cgp_auto_getter, snapshot_delegate_components}; +use insta::assert_snapshot; #[cgp_type] pub trait HasFooType { @@ -10,9 +12,57 @@ pub trait HasBarType { type Bar; } -#[cgp_auto_getter] -pub trait HasFooBar: HasFooType + HasBarType { - fn foo_bar(foo: &Self::Foo) -> &Self::Bar; +snapshot_cgp_auto_getter! { + #[cgp_auto_getter] + pub trait HasFooBar: HasFooType + HasBarType { + fn foo_bar(foo: &Self::Foo) -> &Self::Bar; + } + + expand_has_foo_bar(output) { + assert_snapshot!(output, @" + pub trait HasFooBar: HasFooType + HasBarType { + fn foo_bar(foo: &Self::Foo) -> &Self::Bar; + } + impl<__Context__> HasFooBar for __Context__ + where + __Context__: HasFooType + HasBarType, + __Context__::Foo: HasField< + Symbol< + 7, + Chars< + 'f', + Chars< + 'o', + Chars<'o', Chars<'_', Chars<'b', Chars<'a', Chars<'r', Nil>>>>>, + >, + >, + >, + Value = __Context__::Bar, + >, + { + fn foo_bar(__context__: &__Context__::Foo) -> &__Context__::Bar { + __context__ + .get_field( + ::core::marker::PhantomData::< + Symbol< + 7, + Chars< + 'f', + Chars< + 'o', + Chars< + 'o', + Chars<'_', Chars<'b', Chars<'a', Chars<'r', Nil>>>>, + >, + >, + >, + >, + >, + ) + } + } + ") + } } pub struct App; @@ -22,12 +72,39 @@ pub struct Foo { pub foo_bar: u32, } -delegate_components! { - App { - FooTypeProviderComponent: - UseType, - BarTypeProviderComponent: - UseType, +snapshot_delegate_components! { + delegate_components! { + App { + FooTypeProviderComponent: + UseType, + BarTypeProviderComponent: + UseType, + } + } + + expand_app(output) { + assert_snapshot!(output, @" + impl DelegateComponent for App { + type Delegate = UseType; + } + impl< + __Context__, + __Params__, + > IsProviderFor for App + where + UseType: IsProviderFor, + {} + impl DelegateComponent for App { + type Delegate = UseType; + } + impl< + __Context__, + __Params__, + > IsProviderFor for App + where + UseType: IsProviderFor, + {} + ") } } diff --git a/crates/tests/cgp-tests/tests/getter_tests/option.rs b/crates/tests/cgp-tests/tests/getter_tests/option.rs index 683521e2..b08abac0 100644 --- a/crates/tests/cgp-tests/tests/getter_tests/option.rs +++ b/crates/tests/cgp-tests/tests/getter_tests/option.rs @@ -1,10 +1,136 @@ -use cgp::prelude::*; +mod option_getter { + use cgp::prelude::*; + use cgp_macro_test_util::{snapshot_cgp_getter, snapshot_delegate_components}; + use insta::assert_snapshot; -#[test] -pub fn test_option_getter() { - #[cgp_getter] - pub trait HasFoo { - fn foo(&self) -> Option<&String>; + snapshot_cgp_getter! { + #[cgp_getter] + pub trait HasFoo { + fn foo(&self) -> Option<&String>; + } + + expand_has_foo(output) { + assert_snapshot!(output, @" + pub trait HasFoo { + fn foo(&self) -> Option<&String>; + } + impl<__Context__> HasFoo for __Context__ + where + __Context__: FooGetter<__Context__>, + { + fn foo(&self) -> Option<&String> { + __Context__::foo(self) + } + } + pub trait FooGetter<__Context__>: IsProviderFor { + fn foo(__context__: &__Context__) -> Option<&String>; + } + impl<__Provider__, __Context__> FooGetter<__Context__> for __Provider__ + where + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + FooGetterComponent, + >>::Delegate: FooGetter<__Context__>, + { + fn foo(__context__: &__Context__) -> Option<&String> { + <__Provider__ as DelegateComponent< + FooGetterComponent, + >>::Delegate::foo(__context__) + } + } + pub struct FooGetterComponent; + impl<__Context__> FooGetter<__Context__> for UseContext + where + __Context__: HasFoo, + { + fn foo(__context__: &__Context__) -> Option<&String> { + __Context__::foo(__context__) + } + } + impl<__Context__> IsProviderFor for UseContext + where + __Context__: HasFoo, + {} + impl<__Context__, __Components__, __Path__> FooGetter<__Context__> + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent<__Path__>>::Delegate: FooGetter<__Context__>, + { + fn foo(__context__: &__Context__) -> Option<&String> { + <__Components__ as DelegateComponent<__Path__>>::Delegate::foo(__context__) + } + } + impl< + __Context__, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: IsProviderFor + + FooGetter<__Context__>, + {} + impl<__Context__> FooGetter<__Context__> for UseFields + where + __Context__: HasField< + Symbol<3, Chars<'f', Chars<'o', Chars<'o', Nil>>>>, + Value = Option, + >, + { + fn foo(__context__: &__Context__) -> Option<&String> { + __context__ + .get_field( + ::core::marker::PhantomData::< + Symbol<3, Chars<'f', Chars<'o', Chars<'o', Nil>>>>, + >, + ) + .as_ref() + } + } + impl<__Context__> IsProviderFor for UseFields + where + __Context__: HasField< + Symbol<3, Chars<'f', Chars<'o', Chars<'o', Nil>>>>, + Value = Option, + >, + {} + impl<__Context__, __Tag__> FooGetter<__Context__> for UseField<__Tag__> + where + __Context__: HasField<__Tag__, Value = Option>, + { + fn foo(__context__: &__Context__) -> Option<&String> { + __context__.get_field(::core::marker::PhantomData::<__Tag__>).as_ref() + } + } + impl<__Context__, __Tag__> IsProviderFor + for UseField<__Tag__> + where + __Context__: HasField<__Tag__, Value = Option>, + {} + impl<__Context__, __Provider__> FooGetter<__Context__> for WithProvider<__Provider__> + where + __Provider__: FieldGetter<__Context__, FooGetterComponent, Value = Option>, + { + fn foo(__context__: &__Context__) -> Option<&String> { + __Provider__::get_field( + __context__, + ::core::marker::PhantomData::, + ) + .as_ref() + } + } + impl<__Context__, __Provider__> IsProviderFor + for WithProvider<__Provider__> + where + __Provider__: FieldGetter<__Context__, FooGetterComponent, Value = Option>, + {} + ") + } } #[derive(HasField)] @@ -12,24 +138,71 @@ pub fn test_option_getter() { pub bar: Option, } - delegate_components! { - App { - FooGetterComponent: UseField, + snapshot_delegate_components! { + delegate_components! { + App { + FooGetterComponent: UseField, + } + } + + expand_app(output) { + assert_snapshot!(output, @r#" + impl DelegateComponent for App { + type Delegate = UseField; + } + impl<__Context__, __Params__> IsProviderFor + for App + where + UseField: IsProviderFor, + {} + "#) } } - let context = App { - bar: Some("foo".to_owned()), - }; + #[test] + pub fn test_option_getter() { + let context = App { + bar: Some("foo".to_owned()), + }; - assert_eq!(context.foo(), Some(&"foo".to_owned())); + assert_eq!(context.foo(), Some(&"foo".to_owned())); + } } -#[test] -pub fn test_option_auto_getter() { - #[cgp_auto_getter] - pub trait HasFoo { - fn foo(&self) -> Option<&String>; +mod option_auto_getter { + use cgp::prelude::*; + use cgp_macro_test_util::snapshot_cgp_auto_getter; + use insta::assert_snapshot; + + snapshot_cgp_auto_getter! { + #[cgp_auto_getter] + pub trait HasFoo { + fn foo(&self) -> Option<&String>; + } + + expand_has_foo(output) { + assert_snapshot!(output, @" + pub trait HasFoo { + fn foo(&self) -> Option<&String>; + } + impl<__Context__> HasFoo for __Context__ + where + __Context__: HasField< + Symbol<3, Chars<'f', Chars<'o', Chars<'o', Nil>>>>, + Value = Option, + >, + { + fn foo(&self) -> Option<&String> { + self.get_field( + ::core::marker::PhantomData::< + Symbol<3, Chars<'f', Chars<'o', Chars<'o', Nil>>>>, + >, + ) + .as_ref() + } + } + ") + } } #[derive(HasField)] @@ -37,9 +210,12 @@ pub fn test_option_auto_getter() { pub foo: Option, } - let context = App { - foo: Some("foo".to_owned()), - }; + #[test] + pub fn test_option_auto_getter() { + let context = App { + foo: Some("foo".to_owned()), + }; - assert_eq!(context.foo(), Some(&"foo".to_owned())); + assert_eq!(context.foo(), Some(&"foo".to_owned())); + } } diff --git a/crates/tests/cgp-tests/tests/getter_tests/slice.rs b/crates/tests/cgp-tests/tests/getter_tests/slice.rs index 51e35455..9d668d04 100644 --- a/crates/tests/cgp-tests/tests/getter_tests/slice.rs +++ b/crates/tests/cgp-tests/tests/getter_tests/slice.rs @@ -1,10 +1,144 @@ -use cgp::prelude::*; +mod slice_getter { + use cgp::prelude::*; + use cgp_macro_test_util::{snapshot_cgp_getter, snapshot_delegate_components}; + use insta::assert_snapshot; -#[test] -pub fn test_slice_getter() { - #[cgp_getter] - pub trait HasFoo { - fn foo(&self) -> &[u8]; + snapshot_cgp_getter! { + #[cgp_getter] + pub trait HasFoo { + fn foo(&self) -> &[u8]; + } + + expand_has_foo(output) { + assert_snapshot!(output, @" + pub trait HasFoo { + fn foo(&self) -> &[u8]; + } + impl<__Context__> HasFoo for __Context__ + where + __Context__: FooGetter<__Context__>, + { + fn foo(&self) -> &[u8] { + __Context__::foo(self) + } + } + pub trait FooGetter<__Context__>: IsProviderFor { + fn foo(__context__: &__Context__) -> &[u8]; + } + impl<__Provider__, __Context__> FooGetter<__Context__> for __Provider__ + where + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + FooGetterComponent, + >>::Delegate: FooGetter<__Context__>, + { + fn foo(__context__: &__Context__) -> &[u8] { + <__Provider__ as DelegateComponent< + FooGetterComponent, + >>::Delegate::foo(__context__) + } + } + pub struct FooGetterComponent; + impl<__Context__> FooGetter<__Context__> for UseContext + where + __Context__: HasFoo, + { + fn foo(__context__: &__Context__) -> &[u8] { + __Context__::foo(__context__) + } + } + impl<__Context__> IsProviderFor for UseContext + where + __Context__: HasFoo, + {} + impl<__Context__, __Components__, __Path__> FooGetter<__Context__> + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent<__Path__>>::Delegate: FooGetter<__Context__>, + { + fn foo(__context__: &__Context__) -> &[u8] { + <__Components__ as DelegateComponent<__Path__>>::Delegate::foo(__context__) + } + } + impl< + __Context__, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: IsProviderFor + + FooGetter<__Context__>, + {} + impl<__Context__> FooGetter<__Context__> for UseFields + where + __Context__: HasField< + Symbol<3, Chars<'f', Chars<'o', Chars<'o', Nil>>>>, + Value: AsRef<[u8]> + 'static, + >, + { + fn foo(__context__: &__Context__) -> &[u8] { + __context__ + .get_field( + ::core::marker::PhantomData::< + Symbol<3, Chars<'f', Chars<'o', Chars<'o', Nil>>>>, + >, + ) + .as_ref() + } + } + impl<__Context__> IsProviderFor for UseFields + where + __Context__: HasField< + Symbol<3, Chars<'f', Chars<'o', Chars<'o', Nil>>>>, + Value: AsRef<[u8]> + 'static, + >, + {} + impl<__Context__, __Tag__> FooGetter<__Context__> for UseField<__Tag__> + where + __Context__: HasField<__Tag__, Value: AsRef<[u8]> + 'static>, + { + fn foo(__context__: &__Context__) -> &[u8] { + __context__.get_field(::core::marker::PhantomData::<__Tag__>).as_ref() + } + } + impl<__Context__, __Tag__> IsProviderFor + for UseField<__Tag__> + where + __Context__: HasField<__Tag__, Value: AsRef<[u8]> + 'static>, + {} + impl<__Context__, __Provider__> FooGetter<__Context__> for WithProvider<__Provider__> + where + __Provider__: FieldGetter< + __Context__, + FooGetterComponent, + Value: AsRef<[u8]> + 'static, + >, + { + fn foo(__context__: &__Context__) -> &[u8] { + __Provider__::get_field( + __context__, + ::core::marker::PhantomData::, + ) + .as_ref() + } + } + impl<__Context__, __Provider__> IsProviderFor + for WithProvider<__Provider__> + where + __Provider__: FieldGetter< + __Context__, + FooGetterComponent, + Value: AsRef<[u8]> + 'static, + >, + {} + ") + } } #[derive(HasField)] @@ -12,22 +146,69 @@ pub fn test_slice_getter() { pub bar: Vec, } - delegate_components! { - App { - FooGetterComponent: UseField, + snapshot_delegate_components! { + delegate_components! { + App { + FooGetterComponent: UseField, + } + } + + expand_app(output) { + assert_snapshot!(output, @r#" + impl DelegateComponent for App { + type Delegate = UseField; + } + impl<__Context__, __Params__> IsProviderFor + for App + where + UseField: IsProviderFor, + {} + "#) } } - let context = App { bar: vec![1, 2, 3] }; + #[test] + pub fn test_slice_getter() { + let context = App { bar: vec![1, 2, 3] }; - assert_eq!(context.foo(), &[1, 2, 3]); + assert_eq!(context.foo(), &[1, 2, 3]); + } } -#[test] -pub fn test_slice_auto_getter() { - #[cgp_auto_getter] - pub trait HasFoo { - fn foo(&self) -> &[u8]; +mod slice_auto_getter { + use cgp::prelude::*; + use cgp_macro_test_util::snapshot_cgp_auto_getter; + use insta::assert_snapshot; + + snapshot_cgp_auto_getter! { + #[cgp_auto_getter] + pub trait HasFoo { + fn foo(&self) -> &[u8]; + } + + expand_has_foo(output) { + assert_snapshot!(output, @" + pub trait HasFoo { + fn foo(&self) -> &[u8]; + } + impl<__Context__> HasFoo for __Context__ + where + __Context__: HasField< + Symbol<3, Chars<'f', Chars<'o', Chars<'o', Nil>>>>, + Value: AsRef<[u8]> + 'static, + >, + { + fn foo(&self) -> &[u8] { + self.get_field( + ::core::marker::PhantomData::< + Symbol<3, Chars<'f', Chars<'o', Chars<'o', Nil>>>>, + >, + ) + .as_ref() + } + } + ") + } } #[derive(HasField)] @@ -35,7 +216,10 @@ pub fn test_slice_auto_getter() { pub foo: Vec, } - let context = App { foo: vec![1, 2, 3] }; + #[test] + pub fn test_slice_auto_getter() { + let context = App { foo: vec![1, 2, 3] }; - assert_eq!(context.foo(), &[1, 2, 3]); + assert_eq!(context.foo(), &[1, 2, 3]); + } } diff --git a/crates/tests/cgp-tests/tests/getter_tests/string.rs b/crates/tests/cgp-tests/tests/getter_tests/string.rs index 02add9d9..55c74234 100644 --- a/crates/tests/cgp-tests/tests/getter_tests/string.rs +++ b/crates/tests/cgp-tests/tests/getter_tests/string.rs @@ -1,10 +1,136 @@ -use cgp::prelude::*; +mod string_getter { + use cgp::prelude::*; + use cgp_macro_test_util::{snapshot_cgp_getter, snapshot_delegate_components}; + use insta::assert_snapshot; -#[test] -pub fn test_string_getter() { - #[cgp_getter] - pub trait HasFoo { - fn foo(&self) -> &str; + snapshot_cgp_getter! { + #[cgp_getter] + pub trait HasFoo { + fn foo(&self) -> &str; + } + + expand_has_foo(output) { + assert_snapshot!(output, @" + pub trait HasFoo { + fn foo(&self) -> &str; + } + impl<__Context__> HasFoo for __Context__ + where + __Context__: FooGetter<__Context__>, + { + fn foo(&self) -> &str { + __Context__::foo(self) + } + } + pub trait FooGetter<__Context__>: IsProviderFor { + fn foo(__context__: &__Context__) -> &str; + } + impl<__Provider__, __Context__> FooGetter<__Context__> for __Provider__ + where + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + FooGetterComponent, + >>::Delegate: FooGetter<__Context__>, + { + fn foo(__context__: &__Context__) -> &str { + <__Provider__ as DelegateComponent< + FooGetterComponent, + >>::Delegate::foo(__context__) + } + } + pub struct FooGetterComponent; + impl<__Context__> FooGetter<__Context__> for UseContext + where + __Context__: HasFoo, + { + fn foo(__context__: &__Context__) -> &str { + __Context__::foo(__context__) + } + } + impl<__Context__> IsProviderFor for UseContext + where + __Context__: HasFoo, + {} + impl<__Context__, __Components__, __Path__> FooGetter<__Context__> + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent<__Path__>>::Delegate: FooGetter<__Context__>, + { + fn foo(__context__: &__Context__) -> &str { + <__Components__ as DelegateComponent<__Path__>>::Delegate::foo(__context__) + } + } + impl< + __Context__, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: IsProviderFor + + FooGetter<__Context__>, + {} + impl<__Context__> FooGetter<__Context__> for UseFields + where + __Context__: HasField< + Symbol<3, Chars<'f', Chars<'o', Chars<'o', Nil>>>>, + Value = String, + >, + { + fn foo(__context__: &__Context__) -> &str { + __context__ + .get_field( + ::core::marker::PhantomData::< + Symbol<3, Chars<'f', Chars<'o', Chars<'o', Nil>>>>, + >, + ) + .as_str() + } + } + impl<__Context__> IsProviderFor for UseFields + where + __Context__: HasField< + Symbol<3, Chars<'f', Chars<'o', Chars<'o', Nil>>>>, + Value = String, + >, + {} + impl<__Context__, __Tag__> FooGetter<__Context__> for UseField<__Tag__> + where + __Context__: HasField<__Tag__, Value = String>, + { + fn foo(__context__: &__Context__) -> &str { + __context__.get_field(::core::marker::PhantomData::<__Tag__>).as_str() + } + } + impl<__Context__, __Tag__> IsProviderFor + for UseField<__Tag__> + where + __Context__: HasField<__Tag__, Value = String>, + {} + impl<__Context__, __Provider__> FooGetter<__Context__> for WithProvider<__Provider__> + where + __Provider__: FieldGetter<__Context__, FooGetterComponent, Value = String>, + { + fn foo(__context__: &__Context__) -> &str { + __Provider__::get_field( + __context__, + ::core::marker::PhantomData::, + ) + .as_str() + } + } + impl<__Context__, __Provider__> IsProviderFor + for WithProvider<__Provider__> + where + __Provider__: FieldGetter<__Context__, FooGetterComponent, Value = String>, + {} + ") + } } #[derive(HasField)] @@ -12,24 +138,170 @@ pub fn test_string_getter() { pub bar: String, } - delegate_components! { - App { - FooGetterComponent: UseField, + snapshot_delegate_components! { + delegate_components! { + App { + FooGetterComponent: UseField, + } + } + + expand_app(output) { + assert_snapshot!(output, @r#" + impl DelegateComponent for App { + type Delegate = UseField; + } + impl<__Context__, __Params__> IsProviderFor + for App + where + UseField: IsProviderFor, + {} + "#) } } - let context = App { - bar: "abc".to_owned(), - }; + #[test] + pub fn test_string_getter() { + let context = App { + bar: "abc".to_owned(), + }; - assert_eq!(context.foo(), "abc"); + assert_eq!(context.foo(), "abc"); + } } -#[test] -pub fn test_string_getter_with_custom_name() { - #[cgp_getter(GetString)] - pub trait HasFoo { - fn foo(&self) -> &str; +mod string_getter_with_custom_name { + use cgp::prelude::*; + use cgp_macro_test_util::{snapshot_cgp_getter, snapshot_delegate_components}; + use insta::assert_snapshot; + + snapshot_cgp_getter! { + #[cgp_getter(GetString)] + pub trait HasFoo { + fn foo(&self) -> &str; + } + + expand_has_foo(output) { + assert_snapshot!(output, @" + pub trait HasFoo { + fn foo(&self) -> &str; + } + impl<__Context__> HasFoo for __Context__ + where + __Context__: GetString<__Context__>, + { + fn foo(&self) -> &str { + __Context__::foo(self) + } + } + pub trait GetString<__Context__>: IsProviderFor { + fn foo(__context__: &__Context__) -> &str; + } + impl<__Provider__, __Context__> GetString<__Context__> for __Provider__ + where + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + GetStringComponent, + >>::Delegate: GetString<__Context__>, + { + fn foo(__context__: &__Context__) -> &str { + <__Provider__ as DelegateComponent< + GetStringComponent, + >>::Delegate::foo(__context__) + } + } + pub struct GetStringComponent; + impl<__Context__> GetString<__Context__> for UseContext + where + __Context__: HasFoo, + { + fn foo(__context__: &__Context__) -> &str { + __Context__::foo(__context__) + } + } + impl<__Context__> IsProviderFor for UseContext + where + __Context__: HasFoo, + {} + impl<__Context__, __Components__, __Path__> GetString<__Context__> + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent<__Path__>>::Delegate: GetString<__Context__>, + { + fn foo(__context__: &__Context__) -> &str { + <__Components__ as DelegateComponent<__Path__>>::Delegate::foo(__context__) + } + } + impl< + __Context__, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: IsProviderFor + + GetString<__Context__>, + {} + impl<__Context__> GetString<__Context__> for UseFields + where + __Context__: HasField< + Symbol<3, Chars<'f', Chars<'o', Chars<'o', Nil>>>>, + Value = String, + >, + { + fn foo(__context__: &__Context__) -> &str { + __context__ + .get_field( + ::core::marker::PhantomData::< + Symbol<3, Chars<'f', Chars<'o', Chars<'o', Nil>>>>, + >, + ) + .as_str() + } + } + impl<__Context__> IsProviderFor for UseFields + where + __Context__: HasField< + Symbol<3, Chars<'f', Chars<'o', Chars<'o', Nil>>>>, + Value = String, + >, + {} + impl<__Context__, __Tag__> GetString<__Context__> for UseField<__Tag__> + where + __Context__: HasField<__Tag__, Value = String>, + { + fn foo(__context__: &__Context__) -> &str { + __context__.get_field(::core::marker::PhantomData::<__Tag__>).as_str() + } + } + impl<__Context__, __Tag__> IsProviderFor + for UseField<__Tag__> + where + __Context__: HasField<__Tag__, Value = String>, + {} + impl<__Context__, __Provider__> GetString<__Context__> for WithProvider<__Provider__> + where + __Provider__: FieldGetter<__Context__, GetStringComponent, Value = String>, + { + fn foo(__context__: &__Context__) -> &str { + __Provider__::get_field( + __context__, + ::core::marker::PhantomData::, + ) + .as_str() + } + } + impl<__Context__, __Provider__> IsProviderFor + for WithProvider<__Provider__> + where + __Provider__: FieldGetter<__Context__, GetStringComponent, Value = String>, + {} + ") + } } #[derive(HasField)] @@ -37,27 +309,164 @@ pub fn test_string_getter_with_custom_name() { pub bar: String, } - delegate_components! { - App { - GetStringComponent: UseField, + snapshot_delegate_components! { + delegate_components! { + App { + GetStringComponent: UseField, + } + } + + expand_app(output) { + assert_snapshot!(output, @r#" + impl DelegateComponent for App { + type Delegate = UseField; + } + impl<__Context__, __Params__> IsProviderFor + for App + where + UseField: IsProviderFor, + {} + "#) } } - let context = App { - bar: "abc".to_owned(), - }; + #[test] + pub fn test_string_getter_with_custom_name() { + let context = App { + bar: "abc".to_owned(), + }; - assert_eq!(context.foo(), "abc"); + assert_eq!(context.foo(), "abc"); + } } -#[test] -pub fn test_string_getter_with_custom_spec() { - #[cgp_getter{ - provider: GetString, - name: GetStringComp, - }] - pub trait HasFoo { - fn foo(&self) -> &str; +mod string_getter_with_custom_spec { + use cgp::prelude::*; + use cgp_macro_test_util::{snapshot_cgp_getter, snapshot_delegate_components}; + use insta::assert_snapshot; + + snapshot_cgp_getter! { + #[cgp_getter{ + provider: GetString, + name: GetStringComp, + }] + pub trait HasFoo { + fn foo(&self) -> &str; + } + + expand_has_foo(output) { + assert_snapshot!(output, @" + pub trait HasFoo { + fn foo(&self) -> &str; + } + impl<__Context__> HasFoo for __Context__ + where + __Context__: GetString<__Context__>, + { + fn foo(&self) -> &str { + __Context__::foo(self) + } + } + pub trait GetString<__Context__>: IsProviderFor { + fn foo(__context__: &__Context__) -> &str; + } + impl<__Provider__, __Context__> GetString<__Context__> for __Provider__ + where + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent>::Delegate: GetString<__Context__>, + { + fn foo(__context__: &__Context__) -> &str { + <__Provider__ as DelegateComponent>::Delegate::foo(__context__) + } + } + pub struct GetStringComp; + impl<__Context__> GetString<__Context__> for UseContext + where + __Context__: HasFoo, + { + fn foo(__context__: &__Context__) -> &str { + __Context__::foo(__context__) + } + } + impl<__Context__> IsProviderFor for UseContext + where + __Context__: HasFoo, + {} + impl<__Context__, __Components__, __Path__> GetString<__Context__> + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent<__Path__>>::Delegate: GetString<__Context__>, + { + fn foo(__context__: &__Context__) -> &str { + <__Components__ as DelegateComponent<__Path__>>::Delegate::foo(__context__) + } + } + impl<__Context__, __Components__, __Path__> IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: IsProviderFor + GetString<__Context__>, + {} + impl<__Context__> GetString<__Context__> for UseFields + where + __Context__: HasField< + Symbol<3, Chars<'f', Chars<'o', Chars<'o', Nil>>>>, + Value = String, + >, + { + fn foo(__context__: &__Context__) -> &str { + __context__ + .get_field( + ::core::marker::PhantomData::< + Symbol<3, Chars<'f', Chars<'o', Chars<'o', Nil>>>>, + >, + ) + .as_str() + } + } + impl<__Context__> IsProviderFor for UseFields + where + __Context__: HasField< + Symbol<3, Chars<'f', Chars<'o', Chars<'o', Nil>>>>, + Value = String, + >, + {} + impl<__Context__, __Tag__> GetString<__Context__> for UseField<__Tag__> + where + __Context__: HasField<__Tag__, Value = String>, + { + fn foo(__context__: &__Context__) -> &str { + __context__.get_field(::core::marker::PhantomData::<__Tag__>).as_str() + } + } + impl<__Context__, __Tag__> IsProviderFor + for UseField<__Tag__> + where + __Context__: HasField<__Tag__, Value = String>, + {} + impl<__Context__, __Provider__> GetString<__Context__> for WithProvider<__Provider__> + where + __Provider__: FieldGetter<__Context__, GetStringComp, Value = String>, + { + fn foo(__context__: &__Context__) -> &str { + __Provider__::get_field( + __context__, + ::core::marker::PhantomData::, + ) + .as_str() + } + } + impl<__Context__, __Provider__> IsProviderFor + for WithProvider<__Provider__> + where + __Provider__: FieldGetter<__Context__, GetStringComp, Value = String>, + {} + ") + } } #[derive(HasField)] @@ -65,24 +474,71 @@ pub fn test_string_getter_with_custom_spec() { pub bar: String, } - delegate_components! { - App { - GetStringComp: UseField, + snapshot_delegate_components! { + delegate_components! { + App { + GetStringComp: UseField, + } + } + + expand_app(output) { + assert_snapshot!(output, @r#" + impl DelegateComponent for App { + type Delegate = UseField; + } + impl<__Context__, __Params__> IsProviderFor + for App + where + UseField: IsProviderFor, + {} + "#) } } - let context = App { - bar: "abc".to_owned(), - }; + #[test] + pub fn test_string_getter_with_custom_spec() { + let context = App { + bar: "abc".to_owned(), + }; - assert_eq!(context.foo(), "abc"); + assert_eq!(context.foo(), "abc"); + } } -#[test] -pub fn test_string_auto_getter() { - #[cgp_auto_getter] - pub trait HasFoo { - fn foo(&self) -> &str; +mod string_auto_getter { + use cgp::prelude::*; + use cgp_macro_test_util::snapshot_cgp_auto_getter; + use insta::assert_snapshot; + + snapshot_cgp_auto_getter! { + #[cgp_auto_getter] + pub trait HasFoo { + fn foo(&self) -> &str; + } + + expand_has_foo(output) { + assert_snapshot!(output, @" + pub trait HasFoo { + fn foo(&self) -> &str; + } + impl<__Context__> HasFoo for __Context__ + where + __Context__: HasField< + Symbol<3, Chars<'f', Chars<'o', Chars<'o', Nil>>>>, + Value = String, + >, + { + fn foo(&self) -> &str { + self.get_field( + ::core::marker::PhantomData::< + Symbol<3, Chars<'f', Chars<'o', Chars<'o', Nil>>>>, + >, + ) + .as_str() + } + } + ") + } } #[derive(HasField)] @@ -90,9 +546,12 @@ pub fn test_string_auto_getter() { pub foo: String, } - let context = App { - foo: "abc".to_owned(), - }; + #[test] + pub fn test_string_auto_getter() { + let context = App { + foo: "abc".to_owned(), + }; - assert_eq!(context.foo(), "abc"); + assert_eq!(context.foo(), "abc"); + } } diff --git a/crates/tests/cgp-tests/tests/handler_tests/computer_macro.rs b/crates/tests/cgp-tests/tests/handler_tests/computer_macro.rs index 93a21701..a45bd289 100644 --- a/crates/tests/cgp-tests/tests/handler_tests/computer_macro.rs +++ b/crates/tests/cgp-tests/tests/handler_tests/computer_macro.rs @@ -4,7 +4,9 @@ use cgp::core::error::{ErrorRaiserComponent, ErrorTypeProviderComponent}; use cgp::extra::error::RaiseFrom; use cgp::extra::handler::{ComputerRef, HandlerRef, TryComputerRef}; use cgp::prelude::*; +use cgp_macro_test_util::snapshot_delegate_components; use futures::executor::block_on; +use insta::assert_snapshot; #[cgp_computer] fn add(a: u64, b: u64) -> u64 { @@ -18,12 +20,39 @@ fn add_with_error(a: u64, b: u64) -> Result { pub struct App; -delegate_components! { - App { - ErrorTypeProviderComponent: - UseType, - ErrorRaiserComponent: - RaiseFrom, +snapshot_delegate_components! { + delegate_components! { + App { + ErrorTypeProviderComponent: + UseType, + ErrorRaiserComponent: + RaiseFrom, + } + } + + expand_computer_macro_app(output) { + assert_snapshot!(output, @" + impl DelegateComponent for App { + type Delegate = UseType; + } + impl< + __Context__, + __Params__, + > IsProviderFor for App + where + UseType: IsProviderFor, + {} + impl DelegateComponent for App { + type Delegate = RaiseFrom; + } + impl< + __Context__, + __Params__, + > IsProviderFor for App + where + RaiseFrom: IsProviderFor, + {} + ") } } diff --git a/crates/tests/cgp-tests/tests/handler_tests/handler_macro.rs b/crates/tests/cgp-tests/tests/handler_tests/handler_macro.rs index 0e87d358..187d5534 100644 --- a/crates/tests/cgp-tests/tests/handler_tests/handler_macro.rs +++ b/crates/tests/cgp-tests/tests/handler_tests/handler_macro.rs @@ -4,7 +4,9 @@ use cgp::core::error::{ErrorRaiserComponent, ErrorTypeProviderComponent}; use cgp::extra::error::RaiseFrom; use cgp::extra::handler::HandlerRef; use cgp::prelude::*; +use cgp_macro_test_util::snapshot_delegate_components; use futures::executor::block_on; +use insta::assert_snapshot; #[cgp_computer] async fn add(a: u64, b: u64) -> u64 { @@ -18,12 +20,39 @@ async fn add_with_error(a: u64, b: u64) -> Result { pub struct App; -delegate_components! { - App { - ErrorTypeProviderComponent: - UseType, - ErrorRaiserComponent: - RaiseFrom, +snapshot_delegate_components! { + delegate_components! { + App { + ErrorTypeProviderComponent: + UseType, + ErrorRaiserComponent: + RaiseFrom, + } + } + + expand_handler_macro_app(output) { + assert_snapshot!(output, @" + impl DelegateComponent for App { + type Delegate = UseType; + } + impl< + __Context__, + __Params__, + > IsProviderFor for App + where + UseType: IsProviderFor, + {} + impl DelegateComponent for App { + type Delegate = RaiseFrom; + } + impl< + __Context__, + __Params__, + > IsProviderFor for App + where + RaiseFrom: IsProviderFor, + {} + ") } } diff --git a/crates/tests/cgp-tests/tests/handler_tests/pipe.rs b/crates/tests/cgp-tests/tests/handler_tests/pipe.rs index 29fb2a97..39795f73 100644 --- a/crates/tests/cgp-tests/tests/handler_tests/pipe.rs +++ b/crates/tests/cgp-tests/tests/handler_tests/pipe.rs @@ -1,16 +1,11 @@ -use core::convert::Infallible; -use core::marker::PhantomData; - -use cgp::core::error::ErrorTypeProviderComponent; -use cgp::extra::handler::{ - CanCompute, CanHandle, Computer, ComputerComponent, Handler, HandlerComponent, PipeHandlers, - Promote, PromoteAsync, -}; -use cgp::prelude::*; -use futures::executor::block_on; - -#[test] -pub fn test_pipe_computers() { +mod pipe_computers { + use core::marker::PhantomData; + + use cgp::extra::handler::{CanCompute, Computer, ComputerComponent, PipeHandlers}; + use cgp::prelude::*; + use cgp_macro_test_util::snapshot_delegate_components; + use insta::assert_snapshot; + #[cgp_new_provider] impl Computer for Multiply where @@ -42,16 +37,41 @@ pub fn test_pipe_computers() { pub baz: u64, } - delegate_components! { - MyContext { - ComputerComponent: + snapshot_delegate_components! { + delegate_components! { + MyContext { + ComputerComponent: + PipeHandlers< + Product! [ + Multiply, + Add, + Multiply, + ] + >, + } + } + + expand_pipe_computers(output) { + assert_snapshot!(output, @r#" + impl DelegateComponent for MyContext { + type Delegate = PipeHandlers< + Product![ + Multiply < Symbol!("foo") >, Add < Symbol!("bar") >, Multiply < + Symbol!("baz") >, + ], + >; + } + impl<__Context__, __Params__> IsProviderFor + for MyContext + where PipeHandlers< - Product! [ - Multiply, - Add, - Multiply, - ] - >, + Product![ + Multiply < Symbol!("foo") >, Add < Symbol!("bar") >, Multiply < + Symbol!("baz") >, + ], + >: IsProviderFor, + {} + "#) } } @@ -62,19 +82,33 @@ pub fn test_pipe_computers() { } } - let context = MyContext { - foo: 2, - bar: 3, - baz: 4, - }; + #[test] + pub fn test_pipe_computers() { + let context = MyContext { + foo: 2, + bar: 3, + baz: 4, + }; - let result = context.compute(PhantomData::<()>, 5); + let result = context.compute(PhantomData::<()>, 5); - assert_eq!(result, ((5 * 2) + 3) * 4); + assert_eq!(result, ((5 * 2) + 3) * 4); + } } -#[test] -pub fn test_pipe_handlers() { +mod pipe_handlers { + use core::convert::Infallible; + use core::marker::PhantomData; + + use cgp::core::error::ErrorTypeProviderComponent; + use cgp::extra::handler::{ + CanHandle, Computer, Handler, HandlerComponent, PipeHandlers, Promote, PromoteAsync, + }; + use cgp::prelude::*; + use cgp_macro_test_util::snapshot_delegate_components; + use futures::executor::block_on; + use insta::assert_snapshot; + #[cgp_new_provider] impl Handler for Multiply where @@ -110,17 +144,54 @@ pub fn test_pipe_handlers() { pub baz: u64, } - delegate_components! { - MyContext { - ErrorTypeProviderComponent: UseType, - HandlerComponent: + snapshot_delegate_components! { + delegate_components! { + MyContext { + ErrorTypeProviderComponent: UseType, + HandlerComponent: + PipeHandlers< + Product! [ + Multiply, + PromoteAsync>>, + Multiply, + ] + >, + } + } + + expand_pipe_handlers(output) { + assert_snapshot!(output, @r#" + impl DelegateComponent for MyContext { + type Delegate = UseType; + } + impl< + __Context__, + __Params__, + > IsProviderFor for MyContext + where + UseType< + Infallible, + >: IsProviderFor, + {} + impl DelegateComponent for MyContext { + type Delegate = PipeHandlers< + Product![ + Multiply < Symbol!("foo") >, PromoteAsync < Promote < Add < Symbol!("bar") + >>>, Multiply < Symbol!("baz") >, + ], + >; + } + impl<__Context__, __Params__> IsProviderFor + for MyContext + where PipeHandlers< - Product! [ - Multiply, - PromoteAsync>>, - Multiply, - ] - >, + Product![ + Multiply < Symbol!("foo") >, PromoteAsync < Promote < Add < Symbol!("bar") + >>>, Multiply < Symbol!("baz") >, + ], + >: IsProviderFor, + {} + "#) } } @@ -131,13 +202,16 @@ pub fn test_pipe_handlers() { } } - let context = MyContext { - foo: 2, - bar: 3, - baz: 4, - }; + #[test] + pub fn test_pipe_handlers() { + let context = MyContext { + foo: 2, + bar: 3, + baz: 4, + }; - let result = block_on(context.handle(PhantomData::<()>, 5)).unwrap(); + let result = block_on(context.handle(PhantomData::<()>, 5)).unwrap(); - assert_eq!(result, ((5 * 2) + 3) * 4); + assert_eq!(result, ((5 * 2) + 3) * 4); + } } diff --git a/crates/tests/cgp-tests/tests/handler_tests/producer_macro.rs b/crates/tests/cgp-tests/tests/handler_tests/producer_macro.rs index e913b75a..a88d30e6 100644 --- a/crates/tests/cgp-tests/tests/handler_tests/producer_macro.rs +++ b/crates/tests/cgp-tests/tests/handler_tests/producer_macro.rs @@ -1,7 +1,9 @@ use cgp::core::error::ErrorTypeProviderComponent; use cgp::extra::handler::{ComputerRef, HandlerRef, TryComputerRef}; use cgp::prelude::*; +use cgp_macro_test_util::snapshot_delegate_components; use futures::executor::block_on; +use insta::assert_snapshot; #[cgp_producer] pub fn magic_number() -> u64 { @@ -10,10 +12,27 @@ pub fn magic_number() -> u64 { pub struct App; -delegate_components! { - App { - ErrorTypeProviderComponent: - UseType, +snapshot_delegate_components! { + delegate_components! { + App { + ErrorTypeProviderComponent: + UseType, + } + } + + expand_producer_macro_app(output) { + assert_snapshot!(output, @" + impl DelegateComponent for App { + type Delegate = UseType; + } + impl< + __Context__, + __Params__, + > IsProviderFor for App + where + UseType: IsProviderFor, + {} + ") } } diff --git a/crates/tests/cgp-tests/tests/namespace_tests/multi_param.rs b/crates/tests/cgp-tests/tests/namespace_tests/multi_param.rs index 3c2ddfb1..a19fc104 100644 --- a/crates/tests/cgp-tests/tests/namespace_tests/multi_param.rs +++ b/crates/tests/cgp-tests/tests/namespace_tests/multi_param.rs @@ -1,26 +1,218 @@ use cgp::prelude::*; +use cgp_macro_test_util::{ + snapshot_cgp_component, snapshot_cgp_impl, snapshot_delegate_components, +}; +use insta::assert_snapshot; -#[cgp_component(FooProvider)] -#[prefix(@app in DefaultNamespace)] -pub trait Foo<'a, T, U> { - fn foo(&self, first: &'a T, second: U); +snapshot_cgp_component! { + #[cgp_component(FooProvider)] + #[prefix(@app in DefaultNamespace)] + pub trait Foo<'a, T, U> { + fn foo(&self, first: &'a T, second: U); + } + + expand_multi_param_foo(output) { + assert_snapshot!(output, @" + pub trait Foo<'a, T, U> { + fn foo(&self, first: &'a T, second: U); + } + impl<'a, __Context__, T, U> Foo<'a, T, U> for __Context__ + where + __Context__: FooProvider<'a, __Context__, T, U>, + { + fn foo(&self, first: &'a T, second: U) { + __Context__::foo(self, first, second) + } + } + pub trait FooProvider< + 'a, + __Context__, + T, + U, + >: IsProviderFor, T, U)> { + fn foo(__context__: &__Context__, first: &'a T, second: U); + } + impl<'a, __Provider__, __Context__, T, U> FooProvider<'a, __Context__, T, U> + for __Provider__ + where + __Provider__: DelegateComponent + + IsProviderFor, T, U)>, + <__Provider__ as DelegateComponent< + FooProviderComponent, + >>::Delegate: FooProvider<'a, __Context__, T, U>, + { + fn foo(__context__: &__Context__, first: &'a T, second: U) { + <__Provider__ as DelegateComponent< + FooProviderComponent, + >>::Delegate::foo(__context__, first, second) + } + } + pub struct FooProviderComponent; + impl<'a, __Context__, T, U> FooProvider<'a, __Context__, T, U> for UseContext + where + __Context__: Foo<'a, T, U>, + { + fn foo(__context__: &__Context__, first: &'a T, second: U) { + __Context__::foo(__context__, first, second) + } + } + impl< + 'a, + __Context__, + T, + U, + > IsProviderFor, T, U)> for UseContext + where + __Context__: Foo<'a, T, U>, + {} + impl<'a, __Context__, T, U, __Components__, __Path__> FooProvider<'a, __Context__, T, U> + for RedirectLookup<__Components__, __Path__> + where + __Path__: ConcatPath>>, + __Components__: DelegateComponent< + <__Path__ as ConcatPath>>>::Output, + >, + <__Components__ as DelegateComponent< + <__Path__ as ConcatPath>>>::Output, + >>::Delegate: FooProvider<'a, __Context__, T, U>, + { + fn foo(__context__: &__Context__, first: &'a T, second: U) { + <__Components__ as DelegateComponent< + <__Path__ as ConcatPath>>>::Output, + >>::Delegate::foo(__context__, first, second) + } + } + impl< + 'a, + __Context__, + T, + U, + __Components__, + __Path__, + > IsProviderFor, T, U)> + for RedirectLookup<__Components__, __Path__> + where + __Path__: ConcatPath>>, + __Components__: DelegateComponent< + <__Path__ as ConcatPath>>>::Output, + >, + <__Components__ as DelegateComponent< + <__Path__ as ConcatPath>>>::Output, + >>::Delegate: FooProvider<'a, __Context__, T, U>, + {} + impl<__Components__> DefaultNamespace<__Components__> for FooProviderComponent { + type Delegate = RedirectLookup< + __Components__, + PathCons< + Symbol<3, Chars<'a', Chars<'p', Chars<'p', Nil>>>>, + PathCons, + >, + >; + } + ") + } } -#[cgp_impl(new DummyFoo)] -impl<'a, T, U> FooProvider<'a, T, U> { - fn foo(&self, _first: &'a T, _second: U) {} +snapshot_cgp_impl! { + #[cgp_impl(new DummyFoo)] + impl<'a, T, U> FooProvider<'a, T, U> { + fn foo(&self, _first: &'a T, _second: U) {} + } + + expand_multi_param_dummy_foo(output) { + assert_snapshot!(output, @" + impl<'a, __Context__, T, U> FooProvider<'a, __Context__, T, U> for DummyFoo { + fn foo(__context__: &__Context__, _first: &'a T, _second: U) {} + } + impl< + 'a, + __Context__, + T, + U, + > IsProviderFor, T, U)> for DummyFoo {} + pub struct DummyFoo; + ") + } } pub struct AppA; -delegate_components! { - AppA { - open {FooProviderComponent}; +snapshot_delegate_components! { + delegate_components! { + AppA { + open {FooProviderComponent}; + + @FooProviderComponent.String.u32: + DummyFoo, + @FooProviderComponent.bool.T: + DummyFoo, + } + } - @FooProviderComponent.String.u32: - DummyFoo, - @FooProviderComponent.bool.T: - DummyFoo, + expand_multi_param_app_a(output) { + assert_snapshot!(output, @" + impl DelegateComponent for AppA { + type Delegate = RedirectLookup>; + } + impl< + __Context__, + __Params__, + > IsProviderFor for AppA + where + RedirectLookup< + AppA, + PathCons, + >: IsProviderFor, + {} + impl< + __Wildcard__, + > DelegateComponent< + PathCons>>, + > for AppA { + type Delegate = DummyFoo; + } + impl< + __Wildcard__, + __Context__, + __Params__, + > IsProviderFor< + PathCons>>, + __Context__, + __Params__, + > for AppA + where + DummyFoo: IsProviderFor< + PathCons>>, + __Context__, + __Params__, + >, + {} + impl< + T, + __Wildcard__, + > DelegateComponent< + PathCons>>, + > for AppA { + type Delegate = DummyFoo; + } + impl< + T, + __Wildcard__, + __Context__, + __Params__, + > IsProviderFor< + PathCons>>, + __Context__, + __Params__, + > for AppA + where + DummyFoo: IsProviderFor< + PathCons>>, + __Context__, + __Params__, + >, + {} + ") } } @@ -37,14 +229,103 @@ check_components! { pub struct AppB; -delegate_components! { - AppB { - namespace DefaultNamespace; +snapshot_delegate_components! { + delegate_components! { + AppB { + namespace DefaultNamespace; + + @app.FooProviderComponent.String.u64: + DummyFoo, + @app.FooProviderComponent.bool. T: + DummyFoo, + } + } - @app.FooProviderComponent.String.u64: - DummyFoo, - @app.FooProviderComponent.bool. T: - DummyFoo, + expand_multi_param_app_b(output) { + assert_snapshot!(output, @" + impl<__Key__, __Value__> DelegateComponent<__Key__> for AppB + where + __Key__: DefaultNamespace, + { + type Delegate = __Value__; + } + impl< + __Key__, + __Value__, + __Context__, + __Params__, + > IsProviderFor<__Key__, __Context__, __Params__> for AppB + where + __Key__: DefaultNamespace, + __Value__: IsProviderFor<__Key__, __Context__, __Params__>, + {} + impl< + __Wildcard__, + > DelegateComponent< + PathCons< + Symbol<3, Chars<'a', Chars<'p', Chars<'p', Nil>>>>, + PathCons>>, + >, + > for AppB { + type Delegate = DummyFoo; + } + impl< + __Wildcard__, + __Context__, + __Params__, + > IsProviderFor< + PathCons< + Symbol<3, Chars<'a', Chars<'p', Chars<'p', Nil>>>>, + PathCons>>, + >, + __Context__, + __Params__, + > for AppB + where + DummyFoo: IsProviderFor< + PathCons< + Symbol<3, Chars<'a', Chars<'p', Chars<'p', Nil>>>>, + PathCons>>, + >, + __Context__, + __Params__, + >, + {} + impl< + T, + __Wildcard__, + > DelegateComponent< + PathCons< + Symbol<3, Chars<'a', Chars<'p', Chars<'p', Nil>>>>, + PathCons>>, + >, + > for AppB { + type Delegate = DummyFoo; + } + impl< + T, + __Wildcard__, + __Context__, + __Params__, + > IsProviderFor< + PathCons< + Symbol<3, Chars<'a', Chars<'p', Chars<'p', Nil>>>>, + PathCons>>, + >, + __Context__, + __Params__, + > for AppB + where + DummyFoo: IsProviderFor< + PathCons< + Symbol<3, Chars<'a', Chars<'p', Chars<'p', Nil>>>>, + PathCons>>, + >, + __Context__, + __Params__, + >, + {} + ") } } diff --git a/crates/tests/cgp-tests/tests/namespace_tests/namespace.rs b/crates/tests/cgp-tests/tests/namespace_tests/namespace.rs index 0742ec6e..56396e1f 100644 --- a/crates/tests/cgp-tests/tests/namespace_tests/namespace.rs +++ b/crates/tests/cgp-tests/tests/namespace_tests/namespace.rs @@ -1,25 +1,255 @@ use cgp::core::error::{ErrorRaiserComponent, ErrorTypeProviderComponent}; use cgp::extra::error::ReturnError; use cgp::prelude::*; +use cgp_macro_test_util::{snapshot_cgp_component, snapshot_delegate_components}; +use insta::assert_snapshot; pub struct MyComponents; -#[cgp_component(FooProvider)] -#[prefix(@app.MyComponents.FooProviderComponent in DefaultNamespace)] -pub trait Foo { - fn foo(&self); +snapshot_cgp_component! { + #[cgp_component(FooProvider)] + #[prefix(@app.MyComponents.FooProviderComponent in DefaultNamespace)] + pub trait Foo { + fn foo(&self); + } + + expand_namespace_foo(output) { + assert_snapshot!(output, @" + pub trait Foo { + fn foo(&self); + } + impl<__Context__> Foo for __Context__ + where + __Context__: FooProvider<__Context__>, + { + fn foo(&self) { + __Context__::foo(self) + } + } + pub trait FooProvider< + __Context__, + >: IsProviderFor { + fn foo(__context__: &__Context__); + } + impl<__Provider__, __Context__> FooProvider<__Context__> for __Provider__ + where + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + FooProviderComponent, + >>::Delegate: FooProvider<__Context__>, + { + fn foo(__context__: &__Context__) { + <__Provider__ as DelegateComponent< + FooProviderComponent, + >>::Delegate::foo(__context__) + } + } + pub struct FooProviderComponent; + impl<__Context__> FooProvider<__Context__> for UseContext + where + __Context__: Foo, + { + fn foo(__context__: &__Context__) { + __Context__::foo(__context__) + } + } + impl<__Context__> IsProviderFor for UseContext + where + __Context__: Foo, + {} + impl<__Context__, __Components__, __Path__> FooProvider<__Context__> + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent<__Path__>>::Delegate: FooProvider<__Context__>, + { + fn foo(__context__: &__Context__) { + <__Components__ as DelegateComponent<__Path__>>::Delegate::foo(__context__) + } + } + impl< + __Context__, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: IsProviderFor + + FooProvider<__Context__>, + {} + impl<__Components__> DefaultNamespace<__Components__> for FooProviderComponent { + type Delegate = RedirectLookup< + __Components__, + PathCons< + Symbol<3, Chars<'a', Chars<'p', Chars<'p', Nil>>>>, + PathCons< + MyComponents, + PathCons>, + >, + >, + >; + } + ") + } } pub struct App; -delegate_components! { - App { - namespace DefaultNamespace; +snapshot_delegate_components! { + delegate_components! { + App { + namespace DefaultNamespace; + + @cgp.core.error.ErrorTypeProviderComponent: + UseType, + @cgp.core.error.ErrorRaiserComponent.String: + ReturnError, + } + } - @cgp.core.error.ErrorTypeProviderComponent: - UseType, - @cgp.core.error.ErrorRaiserComponent.String: - ReturnError, + expand_namespace_app(output) { + assert_snapshot!(output, @" + impl<__Key__, __Value__> DelegateComponent<__Key__> for App + where + __Key__: DefaultNamespace, + { + type Delegate = __Value__; + } + impl< + __Key__, + __Value__, + __Context__, + __Params__, + > IsProviderFor<__Key__, __Context__, __Params__> for App + where + __Key__: DefaultNamespace, + __Value__: IsProviderFor<__Key__, __Context__, __Params__>, + {} + impl< + __Wildcard__, + > DelegateComponent< + PathCons< + Symbol<3, Chars<'c', Chars<'g', Chars<'p', Nil>>>>, + PathCons< + Symbol<4, Chars<'c', Chars<'o', Chars<'r', Chars<'e', Nil>>>>>, + PathCons< + Symbol< + 5, + Chars<'e', Chars<'r', Chars<'r', Chars<'o', Chars<'r', Nil>>>>>, + >, + PathCons, + >, + >, + >, + > for App { + type Delegate = UseType; + } + impl< + __Wildcard__, + __Context__, + __Params__, + > IsProviderFor< + PathCons< + Symbol<3, Chars<'c', Chars<'g', Chars<'p', Nil>>>>, + PathCons< + Symbol<4, Chars<'c', Chars<'o', Chars<'r', Chars<'e', Nil>>>>>, + PathCons< + Symbol< + 5, + Chars<'e', Chars<'r', Chars<'r', Chars<'o', Chars<'r', Nil>>>>>, + >, + PathCons, + >, + >, + >, + __Context__, + __Params__, + > for App + where + UseType< + String, + >: IsProviderFor< + PathCons< + Symbol<3, Chars<'c', Chars<'g', Chars<'p', Nil>>>>, + PathCons< + Symbol<4, Chars<'c', Chars<'o', Chars<'r', Chars<'e', Nil>>>>>, + PathCons< + Symbol< + 5, + Chars<'e', Chars<'r', Chars<'r', Chars<'o', Chars<'r', Nil>>>>>, + >, + PathCons, + >, + >, + >, + __Context__, + __Params__, + >, + {} + impl< + __Wildcard__, + > DelegateComponent< + PathCons< + Symbol<3, Chars<'c', Chars<'g', Chars<'p', Nil>>>>, + PathCons< + Symbol<4, Chars<'c', Chars<'o', Chars<'r', Chars<'e', Nil>>>>>, + PathCons< + Symbol< + 5, + Chars<'e', Chars<'r', Chars<'r', Chars<'o', Chars<'r', Nil>>>>>, + >, + PathCons>, + >, + >, + >, + > for App { + type Delegate = ReturnError; + } + impl< + __Wildcard__, + __Context__, + __Params__, + > IsProviderFor< + PathCons< + Symbol<3, Chars<'c', Chars<'g', Chars<'p', Nil>>>>, + PathCons< + Symbol<4, Chars<'c', Chars<'o', Chars<'r', Chars<'e', Nil>>>>>, + PathCons< + Symbol< + 5, + Chars<'e', Chars<'r', Chars<'r', Chars<'o', Chars<'r', Nil>>>>>, + >, + PathCons>, + >, + >, + >, + __Context__, + __Params__, + > for App + where + ReturnError: IsProviderFor< + PathCons< + Symbol<3, Chars<'c', Chars<'g', Chars<'p', Nil>>>>, + PathCons< + Symbol<4, Chars<'c', Chars<'o', Chars<'r', Chars<'e', Nil>>>>>, + PathCons< + Symbol< + 5, + Chars<'e', Chars<'r', Chars<'r', Chars<'o', Chars<'r', Nil>>>>>, + >, + PathCons>, + >, + >, + >, + __Context__, + __Params__, + >, + {} + ") } } diff --git a/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/basic.rs b/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/basic.rs index ab0aac0c..874d9d2f 100644 --- a/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/basic.rs +++ b/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/basic.rs @@ -1,8 +1,85 @@ use cgp::prelude::*; +use cgp_macro_test_util::{ + snapshot_cgp_component, snapshot_cgp_impl, snapshot_delegate_components, +}; +use insta::assert_snapshot; -#[cgp_component(FooProvider)] -pub trait Foo { - fn foo(&self); +snapshot_cgp_component! { + #[cgp_component(FooProvider)] + pub trait Foo { + fn foo(&self); + } + + expand_basic_foo(output) { + assert_snapshot!(output, @" + pub trait Foo { + fn foo(&self); + } + impl<__Context__> Foo for __Context__ + where + __Context__: FooProvider<__Context__>, + { + fn foo(&self) { + __Context__::foo(self) + } + } + pub trait FooProvider< + __Context__, + >: IsProviderFor { + fn foo(__context__: &__Context__); + } + impl<__Provider__, __Context__> FooProvider<__Context__> for __Provider__ + where + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + FooProviderComponent, + >>::Delegate: FooProvider<__Context__>, + { + fn foo(__context__: &__Context__) { + <__Provider__ as DelegateComponent< + FooProviderComponent, + >>::Delegate::foo(__context__) + } + } + pub struct FooProviderComponent; + impl<__Context__> FooProvider<__Context__> for UseContext + where + __Context__: Foo, + { + fn foo(__context__: &__Context__) { + __Context__::foo(__context__) + } + } + impl<__Context__> IsProviderFor for UseContext + where + __Context__: Foo, + {} + impl<__Context__, __Components__, __Path__> FooProvider<__Context__> + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent<__Path__>>::Delegate: FooProvider<__Context__>, + { + fn foo(__context__: &__Context__) { + <__Components__ as DelegateComponent<__Path__>>::Delegate::foo(__context__) + } + } + impl< + __Context__, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: IsProviderFor + + FooProvider<__Context__>, + {} + ") + } } cgp_namespace! { @@ -12,35 +89,191 @@ cgp_namespace! { } } -#[cgp_component(BarProvider)] -#[prefix(@MyBarComponent in MyNamespace)] -pub trait Bar { - fn bar(&self); +snapshot_cgp_component! { + #[cgp_component(BarProvider)] + #[prefix(@MyBarComponent in MyNamespace)] + pub trait Bar { + fn bar(&self); + } + + expand_basic_bar(output) { + assert_snapshot!(output, @" + pub trait Bar { + fn bar(&self); + } + impl<__Context__> Bar for __Context__ + where + __Context__: BarProvider<__Context__>, + { + fn bar(&self) { + __Context__::bar(self) + } + } + pub trait BarProvider< + __Context__, + >: IsProviderFor { + fn bar(__context__: &__Context__); + } + impl<__Provider__, __Context__> BarProvider<__Context__> for __Provider__ + where + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + BarProviderComponent, + >>::Delegate: BarProvider<__Context__>, + { + fn bar(__context__: &__Context__) { + <__Provider__ as DelegateComponent< + BarProviderComponent, + >>::Delegate::bar(__context__) + } + } + pub struct BarProviderComponent; + impl<__Context__> BarProvider<__Context__> for UseContext + where + __Context__: Bar, + { + fn bar(__context__: &__Context__) { + __Context__::bar(__context__) + } + } + impl<__Context__> IsProviderFor for UseContext + where + __Context__: Bar, + {} + impl<__Context__, __Components__, __Path__> BarProvider<__Context__> + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent<__Path__>>::Delegate: BarProvider<__Context__>, + { + fn bar(__context__: &__Context__) { + <__Components__ as DelegateComponent<__Path__>>::Delegate::bar(__context__) + } + } + impl< + __Context__, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: IsProviderFor + + BarProvider<__Context__>, + {} + impl<__Components__> MyNamespace<__Components__> for BarProviderComponent { + type Delegate = RedirectLookup< + __Components__, + PathCons>, + >; + } + ") + } } pub struct MyFooComponent; pub struct MyBarComponent; -#[cgp_impl(new DummyFoo)] -impl FooProvider { - fn foo(&self) {} +snapshot_cgp_impl! { + #[cgp_impl(new DummyFoo)] + impl FooProvider { + fn foo(&self) {} + } + + expand_basic_dummy_foo(output) { + assert_snapshot!(output, @" + impl<__Context__> FooProvider<__Context__> for DummyFoo { + fn foo(__context__: &__Context__) {} + } + impl<__Context__> IsProviderFor for DummyFoo {} + pub struct DummyFoo; + ") + } } -#[cgp_impl(new DummyBar)] -impl BarProvider { - fn bar(&self) {} +snapshot_cgp_impl! { + #[cgp_impl(new DummyBar)] + impl BarProvider { + fn bar(&self) {} + } + + expand_basic_dummy_bar(output) { + assert_snapshot!(output, @" + impl<__Context__> BarProvider<__Context__> for DummyBar { + fn bar(__context__: &__Context__) {} + } + impl<__Context__> IsProviderFor for DummyBar {} + pub struct DummyBar; + ") + } } pub struct App; -delegate_components! { - App { - namespace MyNamespace; +snapshot_delegate_components! { + delegate_components! { + App { + namespace MyNamespace; + + @MyFooComponent: + DummyFoo, + @MyBarComponent: + DummyBar, + } + } - @MyFooComponent: - DummyFoo, - @MyBarComponent: - DummyBar, + expand_basic_app(output) { + assert_snapshot!(output, @" + impl<__Key__, __Value__> DelegateComponent<__Key__> for App + where + __Key__: MyNamespace, + { + type Delegate = __Value__; + } + impl< + __Key__, + __Value__, + __Context__, + __Params__, + > IsProviderFor<__Key__, __Context__, __Params__> for App + where + __Key__: MyNamespace, + __Value__: IsProviderFor<__Key__, __Context__, __Params__>, + {} + impl<__Wildcard__> DelegateComponent> for App { + type Delegate = DummyFoo; + } + impl< + __Wildcard__, + __Context__, + __Params__, + > IsProviderFor, __Context__, __Params__> for App + where + DummyFoo: IsProviderFor< + PathCons, + __Context__, + __Params__, + >, + {} + impl<__Wildcard__> DelegateComponent> for App { + type Delegate = DummyBar; + } + impl< + __Wildcard__, + __Context__, + __Params__, + > IsProviderFor, __Context__, __Params__> for App + where + DummyBar: IsProviderFor< + PathCons, + __Context__, + __Params__, + >, + {} + ") } } diff --git a/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/default_impls.rs b/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/default_impls.rs index dabdc5c9..faaad3ce 100644 --- a/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/default_impls.rs +++ b/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/default_impls.rs @@ -1,21 +1,118 @@ use cgp::core::component::DefaultImpls1; use cgp::prelude::*; +use cgp_macro_test_util::snapshot_delegate_components; use cgp_tests::namespaces::default_impls::{ DefaultShowComponents, ExtendedNamespace, ShowImplComponent, ShowWithDisplay, }; +use insta::assert_snapshot; pub struct AppA; -delegate_components! { - AppA { - namespace DefaultNamespace; +snapshot_delegate_components! { + delegate_components! { + AppA { + namespace DefaultNamespace; + + for in DefaultImpls1 { + @test.ShowImplComponent.T: Provider, + } - for in DefaultImpls1 { - @test.ShowImplComponent.T: Provider, + @test.ShowImplComponent.u64: + ShowWithDisplay, } + } - @test.ShowImplComponent.u64: - ShowWithDisplay, + expand_default_impls_app_a(output) { + assert_snapshot!(output, @" + impl<__Key__, __Value__> DelegateComponent<__Key__> for AppA + where + __Key__: DefaultNamespace, + { + type Delegate = __Value__; + } + impl< + __Key__, + __Value__, + __Context__, + __Params__, + > IsProviderFor<__Key__, __Context__, __Params__> for AppA + where + __Key__: DefaultNamespace, + __Value__: IsProviderFor<__Key__, __Context__, __Params__>, + {} + impl< + __Wildcard__, + T, + Provider, + > DelegateComponent< + PathCons< + Symbol<4, Chars<'t', Chars<'e', Chars<'s', Chars<'t', Nil>>>>>, + PathCons>, + >, + > for AppA + where + T: DefaultImpls1, + { + type Delegate = Provider; + } + impl< + __Wildcard__, + T, + Provider, + __Context__, + __Params__, + > IsProviderFor< + PathCons< + Symbol<4, Chars<'t', Chars<'e', Chars<'s', Chars<'t', Nil>>>>>, + PathCons>, + >, + __Context__, + __Params__, + > for AppA + where + T: DefaultImpls1, + Provider: IsProviderFor< + PathCons< + Symbol<4, Chars<'t', Chars<'e', Chars<'s', Chars<'t', Nil>>>>>, + PathCons>, + >, + __Context__, + __Params__, + >, + {} + impl< + __Wildcard__, + > DelegateComponent< + PathCons< + Symbol<4, Chars<'t', Chars<'e', Chars<'s', Chars<'t', Nil>>>>>, + PathCons>, + >, + > for AppA { + type Delegate = ShowWithDisplay; + } + impl< + __Wildcard__, + __Context__, + __Params__, + > IsProviderFor< + PathCons< + Symbol<4, Chars<'t', Chars<'e', Chars<'s', Chars<'t', Nil>>>>>, + PathCons>, + >, + __Context__, + __Params__, + > for AppA + where + ShowWithDisplay: IsProviderFor< + PathCons< + Symbol<4, Chars<'t', Chars<'e', Chars<'s', Chars<'t', Nil>>>>>, + PathCons>, + >, + __Context__, + __Params__, + >, + {} + ") } } @@ -30,14 +127,77 @@ check_components! { pub struct AppB; -delegate_components! { - AppB { - namespace DefaultNamespace; +snapshot_delegate_components! { + delegate_components! { + AppB { + namespace DefaultNamespace; - for in DefaultShowComponents { - @test.ShowImplComponent.T: Provider, + for in DefaultShowComponents { + @test.ShowImplComponent.T: Provider, + } } } + + expand_default_impls_app_b(output) { + assert_snapshot!(output, @" + impl<__Key__, __Value__> DelegateComponent<__Key__> for AppB + where + __Key__: DefaultNamespace, + { + type Delegate = __Value__; + } + impl< + __Key__, + __Value__, + __Context__, + __Params__, + > IsProviderFor<__Key__, __Context__, __Params__> for AppB + where + __Key__: DefaultNamespace, + __Value__: IsProviderFor<__Key__, __Context__, __Params__>, + {} + impl< + __Wildcard__, + T, + Provider, + > DelegateComponent< + PathCons< + Symbol<4, Chars<'t', Chars<'e', Chars<'s', Chars<'t', Nil>>>>>, + PathCons>, + >, + > for AppB + where + T: DefaultShowComponents, + { + type Delegate = Provider; + } + impl< + __Wildcard__, + T, + Provider, + __Context__, + __Params__, + > IsProviderFor< + PathCons< + Symbol<4, Chars<'t', Chars<'e', Chars<'s', Chars<'t', Nil>>>>>, + PathCons>, + >, + __Context__, + __Params__, + > for AppB + where + T: DefaultShowComponents, + Provider: IsProviderFor< + PathCons< + Symbol<4, Chars<'t', Chars<'e', Chars<'s', Chars<'t', Nil>>>>>, + PathCons>, + >, + __Context__, + __Params__, + >, + {} + ") + } } check_components! { @@ -51,16 +211,111 @@ check_components! { pub struct AppC; -delegate_components! { - AppC { - namespace ExtendedNamespace; +snapshot_delegate_components! { + delegate_components! { + AppC { + namespace ExtendedNamespace; + + for in DefaultImpls1 { + @test.ShowImplComponent.T: Provider, + } - for in DefaultImpls1 { - @test.ShowImplComponent.T: Provider, + @test.ShowImplComponent.u64: + ShowWithDisplay, } + } - @test.ShowImplComponent.u64: - ShowWithDisplay, + expand_default_impls_app_c(output) { + assert_snapshot!(output, @" + impl<__Key__, __Value__> DelegateComponent<__Key__> for AppC + where + __Key__: ExtendedNamespace, + { + type Delegate = __Value__; + } + impl< + __Key__, + __Value__, + __Context__, + __Params__, + > IsProviderFor<__Key__, __Context__, __Params__> for AppC + where + __Key__: ExtendedNamespace, + __Value__: IsProviderFor<__Key__, __Context__, __Params__>, + {} + impl< + __Wildcard__, + T, + Provider, + > DelegateComponent< + PathCons< + Symbol<4, Chars<'t', Chars<'e', Chars<'s', Chars<'t', Nil>>>>>, + PathCons>, + >, + > for AppC + where + T: DefaultImpls1, + { + type Delegate = Provider; + } + impl< + __Wildcard__, + T, + Provider, + __Context__, + __Params__, + > IsProviderFor< + PathCons< + Symbol<4, Chars<'t', Chars<'e', Chars<'s', Chars<'t', Nil>>>>>, + PathCons>, + >, + __Context__, + __Params__, + > for AppC + where + T: DefaultImpls1, + Provider: IsProviderFor< + PathCons< + Symbol<4, Chars<'t', Chars<'e', Chars<'s', Chars<'t', Nil>>>>>, + PathCons>, + >, + __Context__, + __Params__, + >, + {} + impl< + __Wildcard__, + > DelegateComponent< + PathCons< + Symbol<4, Chars<'t', Chars<'e', Chars<'s', Chars<'t', Nil>>>>>, + PathCons>, + >, + > for AppC { + type Delegate = ShowWithDisplay; + } + impl< + __Wildcard__, + __Context__, + __Params__, + > IsProviderFor< + PathCons< + Symbol<4, Chars<'t', Chars<'e', Chars<'s', Chars<'t', Nil>>>>>, + PathCons>, + >, + __Context__, + __Params__, + > for AppC + where + ShowWithDisplay: IsProviderFor< + PathCons< + Symbol<4, Chars<'t', Chars<'e', Chars<'s', Chars<'t', Nil>>>>>, + PathCons>, + >, + __Context__, + __Params__, + >, + {} + ") } } diff --git a/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/extended_namespace.rs b/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/extended_namespace.rs index 64d08afb..b3887d73 100644 --- a/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/extended_namespace.rs +++ b/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/extended_namespace.rs @@ -2,23 +2,188 @@ use cgp::core::error::{ErrorRaiserComponent, ErrorTypeProviderComponent, ErrorWr use cgp::extra::error::RaiseFrom; use cgp::extra::handler::CanTryCompute; use cgp::prelude::*; +use cgp_macro_test_util::snapshot_delegate_components; use cgp_tests::namespaces::extended::ExtendedNamespace; +use insta::assert_snapshot; pub struct App; -delegate_components! { - App { - namespace ExtendedNamespace; +snapshot_delegate_components! { + delegate_components! { + App { + namespace ExtendedNamespace; - @app.ErrorTypeProviderComponent: - UseType, - @app.{ - ErrorRaiserComponent.{&'static str, String}, - ErrorWrapperComponent, - }: - RaiseFrom, - TryComputerComponent: - Foo, + @app.ErrorTypeProviderComponent: + UseType, + @app.{ + ErrorRaiserComponent.{&'static str, String}, + ErrorWrapperComponent, + }: + RaiseFrom, + TryComputerComponent: + Foo, + } + } + + expand_extended_ns_app(output) { + assert_snapshot!(output, @" + impl<__Key__, __Value__> DelegateComponent<__Key__> for App + where + __Key__: ExtendedNamespace, + { + type Delegate = __Value__; + } + impl< + __Key__, + __Value__, + __Context__, + __Params__, + > IsProviderFor<__Key__, __Context__, __Params__> for App + where + __Key__: ExtendedNamespace, + __Value__: IsProviderFor<__Key__, __Context__, __Params__>, + {} + impl< + __Wildcard__, + > DelegateComponent< + PathCons< + Symbol<3, Chars<'a', Chars<'p', Chars<'p', Nil>>>>, + PathCons, + >, + > for App { + type Delegate = UseType; + } + impl< + __Wildcard__, + __Context__, + __Params__, + > IsProviderFor< + PathCons< + Symbol<3, Chars<'a', Chars<'p', Chars<'p', Nil>>>>, + PathCons, + >, + __Context__, + __Params__, + > for App + where + UseType< + String, + >: IsProviderFor< + PathCons< + Symbol<3, Chars<'a', Chars<'p', Chars<'p', Nil>>>>, + PathCons, + >, + __Context__, + __Params__, + >, + {} + impl< + __Wildcard__, + > DelegateComponent< + PathCons< + Symbol<3, Chars<'a', Chars<'p', Chars<'p', Nil>>>>, + PathCons>, + >, + > for App { + type Delegate = RaiseFrom; + } + impl< + __Wildcard__, + __Context__, + __Params__, + > IsProviderFor< + PathCons< + Symbol<3, Chars<'a', Chars<'p', Chars<'p', Nil>>>>, + PathCons>, + >, + __Context__, + __Params__, + > for App + where + RaiseFrom: IsProviderFor< + PathCons< + Symbol<3, Chars<'a', Chars<'p', Chars<'p', Nil>>>>, + PathCons>, + >, + __Context__, + __Params__, + >, + {} + impl< + __Wildcard__, + > DelegateComponent< + PathCons< + Symbol<3, Chars<'a', Chars<'p', Chars<'p', Nil>>>>, + PathCons>, + >, + > for App { + type Delegate = RaiseFrom; + } + impl< + __Wildcard__, + __Context__, + __Params__, + > IsProviderFor< + PathCons< + Symbol<3, Chars<'a', Chars<'p', Chars<'p', Nil>>>>, + PathCons>, + >, + __Context__, + __Params__, + > for App + where + RaiseFrom: IsProviderFor< + PathCons< + Symbol<3, Chars<'a', Chars<'p', Chars<'p', Nil>>>>, + PathCons>, + >, + __Context__, + __Params__, + >, + {} + impl< + __Wildcard__, + > DelegateComponent< + PathCons< + Symbol<3, Chars<'a', Chars<'p', Chars<'p', Nil>>>>, + PathCons, + >, + > for App { + type Delegate = RaiseFrom; + } + impl< + __Wildcard__, + __Context__, + __Params__, + > IsProviderFor< + PathCons< + Symbol<3, Chars<'a', Chars<'p', Chars<'p', Nil>>>>, + PathCons, + >, + __Context__, + __Params__, + > for App + where + RaiseFrom: IsProviderFor< + PathCons< + Symbol<3, Chars<'a', Chars<'p', Chars<'p', Nil>>>>, + PathCons, + >, + __Context__, + __Params__, + >, + {} + impl DelegateComponent for App { + type Delegate = Foo; + } + impl< + __Context__, + __Params__, + > IsProviderFor for App + where + Foo: IsProviderFor, + {} + ") } } diff --git a/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/multi_namespace.rs b/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/multi_namespace.rs index 4425feb0..4a6fd9b6 100644 --- a/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/multi_namespace.rs +++ b/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/multi_namespace.rs @@ -1,10 +1,87 @@ use cgp::prelude::*; +use cgp_macro_test_util::{ + snapshot_cgp_component, snapshot_cgp_impl, snapshot_delegate_components, +}; +use insta::assert_snapshot; pub struct MyApp; -#[cgp_component(FooProvider)] -pub trait Foo { - fn foo(&self); +snapshot_cgp_component! { + #[cgp_component(FooProvider)] + pub trait Foo { + fn foo(&self); + } + + expand_multi_ns_foo(output) { + assert_snapshot!(output, @" + pub trait Foo { + fn foo(&self); + } + impl<__Context__> Foo for __Context__ + where + __Context__: FooProvider<__Context__>, + { + fn foo(&self) { + __Context__::foo(self) + } + } + pub trait FooProvider< + __Context__, + >: IsProviderFor { + fn foo(__context__: &__Context__); + } + impl<__Provider__, __Context__> FooProvider<__Context__> for __Provider__ + where + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + FooProviderComponent, + >>::Delegate: FooProvider<__Context__>, + { + fn foo(__context__: &__Context__) { + <__Provider__ as DelegateComponent< + FooProviderComponent, + >>::Delegate::foo(__context__) + } + } + pub struct FooProviderComponent; + impl<__Context__> FooProvider<__Context__> for UseContext + where + __Context__: Foo, + { + fn foo(__context__: &__Context__) { + __Context__::foo(__context__) + } + } + impl<__Context__> IsProviderFor for UseContext + where + __Context__: Foo, + {} + impl<__Context__, __Components__, __Path__> FooProvider<__Context__> + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent<__Path__>>::Delegate: FooProvider<__Context__>, + { + fn foo(__context__: &__Context__) { + <__Components__ as DelegateComponent<__Path__>>::Delegate::foo(__context__) + } + } + impl< + __Context__, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: IsProviderFor + + FooProvider<__Context__>, + {} + ") + } } cgp_namespace! { @@ -21,37 +98,220 @@ cgp_namespace! { } } -#[cgp_component(BarProvider)] -#[prefix(@MyApp.MyBarComponent in MyNamespace)] -#[prefix(@my_app.MyBarComponent in OtherNamespace)] -pub trait Bar { - fn bar(&self); +snapshot_cgp_component! { + #[cgp_component(BarProvider)] + #[prefix(@MyApp.MyBarComponent in MyNamespace)] + #[prefix(@my_app.MyBarComponent in OtherNamespace)] + pub trait Bar { + fn bar(&self); + } + + expand_multi_ns_bar(output) { + assert_snapshot!(output, @" + pub trait Bar { + fn bar(&self); + } + impl<__Context__> Bar for __Context__ + where + __Context__: BarProvider<__Context__>, + { + fn bar(&self) { + __Context__::bar(self) + } + } + pub trait BarProvider< + __Context__, + >: IsProviderFor { + fn bar(__context__: &__Context__); + } + impl<__Provider__, __Context__> BarProvider<__Context__> for __Provider__ + where + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + BarProviderComponent, + >>::Delegate: BarProvider<__Context__>, + { + fn bar(__context__: &__Context__) { + <__Provider__ as DelegateComponent< + BarProviderComponent, + >>::Delegate::bar(__context__) + } + } + pub struct BarProviderComponent; + impl<__Context__> BarProvider<__Context__> for UseContext + where + __Context__: Bar, + { + fn bar(__context__: &__Context__) { + __Context__::bar(__context__) + } + } + impl<__Context__> IsProviderFor for UseContext + where + __Context__: Bar, + {} + impl<__Context__, __Components__, __Path__> BarProvider<__Context__> + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent<__Path__>>::Delegate: BarProvider<__Context__>, + { + fn bar(__context__: &__Context__) { + <__Components__ as DelegateComponent<__Path__>>::Delegate::bar(__context__) + } + } + impl< + __Context__, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: IsProviderFor + + BarProvider<__Context__>, + {} + impl<__Components__> MyNamespace<__Components__> for BarProviderComponent { + type Delegate = RedirectLookup< + __Components__, + PathCons>>, + >; + } + impl<__Components__> OtherNamespace<__Components__> for BarProviderComponent { + type Delegate = RedirectLookup< + __Components__, + PathCons< + Symbol< + 6, + Chars< + 'm', + Chars<'y', Chars<'_', Chars<'a', Chars<'p', Chars<'p', Nil>>>>>, + >, + >, + PathCons>, + >, + >; + } + ") + } } pub struct MyFooComponent; pub struct MyBarComponent; -#[cgp_impl(new DummyFoo)] -impl FooProvider { - fn foo(&self) {} +snapshot_cgp_impl! { + #[cgp_impl(new DummyFoo)] + impl FooProvider { + fn foo(&self) {} + } + + expand_multi_ns_dummy_foo(output) { + assert_snapshot!(output, @" + impl<__Context__> FooProvider<__Context__> for DummyFoo { + fn foo(__context__: &__Context__) {} + } + impl<__Context__> IsProviderFor for DummyFoo {} + pub struct DummyFoo; + ") + } } -#[cgp_impl(new DummyBar)] -impl BarProvider { - fn bar(&self) {} +snapshot_cgp_impl! { + #[cgp_impl(new DummyBar)] + impl BarProvider { + fn bar(&self) {} + } + + expand_multi_ns_dummy_bar(output) { + assert_snapshot!(output, @" + impl<__Context__> BarProvider<__Context__> for DummyBar { + fn bar(__context__: &__Context__) {} + } + impl<__Context__> IsProviderFor for DummyBar {} + pub struct DummyBar; + ") + } } pub struct App; -delegate_components! { - App { - namespace MyNamespace; +snapshot_delegate_components! { + delegate_components! { + App { + namespace MyNamespace; - @MyApp.MyFooComponent: - DummyFoo, - @MyApp.MyBarComponent: - DummyBar, + @MyApp.MyFooComponent: + DummyFoo, + @MyApp.MyBarComponent: + DummyBar, + } + } + + expand_multi_ns_app(output) { + assert_snapshot!(output, @" + impl<__Key__, __Value__> DelegateComponent<__Key__> for App + where + __Key__: MyNamespace, + { + type Delegate = __Value__; + } + impl< + __Key__, + __Value__, + __Context__, + __Params__, + > IsProviderFor<__Key__, __Context__, __Params__> for App + where + __Key__: MyNamespace, + __Value__: IsProviderFor<__Key__, __Context__, __Params__>, + {} + impl< + __Wildcard__, + > DelegateComponent>> for App { + type Delegate = DummyFoo; + } + impl< + __Wildcard__, + __Context__, + __Params__, + > IsProviderFor< + PathCons>, + __Context__, + __Params__, + > for App + where + DummyFoo: IsProviderFor< + PathCons>, + __Context__, + __Params__, + >, + {} + impl< + __Wildcard__, + > DelegateComponent>> for App { + type Delegate = DummyBar; + } + impl< + __Wildcard__, + __Context__, + __Params__, + > IsProviderFor< + PathCons>, + __Context__, + __Params__, + > for App + where + DummyBar: IsProviderFor< + PathCons>, + __Context__, + __Params__, + >, + {} + ") } } @@ -64,14 +324,125 @@ check_components! { pub struct OtherApp; -delegate_components! { - OtherApp { - namespace OtherNamespace; +snapshot_delegate_components! { + delegate_components! { + OtherApp { + namespace OtherNamespace; + + @my_app.MyFooComponent: + DummyFoo, + @my_app.MyBarComponent: + DummyBar, + } + } - @my_app.MyFooComponent: - DummyFoo, - @my_app.MyBarComponent: - DummyBar, + expand_multi_ns_other_app(output) { + assert_snapshot!(output, @" + impl<__Key__, __Value__> DelegateComponent<__Key__> for OtherApp + where + __Key__: OtherNamespace, + { + type Delegate = __Value__; + } + impl< + __Key__, + __Value__, + __Context__, + __Params__, + > IsProviderFor<__Key__, __Context__, __Params__> for OtherApp + where + __Key__: OtherNamespace, + __Value__: IsProviderFor<__Key__, __Context__, __Params__>, + {} + impl< + __Wildcard__, + > DelegateComponent< + PathCons< + Symbol< + 6, + Chars<'m', Chars<'y', Chars<'_', Chars<'a', Chars<'p', Chars<'p', Nil>>>>>>, + >, + PathCons, + >, + > for OtherApp { + type Delegate = DummyFoo; + } + impl< + __Wildcard__, + __Context__, + __Params__, + > IsProviderFor< + PathCons< + Symbol< + 6, + Chars<'m', Chars<'y', Chars<'_', Chars<'a', Chars<'p', Chars<'p', Nil>>>>>>, + >, + PathCons, + >, + __Context__, + __Params__, + > for OtherApp + where + DummyFoo: IsProviderFor< + PathCons< + Symbol< + 6, + Chars< + 'm', + Chars<'y', Chars<'_', Chars<'a', Chars<'p', Chars<'p', Nil>>>>>, + >, + >, + PathCons, + >, + __Context__, + __Params__, + >, + {} + impl< + __Wildcard__, + > DelegateComponent< + PathCons< + Symbol< + 6, + Chars<'m', Chars<'y', Chars<'_', Chars<'a', Chars<'p', Chars<'p', Nil>>>>>>, + >, + PathCons, + >, + > for OtherApp { + type Delegate = DummyBar; + } + impl< + __Wildcard__, + __Context__, + __Params__, + > IsProviderFor< + PathCons< + Symbol< + 6, + Chars<'m', Chars<'y', Chars<'_', Chars<'a', Chars<'p', Chars<'p', Nil>>>>>>, + >, + PathCons, + >, + __Context__, + __Params__, + > for OtherApp + where + DummyBar: IsProviderFor< + PathCons< + Symbol< + 6, + Chars< + 'm', + Chars<'y', Chars<'_', Chars<'a', Chars<'p', Chars<'p', Nil>>>>>, + >, + >, + PathCons, + >, + __Context__, + __Params__, + >, + {} + ") } } diff --git a/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/symbol_path.rs b/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/symbol_path.rs index e781932c..b2ad1972 100644 --- a/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/symbol_path.rs +++ b/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/symbol_path.rs @@ -1,8 +1,85 @@ use cgp::prelude::*; +use cgp_macro_test_util::{ + snapshot_cgp_component, snapshot_cgp_impl, snapshot_delegate_components, +}; +use insta::assert_snapshot; -#[cgp_component(FooProvider)] -pub trait Foo { - fn foo(&self); +snapshot_cgp_component! { + #[cgp_component(FooProvider)] + pub trait Foo { + fn foo(&self); + } + + expand_symbol_path_foo(output) { + assert_snapshot!(output, @" + pub trait Foo { + fn foo(&self); + } + impl<__Context__> Foo for __Context__ + where + __Context__: FooProvider<__Context__>, + { + fn foo(&self) { + __Context__::foo(self) + } + } + pub trait FooProvider< + __Context__, + >: IsProviderFor { + fn foo(__context__: &__Context__); + } + impl<__Provider__, __Context__> FooProvider<__Context__> for __Provider__ + where + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + FooProviderComponent, + >>::Delegate: FooProvider<__Context__>, + { + fn foo(__context__: &__Context__) { + <__Provider__ as DelegateComponent< + FooProviderComponent, + >>::Delegate::foo(__context__) + } + } + pub struct FooProviderComponent; + impl<__Context__> FooProvider<__Context__> for UseContext + where + __Context__: Foo, + { + fn foo(__context__: &__Context__) { + __Context__::foo(__context__) + } + } + impl<__Context__> IsProviderFor for UseContext + where + __Context__: Foo, + {} + impl<__Context__, __Components__, __Path__> FooProvider<__Context__> + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent<__Path__>>::Delegate: FooProvider<__Context__>, + { + fn foo(__context__: &__Context__) { + <__Components__ as DelegateComponent<__Path__>>::Delegate::foo(__context__) + } + } + impl< + __Context__, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: IsProviderFor + + FooProvider<__Context__>, + {} + ") + } } cgp_namespace! { @@ -12,36 +89,259 @@ cgp_namespace! { } } -#[cgp_component(BarProvider)] -#[prefix(@my_app.MyBarComponent in MyNamespace)] -pub trait Bar { - fn bar(&self); +snapshot_cgp_component! { + #[cgp_component(BarProvider)] + #[prefix(@my_app.MyBarComponent in MyNamespace)] + pub trait Bar { + fn bar(&self); + } + + expand_symbol_path_bar(output) { + assert_snapshot!(output, @" + pub trait Bar { + fn bar(&self); + } + impl<__Context__> Bar for __Context__ + where + __Context__: BarProvider<__Context__>, + { + fn bar(&self) { + __Context__::bar(self) + } + } + pub trait BarProvider< + __Context__, + >: IsProviderFor { + fn bar(__context__: &__Context__); + } + impl<__Provider__, __Context__> BarProvider<__Context__> for __Provider__ + where + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + BarProviderComponent, + >>::Delegate: BarProvider<__Context__>, + { + fn bar(__context__: &__Context__) { + <__Provider__ as DelegateComponent< + BarProviderComponent, + >>::Delegate::bar(__context__) + } + } + pub struct BarProviderComponent; + impl<__Context__> BarProvider<__Context__> for UseContext + where + __Context__: Bar, + { + fn bar(__context__: &__Context__) { + __Context__::bar(__context__) + } + } + impl<__Context__> IsProviderFor for UseContext + where + __Context__: Bar, + {} + impl<__Context__, __Components__, __Path__> BarProvider<__Context__> + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent<__Path__>>::Delegate: BarProvider<__Context__>, + { + fn bar(__context__: &__Context__) { + <__Components__ as DelegateComponent<__Path__>>::Delegate::bar(__context__) + } + } + impl< + __Context__, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: IsProviderFor + + BarProvider<__Context__>, + {} + impl<__Components__> MyNamespace<__Components__> for BarProviderComponent { + type Delegate = RedirectLookup< + __Components__, + PathCons< + Symbol< + 6, + Chars< + 'm', + Chars<'y', Chars<'_', Chars<'a', Chars<'p', Chars<'p', Nil>>>>>, + >, + >, + PathCons>, + >, + >; + } + ") + } } pub struct MyFooComponent; pub struct MyBarComponent; -#[cgp_impl(new DummyFoo)] -impl FooProvider { - fn foo(&self) {} +snapshot_cgp_impl! { + #[cgp_impl(new DummyFoo)] + impl FooProvider { + fn foo(&self) {} + } + + expand_symbol_path_dummy_foo(output) { + assert_snapshot!(output, @" + impl<__Context__> FooProvider<__Context__> for DummyFoo { + fn foo(__context__: &__Context__) {} + } + impl<__Context__> IsProviderFor for DummyFoo {} + pub struct DummyFoo; + ") + } } -#[cgp_impl(new DummyBar)] -impl BarProvider { - fn bar(&self) {} +snapshot_cgp_impl! { + #[cgp_impl(new DummyBar)] + impl BarProvider { + fn bar(&self) {} + } + + expand_symbol_path_dummy_bar(output) { + assert_snapshot!(output, @" + impl<__Context__> BarProvider<__Context__> for DummyBar { + fn bar(__context__: &__Context__) {} + } + impl<__Context__> IsProviderFor for DummyBar {} + pub struct DummyBar; + ") + } } pub struct App; -delegate_components! { - App { - namespace MyNamespace; +snapshot_delegate_components! { + delegate_components! { + App { + namespace MyNamespace; + + @my_app.MyFooComponent: + DummyFoo, + @my_app.MyBarComponent: + DummyBar, + } + } - @my_app.MyFooComponent: - DummyFoo, - @my_app.MyBarComponent: - DummyBar, + expand_symbol_path_app(output) { + assert_snapshot!(output, @" + impl<__Key__, __Value__> DelegateComponent<__Key__> for App + where + __Key__: MyNamespace, + { + type Delegate = __Value__; + } + impl< + __Key__, + __Value__, + __Context__, + __Params__, + > IsProviderFor<__Key__, __Context__, __Params__> for App + where + __Key__: MyNamespace, + __Value__: IsProviderFor<__Key__, __Context__, __Params__>, + {} + impl< + __Wildcard__, + > DelegateComponent< + PathCons< + Symbol< + 6, + Chars<'m', Chars<'y', Chars<'_', Chars<'a', Chars<'p', Chars<'p', Nil>>>>>>, + >, + PathCons, + >, + > for App { + type Delegate = DummyFoo; + } + impl< + __Wildcard__, + __Context__, + __Params__, + > IsProviderFor< + PathCons< + Symbol< + 6, + Chars<'m', Chars<'y', Chars<'_', Chars<'a', Chars<'p', Chars<'p', Nil>>>>>>, + >, + PathCons, + >, + __Context__, + __Params__, + > for App + where + DummyFoo: IsProviderFor< + PathCons< + Symbol< + 6, + Chars< + 'm', + Chars<'y', Chars<'_', Chars<'a', Chars<'p', Chars<'p', Nil>>>>>, + >, + >, + PathCons, + >, + __Context__, + __Params__, + >, + {} + impl< + __Wildcard__, + > DelegateComponent< + PathCons< + Symbol< + 6, + Chars<'m', Chars<'y', Chars<'_', Chars<'a', Chars<'p', Chars<'p', Nil>>>>>>, + >, + PathCons, + >, + > for App { + type Delegate = DummyBar; + } + impl< + __Wildcard__, + __Context__, + __Params__, + > IsProviderFor< + PathCons< + Symbol< + 6, + Chars<'m', Chars<'y', Chars<'_', Chars<'a', Chars<'p', Chars<'p', Nil>>>>>>, + >, + PathCons, + >, + __Context__, + __Params__, + > for App + where + DummyBar: IsProviderFor< + PathCons< + Symbol< + 6, + Chars< + 'm', + Chars<'y', Chars<'_', Chars<'a', Chars<'p', Chars<'p', Nil>>>>>, + >, + >, + PathCons, + >, + __Context__, + __Params__, + >, + {} + ") } } diff --git a/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/type_path.rs b/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/type_path.rs index 0881b5f1..75f60bd8 100644 --- a/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/type_path.rs +++ b/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/type_path.rs @@ -1,10 +1,87 @@ use cgp::prelude::*; +use cgp_macro_test_util::{ + snapshot_cgp_component, snapshot_cgp_impl, snapshot_delegate_components, +}; +use insta::assert_snapshot; pub struct MyApp; -#[cgp_component(FooProvider)] -pub trait Foo { - fn foo(&self); +snapshot_cgp_component! { + #[cgp_component(FooProvider)] + pub trait Foo { + fn foo(&self); + } + + expand_type_path_foo(output) { + assert_snapshot!(output, @" + pub trait Foo { + fn foo(&self); + } + impl<__Context__> Foo for __Context__ + where + __Context__: FooProvider<__Context__>, + { + fn foo(&self) { + __Context__::foo(self) + } + } + pub trait FooProvider< + __Context__, + >: IsProviderFor { + fn foo(__context__: &__Context__); + } + impl<__Provider__, __Context__> FooProvider<__Context__> for __Provider__ + where + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + FooProviderComponent, + >>::Delegate: FooProvider<__Context__>, + { + fn foo(__context__: &__Context__) { + <__Provider__ as DelegateComponent< + FooProviderComponent, + >>::Delegate::foo(__context__) + } + } + pub struct FooProviderComponent; + impl<__Context__> FooProvider<__Context__> for UseContext + where + __Context__: Foo, + { + fn foo(__context__: &__Context__) { + __Context__::foo(__context__) + } + } + impl<__Context__> IsProviderFor for UseContext + where + __Context__: Foo, + {} + impl<__Context__, __Components__, __Path__> FooProvider<__Context__> + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent<__Path__>>::Delegate: FooProvider<__Context__>, + { + fn foo(__context__: &__Context__) { + <__Components__ as DelegateComponent<__Path__>>::Delegate::foo(__context__) + } + } + impl< + __Context__, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: IsProviderFor + + FooProvider<__Context__>, + {} + ") + } } cgp_namespace! { @@ -14,36 +91,204 @@ cgp_namespace! { } } -#[cgp_component(BarProvider)] -#[prefix(@MyApp.MyBarComponent in MyNamespace)] -pub trait Bar { - fn bar(&self); +snapshot_cgp_component! { + #[cgp_component(BarProvider)] + #[prefix(@MyApp.MyBarComponent in MyNamespace)] + pub trait Bar { + fn bar(&self); + } + + expand_type_path_bar(output) { + assert_snapshot!(output, @" + pub trait Bar { + fn bar(&self); + } + impl<__Context__> Bar for __Context__ + where + __Context__: BarProvider<__Context__>, + { + fn bar(&self) { + __Context__::bar(self) + } + } + pub trait BarProvider< + __Context__, + >: IsProviderFor { + fn bar(__context__: &__Context__); + } + impl<__Provider__, __Context__> BarProvider<__Context__> for __Provider__ + where + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + BarProviderComponent, + >>::Delegate: BarProvider<__Context__>, + { + fn bar(__context__: &__Context__) { + <__Provider__ as DelegateComponent< + BarProviderComponent, + >>::Delegate::bar(__context__) + } + } + pub struct BarProviderComponent; + impl<__Context__> BarProvider<__Context__> for UseContext + where + __Context__: Bar, + { + fn bar(__context__: &__Context__) { + __Context__::bar(__context__) + } + } + impl<__Context__> IsProviderFor for UseContext + where + __Context__: Bar, + {} + impl<__Context__, __Components__, __Path__> BarProvider<__Context__> + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent<__Path__>>::Delegate: BarProvider<__Context__>, + { + fn bar(__context__: &__Context__) { + <__Components__ as DelegateComponent<__Path__>>::Delegate::bar(__context__) + } + } + impl< + __Context__, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: IsProviderFor + + BarProvider<__Context__>, + {} + impl<__Components__> MyNamespace<__Components__> for BarProviderComponent { + type Delegate = RedirectLookup< + __Components__, + PathCons>>, + >; + } + ") + } } pub struct MyFooComponent; pub struct MyBarComponent; -#[cgp_impl(new DummyFoo)] -impl FooProvider { - fn foo(&self) {} +snapshot_cgp_impl! { + #[cgp_impl(new DummyFoo)] + impl FooProvider { + fn foo(&self) {} + } + + expand_type_path_dummy_foo(output) { + assert_snapshot!(output, @" + impl<__Context__> FooProvider<__Context__> for DummyFoo { + fn foo(__context__: &__Context__) {} + } + impl<__Context__> IsProviderFor for DummyFoo {} + pub struct DummyFoo; + ") + } } -#[cgp_impl(new DummyBar)] -impl BarProvider { - fn bar(&self) {} +snapshot_cgp_impl! { + #[cgp_impl(new DummyBar)] + impl BarProvider { + fn bar(&self) {} + } + + expand_type_path_dummy_bar(output) { + assert_snapshot!(output, @" + impl<__Context__> BarProvider<__Context__> for DummyBar { + fn bar(__context__: &__Context__) {} + } + impl<__Context__> IsProviderFor for DummyBar {} + pub struct DummyBar; + ") + } } pub struct App; -delegate_components! { - App { - namespace MyNamespace; +snapshot_delegate_components! { + delegate_components! { + App { + namespace MyNamespace; + + @MyApp.MyFooComponent: + DummyFoo, + @MyApp.MyBarComponent: + DummyBar, + } + } - @MyApp.MyFooComponent: - DummyFoo, - @MyApp.MyBarComponent: - DummyBar, + expand_type_path_app(output) { + assert_snapshot!(output, @" + impl<__Key__, __Value__> DelegateComponent<__Key__> for App + where + __Key__: MyNamespace, + { + type Delegate = __Value__; + } + impl< + __Key__, + __Value__, + __Context__, + __Params__, + > IsProviderFor<__Key__, __Context__, __Params__> for App + where + __Key__: MyNamespace, + __Value__: IsProviderFor<__Key__, __Context__, __Params__>, + {} + impl< + __Wildcard__, + > DelegateComponent>> for App { + type Delegate = DummyFoo; + } + impl< + __Wildcard__, + __Context__, + __Params__, + > IsProviderFor< + PathCons>, + __Context__, + __Params__, + > for App + where + DummyFoo: IsProviderFor< + PathCons>, + __Context__, + __Params__, + >, + {} + impl< + __Wildcard__, + > DelegateComponent>> for App { + type Delegate = DummyBar; + } + impl< + __Wildcard__, + __Context__, + __Params__, + > IsProviderFor< + PathCons>, + __Context__, + __Params__, + > for App + where + DummyBar: IsProviderFor< + PathCons>, + __Context__, + __Params__, + >, + {} + ") } } diff --git a/crates/tests/cgp-tests/tests/namespace_tests/open.rs b/crates/tests/cgp-tests/tests/namespace_tests/open.rs index 21c7f9cd..fab5e598 100644 --- a/crates/tests/cgp-tests/tests/namespace_tests/open.rs +++ b/crates/tests/cgp-tests/tests/namespace_tests/open.rs @@ -1,40 +1,403 @@ use cgp::prelude::*; +use cgp_macro_test_util::{ + snapshot_cgp_component, snapshot_cgp_impl, snapshot_delegate_components, +}; +use insta::assert_snapshot; pub struct App; -#[cgp_component(FooProvider)] -pub trait Foo { - fn foo(&self, value: &T); +snapshot_cgp_component! { + #[cgp_component(FooProvider)] + pub trait Foo { + fn foo(&self, value: &T); + } + + expand_open_foo(output) { + assert_snapshot!(output, @" + pub trait Foo { + fn foo(&self, value: &T); + } + impl<__Context__, T> Foo for __Context__ + where + __Context__: FooProvider<__Context__, T>, + { + fn foo(&self, value: &T) { + __Context__::foo(self, value) + } + } + pub trait FooProvider< + __Context__, + T, + >: IsProviderFor { + fn foo(__context__: &__Context__, value: &T); + } + impl<__Provider__, __Context__, T> FooProvider<__Context__, T> for __Provider__ + where + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + FooProviderComponent, + >>::Delegate: FooProvider<__Context__, T>, + { + fn foo(__context__: &__Context__, value: &T) { + <__Provider__ as DelegateComponent< + FooProviderComponent, + >>::Delegate::foo(__context__, value) + } + } + pub struct FooProviderComponent; + impl<__Context__, T> FooProvider<__Context__, T> for UseContext + where + __Context__: Foo, + { + fn foo(__context__: &__Context__, value: &T) { + __Context__::foo(__context__, value) + } + } + impl<__Context__, T> IsProviderFor for UseContext + where + __Context__: Foo, + {} + impl<__Context__, T, __Components__, __Path__> FooProvider<__Context__, T> + for RedirectLookup<__Components__, __Path__> + where + __Path__: ConcatPath>, + __Components__: DelegateComponent< + <__Path__ as ConcatPath>>::Output, + >, + <__Components__ as DelegateComponent< + <__Path__ as ConcatPath>>::Output, + >>::Delegate: FooProvider<__Context__, T>, + { + fn foo(__context__: &__Context__, value: &T) { + <__Components__ as DelegateComponent< + <__Path__ as ConcatPath>>::Output, + >>::Delegate::foo(__context__, value) + } + } + impl< + __Context__, + T, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Path__: ConcatPath>, + __Components__: DelegateComponent< + <__Path__ as ConcatPath>>::Output, + >, + <__Components__ as DelegateComponent< + <__Path__ as ConcatPath>>::Output, + >>::Delegate: IsProviderFor + + FooProvider<__Context__, T>, + {} + ") + } } -#[cgp_component(BarProvider)] -pub trait Bar { - fn bar(&self, value: &T); +snapshot_cgp_component! { + #[cgp_component(BarProvider)] + pub trait Bar { + fn bar(&self, value: &T); + } + + expand_open_bar(output) { + assert_snapshot!(output, @" + pub trait Bar { + fn bar(&self, value: &T); + } + impl<__Context__, T> Bar for __Context__ + where + __Context__: BarProvider<__Context__, T>, + { + fn bar(&self, value: &T) { + __Context__::bar(self, value) + } + } + pub trait BarProvider< + __Context__, + T, + >: IsProviderFor { + fn bar(__context__: &__Context__, value: &T); + } + impl<__Provider__, __Context__, T> BarProvider<__Context__, T> for __Provider__ + where + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + BarProviderComponent, + >>::Delegate: BarProvider<__Context__, T>, + { + fn bar(__context__: &__Context__, value: &T) { + <__Provider__ as DelegateComponent< + BarProviderComponent, + >>::Delegate::bar(__context__, value) + } + } + pub struct BarProviderComponent; + impl<__Context__, T> BarProvider<__Context__, T> for UseContext + where + __Context__: Bar, + { + fn bar(__context__: &__Context__, value: &T) { + __Context__::bar(__context__, value) + } + } + impl<__Context__, T> IsProviderFor for UseContext + where + __Context__: Bar, + {} + impl<__Context__, T, __Components__, __Path__> BarProvider<__Context__, T> + for RedirectLookup<__Components__, __Path__> + where + __Path__: ConcatPath>, + __Components__: DelegateComponent< + <__Path__ as ConcatPath>>::Output, + >, + <__Components__ as DelegateComponent< + <__Path__ as ConcatPath>>::Output, + >>::Delegate: BarProvider<__Context__, T>, + { + fn bar(__context__: &__Context__, value: &T) { + <__Components__ as DelegateComponent< + <__Path__ as ConcatPath>>::Output, + >>::Delegate::bar(__context__, value) + } + } + impl< + __Context__, + T, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Path__: ConcatPath>, + __Components__: DelegateComponent< + <__Path__ as ConcatPath>>::Output, + >, + <__Components__ as DelegateComponent< + <__Path__ as ConcatPath>>::Output, + >>::Delegate: IsProviderFor + + BarProvider<__Context__, T>, + {} + ") + } } -#[cgp_impl(new DummyFoo)] -impl FooProvider { - fn foo(&self, _value: &T) {} +snapshot_cgp_impl! { + #[cgp_impl(new DummyFoo)] + impl FooProvider { + fn foo(&self, _value: &T) {} + } + + expand_open_dummy_foo(output) { + assert_snapshot!(output, @" + impl<__Context__, T> FooProvider<__Context__, T> for DummyFoo { + fn foo(__context__: &__Context__, _value: &T) {} + } + impl<__Context__, T> IsProviderFor for DummyFoo {} + pub struct DummyFoo; + ") + } } -#[cgp_impl(new DummyBar)] -impl BarProvider { - fn bar(&self, _value: &T) {} +snapshot_cgp_impl! { + #[cgp_impl(new DummyBar)] + impl BarProvider { + fn bar(&self, _value: &T) {} + } + + expand_open_dummy_bar(output) { + assert_snapshot!(output, @" + impl<__Context__, T> BarProvider<__Context__, T> for DummyBar { + fn bar(__context__: &__Context__, _value: &T) {} + } + impl<__Context__, T> IsProviderFor for DummyBar {} + pub struct DummyBar; + ") + } } -delegate_components! { - App { - open {FooProviderComponent, BarProviderComponent}; +snapshot_delegate_components! { + delegate_components! { + App { + open {FooProviderComponent, BarProviderComponent}; + + // FooProviderComponent => + // @FooProviderComponent, + // BarProviderComponent => + // @BarProviderComponent, - // FooProviderComponent => - // @FooProviderComponent, - // BarProviderComponent => - // @BarProviderComponent, + @FooProviderComponent.String: + DummyFoo, + @BarProviderComponent.{u32, u64, bool, usize, isize}: + DummyBar, + } + } - @FooProviderComponent.String: - DummyFoo, - @BarProviderComponent.{u32, u64, bool, usize, isize}: - DummyBar, + expand_open_app(output) { + assert_snapshot!(output, @" + impl DelegateComponent for App { + type Delegate = RedirectLookup>; + } + impl< + __Context__, + __Params__, + > IsProviderFor for App + where + RedirectLookup< + App, + PathCons, + >: IsProviderFor, + {} + impl DelegateComponent for App { + type Delegate = RedirectLookup>; + } + impl< + __Context__, + __Params__, + > IsProviderFor for App + where + RedirectLookup< + App, + PathCons, + >: IsProviderFor, + {} + impl< + __Wildcard__, + > DelegateComponent>> + for App { + type Delegate = DummyFoo; + } + impl< + __Wildcard__, + __Context__, + __Params__, + > IsProviderFor< + PathCons>, + __Context__, + __Params__, + > for App + where + DummyFoo: IsProviderFor< + PathCons>, + __Context__, + __Params__, + >, + {} + impl< + __Wildcard__, + > DelegateComponent>> + for App { + type Delegate = DummyBar; + } + impl< + __Wildcard__, + __Context__, + __Params__, + > IsProviderFor< + PathCons>, + __Context__, + __Params__, + > for App + where + DummyBar: IsProviderFor< + PathCons>, + __Context__, + __Params__, + >, + {} + impl< + __Wildcard__, + > DelegateComponent>> + for App { + type Delegate = DummyBar; + } + impl< + __Wildcard__, + __Context__, + __Params__, + > IsProviderFor< + PathCons>, + __Context__, + __Params__, + > for App + where + DummyBar: IsProviderFor< + PathCons>, + __Context__, + __Params__, + >, + {} + impl< + __Wildcard__, + > DelegateComponent>> + for App { + type Delegate = DummyBar; + } + impl< + __Wildcard__, + __Context__, + __Params__, + > IsProviderFor< + PathCons>, + __Context__, + __Params__, + > for App + where + DummyBar: IsProviderFor< + PathCons>, + __Context__, + __Params__, + >, + {} + impl< + __Wildcard__, + > DelegateComponent>> + for App { + type Delegate = DummyBar; + } + impl< + __Wildcard__, + __Context__, + __Params__, + > IsProviderFor< + PathCons>, + __Context__, + __Params__, + > for App + where + DummyBar: IsProviderFor< + PathCons>, + __Context__, + __Params__, + >, + {} + impl< + __Wildcard__, + > DelegateComponent>> + for App { + type Delegate = DummyBar; + } + impl< + __Wildcard__, + __Context__, + __Params__, + > IsProviderFor< + PathCons>, + __Context__, + __Params__, + > for App + where + DummyBar: IsProviderFor< + PathCons>, + __Context__, + __Params__, + >, + {} + ") } } diff --git a/crates/tests/cgp-tests/tests/namespace_tests/redirect.rs b/crates/tests/cgp-tests/tests/namespace_tests/redirect.rs index 4db7ee43..5b3023c1 100644 --- a/crates/tests/cgp-tests/tests/namespace_tests/redirect.rs +++ b/crates/tests/cgp-tests/tests/namespace_tests/redirect.rs @@ -1,31 +1,185 @@ use cgp::prelude::*; +use cgp_macro_test_util::{ + snapshot_cgp_component, snapshot_cgp_impl, snapshot_delegate_components, +}; +use insta::assert_snapshot; -#[cgp_component(FooProvider)] -#[prefix(@bar.baz in DefaultNamespace)] -pub trait CanDoFoo { - fn foo(); +snapshot_cgp_component! { + #[cgp_component(FooProvider)] + #[prefix(@bar.baz in DefaultNamespace)] + pub trait CanDoFoo { + fn foo(); + } + + expand_redirect_foo(output) { + assert_snapshot!(output, @" + pub trait CanDoFoo { + fn foo(); + } + impl<__Context__> CanDoFoo for __Context__ + where + __Context__: FooProvider<__Context__>, + { + fn foo() { + __Context__::foo() + } + } + pub trait FooProvider< + __Context__, + >: IsProviderFor { + fn foo(); + } + impl<__Provider__, __Context__> FooProvider<__Context__> for __Provider__ + where + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + FooProviderComponent, + >>::Delegate: FooProvider<__Context__>, + { + fn foo() { + <__Provider__ as DelegateComponent>::Delegate::foo() + } + } + pub struct FooProviderComponent; + impl<__Context__> FooProvider<__Context__> for UseContext + where + __Context__: CanDoFoo, + { + fn foo() { + __Context__::foo() + } + } + impl<__Context__> IsProviderFor for UseContext + where + __Context__: CanDoFoo, + {} + impl<__Context__, __Components__, __Path__> FooProvider<__Context__> + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent<__Path__>>::Delegate: FooProvider<__Context__>, + { + fn foo() { + <__Components__ as DelegateComponent<__Path__>>::Delegate::foo() + } + } + impl< + __Context__, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: IsProviderFor + + FooProvider<__Context__>, + {} + impl<__Components__> DefaultNamespace<__Components__> for FooProviderComponent { + type Delegate = RedirectLookup< + __Components__, + PathCons< + Symbol<3, Chars<'b', Chars<'a', Chars<'r', Nil>>>>, + PathCons< + Symbol<3, Chars<'b', Chars<'a', Chars<'z', Nil>>>>, + PathCons, + >, + >, + >; + } + ") + } } pub struct BarComponent; pub struct BazComponent; -#[cgp_impl(new TestProvider)] -impl FooProvider { - fn foo() {} +snapshot_cgp_impl! { + #[cgp_impl(new TestProvider)] + impl FooProvider { + fn foo() {} + } + + expand_redirect_test_provider(output) { + assert_snapshot!(output, @" + impl<__Context__> FooProvider<__Context__> for TestProvider { + fn foo() {} + } + impl<__Context__> IsProviderFor for TestProvider {} + pub struct TestProvider; + ") + } } pub struct App; -delegate_components! { - App { - namespace DefaultNamespace; +snapshot_delegate_components! { + delegate_components! { + App { + namespace DefaultNamespace; - // @bar: TestProvider, + // @bar: TestProvider, - @bar.baz: TestProvider, + @bar.baz: TestProvider, + + // @bar.baz.FooProviderComponent: TestProvider, + } + } - // @bar.baz.FooProviderComponent: TestProvider, + expand_redirect_app(output) { + assert_snapshot!(output, @" + impl<__Key__, __Value__> DelegateComponent<__Key__> for App + where + __Key__: DefaultNamespace, + { + type Delegate = __Value__; + } + impl< + __Key__, + __Value__, + __Context__, + __Params__, + > IsProviderFor<__Key__, __Context__, __Params__> for App + where + __Key__: DefaultNamespace, + __Value__: IsProviderFor<__Key__, __Context__, __Params__>, + {} + impl< + __Wildcard__, + > DelegateComponent< + PathCons< + Symbol<3, Chars<'b', Chars<'a', Chars<'r', Nil>>>>, + PathCons>>>, __Wildcard__>, + >, + > for App { + type Delegate = TestProvider; + } + impl< + __Wildcard__, + __Context__, + __Params__, + > IsProviderFor< + PathCons< + Symbol<3, Chars<'b', Chars<'a', Chars<'r', Nil>>>>, + PathCons>>>, __Wildcard__>, + >, + __Context__, + __Params__, + > for App + where + TestProvider: IsProviderFor< + PathCons< + Symbol<3, Chars<'b', Chars<'a', Chars<'r', Nil>>>>, + PathCons>>>, __Wildcard__>, + >, + __Context__, + __Params__, + >, + {} + ") } } diff --git a/crates/tests/cgp-tests/tests/preset_tests/basic/components.rs b/crates/tests/cgp-tests/tests/preset_tests/basic/components.rs index 5514ee49..920aaeeb 100644 --- a/crates/tests/cgp-tests/tests/preset_tests/basic/components.rs +++ b/crates/tests/cgp-tests/tests/preset_tests/basic/components.rs @@ -1,4 +1,6 @@ use cgp::prelude::*; +use cgp_macro_test_util::snapshot_cgp_getter; +use insta::assert_snapshot; #[cgp_type] pub trait HasFooType { @@ -10,12 +12,288 @@ pub trait HasBarType { type Bar; } -#[cgp_getter] -pub trait HasFoo: HasFooType { - fn foo(&self) -> &Self::Foo; +snapshot_cgp_getter! { + #[cgp_getter] + pub trait HasFoo: HasFooType { + fn foo(&self) -> &Self::Foo; + } + + expand_has_foo(output) { + assert_snapshot!(output, @" + pub trait HasFoo: HasFooType { + fn foo(&self) -> &Self::Foo; + } + impl<__Context__> HasFoo for __Context__ + where + __Context__: HasFooType, + __Context__: FooGetter<__Context__>, + { + fn foo(&self) -> &Self::Foo { + __Context__::foo(self) + } + } + pub trait FooGetter<__Context__>: IsProviderFor + where + __Context__: HasFooType, + { + fn foo(__context__: &__Context__) -> &__Context__::Foo; + } + impl<__Provider__, __Context__> FooGetter<__Context__> for __Provider__ + where + __Context__: HasFooType, + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + FooGetterComponent, + >>::Delegate: FooGetter<__Context__>, + { + fn foo(__context__: &__Context__) -> &__Context__::Foo { + <__Provider__ as DelegateComponent< + FooGetterComponent, + >>::Delegate::foo(__context__) + } + } + pub struct FooGetterComponent; + impl<__Context__> FooGetter<__Context__> for UseContext + where + __Context__: HasFooType, + __Context__: HasFoo, + { + fn foo(__context__: &__Context__) -> &__Context__::Foo { + __Context__::foo(__context__) + } + } + impl<__Context__> IsProviderFor for UseContext + where + __Context__: HasFooType, + __Context__: HasFoo, + {} + impl<__Context__, __Components__, __Path__> FooGetter<__Context__> + for RedirectLookup<__Components__, __Path__> + where + __Context__: HasFooType, + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent<__Path__>>::Delegate: FooGetter<__Context__>, + { + fn foo(__context__: &__Context__) -> &__Context__::Foo { + <__Components__ as DelegateComponent<__Path__>>::Delegate::foo(__context__) + } + } + impl< + __Context__, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Context__: HasFooType, + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: IsProviderFor + + FooGetter<__Context__>, + {} + impl<__Context__> FooGetter<__Context__> for UseFields + where + __Context__: HasFooType, + __Context__: HasField< + Symbol<3, Chars<'f', Chars<'o', Chars<'o', Nil>>>>, + Value = __Context__::Foo, + >, + { + fn foo(__context__: &__Context__) -> &__Context__::Foo { + __context__ + .get_field( + ::core::marker::PhantomData::< + Symbol<3, Chars<'f', Chars<'o', Chars<'o', Nil>>>>, + >, + ) + } + } + impl<__Context__> IsProviderFor for UseFields + where + __Context__: HasFooType, + __Context__: HasField< + Symbol<3, Chars<'f', Chars<'o', Chars<'o', Nil>>>>, + Value = __Context__::Foo, + >, + {} + impl<__Context__, __Tag__> FooGetter<__Context__> for UseField<__Tag__> + where + __Context__: HasFooType, + __Context__: HasField<__Tag__, Value = __Context__::Foo>, + { + fn foo(__context__: &__Context__) -> &__Context__::Foo { + __context__.get_field(::core::marker::PhantomData::<__Tag__>) + } + } + impl<__Context__, __Tag__> IsProviderFor + for UseField<__Tag__> + where + __Context__: HasFooType, + __Context__: HasField<__Tag__, Value = __Context__::Foo>, + {} + impl<__Context__, __Provider__> FooGetter<__Context__> for WithProvider<__Provider__> + where + __Context__: HasFooType, + __Provider__: FieldGetter<__Context__, FooGetterComponent, Value = __Context__::Foo>, + { + fn foo(__context__: &__Context__) -> &__Context__::Foo { + __Provider__::get_field( + __context__, + ::core::marker::PhantomData::, + ) + } + } + impl<__Context__, __Provider__> IsProviderFor + for WithProvider<__Provider__> + where + __Context__: HasFooType, + __Provider__: FieldGetter<__Context__, FooGetterComponent, Value = __Context__::Foo>, + {} + ") + } } -#[cgp_getter] -pub trait HasBar: HasBarType { - fn bar(&self) -> &Self::Bar; +snapshot_cgp_getter! { + #[cgp_getter] + pub trait HasBar: HasBarType { + fn bar(&self) -> &Self::Bar; + } + + expand_has_bar(output) { + assert_snapshot!(output, @" + pub trait HasBar: HasBarType { + fn bar(&self) -> &Self::Bar; + } + impl<__Context__> HasBar for __Context__ + where + __Context__: HasBarType, + __Context__: BarGetter<__Context__>, + { + fn bar(&self) -> &Self::Bar { + __Context__::bar(self) + } + } + pub trait BarGetter<__Context__>: IsProviderFor + where + __Context__: HasBarType, + { + fn bar(__context__: &__Context__) -> &__Context__::Bar; + } + impl<__Provider__, __Context__> BarGetter<__Context__> for __Provider__ + where + __Context__: HasBarType, + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + BarGetterComponent, + >>::Delegate: BarGetter<__Context__>, + { + fn bar(__context__: &__Context__) -> &__Context__::Bar { + <__Provider__ as DelegateComponent< + BarGetterComponent, + >>::Delegate::bar(__context__) + } + } + pub struct BarGetterComponent; + impl<__Context__> BarGetter<__Context__> for UseContext + where + __Context__: HasBarType, + __Context__: HasBar, + { + fn bar(__context__: &__Context__) -> &__Context__::Bar { + __Context__::bar(__context__) + } + } + impl<__Context__> IsProviderFor for UseContext + where + __Context__: HasBarType, + __Context__: HasBar, + {} + impl<__Context__, __Components__, __Path__> BarGetter<__Context__> + for RedirectLookup<__Components__, __Path__> + where + __Context__: HasBarType, + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent<__Path__>>::Delegate: BarGetter<__Context__>, + { + fn bar(__context__: &__Context__) -> &__Context__::Bar { + <__Components__ as DelegateComponent<__Path__>>::Delegate::bar(__context__) + } + } + impl< + __Context__, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Context__: HasBarType, + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: IsProviderFor + + BarGetter<__Context__>, + {} + impl<__Context__> BarGetter<__Context__> for UseFields + where + __Context__: HasBarType, + __Context__: HasField< + Symbol<3, Chars<'b', Chars<'a', Chars<'r', Nil>>>>, + Value = __Context__::Bar, + >, + { + fn bar(__context__: &__Context__) -> &__Context__::Bar { + __context__ + .get_field( + ::core::marker::PhantomData::< + Symbol<3, Chars<'b', Chars<'a', Chars<'r', Nil>>>>, + >, + ) + } + } + impl<__Context__> IsProviderFor for UseFields + where + __Context__: HasBarType, + __Context__: HasField< + Symbol<3, Chars<'b', Chars<'a', Chars<'r', Nil>>>>, + Value = __Context__::Bar, + >, + {} + impl<__Context__, __Tag__> BarGetter<__Context__> for UseField<__Tag__> + where + __Context__: HasBarType, + __Context__: HasField<__Tag__, Value = __Context__::Bar>, + { + fn bar(__context__: &__Context__) -> &__Context__::Bar { + __context__.get_field(::core::marker::PhantomData::<__Tag__>) + } + } + impl<__Context__, __Tag__> IsProviderFor + for UseField<__Tag__> + where + __Context__: HasBarType, + __Context__: HasField<__Tag__, Value = __Context__::Bar>, + {} + impl<__Context__, __Provider__> BarGetter<__Context__> for WithProvider<__Provider__> + where + __Context__: HasBarType, + __Provider__: FieldGetter<__Context__, BarGetterComponent, Value = __Context__::Bar>, + { + fn bar(__context__: &__Context__) -> &__Context__::Bar { + __Provider__::get_field( + __context__, + ::core::marker::PhantomData::, + ) + } + } + impl<__Context__, __Provider__> IsProviderFor + for WithProvider<__Provider__> + where + __Context__: HasBarType, + __Provider__: FieldGetter<__Context__, BarGetterComponent, Value = __Context__::Bar>, + {} + ") + } } diff --git a/crates/tests/cgp-tests/tests/preset_tests/basic/contexts.rs b/crates/tests/cgp-tests/tests/preset_tests/basic/contexts.rs index e9a03f01..5e0c785c 100644 --- a/crates/tests/cgp-tests/tests/preset_tests/basic/contexts.rs +++ b/crates/tests/cgp-tests/tests/preset_tests/basic/contexts.rs @@ -1,4 +1,6 @@ use cgp::prelude::*; +use cgp_macro_test_util::snapshot_delegate_components; +use insta::assert_snapshot; use crate::preset_tests::basic::components::{ BarGetterComponent, BarTypeProviderComponent, FooGetterComponent, FooTypeProviderComponent, @@ -12,9 +14,24 @@ pub struct MyContext { pub bar: (), } -delegate_components! { - MyContext { - BarGetterComponent: UseField, +snapshot_delegate_components! { + delegate_components! { + MyContext { + BarGetterComponent: UseField, + } + } + + expand_my_context(output) { + assert_snapshot!(output, @r#" + impl DelegateComponent for MyContext { + type Delegate = UseField; + } + impl<__Context__, __Params__> IsProviderFor + for MyContext + where + UseField: IsProviderFor, + {} + "#) } } diff --git a/crates/tests/cgp-tests/tests/preset_tests/generics/components.rs b/crates/tests/cgp-tests/tests/preset_tests/generics/components.rs index 3c314ad5..765273e7 100644 --- a/crates/tests/cgp-tests/tests/preset_tests/generics/components.rs +++ b/crates/tests/cgp-tests/tests/preset_tests/generics/components.rs @@ -1,6 +1,8 @@ use core::marker::PhantomData; use cgp::prelude::*; +use cgp_macro_test_util::snapshot_cgp_getter; +use insta::assert_snapshot; #[cgp_type] pub trait HasFooType { @@ -12,17 +14,317 @@ pub trait HasBarType { type Bar; } -#[cgp_getter { - name: FooGetterComponent, - provider: FooGetter, -}] -pub trait HasFooAt: HasFooType { - fn foo(&self, _tag: PhantomData) -> &Self::Foo; +snapshot_cgp_getter! { + #[cgp_getter { + name: FooGetterComponent, + provider: FooGetter, + }] + pub trait HasFooAt: HasFooType { + fn foo(&self, _tag: PhantomData) -> &Self::Foo; + } + + expand_has_foo_at(output) { + assert_snapshot!(output, @" + pub trait HasFooAt: HasFooType { + fn foo(&self, _tag: PhantomData) -> &Self::Foo; + } + impl<__Context__, I> HasFooAt for __Context__ + where + __Context__: HasFooType, + __Context__: FooGetter<__Context__, I>, + { + fn foo(&self, _tag: PhantomData) -> &Self::Foo { + __Context__::foo(self, _tag) + } + } + pub trait FooGetter< + __Context__, + I, + >: IsProviderFor, __Context__, (I)> + where + __Context__: HasFooType, + { + fn foo(__context__: &__Context__, _tag: PhantomData) -> &__Context__::Foo; + } + impl<__Provider__, __Context__, I> FooGetter<__Context__, I> for __Provider__ + where + __Context__: HasFooType, + __Provider__: DelegateComponent> + + IsProviderFor, __Context__, (I)>, + <__Provider__ as DelegateComponent< + FooGetterComponent, + >>::Delegate: FooGetter<__Context__, I>, + { + fn foo(__context__: &__Context__, _tag: PhantomData) -> &__Context__::Foo { + <__Provider__ as DelegateComponent< + FooGetterComponent, + >>::Delegate::foo(__context__, _tag) + } + } + pub struct FooGetterComponent(pub ::core::marker::PhantomData<(I)>); + impl<__Context__, I> FooGetter<__Context__, I> for UseContext + where + __Context__: HasFooType, + __Context__: HasFooAt, + { + fn foo(__context__: &__Context__, _tag: PhantomData) -> &__Context__::Foo { + __Context__::foo(__context__, _tag) + } + } + impl<__Context__, I> IsProviderFor, __Context__, (I)> + for UseContext + where + __Context__: HasFooType, + __Context__: HasFooAt, + {} + impl<__Context__, I, __Components__, __Path__> FooGetter<__Context__, I> + for RedirectLookup<__Components__, __Path__> + where + __Context__: HasFooType, + __Path__: ConcatPath>, + __Components__: DelegateComponent< + <__Path__ as ConcatPath>>::Output, + >, + <__Components__ as DelegateComponent< + <__Path__ as ConcatPath>>::Output, + >>::Delegate: FooGetter<__Context__, I>, + { + fn foo(__context__: &__Context__, _tag: PhantomData) -> &__Context__::Foo { + <__Components__ as DelegateComponent< + <__Path__ as ConcatPath>>::Output, + >>::Delegate::foo(__context__, _tag) + } + } + impl< + __Context__, + I, + __Components__, + __Path__, + > IsProviderFor, __Context__, (I)> + for RedirectLookup<__Components__, __Path__> + where + __Context__: HasFooType, + __Path__: ConcatPath>, + __Components__: DelegateComponent< + <__Path__ as ConcatPath>>::Output, + >, + <__Components__ as DelegateComponent< + <__Path__ as ConcatPath>>::Output, + >>::Delegate: IsProviderFor, __Context__, (I)> + + FooGetter<__Context__, I>, + {} + impl<__Context__, I> FooGetter<__Context__, I> for UseFields + where + __Context__: HasFooType, + __Context__: HasField< + Symbol<3, Chars<'f', Chars<'o', Chars<'o', Nil>>>>, + Value = __Context__::Foo, + >, + { + fn foo(__context__: &__Context__, _phantom: PhantomData) -> &__Context__::Foo { + __context__ + .get_field( + ::core::marker::PhantomData::< + Symbol<3, Chars<'f', Chars<'o', Chars<'o', Nil>>>>, + >, + ) + } + } + impl<__Context__, I> IsProviderFor, __Context__, (I)> for UseFields + where + __Context__: HasFooType, + __Context__: HasField< + Symbol<3, Chars<'f', Chars<'o', Chars<'o', Nil>>>>, + Value = __Context__::Foo, + >, + {} + impl<__Context__, I, __Tag__> FooGetter<__Context__, I> for UseField<__Tag__> + where + __Context__: HasFooType, + __Context__: HasField<__Tag__, Value = __Context__::Foo>, + { + fn foo(__context__: &__Context__, _phantom: PhantomData) -> &__Context__::Foo { + __context__.get_field(::core::marker::PhantomData::<__Tag__>) + } + } + impl<__Context__, I, __Tag__> IsProviderFor, __Context__, (I)> + for UseField<__Tag__> + where + __Context__: HasFooType, + __Context__: HasField<__Tag__, Value = __Context__::Foo>, + {} + impl<__Context__, I, __Provider__> FooGetter<__Context__, I> + for WithProvider<__Provider__> + where + __Context__: HasFooType, + __Provider__: FieldGetter< + __Context__, + FooGetterComponent, + Value = __Context__::Foo, + >, + { + fn foo(__context__: &__Context__, _phantom: PhantomData) -> &__Context__::Foo { + __Provider__::get_field( + __context__, + ::core::marker::PhantomData::>, + ) + } + } + impl<__Context__, I, __Provider__> IsProviderFor, __Context__, (I)> + for WithProvider<__Provider__> + where + __Context__: HasFooType, + __Provider__: FieldGetter< + __Context__, + FooGetterComponent, + Value = __Context__::Foo, + >, + {} + ") + } } -#[cgp_getter { - provider: BarGetter, -}] -pub trait HasBar: HasBarType { - fn bar(&self) -> &Self::Bar; +snapshot_cgp_getter! { + #[cgp_getter { + provider: BarGetter, + }] + pub trait HasBar: HasBarType { + fn bar(&self) -> &Self::Bar; + } + + expand_has_bar(output) { + assert_snapshot!(output, @" + pub trait HasBar: HasBarType { + fn bar(&self) -> &Self::Bar; + } + impl<__Context__> HasBar for __Context__ + where + __Context__: HasBarType, + __Context__: BarGetter<__Context__>, + { + fn bar(&self) -> &Self::Bar { + __Context__::bar(self) + } + } + pub trait BarGetter<__Context__>: IsProviderFor + where + __Context__: HasBarType, + { + fn bar(__context__: &__Context__) -> &__Context__::Bar; + } + impl<__Provider__, __Context__> BarGetter<__Context__> for __Provider__ + where + __Context__: HasBarType, + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + BarGetterComponent, + >>::Delegate: BarGetter<__Context__>, + { + fn bar(__context__: &__Context__) -> &__Context__::Bar { + <__Provider__ as DelegateComponent< + BarGetterComponent, + >>::Delegate::bar(__context__) + } + } + pub struct BarGetterComponent; + impl<__Context__> BarGetter<__Context__> for UseContext + where + __Context__: HasBarType, + __Context__: HasBar, + { + fn bar(__context__: &__Context__) -> &__Context__::Bar { + __Context__::bar(__context__) + } + } + impl<__Context__> IsProviderFor for UseContext + where + __Context__: HasBarType, + __Context__: HasBar, + {} + impl<__Context__, __Components__, __Path__> BarGetter<__Context__> + for RedirectLookup<__Components__, __Path__> + where + __Context__: HasBarType, + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent<__Path__>>::Delegate: BarGetter<__Context__>, + { + fn bar(__context__: &__Context__) -> &__Context__::Bar { + <__Components__ as DelegateComponent<__Path__>>::Delegate::bar(__context__) + } + } + impl< + __Context__, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Context__: HasBarType, + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: IsProviderFor + + BarGetter<__Context__>, + {} + impl<__Context__> BarGetter<__Context__> for UseFields + where + __Context__: HasBarType, + __Context__: HasField< + Symbol<3, Chars<'b', Chars<'a', Chars<'r', Nil>>>>, + Value = __Context__::Bar, + >, + { + fn bar(__context__: &__Context__) -> &__Context__::Bar { + __context__ + .get_field( + ::core::marker::PhantomData::< + Symbol<3, Chars<'b', Chars<'a', Chars<'r', Nil>>>>, + >, + ) + } + } + impl<__Context__> IsProviderFor for UseFields + where + __Context__: HasBarType, + __Context__: HasField< + Symbol<3, Chars<'b', Chars<'a', Chars<'r', Nil>>>>, + Value = __Context__::Bar, + >, + {} + impl<__Context__, __Tag__> BarGetter<__Context__> for UseField<__Tag__> + where + __Context__: HasBarType, + __Context__: HasField<__Tag__, Value = __Context__::Bar>, + { + fn bar(__context__: &__Context__) -> &__Context__::Bar { + __context__.get_field(::core::marker::PhantomData::<__Tag__>) + } + } + impl<__Context__, __Tag__> IsProviderFor + for UseField<__Tag__> + where + __Context__: HasBarType, + __Context__: HasField<__Tag__, Value = __Context__::Bar>, + {} + impl<__Context__, __Provider__> BarGetter<__Context__> for WithProvider<__Provider__> + where + __Context__: HasBarType, + __Provider__: FieldGetter<__Context__, BarGetterComponent, Value = __Context__::Bar>, + { + fn bar(__context__: &__Context__) -> &__Context__::Bar { + __Provider__::get_field( + __context__, + ::core::marker::PhantomData::, + ) + } + } + impl<__Context__, __Provider__> IsProviderFor + for WithProvider<__Provider__> + where + __Context__: HasBarType, + __Provider__: FieldGetter<__Context__, BarGetterComponent, Value = __Context__::Bar>, + {} + ") + } } diff --git a/crates/tests/cgp-tests/tests/preset_tests/generics_inheritance/components.rs b/crates/tests/cgp-tests/tests/preset_tests/generics_inheritance/components.rs index 7cd32187..677ca44f 100644 --- a/crates/tests/cgp-tests/tests/preset_tests/generics_inheritance/components.rs +++ b/crates/tests/cgp-tests/tests/preset_tests/generics_inheritance/components.rs @@ -1,6 +1,8 @@ use core::marker::PhantomData; use cgp::prelude::*; +use cgp_macro_test_util::snapshot_cgp_getter; +use insta::assert_snapshot; #[cgp_type] pub trait HasFooType { @@ -12,18 +14,342 @@ pub trait HasBarType { type Bar; } -#[cgp_getter { - name: FooGetterComponent, - provider: FooGetter, -}] -pub trait HasFooAt: HasFooType { - fn foo(&self, _tag: PhantomData) -> &Self::Foo; +snapshot_cgp_getter! { + #[cgp_getter { + name: FooGetterComponent, + provider: FooGetter, + }] + pub trait HasFooAt: HasFooType { + fn foo(&self, _tag: PhantomData) -> &Self::Foo; + } + + expand_has_foo_at(output) { + assert_snapshot!(output, @" + pub trait HasFooAt: HasFooType { + fn foo(&self, _tag: PhantomData) -> &Self::Foo; + } + impl<__Context__, I> HasFooAt for __Context__ + where + __Context__: HasFooType, + __Context__: FooGetter<__Context__, I>, + { + fn foo(&self, _tag: PhantomData) -> &Self::Foo { + __Context__::foo(self, _tag) + } + } + pub trait FooGetter< + __Context__, + I, + >: IsProviderFor, __Context__, (I)> + where + __Context__: HasFooType, + { + fn foo(__context__: &__Context__, _tag: PhantomData) -> &__Context__::Foo; + } + impl<__Provider__, __Context__, I> FooGetter<__Context__, I> for __Provider__ + where + __Context__: HasFooType, + __Provider__: DelegateComponent> + + IsProviderFor, __Context__, (I)>, + <__Provider__ as DelegateComponent< + FooGetterComponent, + >>::Delegate: FooGetter<__Context__, I>, + { + fn foo(__context__: &__Context__, _tag: PhantomData) -> &__Context__::Foo { + <__Provider__ as DelegateComponent< + FooGetterComponent, + >>::Delegate::foo(__context__, _tag) + } + } + pub struct FooGetterComponent(pub ::core::marker::PhantomData<(I)>); + impl<__Context__, I> FooGetter<__Context__, I> for UseContext + where + __Context__: HasFooType, + __Context__: HasFooAt, + { + fn foo(__context__: &__Context__, _tag: PhantomData) -> &__Context__::Foo { + __Context__::foo(__context__, _tag) + } + } + impl<__Context__, I> IsProviderFor, __Context__, (I)> + for UseContext + where + __Context__: HasFooType, + __Context__: HasFooAt, + {} + impl<__Context__, I, __Components__, __Path__> FooGetter<__Context__, I> + for RedirectLookup<__Components__, __Path__> + where + __Context__: HasFooType, + __Path__: ConcatPath>, + __Components__: DelegateComponent< + <__Path__ as ConcatPath>>::Output, + >, + <__Components__ as DelegateComponent< + <__Path__ as ConcatPath>>::Output, + >>::Delegate: FooGetter<__Context__, I>, + { + fn foo(__context__: &__Context__, _tag: PhantomData) -> &__Context__::Foo { + <__Components__ as DelegateComponent< + <__Path__ as ConcatPath>>::Output, + >>::Delegate::foo(__context__, _tag) + } + } + impl< + __Context__, + I, + __Components__, + __Path__, + > IsProviderFor, __Context__, (I)> + for RedirectLookup<__Components__, __Path__> + where + __Context__: HasFooType, + __Path__: ConcatPath>, + __Components__: DelegateComponent< + <__Path__ as ConcatPath>>::Output, + >, + <__Components__ as DelegateComponent< + <__Path__ as ConcatPath>>::Output, + >>::Delegate: IsProviderFor, __Context__, (I)> + + FooGetter<__Context__, I>, + {} + impl<__Context__, I> FooGetter<__Context__, I> for UseFields + where + __Context__: HasFooType, + __Context__: HasField< + Symbol<3, Chars<'f', Chars<'o', Chars<'o', Nil>>>>, + Value = __Context__::Foo, + >, + { + fn foo(__context__: &__Context__, _phantom: PhantomData) -> &__Context__::Foo { + __context__ + .get_field( + ::core::marker::PhantomData::< + Symbol<3, Chars<'f', Chars<'o', Chars<'o', Nil>>>>, + >, + ) + } + } + impl<__Context__, I> IsProviderFor, __Context__, (I)> for UseFields + where + __Context__: HasFooType, + __Context__: HasField< + Symbol<3, Chars<'f', Chars<'o', Chars<'o', Nil>>>>, + Value = __Context__::Foo, + >, + {} + impl<__Context__, I, __Tag__> FooGetter<__Context__, I> for UseField<__Tag__> + where + __Context__: HasFooType, + __Context__: HasField<__Tag__, Value = __Context__::Foo>, + { + fn foo(__context__: &__Context__, _phantom: PhantomData) -> &__Context__::Foo { + __context__.get_field(::core::marker::PhantomData::<__Tag__>) + } + } + impl<__Context__, I, __Tag__> IsProviderFor, __Context__, (I)> + for UseField<__Tag__> + where + __Context__: HasFooType, + __Context__: HasField<__Tag__, Value = __Context__::Foo>, + {} + impl<__Context__, I, __Provider__> FooGetter<__Context__, I> + for WithProvider<__Provider__> + where + __Context__: HasFooType, + __Provider__: FieldGetter< + __Context__, + FooGetterComponent, + Value = __Context__::Foo, + >, + { + fn foo(__context__: &__Context__, _phantom: PhantomData) -> &__Context__::Foo { + __Provider__::get_field( + __context__, + ::core::marker::PhantomData::>, + ) + } + } + impl<__Context__, I, __Provider__> IsProviderFor, __Context__, (I)> + for WithProvider<__Provider__> + where + __Context__: HasFooType, + __Provider__: FieldGetter< + __Context__, + FooGetterComponent, + Value = __Context__::Foo, + >, + {} + ") + } } -#[cgp_getter { - name: BarGetterComponent, - provider: BarGetter, -}] -pub trait HasBarAt: HasBarType { - fn bar(&self) -> &Self::Bar; +snapshot_cgp_getter! { + #[cgp_getter { + name: BarGetterComponent, + provider: BarGetter, + }] + pub trait HasBarAt: HasBarType { + fn bar(&self) -> &Self::Bar; + } + + expand_has_bar_at(output) { + assert_snapshot!(output, @" + pub trait HasBarAt: HasBarType { + fn bar(&self) -> &Self::Bar; + } + impl<__Context__, I> HasBarAt for __Context__ + where + __Context__: HasBarType, + __Context__: BarGetter<__Context__, I>, + { + fn bar(&self) -> &Self::Bar { + __Context__::bar(self) + } + } + pub trait BarGetter< + __Context__, + I, + >: IsProviderFor, __Context__, (I)> + where + __Context__: HasBarType, + { + fn bar(__context__: &__Context__) -> &__Context__::Bar; + } + impl<__Provider__, __Context__, I> BarGetter<__Context__, I> for __Provider__ + where + __Context__: HasBarType, + __Provider__: DelegateComponent> + + IsProviderFor, __Context__, (I)>, + <__Provider__ as DelegateComponent< + BarGetterComponent, + >>::Delegate: BarGetter<__Context__, I>, + { + fn bar(__context__: &__Context__) -> &__Context__::Bar { + <__Provider__ as DelegateComponent< + BarGetterComponent, + >>::Delegate::bar(__context__) + } + } + pub struct BarGetterComponent(pub ::core::marker::PhantomData<(I)>); + impl<__Context__, I> BarGetter<__Context__, I> for UseContext + where + __Context__: HasBarType, + __Context__: HasBarAt, + { + fn bar(__context__: &__Context__) -> &__Context__::Bar { + __Context__::bar(__context__) + } + } + impl<__Context__, I> IsProviderFor, __Context__, (I)> + for UseContext + where + __Context__: HasBarType, + __Context__: HasBarAt, + {} + impl<__Context__, I, __Components__, __Path__> BarGetter<__Context__, I> + for RedirectLookup<__Components__, __Path__> + where + __Context__: HasBarType, + __Path__: ConcatPath>, + __Components__: DelegateComponent< + <__Path__ as ConcatPath>>::Output, + >, + <__Components__ as DelegateComponent< + <__Path__ as ConcatPath>>::Output, + >>::Delegate: BarGetter<__Context__, I>, + { + fn bar(__context__: &__Context__) -> &__Context__::Bar { + <__Components__ as DelegateComponent< + <__Path__ as ConcatPath>>::Output, + >>::Delegate::bar(__context__) + } + } + impl< + __Context__, + I, + __Components__, + __Path__, + > IsProviderFor, __Context__, (I)> + for RedirectLookup<__Components__, __Path__> + where + __Context__: HasBarType, + __Path__: ConcatPath>, + __Components__: DelegateComponent< + <__Path__ as ConcatPath>>::Output, + >, + <__Components__ as DelegateComponent< + <__Path__ as ConcatPath>>::Output, + >>::Delegate: IsProviderFor, __Context__, (I)> + + BarGetter<__Context__, I>, + {} + impl<__Context__, I> BarGetter<__Context__, I> for UseFields + where + __Context__: HasBarType, + __Context__: HasField< + Symbol<3, Chars<'b', Chars<'a', Chars<'r', Nil>>>>, + Value = __Context__::Bar, + >, + { + fn bar(__context__: &__Context__) -> &__Context__::Bar { + __context__ + .get_field( + ::core::marker::PhantomData::< + Symbol<3, Chars<'b', Chars<'a', Chars<'r', Nil>>>>, + >, + ) + } + } + impl<__Context__, I> IsProviderFor, __Context__, (I)> for UseFields + where + __Context__: HasBarType, + __Context__: HasField< + Symbol<3, Chars<'b', Chars<'a', Chars<'r', Nil>>>>, + Value = __Context__::Bar, + >, + {} + impl<__Context__, I, __Tag__> BarGetter<__Context__, I> for UseField<__Tag__> + where + __Context__: HasBarType, + __Context__: HasField<__Tag__, Value = __Context__::Bar>, + { + fn bar(__context__: &__Context__) -> &__Context__::Bar { + __context__.get_field(::core::marker::PhantomData::<__Tag__>) + } + } + impl<__Context__, I, __Tag__> IsProviderFor, __Context__, (I)> + for UseField<__Tag__> + where + __Context__: HasBarType, + __Context__: HasField<__Tag__, Value = __Context__::Bar>, + {} + impl<__Context__, I, __Provider__> BarGetter<__Context__, I> + for WithProvider<__Provider__> + where + __Context__: HasBarType, + __Provider__: FieldGetter< + __Context__, + BarGetterComponent, + Value = __Context__::Bar, + >, + { + fn bar(__context__: &__Context__) -> &__Context__::Bar { + __Provider__::get_field( + __context__, + ::core::marker::PhantomData::>, + ) + } + } + impl<__Context__, I, __Provider__> IsProviderFor, __Context__, (I)> + for WithProvider<__Provider__> + where + __Context__: HasBarType, + __Provider__: FieldGetter< + __Context__, + BarGetterComponent, + Value = __Context__::Bar, + >, + {} + ") + } } diff --git a/crates/tests/cgp-tests/tests/preset_tests/wrapped/context.rs b/crates/tests/cgp-tests/tests/preset_tests/wrapped/context.rs index c6ea5526..04d695c8 100644 --- a/crates/tests/cgp-tests/tests/preset_tests/wrapped/context.rs +++ b/crates/tests/cgp-tests/tests/preset_tests/wrapped/context.rs @@ -2,17 +2,52 @@ use core::convert::Infallible; use cgp::core::error::{ErrorRaiserComponent, ErrorTypeProviderComponent}; use cgp::prelude::*; +use cgp_macro_test_util::snapshot_delegate_components; +use insta::assert_snapshot; use crate::preset_tests::wrapped::preset::{BoxError, ErrorHandlerPreset}; pub struct MyContext; -delegate_components! { - MyContext { - ErrorTypeProviderComponent: - UseType, - ErrorRaiserComponent: - ErrorHandlerPreset::Provider, +snapshot_delegate_components! { + delegate_components! { + MyContext { + ErrorTypeProviderComponent: + UseType, + ErrorRaiserComponent: + ErrorHandlerPreset::Provider, + } + } + + expand_my_context(output) { + assert_snapshot!(output, @" + impl DelegateComponent for MyContext { + type Delegate = UseType; + } + impl< + __Context__, + __Params__, + > IsProviderFor for MyContext + where + UseType< + BoxError, + >: IsProviderFor, + {} + impl DelegateComponent for MyContext { + type Delegate = ErrorHandlerPreset::Provider; + } + impl< + __Context__, + __Params__, + > IsProviderFor for MyContext + where + ErrorHandlerPreset::Provider: IsProviderFor< + ErrorRaiserComponent, + __Context__, + __Params__, + >, + {} + ") } } From 517fc1c699e4d3970dd4fd0d8728869d741f0cc1 Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Fri, 19 Jun 2026 21:51:42 +0200 Subject: [PATCH 21/31] Implement `snapshot_cgp_fn!` --- .../src/entrypoints/mod.rs | 2 + .../src/entrypoints/snapshot_cgp_fn.rs | 13 ++ .../src/functions/mod.rs | 2 +- .../src/types/cgp_fn.rs | 31 +++ .../cgp-macro-test-util-lib/src/types/mod.rs | 2 + crates/macros/cgp-macro-test-util/README.md | 30 ++- crates/macros/cgp-macro-test-util/src/lib.rs | 7 + .../cgp-tests/tests/cgp_fn_tests/async.rs | 40 +++- .../cgp-tests/tests/cgp_fn_tests/basic.rs | 99 +++++++- .../cgp-tests/tests/cgp_fn_tests/call.rs | 160 ++++++++++++- .../cgp-tests/tests/cgp_fn_tests/extend.rs | 83 ++++++- .../tests/cgp_fn_tests/foreign_type.rs | 87 ++++++- .../cgp_fn_tests/foreign_type_equality.rs | 214 +++++++++++++++--- .../cgp-tests/tests/cgp_fn_tests/generics.rs | 80 ++++++- .../tests/cgp_fn_tests/impl_generics.rs | 70 +++++- .../cgp-tests/tests/cgp_fn_tests/multi.rs | 95 ++++++-- .../cgp-tests/tests/cgp_fn_tests/mutable.rs | 49 +++- .../tests/cgp_fn_tests/nested_foreign_type.rs | 87 ++++++- .../tests/cgp_fn_tests/type_equality.rs | 189 ++++++++++++++-- .../tests/cgp_fn_tests/use_provider.rs | 28 ++- .../cgp-tests/tests/cgp_fn_tests/use_type.rs | 76 ++++++- .../tests/cgp_fn_tests/use_type_alias.rs | 79 ++++++- .../cgp-tests/tests/cgp_fn_tests/uses.rs | 156 ++++++++++++- .../cgp_impl/implicit_args/import.rs | 65 +++++- .../tests/component_tests/cgp_impl/shape.rs | 111 ++++++++- 25 files changed, 1661 insertions(+), 194 deletions(-) create mode 100644 crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_fn.rs create mode 100644 crates/macros/cgp-macro-test-util-lib/src/types/cgp_fn.rs diff --git a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/mod.rs b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/mod.rs index 8041c71d..a8ae753b 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/mod.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/mod.rs @@ -1,11 +1,13 @@ mod snapshot_cgp_auto_getter; mod snapshot_cgp_component; +mod snapshot_cgp_fn; mod snapshot_cgp_getter; mod snapshot_cgp_impl; mod snapshot_delegate_components; pub use snapshot_cgp_auto_getter::*; pub use snapshot_cgp_component::*; +pub use snapshot_cgp_fn::*; pub use snapshot_cgp_getter::*; pub use snapshot_cgp_impl::*; pub use snapshot_delegate_components::*; diff --git a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_fn.rs b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_fn.rs new file mode 100644 index 00000000..9b96b777 --- /dev/null +++ b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_fn.rs @@ -0,0 +1,13 @@ +use proc_macro2::TokenStream; +use quote::ToTokens; +use syn::parse2; + +use crate::types::SnapshotCgpFn; + +pub fn snapshot_cgp_fn(body: TokenStream) -> syn::Result { + let item: SnapshotCgpFn = parse2(body)?; + + let output = cgp_macro_lib::cgp_fn(item.attr, item.body.to_token_stream())?; + + item.snapshot.wrap_output(output) +} diff --git a/crates/macros/cgp-macro-test-util-lib/src/functions/mod.rs b/crates/macros/cgp-macro-test-util-lib/src/functions/mod.rs index 3721114c..586dbf2a 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/functions/mod.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/functions/mod.rs @@ -1,5 +1,5 @@ mod parse_attribute; mod pretty_format; -pub use pretty_format::*; pub use parse_attribute::*; +pub use pretty_format::*; diff --git a/crates/macros/cgp-macro-test-util-lib/src/types/cgp_fn.rs b/crates/macros/cgp-macro-test-util-lib/src/types/cgp_fn.rs new file mode 100644 index 00000000..d742b492 --- /dev/null +++ b/crates/macros/cgp-macro-test-util-lib/src/types/cgp_fn.rs @@ -0,0 +1,31 @@ +use proc_macro2::TokenStream; +use syn::ItemFn; +use syn::parse::{Parse, ParseStream}; +use syn::token::Pound; + +use crate::functions::parse_attribute; +use crate::types::MacroSnapshot; + +pub struct SnapshotCgpFn { + pub attr: TokenStream, + pub body: ItemFn, + pub snapshot: MacroSnapshot, +} + +impl Parse for SnapshotCgpFn { + fn parse(input: ParseStream) -> syn::Result { + let _: Pound = input.parse()?; + + let attr = parse_attribute("cgp_fn", input)?; + + let body = input.parse()?; + + let snapshot = input.parse()?; + + Ok(Self { + attr, + body, + snapshot, + }) + } +} diff --git a/crates/macros/cgp-macro-test-util-lib/src/types/mod.rs b/crates/macros/cgp-macro-test-util-lib/src/types/mod.rs index fec4fc9f..7277f380 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/types/mod.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/types/mod.rs @@ -1,5 +1,6 @@ mod cgp_auto_getter; mod cgp_component; +mod cgp_fn; mod cgp_getter; mod cgp_impl; mod delegate_components; @@ -7,6 +8,7 @@ mod snapshot; pub use cgp_auto_getter::*; pub use cgp_component::*; +pub use cgp_fn::*; pub use cgp_getter::*; pub use cgp_impl::*; pub use delegate_components::*; diff --git a/crates/macros/cgp-macro-test-util/README.md b/crates/macros/cgp-macro-test-util/README.md index ff2858e6..8d2fdf02 100644 --- a/crates/macros/cgp-macro-test-util/README.md +++ b/crates/macros/cgp-macro-test-util/README.md @@ -5,7 +5,7 @@ Snapshot-testing macros for the CGP procedural macros. This crate exposes a family of `snapshot_*!` procedural macros that make it easy to write **golden / snapshot tests** for the code generated by the core CGP macros such as `#[cgp_component]`, `#[cgp_impl]`, `#[cgp_auto_getter]`, -`#[cgp_getter]`, and `delegate_components!`. +`#[cgp_getter]`, `#[cgp_fn]`, and `delegate_components!`. The snapshots are asserted using the [`insta`](https://insta.rs) crate. @@ -61,6 +61,7 @@ snapshot output is guaranteed to match what the production macros generate. | `snapshot_cgp_impl!` | `#[cgp_impl]` | | `snapshot_cgp_auto_getter!` | `#[cgp_auto_getter]` | | `snapshot_cgp_getter!` | `#[cgp_getter]` | +| `snapshot_cgp_fn!` | `#[cgp_fn]` | | `snapshot_delegate_components!` | `delegate_components!` | ## Anatomy of a snapshot invocation @@ -177,6 +178,29 @@ snapshot_cgp_auto_getter! { provider name forms `#[cgp_getter(NameGetter)]` and `#[cgp_getter { provider: ..., name: ... }]`. +### `snapshot_cgp_fn!` + +The item under test is the full `#[cgp_fn]` function, written exactly as you +would normally write it — including any extra attributes such as `#[uses(...)]`, +`#[extend(...)]`, `#[extend_where(...)]`, `#[use_type(...)]`, `#[impl_generics(...)]`, +or `#[async_trait]`, all kept above the `fn` with `#[cgp_fn]` first: + +```rust +snapshot_cgp_fn! { + #[cgp_fn] + pub fn rectangle_area(&self, #[implicit] width: f64, #[implicit] height: f64) -> f64 { + width * height + } + + expand_rectangle_area(output) { + assert_snapshot!(output, @"...") + } +} +``` + +Both the default form `#[cgp_fn]` and the custom trait name form +`#[cgp_fn(CanCalculateRectangleArea)]` are accepted, mirroring the real macro. + ### `snapshot_delegate_components!` Here the *whole* `delegate_components! { ... }` invocation is written verbatim, @@ -248,8 +272,8 @@ When migrating an existing macro test, two situations come up: ## Notes / limitations -- Snapshot macros exist only for the five macros listed above. Other CGP macros - (`#[cgp_type]`, `#[cgp_provider]`, `#[cgp_fn]`, `#[cgp_preset]`, +- Snapshot macros exist only for the six macros listed above. Other CGP macros + (`#[cgp_type]`, `#[cgp_provider]`, `#[cgp_preset]`, `check_components!`, `delegate_and_check_components!`, …) are not (yet) snapshot-wrapped and are left as-is. - The pretty-printing is done with diff --git a/crates/macros/cgp-macro-test-util/src/lib.rs b/crates/macros/cgp-macro-test-util/src/lib.rs index 9808f8db..3e90a20a 100644 --- a/crates/macros/cgp-macro-test-util/src/lib.rs +++ b/crates/macros/cgp-macro-test-util/src/lib.rs @@ -22,6 +22,13 @@ pub fn snapshot_cgp_impl(body: TokenStream) -> TokenStream { .into() } +#[proc_macro] +pub fn snapshot_cgp_fn(body: TokenStream) -> TokenStream { + entrypoints::snapshot_cgp_fn(body.into()) + .unwrap_or_else(syn::Error::into_compile_error) + .into() +} + #[proc_macro] pub fn snapshot_cgp_auto_getter(body: TokenStream) -> TokenStream { entrypoints::snapshot_cgp_auto_getter(body.into()) diff --git a/crates/tests/cgp-tests/tests/cgp_fn_tests/async.rs b/crates/tests/cgp-tests/tests/cgp_fn_tests/async.rs index a4110246..f04ba8cb 100644 --- a/crates/tests/cgp-tests/tests/cgp_fn_tests/async.rs +++ b/crates/tests/cgp-tests/tests/cgp_fn_tests/async.rs @@ -1,7 +1,39 @@ use cgp::prelude::*; +use cgp_macro_test_util::snapshot_cgp_fn; +use insta::assert_snapshot; -#[cgp_fn] -#[async_trait] -pub async fn greet(&self, #[implicit] name: &str) -> String { - format!("Hello, {}!", name) +snapshot_cgp_fn! { + #[cgp_fn] + #[async_trait] + pub async fn greet(&self, #[implicit] name: &str) -> String { + format!("Hello, {}!", name) + } + + expand_greet(output) { + assert_snapshot!(output, @r#" + #[async_trait] + pub trait Greet { + async fn greet(&self) -> String; + } + #[async_trait] + impl<__Context__> Greet for __Context__ + where + Self: HasField< + Symbol<4, Chars<'n', Chars<'a', Chars<'m', Chars<'e', Nil>>>>>, + Value = String, + >, + { + async fn greet(&self) -> String { + let name: &str = self + .get_field( + ::core::marker::PhantomData::< + Symbol<4, Chars<'n', Chars<'a', Chars<'m', Chars<'e', Nil>>>>>, + >, + ) + .as_str(); + format!("Hello, {}!", name) + } + } + "#) + } } diff --git a/crates/tests/cgp-tests/tests/cgp_fn_tests/basic.rs b/crates/tests/cgp-tests/tests/cgp_fn_tests/basic.rs index 2274c229..a735e495 100644 --- a/crates/tests/cgp-tests/tests/cgp_fn_tests/basic.rs +++ b/crates/tests/cgp-tests/tests/cgp_fn_tests/basic.rs @@ -1,8 +1,38 @@ use cgp::prelude::*; +use cgp_macro_test_util::snapshot_cgp_fn; +use insta::assert_snapshot; -#[cgp_fn] -pub fn greet(&self, #[implicit] name: &str) { - println!("Hello, {}!", name); +snapshot_cgp_fn! { + #[cgp_fn] + pub fn greet(&self, #[implicit] name: &str) { + println!("Hello, {}!", name); + } + + expand_greet(output) { + assert_snapshot!(output, @r#" + pub trait Greet { + fn greet(&self); + } + impl<__Context__> Greet for __Context__ + where + Self: HasField< + Symbol<4, Chars<'n', Chars<'a', Chars<'m', Chars<'e', Nil>>>>>, + Value = String, + >, + { + fn greet(&self) { + let name: &str = self + .get_field( + ::core::marker::PhantomData::< + Symbol<4, Chars<'n', Chars<'a', Chars<'m', Chars<'e', Nil>>>>>, + >, + ) + .as_str(); + println!("Hello, {}!", name); + } + } + "#) + } } #[derive(HasField)] @@ -13,9 +43,66 @@ pub struct Person { pub trait CheckPerson: Greet {} impl CheckPerson for Person {} -#[cgp_fn(CanCalculateRectangleArea)] -pub fn rectangle_area(&self, #[implicit] width: f64, #[implicit] height: f64) -> f64 { - width * height +snapshot_cgp_fn! { + #[cgp_fn(CanCalculateRectangleArea)] + pub fn rectangle_area(&self, #[implicit] width: f64, #[implicit] height: f64) -> f64 { + width * height + } + + expand_rectangle_area(output) { + assert_snapshot!(output, @" + pub trait CanCalculateRectangleArea { + fn rectangle_area(&self) -> f64; + } + impl<__Context__> CanCalculateRectangleArea for __Context__ + where + Self: HasField< + Symbol<5, Chars<'w', Chars<'i', Chars<'d', Chars<'t', Chars<'h', Nil>>>>>>, + Value = f64, + > + + HasField< + Symbol< + 6, + Chars< + 'h', + Chars<'e', Chars<'i', Chars<'g', Chars<'h', Chars<'t', Nil>>>>>, + >, + >, + Value = f64, + >, + { + fn rectangle_area(&self) -> f64 { + let width: f64 = self + .get_field( + ::core::marker::PhantomData::< + Symbol< + 5, + Chars<'w', Chars<'i', Chars<'d', Chars<'t', Chars<'h', Nil>>>>>, + >, + >, + ) + .clone(); + let height: f64 = self + .get_field( + ::core::marker::PhantomData::< + Symbol< + 6, + Chars< + 'h', + Chars< + 'e', + Chars<'i', Chars<'g', Chars<'h', Chars<'t', Nil>>>>, + >, + >, + >, + >, + ) + .clone(); + width * height + } + } + ") + } } #[derive(HasField)] diff --git a/crates/tests/cgp-tests/tests/cgp_fn_tests/call.rs b/crates/tests/cgp-tests/tests/cgp_fn_tests/call.rs index c792c749..acde29f6 100644 --- a/crates/tests/cgp-tests/tests/cgp_fn_tests/call.rs +++ b/crates/tests/cgp-tests/tests/cgp_fn_tests/call.rs @@ -1,16 +1,158 @@ use cgp::prelude::*; +use cgp_macro_test_util::snapshot_cgp_fn; +use insta::assert_snapshot; -#[cgp_fn] -pub fn rectangle_area(&self, #[implicit] width: f64, #[implicit] height: f64) -> f64 { - width * height +snapshot_cgp_fn! { + #[cgp_fn] + pub fn rectangle_area(&self, #[implicit] width: f64, #[implicit] height: f64) -> f64 { + width * height + } + + expand_rectangle_area(output) { + assert_snapshot!(output, @" + pub trait RectangleArea { + fn rectangle_area(&self) -> f64; + } + impl<__Context__> RectangleArea for __Context__ + where + Self: HasField< + Symbol<5, Chars<'w', Chars<'i', Chars<'d', Chars<'t', Chars<'h', Nil>>>>>>, + Value = f64, + > + + HasField< + Symbol< + 6, + Chars< + 'h', + Chars<'e', Chars<'i', Chars<'g', Chars<'h', Chars<'t', Nil>>>>>, + >, + >, + Value = f64, + >, + { + fn rectangle_area(&self) -> f64 { + let width: f64 = self + .get_field( + ::core::marker::PhantomData::< + Symbol< + 5, + Chars<'w', Chars<'i', Chars<'d', Chars<'t', Chars<'h', Nil>>>>>, + >, + >, + ) + .clone(); + let height: f64 = self + .get_field( + ::core::marker::PhantomData::< + Symbol< + 6, + Chars< + 'h', + Chars< + 'e', + Chars<'i', Chars<'g', Chars<'h', Chars<'t', Nil>>>>, + >, + >, + >, + >, + ) + .clone(); + width * height + } + } + ") + } } -#[cgp_fn] -pub fn scaled_rectangle_area(&self, #[implicit] scale_factor: f64) -> f64 -where - Self: RectangleArea, -{ - self.rectangle_area() * scale_factor * scale_factor +snapshot_cgp_fn! { + #[cgp_fn] + pub fn scaled_rectangle_area(&self, #[implicit] scale_factor: f64) -> f64 + where + Self: RectangleArea, + { + self.rectangle_area() * scale_factor * scale_factor + } + + expand_scaled_rectangle_area(output) { + assert_snapshot!(output, @" + pub trait ScaledRectangleArea { + fn scaled_rectangle_area(&self) -> f64; + } + impl<__Context__> ScaledRectangleArea for __Context__ + where + Self: RectangleArea, + Self: HasField< + Symbol< + 12, + Chars< + 's', + Chars< + 'c', + Chars< + 'a', + Chars< + 'l', + Chars< + 'e', + Chars< + '_', + Chars< + 'f', + Chars< + 'a', + Chars<'c', Chars<'t', Chars<'o', Chars<'r', Nil>>>>, + >, + >, + >, + >, + >, + >, + >, + >, + >, + Value = f64, + >, + { + fn scaled_rectangle_area(&self) -> f64 { + let scale_factor: f64 = self + .get_field( + ::core::marker::PhantomData::< + Symbol< + 12, + Chars< + 's', + Chars< + 'c', + Chars< + 'a', + Chars< + 'l', + Chars< + 'e', + Chars< + '_', + Chars< + 'f', + Chars< + 'a', + Chars<'c', Chars<'t', Chars<'o', Chars<'r', Nil>>>>, + >, + >, + >, + >, + >, + >, + >, + >, + >, + >, + ) + .clone(); + self.rectangle_area() * scale_factor * scale_factor + } + } + ") + } } #[derive(HasField)] diff --git a/crates/tests/cgp-tests/tests/cgp_fn_tests/extend.rs b/crates/tests/cgp-tests/tests/cgp_fn_tests/extend.rs index 172729fa..b2eb9075 100644 --- a/crates/tests/cgp-tests/tests/cgp_fn_tests/extend.rs +++ b/crates/tests/cgp-tests/tests/cgp_fn_tests/extend.rs @@ -1,23 +1,84 @@ use std::ops::Mul; use cgp::prelude::*; +use cgp_macro_test_util::snapshot_cgp_fn; +use insta::assert_snapshot; #[cgp_type] pub trait HasScalarType { type Scalar; } -#[cgp_fn] -#[extend(HasScalarType)] -pub fn rectangle_area( - &self, - #[implicit] width: Self::Scalar, - #[implicit] height: Self::Scalar, -) -> Self::Scalar -where - Self::Scalar: Mul + Copy, -{ - width * height +snapshot_cgp_fn! { + #[cgp_fn] + #[extend(HasScalarType)] + pub fn rectangle_area( + &self, + #[implicit] width: Self::Scalar, + #[implicit] height: Self::Scalar, + ) -> Self::Scalar + where + Self::Scalar: Mul + Copy, + { + width * height + } + + expand_rectangle_area(output) { + assert_snapshot!(output, @" + pub trait RectangleArea: HasScalarType { + fn rectangle_area(&self) -> Self::Scalar; + } + impl<__Context__> RectangleArea for __Context__ + where + Self::Scalar: Mul + Copy, + Self: HasScalarType, + Self: HasField< + Symbol<5, Chars<'w', Chars<'i', Chars<'d', Chars<'t', Chars<'h', Nil>>>>>>, + Value = Self::Scalar, + > + + HasField< + Symbol< + 6, + Chars< + 'h', + Chars<'e', Chars<'i', Chars<'g', Chars<'h', Chars<'t', Nil>>>>>, + >, + >, + Value = Self::Scalar, + >, + { + fn rectangle_area(&self) -> Self::Scalar { + let width: Self::Scalar = self + .get_field( + ::core::marker::PhantomData::< + Symbol< + 5, + Chars<'w', Chars<'i', Chars<'d', Chars<'t', Chars<'h', Nil>>>>>, + >, + >, + ) + .clone(); + let height: Self::Scalar = self + .get_field( + ::core::marker::PhantomData::< + Symbol< + 6, + Chars< + 'h', + Chars< + 'e', + Chars<'i', Chars<'g', Chars<'h', Chars<'t', Nil>>>>, + >, + >, + >, + >, + ) + .clone(); + width * height + } + } + ") + } } #[derive(HasField)] diff --git a/crates/tests/cgp-tests/tests/cgp_fn_tests/foreign_type.rs b/crates/tests/cgp-tests/tests/cgp_fn_tests/foreign_type.rs index 162b10d5..4b22f5a4 100644 --- a/crates/tests/cgp-tests/tests/cgp_fn_tests/foreign_type.rs +++ b/crates/tests/cgp-tests/tests/cgp_fn_tests/foreign_type.rs @@ -1,24 +1,87 @@ use std::ops::Mul; use cgp::prelude::*; +use cgp_macro_test_util::snapshot_cgp_fn; +use insta::assert_snapshot; #[cgp_type] pub trait HasScalarType { type Scalar; } -#[cgp_fn] -#[use_type(@Types::HasScalarType::Scalar)] -pub fn rectangle_area( - &self, - #[implicit] width: Scalar, - #[implicit] height: Scalar, -) -> Scalar -where - Scalar: Mul + Copy, -{ - let res: Scalar = width * height; - res +snapshot_cgp_fn! { + #[cgp_fn] + #[use_type(@Types::HasScalarType::Scalar)] + pub fn rectangle_area( + &self, + #[implicit] width: Scalar, + #[implicit] height: Scalar, + ) -> Scalar + where + Scalar: Mul + Copy, + { + let res: Scalar = width * height; + res + } + + expand_rectangle_area(output) { + assert_snapshot!(output, @" + pub trait RectangleArea { + fn rectangle_area(&self) -> ::Scalar; + } + impl<__Context__, Types: HasScalarType> RectangleArea for __Context__ + where + ::Scalar: Mul::Scalar> + + Copy, + Self: HasField< + Symbol<5, Chars<'w', Chars<'i', Chars<'d', Chars<'t', Chars<'h', Nil>>>>>>, + Value = ::Scalar, + > + + HasField< + Symbol< + 6, + Chars< + 'h', + Chars<'e', Chars<'i', Chars<'g', Chars<'h', Chars<'t', Nil>>>>>, + >, + >, + Value = ::Scalar, + >, + Types: HasScalarType, + { + fn rectangle_area(&self) -> ::Scalar { + let width: ::Scalar = self + .get_field( + ::core::marker::PhantomData::< + Symbol< + 5, + Chars<'w', Chars<'i', Chars<'d', Chars<'t', Chars<'h', Nil>>>>>, + >, + >, + ) + .clone(); + let height: ::Scalar = self + .get_field( + ::core::marker::PhantomData::< + Symbol< + 6, + Chars< + 'h', + Chars< + 'e', + Chars<'i', Chars<'g', Chars<'h', Chars<'t', Nil>>>>, + >, + >, + >, + >, + ) + .clone(); + let res: ::Scalar = width * height; + res + } + } + ") + } } pub struct Types; diff --git a/crates/tests/cgp-tests/tests/cgp_fn_tests/foreign_type_equality.rs b/crates/tests/cgp-tests/tests/cgp_fn_tests/foreign_type_equality.rs index 54b4a00b..374ea8a1 100644 --- a/crates/tests/cgp-tests/tests/cgp_fn_tests/foreign_type_equality.rs +++ b/crates/tests/cgp-tests/tests/cgp_fn_tests/foreign_type_equality.rs @@ -1,4 +1,6 @@ use cgp::prelude::*; +use cgp_macro_test_util::snapshot_cgp_fn; +use insta::assert_snapshot; #[cgp_type] pub trait HasScalarType { @@ -10,14 +12,74 @@ pub trait HasTypes { type Types: HasScalarType; } -#[cgp_fn] -#[use_type( - HasTypes::Types, - @Types::HasScalarType::{Scalar = f64}, -)] -pub fn rectangle_area(&self, #[implicit] width: Scalar, #[implicit] height: Scalar) -> Scalar { - let res: f64 = width * height; - res +snapshot_cgp_fn! { + #[cgp_fn] + #[use_type( + HasTypes::Types, + @Types::HasScalarType::{Scalar = f64}, + )] + pub fn rectangle_area(&self, #[implicit] width: Scalar, #[implicit] height: Scalar) -> Scalar { + let res: f64 = width * height; + res + } + + expand_rectangle_area(output) { + assert_snapshot!(output, @" + pub trait RectangleArea: HasTypes { + fn rectangle_area(&self) -> <::Types as HasScalarType>::Scalar; + } + impl<__Context__> RectangleArea for __Context__ + where + Self: HasField< + Symbol<5, Chars<'w', Chars<'i', Chars<'d', Chars<'t', Chars<'h', Nil>>>>>>, + Value = <::Types as HasScalarType>::Scalar, + > + + HasField< + Symbol< + 6, + Chars< + 'h', + Chars<'e', Chars<'i', Chars<'g', Chars<'h', Chars<'t', Nil>>>>>, + >, + >, + Value = <::Types as HasScalarType>::Scalar, + >, + Self: HasTypes, + ::Types: HasScalarType, + { + fn rectangle_area(&self) -> <::Types as HasScalarType>::Scalar { + let width: <::Types as HasScalarType>::Scalar = self + .get_field( + ::core::marker::PhantomData::< + Symbol< + 5, + Chars<'w', Chars<'i', Chars<'d', Chars<'t', Chars<'h', Nil>>>>>, + >, + >, + ) + .clone(); + let height: <::Types as HasScalarType>::Scalar = self + .get_field( + ::core::marker::PhantomData::< + Symbol< + 6, + Chars< + 'h', + Chars< + 'e', + Chars<'i', Chars<'g', Chars<'h', Chars<'t', Nil>>>>, + >, + >, + >, + >, + ) + .clone(); + let res: f64 = width * height; + res + } + } + ") + } } pub trait HasFooType { @@ -28,31 +90,115 @@ pub trait HasBarType { type Bar: HasFooType; } -#[cgp_fn] -#[use_type(HasFooType::Foo)] -pub fn do_foo(&self) -> Foo { - todo!() -} - -#[cgp_fn] -#[use_type(HasBarType::Bar, @Bar::HasFooType::Foo)] -pub fn do_bar(&self) -> Foo { - todo!() -} - -#[cgp_fn] -#[use_type( - HasFooType::Foo, - HasBarType::Bar, - @Bar::HasFooType::{Foo as BarFoo = Foo}, -)] -#[uses(DoFoo, DoBar)] -fn return_foo_or_bar(&self, flag: bool, #[implicit] foo: &Foo, #[implicit] bar: &BarFoo) -> Foo { - if flag { - let res: Foo = self.do_foo(); - if &res < foo { res } else { foo.clone() } - } else { - let res: BarFoo = self.do_bar(); - if &res < bar { res } else { bar.clone() } +snapshot_cgp_fn! { + #[cgp_fn] + #[use_type(HasFooType::Foo)] + pub fn do_foo(&self) -> Foo { + todo!() + } + + expand_do_foo(output) { + assert_snapshot!(output, @" + pub trait DoFoo: HasFooType { + fn do_foo(&self) -> ::Foo; + } + impl<__Context__> DoFoo for __Context__ + where + Self: HasFooType, + { + fn do_foo(&self) -> ::Foo { + todo!() + } + } + ") + } +} + +snapshot_cgp_fn! { + #[cgp_fn] + #[use_type(HasBarType::Bar, @Bar::HasFooType::Foo)] + pub fn do_bar(&self) -> Foo { + todo!() + } + + expand_do_bar(output) { + assert_snapshot!(output, @" + pub trait DoBar: HasBarType { + fn do_bar(&self) -> <::Bar as HasFooType>::Foo; + } + impl<__Context__> DoBar for __Context__ + where + Self: HasBarType, + ::Bar: HasFooType, + { + fn do_bar(&self) -> <::Bar as HasFooType>::Foo { + todo!() + } + } + ") + } +} + +snapshot_cgp_fn! { + #[cgp_fn] + #[use_type( + HasFooType::Foo, + HasBarType::Bar, + @Bar::HasFooType::{Foo as BarFoo = Foo}, + )] + #[uses(DoFoo, DoBar)] + fn return_foo_or_bar(&self, flag: bool, #[implicit] foo: &Foo, #[implicit] bar: &BarFoo) -> Foo { + if flag { + let res: Foo = self.do_foo(); + if &res < foo { res } else { foo.clone() } + } else { + let res: BarFoo = self.do_bar(); + if &res < bar { res } else { bar.clone() } + } + } + + expand_return_foo_or_bar(output) { + assert_snapshot!(output, @" + trait ReturnFooOrBar: HasFooType + HasBarType { + fn return_foo_or_bar(&self, flag: bool) -> ::Foo; + } + impl<__Context__> ReturnFooOrBar for __Context__ + where + Self: DoFoo + DoBar, + Self: HasField< + Symbol<3, Chars<'f', Chars<'o', Chars<'o', Nil>>>>, + Value = ::Foo, + > + + HasField< + Symbol<3, Chars<'b', Chars<'a', Chars<'r', Nil>>>>, + Value = <::Bar as HasFooType>::Foo, + >, + Self: HasFooType, + Self: HasBarType, + ::Bar: HasFooType::Foo>, + { + fn return_foo_or_bar(&self, flag: bool) -> ::Foo { + let foo: &::Foo = self + .get_field( + ::core::marker::PhantomData::< + Symbol<3, Chars<'f', Chars<'o', Chars<'o', Nil>>>>, + >, + ); + let bar: &<::Bar as HasFooType>::Foo = self + .get_field( + ::core::marker::PhantomData::< + Symbol<3, Chars<'b', Chars<'a', Chars<'r', Nil>>>>, + >, + ); + if flag { + let res: ::Foo = self.do_foo(); + if &res < foo { res } else { foo.clone() } + } else { + let res: <::Bar as HasFooType>::Foo = self.do_bar(); + if &res < bar { res } else { bar.clone() } + } + } + } + ") } } diff --git a/crates/tests/cgp-tests/tests/cgp_fn_tests/generics.rs b/crates/tests/cgp-tests/tests/cgp_fn_tests/generics.rs index baaae9f7..33e4cc8d 100644 --- a/crates/tests/cgp-tests/tests/cgp_fn_tests/generics.rs +++ b/crates/tests/cgp-tests/tests/cgp_fn_tests/generics.rs @@ -1,17 +1,77 @@ use std::ops::Mul; use cgp::prelude::*; +use cgp_macro_test_util::snapshot_cgp_fn; +use insta::assert_snapshot; -#[cgp_fn] -pub fn rectangle_area( - &self, - #[implicit] width: Scalar, - #[implicit] height: Scalar, -) -> Scalar -where - Scalar: Mul + Copy, -{ - width * height +snapshot_cgp_fn! { + #[cgp_fn] + pub fn rectangle_area( + &self, + #[implicit] width: Scalar, + #[implicit] height: Scalar, + ) -> Scalar + where + Scalar: Mul + Copy, + { + width * height + } + + expand_rectangle_area(output) { + assert_snapshot!(output, @" + pub trait RectangleArea { + fn rectangle_area(&self) -> Scalar; + } + impl<__Context__, Scalar> RectangleArea for __Context__ + where + Scalar: Mul + Copy, + Self: HasField< + Symbol<5, Chars<'w', Chars<'i', Chars<'d', Chars<'t', Chars<'h', Nil>>>>>>, + Value = Scalar, + > + + HasField< + Symbol< + 6, + Chars< + 'h', + Chars<'e', Chars<'i', Chars<'g', Chars<'h', Chars<'t', Nil>>>>>, + >, + >, + Value = Scalar, + >, + { + fn rectangle_area(&self) -> Scalar { + let width: Scalar = self + .get_field( + ::core::marker::PhantomData::< + Symbol< + 5, + Chars<'w', Chars<'i', Chars<'d', Chars<'t', Chars<'h', Nil>>>>>, + >, + >, + ) + .clone(); + let height: Scalar = self + .get_field( + ::core::marker::PhantomData::< + Symbol< + 6, + Chars< + 'h', + Chars< + 'e', + Chars<'i', Chars<'g', Chars<'h', Chars<'t', Nil>>>>, + >, + >, + >, + >, + ) + .clone(); + width * height + } + } + ") + } } #[derive(HasField)] diff --git a/crates/tests/cgp-tests/tests/cgp_fn_tests/impl_generics.rs b/crates/tests/cgp-tests/tests/cgp_fn_tests/impl_generics.rs index 65f0e629..c2ccf343 100644 --- a/crates/tests/cgp-tests/tests/cgp_fn_tests/impl_generics.rs +++ b/crates/tests/cgp-tests/tests/cgp_fn_tests/impl_generics.rs @@ -1,20 +1,68 @@ use core::fmt::Display; use cgp::prelude::*; +use cgp_macro_test_util::snapshot_cgp_fn; +use insta::assert_snapshot; -#[cgp_fn] -#[impl_generics(Name: Display)] -pub fn greet(&self, #[implicit] name: &Name) -> String -where - Name: Display, -{ - format!("Hello, {}!", name) +snapshot_cgp_fn! { + #[cgp_fn] + #[impl_generics(Name: Display)] + pub fn greet(&self, #[implicit] name: &Name) -> String + where + Name: Display, + { + format!("Hello, {}!", name) + } + + expand_greet(output) { + assert_snapshot!(output, @r#" + pub trait Greet { + fn greet(&self) -> String; + } + impl<__Context__, Name: Display> Greet for __Context__ + where + Name: Display, + Self: HasField< + Symbol<4, Chars<'n', Chars<'a', Chars<'m', Chars<'e', Nil>>>>>, + Value = Name, + >, + { + fn greet(&self) -> String { + let name: &Name = self + .get_field( + ::core::marker::PhantomData::< + Symbol<4, Chars<'n', Chars<'a', Chars<'m', Chars<'e', Nil>>>>>, + >, + ); + format!("Hello, {}!", name) + } + } + "#) + } } -#[cgp_fn] -#[uses(Greet)] -pub fn test_greet(&self) { - assert_eq!(self.greet(), "Hello, John!"); +snapshot_cgp_fn! { + #[cgp_fn] + #[uses(Greet)] + pub fn test_greet(&self) { + assert_eq!(self.greet(), "Hello, John!"); + } + + expand_test_greet(output) { + assert_snapshot!(output, @r#" + pub trait TestGreet { + fn test_greet(&self); + } + impl<__Context__> TestGreet for __Context__ + where + Self: Greet, + { + fn test_greet(&self) { + assert_eq!(self.greet(), "Hello, John!"); + } + } + "#) + } } #[derive(HasField)] diff --git a/crates/tests/cgp-tests/tests/cgp_fn_tests/multi.rs b/crates/tests/cgp-tests/tests/cgp_fn_tests/multi.rs index 5c93b406..7eadb01b 100644 --- a/crates/tests/cgp-tests/tests/cgp_fn_tests/multi.rs +++ b/crates/tests/cgp-tests/tests/cgp_fn_tests/multi.rs @@ -1,6 +1,8 @@ use core::fmt::Display; use cgp::prelude::*; +use cgp_macro_test_util::snapshot_cgp_fn; +use insta::assert_snapshot; pub trait HasFooType { type Foo; @@ -12,20 +14,81 @@ pub trait HasBarType { type Baz; } -#[cgp_fn] -#[allow(unused)] -#[async_trait] -#[use_type(>::{Foo as FooX}, >::{Foo as FooY}, HasBarType::{Bar, Baz})] -pub async fn do_foo_bar( - &self, - x: X, - #[implicit] foo_x: &FooX, - #[implicit] foo_y: &FooY, - #[implicit] bar: &Bar, - y: Y, -) -> Option -where - FooX: Display, -{ - None +snapshot_cgp_fn! { + #[cgp_fn] + #[allow(unused)] + #[async_trait] + #[use_type(>::{Foo as FooX}, >::{Foo as FooY}, HasBarType::{Bar, Baz})] + pub async fn do_foo_bar( + &self, + x: X, + #[implicit] foo_x: &FooX, + #[implicit] foo_y: &FooY, + #[implicit] bar: &Bar, + y: Y, + ) -> Option + where + FooX: Display, + { + None + } + + expand_do_foo_bar(output) { + assert_snapshot!(output, @" + #[allow(unused)] + #[async_trait] + pub trait DoFooBar: HasFooType + HasFooType + HasBarType { + async fn do_foo_bar(&self, x: X, y: Y) -> Option<::Baz>; + } + #[allow(unused)] + #[async_trait] + impl<__Context__, X, Y> DoFooBar for __Context__ + where + >::Foo: Display, + Self: HasField< + Symbol<5, Chars<'f', Chars<'o', Chars<'o', Chars<'_', Chars<'x', Nil>>>>>>, + Value = >::Foo, + > + + HasField< + Symbol<5, Chars<'f', Chars<'o', Chars<'o', Chars<'_', Chars<'y', Nil>>>>>>, + Value = >::Foo, + > + + HasField< + Symbol<3, Chars<'b', Chars<'a', Chars<'r', Nil>>>>, + Value = ::Bar, + >, + Self: HasFooType, + Self: HasFooType, + Self: HasBarType, + { + async fn do_foo_bar(&self, x: X, y: Y) -> Option<::Baz> { + let foo_x: &>::Foo = self + .get_field( + ::core::marker::PhantomData::< + Symbol< + 5, + Chars<'f', Chars<'o', Chars<'o', Chars<'_', Chars<'x', Nil>>>>>, + >, + >, + ); + let foo_y: &>::Foo = self + .get_field( + ::core::marker::PhantomData::< + Symbol< + 5, + Chars<'f', Chars<'o', Chars<'o', Chars<'_', Chars<'y', Nil>>>>>, + >, + >, + ); + let bar: &::Bar = self + .get_field( + ::core::marker::PhantomData::< + Symbol<3, Chars<'b', Chars<'a', Chars<'r', Nil>>>>, + >, + ); + None + } + } + ") + } } diff --git a/crates/tests/cgp-tests/tests/cgp_fn_tests/mutable.rs b/crates/tests/cgp-tests/tests/cgp_fn_tests/mutable.rs index 507d127d..efe8a7bd 100644 --- a/crates/tests/cgp-tests/tests/cgp_fn_tests/mutable.rs +++ b/crates/tests/cgp-tests/tests/cgp_fn_tests/mutable.rs @@ -1,13 +1,46 @@ use cgp::prelude::*; +use cgp_macro_test_util::snapshot_cgp_fn; +use insta::assert_snapshot; -#[cgp_fn] -pub fn capitalize_name(&mut self, #[implicit] name: &mut String) { - if let Some(first_char) = name.chars().next() - && first_char.is_lowercase() - { - let char_len = first_char.len_utf8(); - let capitalized = first_char.to_uppercase().to_string(); - name.replace_range(..char_len, &capitalized); +snapshot_cgp_fn! { + #[cgp_fn] + pub fn capitalize_name(&mut self, #[implicit] name: &mut String) { + if let Some(first_char) = name.chars().next() + && first_char.is_lowercase() + { + let char_len = first_char.len_utf8(); + let capitalized = first_char.to_uppercase().to_string(); + name.replace_range(..char_len, &capitalized); + } + } + + expand_capitalize_name(output) { + assert_snapshot!(output, @" + pub trait CapitalizeName { + fn capitalize_name(&mut self); + } + impl<__Context__> CapitalizeName for __Context__ + where + Self: HasFieldMut< + Symbol<4, Chars<'n', Chars<'a', Chars<'m', Chars<'e', Nil>>>>>, + Value = String, + >, + { + fn capitalize_name(&mut self) { + let name: &mut String = self + .get_field_mut( + ::core::marker::PhantomData::< + Symbol<4, Chars<'n', Chars<'a', Chars<'m', Chars<'e', Nil>>>>>, + >, + ); + if let Some(first_char) = name.chars().next() && first_char.is_lowercase() { + let char_len = first_char.len_utf8(); + let capitalized = first_char.to_uppercase().to_string(); + name.replace_range(..char_len, &capitalized); + } + } + } + ") } } diff --git a/crates/tests/cgp-tests/tests/cgp_fn_tests/nested_foreign_type.rs b/crates/tests/cgp-tests/tests/cgp_fn_tests/nested_foreign_type.rs index 31da2d1b..19807be8 100644 --- a/crates/tests/cgp-tests/tests/cgp_fn_tests/nested_foreign_type.rs +++ b/crates/tests/cgp-tests/tests/cgp_fn_tests/nested_foreign_type.rs @@ -1,6 +1,8 @@ use std::ops::Mul; use cgp::prelude::*; +use cgp_macro_test_util::snapshot_cgp_fn; +use insta::assert_snapshot; #[cgp_type] pub trait HasScalarType { @@ -12,15 +14,82 @@ pub trait HasTypes { type Types; } -#[cgp_fn] -#[use_type(HasTypes::Types, @Types::HasScalarType::Scalar)] -#[extend_where(Types: HasScalarType)] -pub fn rectangle_area(&self, #[implicit] width: Scalar, #[implicit] height: Scalar) -> Scalar -where - Scalar: Mul + Copy, -{ - let res: Scalar = width * height; - res +snapshot_cgp_fn! { + #[cgp_fn] + #[use_type(HasTypes::Types, @Types::HasScalarType::Scalar)] + #[extend_where(Types: HasScalarType)] + pub fn rectangle_area(&self, #[implicit] width: Scalar, #[implicit] height: Scalar) -> Scalar + where + Scalar: Mul + Copy, + { + let res: Scalar = width * height; + res + } + + expand_rectangle_area(output) { + assert_snapshot!(output, @" + pub trait RectangleArea: HasTypes + where + ::Types: HasScalarType, + { + fn rectangle_area(&self) -> <::Types as HasScalarType>::Scalar; + } + impl<__Context__> RectangleArea for __Context__ + where + <::Types as HasScalarType>::Scalar: Mul< + Output = <::Types as HasScalarType>::Scalar, + > + Copy, + ::Types: HasScalarType, + Self: HasField< + Symbol<5, Chars<'w', Chars<'i', Chars<'d', Chars<'t', Chars<'h', Nil>>>>>>, + Value = <::Types as HasScalarType>::Scalar, + > + + HasField< + Symbol< + 6, + Chars< + 'h', + Chars<'e', Chars<'i', Chars<'g', Chars<'h', Chars<'t', Nil>>>>>, + >, + >, + Value = <::Types as HasScalarType>::Scalar, + >, + Self: HasTypes, + ::Types: HasScalarType, + { + fn rectangle_area(&self) -> <::Types as HasScalarType>::Scalar { + let width: <::Types as HasScalarType>::Scalar = self + .get_field( + ::core::marker::PhantomData::< + Symbol< + 5, + Chars<'w', Chars<'i', Chars<'d', Chars<'t', Chars<'h', Nil>>>>>, + >, + >, + ) + .clone(); + let height: <::Types as HasScalarType>::Scalar = self + .get_field( + ::core::marker::PhantomData::< + Symbol< + 6, + Chars< + 'h', + Chars< + 'e', + Chars<'i', Chars<'g', Chars<'h', Chars<'t', Nil>>>>, + >, + >, + >, + >, + ) + .clone(); + let res: <::Types as HasScalarType>::Scalar = width * height; + res + } + } + ") + } } pub struct MyTypes; diff --git a/crates/tests/cgp-tests/tests/cgp_fn_tests/type_equality.rs b/crates/tests/cgp-tests/tests/cgp_fn_tests/type_equality.rs index 8da2b1a3..946cfbe9 100644 --- a/crates/tests/cgp-tests/tests/cgp_fn_tests/type_equality.rs +++ b/crates/tests/cgp-tests/tests/cgp_fn_tests/type_equality.rs @@ -1,17 +1,78 @@ use std::fmt::Display; use cgp::prelude::*; +use cgp_macro_test_util::snapshot_cgp_fn; +use insta::assert_snapshot; #[cgp_type] pub trait HasScalarType { type Scalar; } -#[cgp_fn] -#[use_type(HasScalarType::{Scalar = f64})] -pub fn rectangle_area(&self, #[implicit] width: Scalar, #[implicit] height: Scalar) -> Scalar { - let res: f64 = width * height; - res +snapshot_cgp_fn! { + #[cgp_fn] + #[use_type(HasScalarType::{Scalar = f64})] + pub fn rectangle_area(&self, #[implicit] width: Scalar, #[implicit] height: Scalar) -> Scalar { + let res: f64 = width * height; + res + } + + expand_rectangle_area(output) { + assert_snapshot!(output, @" + pub trait RectangleArea: HasScalarType { + fn rectangle_area(&self) -> ::Scalar; + } + impl<__Context__> RectangleArea for __Context__ + where + Self: HasField< + Symbol<5, Chars<'w', Chars<'i', Chars<'d', Chars<'t', Chars<'h', Nil>>>>>>, + Value = ::Scalar, + > + + HasField< + Symbol< + 6, + Chars< + 'h', + Chars<'e', Chars<'i', Chars<'g', Chars<'h', Chars<'t', Nil>>>>>, + >, + >, + Value = ::Scalar, + >, + Self: HasScalarType, + { + fn rectangle_area(&self) -> ::Scalar { + let width: ::Scalar = self + .get_field( + ::core::marker::PhantomData::< + Symbol< + 5, + Chars<'w', Chars<'i', Chars<'d', Chars<'t', Chars<'h', Nil>>>>>, + >, + >, + ) + .clone(); + let height: ::Scalar = self + .get_field( + ::core::marker::PhantomData::< + Symbol< + 6, + Chars< + 'h', + Chars< + 'e', + Chars<'i', Chars<'g', Chars<'h', Chars<'t', Nil>>>>, + >, + >, + >, + >, + ) + .clone(); + let res: f64 = width * height; + res + } + } + ") + } } pub trait HasFooType { @@ -24,27 +85,109 @@ pub trait HasBarType { type Bar: Display; } -#[cgp_fn] -#[use_type(HasFooType::Foo)] -pub fn do_foo(&self) -> Foo { - todo!() +snapshot_cgp_fn! { + #[cgp_fn] + #[use_type(HasFooType::Foo)] + pub fn do_foo(&self) -> Foo { + todo!() + } + + expand_do_foo(output) { + assert_snapshot!(output, @" + pub trait DoFoo: HasFooType { + fn do_foo(&self) -> ::Foo; + } + impl<__Context__> DoFoo for __Context__ + where + Self: HasFooType, + { + fn do_foo(&self) -> ::Foo { + todo!() + } + } + ") + } } -#[cgp_fn] -#[use_type(HasBarType::Bar)] -pub fn do_bar(&self) -> Bar { - todo!() +snapshot_cgp_fn! { + #[cgp_fn] + #[use_type(HasBarType::Bar)] + pub fn do_bar(&self) -> Bar { + todo!() + } + + expand_do_bar(output) { + assert_snapshot!(output, @" + pub trait DoBar: HasBarType { + fn do_bar(&self) -> ::Bar; + } + impl<__Context__> DoBar for __Context__ + where + Self: HasBarType, + { + fn do_bar(&self) -> ::Bar { + todo!() + } + } + ") + } } -#[cgp_fn] -#[use_type(HasBarType::{Bar as Baz = Foo}, HasFooType::Foo)] -#[uses(DoFoo, DoBar)] -fn return_foo_or_bar(&self, flag: bool, #[implicit] foo: &Foo, #[implicit] bar: &Baz) -> Foo { - if flag { - let res: Foo = self.do_foo(); - if &res < foo { res } else { foo.clone() } - } else { - let res: Baz = self.do_bar(); - if &res < bar { res } else { bar.clone() } +snapshot_cgp_fn! { + #[cgp_fn] + #[use_type(HasBarType::{Bar as Baz = Foo}, HasFooType::Foo)] + #[uses(DoFoo, DoBar)] + fn return_foo_or_bar(&self, flag: bool, #[implicit] foo: &Foo, #[implicit] bar: &Baz) -> Foo { + if flag { + let res: Foo = self.do_foo(); + if &res < foo { res } else { foo.clone() } + } else { + let res: Baz = self.do_bar(); + if &res < bar { res } else { bar.clone() } + } + } + + expand_return_foo_or_bar(output) { + assert_snapshot!(output, @" + trait ReturnFooOrBar: HasBarType + HasFooType { + fn return_foo_or_bar(&self, flag: bool) -> ::Foo; + } + impl<__Context__> ReturnFooOrBar for __Context__ + where + Self: DoFoo + DoBar, + Self: HasField< + Symbol<3, Chars<'f', Chars<'o', Chars<'o', Nil>>>>, + Value = ::Foo, + > + + HasField< + Symbol<3, Chars<'b', Chars<'a', Chars<'r', Nil>>>>, + Value = ::Bar, + >, + Self: HasBarType::Foo>, + Self: HasFooType, + { + fn return_foo_or_bar(&self, flag: bool) -> ::Foo { + let foo: &::Foo = self + .get_field( + ::core::marker::PhantomData::< + Symbol<3, Chars<'f', Chars<'o', Chars<'o', Nil>>>>, + >, + ); + let bar: &::Bar = self + .get_field( + ::core::marker::PhantomData::< + Symbol<3, Chars<'b', Chars<'a', Chars<'r', Nil>>>>, + >, + ); + if flag { + let res: ::Foo = self.do_foo(); + if &res < foo { res } else { foo.clone() } + } else { + let res: ::Bar = self.do_bar(); + if &res < bar { res } else { bar.clone() } + } + } + } + ") } } diff --git a/crates/tests/cgp-tests/tests/cgp_fn_tests/use_provider.rs b/crates/tests/cgp-tests/tests/cgp_fn_tests/use_provider.rs index 1aec333b..d964ba89 100644 --- a/crates/tests/cgp-tests/tests/cgp_fn_tests/use_provider.rs +++ b/crates/tests/cgp-tests/tests/cgp_fn_tests/use_provider.rs @@ -1,5 +1,5 @@ use cgp::prelude::*; -use cgp_macro_test_util::{snapshot_cgp_component, snapshot_cgp_impl}; +use cgp_macro_test_util::{snapshot_cgp_component, snapshot_cgp_fn, snapshot_cgp_impl}; use insta::assert_snapshot; snapshot_cgp_component! { @@ -162,10 +162,28 @@ snapshot_cgp_impl! { } } -#[cgp_fn] -#[use_provider(RectangleAreaCalculator: AreaCalculator)] -fn rectangle_area(&self) -> f64 { - RectangleAreaCalculator::area(self) +snapshot_cgp_fn! { + #[cgp_fn] + #[use_provider(RectangleAreaCalculator: AreaCalculator)] + fn rectangle_area(&self) -> f64 { + RectangleAreaCalculator::area(self) + } + + expand_rectangle_area(output) { + assert_snapshot!(output, @" + trait RectangleArea { + fn rectangle_area(&self) -> f64; + } + impl<__Context__> RectangleArea for __Context__ + where + RectangleAreaCalculator: AreaCalculator, + { + fn rectangle_area(&self) -> f64 { + RectangleAreaCalculator::area(self) + } + } + ") + } } #[derive(HasField)] diff --git a/crates/tests/cgp-tests/tests/cgp_fn_tests/use_type.rs b/crates/tests/cgp-tests/tests/cgp_fn_tests/use_type.rs index 95ccfec5..87c00ced 100644 --- a/crates/tests/cgp-tests/tests/cgp_fn_tests/use_type.rs +++ b/crates/tests/cgp-tests/tests/cgp_fn_tests/use_type.rs @@ -2,20 +2,80 @@ use core::f64; use std::ops::Mul; use cgp::prelude::*; +use cgp_macro_test_util::snapshot_cgp_fn; +use insta::assert_snapshot; #[cgp_type] pub trait HasScalarType { type Scalar: Mul + Copy; } -#[cgp_fn] -#[extend(HasScalarType)] -pub fn rectangle_area( - &self, - #[implicit] width: Self::Scalar, - #[implicit] height: Self::Scalar, -) -> Self::Scalar { - width * height +snapshot_cgp_fn! { + #[cgp_fn] + #[extend(HasScalarType)] + pub fn rectangle_area( + &self, + #[implicit] width: Self::Scalar, + #[implicit] height: Self::Scalar, + ) -> Self::Scalar { + width * height + } + + expand_rectangle_area(output) { + assert_snapshot!(output, @" + pub trait RectangleArea: HasScalarType { + fn rectangle_area(&self) -> Self::Scalar; + } + impl<__Context__> RectangleArea for __Context__ + where + Self: HasScalarType, + Self: HasField< + Symbol<5, Chars<'w', Chars<'i', Chars<'d', Chars<'t', Chars<'h', Nil>>>>>>, + Value = Self::Scalar, + > + + HasField< + Symbol< + 6, + Chars< + 'h', + Chars<'e', Chars<'i', Chars<'g', Chars<'h', Chars<'t', Nil>>>>>, + >, + >, + Value = Self::Scalar, + >, + { + fn rectangle_area(&self) -> Self::Scalar { + let width: Self::Scalar = self + .get_field( + ::core::marker::PhantomData::< + Symbol< + 5, + Chars<'w', Chars<'i', Chars<'d', Chars<'t', Chars<'h', Nil>>>>>, + >, + >, + ) + .clone(); + let height: Self::Scalar = self + .get_field( + ::core::marker::PhantomData::< + Symbol< + 6, + Chars< + 'h', + Chars< + 'e', + Chars<'i', Chars<'g', Chars<'h', Chars<'t', Nil>>>>, + >, + >, + >, + >, + ) + .clone(); + width * height + } + } + ") + } } #[derive(HasField)] diff --git a/crates/tests/cgp-tests/tests/cgp_fn_tests/use_type_alias.rs b/crates/tests/cgp-tests/tests/cgp_fn_tests/use_type_alias.rs index a22706e3..48742b36 100644 --- a/crates/tests/cgp-tests/tests/cgp_fn_tests/use_type_alias.rs +++ b/crates/tests/cgp-tests/tests/cgp_fn_tests/use_type_alias.rs @@ -1,18 +1,81 @@ use std::ops::Mul; use cgp::prelude::*; +use cgp_macro_test_util::snapshot_cgp_fn; +use insta::assert_snapshot; #[cgp_type] pub trait HasScalarType { type Scalar; } -#[cgp_fn] -#[use_type(HasScalarType::{Scalar as S})] -pub fn rectangle_area(&self, #[implicit] width: S, #[implicit] height: S) -> S -where - S: Mul + Copy, -{ - let res: S = width * height; - res +snapshot_cgp_fn! { + #[cgp_fn] + #[use_type(HasScalarType::{Scalar as S})] + pub fn rectangle_area(&self, #[implicit] width: S, #[implicit] height: S) -> S + where + S: Mul + Copy, + { + let res: S = width * height; + res + } + + expand_rectangle_area(output) { + assert_snapshot!(output, @" + pub trait RectangleArea: HasScalarType { + fn rectangle_area(&self) -> ::Scalar; + } + impl<__Context__> RectangleArea for __Context__ + where + ::Scalar: Mul::Scalar> + + Copy, + Self: HasField< + Symbol<5, Chars<'w', Chars<'i', Chars<'d', Chars<'t', Chars<'h', Nil>>>>>>, + Value = ::Scalar, + > + + HasField< + Symbol< + 6, + Chars< + 'h', + Chars<'e', Chars<'i', Chars<'g', Chars<'h', Chars<'t', Nil>>>>>, + >, + >, + Value = ::Scalar, + >, + Self: HasScalarType, + { + fn rectangle_area(&self) -> ::Scalar { + let width: ::Scalar = self + .get_field( + ::core::marker::PhantomData::< + Symbol< + 5, + Chars<'w', Chars<'i', Chars<'d', Chars<'t', Chars<'h', Nil>>>>>, + >, + >, + ) + .clone(); + let height: ::Scalar = self + .get_field( + ::core::marker::PhantomData::< + Symbol< + 6, + Chars< + 'h', + Chars< + 'e', + Chars<'i', Chars<'g', Chars<'h', Chars<'t', Nil>>>>, + >, + >, + >, + >, + ) + .clone(); + let res: ::Scalar = width * height; + res + } + } + ") + } } diff --git a/crates/tests/cgp-tests/tests/cgp_fn_tests/uses.rs b/crates/tests/cgp-tests/tests/cgp_fn_tests/uses.rs index a267732b..54d1bba9 100644 --- a/crates/tests/cgp-tests/tests/cgp_fn_tests/uses.rs +++ b/crates/tests/cgp-tests/tests/cgp_fn_tests/uses.rs @@ -1,14 +1,156 @@ use cgp::prelude::*; +use cgp_macro_test_util::snapshot_cgp_fn; +use insta::assert_snapshot; -#[cgp_fn] -pub fn rectangle_area(&self, #[implicit] width: f64, #[implicit] height: f64) -> f64 { - width * height +snapshot_cgp_fn! { + #[cgp_fn] + pub fn rectangle_area(&self, #[implicit] width: f64, #[implicit] height: f64) -> f64 { + width * height + } + + expand_rectangle_area(output) { + assert_snapshot!(output, @" + pub trait RectangleArea { + fn rectangle_area(&self) -> f64; + } + impl<__Context__> RectangleArea for __Context__ + where + Self: HasField< + Symbol<5, Chars<'w', Chars<'i', Chars<'d', Chars<'t', Chars<'h', Nil>>>>>>, + Value = f64, + > + + HasField< + Symbol< + 6, + Chars< + 'h', + Chars<'e', Chars<'i', Chars<'g', Chars<'h', Chars<'t', Nil>>>>>, + >, + >, + Value = f64, + >, + { + fn rectangle_area(&self) -> f64 { + let width: f64 = self + .get_field( + ::core::marker::PhantomData::< + Symbol< + 5, + Chars<'w', Chars<'i', Chars<'d', Chars<'t', Chars<'h', Nil>>>>>, + >, + >, + ) + .clone(); + let height: f64 = self + .get_field( + ::core::marker::PhantomData::< + Symbol< + 6, + Chars< + 'h', + Chars< + 'e', + Chars<'i', Chars<'g', Chars<'h', Chars<'t', Nil>>>>, + >, + >, + >, + >, + ) + .clone(); + width * height + } + } + ") + } } -#[cgp_fn] -#[uses(RectangleArea)] -pub fn scaled_rectangle_area(&self, #[implicit] scale_factor: f64) -> f64 { - self.rectangle_area() * scale_factor * scale_factor +snapshot_cgp_fn! { + #[cgp_fn] + #[uses(RectangleArea)] + pub fn scaled_rectangle_area(&self, #[implicit] scale_factor: f64) -> f64 { + self.rectangle_area() * scale_factor * scale_factor + } + + expand_scaled_rectangle_area(output) { + assert_snapshot!(output, @" + pub trait ScaledRectangleArea { + fn scaled_rectangle_area(&self) -> f64; + } + impl<__Context__> ScaledRectangleArea for __Context__ + where + Self: RectangleArea, + Self: HasField< + Symbol< + 12, + Chars< + 's', + Chars< + 'c', + Chars< + 'a', + Chars< + 'l', + Chars< + 'e', + Chars< + '_', + Chars< + 'f', + Chars< + 'a', + Chars<'c', Chars<'t', Chars<'o', Chars<'r', Nil>>>>, + >, + >, + >, + >, + >, + >, + >, + >, + >, + Value = f64, + >, + { + fn scaled_rectangle_area(&self) -> f64 { + let scale_factor: f64 = self + .get_field( + ::core::marker::PhantomData::< + Symbol< + 12, + Chars< + 's', + Chars< + 'c', + Chars< + 'a', + Chars< + 'l', + Chars< + 'e', + Chars< + '_', + Chars< + 'f', + Chars< + 'a', + Chars<'c', Chars<'t', Chars<'o', Chars<'r', Nil>>>>, + >, + >, + >, + >, + >, + >, + >, + >, + >, + >, + ) + .clone(); + self.rectangle_area() * scale_factor * scale_factor + } + } + ") + } } #[derive(HasField)] diff --git a/crates/tests/cgp-tests/tests/component_tests/cgp_impl/implicit_args/import.rs b/crates/tests/cgp-tests/tests/component_tests/cgp_impl/implicit_args/import.rs index c946e12a..2e7cd915 100644 --- a/crates/tests/cgp-tests/tests/component_tests/cgp_impl/implicit_args/import.rs +++ b/crates/tests/cgp-tests/tests/component_tests/cgp_impl/implicit_args/import.rs @@ -1,4 +1,6 @@ use cgp::prelude::*; +use cgp_macro_test_util::snapshot_cgp_fn; +use insta::assert_snapshot; #[cgp_component(AreaCalculator)] pub trait CanCalculateArea { @@ -13,9 +15,66 @@ impl AreaCalculator { } } -#[cgp_fn] -pub fn rectangle_area(&self, #[implicit] width: f64, #[implicit] height: f64) -> f64 { - width * height +snapshot_cgp_fn! { + #[cgp_fn] + pub fn rectangle_area(&self, #[implicit] width: f64, #[implicit] height: f64) -> f64 { + width * height + } + + expand_rectangle_area(output) { + assert_snapshot!(output, @" + pub trait RectangleArea { + fn rectangle_area(&self) -> f64; + } + impl<__Context__> RectangleArea for __Context__ + where + Self: HasField< + Symbol<5, Chars<'w', Chars<'i', Chars<'d', Chars<'t', Chars<'h', Nil>>>>>>, + Value = f64, + > + + HasField< + Symbol< + 6, + Chars< + 'h', + Chars<'e', Chars<'i', Chars<'g', Chars<'h', Chars<'t', Nil>>>>>, + >, + >, + Value = f64, + >, + { + fn rectangle_area(&self) -> f64 { + let width: f64 = self + .get_field( + ::core::marker::PhantomData::< + Symbol< + 5, + Chars<'w', Chars<'i', Chars<'d', Chars<'t', Chars<'h', Nil>>>>>, + >, + >, + ) + .clone(); + let height: f64 = self + .get_field( + ::core::marker::PhantomData::< + Symbol< + 6, + Chars< + 'h', + Chars< + 'e', + Chars<'i', Chars<'g', Chars<'h', Chars<'t', Nil>>>>, + >, + >, + >, + >, + ) + .clone(); + width * height + } + } + ") + } } #[derive(HasField)] diff --git a/crates/tests/cgp-tests/tests/component_tests/cgp_impl/shape.rs b/crates/tests/cgp-tests/tests/component_tests/cgp_impl/shape.rs index 337f6bd7..98f25abc 100644 --- a/crates/tests/cgp-tests/tests/component_tests/cgp_impl/shape.rs +++ b/crates/tests/cgp-tests/tests/component_tests/cgp_impl/shape.rs @@ -1,15 +1,114 @@ use core::f64::consts::PI; use cgp::prelude::*; +use cgp_macro_test_util::snapshot_cgp_fn; +use insta::assert_snapshot; -#[cgp_fn] -pub fn rectangle_area(&self, #[implicit] width: f64, #[implicit] height: f64) -> f64 { - width * height +snapshot_cgp_fn! { + #[cgp_fn] + pub fn rectangle_area(&self, #[implicit] width: f64, #[implicit] height: f64) -> f64 { + width * height + } + + expand_rectangle_area(output) { + assert_snapshot!(output, @" + pub trait RectangleArea { + fn rectangle_area(&self) -> f64; + } + impl<__Context__> RectangleArea for __Context__ + where + Self: HasField< + Symbol<5, Chars<'w', Chars<'i', Chars<'d', Chars<'t', Chars<'h', Nil>>>>>>, + Value = f64, + > + + HasField< + Symbol< + 6, + Chars< + 'h', + Chars<'e', Chars<'i', Chars<'g', Chars<'h', Chars<'t', Nil>>>>>, + >, + >, + Value = f64, + >, + { + fn rectangle_area(&self) -> f64 { + let width: f64 = self + .get_field( + ::core::marker::PhantomData::< + Symbol< + 5, + Chars<'w', Chars<'i', Chars<'d', Chars<'t', Chars<'h', Nil>>>>>, + >, + >, + ) + .clone(); + let height: f64 = self + .get_field( + ::core::marker::PhantomData::< + Symbol< + 6, + Chars< + 'h', + Chars< + 'e', + Chars<'i', Chars<'g', Chars<'h', Chars<'t', Nil>>>>, + >, + >, + >, + >, + ) + .clone(); + width * height + } + } + ") + } } -#[cgp_fn] -pub fn circle_area(&self, #[implicit] radius: f64) -> f64 { - PI * radius * radius +snapshot_cgp_fn! { + #[cgp_fn] + pub fn circle_area(&self, #[implicit] radius: f64) -> f64 { + PI * radius * radius + } + + expand_circle_area(output) { + assert_snapshot!(output, @" + pub trait CircleArea { + fn circle_area(&self) -> f64; + } + impl<__Context__> CircleArea for __Context__ + where + Self: HasField< + Symbol< + 6, + Chars<'r', Chars<'a', Chars<'d', Chars<'i', Chars<'u', Chars<'s', Nil>>>>>>, + >, + Value = f64, + >, + { + fn circle_area(&self) -> f64 { + let radius: f64 = self + .get_field( + ::core::marker::PhantomData::< + Symbol< + 6, + Chars< + 'r', + Chars< + 'a', + Chars<'d', Chars<'i', Chars<'u', Chars<'s', Nil>>>>, + >, + >, + >, + >, + ) + .clone(); + PI * radius * radius + } + } + ") + } } #[cgp_component(AreaCalculator)] From 62a3187f42e7d24a815a60b7a3333572c8b47378 Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Fri, 19 Jun 2026 21:53:50 +0200 Subject: [PATCH 22/31] Use fully qualified `insta::assert_snapshot!` --- .../cgp-tests/src/namespaces/default_impls.rs | 10 ++++------ .../tests/cgp-tests/src/tests/async/spawn.rs | 9 ++++----- .../cgp-tests/src/tests/check_components.rs | 12 +++++------- .../src/tests/delegate_and_check_components.rs | 6 ++---- .../cgp-tests/src/tests/has_field/chain.rs | 3 +-- .../cgp-tests/src/tests/use_delegate/getter.rs | 6 ++---- .../cgp-tests/tests/cgp_fn_tests/async.rs | 3 +-- .../cgp-tests/tests/cgp_fn_tests/basic.rs | 5 ++--- .../tests/cgp-tests/tests/cgp_fn_tests/call.rs | 5 ++--- .../cgp-tests/tests/cgp_fn_tests/extend.rs | 3 +-- .../tests/cgp_fn_tests/foreign_type.rs | 3 +-- .../cgp_fn_tests/foreign_type_equality.rs | 9 ++++----- .../cgp-tests/tests/cgp_fn_tests/generics.rs | 3 +-- .../tests/cgp_fn_tests/impl_generics.rs | 5 ++--- .../cgp-tests/tests/cgp_fn_tests/multi.rs | 3 +-- .../cgp-tests/tests/cgp_fn_tests/mutable.rs | 3 +-- .../tests/cgp_fn_tests/nested_foreign_type.rs | 3 +-- .../tests/cgp_fn_tests/type_equality.rs | 9 ++++----- .../tests/cgp_fn_tests/use_provider.rs | 7 +++---- .../cgp-tests/tests/cgp_fn_tests/use_type.rs | 3 +-- .../tests/cgp_fn_tests/use_type_alias.rs | 3 +-- .../tests/cgp-tests/tests/cgp_fn_tests/uses.rs | 5 ++--- .../cgp_component/default_impl.rs | 3 +-- .../component_tests/cgp_component/lifetime.rs | 3 +-- .../tests/component_tests/cgp_impl/basic.rs | 7 +++---- .../cgp_impl/implicit_args/import.rs | 3 +-- .../tests/component_tests/cgp_impl/shape.rs | 5 ++--- .../delegate_components/direct.rs | 5 ++--- .../delegate_components/general.rs | 4 ++-- .../extensible_data_tests/records/basic.rs | 3 +-- .../extensible_data_tests/variants/basic.rs | 3 +-- .../extensible_data_tests/variants/shape.rs | 3 +-- .../getter_tests/abstract_type/explicit.rs | 5 ++--- .../tests/getter_tests/abstract_type/import.rs | 5 ++--- .../getter_tests/abstract_type/use_type.rs | 5 ++--- .../getter_tests/assoc_type/auto_getter.rs | 3 +-- .../tests/getter_tests/assoc_type/getter.rs | 5 ++--- .../assoc_type/self_referential.rs | 5 ++--- .../assoc_type/self_referential_auto.rs | 3 +-- .../tests/getter_tests/auto_generics.rs | 3 +-- .../cgp-tests/tests/getter_tests/clone.rs | 10 ++++------ .../tests/cgp-tests/tests/getter_tests/mref.rs | 8 +++----- .../cgp-tests/tests/getter_tests/non_self.rs | 5 ++--- .../tests/getter_tests/non_self_auto.rs | 5 ++--- .../cgp-tests/tests/getter_tests/option.rs | 8 +++----- .../cgp-tests/tests/getter_tests/slice.rs | 8 +++----- .../cgp-tests/tests/getter_tests/string.rs | 18 +++++++----------- .../tests/handler_tests/computer_macro.rs | 3 +-- .../tests/handler_tests/handler_macro.rs | 3 +-- .../cgp-tests/tests/handler_tests/pipe.rs | 6 ++---- .../tests/handler_tests/producer_macro.rs | 3 +-- .../tests/namespace_tests/multi_param.rs | 9 ++++----- .../tests/namespace_tests/namespace.rs | 5 ++--- .../namespace_tests/namespace_macro/basic.rs | 11 +++++------ .../namespace_macro/default_impls.rs | 7 +++---- .../namespace_macro/extended_namespace.rs | 3 +-- .../namespace_macro/multi_namespace.rs | 13 ++++++------- .../namespace_macro/symbol_path.rs | 11 +++++------ .../namespace_macro/type_path.rs | 11 +++++------ .../cgp-tests/tests/namespace_tests/open.rs | 11 +++++------ .../tests/namespace_tests/redirect.rs | 7 +++---- .../tests/preset_tests/basic/components.rs | 5 ++--- .../tests/preset_tests/basic/contexts.rs | 3 +-- .../tests/preset_tests/generics/components.rs | 5 ++--- .../generics_inheritance/components.rs | 5 ++--- .../tests/preset_tests/wrapped/context.rs | 3 +-- 66 files changed, 150 insertions(+), 227 deletions(-) diff --git a/crates/tests/cgp-tests/src/namespaces/default_impls.rs b/crates/tests/cgp-tests/src/namespaces/default_impls.rs index c56a925b..b9081391 100644 --- a/crates/tests/cgp-tests/src/namespaces/default_impls.rs +++ b/crates/tests/cgp-tests/src/namespaces/default_impls.rs @@ -3,8 +3,6 @@ use core::fmt::Display; use cgp::core::component::DefaultImpls1; use cgp::prelude::*; use cgp_macro_test_util::{snapshot_cgp_component, snapshot_cgp_impl}; -#[cfg(test)] -use insta::assert_snapshot; snapshot_cgp_component! { #[cgp_component(ShowImpl)] @@ -14,7 +12,7 @@ snapshot_cgp_component! { } expand_show(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub trait Show { fn show(&self, value: &T) -> String; } @@ -113,7 +111,7 @@ snapshot_cgp_impl! { } expand_show_string(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" impl<__Context__> ShowImpl<__Context__, String> for ShowString { fn show(__context__: &__Context__, value: &String) -> String { value.clone() @@ -138,7 +136,7 @@ snapshot_cgp_impl! { } expand_show_with_display(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" impl<__Context__, T: Display> ShowImpl<__Context__, T> for ShowWithDisplay { fn show(__context__: &__Context__, value: &T) -> String { value.to_string() @@ -176,7 +174,7 @@ snapshot_cgp_impl! { } expand_show_u32(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" impl<__Context__> ShowImpl<__Context__, u32> for ShowU32 { fn show(__context__: &__Context__, value: &u32) -> String { value.to_string() diff --git a/crates/tests/cgp-tests/src/tests/async/spawn.rs b/crates/tests/cgp-tests/src/tests/async/spawn.rs index 7118855f..22f332bf 100644 --- a/crates/tests/cgp-tests/src/tests/async/spawn.rs +++ b/crates/tests/cgp-tests/src/tests/async/spawn.rs @@ -19,7 +19,6 @@ use cgp::extra::run::{ use cgp::prelude::*; use cgp_macro_test_util::{snapshot_cgp_component, snapshot_delegate_components}; use futures::executor::block_on; -use insta::assert_snapshot; // A dummy spawn function that has the same signature as tokio::spawn, // requiring the Future to implement Send + 'static. @@ -50,7 +49,7 @@ snapshot_cgp_component! { } expand_can_fetch_foo(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" #[async_trait] pub trait CanFetchFoo: HasFooType + HasErrorType { async fn fetch_foo(&self) -> Result; @@ -152,7 +151,7 @@ snapshot_cgp_component! { } expand_can_fetch_bar(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" #[async_trait] pub trait CanFetchBar: HasBarType + HasErrorType { async fn fetch_bar(&self) -> Result; @@ -254,7 +253,7 @@ snapshot_cgp_component! { } expand_can_run_foo_bar(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" #[async_trait] pub trait CanRunFooBar: HasFooType + HasBarType + HasErrorType { async fn run_foo_bar( @@ -468,7 +467,7 @@ snapshot_delegate_components! { } expand_app(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub struct AppRunnerComponents; impl DelegateComponent for App { type Delegate = UseType; diff --git a/crates/tests/cgp-tests/src/tests/check_components.rs b/crates/tests/cgp-tests/src/tests/check_components.rs index be605c5e..3109ca1b 100644 --- a/crates/tests/cgp-tests/src/tests/check_components.rs +++ b/crates/tests/cgp-tests/src/tests/check_components.rs @@ -5,7 +5,6 @@ mod basic_check_components { use cgp::prelude::*; use cgp_macro_test_util::snapshot_cgp_getter; - use insta::assert_snapshot; #[cgp_type] pub trait HasFooType { @@ -26,7 +25,7 @@ mod basic_check_components { } expand_has_foo_at(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub trait HasFooAt: HasFooType { fn foo(&self, _tag: PhantomData) -> &Self::Foo; } @@ -194,7 +193,7 @@ mod basic_check_components { } expand_has_bar_at(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub trait HasBarAt: HasBarType { fn foo(&self, _tag: PhantomData<(I, J)>) -> &Self::Bar; } @@ -469,7 +468,6 @@ mod generic_check_components { use cgp::prelude::*; use cgp_macro_test_util::{snapshot_cgp_getter, snapshot_delegate_components}; - use insta::assert_snapshot; #[cgp_type] pub trait HasFooType { @@ -490,7 +488,7 @@ mod generic_check_components { } expand_has_foo_at(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub trait HasFooAt: HasFooType { fn foo(&self, _tag: PhantomData) -> &Self::Foo; } @@ -667,7 +665,7 @@ mod generic_check_components { } expand_has_bar_at(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub trait HasBarAt: HasBarType { fn foo(&self, _tag: PhantomData<(I, J)>) -> &Self::Bar; } @@ -878,7 +876,7 @@ mod generic_check_components { } expand_context(output) { - assert_snapshot!(output, @r#" + insta::assert_snapshot!(output, @r#" impl DelegateComponent for Context { type Delegate = UseType<()>; } diff --git a/crates/tests/cgp-tests/src/tests/delegate_and_check_components.rs b/crates/tests/cgp-tests/src/tests/delegate_and_check_components.rs index 8564ef0d..2e51ee63 100644 --- a/crates/tests/cgp-tests/src/tests/delegate_and_check_components.rs +++ b/crates/tests/cgp-tests/src/tests/delegate_and_check_components.rs @@ -3,7 +3,6 @@ mod basic_delegate_and_check_components { use cgp::prelude::*; use cgp_macro_test_util::snapshot_cgp_getter; - use insta::assert_snapshot; #[cgp_type] pub trait HasNameType { @@ -17,7 +16,7 @@ mod basic_delegate_and_check_components { } expand_has_name(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub trait HasName: HasNameType { fn name(&self) -> &Self::Name; } @@ -178,7 +177,6 @@ mod basic_delegate_and_check_components { mod generic_delegate_and_check_components { use cgp::prelude::*; use cgp_macro_test_util::snapshot_cgp_getter; - use insta::assert_snapshot; #[cgp_type] pub trait HasNameType { @@ -192,7 +190,7 @@ mod generic_delegate_and_check_components { } expand_has_name(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub trait HasName: HasNameType { fn name(&self) -> &Self::Name; } diff --git a/crates/tests/cgp-tests/src/tests/has_field/chain.rs b/crates/tests/cgp-tests/src/tests/has_field/chain.rs index 03721e79..9b003809 100644 --- a/crates/tests/cgp-tests/src/tests/has_field/chain.rs +++ b/crates/tests/cgp-tests/src/tests/has_field/chain.rs @@ -80,7 +80,6 @@ mod deeply_nested_getter { use cgp::core::field::impls::ChainGetters; use cgp::prelude::*; use cgp_macro_test_util::snapshot_cgp_getter; - use insta::assert_snapshot; #[derive(HasField)] pub struct A { @@ -114,7 +113,7 @@ mod deeply_nested_getter { } expand_has_name(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub trait HasName { fn name(&self) -> &str; } diff --git a/crates/tests/cgp-tests/src/tests/use_delegate/getter.rs b/crates/tests/cgp-tests/src/tests/use_delegate/getter.rs index 420abf51..1020f44c 100644 --- a/crates/tests/cgp-tests/src/tests/use_delegate/getter.rs +++ b/crates/tests/cgp-tests/src/tests/use_delegate/getter.rs @@ -2,7 +2,6 @@ use core::marker::PhantomData; use cgp::prelude::*; use cgp_macro_test_util::snapshot_cgp_getter; -use insta::assert_snapshot; pub struct UseDelegate2(pub PhantomData); @@ -30,7 +29,7 @@ snapshot_cgp_getter! { } expand_has_foo_at(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub trait HasFooAt: HasFooTypeAt { fn foo_at(&self, _tag: PhantomData<(I, J)>) -> &Self::Foo; } @@ -344,7 +343,6 @@ mod derive_delegate2 { use cgp::prelude::*; use cgp_macro_test_util::snapshot_delegate_components; - use insta::assert_snapshot; use super::*; @@ -373,7 +371,7 @@ mod derive_delegate2 { } expand_my_context(output) { - assert_snapshot!(output, @r#" + insta::assert_snapshot!(output, @r#" pub struct FooTypes; pub struct FooGetters; impl DelegateComponent for MyContext { diff --git a/crates/tests/cgp-tests/tests/cgp_fn_tests/async.rs b/crates/tests/cgp-tests/tests/cgp_fn_tests/async.rs index f04ba8cb..b3647e80 100644 --- a/crates/tests/cgp-tests/tests/cgp_fn_tests/async.rs +++ b/crates/tests/cgp-tests/tests/cgp_fn_tests/async.rs @@ -1,6 +1,5 @@ use cgp::prelude::*; use cgp_macro_test_util::snapshot_cgp_fn; -use insta::assert_snapshot; snapshot_cgp_fn! { #[cgp_fn] @@ -10,7 +9,7 @@ snapshot_cgp_fn! { } expand_greet(output) { - assert_snapshot!(output, @r#" + insta::assert_snapshot!(output, @r#" #[async_trait] pub trait Greet { async fn greet(&self) -> String; diff --git a/crates/tests/cgp-tests/tests/cgp_fn_tests/basic.rs b/crates/tests/cgp-tests/tests/cgp_fn_tests/basic.rs index a735e495..7a89d3f8 100644 --- a/crates/tests/cgp-tests/tests/cgp_fn_tests/basic.rs +++ b/crates/tests/cgp-tests/tests/cgp_fn_tests/basic.rs @@ -1,6 +1,5 @@ use cgp::prelude::*; use cgp_macro_test_util::snapshot_cgp_fn; -use insta::assert_snapshot; snapshot_cgp_fn! { #[cgp_fn] @@ -9,7 +8,7 @@ snapshot_cgp_fn! { } expand_greet(output) { - assert_snapshot!(output, @r#" + insta::assert_snapshot!(output, @r#" pub trait Greet { fn greet(&self); } @@ -50,7 +49,7 @@ snapshot_cgp_fn! { } expand_rectangle_area(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub trait CanCalculateRectangleArea { fn rectangle_area(&self) -> f64; } diff --git a/crates/tests/cgp-tests/tests/cgp_fn_tests/call.rs b/crates/tests/cgp-tests/tests/cgp_fn_tests/call.rs index acde29f6..2eb15da6 100644 --- a/crates/tests/cgp-tests/tests/cgp_fn_tests/call.rs +++ b/crates/tests/cgp-tests/tests/cgp_fn_tests/call.rs @@ -1,6 +1,5 @@ use cgp::prelude::*; use cgp_macro_test_util::snapshot_cgp_fn; -use insta::assert_snapshot; snapshot_cgp_fn! { #[cgp_fn] @@ -9,7 +8,7 @@ snapshot_cgp_fn! { } expand_rectangle_area(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub trait RectangleArea { fn rectangle_area(&self) -> f64; } @@ -74,7 +73,7 @@ snapshot_cgp_fn! { } expand_scaled_rectangle_area(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub trait ScaledRectangleArea { fn scaled_rectangle_area(&self) -> f64; } diff --git a/crates/tests/cgp-tests/tests/cgp_fn_tests/extend.rs b/crates/tests/cgp-tests/tests/cgp_fn_tests/extend.rs index b2eb9075..9ad795a0 100644 --- a/crates/tests/cgp-tests/tests/cgp_fn_tests/extend.rs +++ b/crates/tests/cgp-tests/tests/cgp_fn_tests/extend.rs @@ -2,7 +2,6 @@ use std::ops::Mul; use cgp::prelude::*; use cgp_macro_test_util::snapshot_cgp_fn; -use insta::assert_snapshot; #[cgp_type] pub trait HasScalarType { @@ -24,7 +23,7 @@ snapshot_cgp_fn! { } expand_rectangle_area(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub trait RectangleArea: HasScalarType { fn rectangle_area(&self) -> Self::Scalar; } diff --git a/crates/tests/cgp-tests/tests/cgp_fn_tests/foreign_type.rs b/crates/tests/cgp-tests/tests/cgp_fn_tests/foreign_type.rs index 4b22f5a4..ad6d2ff4 100644 --- a/crates/tests/cgp-tests/tests/cgp_fn_tests/foreign_type.rs +++ b/crates/tests/cgp-tests/tests/cgp_fn_tests/foreign_type.rs @@ -2,7 +2,6 @@ use std::ops::Mul; use cgp::prelude::*; use cgp_macro_test_util::snapshot_cgp_fn; -use insta::assert_snapshot; #[cgp_type] pub trait HasScalarType { @@ -25,7 +24,7 @@ snapshot_cgp_fn! { } expand_rectangle_area(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub trait RectangleArea { fn rectangle_area(&self) -> ::Scalar; } diff --git a/crates/tests/cgp-tests/tests/cgp_fn_tests/foreign_type_equality.rs b/crates/tests/cgp-tests/tests/cgp_fn_tests/foreign_type_equality.rs index 374ea8a1..e160bef6 100644 --- a/crates/tests/cgp-tests/tests/cgp_fn_tests/foreign_type_equality.rs +++ b/crates/tests/cgp-tests/tests/cgp_fn_tests/foreign_type_equality.rs @@ -1,6 +1,5 @@ use cgp::prelude::*; use cgp_macro_test_util::snapshot_cgp_fn; -use insta::assert_snapshot; #[cgp_type] pub trait HasScalarType { @@ -24,7 +23,7 @@ snapshot_cgp_fn! { } expand_rectangle_area(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub trait RectangleArea: HasTypes { fn rectangle_area(&self) -> <::Types as HasScalarType>::Scalar; } @@ -98,7 +97,7 @@ snapshot_cgp_fn! { } expand_do_foo(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub trait DoFoo: HasFooType { fn do_foo(&self) -> ::Foo; } @@ -122,7 +121,7 @@ snapshot_cgp_fn! { } expand_do_bar(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub trait DoBar: HasBarType { fn do_bar(&self) -> <::Bar as HasFooType>::Foo; } @@ -158,7 +157,7 @@ snapshot_cgp_fn! { } expand_return_foo_or_bar(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" trait ReturnFooOrBar: HasFooType + HasBarType { fn return_foo_or_bar(&self, flag: bool) -> ::Foo; } diff --git a/crates/tests/cgp-tests/tests/cgp_fn_tests/generics.rs b/crates/tests/cgp-tests/tests/cgp_fn_tests/generics.rs index 33e4cc8d..c9f1a0e9 100644 --- a/crates/tests/cgp-tests/tests/cgp_fn_tests/generics.rs +++ b/crates/tests/cgp-tests/tests/cgp_fn_tests/generics.rs @@ -2,7 +2,6 @@ use std::ops::Mul; use cgp::prelude::*; use cgp_macro_test_util::snapshot_cgp_fn; -use insta::assert_snapshot; snapshot_cgp_fn! { #[cgp_fn] @@ -18,7 +17,7 @@ snapshot_cgp_fn! { } expand_rectangle_area(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub trait RectangleArea { fn rectangle_area(&self) -> Scalar; } diff --git a/crates/tests/cgp-tests/tests/cgp_fn_tests/impl_generics.rs b/crates/tests/cgp-tests/tests/cgp_fn_tests/impl_generics.rs index c2ccf343..af4bae12 100644 --- a/crates/tests/cgp-tests/tests/cgp_fn_tests/impl_generics.rs +++ b/crates/tests/cgp-tests/tests/cgp_fn_tests/impl_generics.rs @@ -2,7 +2,6 @@ use core::fmt::Display; use cgp::prelude::*; use cgp_macro_test_util::snapshot_cgp_fn; -use insta::assert_snapshot; snapshot_cgp_fn! { #[cgp_fn] @@ -15,7 +14,7 @@ snapshot_cgp_fn! { } expand_greet(output) { - assert_snapshot!(output, @r#" + insta::assert_snapshot!(output, @r#" pub trait Greet { fn greet(&self) -> String; } @@ -49,7 +48,7 @@ snapshot_cgp_fn! { } expand_test_greet(output) { - assert_snapshot!(output, @r#" + insta::assert_snapshot!(output, @r#" pub trait TestGreet { fn test_greet(&self); } diff --git a/crates/tests/cgp-tests/tests/cgp_fn_tests/multi.rs b/crates/tests/cgp-tests/tests/cgp_fn_tests/multi.rs index 7eadb01b..6771f485 100644 --- a/crates/tests/cgp-tests/tests/cgp_fn_tests/multi.rs +++ b/crates/tests/cgp-tests/tests/cgp_fn_tests/multi.rs @@ -2,7 +2,6 @@ use core::fmt::Display; use cgp::prelude::*; use cgp_macro_test_util::snapshot_cgp_fn; -use insta::assert_snapshot; pub trait HasFooType { type Foo; @@ -34,7 +33,7 @@ snapshot_cgp_fn! { } expand_do_foo_bar(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" #[allow(unused)] #[async_trait] pub trait DoFooBar: HasFooType + HasFooType + HasBarType { diff --git a/crates/tests/cgp-tests/tests/cgp_fn_tests/mutable.rs b/crates/tests/cgp-tests/tests/cgp_fn_tests/mutable.rs index efe8a7bd..36b96b43 100644 --- a/crates/tests/cgp-tests/tests/cgp_fn_tests/mutable.rs +++ b/crates/tests/cgp-tests/tests/cgp_fn_tests/mutable.rs @@ -1,6 +1,5 @@ use cgp::prelude::*; use cgp_macro_test_util::snapshot_cgp_fn; -use insta::assert_snapshot; snapshot_cgp_fn! { #[cgp_fn] @@ -15,7 +14,7 @@ snapshot_cgp_fn! { } expand_capitalize_name(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub trait CapitalizeName { fn capitalize_name(&mut self); } diff --git a/crates/tests/cgp-tests/tests/cgp_fn_tests/nested_foreign_type.rs b/crates/tests/cgp-tests/tests/cgp_fn_tests/nested_foreign_type.rs index 19807be8..db802328 100644 --- a/crates/tests/cgp-tests/tests/cgp_fn_tests/nested_foreign_type.rs +++ b/crates/tests/cgp-tests/tests/cgp_fn_tests/nested_foreign_type.rs @@ -2,7 +2,6 @@ use std::ops::Mul; use cgp::prelude::*; use cgp_macro_test_util::snapshot_cgp_fn; -use insta::assert_snapshot; #[cgp_type] pub trait HasScalarType { @@ -27,7 +26,7 @@ snapshot_cgp_fn! { } expand_rectangle_area(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub trait RectangleArea: HasTypes where ::Types: HasScalarType, diff --git a/crates/tests/cgp-tests/tests/cgp_fn_tests/type_equality.rs b/crates/tests/cgp-tests/tests/cgp_fn_tests/type_equality.rs index 946cfbe9..642fa78c 100644 --- a/crates/tests/cgp-tests/tests/cgp_fn_tests/type_equality.rs +++ b/crates/tests/cgp-tests/tests/cgp_fn_tests/type_equality.rs @@ -2,7 +2,6 @@ use std::fmt::Display; use cgp::prelude::*; use cgp_macro_test_util::snapshot_cgp_fn; -use insta::assert_snapshot; #[cgp_type] pub trait HasScalarType { @@ -18,7 +17,7 @@ snapshot_cgp_fn! { } expand_rectangle_area(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub trait RectangleArea: HasScalarType { fn rectangle_area(&self) -> ::Scalar; } @@ -93,7 +92,7 @@ snapshot_cgp_fn! { } expand_do_foo(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub trait DoFoo: HasFooType { fn do_foo(&self) -> ::Foo; } @@ -117,7 +116,7 @@ snapshot_cgp_fn! { } expand_do_bar(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub trait DoBar: HasBarType { fn do_bar(&self) -> ::Bar; } @@ -148,7 +147,7 @@ snapshot_cgp_fn! { } expand_return_foo_or_bar(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" trait ReturnFooOrBar: HasBarType + HasFooType { fn return_foo_or_bar(&self, flag: bool) -> ::Foo; } diff --git a/crates/tests/cgp-tests/tests/cgp_fn_tests/use_provider.rs b/crates/tests/cgp-tests/tests/cgp_fn_tests/use_provider.rs index d964ba89..e44eaaff 100644 --- a/crates/tests/cgp-tests/tests/cgp_fn_tests/use_provider.rs +++ b/crates/tests/cgp-tests/tests/cgp_fn_tests/use_provider.rs @@ -1,6 +1,5 @@ use cgp::prelude::*; use cgp_macro_test_util::{snapshot_cgp_component, snapshot_cgp_fn, snapshot_cgp_impl}; -use insta::assert_snapshot; snapshot_cgp_component! { #[cgp_component(AreaCalculator)] @@ -9,7 +8,7 @@ snapshot_cgp_component! { } expand_can_calculate_area(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub trait CanCalculateArea { fn area(&self) -> f64; } @@ -91,7 +90,7 @@ snapshot_cgp_impl! { } expand_rectangle_area_calculator(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" impl<__Context__> AreaCalculator<__Context__> for RectangleAreaCalculator where __Context__: HasField< @@ -170,7 +169,7 @@ snapshot_cgp_fn! { } expand_rectangle_area(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" trait RectangleArea { fn rectangle_area(&self) -> f64; } diff --git a/crates/tests/cgp-tests/tests/cgp_fn_tests/use_type.rs b/crates/tests/cgp-tests/tests/cgp_fn_tests/use_type.rs index 87c00ced..3c11d95f 100644 --- a/crates/tests/cgp-tests/tests/cgp_fn_tests/use_type.rs +++ b/crates/tests/cgp-tests/tests/cgp_fn_tests/use_type.rs @@ -3,7 +3,6 @@ use std::ops::Mul; use cgp::prelude::*; use cgp_macro_test_util::snapshot_cgp_fn; -use insta::assert_snapshot; #[cgp_type] pub trait HasScalarType { @@ -22,7 +21,7 @@ snapshot_cgp_fn! { } expand_rectangle_area(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub trait RectangleArea: HasScalarType { fn rectangle_area(&self) -> Self::Scalar; } diff --git a/crates/tests/cgp-tests/tests/cgp_fn_tests/use_type_alias.rs b/crates/tests/cgp-tests/tests/cgp_fn_tests/use_type_alias.rs index 48742b36..9c80e765 100644 --- a/crates/tests/cgp-tests/tests/cgp_fn_tests/use_type_alias.rs +++ b/crates/tests/cgp-tests/tests/cgp_fn_tests/use_type_alias.rs @@ -2,7 +2,6 @@ use std::ops::Mul; use cgp::prelude::*; use cgp_macro_test_util::snapshot_cgp_fn; -use insta::assert_snapshot; #[cgp_type] pub trait HasScalarType { @@ -21,7 +20,7 @@ snapshot_cgp_fn! { } expand_rectangle_area(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub trait RectangleArea: HasScalarType { fn rectangle_area(&self) -> ::Scalar; } diff --git a/crates/tests/cgp-tests/tests/cgp_fn_tests/uses.rs b/crates/tests/cgp-tests/tests/cgp_fn_tests/uses.rs index 54d1bba9..1daf1fbd 100644 --- a/crates/tests/cgp-tests/tests/cgp_fn_tests/uses.rs +++ b/crates/tests/cgp-tests/tests/cgp_fn_tests/uses.rs @@ -1,6 +1,5 @@ use cgp::prelude::*; use cgp_macro_test_util::snapshot_cgp_fn; -use insta::assert_snapshot; snapshot_cgp_fn! { #[cgp_fn] @@ -9,7 +8,7 @@ snapshot_cgp_fn! { } expand_rectangle_area(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub trait RectangleArea { fn rectangle_area(&self) -> f64; } @@ -72,7 +71,7 @@ snapshot_cgp_fn! { } expand_scaled_rectangle_area(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub trait ScaledRectangleArea { fn scaled_rectangle_area(&self) -> f64; } diff --git a/crates/tests/cgp-tests/tests/component_tests/cgp_component/default_impl.rs b/crates/tests/cgp-tests/tests/component_tests/cgp_component/default_impl.rs index a5498f37..971edfe2 100644 --- a/crates/tests/cgp-tests/tests/component_tests/cgp_component/default_impl.rs +++ b/crates/tests/cgp-tests/tests/component_tests/cgp_component/default_impl.rs @@ -1,6 +1,5 @@ use cgp::prelude::*; use cgp_macro_test_util::snapshot_cgp_component; -use insta::assert_snapshot; #[cgp_getter] pub trait HasName { @@ -18,7 +17,7 @@ snapshot_cgp_component! { } expand_can_greet(output) { - assert_snapshot!(output, @r#" + insta::assert_snapshot!(output, @r#" pub trait CanGreet: HasName { fn greet(&self) -> String { format!("Hello, {}!", self.name()) diff --git a/crates/tests/cgp-tests/tests/component_tests/cgp_component/lifetime.rs b/crates/tests/cgp-tests/tests/component_tests/cgp_component/lifetime.rs index fdb6bee3..1085b31e 100644 --- a/crates/tests/cgp-tests/tests/component_tests/cgp_component/lifetime.rs +++ b/crates/tests/cgp-tests/tests/component_tests/cgp_component/lifetime.rs @@ -1,6 +1,5 @@ use cgp::prelude::*; use cgp_macro_test_util::snapshot_cgp_component; -use insta::assert_snapshot; snapshot_cgp_component! { #[cgp_component(ReferenceGetter)] @@ -9,7 +8,7 @@ snapshot_cgp_component! { } expand_can_greet(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub trait HasReference<'a, T: 'a + ?Sized> { fn get_reference(&self) -> &'a T; } diff --git a/crates/tests/cgp-tests/tests/component_tests/cgp_impl/basic.rs b/crates/tests/cgp-tests/tests/component_tests/cgp_impl/basic.rs index c8b78887..b2ee00ef 100644 --- a/crates/tests/cgp-tests/tests/component_tests/cgp_impl/basic.rs +++ b/crates/tests/cgp-tests/tests/component_tests/cgp_impl/basic.rs @@ -1,5 +1,4 @@ use cgp_macro_test_util::{snapshot_cgp_auto_getter, snapshot_cgp_component, snapshot_cgp_impl}; -use insta::assert_snapshot; snapshot_cgp_component! { #[cgp_component(FooProvider)] @@ -8,7 +7,7 @@ snapshot_cgp_component! { } expand_foo_component(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub trait CanDoFoo { fn foo(&self, value: u32) -> String; } @@ -88,7 +87,7 @@ snapshot_cgp_auto_getter! { } expand_has_name(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub trait HasName { fn name(&self) -> &str; } @@ -121,7 +120,7 @@ snapshot_cgp_impl! { } expand_value_to_string(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" impl FooProvider for ValueToString { fn foo(__context__: &Context, value: u32) -> String { value.to_string() diff --git a/crates/tests/cgp-tests/tests/component_tests/cgp_impl/implicit_args/import.rs b/crates/tests/cgp-tests/tests/component_tests/cgp_impl/implicit_args/import.rs index 2e7cd915..58c566b1 100644 --- a/crates/tests/cgp-tests/tests/component_tests/cgp_impl/implicit_args/import.rs +++ b/crates/tests/cgp-tests/tests/component_tests/cgp_impl/implicit_args/import.rs @@ -1,6 +1,5 @@ use cgp::prelude::*; use cgp_macro_test_util::snapshot_cgp_fn; -use insta::assert_snapshot; #[cgp_component(AreaCalculator)] pub trait CanCalculateArea { @@ -22,7 +21,7 @@ snapshot_cgp_fn! { } expand_rectangle_area(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub trait RectangleArea { fn rectangle_area(&self) -> f64; } diff --git a/crates/tests/cgp-tests/tests/component_tests/cgp_impl/shape.rs b/crates/tests/cgp-tests/tests/component_tests/cgp_impl/shape.rs index 98f25abc..24c5b9a4 100644 --- a/crates/tests/cgp-tests/tests/component_tests/cgp_impl/shape.rs +++ b/crates/tests/cgp-tests/tests/component_tests/cgp_impl/shape.rs @@ -2,7 +2,6 @@ use core::f64::consts::PI; use cgp::prelude::*; use cgp_macro_test_util::snapshot_cgp_fn; -use insta::assert_snapshot; snapshot_cgp_fn! { #[cgp_fn] @@ -11,7 +10,7 @@ snapshot_cgp_fn! { } expand_rectangle_area(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub trait RectangleArea { fn rectangle_area(&self) -> f64; } @@ -73,7 +72,7 @@ snapshot_cgp_fn! { } expand_circle_area(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub trait CircleArea { fn circle_area(&self) -> f64; } diff --git a/crates/tests/cgp-tests/tests/component_tests/delegate_components/direct.rs b/crates/tests/cgp-tests/tests/component_tests/delegate_components/direct.rs index b4f7f312..158ec76c 100644 --- a/crates/tests/cgp-tests/tests/component_tests/delegate_components/direct.rs +++ b/crates/tests/cgp-tests/tests/component_tests/delegate_components/direct.rs @@ -1,6 +1,5 @@ use cgp::prelude::*; use cgp_macro_test_util::snapshot_delegate_components; -use insta::assert_snapshot; snapshot_delegate_components! { delegate_components! { @@ -11,7 +10,7 @@ snapshot_delegate_components! { } expand_foo_component(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub struct FooComponents; impl DelegateComponent> for FooComponents { type Delegate = u64; @@ -44,7 +43,7 @@ snapshot_delegate_components! { } expand_bar_component(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub struct BarComponents; impl DelegateComponent> for BarComponents { type Delegate = FooComponents; diff --git a/crates/tests/cgp-tests/tests/component_tests/delegate_components/general.rs b/crates/tests/cgp-tests/tests/component_tests/delegate_components/general.rs index 2a8dc554..76cbb9b5 100644 --- a/crates/tests/cgp-tests/tests/component_tests/delegate_components/general.rs +++ b/crates/tests/cgp-tests/tests/component_tests/delegate_components/general.rs @@ -26,7 +26,7 @@ mod test_basic_delegate_components { } expand_components(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" impl DelegateComponent for Components { type Delegate = FooValue; } @@ -93,7 +93,7 @@ mod test_generic_delegate_components { } } expand_components(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" impl<'a, T1: Clone> DelegateComponent> for Components { type Delegate = FooValue; } diff --git a/crates/tests/cgp-tests/tests/extensible_data_tests/records/basic.rs b/crates/tests/cgp-tests/tests/extensible_data_tests/records/basic.rs index 0b0e52c0..fa93bbcc 100644 --- a/crates/tests/cgp-tests/tests/extensible_data_tests/records/basic.rs +++ b/crates/tests/cgp-tests/tests/extensible_data_tests/records/basic.rs @@ -7,7 +7,6 @@ use cgp::extra::dispatch::{BuildAndMerge, BuildAndSetField, BuildWithHandlers}; use cgp::extra::handler::{Computer, Producer, ProducerComponent}; use cgp::prelude::*; use cgp_macro_test_util::snapshot_delegate_components; -use insta::assert_snapshot; #[derive(Debug, Eq, PartialEq, CgpData)] pub struct FooBarBaz { @@ -92,7 +91,7 @@ snapshot_delegate_components! { } expand_app(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" impl DelegateComponent for App { type Delegate = UseType; } diff --git a/crates/tests/cgp-tests/tests/extensible_data_tests/variants/basic.rs b/crates/tests/cgp-tests/tests/extensible_data_tests/variants/basic.rs index 3ebad849..1781bb62 100644 --- a/crates/tests/cgp-tests/tests/extensible_data_tests/variants/basic.rs +++ b/crates/tests/cgp-tests/tests/extensible_data_tests/variants/basic.rs @@ -14,7 +14,6 @@ use cgp::extra::handler::{ use cgp::prelude::*; use cgp_macro_test_util::snapshot_delegate_components; use futures::executor::block_on; -use insta::assert_snapshot; #[derive(Debug, Eq, PartialEq, CgpData)] pub enum FooBarBaz { @@ -137,7 +136,7 @@ snapshot_delegate_components! { } expand_app(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" impl DelegateComponent for App { type Delegate = UseType; } diff --git a/crates/tests/cgp-tests/tests/extensible_data_tests/variants/shape.rs b/crates/tests/cgp-tests/tests/extensible_data_tests/variants/shape.rs index 782fa19a..d3bc4f8a 100644 --- a/crates/tests/cgp-tests/tests/extensible_data_tests/variants/shape.rs +++ b/crates/tests/cgp-tests/tests/extensible_data_tests/variants/shape.rs @@ -9,7 +9,6 @@ use cgp::extra::dispatch::{ use cgp::extra::handler::{NoCode, UseInputDelegate}; use cgp::prelude::*; use cgp_macro_test_util::snapshot_delegate_components; -use insta::assert_snapshot; #[derive(Debug, PartialEq, CgpData)] pub enum Shape { @@ -208,7 +207,7 @@ snapshot_delegate_components! { } expand_app(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub struct AreaComputers; impl DelegateComponent for App { type Delegate = UseInputDelegate; diff --git a/crates/tests/cgp-tests/tests/getter_tests/abstract_type/explicit.rs b/crates/tests/cgp-tests/tests/getter_tests/abstract_type/explicit.rs index 53276ebd..05dce299 100644 --- a/crates/tests/cgp-tests/tests/getter_tests/abstract_type/explicit.rs +++ b/crates/tests/cgp-tests/tests/getter_tests/abstract_type/explicit.rs @@ -1,6 +1,5 @@ use cgp::prelude::*; use cgp_macro_test_util::{snapshot_cgp_auto_getter, snapshot_cgp_getter}; -use insta::assert_snapshot; #[cgp_type] pub trait HasScalarType { @@ -17,7 +16,7 @@ snapshot_cgp_auto_getter! { } expand_auto_rectangle_fields(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub trait AutoRectangleFields: HasScalarType { fn width(&self) -> Self::Scalar; fn height(&self) -> Self::Scalar; @@ -80,7 +79,7 @@ snapshot_cgp_getter! { } expand_has_rectangle_fields(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub trait HasRectangleFields: HasScalarType { fn width(&self) -> Self::Scalar; fn height(&self) -> Self::Scalar; diff --git a/crates/tests/cgp-tests/tests/getter_tests/abstract_type/import.rs b/crates/tests/cgp-tests/tests/getter_tests/abstract_type/import.rs index b94a9830..7c60cd05 100644 --- a/crates/tests/cgp-tests/tests/getter_tests/abstract_type/import.rs +++ b/crates/tests/cgp-tests/tests/getter_tests/abstract_type/import.rs @@ -1,6 +1,5 @@ use cgp::prelude::*; use cgp_macro_test_util::{snapshot_cgp_auto_getter, snapshot_cgp_getter}; -use insta::assert_snapshot; #[cgp_type] pub trait HasScalarType { @@ -17,7 +16,7 @@ snapshot_cgp_auto_getter! { } expand_auto_rectangle_fields(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub trait AutoRectangleFields: HasScalarType { fn width(&self) -> ::Scalar; fn height(&self) -> ::Scalar; @@ -80,7 +79,7 @@ snapshot_cgp_getter! { } expand_has_rectangle_fields(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub trait HasRectangleFields: HasScalarType { fn width(&self) -> ::Scalar; fn height(&self) -> ::Scalar; diff --git a/crates/tests/cgp-tests/tests/getter_tests/abstract_type/use_type.rs b/crates/tests/cgp-tests/tests/getter_tests/abstract_type/use_type.rs index b94a9830..7c60cd05 100644 --- a/crates/tests/cgp-tests/tests/getter_tests/abstract_type/use_type.rs +++ b/crates/tests/cgp-tests/tests/getter_tests/abstract_type/use_type.rs @@ -1,6 +1,5 @@ use cgp::prelude::*; use cgp_macro_test_util::{snapshot_cgp_auto_getter, snapshot_cgp_getter}; -use insta::assert_snapshot; #[cgp_type] pub trait HasScalarType { @@ -17,7 +16,7 @@ snapshot_cgp_auto_getter! { } expand_auto_rectangle_fields(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub trait AutoRectangleFields: HasScalarType { fn width(&self) -> ::Scalar; fn height(&self) -> ::Scalar; @@ -80,7 +79,7 @@ snapshot_cgp_getter! { } expand_has_rectangle_fields(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub trait HasRectangleFields: HasScalarType { fn width(&self) -> ::Scalar; fn height(&self) -> ::Scalar; diff --git a/crates/tests/cgp-tests/tests/getter_tests/assoc_type/auto_getter.rs b/crates/tests/cgp-tests/tests/getter_tests/assoc_type/auto_getter.rs index a44b10e4..28c20431 100644 --- a/crates/tests/cgp-tests/tests/getter_tests/assoc_type/auto_getter.rs +++ b/crates/tests/cgp-tests/tests/getter_tests/assoc_type/auto_getter.rs @@ -2,7 +2,6 @@ use core::fmt::Display; use cgp::prelude::*; use cgp_macro_test_util::snapshot_cgp_auto_getter; -use insta::assert_snapshot; snapshot_cgp_auto_getter! { #[cgp_auto_getter] @@ -13,7 +12,7 @@ snapshot_cgp_auto_getter! { } expand_has_name(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub trait HasName { type Name: Display; fn name(&self) -> &Self::Name; diff --git a/crates/tests/cgp-tests/tests/getter_tests/assoc_type/getter.rs b/crates/tests/cgp-tests/tests/getter_tests/assoc_type/getter.rs index da51827d..6b5abdae 100644 --- a/crates/tests/cgp-tests/tests/getter_tests/assoc_type/getter.rs +++ b/crates/tests/cgp-tests/tests/getter_tests/assoc_type/getter.rs @@ -2,7 +2,6 @@ use core::ops::Mul; use cgp::prelude::*; use cgp_macro_test_util::{snapshot_cgp_getter, snapshot_delegate_components}; -use insta::assert_snapshot; snapshot_cgp_getter! { #[cgp_getter] @@ -13,7 +12,7 @@ snapshot_cgp_getter! { } expand_has_scalar(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub trait HasScalar { type Scalar: Mul + Clone; fn scalar(&self) -> &Self::Scalar; @@ -189,7 +188,7 @@ snapshot_delegate_components! { } expand_app(output) { - assert_snapshot!(output, @r#" + insta::assert_snapshot!(output, @r#" impl DelegateComponent for App { type Delegate = UseField; } diff --git a/crates/tests/cgp-tests/tests/getter_tests/assoc_type/self_referential.rs b/crates/tests/cgp-tests/tests/getter_tests/assoc_type/self_referential.rs index 2b112180..40abfa1e 100644 --- a/crates/tests/cgp-tests/tests/getter_tests/assoc_type/self_referential.rs +++ b/crates/tests/cgp-tests/tests/getter_tests/assoc_type/self_referential.rs @@ -2,7 +2,6 @@ use core::fmt::Display; use cgp::prelude::*; use cgp_macro_test_util::{snapshot_cgp_getter, snapshot_delegate_components}; -use insta::assert_snapshot; snapshot_cgp_getter! { #[cgp_getter] @@ -13,7 +12,7 @@ snapshot_cgp_getter! { } expand_has_name(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub trait HasName { type Name: Display; fn name(&self) -> &Self::Name; @@ -168,7 +167,7 @@ snapshot_delegate_components! { } expand_person(output) { - assert_snapshot!(output, @r#" + insta::assert_snapshot!(output, @r#" impl DelegateComponent for Person { type Delegate = UseField; } diff --git a/crates/tests/cgp-tests/tests/getter_tests/assoc_type/self_referential_auto.rs b/crates/tests/cgp-tests/tests/getter_tests/assoc_type/self_referential_auto.rs index 58d82337..8ac420c6 100644 --- a/crates/tests/cgp-tests/tests/getter_tests/assoc_type/self_referential_auto.rs +++ b/crates/tests/cgp-tests/tests/getter_tests/assoc_type/self_referential_auto.rs @@ -2,7 +2,6 @@ use core::ops::Mul; use cgp::prelude::*; use cgp_macro_test_util::snapshot_cgp_auto_getter; -use insta::assert_snapshot; snapshot_cgp_auto_getter! { #[cgp_auto_getter] @@ -13,7 +12,7 @@ snapshot_cgp_auto_getter! { } expand_has_scalar_type(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub trait HasScalarType { type Scalar: Mul + Clone; fn scalar(&self) -> &Self::Scalar; diff --git a/crates/tests/cgp-tests/tests/getter_tests/auto_generics.rs b/crates/tests/cgp-tests/tests/getter_tests/auto_generics.rs index 32295db4..0e68c9c3 100644 --- a/crates/tests/cgp-tests/tests/getter_tests/auto_generics.rs +++ b/crates/tests/cgp-tests/tests/getter_tests/auto_generics.rs @@ -1,6 +1,5 @@ use cgp::prelude::*; use cgp_macro_test_util::snapshot_cgp_auto_getter; -use insta::assert_snapshot; snapshot_cgp_auto_getter! { #[cgp_auto_getter] @@ -9,7 +8,7 @@ snapshot_cgp_auto_getter! { } expand_has_foo(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub trait HasFoo { fn foo(&self, _tag: PhantomData) -> &Foo; } diff --git a/crates/tests/cgp-tests/tests/getter_tests/clone.rs b/crates/tests/cgp-tests/tests/getter_tests/clone.rs index 22a39eb3..0f81c5f7 100644 --- a/crates/tests/cgp-tests/tests/getter_tests/clone.rs +++ b/crates/tests/cgp-tests/tests/getter_tests/clone.rs @@ -1,7 +1,6 @@ mod clone_getter { use cgp::prelude::*; use cgp_macro_test_util::{snapshot_cgp_getter, snapshot_delegate_components}; - use insta::assert_snapshot; #[cgp_type] pub trait HasNameType { @@ -15,7 +14,7 @@ mod clone_getter { } expand_has_name(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub trait HasName: HasNameType { fn name(&self) -> Self::Name; } @@ -175,7 +174,7 @@ mod clone_getter { } expand_app(output) { - assert_snapshot!(output, @r#" + insta::assert_snapshot!(output, @r#" impl DelegateComponent for App { type Delegate = UseType<&'static str>; } @@ -213,7 +212,6 @@ mod clone_getter { mod clone_auto_getter { use cgp::prelude::*; use cgp_macro_test_util::{snapshot_cgp_auto_getter, snapshot_delegate_components}; - use insta::assert_snapshot; #[cgp_type] pub trait HasNameType { @@ -227,7 +225,7 @@ mod clone_auto_getter { } expand_has_name(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub trait HasName: HasNameType { fn name(&self) -> Self::Name; } @@ -265,7 +263,7 @@ mod clone_auto_getter { } expand_app(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" impl DelegateComponent for App { type Delegate = UseType<&'static str>; } diff --git a/crates/tests/cgp-tests/tests/getter_tests/mref.rs b/crates/tests/cgp-tests/tests/getter_tests/mref.rs index 1c6552d7..f703e842 100644 --- a/crates/tests/cgp-tests/tests/getter_tests/mref.rs +++ b/crates/tests/cgp-tests/tests/getter_tests/mref.rs @@ -2,7 +2,6 @@ mod mref_getter { use cgp::core::field::types::MRef; use cgp::prelude::*; use cgp_macro_test_util::{snapshot_cgp_getter, snapshot_delegate_components}; - use insta::assert_snapshot; snapshot_cgp_getter! { #[cgp_getter] @@ -11,7 +10,7 @@ mod mref_getter { } expand_has_foo(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub trait HasFoo { fn foo(&self) -> MRef<'_, String>; } @@ -149,7 +148,7 @@ mod mref_getter { } expand_app(output) { - assert_snapshot!(output, @r#" + insta::assert_snapshot!(output, @r#" impl DelegateComponent for App { type Delegate = UseField; } @@ -174,7 +173,6 @@ mod mref_auto_getter { use cgp::core::field::types::MRef; use cgp::prelude::*; use cgp_macro_test_util::snapshot_cgp_auto_getter; - use insta::assert_snapshot; snapshot_cgp_auto_getter! { #[cgp_auto_getter] @@ -183,7 +181,7 @@ mod mref_auto_getter { } expand_has_foo(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub trait HasFoo { fn foo(&self) -> MRef<'_, String>; } diff --git a/crates/tests/cgp-tests/tests/getter_tests/non_self.rs b/crates/tests/cgp-tests/tests/getter_tests/non_self.rs index 079a1af7..0f9af1dc 100644 --- a/crates/tests/cgp-tests/tests/getter_tests/non_self.rs +++ b/crates/tests/cgp-tests/tests/getter_tests/non_self.rs @@ -1,6 +1,5 @@ use cgp::prelude::*; use cgp_macro_test_util::{snapshot_cgp_getter, snapshot_delegate_components}; -use insta::assert_snapshot; #[cgp_type] pub trait HasFooType { @@ -19,7 +18,7 @@ snapshot_cgp_getter! { } expand_has_foo_bar(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub trait HasFooBar: HasFooType + HasBarType { fn foo_bar(foo: &Self::Foo) -> &Self::Bar; } @@ -215,7 +214,7 @@ snapshot_delegate_components! { } expand_app(output) { - assert_snapshot!(output, @r#" + insta::assert_snapshot!(output, @r#" impl DelegateComponent for App { type Delegate = UseType; } diff --git a/crates/tests/cgp-tests/tests/getter_tests/non_self_auto.rs b/crates/tests/cgp-tests/tests/getter_tests/non_self_auto.rs index 836d4a8d..625bb103 100644 --- a/crates/tests/cgp-tests/tests/getter_tests/non_self_auto.rs +++ b/crates/tests/cgp-tests/tests/getter_tests/non_self_auto.rs @@ -1,6 +1,5 @@ use cgp::prelude::*; use cgp_macro_test_util::{snapshot_cgp_auto_getter, snapshot_delegate_components}; -use insta::assert_snapshot; #[cgp_type] pub trait HasFooType { @@ -19,7 +18,7 @@ snapshot_cgp_auto_getter! { } expand_has_foo_bar(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub trait HasFooBar: HasFooType + HasBarType { fn foo_bar(foo: &Self::Foo) -> &Self::Bar; } @@ -83,7 +82,7 @@ snapshot_delegate_components! { } expand_app(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" impl DelegateComponent for App { type Delegate = UseType; } diff --git a/crates/tests/cgp-tests/tests/getter_tests/option.rs b/crates/tests/cgp-tests/tests/getter_tests/option.rs index b08abac0..b8f626b2 100644 --- a/crates/tests/cgp-tests/tests/getter_tests/option.rs +++ b/crates/tests/cgp-tests/tests/getter_tests/option.rs @@ -1,7 +1,6 @@ mod option_getter { use cgp::prelude::*; use cgp_macro_test_util::{snapshot_cgp_getter, snapshot_delegate_components}; - use insta::assert_snapshot; snapshot_cgp_getter! { #[cgp_getter] @@ -10,7 +9,7 @@ mod option_getter { } expand_has_foo(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub trait HasFoo { fn foo(&self) -> Option<&String>; } @@ -146,7 +145,7 @@ mod option_getter { } expand_app(output) { - assert_snapshot!(output, @r#" + insta::assert_snapshot!(output, @r#" impl DelegateComponent for App { type Delegate = UseField; } @@ -172,7 +171,6 @@ mod option_getter { mod option_auto_getter { use cgp::prelude::*; use cgp_macro_test_util::snapshot_cgp_auto_getter; - use insta::assert_snapshot; snapshot_cgp_auto_getter! { #[cgp_auto_getter] @@ -181,7 +179,7 @@ mod option_auto_getter { } expand_has_foo(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub trait HasFoo { fn foo(&self) -> Option<&String>; } diff --git a/crates/tests/cgp-tests/tests/getter_tests/slice.rs b/crates/tests/cgp-tests/tests/getter_tests/slice.rs index 9d668d04..b6c9f926 100644 --- a/crates/tests/cgp-tests/tests/getter_tests/slice.rs +++ b/crates/tests/cgp-tests/tests/getter_tests/slice.rs @@ -1,7 +1,6 @@ mod slice_getter { use cgp::prelude::*; use cgp_macro_test_util::{snapshot_cgp_getter, snapshot_delegate_components}; - use insta::assert_snapshot; snapshot_cgp_getter! { #[cgp_getter] @@ -10,7 +9,7 @@ mod slice_getter { } expand_has_foo(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub trait HasFoo { fn foo(&self) -> &[u8]; } @@ -154,7 +153,7 @@ mod slice_getter { } expand_app(output) { - assert_snapshot!(output, @r#" + insta::assert_snapshot!(output, @r#" impl DelegateComponent for App { type Delegate = UseField; } @@ -178,7 +177,6 @@ mod slice_getter { mod slice_auto_getter { use cgp::prelude::*; use cgp_macro_test_util::snapshot_cgp_auto_getter; - use insta::assert_snapshot; snapshot_cgp_auto_getter! { #[cgp_auto_getter] @@ -187,7 +185,7 @@ mod slice_auto_getter { } expand_has_foo(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub trait HasFoo { fn foo(&self) -> &[u8]; } diff --git a/crates/tests/cgp-tests/tests/getter_tests/string.rs b/crates/tests/cgp-tests/tests/getter_tests/string.rs index 55c74234..bd94f9bd 100644 --- a/crates/tests/cgp-tests/tests/getter_tests/string.rs +++ b/crates/tests/cgp-tests/tests/getter_tests/string.rs @@ -1,7 +1,6 @@ mod string_getter { use cgp::prelude::*; use cgp_macro_test_util::{snapshot_cgp_getter, snapshot_delegate_components}; - use insta::assert_snapshot; snapshot_cgp_getter! { #[cgp_getter] @@ -10,7 +9,7 @@ mod string_getter { } expand_has_foo(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub trait HasFoo { fn foo(&self) -> &str; } @@ -146,7 +145,7 @@ mod string_getter { } expand_app(output) { - assert_snapshot!(output, @r#" + insta::assert_snapshot!(output, @r#" impl DelegateComponent for App { type Delegate = UseField; } @@ -172,7 +171,6 @@ mod string_getter { mod string_getter_with_custom_name { use cgp::prelude::*; use cgp_macro_test_util::{snapshot_cgp_getter, snapshot_delegate_components}; - use insta::assert_snapshot; snapshot_cgp_getter! { #[cgp_getter(GetString)] @@ -181,7 +179,7 @@ mod string_getter_with_custom_name { } expand_has_foo(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub trait HasFoo { fn foo(&self) -> &str; } @@ -317,7 +315,7 @@ mod string_getter_with_custom_name { } expand_app(output) { - assert_snapshot!(output, @r#" + insta::assert_snapshot!(output, @r#" impl DelegateComponent for App { type Delegate = UseField; } @@ -343,7 +341,6 @@ mod string_getter_with_custom_name { mod string_getter_with_custom_spec { use cgp::prelude::*; use cgp_macro_test_util::{snapshot_cgp_getter, snapshot_delegate_components}; - use insta::assert_snapshot; snapshot_cgp_getter! { #[cgp_getter{ @@ -355,7 +352,7 @@ mod string_getter_with_custom_spec { } expand_has_foo(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub trait HasFoo { fn foo(&self) -> &str; } @@ -482,7 +479,7 @@ mod string_getter_with_custom_spec { } expand_app(output) { - assert_snapshot!(output, @r#" + insta::assert_snapshot!(output, @r#" impl DelegateComponent for App { type Delegate = UseField; } @@ -508,7 +505,6 @@ mod string_getter_with_custom_spec { mod string_auto_getter { use cgp::prelude::*; use cgp_macro_test_util::snapshot_cgp_auto_getter; - use insta::assert_snapshot; snapshot_cgp_auto_getter! { #[cgp_auto_getter] @@ -517,7 +513,7 @@ mod string_auto_getter { } expand_has_foo(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub trait HasFoo { fn foo(&self) -> &str; } diff --git a/crates/tests/cgp-tests/tests/handler_tests/computer_macro.rs b/crates/tests/cgp-tests/tests/handler_tests/computer_macro.rs index a45bd289..deb06236 100644 --- a/crates/tests/cgp-tests/tests/handler_tests/computer_macro.rs +++ b/crates/tests/cgp-tests/tests/handler_tests/computer_macro.rs @@ -6,7 +6,6 @@ use cgp::extra::handler::{ComputerRef, HandlerRef, TryComputerRef}; use cgp::prelude::*; use cgp_macro_test_util::snapshot_delegate_components; use futures::executor::block_on; -use insta::assert_snapshot; #[cgp_computer] fn add(a: u64, b: u64) -> u64 { @@ -31,7 +30,7 @@ snapshot_delegate_components! { } expand_computer_macro_app(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" impl DelegateComponent for App { type Delegate = UseType; } diff --git a/crates/tests/cgp-tests/tests/handler_tests/handler_macro.rs b/crates/tests/cgp-tests/tests/handler_tests/handler_macro.rs index 187d5534..b693cab6 100644 --- a/crates/tests/cgp-tests/tests/handler_tests/handler_macro.rs +++ b/crates/tests/cgp-tests/tests/handler_tests/handler_macro.rs @@ -6,7 +6,6 @@ use cgp::extra::handler::HandlerRef; use cgp::prelude::*; use cgp_macro_test_util::snapshot_delegate_components; use futures::executor::block_on; -use insta::assert_snapshot; #[cgp_computer] async fn add(a: u64, b: u64) -> u64 { @@ -31,7 +30,7 @@ snapshot_delegate_components! { } expand_handler_macro_app(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" impl DelegateComponent for App { type Delegate = UseType; } diff --git a/crates/tests/cgp-tests/tests/handler_tests/pipe.rs b/crates/tests/cgp-tests/tests/handler_tests/pipe.rs index 39795f73..eea3df73 100644 --- a/crates/tests/cgp-tests/tests/handler_tests/pipe.rs +++ b/crates/tests/cgp-tests/tests/handler_tests/pipe.rs @@ -4,7 +4,6 @@ mod pipe_computers { use cgp::extra::handler::{CanCompute, Computer, ComputerComponent, PipeHandlers}; use cgp::prelude::*; use cgp_macro_test_util::snapshot_delegate_components; - use insta::assert_snapshot; #[cgp_new_provider] impl Computer for Multiply @@ -52,7 +51,7 @@ mod pipe_computers { } expand_pipe_computers(output) { - assert_snapshot!(output, @r#" + insta::assert_snapshot!(output, @r#" impl DelegateComponent for MyContext { type Delegate = PipeHandlers< Product![ @@ -107,7 +106,6 @@ mod pipe_handlers { use cgp::prelude::*; use cgp_macro_test_util::snapshot_delegate_components; use futures::executor::block_on; - use insta::assert_snapshot; #[cgp_new_provider] impl Handler for Multiply @@ -160,7 +158,7 @@ mod pipe_handlers { } expand_pipe_handlers(output) { - assert_snapshot!(output, @r#" + insta::assert_snapshot!(output, @r#" impl DelegateComponent for MyContext { type Delegate = UseType; } diff --git a/crates/tests/cgp-tests/tests/handler_tests/producer_macro.rs b/crates/tests/cgp-tests/tests/handler_tests/producer_macro.rs index a88d30e6..b256e0ba 100644 --- a/crates/tests/cgp-tests/tests/handler_tests/producer_macro.rs +++ b/crates/tests/cgp-tests/tests/handler_tests/producer_macro.rs @@ -3,7 +3,6 @@ use cgp::extra::handler::{ComputerRef, HandlerRef, TryComputerRef}; use cgp::prelude::*; use cgp_macro_test_util::snapshot_delegate_components; use futures::executor::block_on; -use insta::assert_snapshot; #[cgp_producer] pub fn magic_number() -> u64 { @@ -21,7 +20,7 @@ snapshot_delegate_components! { } expand_producer_macro_app(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" impl DelegateComponent for App { type Delegate = UseType; } diff --git a/crates/tests/cgp-tests/tests/namespace_tests/multi_param.rs b/crates/tests/cgp-tests/tests/namespace_tests/multi_param.rs index a19fc104..b834a6dc 100644 --- a/crates/tests/cgp-tests/tests/namespace_tests/multi_param.rs +++ b/crates/tests/cgp-tests/tests/namespace_tests/multi_param.rs @@ -2,7 +2,6 @@ use cgp::prelude::*; use cgp_macro_test_util::{ snapshot_cgp_component, snapshot_cgp_impl, snapshot_delegate_components, }; -use insta::assert_snapshot; snapshot_cgp_component! { #[cgp_component(FooProvider)] @@ -12,7 +11,7 @@ snapshot_cgp_component! { } expand_multi_param_foo(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub trait Foo<'a, T, U> { fn foo(&self, first: &'a T, second: U); } @@ -120,7 +119,7 @@ snapshot_cgp_impl! { } expand_multi_param_dummy_foo(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" impl<'a, __Context__, T, U> FooProvider<'a, __Context__, T, U> for DummyFoo { fn foo(__context__: &__Context__, _first: &'a T, _second: U) {} } @@ -150,7 +149,7 @@ snapshot_delegate_components! { } expand_multi_param_app_a(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" impl DelegateComponent for AppA { type Delegate = RedirectLookup>; } @@ -242,7 +241,7 @@ snapshot_delegate_components! { } expand_multi_param_app_b(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" impl<__Key__, __Value__> DelegateComponent<__Key__> for AppB where __Key__: DefaultNamespace, diff --git a/crates/tests/cgp-tests/tests/namespace_tests/namespace.rs b/crates/tests/cgp-tests/tests/namespace_tests/namespace.rs index 56396e1f..6fed3734 100644 --- a/crates/tests/cgp-tests/tests/namespace_tests/namespace.rs +++ b/crates/tests/cgp-tests/tests/namespace_tests/namespace.rs @@ -2,7 +2,6 @@ use cgp::core::error::{ErrorRaiserComponent, ErrorTypeProviderComponent}; use cgp::extra::error::ReturnError; use cgp::prelude::*; use cgp_macro_test_util::{snapshot_cgp_component, snapshot_delegate_components}; -use insta::assert_snapshot; pub struct MyComponents; @@ -14,7 +13,7 @@ snapshot_cgp_component! { } expand_namespace_foo(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub trait Foo { fn foo(&self); } @@ -112,7 +111,7 @@ snapshot_delegate_components! { } expand_namespace_app(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" impl<__Key__, __Value__> DelegateComponent<__Key__> for App where __Key__: DefaultNamespace, diff --git a/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/basic.rs b/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/basic.rs index 874d9d2f..7fc3c4ed 100644 --- a/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/basic.rs +++ b/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/basic.rs @@ -2,7 +2,6 @@ use cgp::prelude::*; use cgp_macro_test_util::{ snapshot_cgp_component, snapshot_cgp_impl, snapshot_delegate_components, }; -use insta::assert_snapshot; snapshot_cgp_component! { #[cgp_component(FooProvider)] @@ -11,7 +10,7 @@ snapshot_cgp_component! { } expand_basic_foo(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub trait Foo { fn foo(&self); } @@ -97,7 +96,7 @@ snapshot_cgp_component! { } expand_basic_bar(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub trait Bar { fn bar(&self); } @@ -184,7 +183,7 @@ snapshot_cgp_impl! { } expand_basic_dummy_foo(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" impl<__Context__> FooProvider<__Context__> for DummyFoo { fn foo(__context__: &__Context__) {} } @@ -201,7 +200,7 @@ snapshot_cgp_impl! { } expand_basic_dummy_bar(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" impl<__Context__> BarProvider<__Context__> for DummyBar { fn bar(__context__: &__Context__) {} } @@ -226,7 +225,7 @@ snapshot_delegate_components! { } expand_basic_app(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" impl<__Key__, __Value__> DelegateComponent<__Key__> for App where __Key__: MyNamespace, diff --git a/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/default_impls.rs b/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/default_impls.rs index faaad3ce..456b2f53 100644 --- a/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/default_impls.rs +++ b/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/default_impls.rs @@ -4,7 +4,6 @@ use cgp_macro_test_util::snapshot_delegate_components; use cgp_tests::namespaces::default_impls::{ DefaultShowComponents, ExtendedNamespace, ShowImplComponent, ShowWithDisplay, }; -use insta::assert_snapshot; pub struct AppA; @@ -23,7 +22,7 @@ snapshot_delegate_components! { } expand_default_impls_app_a(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" impl<__Key__, __Value__> DelegateComponent<__Key__> for AppA where __Key__: DefaultNamespace, @@ -139,7 +138,7 @@ snapshot_delegate_components! { } expand_default_impls_app_b(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" impl<__Key__, __Value__> DelegateComponent<__Key__> for AppB where __Key__: DefaultNamespace, @@ -226,7 +225,7 @@ snapshot_delegate_components! { } expand_default_impls_app_c(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" impl<__Key__, __Value__> DelegateComponent<__Key__> for AppC where __Key__: ExtendedNamespace, diff --git a/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/extended_namespace.rs b/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/extended_namespace.rs index b3887d73..7d067728 100644 --- a/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/extended_namespace.rs +++ b/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/extended_namespace.rs @@ -4,7 +4,6 @@ use cgp::extra::handler::CanTryCompute; use cgp::prelude::*; use cgp_macro_test_util::snapshot_delegate_components; use cgp_tests::namespaces::extended::ExtendedNamespace; -use insta::assert_snapshot; pub struct App; @@ -26,7 +25,7 @@ snapshot_delegate_components! { } expand_extended_ns_app(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" impl<__Key__, __Value__> DelegateComponent<__Key__> for App where __Key__: ExtendedNamespace, diff --git a/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/multi_namespace.rs b/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/multi_namespace.rs index 4a6fd9b6..5a7f48db 100644 --- a/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/multi_namespace.rs +++ b/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/multi_namespace.rs @@ -2,7 +2,6 @@ use cgp::prelude::*; use cgp_macro_test_util::{ snapshot_cgp_component, snapshot_cgp_impl, snapshot_delegate_components, }; -use insta::assert_snapshot; pub struct MyApp; @@ -13,7 +12,7 @@ snapshot_cgp_component! { } expand_multi_ns_foo(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub trait Foo { fn foo(&self); } @@ -107,7 +106,7 @@ snapshot_cgp_component! { } expand_multi_ns_bar(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub trait Bar { fn bar(&self); } @@ -210,7 +209,7 @@ snapshot_cgp_impl! { } expand_multi_ns_dummy_foo(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" impl<__Context__> FooProvider<__Context__> for DummyFoo { fn foo(__context__: &__Context__) {} } @@ -227,7 +226,7 @@ snapshot_cgp_impl! { } expand_multi_ns_dummy_bar(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" impl<__Context__> BarProvider<__Context__> for DummyBar { fn bar(__context__: &__Context__) {} } @@ -252,7 +251,7 @@ snapshot_delegate_components! { } expand_multi_ns_app(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" impl<__Key__, __Value__> DelegateComponent<__Key__> for App where __Key__: MyNamespace, @@ -337,7 +336,7 @@ snapshot_delegate_components! { } expand_multi_ns_other_app(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" impl<__Key__, __Value__> DelegateComponent<__Key__> for OtherApp where __Key__: OtherNamespace, diff --git a/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/symbol_path.rs b/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/symbol_path.rs index b2ad1972..8ca1aa8d 100644 --- a/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/symbol_path.rs +++ b/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/symbol_path.rs @@ -2,7 +2,6 @@ use cgp::prelude::*; use cgp_macro_test_util::{ snapshot_cgp_component, snapshot_cgp_impl, snapshot_delegate_components, }; -use insta::assert_snapshot; snapshot_cgp_component! { #[cgp_component(FooProvider)] @@ -11,7 +10,7 @@ snapshot_cgp_component! { } expand_symbol_path_foo(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub trait Foo { fn foo(&self); } @@ -97,7 +96,7 @@ snapshot_cgp_component! { } expand_symbol_path_bar(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub trait Bar { fn bar(&self); } @@ -194,7 +193,7 @@ snapshot_cgp_impl! { } expand_symbol_path_dummy_foo(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" impl<__Context__> FooProvider<__Context__> for DummyFoo { fn foo(__context__: &__Context__) {} } @@ -211,7 +210,7 @@ snapshot_cgp_impl! { } expand_symbol_path_dummy_bar(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" impl<__Context__> BarProvider<__Context__> for DummyBar { fn bar(__context__: &__Context__) {} } @@ -236,7 +235,7 @@ snapshot_delegate_components! { } expand_symbol_path_app(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" impl<__Key__, __Value__> DelegateComponent<__Key__> for App where __Key__: MyNamespace, diff --git a/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/type_path.rs b/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/type_path.rs index 75f60bd8..256adbe8 100644 --- a/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/type_path.rs +++ b/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/type_path.rs @@ -2,7 +2,6 @@ use cgp::prelude::*; use cgp_macro_test_util::{ snapshot_cgp_component, snapshot_cgp_impl, snapshot_delegate_components, }; -use insta::assert_snapshot; pub struct MyApp; @@ -13,7 +12,7 @@ snapshot_cgp_component! { } expand_type_path_foo(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub trait Foo { fn foo(&self); } @@ -99,7 +98,7 @@ snapshot_cgp_component! { } expand_type_path_bar(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub trait Bar { fn bar(&self); } @@ -187,7 +186,7 @@ snapshot_cgp_impl! { } expand_type_path_dummy_foo(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" impl<__Context__> FooProvider<__Context__> for DummyFoo { fn foo(__context__: &__Context__) {} } @@ -204,7 +203,7 @@ snapshot_cgp_impl! { } expand_type_path_dummy_bar(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" impl<__Context__> BarProvider<__Context__> for DummyBar { fn bar(__context__: &__Context__) {} } @@ -229,7 +228,7 @@ snapshot_delegate_components! { } expand_type_path_app(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" impl<__Key__, __Value__> DelegateComponent<__Key__> for App where __Key__: MyNamespace, diff --git a/crates/tests/cgp-tests/tests/namespace_tests/open.rs b/crates/tests/cgp-tests/tests/namespace_tests/open.rs index fab5e598..adfcdc34 100644 --- a/crates/tests/cgp-tests/tests/namespace_tests/open.rs +++ b/crates/tests/cgp-tests/tests/namespace_tests/open.rs @@ -2,7 +2,6 @@ use cgp::prelude::*; use cgp_macro_test_util::{ snapshot_cgp_component, snapshot_cgp_impl, snapshot_delegate_components, }; -use insta::assert_snapshot; pub struct App; @@ -13,7 +12,7 @@ snapshot_cgp_component! { } expand_open_foo(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub trait Foo { fn foo(&self, value: &T); } @@ -103,7 +102,7 @@ snapshot_cgp_component! { } expand_open_bar(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub trait Bar { fn bar(&self, value: &T); } @@ -193,7 +192,7 @@ snapshot_cgp_impl! { } expand_open_dummy_foo(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" impl<__Context__, T> FooProvider<__Context__, T> for DummyFoo { fn foo(__context__: &__Context__, _value: &T) {} } @@ -210,7 +209,7 @@ snapshot_cgp_impl! { } expand_open_dummy_bar(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" impl<__Context__, T> BarProvider<__Context__, T> for DummyBar { fn bar(__context__: &__Context__, _value: &T) {} } @@ -238,7 +237,7 @@ snapshot_delegate_components! { } expand_open_app(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" impl DelegateComponent for App { type Delegate = RedirectLookup>; } diff --git a/crates/tests/cgp-tests/tests/namespace_tests/redirect.rs b/crates/tests/cgp-tests/tests/namespace_tests/redirect.rs index 5b3023c1..c0bb0a53 100644 --- a/crates/tests/cgp-tests/tests/namespace_tests/redirect.rs +++ b/crates/tests/cgp-tests/tests/namespace_tests/redirect.rs @@ -2,7 +2,6 @@ use cgp::prelude::*; use cgp_macro_test_util::{ snapshot_cgp_component, snapshot_cgp_impl, snapshot_delegate_components, }; -use insta::assert_snapshot; snapshot_cgp_component! { #[cgp_component(FooProvider)] @@ -12,7 +11,7 @@ snapshot_cgp_component! { } expand_redirect_foo(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub trait CanDoFoo { fn foo(); } @@ -104,7 +103,7 @@ snapshot_cgp_impl! { } expand_redirect_test_provider(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" impl<__Context__> FooProvider<__Context__> for TestProvider { fn foo() {} } @@ -130,7 +129,7 @@ snapshot_delegate_components! { } expand_redirect_app(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" impl<__Key__, __Value__> DelegateComponent<__Key__> for App where __Key__: DefaultNamespace, diff --git a/crates/tests/cgp-tests/tests/preset_tests/basic/components.rs b/crates/tests/cgp-tests/tests/preset_tests/basic/components.rs index 920aaeeb..8af1b1f3 100644 --- a/crates/tests/cgp-tests/tests/preset_tests/basic/components.rs +++ b/crates/tests/cgp-tests/tests/preset_tests/basic/components.rs @@ -1,6 +1,5 @@ use cgp::prelude::*; use cgp_macro_test_util::snapshot_cgp_getter; -use insta::assert_snapshot; #[cgp_type] pub trait HasFooType { @@ -19,7 +18,7 @@ snapshot_cgp_getter! { } expand_has_foo(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub trait HasFoo: HasFooType { fn foo(&self) -> &Self::Foo; } @@ -162,7 +161,7 @@ snapshot_cgp_getter! { } expand_has_bar(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub trait HasBar: HasBarType { fn bar(&self) -> &Self::Bar; } diff --git a/crates/tests/cgp-tests/tests/preset_tests/basic/contexts.rs b/crates/tests/cgp-tests/tests/preset_tests/basic/contexts.rs index 5e0c785c..79dc6cf2 100644 --- a/crates/tests/cgp-tests/tests/preset_tests/basic/contexts.rs +++ b/crates/tests/cgp-tests/tests/preset_tests/basic/contexts.rs @@ -1,6 +1,5 @@ use cgp::prelude::*; use cgp_macro_test_util::snapshot_delegate_components; -use insta::assert_snapshot; use crate::preset_tests::basic::components::{ BarGetterComponent, BarTypeProviderComponent, FooGetterComponent, FooTypeProviderComponent, @@ -22,7 +21,7 @@ snapshot_delegate_components! { } expand_my_context(output) { - assert_snapshot!(output, @r#" + insta::assert_snapshot!(output, @r#" impl DelegateComponent for MyContext { type Delegate = UseField; } diff --git a/crates/tests/cgp-tests/tests/preset_tests/generics/components.rs b/crates/tests/cgp-tests/tests/preset_tests/generics/components.rs index 765273e7..95aa2235 100644 --- a/crates/tests/cgp-tests/tests/preset_tests/generics/components.rs +++ b/crates/tests/cgp-tests/tests/preset_tests/generics/components.rs @@ -2,7 +2,6 @@ use core::marker::PhantomData; use cgp::prelude::*; use cgp_macro_test_util::snapshot_cgp_getter; -use insta::assert_snapshot; #[cgp_type] pub trait HasFooType { @@ -24,7 +23,7 @@ snapshot_cgp_getter! { } expand_has_foo_at(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub trait HasFooAt: HasFooType { fn foo(&self, _tag: PhantomData) -> &Self::Foo; } @@ -193,7 +192,7 @@ snapshot_cgp_getter! { } expand_has_bar(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub trait HasBar: HasBarType { fn bar(&self) -> &Self::Bar; } diff --git a/crates/tests/cgp-tests/tests/preset_tests/generics_inheritance/components.rs b/crates/tests/cgp-tests/tests/preset_tests/generics_inheritance/components.rs index 677ca44f..2d2487ac 100644 --- a/crates/tests/cgp-tests/tests/preset_tests/generics_inheritance/components.rs +++ b/crates/tests/cgp-tests/tests/preset_tests/generics_inheritance/components.rs @@ -2,7 +2,6 @@ use core::marker::PhantomData; use cgp::prelude::*; use cgp_macro_test_util::snapshot_cgp_getter; -use insta::assert_snapshot; #[cgp_type] pub trait HasFooType { @@ -24,7 +23,7 @@ snapshot_cgp_getter! { } expand_has_foo_at(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub trait HasFooAt: HasFooType { fn foo(&self, _tag: PhantomData) -> &Self::Foo; } @@ -194,7 +193,7 @@ snapshot_cgp_getter! { } expand_has_bar_at(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" pub trait HasBarAt: HasBarType { fn bar(&self) -> &Self::Bar; } diff --git a/crates/tests/cgp-tests/tests/preset_tests/wrapped/context.rs b/crates/tests/cgp-tests/tests/preset_tests/wrapped/context.rs index 04d695c8..17c9a17d 100644 --- a/crates/tests/cgp-tests/tests/preset_tests/wrapped/context.rs +++ b/crates/tests/cgp-tests/tests/preset_tests/wrapped/context.rs @@ -3,7 +3,6 @@ use core::convert::Infallible; use cgp::core::error::{ErrorRaiserComponent, ErrorTypeProviderComponent}; use cgp::prelude::*; use cgp_macro_test_util::snapshot_delegate_components; -use insta::assert_snapshot; use crate::preset_tests::wrapped::preset::{BoxError, ErrorHandlerPreset}; @@ -20,7 +19,7 @@ snapshot_delegate_components! { } expand_my_context(output) { - assert_snapshot!(output, @" + insta::assert_snapshot!(output, @" impl DelegateComponent for MyContext { type Delegate = UseType; } From ea8fe0c0a0bff82be79f562d1a74b5e5ca03f504 Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Fri, 19 Jun 2026 22:03:25 +0200 Subject: [PATCH 23/31] Add `snapshot_cgp_namespace!` macro --- .../src/entrypoints/mod.rs | 2 + .../src/entrypoints/snapshot_cgp_namespace.rs | 12 ++++ .../src/types/cgp_namespace.rs | 31 ++++++++++ .../cgp-macro-test-util-lib/src/types/mod.rs | 2 + crates/macros/cgp-macro-test-util/README.md | 27 ++++++++- crates/macros/cgp-macro-test-util/src/lib.rs | 7 +++ .../cgp-tests/src/namespaces/default_impls.rs | 54 +++++++++++++---- .../cgp-tests/src/namespaces/extended.rs | 45 ++++++++++++-- .../namespace_tests/namespace_macro/basic.rs | 23 ++++++-- .../namespace_macro/multi_namespace.rs | 59 ++++++++++++++++--- .../namespace_macro/symbol_path.rs | 35 +++++++++-- .../namespace_macro/type_path.rs | 26 ++++++-- 12 files changed, 283 insertions(+), 40 deletions(-) create mode 100644 crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_namespace.rs create mode 100644 crates/macros/cgp-macro-test-util-lib/src/types/cgp_namespace.rs diff --git a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/mod.rs b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/mod.rs index a8ae753b..3cb9f493 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/mod.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/mod.rs @@ -3,6 +3,7 @@ mod snapshot_cgp_component; mod snapshot_cgp_fn; mod snapshot_cgp_getter; mod snapshot_cgp_impl; +mod snapshot_cgp_namespace; mod snapshot_delegate_components; pub use snapshot_cgp_auto_getter::*; @@ -10,4 +11,5 @@ pub use snapshot_cgp_component::*; pub use snapshot_cgp_fn::*; pub use snapshot_cgp_getter::*; pub use snapshot_cgp_impl::*; +pub use snapshot_cgp_namespace::*; pub use snapshot_delegate_components::*; diff --git a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_namespace.rs b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_namespace.rs new file mode 100644 index 00000000..307ed59d --- /dev/null +++ b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_namespace.rs @@ -0,0 +1,12 @@ +use proc_macro2::TokenStream; +use syn::parse2; + +use crate::types::AssertCgpNamespace; + +pub fn snapshot_cgp_namespace(body: TokenStream) -> syn::Result { + let item: AssertCgpNamespace = parse2(body)?; + + let output = cgp_macro_lib::cgp_namespace(item.body.clone())?; + + item.snapshot.wrap_output(output) +} diff --git a/crates/macros/cgp-macro-test-util-lib/src/types/cgp_namespace.rs b/crates/macros/cgp-macro-test-util-lib/src/types/cgp_namespace.rs new file mode 100644 index 00000000..0f2c59ac --- /dev/null +++ b/crates/macros/cgp-macro-test-util-lib/src/types/cgp_namespace.rs @@ -0,0 +1,31 @@ +use cgp_macro_core::define_keyword; +use cgp_macro_core::types::keyword::Keyword; +use proc_macro2::TokenStream; +use syn::braced; +use syn::parse::{Parse, ParseStream}; +use syn::token::Not; + +use crate::types::MacroSnapshot; + +define_keyword!(CgpNamespace, "cgp_namespace"); + +pub struct AssertCgpNamespace { + pub body: TokenStream, + pub snapshot: MacroSnapshot, +} + +impl Parse for AssertCgpNamespace { + fn parse(input: ParseStream) -> syn::Result { + let _: Keyword = input.parse()?; + let _: Not = input.parse()?; + + let body = { + let body; + braced!(body in input); + body.parse()? + }; + + let snapshot = input.parse()?; + Ok(Self { body, snapshot }) + } +} diff --git a/crates/macros/cgp-macro-test-util-lib/src/types/mod.rs b/crates/macros/cgp-macro-test-util-lib/src/types/mod.rs index 7277f380..8c89459b 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/types/mod.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/types/mod.rs @@ -3,6 +3,7 @@ mod cgp_component; mod cgp_fn; mod cgp_getter; mod cgp_impl; +mod cgp_namespace; mod delegate_components; mod snapshot; @@ -11,5 +12,6 @@ pub use cgp_component::*; pub use cgp_fn::*; pub use cgp_getter::*; pub use cgp_impl::*; +pub use cgp_namespace::*; pub use delegate_components::*; pub use snapshot::*; diff --git a/crates/macros/cgp-macro-test-util/README.md b/crates/macros/cgp-macro-test-util/README.md index 8d2fdf02..4807474b 100644 --- a/crates/macros/cgp-macro-test-util/README.md +++ b/crates/macros/cgp-macro-test-util/README.md @@ -63,6 +63,7 @@ snapshot output is guaranteed to match what the production macros generate. | `snapshot_cgp_getter!` | `#[cgp_getter]` | | `snapshot_cgp_fn!` | `#[cgp_fn]` | | `snapshot_delegate_components!` | `delegate_components!` | +| `snapshot_cgp_namespace!` | `cgp_namespace!` | ## Anatomy of a snapshot invocation @@ -221,6 +222,30 @@ snapshot_delegate_components! { } ``` +### `snapshot_cgp_namespace!` + +Like `snapshot_delegate_components!`, the *whole* `cgp_namespace! { ... }` +invocation is written verbatim, followed by the test block: + +```rust +snapshot_cgp_namespace! { + cgp_namespace! { + new MyNamespace { + FooProviderComponent => + @MyApp.MyFooComponent, + } + } + + expand_my_namespace(output) { + assert_snapshot!(output, @"...") + } +} +``` + +All `cgp_namespace!` forms are accepted, since the body is forwarded to the real +macro verbatim — including parent namespaces (`new Extended: DefaultNamespace { ... }`), +symbol/type path keys (`@my_app.MyFooComponent`), and array keys. + ## Workflow with `insta` Write the test with an **empty** inline snapshot first: @@ -272,7 +297,7 @@ When migrating an existing macro test, two situations come up: ## Notes / limitations -- Snapshot macros exist only for the six macros listed above. Other CGP macros +- Snapshot macros exist only for the seven macros listed above. Other CGP macros (`#[cgp_type]`, `#[cgp_provider]`, `#[cgp_preset]`, `check_components!`, `delegate_and_check_components!`, …) are not (yet) snapshot-wrapped and are left as-is. diff --git a/crates/macros/cgp-macro-test-util/src/lib.rs b/crates/macros/cgp-macro-test-util/src/lib.rs index 3e90a20a..886e7bf3 100644 --- a/crates/macros/cgp-macro-test-util/src/lib.rs +++ b/crates/macros/cgp-macro-test-util/src/lib.rs @@ -42,3 +42,10 @@ pub fn snapshot_cgp_getter(body: TokenStream) -> TokenStream { .unwrap_or_else(syn::Error::into_compile_error) .into() } + +#[proc_macro] +pub fn snapshot_cgp_namespace(body: TokenStream) -> TokenStream { + entrypoints::snapshot_cgp_namespace(body.into()) + .unwrap_or_else(syn::Error::into_compile_error) + .into() +} diff --git a/crates/tests/cgp-tests/src/namespaces/default_impls.rs b/crates/tests/cgp-tests/src/namespaces/default_impls.rs index b9081391..e6363ea7 100644 --- a/crates/tests/cgp-tests/src/namespaces/default_impls.rs +++ b/crates/tests/cgp-tests/src/namespaces/default_impls.rs @@ -2,7 +2,7 @@ use core::fmt::Display; use cgp::core::component::DefaultImpls1; use cgp::prelude::*; -use cgp_macro_test_util::{snapshot_cgp_component, snapshot_cgp_impl}; +use cgp_macro_test_util::{snapshot_cgp_component, snapshot_cgp_impl, snapshot_cgp_namespace}; snapshot_cgp_component! { #[cgp_component(ShowImpl)] @@ -149,18 +149,52 @@ snapshot_cgp_impl! { } } -cgp_namespace! { - new DefaultShowComponents { - [ - String, - u64, - ]: - ShowWithDisplay, +snapshot_cgp_namespace! { + cgp_namespace! { + new DefaultShowComponents { + [ + String, + u64, + ]: + ShowWithDisplay, + } + } + + expand_default_show_components(output) { + insta::assert_snapshot!(output, @" + pub trait DefaultShowComponents<__Table__> { + type Delegate; + } + impl<__Table__> DefaultShowComponents<__Table__> for String { + type Delegate = ShowWithDisplay; + } + impl<__Table__> DefaultShowComponents<__Table__> for u64 { + type Delegate = ShowWithDisplay; + } + ") } } -cgp_namespace! { - new ExtendedNamespace: DefaultNamespace { +snapshot_cgp_namespace! { + cgp_namespace! { + new ExtendedNamespace: DefaultNamespace { + } + } + + expand_default_impls_extended_namespace(output) { + insta::assert_snapshot!(output, @" + pub struct __ExtendedNamespaceComponents; + pub trait ExtendedNamespace<__Table__> { + type Delegate; + } + impl<__Table__, __Key__, __Value__> ExtendedNamespace<__Table__> for __Key__ + where + __Key__: DefaultNamespace<__ExtendedNamespaceComponents>, + __Key__: DefaultNamespace<__Table__, Delegate = __Value__>, + { + type Delegate = __Value__; + } + ") } } diff --git a/crates/tests/cgp-tests/src/namespaces/extended.rs b/crates/tests/cgp-tests/src/namespaces/extended.rs index 2e74b25e..a87df68c 100644 --- a/crates/tests/cgp-tests/src/namespaces/extended.rs +++ b/crates/tests/cgp-tests/src/namespaces/extended.rs @@ -1,8 +1,43 @@ -use cgp::prelude::{DefaultNamespace, cgp_namespace}; +use cgp::prelude::DefaultNamespace; +use cgp_macro_test_util::snapshot_cgp_namespace; -cgp_namespace! { - new ExtendedNamespace: DefaultNamespace { - @cgp.core.error => - @app, +snapshot_cgp_namespace! { + cgp_namespace! { + new ExtendedNamespace: DefaultNamespace { + @cgp.core.error => + @app, + } + } + + expand_extended_namespace(output) { + insta::assert_snapshot!(output, @" + pub struct __ExtendedNamespaceComponents; + pub trait ExtendedNamespace<__Table__> { + type Delegate; + } + impl<__Table__, __Key__, __Value__> ExtendedNamespace<__Table__> for __Key__ + where + __Key__: DefaultNamespace<__ExtendedNamespaceComponents>, + __Key__: DefaultNamespace<__Table__, Delegate = __Value__>, + { + type Delegate = __Value__; + } + impl<__Table__, __Wildcard__> ExtendedNamespace<__Table__> + for PathCons< + Symbol<3, Chars<'c', Chars<'g', Chars<'p', Nil>>>>, + PathCons< + Symbol<4, Chars<'c', Chars<'o', Chars<'r', Chars<'e', Nil>>>>>, + PathCons< + Symbol<5, Chars<'e', Chars<'r', Chars<'r', Chars<'o', Chars<'r', Nil>>>>>>, + __Wildcard__, + >, + >, + > { + type Delegate = RedirectLookup< + __Table__, + PathCons>>>, __Wildcard__>, + >; + } + ") } } diff --git a/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/basic.rs b/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/basic.rs index 7fc3c4ed..41dcf87b 100644 --- a/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/basic.rs +++ b/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/basic.rs @@ -1,6 +1,6 @@ use cgp::prelude::*; use cgp_macro_test_util::{ - snapshot_cgp_component, snapshot_cgp_impl, snapshot_delegate_components, + snapshot_cgp_component, snapshot_cgp_impl, snapshot_cgp_namespace, snapshot_delegate_components, }; snapshot_cgp_component! { @@ -81,10 +81,23 @@ snapshot_cgp_component! { } } -cgp_namespace! { - new MyNamespace { - FooProviderComponent => - @MyFooComponent, +snapshot_cgp_namespace! { + cgp_namespace! { + new MyNamespace { + FooProviderComponent => + @MyFooComponent, + } + } + + expand_basic_my_namespace(output) { + insta::assert_snapshot!(output, @" + pub trait MyNamespace<__Table__> { + type Delegate; + } + impl<__Table__> MyNamespace<__Table__> for FooProviderComponent { + type Delegate = RedirectLookup<__Table__, PathCons>; + } + ") } } diff --git a/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/multi_namespace.rs b/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/multi_namespace.rs index 5a7f48db..80075503 100644 --- a/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/multi_namespace.rs +++ b/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/multi_namespace.rs @@ -1,6 +1,6 @@ use cgp::prelude::*; use cgp_macro_test_util::{ - snapshot_cgp_component, snapshot_cgp_impl, snapshot_delegate_components, + snapshot_cgp_component, snapshot_cgp_impl, snapshot_cgp_namespace, snapshot_delegate_components, }; pub struct MyApp; @@ -83,17 +83,58 @@ snapshot_cgp_component! { } } -cgp_namespace! { - new MyNamespace { - FooProviderComponent => - @MyApp.MyFooComponent, +snapshot_cgp_namespace! { + cgp_namespace! { + new MyNamespace { + FooProviderComponent => + @MyApp.MyFooComponent, + } + } + + expand_multi_ns_my_namespace(output) { + insta::assert_snapshot!(output, @" + pub trait MyNamespace<__Table__> { + type Delegate; + } + impl<__Table__> MyNamespace<__Table__> for FooProviderComponent { + type Delegate = RedirectLookup< + __Table__, + PathCons>, + >; + } + ") } } -cgp_namespace! { - new OtherNamespace { - FooProviderComponent => - @my_app.MyFooComponent, +snapshot_cgp_namespace! { + cgp_namespace! { + new OtherNamespace { + FooProviderComponent => + @my_app.MyFooComponent, + } + } + + expand_multi_ns_other_namespace(output) { + insta::assert_snapshot!(output, @" + pub trait OtherNamespace<__Table__> { + type Delegate; + } + impl<__Table__> OtherNamespace<__Table__> for FooProviderComponent { + type Delegate = RedirectLookup< + __Table__, + PathCons< + Symbol< + 6, + Chars< + 'm', + Chars<'y', Chars<'_', Chars<'a', Chars<'p', Chars<'p', Nil>>>>>, + >, + >, + PathCons, + >, + >; + } + ") } } diff --git a/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/symbol_path.rs b/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/symbol_path.rs index 8ca1aa8d..53d46c33 100644 --- a/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/symbol_path.rs +++ b/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/symbol_path.rs @@ -1,6 +1,6 @@ use cgp::prelude::*; use cgp_macro_test_util::{ - snapshot_cgp_component, snapshot_cgp_impl, snapshot_delegate_components, + snapshot_cgp_component, snapshot_cgp_impl, snapshot_cgp_namespace, snapshot_delegate_components, }; snapshot_cgp_component! { @@ -81,10 +81,35 @@ snapshot_cgp_component! { } } -cgp_namespace! { - new MyNamespace { - FooProviderComponent => - @my_app.MyFooComponent, +snapshot_cgp_namespace! { + cgp_namespace! { + new MyNamespace { + FooProviderComponent => + @my_app.MyFooComponent, + } + } + + expand_symbol_path_my_namespace(output) { + insta::assert_snapshot!(output, @" + pub trait MyNamespace<__Table__> { + type Delegate; + } + impl<__Table__> MyNamespace<__Table__> for FooProviderComponent { + type Delegate = RedirectLookup< + __Table__, + PathCons< + Symbol< + 6, + Chars< + 'm', + Chars<'y', Chars<'_', Chars<'a', Chars<'p', Chars<'p', Nil>>>>>, + >, + >, + PathCons, + >, + >; + } + ") } } diff --git a/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/type_path.rs b/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/type_path.rs index 256adbe8..7e402354 100644 --- a/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/type_path.rs +++ b/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/type_path.rs @@ -1,6 +1,6 @@ use cgp::prelude::*; use cgp_macro_test_util::{ - snapshot_cgp_component, snapshot_cgp_impl, snapshot_delegate_components, + snapshot_cgp_component, snapshot_cgp_impl, snapshot_cgp_namespace, snapshot_delegate_components, }; pub struct MyApp; @@ -83,10 +83,26 @@ snapshot_cgp_component! { } } -cgp_namespace! { - new MyNamespace { - FooProviderComponent => - @MyApp.MyFooComponent, +snapshot_cgp_namespace! { + cgp_namespace! { + new MyNamespace { + FooProviderComponent => + @MyApp.MyFooComponent, + } + } + + expand_type_path_my_namespace(output) { + insta::assert_snapshot!(output, @" + pub trait MyNamespace<__Table__> { + type Delegate; + } + impl<__Table__> MyNamespace<__Table__> for FooProviderComponent { + type Delegate = RedirectLookup< + __Table__, + PathCons>, + >; + } + ") } } From 174f9c7fb5629873bc1e9f0ee5d0545c46bca297 Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Fri, 19 Jun 2026 22:13:24 +0200 Subject: [PATCH 24/31] Add `snapshot_cgp_type!` macro --- .../src/entrypoints/mod.rs | 2 + .../src/entrypoints/snapshot_cgp_type.rs | 13 + .../src/types/cgp_type.rs | 31 ++ .../cgp-macro-test-util-lib/src/types/mod.rs | 2 + crates/macros/cgp-macro-test-util/README.md | 30 +- crates/macros/cgp-macro-test-util/src/lib.rs | 7 + .../tests/cgp-tests/src/tests/async/spawn.rs | 210 ++++++++- .../cgp-tests/src/tests/check_components.rs | 418 +++++++++++++++++- .../tests/delegate_and_check_components.rs | 214 ++++++++- .../src/tests/use_delegate/getter.rs | 188 +++++++- .../cgp-tests/tests/cgp_fn_tests/extend.rs | 107 ++++- .../tests/cgp_fn_tests/foreign_type.rs | 107 ++++- .../cgp_fn_tests/foreign_type_equality.rs | 212 ++++++++- .../tests/cgp_fn_tests/nested_foreign_type.rs | 212 ++++++++- .../tests/cgp_fn_tests/type_equality.rs | 107 ++++- .../cgp-tests/tests/cgp_fn_tests/use_type.rs | 107 ++++- .../tests/cgp_fn_tests/use_type_alias.rs | 107 ++++- .../component_tests/abstract_types/basic.rs | 106 ++++- .../component_tests/abstract_types/extend.rs | 106 ++++- .../component_tests/abstract_types/foreign.rs | 106 ++++- .../abstract_types/self_referential.rs | 106 ++++- .../component_tests/cgp_component/constant.rs | 114 ++++- .../component_tests/cgp_component/sized.rs | 118 ++++- .../getter_tests/abstract_type/explicit.rs | 107 ++++- .../getter_tests/abstract_type/import.rs | 107 ++++- .../getter_tests/abstract_type/use_type.rs | 107 ++++- .../cgp-tests/tests/getter_tests/clone.rs | 218 ++++++++- .../cgp-tests/tests/getter_tests/non_self.rs | 208 ++++++++- .../tests/getter_tests/non_self_auto.rs | 210 ++++++++- .../tests/preset_tests/basic/components.rs | 208 ++++++++- .../tests/preset_tests/generics/components.rs | 208 ++++++++- .../generics_inheritance/components.rs | 208 ++++++++- 32 files changed, 4162 insertions(+), 149 deletions(-) create mode 100644 crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_type.rs create mode 100644 crates/macros/cgp-macro-test-util-lib/src/types/cgp_type.rs diff --git a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/mod.rs b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/mod.rs index 3cb9f493..7e1772f8 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/mod.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/mod.rs @@ -4,6 +4,7 @@ mod snapshot_cgp_fn; mod snapshot_cgp_getter; mod snapshot_cgp_impl; mod snapshot_cgp_namespace; +mod snapshot_cgp_type; mod snapshot_delegate_components; pub use snapshot_cgp_auto_getter::*; @@ -12,4 +13,5 @@ pub use snapshot_cgp_fn::*; pub use snapshot_cgp_getter::*; pub use snapshot_cgp_impl::*; pub use snapshot_cgp_namespace::*; +pub use snapshot_cgp_type::*; pub use snapshot_delegate_components::*; diff --git a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_type.rs b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_type.rs new file mode 100644 index 00000000..4b5c3676 --- /dev/null +++ b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_type.rs @@ -0,0 +1,13 @@ +use proc_macro2::TokenStream; +use quote::ToTokens; +use syn::parse2; + +use crate::types::SnapshotCgpType; + +pub fn snapshot_cgp_type(body: TokenStream) -> syn::Result { + let item: SnapshotCgpType = parse2(body)?; + + let output = cgp_macro_lib::cgp_type(item.attr, item.body.to_token_stream())?; + + item.snapshot.wrap_output(output) +} diff --git a/crates/macros/cgp-macro-test-util-lib/src/types/cgp_type.rs b/crates/macros/cgp-macro-test-util-lib/src/types/cgp_type.rs new file mode 100644 index 00000000..99200b81 --- /dev/null +++ b/crates/macros/cgp-macro-test-util-lib/src/types/cgp_type.rs @@ -0,0 +1,31 @@ +use proc_macro2::TokenStream; +use syn::ItemTrait; +use syn::parse::{Parse, ParseStream}; +use syn::token::Pound; + +use crate::functions::parse_attribute; +use crate::types::MacroSnapshot; + +pub struct SnapshotCgpType { + pub attr: TokenStream, + pub body: ItemTrait, + pub snapshot: MacroSnapshot, +} + +impl Parse for SnapshotCgpType { + fn parse(input: ParseStream) -> syn::Result { + let _: Pound = input.parse()?; + + let attr = parse_attribute("cgp_type", input)?; + + let body = input.parse()?; + + let snapshot = input.parse()?; + + Ok(Self { + attr, + body, + snapshot, + }) + } +} diff --git a/crates/macros/cgp-macro-test-util-lib/src/types/mod.rs b/crates/macros/cgp-macro-test-util-lib/src/types/mod.rs index 8c89459b..9136f935 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/types/mod.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/types/mod.rs @@ -4,6 +4,7 @@ mod cgp_fn; mod cgp_getter; mod cgp_impl; mod cgp_namespace; +mod cgp_type; mod delegate_components; mod snapshot; @@ -13,5 +14,6 @@ pub use cgp_fn::*; pub use cgp_getter::*; pub use cgp_impl::*; pub use cgp_namespace::*; +pub use cgp_type::*; pub use delegate_components::*; pub use snapshot::*; diff --git a/crates/macros/cgp-macro-test-util/README.md b/crates/macros/cgp-macro-test-util/README.md index 4807474b..45fbbb1c 100644 --- a/crates/macros/cgp-macro-test-util/README.md +++ b/crates/macros/cgp-macro-test-util/README.md @@ -62,6 +62,7 @@ snapshot output is guaranteed to match what the production macros generate. | `snapshot_cgp_auto_getter!` | `#[cgp_auto_getter]` | | `snapshot_cgp_getter!` | `#[cgp_getter]` | | `snapshot_cgp_fn!` | `#[cgp_fn]` | +| `snapshot_cgp_type!` | `#[cgp_type]` | | `snapshot_delegate_components!` | `delegate_components!` | | `snapshot_cgp_namespace!` | `cgp_namespace!` | @@ -202,6 +203,31 @@ snapshot_cgp_fn! { Both the default form `#[cgp_fn]` and the custom trait name form `#[cgp_fn(CanCalculateRectangleArea)]` are accepted, mirroring the real macro. +### `snapshot_cgp_type!` + +Wraps `#[cgp_type]` abstract-type traits. The item under test is written exactly +as you would normally write the `#[cgp_type]` invocation: + +```rust +snapshot_cgp_type! { + #[cgp_type] + pub trait HasScalarType { + type Scalar; + } + + expand_has_scalar_type(output) { + assert_snapshot!(output, @"...") + } +} +``` + +Both the default form `#[cgp_type]` and the custom provider name forms +`#[cgp_type(ScalarTypeProvider)]` and +`#[cgp_type { provider: ..., derive_delegate: ... }]` are accepted, mirroring the +real macro. In addition to the usual `#[cgp_component]` output, the snapshot +captures the extra `UseType` / `WithProvider` providers that `#[cgp_type]` +generates. + ### `snapshot_delegate_components!` Here the *whole* `delegate_components! { ... }` invocation is written verbatim, @@ -297,8 +323,8 @@ When migrating an existing macro test, two situations come up: ## Notes / limitations -- Snapshot macros exist only for the seven macros listed above. Other CGP macros - (`#[cgp_type]`, `#[cgp_provider]`, `#[cgp_preset]`, +- Snapshot macros exist only for the eight macros listed above. Other CGP macros + (`#[cgp_provider]`, `#[cgp_preset]`, `check_components!`, `delegate_and_check_components!`, …) are not (yet) snapshot-wrapped and are left as-is. - The pretty-printing is done with diff --git a/crates/macros/cgp-macro-test-util/src/lib.rs b/crates/macros/cgp-macro-test-util/src/lib.rs index 886e7bf3..059c056a 100644 --- a/crates/macros/cgp-macro-test-util/src/lib.rs +++ b/crates/macros/cgp-macro-test-util/src/lib.rs @@ -49,3 +49,10 @@ pub fn snapshot_cgp_namespace(body: TokenStream) -> TokenStream { .unwrap_or_else(syn::Error::into_compile_error) .into() } + +#[proc_macro] +pub fn snapshot_cgp_type(body: TokenStream) -> TokenStream { + entrypoints::snapshot_cgp_type(body.into()) + .unwrap_or_else(syn::Error::into_compile_error) + .into() +} diff --git a/crates/tests/cgp-tests/src/tests/async/spawn.rs b/crates/tests/cgp-tests/src/tests/async/spawn.rs index 22f332bf..81a8e314 100644 --- a/crates/tests/cgp-tests/src/tests/async/spawn.rs +++ b/crates/tests/cgp-tests/src/tests/async/spawn.rs @@ -17,7 +17,9 @@ use cgp::extra::run::{ CanRun, CanSendRun, Runner, RunnerComponent, SendRunner, SendRunnerComponent, }; use cgp::prelude::*; -use cgp_macro_test_util::{snapshot_cgp_component, snapshot_delegate_components}; +use cgp_macro_test_util::{ + snapshot_cgp_component, snapshot_cgp_type, snapshot_delegate_components, +}; use futures::executor::block_on; // A dummy spawn function that has the same signature as tokio::spawn, @@ -31,14 +33,208 @@ where // The abstract types and interfaces do not contain explicit Send bounds -#[cgp_type] -pub trait HasFooType { - type Foo; +snapshot_cgp_type! { + #[cgp_type] + pub trait HasFooType { + type Foo; + } + + expand_has_foo_type(output) { + insta::assert_snapshot!(output, @" + pub trait HasFooType { + type Foo; + } + impl<__Context__> HasFooType for __Context__ + where + __Context__: FooTypeProvider<__Context__>, + { + type Foo = <__Context__ as FooTypeProvider<__Context__>>::Foo; + } + pub trait FooTypeProvider< + __Context__, + >: IsProviderFor { + type Foo; + } + impl<__Provider__, __Context__> FooTypeProvider<__Context__> for __Provider__ + where + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + FooTypeProviderComponent, + >>::Delegate: FooTypeProvider<__Context__>, + { + type Foo = <<__Provider__ as DelegateComponent< + FooTypeProviderComponent, + >>::Delegate as FooTypeProvider<__Context__>>::Foo; + } + pub struct FooTypeProviderComponent; + impl<__Context__> FooTypeProvider<__Context__> for UseContext + where + __Context__: HasFooType, + { + type Foo = <__Context__ as HasFooType>::Foo; + } + impl<__Context__> IsProviderFor for UseContext + where + __Context__: HasFooType, + {} + impl<__Context__, __Components__, __Path__> FooTypeProvider<__Context__> + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: FooTypeProvider<__Context__>, + { + type Foo = <<__Components__ as DelegateComponent< + __Path__, + >>::Delegate as FooTypeProvider<__Context__>>::Foo; + } + impl< + __Context__, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: IsProviderFor + + FooTypeProvider<__Context__>, + {} + impl FooTypeProvider<__Context__> for UseType + where + Foo:, + { + type Foo = Foo; + } + impl IsProviderFor + for UseType + where + Foo:, + {} + impl<__Provider__, Foo, __Context__> FooTypeProvider<__Context__> + for WithProvider<__Provider__> + where + __Provider__: TypeProvider<__Context__, FooTypeProviderComponent, Type = Foo>, + Foo:, + { + type Foo = Foo; + } + impl< + __Provider__, + Foo, + __Context__, + > IsProviderFor for WithProvider<__Provider__> + where + __Provider__: TypeProvider<__Context__, FooTypeProviderComponent, Type = Foo>, + Foo:, + {} + ") + } } -#[cgp_type] -pub trait HasBarType { - type Bar; +snapshot_cgp_type! { + #[cgp_type] + pub trait HasBarType { + type Bar; + } + + expand_has_bar_type(output) { + insta::assert_snapshot!(output, @" + pub trait HasBarType { + type Bar; + } + impl<__Context__> HasBarType for __Context__ + where + __Context__: BarTypeProvider<__Context__>, + { + type Bar = <__Context__ as BarTypeProvider<__Context__>>::Bar; + } + pub trait BarTypeProvider< + __Context__, + >: IsProviderFor { + type Bar; + } + impl<__Provider__, __Context__> BarTypeProvider<__Context__> for __Provider__ + where + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + BarTypeProviderComponent, + >>::Delegate: BarTypeProvider<__Context__>, + { + type Bar = <<__Provider__ as DelegateComponent< + BarTypeProviderComponent, + >>::Delegate as BarTypeProvider<__Context__>>::Bar; + } + pub struct BarTypeProviderComponent; + impl<__Context__> BarTypeProvider<__Context__> for UseContext + where + __Context__: HasBarType, + { + type Bar = <__Context__ as HasBarType>::Bar; + } + impl<__Context__> IsProviderFor for UseContext + where + __Context__: HasBarType, + {} + impl<__Context__, __Components__, __Path__> BarTypeProvider<__Context__> + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: BarTypeProvider<__Context__>, + { + type Bar = <<__Components__ as DelegateComponent< + __Path__, + >>::Delegate as BarTypeProvider<__Context__>>::Bar; + } + impl< + __Context__, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: IsProviderFor + + BarTypeProvider<__Context__>, + {} + impl BarTypeProvider<__Context__> for UseType + where + Bar:, + { + type Bar = Bar; + } + impl IsProviderFor + for UseType + where + Bar:, + {} + impl<__Provider__, Bar, __Context__> BarTypeProvider<__Context__> + for WithProvider<__Provider__> + where + __Provider__: TypeProvider<__Context__, BarTypeProviderComponent, Type = Bar>, + Bar:, + { + type Bar = Bar; + } + impl< + __Provider__, + Bar, + __Context__, + > IsProviderFor for WithProvider<__Provider__> + where + __Provider__: TypeProvider<__Context__, BarTypeProviderComponent, Type = Bar>, + Bar:, + {} + ") + } } snapshot_cgp_component! { diff --git a/crates/tests/cgp-tests/src/tests/check_components.rs b/crates/tests/cgp-tests/src/tests/check_components.rs index 3109ca1b..86cd296e 100644 --- a/crates/tests/cgp-tests/src/tests/check_components.rs +++ b/crates/tests/cgp-tests/src/tests/check_components.rs @@ -4,16 +4,210 @@ mod basic_check_components { use core::marker::PhantomData; use cgp::prelude::*; - use cgp_macro_test_util::snapshot_cgp_getter; + use cgp_macro_test_util::{snapshot_cgp_getter, snapshot_cgp_type}; - #[cgp_type] - pub trait HasFooType { - type Foo; + snapshot_cgp_type! { + #[cgp_type] + pub trait HasFooType { + type Foo; + } + + expand_has_foo_type(output) { + insta::assert_snapshot!(output, @" + pub trait HasFooType { + type Foo; + } + impl<__Context__> HasFooType for __Context__ + where + __Context__: FooTypeProvider<__Context__>, + { + type Foo = <__Context__ as FooTypeProvider<__Context__>>::Foo; + } + pub trait FooTypeProvider< + __Context__, + >: IsProviderFor { + type Foo; + } + impl<__Provider__, __Context__> FooTypeProvider<__Context__> for __Provider__ + where + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + FooTypeProviderComponent, + >>::Delegate: FooTypeProvider<__Context__>, + { + type Foo = <<__Provider__ as DelegateComponent< + FooTypeProviderComponent, + >>::Delegate as FooTypeProvider<__Context__>>::Foo; + } + pub struct FooTypeProviderComponent; + impl<__Context__> FooTypeProvider<__Context__> for UseContext + where + __Context__: HasFooType, + { + type Foo = <__Context__ as HasFooType>::Foo; + } + impl<__Context__> IsProviderFor for UseContext + where + __Context__: HasFooType, + {} + impl<__Context__, __Components__, __Path__> FooTypeProvider<__Context__> + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: FooTypeProvider<__Context__>, + { + type Foo = <<__Components__ as DelegateComponent< + __Path__, + >>::Delegate as FooTypeProvider<__Context__>>::Foo; + } + impl< + __Context__, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: IsProviderFor + + FooTypeProvider<__Context__>, + {} + impl FooTypeProvider<__Context__> for UseType + where + Foo:, + { + type Foo = Foo; + } + impl IsProviderFor + for UseType + where + Foo:, + {} + impl<__Provider__, Foo, __Context__> FooTypeProvider<__Context__> + for WithProvider<__Provider__> + where + __Provider__: TypeProvider<__Context__, FooTypeProviderComponent, Type = Foo>, + Foo:, + { + type Foo = Foo; + } + impl< + __Provider__, + Foo, + __Context__, + > IsProviderFor for WithProvider<__Provider__> + where + __Provider__: TypeProvider<__Context__, FooTypeProviderComponent, Type = Foo>, + Foo:, + {} + ") + } } - #[cgp_type] - pub trait HasBarType { - type Bar; + snapshot_cgp_type! { + #[cgp_type] + pub trait HasBarType { + type Bar; + } + + expand_has_bar_type(output) { + insta::assert_snapshot!(output, @" + pub trait HasBarType { + type Bar; + } + impl<__Context__> HasBarType for __Context__ + where + __Context__: BarTypeProvider<__Context__>, + { + type Bar = <__Context__ as BarTypeProvider<__Context__>>::Bar; + } + pub trait BarTypeProvider< + __Context__, + >: IsProviderFor { + type Bar; + } + impl<__Provider__, __Context__> BarTypeProvider<__Context__> for __Provider__ + where + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + BarTypeProviderComponent, + >>::Delegate: BarTypeProvider<__Context__>, + { + type Bar = <<__Provider__ as DelegateComponent< + BarTypeProviderComponent, + >>::Delegate as BarTypeProvider<__Context__>>::Bar; + } + pub struct BarTypeProviderComponent; + impl<__Context__> BarTypeProvider<__Context__> for UseContext + where + __Context__: HasBarType, + { + type Bar = <__Context__ as HasBarType>::Bar; + } + impl<__Context__> IsProviderFor for UseContext + where + __Context__: HasBarType, + {} + impl<__Context__, __Components__, __Path__> BarTypeProvider<__Context__> + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: BarTypeProvider<__Context__>, + { + type Bar = <<__Components__ as DelegateComponent< + __Path__, + >>::Delegate as BarTypeProvider<__Context__>>::Bar; + } + impl< + __Context__, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: IsProviderFor + + BarTypeProvider<__Context__>, + {} + impl BarTypeProvider<__Context__> for UseType + where + Bar:, + { + type Bar = Bar; + } + impl IsProviderFor + for UseType + where + Bar:, + {} + impl<__Provider__, Bar, __Context__> BarTypeProvider<__Context__> + for WithProvider<__Provider__> + where + __Provider__: TypeProvider<__Context__, BarTypeProviderComponent, Type = Bar>, + Bar:, + { + type Bar = Bar; + } + impl< + __Provider__, + Bar, + __Context__, + > IsProviderFor for WithProvider<__Provider__> + where + __Provider__: TypeProvider<__Context__, BarTypeProviderComponent, Type = Bar>, + Bar:, + {} + ") + } } snapshot_cgp_getter! { @@ -467,16 +661,212 @@ mod generic_check_components { use core::marker::PhantomData; use cgp::prelude::*; - use cgp_macro_test_util::{snapshot_cgp_getter, snapshot_delegate_components}; + use cgp_macro_test_util::{ + snapshot_cgp_getter, snapshot_cgp_type, snapshot_delegate_components, + }; - #[cgp_type] - pub trait HasFooType { - type Foo; + snapshot_cgp_type! { + #[cgp_type] + pub trait HasFooType { + type Foo; + } + + expand_has_foo_type(output) { + insta::assert_snapshot!(output, @" + pub trait HasFooType { + type Foo; + } + impl<__Context__> HasFooType for __Context__ + where + __Context__: FooTypeProvider<__Context__>, + { + type Foo = <__Context__ as FooTypeProvider<__Context__>>::Foo; + } + pub trait FooTypeProvider< + __Context__, + >: IsProviderFor { + type Foo; + } + impl<__Provider__, __Context__> FooTypeProvider<__Context__> for __Provider__ + where + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + FooTypeProviderComponent, + >>::Delegate: FooTypeProvider<__Context__>, + { + type Foo = <<__Provider__ as DelegateComponent< + FooTypeProviderComponent, + >>::Delegate as FooTypeProvider<__Context__>>::Foo; + } + pub struct FooTypeProviderComponent; + impl<__Context__> FooTypeProvider<__Context__> for UseContext + where + __Context__: HasFooType, + { + type Foo = <__Context__ as HasFooType>::Foo; + } + impl<__Context__> IsProviderFor for UseContext + where + __Context__: HasFooType, + {} + impl<__Context__, __Components__, __Path__> FooTypeProvider<__Context__> + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: FooTypeProvider<__Context__>, + { + type Foo = <<__Components__ as DelegateComponent< + __Path__, + >>::Delegate as FooTypeProvider<__Context__>>::Foo; + } + impl< + __Context__, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: IsProviderFor + + FooTypeProvider<__Context__>, + {} + impl FooTypeProvider<__Context__> for UseType + where + Foo:, + { + type Foo = Foo; + } + impl IsProviderFor + for UseType + where + Foo:, + {} + impl<__Provider__, Foo, __Context__> FooTypeProvider<__Context__> + for WithProvider<__Provider__> + where + __Provider__: TypeProvider<__Context__, FooTypeProviderComponent, Type = Foo>, + Foo:, + { + type Foo = Foo; + } + impl< + __Provider__, + Foo, + __Context__, + > IsProviderFor for WithProvider<__Provider__> + where + __Provider__: TypeProvider<__Context__, FooTypeProviderComponent, Type = Foo>, + Foo:, + {} + ") + } } - #[cgp_type] - pub trait HasBarType { - type Bar; + snapshot_cgp_type! { + #[cgp_type] + pub trait HasBarType { + type Bar; + } + + expand_has_bar_type(output) { + insta::assert_snapshot!(output, @" + pub trait HasBarType { + type Bar; + } + impl<__Context__> HasBarType for __Context__ + where + __Context__: BarTypeProvider<__Context__>, + { + type Bar = <__Context__ as BarTypeProvider<__Context__>>::Bar; + } + pub trait BarTypeProvider< + __Context__, + >: IsProviderFor { + type Bar; + } + impl<__Provider__, __Context__> BarTypeProvider<__Context__> for __Provider__ + where + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + BarTypeProviderComponent, + >>::Delegate: BarTypeProvider<__Context__>, + { + type Bar = <<__Provider__ as DelegateComponent< + BarTypeProviderComponent, + >>::Delegate as BarTypeProvider<__Context__>>::Bar; + } + pub struct BarTypeProviderComponent; + impl<__Context__> BarTypeProvider<__Context__> for UseContext + where + __Context__: HasBarType, + { + type Bar = <__Context__ as HasBarType>::Bar; + } + impl<__Context__> IsProviderFor for UseContext + where + __Context__: HasBarType, + {} + impl<__Context__, __Components__, __Path__> BarTypeProvider<__Context__> + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: BarTypeProvider<__Context__>, + { + type Bar = <<__Components__ as DelegateComponent< + __Path__, + >>::Delegate as BarTypeProvider<__Context__>>::Bar; + } + impl< + __Context__, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: IsProviderFor + + BarTypeProvider<__Context__>, + {} + impl BarTypeProvider<__Context__> for UseType + where + Bar:, + { + type Bar = Bar; + } + impl IsProviderFor + for UseType + where + Bar:, + {} + impl<__Provider__, Bar, __Context__> BarTypeProvider<__Context__> + for WithProvider<__Provider__> + where + __Provider__: TypeProvider<__Context__, BarTypeProviderComponent, Type = Bar>, + Bar:, + { + type Bar = Bar; + } + impl< + __Provider__, + Bar, + __Context__, + > IsProviderFor for WithProvider<__Provider__> + where + __Provider__: TypeProvider<__Context__, BarTypeProviderComponent, Type = Bar>, + Bar:, + {} + ") + } } snapshot_cgp_getter! { diff --git a/crates/tests/cgp-tests/src/tests/delegate_and_check_components.rs b/crates/tests/cgp-tests/src/tests/delegate_and_check_components.rs index 2e51ee63..bcfe4e46 100644 --- a/crates/tests/cgp-tests/src/tests/delegate_and_check_components.rs +++ b/crates/tests/cgp-tests/src/tests/delegate_and_check_components.rs @@ -2,11 +2,110 @@ mod basic_delegate_and_check_components { use cgp::prelude::*; - use cgp_macro_test_util::snapshot_cgp_getter; + use cgp_macro_test_util::{snapshot_cgp_getter, snapshot_cgp_type}; - #[cgp_type] - pub trait HasNameType { - type Name; + snapshot_cgp_type! { + #[cgp_type] + pub trait HasNameType { + type Name; + } + + expand_has_name_type(output) { + insta::assert_snapshot!(output, @" + pub trait HasNameType { + type Name; + } + impl<__Context__> HasNameType for __Context__ + where + __Context__: NameTypeProvider<__Context__>, + { + type Name = <__Context__ as NameTypeProvider<__Context__>>::Name; + } + pub trait NameTypeProvider< + __Context__, + >: IsProviderFor { + type Name; + } + impl<__Provider__, __Context__> NameTypeProvider<__Context__> for __Provider__ + where + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + NameTypeProviderComponent, + >>::Delegate: NameTypeProvider<__Context__>, + { + type Name = <<__Provider__ as DelegateComponent< + NameTypeProviderComponent, + >>::Delegate as NameTypeProvider<__Context__>>::Name; + } + pub struct NameTypeProviderComponent; + impl<__Context__> NameTypeProvider<__Context__> for UseContext + where + __Context__: HasNameType, + { + type Name = <__Context__ as HasNameType>::Name; + } + impl<__Context__> IsProviderFor + for UseContext + where + __Context__: HasNameType, + {} + impl<__Context__, __Components__, __Path__> NameTypeProvider<__Context__> + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: NameTypeProvider<__Context__>, + { + type Name = <<__Components__ as DelegateComponent< + __Path__, + >>::Delegate as NameTypeProvider<__Context__>>::Name; + } + impl< + __Context__, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: IsProviderFor + + NameTypeProvider<__Context__>, + {} + impl NameTypeProvider<__Context__> for UseType + where + Name:, + { + type Name = Name; + } + impl IsProviderFor + for UseType + where + Name:, + {} + impl<__Provider__, Name, __Context__> NameTypeProvider<__Context__> + for WithProvider<__Provider__> + where + __Provider__: TypeProvider<__Context__, NameTypeProviderComponent, Type = Name>, + Name:, + { + type Name = Name; + } + impl< + __Provider__, + Name, + __Context__, + > IsProviderFor + for WithProvider<__Provider__> + where + __Provider__: TypeProvider<__Context__, NameTypeProviderComponent, Type = Name>, + Name:, + {} + ") + } } snapshot_cgp_getter! { @@ -176,11 +275,110 @@ mod basic_delegate_and_check_components { mod generic_delegate_and_check_components { use cgp::prelude::*; - use cgp_macro_test_util::snapshot_cgp_getter; + use cgp_macro_test_util::{snapshot_cgp_getter, snapshot_cgp_type}; - #[cgp_type] - pub trait HasNameType { - type Name; + snapshot_cgp_type! { + #[cgp_type] + pub trait HasNameType { + type Name; + } + + expand_has_name_type(output) { + insta::assert_snapshot!(output, @" + pub trait HasNameType { + type Name; + } + impl<__Context__> HasNameType for __Context__ + where + __Context__: NameTypeProvider<__Context__>, + { + type Name = <__Context__ as NameTypeProvider<__Context__>>::Name; + } + pub trait NameTypeProvider< + __Context__, + >: IsProviderFor { + type Name; + } + impl<__Provider__, __Context__> NameTypeProvider<__Context__> for __Provider__ + where + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + NameTypeProviderComponent, + >>::Delegate: NameTypeProvider<__Context__>, + { + type Name = <<__Provider__ as DelegateComponent< + NameTypeProviderComponent, + >>::Delegate as NameTypeProvider<__Context__>>::Name; + } + pub struct NameTypeProviderComponent; + impl<__Context__> NameTypeProvider<__Context__> for UseContext + where + __Context__: HasNameType, + { + type Name = <__Context__ as HasNameType>::Name; + } + impl<__Context__> IsProviderFor + for UseContext + where + __Context__: HasNameType, + {} + impl<__Context__, __Components__, __Path__> NameTypeProvider<__Context__> + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: NameTypeProvider<__Context__>, + { + type Name = <<__Components__ as DelegateComponent< + __Path__, + >>::Delegate as NameTypeProvider<__Context__>>::Name; + } + impl< + __Context__, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: IsProviderFor + + NameTypeProvider<__Context__>, + {} + impl NameTypeProvider<__Context__> for UseType + where + Name:, + { + type Name = Name; + } + impl IsProviderFor + for UseType + where + Name:, + {} + impl<__Provider__, Name, __Context__> NameTypeProvider<__Context__> + for WithProvider<__Provider__> + where + __Provider__: TypeProvider<__Context__, NameTypeProviderComponent, Type = Name>, + Name:, + { + type Name = Name; + } + impl< + __Provider__, + Name, + __Context__, + > IsProviderFor + for WithProvider<__Provider__> + where + __Provider__: TypeProvider<__Context__, NameTypeProviderComponent, Type = Name>, + Name:, + {} + ") + } } snapshot_cgp_getter! { diff --git a/crates/tests/cgp-tests/src/tests/use_delegate/getter.rs b/crates/tests/cgp-tests/src/tests/use_delegate/getter.rs index 1020f44c..88d687f1 100644 --- a/crates/tests/cgp-tests/src/tests/use_delegate/getter.rs +++ b/crates/tests/cgp-tests/src/tests/use_delegate/getter.rs @@ -1,19 +1,187 @@ use core::marker::PhantomData; use cgp::prelude::*; -use cgp_macro_test_util::snapshot_cgp_getter; +use cgp_macro_test_util::{snapshot_cgp_getter, snapshot_cgp_type}; pub struct UseDelegate2(pub PhantomData); -#[cgp_type { - provider: FooTypeProviderAt, - derive_delegate: [ - UseDelegate, - UseDelegate2<(I, J)>, - ], -}] -pub trait HasFooTypeAt { - type Foo; +snapshot_cgp_type! { + #[cgp_type { + provider: FooTypeProviderAt, + derive_delegate: [ + UseDelegate, + UseDelegate2<(I, J)>, + ], + }] + pub trait HasFooTypeAt { + type Foo; + } + + expand_has_foo_type_at(output) { + insta::assert_snapshot!(output, @" + pub trait HasFooTypeAt { + type Foo; + } + impl<__Context__, I, J> HasFooTypeAt for __Context__ + where + __Context__: FooTypeProviderAt<__Context__, I, J>, + { + type Foo = <__Context__ as FooTypeProviderAt<__Context__, I, J>>::Foo; + } + pub trait FooTypeProviderAt< + __Context__, + I, + J, + >: IsProviderFor { + type Foo; + } + impl<__Provider__, __Context__, I, J> FooTypeProviderAt<__Context__, I, J> + for __Provider__ + where + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + FooTypeProviderAtComponent, + >>::Delegate: FooTypeProviderAt<__Context__, I, J>, + { + type Foo = <<__Provider__ as DelegateComponent< + FooTypeProviderAtComponent, + >>::Delegate as FooTypeProviderAt<__Context__, I, J>>::Foo; + } + pub struct FooTypeProviderAtComponent; + impl<__Context__, I, J> FooTypeProviderAt<__Context__, I, J> for UseContext + where + __Context__: HasFooTypeAt, + { + type Foo = <__Context__ as HasFooTypeAt>::Foo; + } + impl<__Context__, I, J> IsProviderFor + for UseContext + where + __Context__: HasFooTypeAt, + {} + impl<__Context__, I, J, __Components__, __Path__> FooTypeProviderAt<__Context__, I, J> + for RedirectLookup<__Components__, __Path__> + where + __Path__: ConcatPath>>, + __Components__: DelegateComponent< + <__Path__ as ConcatPath>>>::Output, + >, + <__Components__ as DelegateComponent< + <__Path__ as ConcatPath>>>::Output, + >>::Delegate: FooTypeProviderAt<__Context__, I, J>, + { + type Foo = <<__Components__ as DelegateComponent< + <__Path__ as ConcatPath>>>::Output, + >>::Delegate as FooTypeProviderAt<__Context__, I, J>>::Foo; + } + impl< + __Context__, + I, + J, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Path__: ConcatPath>>, + __Components__: DelegateComponent< + <__Path__ as ConcatPath>>>::Output, + >, + <__Components__ as DelegateComponent< + <__Path__ as ConcatPath>>>::Output, + >>::Delegate: IsProviderFor + + FooTypeProviderAt<__Context__, I, J>, + {} + impl< + __Context__, + I, + J, + __Components__, + __Delegate__, + > FooTypeProviderAt<__Context__, I, J> for UseDelegate<__Components__> + where + __Components__: DelegateComponent<(I), Delegate = __Delegate__>, + __Delegate__: FooTypeProviderAt<__Context__, I, J>, + { + type Foo = <__Delegate__ as FooTypeProviderAt<__Context__, I, J>>::Foo; + } + impl< + __Context__, + I, + J, + __Components__, + __Delegate__, + > IsProviderFor + for UseDelegate<__Components__> + where + __Components__: DelegateComponent<(I), Delegate = __Delegate__>, + __Delegate__: IsProviderFor + + FooTypeProviderAt<__Context__, I, J>, + {} + impl< + __Context__, + I, + J, + __Components__, + __Delegate__, + > FooTypeProviderAt<__Context__, I, J> for UseDelegate2<__Components__> + where + __Components__: DelegateComponent<(I, J), Delegate = __Delegate__>, + __Delegate__: FooTypeProviderAt<__Context__, I, J>, + { + type Foo = <__Delegate__ as FooTypeProviderAt<__Context__, I, J>>::Foo; + } + impl< + __Context__, + I, + J, + __Components__, + __Delegate__, + > IsProviderFor + for UseDelegate2<__Components__> + where + __Components__: DelegateComponent<(I, J), Delegate = __Delegate__>, + __Delegate__: IsProviderFor + + FooTypeProviderAt<__Context__, I, J>, + {} + impl FooTypeProviderAt<__Context__, I, J> for UseType + where + Foo:, + { + type Foo = Foo; + } + impl< + Foo, + __Context__, + I, + J, + > IsProviderFor for UseType + where + Foo:, + {} + impl<__Provider__, Foo, __Context__, I, J> FooTypeProviderAt<__Context__, I, J> + for WithProvider<__Provider__> + where + __Provider__: TypeProvider<__Context__, FooTypeProviderAtComponent, Type = Foo>, + Foo:, + { + type Foo = Foo; + } + impl< + __Provider__, + Foo, + __Context__, + I, + J, + > IsProviderFor + for WithProvider<__Provider__> + where + __Provider__: TypeProvider<__Context__, FooTypeProviderAtComponent, Type = Foo>, + Foo:, + {} + ") + } } snapshot_cgp_getter! { diff --git a/crates/tests/cgp-tests/tests/cgp_fn_tests/extend.rs b/crates/tests/cgp-tests/tests/cgp_fn_tests/extend.rs index 9ad795a0..531546c6 100644 --- a/crates/tests/cgp-tests/tests/cgp_fn_tests/extend.rs +++ b/crates/tests/cgp-tests/tests/cgp_fn_tests/extend.rs @@ -1,11 +1,110 @@ use std::ops::Mul; use cgp::prelude::*; -use cgp_macro_test_util::snapshot_cgp_fn; +use cgp_macro_test_util::{snapshot_cgp_fn, snapshot_cgp_type}; -#[cgp_type] -pub trait HasScalarType { - type Scalar; +snapshot_cgp_type! { + #[cgp_type] + pub trait HasScalarType { + type Scalar; + } + + expand_has_scalar_type(output) { + insta::assert_snapshot!(output, @" + pub trait HasScalarType { + type Scalar; + } + impl<__Context__> HasScalarType for __Context__ + where + __Context__: ScalarTypeProvider<__Context__>, + { + type Scalar = <__Context__ as ScalarTypeProvider<__Context__>>::Scalar; + } + pub trait ScalarTypeProvider< + __Context__, + >: IsProviderFor { + type Scalar; + } + impl<__Provider__, __Context__> ScalarTypeProvider<__Context__> for __Provider__ + where + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + ScalarTypeProviderComponent, + >>::Delegate: ScalarTypeProvider<__Context__>, + { + type Scalar = <<__Provider__ as DelegateComponent< + ScalarTypeProviderComponent, + >>::Delegate as ScalarTypeProvider<__Context__>>::Scalar; + } + pub struct ScalarTypeProviderComponent; + impl<__Context__> ScalarTypeProvider<__Context__> for UseContext + where + __Context__: HasScalarType, + { + type Scalar = <__Context__ as HasScalarType>::Scalar; + } + impl<__Context__> IsProviderFor + for UseContext + where + __Context__: HasScalarType, + {} + impl<__Context__, __Components__, __Path__> ScalarTypeProvider<__Context__> + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: ScalarTypeProvider<__Context__>, + { + type Scalar = <<__Components__ as DelegateComponent< + __Path__, + >>::Delegate as ScalarTypeProvider<__Context__>>::Scalar; + } + impl< + __Context__, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: IsProviderFor + + ScalarTypeProvider<__Context__>, + {} + impl ScalarTypeProvider<__Context__> for UseType + where + Scalar:, + { + type Scalar = Scalar; + } + impl IsProviderFor + for UseType + where + Scalar:, + {} + impl<__Provider__, Scalar, __Context__> ScalarTypeProvider<__Context__> + for WithProvider<__Provider__> + where + __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, + Scalar:, + { + type Scalar = Scalar; + } + impl< + __Provider__, + Scalar, + __Context__, + > IsProviderFor + for WithProvider<__Provider__> + where + __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, + Scalar:, + {} + ") + } } snapshot_cgp_fn! { diff --git a/crates/tests/cgp-tests/tests/cgp_fn_tests/foreign_type.rs b/crates/tests/cgp-tests/tests/cgp_fn_tests/foreign_type.rs index ad6d2ff4..91d804fa 100644 --- a/crates/tests/cgp-tests/tests/cgp_fn_tests/foreign_type.rs +++ b/crates/tests/cgp-tests/tests/cgp_fn_tests/foreign_type.rs @@ -1,11 +1,110 @@ use std::ops::Mul; use cgp::prelude::*; -use cgp_macro_test_util::snapshot_cgp_fn; +use cgp_macro_test_util::{snapshot_cgp_fn, snapshot_cgp_type}; -#[cgp_type] -pub trait HasScalarType { - type Scalar; +snapshot_cgp_type! { + #[cgp_type] + pub trait HasScalarType { + type Scalar; + } + + expand_has_scalar_type(output) { + insta::assert_snapshot!(output, @" + pub trait HasScalarType { + type Scalar; + } + impl<__Context__> HasScalarType for __Context__ + where + __Context__: ScalarTypeProvider<__Context__>, + { + type Scalar = <__Context__ as ScalarTypeProvider<__Context__>>::Scalar; + } + pub trait ScalarTypeProvider< + __Context__, + >: IsProviderFor { + type Scalar; + } + impl<__Provider__, __Context__> ScalarTypeProvider<__Context__> for __Provider__ + where + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + ScalarTypeProviderComponent, + >>::Delegate: ScalarTypeProvider<__Context__>, + { + type Scalar = <<__Provider__ as DelegateComponent< + ScalarTypeProviderComponent, + >>::Delegate as ScalarTypeProvider<__Context__>>::Scalar; + } + pub struct ScalarTypeProviderComponent; + impl<__Context__> ScalarTypeProvider<__Context__> for UseContext + where + __Context__: HasScalarType, + { + type Scalar = <__Context__ as HasScalarType>::Scalar; + } + impl<__Context__> IsProviderFor + for UseContext + where + __Context__: HasScalarType, + {} + impl<__Context__, __Components__, __Path__> ScalarTypeProvider<__Context__> + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: ScalarTypeProvider<__Context__>, + { + type Scalar = <<__Components__ as DelegateComponent< + __Path__, + >>::Delegate as ScalarTypeProvider<__Context__>>::Scalar; + } + impl< + __Context__, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: IsProviderFor + + ScalarTypeProvider<__Context__>, + {} + impl ScalarTypeProvider<__Context__> for UseType + where + Scalar:, + { + type Scalar = Scalar; + } + impl IsProviderFor + for UseType + where + Scalar:, + {} + impl<__Provider__, Scalar, __Context__> ScalarTypeProvider<__Context__> + for WithProvider<__Provider__> + where + __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, + Scalar:, + { + type Scalar = Scalar; + } + impl< + __Provider__, + Scalar, + __Context__, + > IsProviderFor + for WithProvider<__Provider__> + where + __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, + Scalar:, + {} + ") + } } snapshot_cgp_fn! { diff --git a/crates/tests/cgp-tests/tests/cgp_fn_tests/foreign_type_equality.rs b/crates/tests/cgp-tests/tests/cgp_fn_tests/foreign_type_equality.rs index e160bef6..bf76eb08 100644 --- a/crates/tests/cgp-tests/tests/cgp_fn_tests/foreign_type_equality.rs +++ b/crates/tests/cgp-tests/tests/cgp_fn_tests/foreign_type_equality.rs @@ -1,14 +1,212 @@ use cgp::prelude::*; -use cgp_macro_test_util::snapshot_cgp_fn; +use cgp_macro_test_util::{snapshot_cgp_fn, snapshot_cgp_type}; -#[cgp_type] -pub trait HasScalarType { - type Scalar; +snapshot_cgp_type! { + #[cgp_type] + pub trait HasScalarType { + type Scalar; + } + + expand_has_scalar_type(output) { + insta::assert_snapshot!(output, @" + pub trait HasScalarType { + type Scalar; + } + impl<__Context__> HasScalarType for __Context__ + where + __Context__: ScalarTypeProvider<__Context__>, + { + type Scalar = <__Context__ as ScalarTypeProvider<__Context__>>::Scalar; + } + pub trait ScalarTypeProvider< + __Context__, + >: IsProviderFor { + type Scalar; + } + impl<__Provider__, __Context__> ScalarTypeProvider<__Context__> for __Provider__ + where + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + ScalarTypeProviderComponent, + >>::Delegate: ScalarTypeProvider<__Context__>, + { + type Scalar = <<__Provider__ as DelegateComponent< + ScalarTypeProviderComponent, + >>::Delegate as ScalarTypeProvider<__Context__>>::Scalar; + } + pub struct ScalarTypeProviderComponent; + impl<__Context__> ScalarTypeProvider<__Context__> for UseContext + where + __Context__: HasScalarType, + { + type Scalar = <__Context__ as HasScalarType>::Scalar; + } + impl<__Context__> IsProviderFor + for UseContext + where + __Context__: HasScalarType, + {} + impl<__Context__, __Components__, __Path__> ScalarTypeProvider<__Context__> + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: ScalarTypeProvider<__Context__>, + { + type Scalar = <<__Components__ as DelegateComponent< + __Path__, + >>::Delegate as ScalarTypeProvider<__Context__>>::Scalar; + } + impl< + __Context__, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: IsProviderFor + + ScalarTypeProvider<__Context__>, + {} + impl ScalarTypeProvider<__Context__> for UseType + where + Scalar:, + { + type Scalar = Scalar; + } + impl IsProviderFor + for UseType + where + Scalar:, + {} + impl<__Provider__, Scalar, __Context__> ScalarTypeProvider<__Context__> + for WithProvider<__Provider__> + where + __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, + Scalar:, + { + type Scalar = Scalar; + } + impl< + __Provider__, + Scalar, + __Context__, + > IsProviderFor + for WithProvider<__Provider__> + where + __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, + Scalar:, + {} + ") + } } -#[cgp_type] -pub trait HasTypes { - type Types: HasScalarType; +snapshot_cgp_type! { + #[cgp_type] + pub trait HasTypes { + type Types: HasScalarType; + } + + expand_has_types(output) { + insta::assert_snapshot!(output, @" + pub trait HasTypes { + type Types: HasScalarType; + } + impl<__Context__> HasTypes for __Context__ + where + __Context__: TypesTypeProvider<__Context__>, + { + type Types = <__Context__ as TypesTypeProvider<__Context__>>::Types; + } + pub trait TypesTypeProvider< + __Context__, + >: IsProviderFor { + type Types: HasScalarType; + } + impl<__Provider__, __Context__> TypesTypeProvider<__Context__> for __Provider__ + where + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + TypesTypeProviderComponent, + >>::Delegate: TypesTypeProvider<__Context__>, + { + type Types = <<__Provider__ as DelegateComponent< + TypesTypeProviderComponent, + >>::Delegate as TypesTypeProvider<__Context__>>::Types; + } + pub struct TypesTypeProviderComponent; + impl<__Context__> TypesTypeProvider<__Context__> for UseContext + where + __Context__: HasTypes, + { + type Types = <__Context__ as HasTypes>::Types; + } + impl<__Context__> IsProviderFor + for UseContext + where + __Context__: HasTypes, + {} + impl<__Context__, __Components__, __Path__> TypesTypeProvider<__Context__> + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: TypesTypeProvider<__Context__>, + { + type Types = <<__Components__ as DelegateComponent< + __Path__, + >>::Delegate as TypesTypeProvider<__Context__>>::Types; + } + impl< + __Context__, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: IsProviderFor + + TypesTypeProvider<__Context__>, + {} + impl TypesTypeProvider<__Context__> for UseType + where + Types: HasScalarType, + { + type Types = Types; + } + impl IsProviderFor + for UseType + where + Types: HasScalarType, + {} + impl<__Provider__, Types, __Context__> TypesTypeProvider<__Context__> + for WithProvider<__Provider__> + where + __Provider__: TypeProvider<__Context__, TypesTypeProviderComponent, Type = Types>, + Types: HasScalarType, + { + type Types = Types; + } + impl< + __Provider__, + Types, + __Context__, + > IsProviderFor + for WithProvider<__Provider__> + where + __Provider__: TypeProvider<__Context__, TypesTypeProviderComponent, Type = Types>, + Types: HasScalarType, + {} + ") + } } snapshot_cgp_fn! { diff --git a/crates/tests/cgp-tests/tests/cgp_fn_tests/nested_foreign_type.rs b/crates/tests/cgp-tests/tests/cgp_fn_tests/nested_foreign_type.rs index db802328..f9669016 100644 --- a/crates/tests/cgp-tests/tests/cgp_fn_tests/nested_foreign_type.rs +++ b/crates/tests/cgp-tests/tests/cgp_fn_tests/nested_foreign_type.rs @@ -1,16 +1,214 @@ use std::ops::Mul; use cgp::prelude::*; -use cgp_macro_test_util::snapshot_cgp_fn; +use cgp_macro_test_util::{snapshot_cgp_fn, snapshot_cgp_type}; -#[cgp_type] -pub trait HasScalarType { - type Scalar; +snapshot_cgp_type! { + #[cgp_type] + pub trait HasScalarType { + type Scalar; + } + + expand_has_scalar_type(output) { + insta::assert_snapshot!(output, @" + pub trait HasScalarType { + type Scalar; + } + impl<__Context__> HasScalarType for __Context__ + where + __Context__: ScalarTypeProvider<__Context__>, + { + type Scalar = <__Context__ as ScalarTypeProvider<__Context__>>::Scalar; + } + pub trait ScalarTypeProvider< + __Context__, + >: IsProviderFor { + type Scalar; + } + impl<__Provider__, __Context__> ScalarTypeProvider<__Context__> for __Provider__ + where + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + ScalarTypeProviderComponent, + >>::Delegate: ScalarTypeProvider<__Context__>, + { + type Scalar = <<__Provider__ as DelegateComponent< + ScalarTypeProviderComponent, + >>::Delegate as ScalarTypeProvider<__Context__>>::Scalar; + } + pub struct ScalarTypeProviderComponent; + impl<__Context__> ScalarTypeProvider<__Context__> for UseContext + where + __Context__: HasScalarType, + { + type Scalar = <__Context__ as HasScalarType>::Scalar; + } + impl<__Context__> IsProviderFor + for UseContext + where + __Context__: HasScalarType, + {} + impl<__Context__, __Components__, __Path__> ScalarTypeProvider<__Context__> + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: ScalarTypeProvider<__Context__>, + { + type Scalar = <<__Components__ as DelegateComponent< + __Path__, + >>::Delegate as ScalarTypeProvider<__Context__>>::Scalar; + } + impl< + __Context__, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: IsProviderFor + + ScalarTypeProvider<__Context__>, + {} + impl ScalarTypeProvider<__Context__> for UseType + where + Scalar:, + { + type Scalar = Scalar; + } + impl IsProviderFor + for UseType + where + Scalar:, + {} + impl<__Provider__, Scalar, __Context__> ScalarTypeProvider<__Context__> + for WithProvider<__Provider__> + where + __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, + Scalar:, + { + type Scalar = Scalar; + } + impl< + __Provider__, + Scalar, + __Context__, + > IsProviderFor + for WithProvider<__Provider__> + where + __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, + Scalar:, + {} + ") + } } -#[cgp_type] -pub trait HasTypes { - type Types; +snapshot_cgp_type! { + #[cgp_type] + pub trait HasTypes { + type Types; + } + + expand_has_types(output) { + insta::assert_snapshot!(output, @" + pub trait HasTypes { + type Types; + } + impl<__Context__> HasTypes for __Context__ + where + __Context__: TypesTypeProvider<__Context__>, + { + type Types = <__Context__ as TypesTypeProvider<__Context__>>::Types; + } + pub trait TypesTypeProvider< + __Context__, + >: IsProviderFor { + type Types; + } + impl<__Provider__, __Context__> TypesTypeProvider<__Context__> for __Provider__ + where + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + TypesTypeProviderComponent, + >>::Delegate: TypesTypeProvider<__Context__>, + { + type Types = <<__Provider__ as DelegateComponent< + TypesTypeProviderComponent, + >>::Delegate as TypesTypeProvider<__Context__>>::Types; + } + pub struct TypesTypeProviderComponent; + impl<__Context__> TypesTypeProvider<__Context__> for UseContext + where + __Context__: HasTypes, + { + type Types = <__Context__ as HasTypes>::Types; + } + impl<__Context__> IsProviderFor + for UseContext + where + __Context__: HasTypes, + {} + impl<__Context__, __Components__, __Path__> TypesTypeProvider<__Context__> + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: TypesTypeProvider<__Context__>, + { + type Types = <<__Components__ as DelegateComponent< + __Path__, + >>::Delegate as TypesTypeProvider<__Context__>>::Types; + } + impl< + __Context__, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: IsProviderFor + + TypesTypeProvider<__Context__>, + {} + impl TypesTypeProvider<__Context__> for UseType + where + Types:, + { + type Types = Types; + } + impl IsProviderFor + for UseType + where + Types:, + {} + impl<__Provider__, Types, __Context__> TypesTypeProvider<__Context__> + for WithProvider<__Provider__> + where + __Provider__: TypeProvider<__Context__, TypesTypeProviderComponent, Type = Types>, + Types:, + { + type Types = Types; + } + impl< + __Provider__, + Types, + __Context__, + > IsProviderFor + for WithProvider<__Provider__> + where + __Provider__: TypeProvider<__Context__, TypesTypeProviderComponent, Type = Types>, + Types:, + {} + ") + } } snapshot_cgp_fn! { diff --git a/crates/tests/cgp-tests/tests/cgp_fn_tests/type_equality.rs b/crates/tests/cgp-tests/tests/cgp_fn_tests/type_equality.rs index 642fa78c..96cbf81b 100644 --- a/crates/tests/cgp-tests/tests/cgp_fn_tests/type_equality.rs +++ b/crates/tests/cgp-tests/tests/cgp_fn_tests/type_equality.rs @@ -1,11 +1,110 @@ use std::fmt::Display; use cgp::prelude::*; -use cgp_macro_test_util::snapshot_cgp_fn; +use cgp_macro_test_util::{snapshot_cgp_fn, snapshot_cgp_type}; -#[cgp_type] -pub trait HasScalarType { - type Scalar; +snapshot_cgp_type! { + #[cgp_type] + pub trait HasScalarType { + type Scalar; + } + + expand_has_scalar_type(output) { + insta::assert_snapshot!(output, @" + pub trait HasScalarType { + type Scalar; + } + impl<__Context__> HasScalarType for __Context__ + where + __Context__: ScalarTypeProvider<__Context__>, + { + type Scalar = <__Context__ as ScalarTypeProvider<__Context__>>::Scalar; + } + pub trait ScalarTypeProvider< + __Context__, + >: IsProviderFor { + type Scalar; + } + impl<__Provider__, __Context__> ScalarTypeProvider<__Context__> for __Provider__ + where + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + ScalarTypeProviderComponent, + >>::Delegate: ScalarTypeProvider<__Context__>, + { + type Scalar = <<__Provider__ as DelegateComponent< + ScalarTypeProviderComponent, + >>::Delegate as ScalarTypeProvider<__Context__>>::Scalar; + } + pub struct ScalarTypeProviderComponent; + impl<__Context__> ScalarTypeProvider<__Context__> for UseContext + where + __Context__: HasScalarType, + { + type Scalar = <__Context__ as HasScalarType>::Scalar; + } + impl<__Context__> IsProviderFor + for UseContext + where + __Context__: HasScalarType, + {} + impl<__Context__, __Components__, __Path__> ScalarTypeProvider<__Context__> + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: ScalarTypeProvider<__Context__>, + { + type Scalar = <<__Components__ as DelegateComponent< + __Path__, + >>::Delegate as ScalarTypeProvider<__Context__>>::Scalar; + } + impl< + __Context__, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: IsProviderFor + + ScalarTypeProvider<__Context__>, + {} + impl ScalarTypeProvider<__Context__> for UseType + where + Scalar:, + { + type Scalar = Scalar; + } + impl IsProviderFor + for UseType + where + Scalar:, + {} + impl<__Provider__, Scalar, __Context__> ScalarTypeProvider<__Context__> + for WithProvider<__Provider__> + where + __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, + Scalar:, + { + type Scalar = Scalar; + } + impl< + __Provider__, + Scalar, + __Context__, + > IsProviderFor + for WithProvider<__Provider__> + where + __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, + Scalar:, + {} + ") + } } snapshot_cgp_fn! { diff --git a/crates/tests/cgp-tests/tests/cgp_fn_tests/use_type.rs b/crates/tests/cgp-tests/tests/cgp_fn_tests/use_type.rs index 3c11d95f..04b4abee 100644 --- a/crates/tests/cgp-tests/tests/cgp_fn_tests/use_type.rs +++ b/crates/tests/cgp-tests/tests/cgp_fn_tests/use_type.rs @@ -2,11 +2,110 @@ use core::f64; use std::ops::Mul; use cgp::prelude::*; -use cgp_macro_test_util::snapshot_cgp_fn; +use cgp_macro_test_util::{snapshot_cgp_fn, snapshot_cgp_type}; -#[cgp_type] -pub trait HasScalarType { - type Scalar: Mul + Copy; +snapshot_cgp_type! { + #[cgp_type] + pub trait HasScalarType { + type Scalar: Mul + Copy; + } + + expand_has_scalar_type(output) { + insta::assert_snapshot!(output, @" + pub trait HasScalarType { + type Scalar: Mul + Copy; + } + impl<__Context__> HasScalarType for __Context__ + where + __Context__: ScalarTypeProvider<__Context__>, + { + type Scalar = <__Context__ as ScalarTypeProvider<__Context__>>::Scalar; + } + pub trait ScalarTypeProvider< + __Context__, + >: IsProviderFor { + type Scalar: Mul + Copy; + } + impl<__Provider__, __Context__> ScalarTypeProvider<__Context__> for __Provider__ + where + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + ScalarTypeProviderComponent, + >>::Delegate: ScalarTypeProvider<__Context__>, + { + type Scalar = <<__Provider__ as DelegateComponent< + ScalarTypeProviderComponent, + >>::Delegate as ScalarTypeProvider<__Context__>>::Scalar; + } + pub struct ScalarTypeProviderComponent; + impl<__Context__> ScalarTypeProvider<__Context__> for UseContext + where + __Context__: HasScalarType, + { + type Scalar = <__Context__ as HasScalarType>::Scalar; + } + impl<__Context__> IsProviderFor + for UseContext + where + __Context__: HasScalarType, + {} + impl<__Context__, __Components__, __Path__> ScalarTypeProvider<__Context__> + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: ScalarTypeProvider<__Context__>, + { + type Scalar = <<__Components__ as DelegateComponent< + __Path__, + >>::Delegate as ScalarTypeProvider<__Context__>>::Scalar; + } + impl< + __Context__, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: IsProviderFor + + ScalarTypeProvider<__Context__>, + {} + impl ScalarTypeProvider<__Context__> for UseType + where + Scalar: Mul + Copy, + { + type Scalar = Scalar; + } + impl IsProviderFor + for UseType + where + Scalar: Mul + Copy, + {} + impl<__Provider__, Scalar, __Context__> ScalarTypeProvider<__Context__> + for WithProvider<__Provider__> + where + __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, + Scalar: Mul + Copy, + { + type Scalar = Scalar; + } + impl< + __Provider__, + Scalar, + __Context__, + > IsProviderFor + for WithProvider<__Provider__> + where + __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, + Scalar: Mul + Copy, + {} + ") + } } snapshot_cgp_fn! { diff --git a/crates/tests/cgp-tests/tests/cgp_fn_tests/use_type_alias.rs b/crates/tests/cgp-tests/tests/cgp_fn_tests/use_type_alias.rs index 9c80e765..8e85f7c5 100644 --- a/crates/tests/cgp-tests/tests/cgp_fn_tests/use_type_alias.rs +++ b/crates/tests/cgp-tests/tests/cgp_fn_tests/use_type_alias.rs @@ -1,11 +1,110 @@ use std::ops::Mul; use cgp::prelude::*; -use cgp_macro_test_util::snapshot_cgp_fn; +use cgp_macro_test_util::{snapshot_cgp_fn, snapshot_cgp_type}; -#[cgp_type] -pub trait HasScalarType { - type Scalar; +snapshot_cgp_type! { + #[cgp_type] + pub trait HasScalarType { + type Scalar; + } + + expand_has_scalar_type(output) { + insta::assert_snapshot!(output, @" + pub trait HasScalarType { + type Scalar; + } + impl<__Context__> HasScalarType for __Context__ + where + __Context__: ScalarTypeProvider<__Context__>, + { + type Scalar = <__Context__ as ScalarTypeProvider<__Context__>>::Scalar; + } + pub trait ScalarTypeProvider< + __Context__, + >: IsProviderFor { + type Scalar; + } + impl<__Provider__, __Context__> ScalarTypeProvider<__Context__> for __Provider__ + where + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + ScalarTypeProviderComponent, + >>::Delegate: ScalarTypeProvider<__Context__>, + { + type Scalar = <<__Provider__ as DelegateComponent< + ScalarTypeProviderComponent, + >>::Delegate as ScalarTypeProvider<__Context__>>::Scalar; + } + pub struct ScalarTypeProviderComponent; + impl<__Context__> ScalarTypeProvider<__Context__> for UseContext + where + __Context__: HasScalarType, + { + type Scalar = <__Context__ as HasScalarType>::Scalar; + } + impl<__Context__> IsProviderFor + for UseContext + where + __Context__: HasScalarType, + {} + impl<__Context__, __Components__, __Path__> ScalarTypeProvider<__Context__> + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: ScalarTypeProvider<__Context__>, + { + type Scalar = <<__Components__ as DelegateComponent< + __Path__, + >>::Delegate as ScalarTypeProvider<__Context__>>::Scalar; + } + impl< + __Context__, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: IsProviderFor + + ScalarTypeProvider<__Context__>, + {} + impl ScalarTypeProvider<__Context__> for UseType + where + Scalar:, + { + type Scalar = Scalar; + } + impl IsProviderFor + for UseType + where + Scalar:, + {} + impl<__Provider__, Scalar, __Context__> ScalarTypeProvider<__Context__> + for WithProvider<__Provider__> + where + __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, + Scalar:, + { + type Scalar = Scalar; + } + impl< + __Provider__, + Scalar, + __Context__, + > IsProviderFor + for WithProvider<__Provider__> + where + __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, + Scalar:, + {} + ") + } } snapshot_cgp_fn! { diff --git a/crates/tests/cgp-tests/tests/component_tests/abstract_types/basic.rs b/crates/tests/cgp-tests/tests/component_tests/abstract_types/basic.rs index e7c28fa2..73945946 100644 --- a/crates/tests/cgp-tests/tests/component_tests/abstract_types/basic.rs +++ b/crates/tests/cgp-tests/tests/component_tests/abstract_types/basic.rs @@ -3,10 +3,110 @@ use std::ops::Mul; use cgp::core::error::ErrorTypeProviderComponent; use cgp::prelude::*; +use cgp_macro_test_util::snapshot_cgp_type; -#[cgp_type] -pub trait HasScalarType { - type Scalar; +snapshot_cgp_type! { + #[cgp_type] + pub trait HasScalarType { + type Scalar; + } + + expand_has_scalar_type(output) { + insta::assert_snapshot!(output, @" + pub trait HasScalarType { + type Scalar; + } + impl<__Context__> HasScalarType for __Context__ + where + __Context__: ScalarTypeProvider<__Context__>, + { + type Scalar = <__Context__ as ScalarTypeProvider<__Context__>>::Scalar; + } + pub trait ScalarTypeProvider< + __Context__, + >: IsProviderFor { + type Scalar; + } + impl<__Provider__, __Context__> ScalarTypeProvider<__Context__> for __Provider__ + where + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + ScalarTypeProviderComponent, + >>::Delegate: ScalarTypeProvider<__Context__>, + { + type Scalar = <<__Provider__ as DelegateComponent< + ScalarTypeProviderComponent, + >>::Delegate as ScalarTypeProvider<__Context__>>::Scalar; + } + pub struct ScalarTypeProviderComponent; + impl<__Context__> ScalarTypeProvider<__Context__> for UseContext + where + __Context__: HasScalarType, + { + type Scalar = <__Context__ as HasScalarType>::Scalar; + } + impl<__Context__> IsProviderFor + for UseContext + where + __Context__: HasScalarType, + {} + impl<__Context__, __Components__, __Path__> ScalarTypeProvider<__Context__> + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: ScalarTypeProvider<__Context__>, + { + type Scalar = <<__Components__ as DelegateComponent< + __Path__, + >>::Delegate as ScalarTypeProvider<__Context__>>::Scalar; + } + impl< + __Context__, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: IsProviderFor + + ScalarTypeProvider<__Context__>, + {} + impl ScalarTypeProvider<__Context__> for UseType + where + Scalar:, + { + type Scalar = Scalar; + } + impl IsProviderFor + for UseType + where + Scalar:, + {} + impl<__Provider__, Scalar, __Context__> ScalarTypeProvider<__Context__> + for WithProvider<__Provider__> + where + __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, + Scalar:, + { + type Scalar = Scalar; + } + impl< + __Provider__, + Scalar, + __Context__, + > IsProviderFor + for WithProvider<__Provider__> + where + __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, + Scalar:, + {} + ") + } } #[cgp_component(AreaCalculator)] diff --git a/crates/tests/cgp-tests/tests/component_tests/abstract_types/extend.rs b/crates/tests/cgp-tests/tests/component_tests/abstract_types/extend.rs index 33f00d79..aac4927d 100644 --- a/crates/tests/cgp-tests/tests/component_tests/abstract_types/extend.rs +++ b/crates/tests/cgp-tests/tests/component_tests/abstract_types/extend.rs @@ -3,10 +3,110 @@ use std::ops::Mul; use cgp::core::error::ErrorTypeProviderComponent; use cgp::prelude::*; +use cgp_macro_test_util::snapshot_cgp_type; -#[cgp_type] -pub trait HasScalarType { - type Scalar; +snapshot_cgp_type! { + #[cgp_type] + pub trait HasScalarType { + type Scalar; + } + + expand_has_scalar_type(output) { + insta::assert_snapshot!(output, @" + pub trait HasScalarType { + type Scalar; + } + impl<__Context__> HasScalarType for __Context__ + where + __Context__: ScalarTypeProvider<__Context__>, + { + type Scalar = <__Context__ as ScalarTypeProvider<__Context__>>::Scalar; + } + pub trait ScalarTypeProvider< + __Context__, + >: IsProviderFor { + type Scalar; + } + impl<__Provider__, __Context__> ScalarTypeProvider<__Context__> for __Provider__ + where + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + ScalarTypeProviderComponent, + >>::Delegate: ScalarTypeProvider<__Context__>, + { + type Scalar = <<__Provider__ as DelegateComponent< + ScalarTypeProviderComponent, + >>::Delegate as ScalarTypeProvider<__Context__>>::Scalar; + } + pub struct ScalarTypeProviderComponent; + impl<__Context__> ScalarTypeProvider<__Context__> for UseContext + where + __Context__: HasScalarType, + { + type Scalar = <__Context__ as HasScalarType>::Scalar; + } + impl<__Context__> IsProviderFor + for UseContext + where + __Context__: HasScalarType, + {} + impl<__Context__, __Components__, __Path__> ScalarTypeProvider<__Context__> + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: ScalarTypeProvider<__Context__>, + { + type Scalar = <<__Components__ as DelegateComponent< + __Path__, + >>::Delegate as ScalarTypeProvider<__Context__>>::Scalar; + } + impl< + __Context__, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: IsProviderFor + + ScalarTypeProvider<__Context__>, + {} + impl ScalarTypeProvider<__Context__> for UseType + where + Scalar:, + { + type Scalar = Scalar; + } + impl IsProviderFor + for UseType + where + Scalar:, + {} + impl<__Provider__, Scalar, __Context__> ScalarTypeProvider<__Context__> + for WithProvider<__Provider__> + where + __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, + Scalar:, + { + type Scalar = Scalar; + } + impl< + __Provider__, + Scalar, + __Context__, + > IsProviderFor + for WithProvider<__Provider__> + where + __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, + Scalar:, + {} + ") + } } #[cgp_component(AreaCalculator)] diff --git a/crates/tests/cgp-tests/tests/component_tests/abstract_types/foreign.rs b/crates/tests/cgp-tests/tests/component_tests/abstract_types/foreign.rs index 2818e32d..c1608cb1 100644 --- a/crates/tests/cgp-tests/tests/component_tests/abstract_types/foreign.rs +++ b/crates/tests/cgp-tests/tests/component_tests/abstract_types/foreign.rs @@ -3,10 +3,110 @@ use std::ops::Mul; use cgp::core::error::ErrorTypeProviderComponent; use cgp::prelude::*; +use cgp_macro_test_util::snapshot_cgp_type; -#[cgp_type] -pub trait HasScalarType { - type Scalar; +snapshot_cgp_type! { + #[cgp_type] + pub trait HasScalarType { + type Scalar; + } + + expand_has_scalar_type(output) { + insta::assert_snapshot!(output, @" + pub trait HasScalarType { + type Scalar; + } + impl<__Context__> HasScalarType for __Context__ + where + __Context__: ScalarTypeProvider<__Context__>, + { + type Scalar = <__Context__ as ScalarTypeProvider<__Context__>>::Scalar; + } + pub trait ScalarTypeProvider< + __Context__, + >: IsProviderFor { + type Scalar; + } + impl<__Provider__, __Context__> ScalarTypeProvider<__Context__> for __Provider__ + where + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + ScalarTypeProviderComponent, + >>::Delegate: ScalarTypeProvider<__Context__>, + { + type Scalar = <<__Provider__ as DelegateComponent< + ScalarTypeProviderComponent, + >>::Delegate as ScalarTypeProvider<__Context__>>::Scalar; + } + pub struct ScalarTypeProviderComponent; + impl<__Context__> ScalarTypeProvider<__Context__> for UseContext + where + __Context__: HasScalarType, + { + type Scalar = <__Context__ as HasScalarType>::Scalar; + } + impl<__Context__> IsProviderFor + for UseContext + where + __Context__: HasScalarType, + {} + impl<__Context__, __Components__, __Path__> ScalarTypeProvider<__Context__> + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: ScalarTypeProvider<__Context__>, + { + type Scalar = <<__Components__ as DelegateComponent< + __Path__, + >>::Delegate as ScalarTypeProvider<__Context__>>::Scalar; + } + impl< + __Context__, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: IsProviderFor + + ScalarTypeProvider<__Context__>, + {} + impl ScalarTypeProvider<__Context__> for UseType + where + Scalar:, + { + type Scalar = Scalar; + } + impl IsProviderFor + for UseType + where + Scalar:, + {} + impl<__Provider__, Scalar, __Context__> ScalarTypeProvider<__Context__> + for WithProvider<__Provider__> + where + __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, + Scalar:, + { + type Scalar = Scalar; + } + impl< + __Provider__, + Scalar, + __Context__, + > IsProviderFor + for WithProvider<__Provider__> + where + __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, + Scalar:, + {} + ") + } } #[cgp_component(AreaCalculator)] diff --git a/crates/tests/cgp-tests/tests/component_tests/abstract_types/self_referential.rs b/crates/tests/cgp-tests/tests/component_tests/abstract_types/self_referential.rs index ee96d510..341e4de6 100644 --- a/crates/tests/cgp-tests/tests/component_tests/abstract_types/self_referential.rs +++ b/crates/tests/cgp-tests/tests/component_tests/abstract_types/self_referential.rs @@ -1,10 +1,110 @@ use core::ops::Mul; use cgp::prelude::*; +use cgp_macro_test_util::snapshot_cgp_type; -#[cgp_type] -pub trait HasScalarType { - type Scalar: Mul + Clone; +snapshot_cgp_type! { + #[cgp_type] + pub trait HasScalarType { + type Scalar: Mul + Clone; + } + + expand_has_scalar_type(output) { + insta::assert_snapshot!(output, @" + pub trait HasScalarType { + type Scalar: Mul + Clone; + } + impl<__Context__> HasScalarType for __Context__ + where + __Context__: ScalarTypeProvider<__Context__>, + { + type Scalar = <__Context__ as ScalarTypeProvider<__Context__>>::Scalar; + } + pub trait ScalarTypeProvider< + __Context__, + >: IsProviderFor { + type Scalar: Mul + Clone; + } + impl<__Provider__, __Context__> ScalarTypeProvider<__Context__> for __Provider__ + where + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + ScalarTypeProviderComponent, + >>::Delegate: ScalarTypeProvider<__Context__>, + { + type Scalar = <<__Provider__ as DelegateComponent< + ScalarTypeProviderComponent, + >>::Delegate as ScalarTypeProvider<__Context__>>::Scalar; + } + pub struct ScalarTypeProviderComponent; + impl<__Context__> ScalarTypeProvider<__Context__> for UseContext + where + __Context__: HasScalarType, + { + type Scalar = <__Context__ as HasScalarType>::Scalar; + } + impl<__Context__> IsProviderFor + for UseContext + where + __Context__: HasScalarType, + {} + impl<__Context__, __Components__, __Path__> ScalarTypeProvider<__Context__> + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: ScalarTypeProvider<__Context__>, + { + type Scalar = <<__Components__ as DelegateComponent< + __Path__, + >>::Delegate as ScalarTypeProvider<__Context__>>::Scalar; + } + impl< + __Context__, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: IsProviderFor + + ScalarTypeProvider<__Context__>, + {} + impl ScalarTypeProvider<__Context__> for UseType + where + Scalar: Mul + Clone, + { + type Scalar = Scalar; + } + impl IsProviderFor + for UseType + where + Scalar: Mul + Clone, + {} + impl<__Provider__, Scalar, __Context__> ScalarTypeProvider<__Context__> + for WithProvider<__Provider__> + where + __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, + Scalar: Mul + Clone, + { + type Scalar = Scalar; + } + impl< + __Provider__, + Scalar, + __Context__, + > IsProviderFor + for WithProvider<__Provider__> + where + __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, + Scalar: Mul + Clone, + {} + ") + } } pub struct App; diff --git a/crates/tests/cgp-tests/tests/component_tests/cgp_component/constant.rs b/crates/tests/cgp-tests/tests/component_tests/cgp_component/constant.rs index 1f8e018c..39c8c866 100644 --- a/crates/tests/cgp-tests/tests/component_tests/cgp_component/constant.rs +++ b/crates/tests/cgp-tests/tests/component_tests/cgp_component/constant.rs @@ -24,10 +24,112 @@ pub fn test_component_with_const() { assert_eq!(::CONSTANT, 42); } -pub fn test_component_with_generic_const() { - #[cgp_type] - pub trait HasUnitType { - type Unit; +mod generic_const { + use cgp::prelude::*; + use cgp_macro_test_util::snapshot_cgp_type; + + snapshot_cgp_type! { + #[cgp_type] + pub trait HasUnitType { + type Unit; + } + + expand_has_unit_type(output) { + insta::assert_snapshot!(output, @" + pub trait HasUnitType { + type Unit; + } + impl<__Context__> HasUnitType for __Context__ + where + __Context__: UnitTypeProvider<__Context__>, + { + type Unit = <__Context__ as UnitTypeProvider<__Context__>>::Unit; + } + pub trait UnitTypeProvider< + __Context__, + >: IsProviderFor { + type Unit; + } + impl<__Provider__, __Context__> UnitTypeProvider<__Context__> for __Provider__ + where + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + UnitTypeProviderComponent, + >>::Delegate: UnitTypeProvider<__Context__>, + { + type Unit = <<__Provider__ as DelegateComponent< + UnitTypeProviderComponent, + >>::Delegate as UnitTypeProvider<__Context__>>::Unit; + } + pub struct UnitTypeProviderComponent; + impl<__Context__> UnitTypeProvider<__Context__> for UseContext + where + __Context__: HasUnitType, + { + type Unit = <__Context__ as HasUnitType>::Unit; + } + impl<__Context__> IsProviderFor + for UseContext + where + __Context__: HasUnitType, + {} + impl<__Context__, __Components__, __Path__> UnitTypeProvider<__Context__> + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: UnitTypeProvider<__Context__>, + { + type Unit = <<__Components__ as DelegateComponent< + __Path__, + >>::Delegate as UnitTypeProvider<__Context__>>::Unit; + } + impl< + __Context__, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: IsProviderFor + + UnitTypeProvider<__Context__>, + {} + impl UnitTypeProvider<__Context__> for UseType + where + Unit:, + { + type Unit = Unit; + } + impl IsProviderFor + for UseType + where + Unit:, + {} + impl<__Provider__, Unit, __Context__> UnitTypeProvider<__Context__> + for WithProvider<__Provider__> + where + __Provider__: TypeProvider<__Context__, UnitTypeProviderComponent, Type = Unit>, + Unit:, + { + type Unit = Unit; + } + impl< + __Provider__, + Unit, + __Context__, + > IsProviderFor + for WithProvider<__Provider__> + where + __Provider__: TypeProvider<__Context__, UnitTypeProviderComponent, Type = Unit>, + Unit:, + {} + ") + } } #[cgp_component(ConstantGetter)] @@ -59,6 +161,10 @@ pub fn test_component_with_generic_const() { ConstantGetterComponent, } } +} + +pub fn test_component_with_generic_const() { + use generic_const::{HasConstant, MyContext}; assert_eq!(::CONSTANT, 42); } diff --git a/crates/tests/cgp-tests/tests/component_tests/cgp_component/sized.rs b/crates/tests/cgp-tests/tests/component_tests/cgp_component/sized.rs index e347d241..7db71c9a 100644 --- a/crates/tests/cgp-tests/tests/component_tests/cgp_component/sized.rs +++ b/crates/tests/cgp-tests/tests/component_tests/cgp_component/sized.rs @@ -1,8 +1,120 @@ use cgp::prelude::*; +use cgp_macro_test_util::snapshot_cgp_type; -#[cgp_type(ProvideFooType)] -pub trait HasFooType { - type Foo; +snapshot_cgp_type! { + #[cgp_type(ProvideFooType)] + pub trait HasFooType { + type Foo; + } + + expand_has_foo_type(output) { + insta::assert_snapshot!(output, @" + pub trait HasFooType { + type Foo; + } + impl<__Context__, T: ?Sized> HasFooType for __Context__ + where + __Context__: ProvideFooType<__Context__, T>, + { + type Foo = <__Context__ as ProvideFooType<__Context__, T>>::Foo; + } + pub trait ProvideFooType< + __Context__, + T: ?Sized, + >: IsProviderFor { + type Foo; + } + impl<__Provider__, __Context__, T: ?Sized> ProvideFooType<__Context__, T> + for __Provider__ + where + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + ProvideFooTypeComponent, + >>::Delegate: ProvideFooType<__Context__, T>, + { + type Foo = <<__Provider__ as DelegateComponent< + ProvideFooTypeComponent, + >>::Delegate as ProvideFooType<__Context__, T>>::Foo; + } + pub struct ProvideFooTypeComponent; + impl<__Context__, T: ?Sized> ProvideFooType<__Context__, T> for UseContext + where + __Context__: HasFooType, + { + type Foo = <__Context__ as HasFooType>::Foo; + } + impl<__Context__, T: ?Sized> IsProviderFor + for UseContext + where + __Context__: HasFooType, + {} + impl<__Context__, T: ?Sized, __Components__, __Path__> ProvideFooType<__Context__, T> + for RedirectLookup<__Components__, __Path__> + where + __Path__: ConcatPath>, + __Components__: DelegateComponent< + <__Path__ as ConcatPath>>::Output, + >, + <__Components__ as DelegateComponent< + <__Path__ as ConcatPath>>::Output, + >>::Delegate: ProvideFooType<__Context__, T>, + { + type Foo = <<__Components__ as DelegateComponent< + <__Path__ as ConcatPath>>::Output, + >>::Delegate as ProvideFooType<__Context__, T>>::Foo; + } + impl< + __Context__, + T: ?Sized, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Path__: ConcatPath>, + __Components__: DelegateComponent< + <__Path__ as ConcatPath>>::Output, + >, + <__Components__ as DelegateComponent< + <__Path__ as ConcatPath>>::Output, + >>::Delegate: IsProviderFor + + ProvideFooType<__Context__, T>, + {} + impl ProvideFooType<__Context__, T> for UseType + where + Foo:, + { + type Foo = Foo; + } + impl< + Foo, + __Context__, + T: ?Sized, + > IsProviderFor for UseType + where + Foo:, + {} + impl<__Provider__, Foo, __Context__, T: ?Sized> ProvideFooType<__Context__, T> + for WithProvider<__Provider__> + where + __Provider__: TypeProvider<__Context__, ProvideFooTypeComponent, Type = Foo>, + Foo:, + { + type Foo = Foo; + } + impl< + __Provider__, + Foo, + __Context__, + T: ?Sized, + > IsProviderFor for WithProvider<__Provider__> + where + __Provider__: TypeProvider<__Context__, ProvideFooTypeComponent, Type = Foo>, + Foo:, + {} + ") + } } #[cgp_getter] diff --git a/crates/tests/cgp-tests/tests/getter_tests/abstract_type/explicit.rs b/crates/tests/cgp-tests/tests/getter_tests/abstract_type/explicit.rs index 05dce299..5d5d5dc4 100644 --- a/crates/tests/cgp-tests/tests/getter_tests/abstract_type/explicit.rs +++ b/crates/tests/cgp-tests/tests/getter_tests/abstract_type/explicit.rs @@ -1,9 +1,108 @@ use cgp::prelude::*; -use cgp_macro_test_util::{snapshot_cgp_auto_getter, snapshot_cgp_getter}; +use cgp_macro_test_util::{snapshot_cgp_auto_getter, snapshot_cgp_getter, snapshot_cgp_type}; -#[cgp_type] -pub trait HasScalarType { - type Scalar: Copy; +snapshot_cgp_type! { + #[cgp_type] + pub trait HasScalarType { + type Scalar: Copy; + } + + expand_has_scalar_type(output) { + insta::assert_snapshot!(output, @" + pub trait HasScalarType { + type Scalar: Copy; + } + impl<__Context__> HasScalarType for __Context__ + where + __Context__: ScalarTypeProvider<__Context__>, + { + type Scalar = <__Context__ as ScalarTypeProvider<__Context__>>::Scalar; + } + pub trait ScalarTypeProvider< + __Context__, + >: IsProviderFor { + type Scalar: Copy; + } + impl<__Provider__, __Context__> ScalarTypeProvider<__Context__> for __Provider__ + where + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + ScalarTypeProviderComponent, + >>::Delegate: ScalarTypeProvider<__Context__>, + { + type Scalar = <<__Provider__ as DelegateComponent< + ScalarTypeProviderComponent, + >>::Delegate as ScalarTypeProvider<__Context__>>::Scalar; + } + pub struct ScalarTypeProviderComponent; + impl<__Context__> ScalarTypeProvider<__Context__> for UseContext + where + __Context__: HasScalarType, + { + type Scalar = <__Context__ as HasScalarType>::Scalar; + } + impl<__Context__> IsProviderFor + for UseContext + where + __Context__: HasScalarType, + {} + impl<__Context__, __Components__, __Path__> ScalarTypeProvider<__Context__> + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: ScalarTypeProvider<__Context__>, + { + type Scalar = <<__Components__ as DelegateComponent< + __Path__, + >>::Delegate as ScalarTypeProvider<__Context__>>::Scalar; + } + impl< + __Context__, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: IsProviderFor + + ScalarTypeProvider<__Context__>, + {} + impl ScalarTypeProvider<__Context__> for UseType + where + Scalar: Copy, + { + type Scalar = Scalar; + } + impl IsProviderFor + for UseType + where + Scalar: Copy, + {} + impl<__Provider__, Scalar, __Context__> ScalarTypeProvider<__Context__> + for WithProvider<__Provider__> + where + __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, + Scalar: Copy, + { + type Scalar = Scalar; + } + impl< + __Provider__, + Scalar, + __Context__, + > IsProviderFor + for WithProvider<__Provider__> + where + __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, + Scalar: Copy, + {} + ") + } } snapshot_cgp_auto_getter! { diff --git a/crates/tests/cgp-tests/tests/getter_tests/abstract_type/import.rs b/crates/tests/cgp-tests/tests/getter_tests/abstract_type/import.rs index 7c60cd05..ecbf733a 100644 --- a/crates/tests/cgp-tests/tests/getter_tests/abstract_type/import.rs +++ b/crates/tests/cgp-tests/tests/getter_tests/abstract_type/import.rs @@ -1,9 +1,108 @@ use cgp::prelude::*; -use cgp_macro_test_util::{snapshot_cgp_auto_getter, snapshot_cgp_getter}; +use cgp_macro_test_util::{snapshot_cgp_auto_getter, snapshot_cgp_getter, snapshot_cgp_type}; -#[cgp_type] -pub trait HasScalarType { - type Scalar: Copy; +snapshot_cgp_type! { + #[cgp_type] + pub trait HasScalarType { + type Scalar: Copy; + } + + expand_has_scalar_type(output) { + insta::assert_snapshot!(output, @" + pub trait HasScalarType { + type Scalar: Copy; + } + impl<__Context__> HasScalarType for __Context__ + where + __Context__: ScalarTypeProvider<__Context__>, + { + type Scalar = <__Context__ as ScalarTypeProvider<__Context__>>::Scalar; + } + pub trait ScalarTypeProvider< + __Context__, + >: IsProviderFor { + type Scalar: Copy; + } + impl<__Provider__, __Context__> ScalarTypeProvider<__Context__> for __Provider__ + where + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + ScalarTypeProviderComponent, + >>::Delegate: ScalarTypeProvider<__Context__>, + { + type Scalar = <<__Provider__ as DelegateComponent< + ScalarTypeProviderComponent, + >>::Delegate as ScalarTypeProvider<__Context__>>::Scalar; + } + pub struct ScalarTypeProviderComponent; + impl<__Context__> ScalarTypeProvider<__Context__> for UseContext + where + __Context__: HasScalarType, + { + type Scalar = <__Context__ as HasScalarType>::Scalar; + } + impl<__Context__> IsProviderFor + for UseContext + where + __Context__: HasScalarType, + {} + impl<__Context__, __Components__, __Path__> ScalarTypeProvider<__Context__> + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: ScalarTypeProvider<__Context__>, + { + type Scalar = <<__Components__ as DelegateComponent< + __Path__, + >>::Delegate as ScalarTypeProvider<__Context__>>::Scalar; + } + impl< + __Context__, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: IsProviderFor + + ScalarTypeProvider<__Context__>, + {} + impl ScalarTypeProvider<__Context__> for UseType + where + Scalar: Copy, + { + type Scalar = Scalar; + } + impl IsProviderFor + for UseType + where + Scalar: Copy, + {} + impl<__Provider__, Scalar, __Context__> ScalarTypeProvider<__Context__> + for WithProvider<__Provider__> + where + __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, + Scalar: Copy, + { + type Scalar = Scalar; + } + impl< + __Provider__, + Scalar, + __Context__, + > IsProviderFor + for WithProvider<__Provider__> + where + __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, + Scalar: Copy, + {} + ") + } } snapshot_cgp_auto_getter! { diff --git a/crates/tests/cgp-tests/tests/getter_tests/abstract_type/use_type.rs b/crates/tests/cgp-tests/tests/getter_tests/abstract_type/use_type.rs index 7c60cd05..ecbf733a 100644 --- a/crates/tests/cgp-tests/tests/getter_tests/abstract_type/use_type.rs +++ b/crates/tests/cgp-tests/tests/getter_tests/abstract_type/use_type.rs @@ -1,9 +1,108 @@ use cgp::prelude::*; -use cgp_macro_test_util::{snapshot_cgp_auto_getter, snapshot_cgp_getter}; +use cgp_macro_test_util::{snapshot_cgp_auto_getter, snapshot_cgp_getter, snapshot_cgp_type}; -#[cgp_type] -pub trait HasScalarType { - type Scalar: Copy; +snapshot_cgp_type! { + #[cgp_type] + pub trait HasScalarType { + type Scalar: Copy; + } + + expand_has_scalar_type(output) { + insta::assert_snapshot!(output, @" + pub trait HasScalarType { + type Scalar: Copy; + } + impl<__Context__> HasScalarType for __Context__ + where + __Context__: ScalarTypeProvider<__Context__>, + { + type Scalar = <__Context__ as ScalarTypeProvider<__Context__>>::Scalar; + } + pub trait ScalarTypeProvider< + __Context__, + >: IsProviderFor { + type Scalar: Copy; + } + impl<__Provider__, __Context__> ScalarTypeProvider<__Context__> for __Provider__ + where + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + ScalarTypeProviderComponent, + >>::Delegate: ScalarTypeProvider<__Context__>, + { + type Scalar = <<__Provider__ as DelegateComponent< + ScalarTypeProviderComponent, + >>::Delegate as ScalarTypeProvider<__Context__>>::Scalar; + } + pub struct ScalarTypeProviderComponent; + impl<__Context__> ScalarTypeProvider<__Context__> for UseContext + where + __Context__: HasScalarType, + { + type Scalar = <__Context__ as HasScalarType>::Scalar; + } + impl<__Context__> IsProviderFor + for UseContext + where + __Context__: HasScalarType, + {} + impl<__Context__, __Components__, __Path__> ScalarTypeProvider<__Context__> + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: ScalarTypeProvider<__Context__>, + { + type Scalar = <<__Components__ as DelegateComponent< + __Path__, + >>::Delegate as ScalarTypeProvider<__Context__>>::Scalar; + } + impl< + __Context__, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: IsProviderFor + + ScalarTypeProvider<__Context__>, + {} + impl ScalarTypeProvider<__Context__> for UseType + where + Scalar: Copy, + { + type Scalar = Scalar; + } + impl IsProviderFor + for UseType + where + Scalar: Copy, + {} + impl<__Provider__, Scalar, __Context__> ScalarTypeProvider<__Context__> + for WithProvider<__Provider__> + where + __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, + Scalar: Copy, + { + type Scalar = Scalar; + } + impl< + __Provider__, + Scalar, + __Context__, + > IsProviderFor + for WithProvider<__Provider__> + where + __Provider__: TypeProvider<__Context__, ScalarTypeProviderComponent, Type = Scalar>, + Scalar: Copy, + {} + ") + } } snapshot_cgp_auto_getter! { diff --git a/crates/tests/cgp-tests/tests/getter_tests/clone.rs b/crates/tests/cgp-tests/tests/getter_tests/clone.rs index 0f81c5f7..4355a627 100644 --- a/crates/tests/cgp-tests/tests/getter_tests/clone.rs +++ b/crates/tests/cgp-tests/tests/getter_tests/clone.rs @@ -1,10 +1,111 @@ mod clone_getter { use cgp::prelude::*; - use cgp_macro_test_util::{snapshot_cgp_getter, snapshot_delegate_components}; + use cgp_macro_test_util::{ + snapshot_cgp_getter, snapshot_cgp_type, snapshot_delegate_components, + }; - #[cgp_type] - pub trait HasNameType { - type Name; + snapshot_cgp_type! { + #[cgp_type] + pub trait HasNameType { + type Name; + } + + expand_has_name_type(output) { + insta::assert_snapshot!(output, @" + pub trait HasNameType { + type Name; + } + impl<__Context__> HasNameType for __Context__ + where + __Context__: NameTypeProvider<__Context__>, + { + type Name = <__Context__ as NameTypeProvider<__Context__>>::Name; + } + pub trait NameTypeProvider< + __Context__, + >: IsProviderFor { + type Name; + } + impl<__Provider__, __Context__> NameTypeProvider<__Context__> for __Provider__ + where + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + NameTypeProviderComponent, + >>::Delegate: NameTypeProvider<__Context__>, + { + type Name = <<__Provider__ as DelegateComponent< + NameTypeProviderComponent, + >>::Delegate as NameTypeProvider<__Context__>>::Name; + } + pub struct NameTypeProviderComponent; + impl<__Context__> NameTypeProvider<__Context__> for UseContext + where + __Context__: HasNameType, + { + type Name = <__Context__ as HasNameType>::Name; + } + impl<__Context__> IsProviderFor + for UseContext + where + __Context__: HasNameType, + {} + impl<__Context__, __Components__, __Path__> NameTypeProvider<__Context__> + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: NameTypeProvider<__Context__>, + { + type Name = <<__Components__ as DelegateComponent< + __Path__, + >>::Delegate as NameTypeProvider<__Context__>>::Name; + } + impl< + __Context__, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: IsProviderFor + + NameTypeProvider<__Context__>, + {} + impl NameTypeProvider<__Context__> for UseType + where + Name:, + { + type Name = Name; + } + impl IsProviderFor + for UseType + where + Name:, + {} + impl<__Provider__, Name, __Context__> NameTypeProvider<__Context__> + for WithProvider<__Provider__> + where + __Provider__: TypeProvider<__Context__, NameTypeProviderComponent, Type = Name>, + Name:, + { + type Name = Name; + } + impl< + __Provider__, + Name, + __Context__, + > IsProviderFor + for WithProvider<__Provider__> + where + __Provider__: TypeProvider<__Context__, NameTypeProviderComponent, Type = Name>, + Name:, + {} + ") + } } snapshot_cgp_getter! { @@ -211,11 +312,112 @@ mod clone_getter { mod clone_auto_getter { use cgp::prelude::*; - use cgp_macro_test_util::{snapshot_cgp_auto_getter, snapshot_delegate_components}; + use cgp_macro_test_util::{ + snapshot_cgp_auto_getter, snapshot_cgp_type, snapshot_delegate_components, + }; - #[cgp_type] - pub trait HasNameType { - type Name; + snapshot_cgp_type! { + #[cgp_type] + pub trait HasNameType { + type Name; + } + + expand_has_name_type(output) { + insta::assert_snapshot!(output, @" + pub trait HasNameType { + type Name; + } + impl<__Context__> HasNameType for __Context__ + where + __Context__: NameTypeProvider<__Context__>, + { + type Name = <__Context__ as NameTypeProvider<__Context__>>::Name; + } + pub trait NameTypeProvider< + __Context__, + >: IsProviderFor { + type Name; + } + impl<__Provider__, __Context__> NameTypeProvider<__Context__> for __Provider__ + where + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + NameTypeProviderComponent, + >>::Delegate: NameTypeProvider<__Context__>, + { + type Name = <<__Provider__ as DelegateComponent< + NameTypeProviderComponent, + >>::Delegate as NameTypeProvider<__Context__>>::Name; + } + pub struct NameTypeProviderComponent; + impl<__Context__> NameTypeProvider<__Context__> for UseContext + where + __Context__: HasNameType, + { + type Name = <__Context__ as HasNameType>::Name; + } + impl<__Context__> IsProviderFor + for UseContext + where + __Context__: HasNameType, + {} + impl<__Context__, __Components__, __Path__> NameTypeProvider<__Context__> + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: NameTypeProvider<__Context__>, + { + type Name = <<__Components__ as DelegateComponent< + __Path__, + >>::Delegate as NameTypeProvider<__Context__>>::Name; + } + impl< + __Context__, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: IsProviderFor + + NameTypeProvider<__Context__>, + {} + impl NameTypeProvider<__Context__> for UseType + where + Name:, + { + type Name = Name; + } + impl IsProviderFor + for UseType + where + Name:, + {} + impl<__Provider__, Name, __Context__> NameTypeProvider<__Context__> + for WithProvider<__Provider__> + where + __Provider__: TypeProvider<__Context__, NameTypeProviderComponent, Type = Name>, + Name:, + { + type Name = Name; + } + impl< + __Provider__, + Name, + __Context__, + > IsProviderFor + for WithProvider<__Provider__> + where + __Provider__: TypeProvider<__Context__, NameTypeProviderComponent, Type = Name>, + Name:, + {} + ") + } } snapshot_cgp_auto_getter! { diff --git a/crates/tests/cgp-tests/tests/getter_tests/non_self.rs b/crates/tests/cgp-tests/tests/getter_tests/non_self.rs index 0f9af1dc..0af7397b 100644 --- a/crates/tests/cgp-tests/tests/getter_tests/non_self.rs +++ b/crates/tests/cgp-tests/tests/getter_tests/non_self.rs @@ -1,14 +1,208 @@ use cgp::prelude::*; -use cgp_macro_test_util::{snapshot_cgp_getter, snapshot_delegate_components}; +use cgp_macro_test_util::{snapshot_cgp_getter, snapshot_cgp_type, snapshot_delegate_components}; -#[cgp_type] -pub trait HasFooType { - type Foo; +snapshot_cgp_type! { + #[cgp_type] + pub trait HasFooType { + type Foo; + } + + expand_has_foo_type(output) { + insta::assert_snapshot!(output, @" + pub trait HasFooType { + type Foo; + } + impl<__Context__> HasFooType for __Context__ + where + __Context__: FooTypeProvider<__Context__>, + { + type Foo = <__Context__ as FooTypeProvider<__Context__>>::Foo; + } + pub trait FooTypeProvider< + __Context__, + >: IsProviderFor { + type Foo; + } + impl<__Provider__, __Context__> FooTypeProvider<__Context__> for __Provider__ + where + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + FooTypeProviderComponent, + >>::Delegate: FooTypeProvider<__Context__>, + { + type Foo = <<__Provider__ as DelegateComponent< + FooTypeProviderComponent, + >>::Delegate as FooTypeProvider<__Context__>>::Foo; + } + pub struct FooTypeProviderComponent; + impl<__Context__> FooTypeProvider<__Context__> for UseContext + where + __Context__: HasFooType, + { + type Foo = <__Context__ as HasFooType>::Foo; + } + impl<__Context__> IsProviderFor for UseContext + where + __Context__: HasFooType, + {} + impl<__Context__, __Components__, __Path__> FooTypeProvider<__Context__> + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: FooTypeProvider<__Context__>, + { + type Foo = <<__Components__ as DelegateComponent< + __Path__, + >>::Delegate as FooTypeProvider<__Context__>>::Foo; + } + impl< + __Context__, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: IsProviderFor + + FooTypeProvider<__Context__>, + {} + impl FooTypeProvider<__Context__> for UseType + where + Foo:, + { + type Foo = Foo; + } + impl IsProviderFor + for UseType + where + Foo:, + {} + impl<__Provider__, Foo, __Context__> FooTypeProvider<__Context__> + for WithProvider<__Provider__> + where + __Provider__: TypeProvider<__Context__, FooTypeProviderComponent, Type = Foo>, + Foo:, + { + type Foo = Foo; + } + impl< + __Provider__, + Foo, + __Context__, + > IsProviderFor for WithProvider<__Provider__> + where + __Provider__: TypeProvider<__Context__, FooTypeProviderComponent, Type = Foo>, + Foo:, + {} + ") + } } -#[cgp_type] -pub trait HasBarType { - type Bar; +snapshot_cgp_type! { + #[cgp_type] + pub trait HasBarType { + type Bar; + } + + expand_has_bar_type(output) { + insta::assert_snapshot!(output, @" + pub trait HasBarType { + type Bar; + } + impl<__Context__> HasBarType for __Context__ + where + __Context__: BarTypeProvider<__Context__>, + { + type Bar = <__Context__ as BarTypeProvider<__Context__>>::Bar; + } + pub trait BarTypeProvider< + __Context__, + >: IsProviderFor { + type Bar; + } + impl<__Provider__, __Context__> BarTypeProvider<__Context__> for __Provider__ + where + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + BarTypeProviderComponent, + >>::Delegate: BarTypeProvider<__Context__>, + { + type Bar = <<__Provider__ as DelegateComponent< + BarTypeProviderComponent, + >>::Delegate as BarTypeProvider<__Context__>>::Bar; + } + pub struct BarTypeProviderComponent; + impl<__Context__> BarTypeProvider<__Context__> for UseContext + where + __Context__: HasBarType, + { + type Bar = <__Context__ as HasBarType>::Bar; + } + impl<__Context__> IsProviderFor for UseContext + where + __Context__: HasBarType, + {} + impl<__Context__, __Components__, __Path__> BarTypeProvider<__Context__> + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: BarTypeProvider<__Context__>, + { + type Bar = <<__Components__ as DelegateComponent< + __Path__, + >>::Delegate as BarTypeProvider<__Context__>>::Bar; + } + impl< + __Context__, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: IsProviderFor + + BarTypeProvider<__Context__>, + {} + impl BarTypeProvider<__Context__> for UseType + where + Bar:, + { + type Bar = Bar; + } + impl IsProviderFor + for UseType + where + Bar:, + {} + impl<__Provider__, Bar, __Context__> BarTypeProvider<__Context__> + for WithProvider<__Provider__> + where + __Provider__: TypeProvider<__Context__, BarTypeProviderComponent, Type = Bar>, + Bar:, + { + type Bar = Bar; + } + impl< + __Provider__, + Bar, + __Context__, + > IsProviderFor for WithProvider<__Provider__> + where + __Provider__: TypeProvider<__Context__, BarTypeProviderComponent, Type = Bar>, + Bar:, + {} + ") + } } snapshot_cgp_getter! { diff --git a/crates/tests/cgp-tests/tests/getter_tests/non_self_auto.rs b/crates/tests/cgp-tests/tests/getter_tests/non_self_auto.rs index 625bb103..f1bdeda6 100644 --- a/crates/tests/cgp-tests/tests/getter_tests/non_self_auto.rs +++ b/crates/tests/cgp-tests/tests/getter_tests/non_self_auto.rs @@ -1,14 +1,210 @@ use cgp::prelude::*; -use cgp_macro_test_util::{snapshot_cgp_auto_getter, snapshot_delegate_components}; +use cgp_macro_test_util::{ + snapshot_cgp_auto_getter, snapshot_cgp_type, snapshot_delegate_components, +}; -#[cgp_type] -pub trait HasFooType { - type Foo; +snapshot_cgp_type! { + #[cgp_type] + pub trait HasFooType { + type Foo; + } + + expand_has_foo_type(output) { + insta::assert_snapshot!(output, @" + pub trait HasFooType { + type Foo; + } + impl<__Context__> HasFooType for __Context__ + where + __Context__: FooTypeProvider<__Context__>, + { + type Foo = <__Context__ as FooTypeProvider<__Context__>>::Foo; + } + pub trait FooTypeProvider< + __Context__, + >: IsProviderFor { + type Foo; + } + impl<__Provider__, __Context__> FooTypeProvider<__Context__> for __Provider__ + where + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + FooTypeProviderComponent, + >>::Delegate: FooTypeProvider<__Context__>, + { + type Foo = <<__Provider__ as DelegateComponent< + FooTypeProviderComponent, + >>::Delegate as FooTypeProvider<__Context__>>::Foo; + } + pub struct FooTypeProviderComponent; + impl<__Context__> FooTypeProvider<__Context__> for UseContext + where + __Context__: HasFooType, + { + type Foo = <__Context__ as HasFooType>::Foo; + } + impl<__Context__> IsProviderFor for UseContext + where + __Context__: HasFooType, + {} + impl<__Context__, __Components__, __Path__> FooTypeProvider<__Context__> + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: FooTypeProvider<__Context__>, + { + type Foo = <<__Components__ as DelegateComponent< + __Path__, + >>::Delegate as FooTypeProvider<__Context__>>::Foo; + } + impl< + __Context__, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: IsProviderFor + + FooTypeProvider<__Context__>, + {} + impl FooTypeProvider<__Context__> for UseType + where + Foo:, + { + type Foo = Foo; + } + impl IsProviderFor + for UseType + where + Foo:, + {} + impl<__Provider__, Foo, __Context__> FooTypeProvider<__Context__> + for WithProvider<__Provider__> + where + __Provider__: TypeProvider<__Context__, FooTypeProviderComponent, Type = Foo>, + Foo:, + { + type Foo = Foo; + } + impl< + __Provider__, + Foo, + __Context__, + > IsProviderFor for WithProvider<__Provider__> + where + __Provider__: TypeProvider<__Context__, FooTypeProviderComponent, Type = Foo>, + Foo:, + {} + ") + } } -#[cgp_type] -pub trait HasBarType { - type Bar; +snapshot_cgp_type! { + #[cgp_type] + pub trait HasBarType { + type Bar; + } + + expand_has_bar_type(output) { + insta::assert_snapshot!(output, @" + pub trait HasBarType { + type Bar; + } + impl<__Context__> HasBarType for __Context__ + where + __Context__: BarTypeProvider<__Context__>, + { + type Bar = <__Context__ as BarTypeProvider<__Context__>>::Bar; + } + pub trait BarTypeProvider< + __Context__, + >: IsProviderFor { + type Bar; + } + impl<__Provider__, __Context__> BarTypeProvider<__Context__> for __Provider__ + where + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + BarTypeProviderComponent, + >>::Delegate: BarTypeProvider<__Context__>, + { + type Bar = <<__Provider__ as DelegateComponent< + BarTypeProviderComponent, + >>::Delegate as BarTypeProvider<__Context__>>::Bar; + } + pub struct BarTypeProviderComponent; + impl<__Context__> BarTypeProvider<__Context__> for UseContext + where + __Context__: HasBarType, + { + type Bar = <__Context__ as HasBarType>::Bar; + } + impl<__Context__> IsProviderFor for UseContext + where + __Context__: HasBarType, + {} + impl<__Context__, __Components__, __Path__> BarTypeProvider<__Context__> + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: BarTypeProvider<__Context__>, + { + type Bar = <<__Components__ as DelegateComponent< + __Path__, + >>::Delegate as BarTypeProvider<__Context__>>::Bar; + } + impl< + __Context__, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: IsProviderFor + + BarTypeProvider<__Context__>, + {} + impl BarTypeProvider<__Context__> for UseType + where + Bar:, + { + type Bar = Bar; + } + impl IsProviderFor + for UseType + where + Bar:, + {} + impl<__Provider__, Bar, __Context__> BarTypeProvider<__Context__> + for WithProvider<__Provider__> + where + __Provider__: TypeProvider<__Context__, BarTypeProviderComponent, Type = Bar>, + Bar:, + { + type Bar = Bar; + } + impl< + __Provider__, + Bar, + __Context__, + > IsProviderFor for WithProvider<__Provider__> + where + __Provider__: TypeProvider<__Context__, BarTypeProviderComponent, Type = Bar>, + Bar:, + {} + ") + } } snapshot_cgp_auto_getter! { diff --git a/crates/tests/cgp-tests/tests/preset_tests/basic/components.rs b/crates/tests/cgp-tests/tests/preset_tests/basic/components.rs index 8af1b1f3..8b603884 100644 --- a/crates/tests/cgp-tests/tests/preset_tests/basic/components.rs +++ b/crates/tests/cgp-tests/tests/preset_tests/basic/components.rs @@ -1,14 +1,208 @@ use cgp::prelude::*; -use cgp_macro_test_util::snapshot_cgp_getter; +use cgp_macro_test_util::{snapshot_cgp_getter, snapshot_cgp_type}; -#[cgp_type] -pub trait HasFooType { - type Foo; +snapshot_cgp_type! { + #[cgp_type] + pub trait HasFooType { + type Foo; + } + + expand_has_foo_type(output) { + insta::assert_snapshot!(output, @" + pub trait HasFooType { + type Foo; + } + impl<__Context__> HasFooType for __Context__ + where + __Context__: FooTypeProvider<__Context__>, + { + type Foo = <__Context__ as FooTypeProvider<__Context__>>::Foo; + } + pub trait FooTypeProvider< + __Context__, + >: IsProviderFor { + type Foo; + } + impl<__Provider__, __Context__> FooTypeProvider<__Context__> for __Provider__ + where + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + FooTypeProviderComponent, + >>::Delegate: FooTypeProvider<__Context__>, + { + type Foo = <<__Provider__ as DelegateComponent< + FooTypeProviderComponent, + >>::Delegate as FooTypeProvider<__Context__>>::Foo; + } + pub struct FooTypeProviderComponent; + impl<__Context__> FooTypeProvider<__Context__> for UseContext + where + __Context__: HasFooType, + { + type Foo = <__Context__ as HasFooType>::Foo; + } + impl<__Context__> IsProviderFor for UseContext + where + __Context__: HasFooType, + {} + impl<__Context__, __Components__, __Path__> FooTypeProvider<__Context__> + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: FooTypeProvider<__Context__>, + { + type Foo = <<__Components__ as DelegateComponent< + __Path__, + >>::Delegate as FooTypeProvider<__Context__>>::Foo; + } + impl< + __Context__, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: IsProviderFor + + FooTypeProvider<__Context__>, + {} + impl FooTypeProvider<__Context__> for UseType + where + Foo:, + { + type Foo = Foo; + } + impl IsProviderFor + for UseType + where + Foo:, + {} + impl<__Provider__, Foo, __Context__> FooTypeProvider<__Context__> + for WithProvider<__Provider__> + where + __Provider__: TypeProvider<__Context__, FooTypeProviderComponent, Type = Foo>, + Foo:, + { + type Foo = Foo; + } + impl< + __Provider__, + Foo, + __Context__, + > IsProviderFor for WithProvider<__Provider__> + where + __Provider__: TypeProvider<__Context__, FooTypeProviderComponent, Type = Foo>, + Foo:, + {} + ") + } } -#[cgp_type] -pub trait HasBarType { - type Bar; +snapshot_cgp_type! { + #[cgp_type] + pub trait HasBarType { + type Bar; + } + + expand_has_bar_type(output) { + insta::assert_snapshot!(output, @" + pub trait HasBarType { + type Bar; + } + impl<__Context__> HasBarType for __Context__ + where + __Context__: BarTypeProvider<__Context__>, + { + type Bar = <__Context__ as BarTypeProvider<__Context__>>::Bar; + } + pub trait BarTypeProvider< + __Context__, + >: IsProviderFor { + type Bar; + } + impl<__Provider__, __Context__> BarTypeProvider<__Context__> for __Provider__ + where + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + BarTypeProviderComponent, + >>::Delegate: BarTypeProvider<__Context__>, + { + type Bar = <<__Provider__ as DelegateComponent< + BarTypeProviderComponent, + >>::Delegate as BarTypeProvider<__Context__>>::Bar; + } + pub struct BarTypeProviderComponent; + impl<__Context__> BarTypeProvider<__Context__> for UseContext + where + __Context__: HasBarType, + { + type Bar = <__Context__ as HasBarType>::Bar; + } + impl<__Context__> IsProviderFor for UseContext + where + __Context__: HasBarType, + {} + impl<__Context__, __Components__, __Path__> BarTypeProvider<__Context__> + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: BarTypeProvider<__Context__>, + { + type Bar = <<__Components__ as DelegateComponent< + __Path__, + >>::Delegate as BarTypeProvider<__Context__>>::Bar; + } + impl< + __Context__, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: IsProviderFor + + BarTypeProvider<__Context__>, + {} + impl BarTypeProvider<__Context__> for UseType + where + Bar:, + { + type Bar = Bar; + } + impl IsProviderFor + for UseType + where + Bar:, + {} + impl<__Provider__, Bar, __Context__> BarTypeProvider<__Context__> + for WithProvider<__Provider__> + where + __Provider__: TypeProvider<__Context__, BarTypeProviderComponent, Type = Bar>, + Bar:, + { + type Bar = Bar; + } + impl< + __Provider__, + Bar, + __Context__, + > IsProviderFor for WithProvider<__Provider__> + where + __Provider__: TypeProvider<__Context__, BarTypeProviderComponent, Type = Bar>, + Bar:, + {} + ") + } } snapshot_cgp_getter! { diff --git a/crates/tests/cgp-tests/tests/preset_tests/generics/components.rs b/crates/tests/cgp-tests/tests/preset_tests/generics/components.rs index 95aa2235..4ff6ecf2 100644 --- a/crates/tests/cgp-tests/tests/preset_tests/generics/components.rs +++ b/crates/tests/cgp-tests/tests/preset_tests/generics/components.rs @@ -1,16 +1,210 @@ use core::marker::PhantomData; use cgp::prelude::*; -use cgp_macro_test_util::snapshot_cgp_getter; +use cgp_macro_test_util::{snapshot_cgp_getter, snapshot_cgp_type}; -#[cgp_type] -pub trait HasFooType { - type Foo; +snapshot_cgp_type! { + #[cgp_type] + pub trait HasFooType { + type Foo; + } + + expand_has_foo_type(output) { + insta::assert_snapshot!(output, @" + pub trait HasFooType { + type Foo; + } + impl<__Context__> HasFooType for __Context__ + where + __Context__: FooTypeProvider<__Context__>, + { + type Foo = <__Context__ as FooTypeProvider<__Context__>>::Foo; + } + pub trait FooTypeProvider< + __Context__, + >: IsProviderFor { + type Foo; + } + impl<__Provider__, __Context__> FooTypeProvider<__Context__> for __Provider__ + where + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + FooTypeProviderComponent, + >>::Delegate: FooTypeProvider<__Context__>, + { + type Foo = <<__Provider__ as DelegateComponent< + FooTypeProviderComponent, + >>::Delegate as FooTypeProvider<__Context__>>::Foo; + } + pub struct FooTypeProviderComponent; + impl<__Context__> FooTypeProvider<__Context__> for UseContext + where + __Context__: HasFooType, + { + type Foo = <__Context__ as HasFooType>::Foo; + } + impl<__Context__> IsProviderFor for UseContext + where + __Context__: HasFooType, + {} + impl<__Context__, __Components__, __Path__> FooTypeProvider<__Context__> + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: FooTypeProvider<__Context__>, + { + type Foo = <<__Components__ as DelegateComponent< + __Path__, + >>::Delegate as FooTypeProvider<__Context__>>::Foo; + } + impl< + __Context__, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: IsProviderFor + + FooTypeProvider<__Context__>, + {} + impl FooTypeProvider<__Context__> for UseType + where + Foo:, + { + type Foo = Foo; + } + impl IsProviderFor + for UseType + where + Foo:, + {} + impl<__Provider__, Foo, __Context__> FooTypeProvider<__Context__> + for WithProvider<__Provider__> + where + __Provider__: TypeProvider<__Context__, FooTypeProviderComponent, Type = Foo>, + Foo:, + { + type Foo = Foo; + } + impl< + __Provider__, + Foo, + __Context__, + > IsProviderFor for WithProvider<__Provider__> + where + __Provider__: TypeProvider<__Context__, FooTypeProviderComponent, Type = Foo>, + Foo:, + {} + ") + } } -#[cgp_type] -pub trait HasBarType { - type Bar; +snapshot_cgp_type! { + #[cgp_type] + pub trait HasBarType { + type Bar; + } + + expand_has_bar_type(output) { + insta::assert_snapshot!(output, @" + pub trait HasBarType { + type Bar; + } + impl<__Context__> HasBarType for __Context__ + where + __Context__: BarTypeProvider<__Context__>, + { + type Bar = <__Context__ as BarTypeProvider<__Context__>>::Bar; + } + pub trait BarTypeProvider< + __Context__, + >: IsProviderFor { + type Bar; + } + impl<__Provider__, __Context__> BarTypeProvider<__Context__> for __Provider__ + where + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + BarTypeProviderComponent, + >>::Delegate: BarTypeProvider<__Context__>, + { + type Bar = <<__Provider__ as DelegateComponent< + BarTypeProviderComponent, + >>::Delegate as BarTypeProvider<__Context__>>::Bar; + } + pub struct BarTypeProviderComponent; + impl<__Context__> BarTypeProvider<__Context__> for UseContext + where + __Context__: HasBarType, + { + type Bar = <__Context__ as HasBarType>::Bar; + } + impl<__Context__> IsProviderFor for UseContext + where + __Context__: HasBarType, + {} + impl<__Context__, __Components__, __Path__> BarTypeProvider<__Context__> + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: BarTypeProvider<__Context__>, + { + type Bar = <<__Components__ as DelegateComponent< + __Path__, + >>::Delegate as BarTypeProvider<__Context__>>::Bar; + } + impl< + __Context__, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: IsProviderFor + + BarTypeProvider<__Context__>, + {} + impl BarTypeProvider<__Context__> for UseType + where + Bar:, + { + type Bar = Bar; + } + impl IsProviderFor + for UseType + where + Bar:, + {} + impl<__Provider__, Bar, __Context__> BarTypeProvider<__Context__> + for WithProvider<__Provider__> + where + __Provider__: TypeProvider<__Context__, BarTypeProviderComponent, Type = Bar>, + Bar:, + { + type Bar = Bar; + } + impl< + __Provider__, + Bar, + __Context__, + > IsProviderFor for WithProvider<__Provider__> + where + __Provider__: TypeProvider<__Context__, BarTypeProviderComponent, Type = Bar>, + Bar:, + {} + ") + } } snapshot_cgp_getter! { diff --git a/crates/tests/cgp-tests/tests/preset_tests/generics_inheritance/components.rs b/crates/tests/cgp-tests/tests/preset_tests/generics_inheritance/components.rs index 2d2487ac..c76a716d 100644 --- a/crates/tests/cgp-tests/tests/preset_tests/generics_inheritance/components.rs +++ b/crates/tests/cgp-tests/tests/preset_tests/generics_inheritance/components.rs @@ -1,16 +1,210 @@ use core::marker::PhantomData; use cgp::prelude::*; -use cgp_macro_test_util::snapshot_cgp_getter; +use cgp_macro_test_util::{snapshot_cgp_getter, snapshot_cgp_type}; -#[cgp_type] -pub trait HasFooType { - type Foo; +snapshot_cgp_type! { + #[cgp_type] + pub trait HasFooType { + type Foo; + } + + expand_has_foo_type(output) { + insta::assert_snapshot!(output, @" + pub trait HasFooType { + type Foo; + } + impl<__Context__> HasFooType for __Context__ + where + __Context__: FooTypeProvider<__Context__>, + { + type Foo = <__Context__ as FooTypeProvider<__Context__>>::Foo; + } + pub trait FooTypeProvider< + __Context__, + >: IsProviderFor { + type Foo; + } + impl<__Provider__, __Context__> FooTypeProvider<__Context__> for __Provider__ + where + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + FooTypeProviderComponent, + >>::Delegate: FooTypeProvider<__Context__>, + { + type Foo = <<__Provider__ as DelegateComponent< + FooTypeProviderComponent, + >>::Delegate as FooTypeProvider<__Context__>>::Foo; + } + pub struct FooTypeProviderComponent; + impl<__Context__> FooTypeProvider<__Context__> for UseContext + where + __Context__: HasFooType, + { + type Foo = <__Context__ as HasFooType>::Foo; + } + impl<__Context__> IsProviderFor for UseContext + where + __Context__: HasFooType, + {} + impl<__Context__, __Components__, __Path__> FooTypeProvider<__Context__> + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: FooTypeProvider<__Context__>, + { + type Foo = <<__Components__ as DelegateComponent< + __Path__, + >>::Delegate as FooTypeProvider<__Context__>>::Foo; + } + impl< + __Context__, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: IsProviderFor + + FooTypeProvider<__Context__>, + {} + impl FooTypeProvider<__Context__> for UseType + where + Foo:, + { + type Foo = Foo; + } + impl IsProviderFor + for UseType + where + Foo:, + {} + impl<__Provider__, Foo, __Context__> FooTypeProvider<__Context__> + for WithProvider<__Provider__> + where + __Provider__: TypeProvider<__Context__, FooTypeProviderComponent, Type = Foo>, + Foo:, + { + type Foo = Foo; + } + impl< + __Provider__, + Foo, + __Context__, + > IsProviderFor for WithProvider<__Provider__> + where + __Provider__: TypeProvider<__Context__, FooTypeProviderComponent, Type = Foo>, + Foo:, + {} + ") + } } -#[cgp_type] -pub trait HasBarType { - type Bar; +snapshot_cgp_type! { + #[cgp_type] + pub trait HasBarType { + type Bar; + } + + expand_has_bar_type(output) { + insta::assert_snapshot!(output, @" + pub trait HasBarType { + type Bar; + } + impl<__Context__> HasBarType for __Context__ + where + __Context__: BarTypeProvider<__Context__>, + { + type Bar = <__Context__ as BarTypeProvider<__Context__>>::Bar; + } + pub trait BarTypeProvider< + __Context__, + >: IsProviderFor { + type Bar; + } + impl<__Provider__, __Context__> BarTypeProvider<__Context__> for __Provider__ + where + __Provider__: DelegateComponent + + IsProviderFor, + <__Provider__ as DelegateComponent< + BarTypeProviderComponent, + >>::Delegate: BarTypeProvider<__Context__>, + { + type Bar = <<__Provider__ as DelegateComponent< + BarTypeProviderComponent, + >>::Delegate as BarTypeProvider<__Context__>>::Bar; + } + pub struct BarTypeProviderComponent; + impl<__Context__> BarTypeProvider<__Context__> for UseContext + where + __Context__: HasBarType, + { + type Bar = <__Context__ as HasBarType>::Bar; + } + impl<__Context__> IsProviderFor for UseContext + where + __Context__: HasBarType, + {} + impl<__Context__, __Components__, __Path__> BarTypeProvider<__Context__> + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: BarTypeProvider<__Context__>, + { + type Bar = <<__Components__ as DelegateComponent< + __Path__, + >>::Delegate as BarTypeProvider<__Context__>>::Bar; + } + impl< + __Context__, + __Components__, + __Path__, + > IsProviderFor + for RedirectLookup<__Components__, __Path__> + where + __Components__: DelegateComponent<__Path__>, + <__Components__ as DelegateComponent< + __Path__, + >>::Delegate: IsProviderFor + + BarTypeProvider<__Context__>, + {} + impl BarTypeProvider<__Context__> for UseType + where + Bar:, + { + type Bar = Bar; + } + impl IsProviderFor + for UseType + where + Bar:, + {} + impl<__Provider__, Bar, __Context__> BarTypeProvider<__Context__> + for WithProvider<__Provider__> + where + __Provider__: TypeProvider<__Context__, BarTypeProviderComponent, Type = Bar>, + Bar:, + { + type Bar = Bar; + } + impl< + __Provider__, + Bar, + __Context__, + > IsProviderFor for WithProvider<__Provider__> + where + __Provider__: TypeProvider<__Context__, BarTypeProviderComponent, Type = Bar>, + Bar:, + {} + ") + } } snapshot_cgp_getter! { From 526ab3a60a8bd8e9e840c05fb78f8a10c0043fa9 Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Fri, 19 Jun 2026 22:28:28 +0200 Subject: [PATCH 25/31] Add `snapshot_check_components!` and `snapshot_delegate_and_check_components!` --- .../src/entrypoints/mod.rs | 4 + .../entrypoints/snapshot_check_components.rs | 12 + .../snapshot_delegate_and_check_components.rs | 12 + .../src/types/check_components.rs | 31 ++ .../types/delegate_and_check_components.rs | 31 ++ .../cgp-macro-test-util-lib/src/types/mod.rs | 4 + crates/macros/cgp-macro-test-util/README.md | 66 +++- crates/macros/cgp-macro-test-util/src/lib.rs | 14 + .../cgp-tests/src/tests/check_components.rs | 322 +++++++++++++----- .../tests/delegate_and_check_components.rs | 98 +++++- .../cgp-tests/src/tests/has_field/chain.rs | 56 ++- .../src/tests/use_delegate/getter.rs | 196 ++++++++--- .../component_tests/abstract_types/basic.rs | 64 +++- .../component_tests/abstract_types/extend.rs | 64 +++- .../component_tests/abstract_types/foreign.rs | 20 +- .../abstract_types/self_referential.rs | 20 +- .../component_tests/cgp_component/constant.rs | 57 +++- .../component_tests/cgp_component/lifetime.rs | 22 +- .../cgp_impl/implicit_args/basic.rs | 31 +- .../cgp_impl/implicit_args/generics.rs | 33 +- .../cgp_impl/implicit_args/import.rs | 36 +- .../tests/component_tests/cgp_impl/shape.rs | 167 +++++++-- .../extensible_data_tests/variants/shape.rs | 27 +- .../cgp-tests/tests/handler_tests/pipe.rs | 44 ++- .../tests/namespace_tests/multi_param.rs | 58 +++- .../tests/namespace_tests/namespace.rs | 22 +- .../namespace_tests/namespace_macro/basic.rs | 24 +- .../namespace_macro/default_impls.rs | 80 +++-- .../namespace_macro/multi_namespace.rs | 45 ++- .../namespace_macro/symbol_path.rs | 24 +- .../namespace_macro/type_path.rs | 24 +- .../cgp-tests/tests/namespace_tests/open.rs | 42 ++- .../tests/namespace_tests/redirect.rs | 21 +- .../preset_tests/basic/consumer_delegate.rs | 25 +- .../tests/preset_tests/basic/contexts.rs | 29 +- .../generics/consumer_delegate.rs | 48 ++- .../tests/preset_tests/generics/contexts.rs | 48 ++- .../generics_inheritance/contexts.rs | 49 ++- .../preset_tests/inheritance/contexts.rs | 28 +- .../nested_inheritance/contexts.rs | 28 +- .../tests/preset_tests/wrapped/context.rs | 30 +- 41 files changed, 1664 insertions(+), 392 deletions(-) create mode 100644 crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_check_components.rs create mode 100644 crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_delegate_and_check_components.rs create mode 100644 crates/macros/cgp-macro-test-util-lib/src/types/check_components.rs create mode 100644 crates/macros/cgp-macro-test-util-lib/src/types/delegate_and_check_components.rs diff --git a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/mod.rs b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/mod.rs index 7e1772f8..2e6b30d7 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/mod.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/mod.rs @@ -5,6 +5,8 @@ mod snapshot_cgp_getter; mod snapshot_cgp_impl; mod snapshot_cgp_namespace; mod snapshot_cgp_type; +mod snapshot_check_components; +mod snapshot_delegate_and_check_components; mod snapshot_delegate_components; pub use snapshot_cgp_auto_getter::*; @@ -14,4 +16,6 @@ pub use snapshot_cgp_getter::*; pub use snapshot_cgp_impl::*; pub use snapshot_cgp_namespace::*; pub use snapshot_cgp_type::*; +pub use snapshot_check_components::*; +pub use snapshot_delegate_and_check_components::*; pub use snapshot_delegate_components::*; diff --git a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_check_components.rs b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_check_components.rs new file mode 100644 index 00000000..ebcbf7e6 --- /dev/null +++ b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_check_components.rs @@ -0,0 +1,12 @@ +use proc_macro2::TokenStream; +use syn::parse2; + +use crate::types::AssertCheckComponents; + +pub fn snapshot_check_components(body: TokenStream) -> syn::Result { + let item: AssertCheckComponents = parse2(body)?; + + let output = cgp_macro_lib::check_components(item.body.clone())?; + + item.snapshot.wrap_output(output) +} diff --git a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_delegate_and_check_components.rs b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_delegate_and_check_components.rs new file mode 100644 index 00000000..64a014e5 --- /dev/null +++ b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_delegate_and_check_components.rs @@ -0,0 +1,12 @@ +use proc_macro2::TokenStream; +use syn::parse2; + +use crate::types::AssertDelegateAndCheckComponents; + +pub fn snapshot_delegate_and_check_components(body: TokenStream) -> syn::Result { + let item: AssertDelegateAndCheckComponents = parse2(body)?; + + let output = cgp_macro_lib::delegate_and_check_components(item.body.clone())?; + + item.snapshot.wrap_output(output) +} diff --git a/crates/macros/cgp-macro-test-util-lib/src/types/check_components.rs b/crates/macros/cgp-macro-test-util-lib/src/types/check_components.rs new file mode 100644 index 00000000..bc088ff8 --- /dev/null +++ b/crates/macros/cgp-macro-test-util-lib/src/types/check_components.rs @@ -0,0 +1,31 @@ +use cgp_macro_core::define_keyword; +use cgp_macro_core::types::keyword::Keyword; +use proc_macro2::TokenStream; +use syn::braced; +use syn::parse::{Parse, ParseStream}; +use syn::token::Not; + +use crate::types::MacroSnapshot; + +define_keyword!(CheckComponents, "check_components"); + +pub struct AssertCheckComponents { + pub body: TokenStream, + pub snapshot: MacroSnapshot, +} + +impl Parse for AssertCheckComponents { + fn parse(input: ParseStream) -> syn::Result { + let _: Keyword = input.parse()?; + let _: Not = input.parse()?; + + let body = { + let body; + braced!(body in input); + body.parse()? + }; + + let snapshot = input.parse()?; + Ok(Self { body, snapshot }) + } +} diff --git a/crates/macros/cgp-macro-test-util-lib/src/types/delegate_and_check_components.rs b/crates/macros/cgp-macro-test-util-lib/src/types/delegate_and_check_components.rs new file mode 100644 index 00000000..8b886fa6 --- /dev/null +++ b/crates/macros/cgp-macro-test-util-lib/src/types/delegate_and_check_components.rs @@ -0,0 +1,31 @@ +use cgp_macro_core::define_keyword; +use cgp_macro_core::types::keyword::Keyword; +use proc_macro2::TokenStream; +use syn::braced; +use syn::parse::{Parse, ParseStream}; +use syn::token::Not; + +use crate::types::MacroSnapshot; + +define_keyword!(DelegateAndCheckComponents, "delegate_and_check_components"); + +pub struct AssertDelegateAndCheckComponents { + pub body: TokenStream, + pub snapshot: MacroSnapshot, +} + +impl Parse for AssertDelegateAndCheckComponents { + fn parse(input: ParseStream) -> syn::Result { + let _: Keyword = input.parse()?; + let _: Not = input.parse()?; + + let body = { + let body; + braced!(body in input); + body.parse()? + }; + + let snapshot = input.parse()?; + Ok(Self { body, snapshot }) + } +} diff --git a/crates/macros/cgp-macro-test-util-lib/src/types/mod.rs b/crates/macros/cgp-macro-test-util-lib/src/types/mod.rs index 9136f935..173e146a 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/types/mod.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/types/mod.rs @@ -5,6 +5,8 @@ mod cgp_getter; mod cgp_impl; mod cgp_namespace; mod cgp_type; +mod check_components; +mod delegate_and_check_components; mod delegate_components; mod snapshot; @@ -15,5 +17,7 @@ pub use cgp_getter::*; pub use cgp_impl::*; pub use cgp_namespace::*; pub use cgp_type::*; +pub use check_components::*; +pub use delegate_and_check_components::*; pub use delegate_components::*; pub use snapshot::*; diff --git a/crates/macros/cgp-macro-test-util/README.md b/crates/macros/cgp-macro-test-util/README.md index 45fbbb1c..e766b75d 100644 --- a/crates/macros/cgp-macro-test-util/README.md +++ b/crates/macros/cgp-macro-test-util/README.md @@ -64,6 +64,8 @@ snapshot output is guaranteed to match what the production macros generate. | `snapshot_cgp_fn!` | `#[cgp_fn]` | | `snapshot_cgp_type!` | `#[cgp_type]` | | `snapshot_delegate_components!` | `delegate_components!` | +| `snapshot_check_components!` | `check_components!` | +| `snapshot_delegate_and_check_components!` | `delegate_and_check_components!` | | `snapshot_cgp_namespace!` | `cgp_namespace!` | ## Anatomy of a snapshot invocation @@ -248,6 +250,63 @@ snapshot_delegate_components! { } ``` +### `snapshot_check_components!` + +The *whole* `check_components! { ... }` invocation is written verbatim, followed +by the test block: + +```rust +snapshot_check_components! { + check_components! { + App { + ErrorRaiserComponent: String, + } + } + + expand_check_app(output) { + assert_snapshot!(output, @"...") + } +} +``` + +The body is forwarded to the real macro verbatim, so every `check_components!` +form is accepted — including the `#[check_trait(...)]` and +`#[check_providers(...)]` attributes, `#[check_params(...)]` / generic +parameters, the array syntax for grouping components and params, and multiple +check specs in a single invocation. The snapshot captures the generated check +trait(s) and their `impl` blocks. + +Note that the snapshot macro emits the same check trait/impls into the +surrounding module, so the compile-time wiring check is preserved — it only +*adds* a snapshot assertion on top. + +### `snapshot_delegate_and_check_components!` + +Likewise, the *whole* `delegate_and_check_components! { ... }` invocation is +written verbatim, followed by the test block: + +```rust +snapshot_delegate_and_check_components! { + delegate_and_check_components! { + #[check_trait(CheckMyContext)] + MyContext { + NameTypeProviderComponent: UseType, + NameGetterComponent: UseField, + } + } + + expand_my_context(output) { + assert_snapshot!(output, @"...") + } +} +``` + +All `delegate_and_check_components!` forms are accepted, since the body is +forwarded to the real macro verbatim — including `#[check_trait(...)]`, +`#[check_params(...)]`, `#[skip_check]`, generic parameters, and array syntax. +The snapshot captures both the generated `DelegateComponent` / `IsProviderFor` +impls *and* the generated check trait + impls. + ### `snapshot_cgp_namespace!` Like `snapshot_delegate_components!`, the *whole* `cgp_namespace! { ... }` @@ -323,10 +382,9 @@ When migrating an existing macro test, two situations come up: ## Notes / limitations -- Snapshot macros exist only for the eight macros listed above. Other CGP macros - (`#[cgp_provider]`, `#[cgp_preset]`, - `check_components!`, `delegate_and_check_components!`, …) are not (yet) - snapshot-wrapped and are left as-is. +- Snapshot macros exist only for the ten macros listed above. Other CGP macros + (`#[cgp_provider]`, `#[cgp_preset]`, …) are not (yet) snapshot-wrapped and are + left as-is. - The pretty-printing is done with [`prettyplease`](https://crates.io/crates/prettyplease), and any macro-prelude noise is stripped beforehand diff --git a/crates/macros/cgp-macro-test-util/src/lib.rs b/crates/macros/cgp-macro-test-util/src/lib.rs index 059c056a..5878264a 100644 --- a/crates/macros/cgp-macro-test-util/src/lib.rs +++ b/crates/macros/cgp-macro-test-util/src/lib.rs @@ -56,3 +56,17 @@ pub fn snapshot_cgp_type(body: TokenStream) -> TokenStream { .unwrap_or_else(syn::Error::into_compile_error) .into() } + +#[proc_macro] +pub fn snapshot_check_components(body: TokenStream) -> TokenStream { + entrypoints::snapshot_check_components(body.into()) + .unwrap_or_else(syn::Error::into_compile_error) + .into() +} + +#[proc_macro] +pub fn snapshot_delegate_and_check_components(body: TokenStream) -> TokenStream { + entrypoints::snapshot_delegate_and_check_components(body.into()) + .unwrap_or_else(syn::Error::into_compile_error) + .into() +} diff --git a/crates/tests/cgp-tests/src/tests/check_components.rs b/crates/tests/cgp-tests/src/tests/check_components.rs index 86cd296e..5daf1824 100644 --- a/crates/tests/cgp-tests/src/tests/check_components.rs +++ b/crates/tests/cgp-tests/src/tests/check_components.rs @@ -4,7 +4,10 @@ mod basic_check_components { use core::marker::PhantomData; use cgp::prelude::*; - use cgp_macro_test_util::{snapshot_cgp_getter, snapshot_cgp_type}; + use cgp_macro_test_util::{ + snapshot_cgp_getter, snapshot_cgp_type, snapshot_check_components, + snapshot_delegate_and_check_components, + }; snapshot_cgp_type! { #[cgp_type] @@ -569,90 +572,223 @@ mod basic_check_components { pub extra_dummy: (), } - delegate_and_check_components! { - Context { - [ - FooTypeProviderComponent, - BarTypeProviderComponent, - ]: - UseType<()>, + snapshot_delegate_and_check_components! { + delegate_and_check_components! { + Context { + [ + FooTypeProviderComponent, + BarTypeProviderComponent, + ]: + UseType<()>, - #[check_params( - (Index<5>, Index<6>), - (Index<7>, Index<8>), - )] - [ #[check_params( - Index<0>, - Index<1>, + (Index<5>, Index<6>), + (Index<7>, Index<8>), )] - FooGetterAtComponent, + [ + #[check_params( + Index<0>, + Index<1>, + )] + FooGetterAtComponent, - #[check_params( - (Index<0>, Index<1>), - (Index<1>, Index<0>), - )] - BarGetterAtComponent, - ]: - UseField, + #[check_params( + (Index<0>, Index<1>), + (Index<1>, Index<0>), + )] + BarGetterAtComponent, + ]: + UseField, + } } - } - check_components! { - #[check_trait(CanUseContext)] - Context { - FooTypeProviderComponent, - BarTypeProviderComponent, - FooGetterAtComponent: [ - Index<0>, - Index<1>, - ], - FooGetterAtComponent: - Index<3>, + expand_context(output) { + insta::assert_snapshot!(output, @r#" + impl DelegateComponent for Context { + type Delegate = UseType<()>; + } + impl< + __Context__, + __Params__, + > IsProviderFor for Context + where + UseType<()>: IsProviderFor, + {} + impl DelegateComponent for Context { + type Delegate = UseType<()>; + } + impl< + __Context__, + __Params__, + > IsProviderFor for Context + where + UseType<()>: IsProviderFor, + {} + impl DelegateComponent for Context { + type Delegate = UseField; + } + impl< + __Context__, + __Params__, + > IsProviderFor for Context + where + UseField< + Symbol!("dummy"), + >: IsProviderFor, + {} + impl DelegateComponent for Context { + type Delegate = UseField; + } + impl< + __Context__, + __Params__, + > IsProviderFor for Context + where + UseField< + Symbol!("dummy"), + >: IsProviderFor, + {} + trait __CanUseContext< + __Component__, + __Params__: ?Sized, + >: CanUseComponent<__Component__, __Params__> {} + impl __CanUseContext for Context {} + impl __CanUseContext for Context {} + impl __CanUseContext> for Context {} + impl __CanUseContext> for Context {} + impl __CanUseContext, Index<6>)> for Context {} + impl __CanUseContext, Index<8>)> for Context {} + impl __CanUseContext, Index<1>)> for Context {} + impl __CanUseContext, Index<0>)> for Context {} + impl __CanUseContext, Index<6>)> for Context {} + impl __CanUseContext, Index<8>)> for Context {} + "#) } + } + + snapshot_check_components! { + check_components! { + #[check_trait(CanUseContext)] + Context { + FooTypeProviderComponent, + BarTypeProviderComponent, + FooGetterAtComponent: [ + Index<0>, + Index<1>, + ], + FooGetterAtComponent: + Index<3>, + } + + #[check_trait(CanUseContext2)] + Context { + BarGetterAtComponent: [ + (Index<0>, Index<1>), + (Index<1>, Index<0>), + ], + BarGetterAtComponent: + (Index<3>, Index<4>), + [ + FooGetterAtComponent, + BarGetterAtComponent, + ]: [ + (Index<5>, Index<6>), + (Index<7>, Index<8>), + ] + } - #[check_trait(CanUseContext2)] - Context { - BarGetterAtComponent: [ - (Index<0>, Index<1>), - (Index<1>, Index<0>), - ], - BarGetterAtComponent: - (Index<3>, Index<4>), - [ - FooGetterAtComponent, - BarGetterAtComponent, - ]: [ - (Index<5>, Index<6>), - (Index<7>, Index<8>), - ] + #[check_trait(CanUseDummyField)] + #[check_providers( + UseField, + UseField, + )] + Context { + FooGetterAtComponent: [ + Index<0>, + Index<1>, + ], + FooGetterAtComponent: + Index<3>, + BarGetterAtComponent: [ + (Index<0>, Index<1>), + (Index<1>, Index<0>), + ], + BarGetterAtComponent: + (Index<3>, Index<4>), + [ + FooGetterAtComponent, + BarGetterAtComponent, + ]: [ + (Index<5>, Index<6>), + (Index<7>, Index<8>), + ] + } } - #[check_trait(CanUseDummyField)] - #[check_providers( - UseField, - UseField, - )] - Context { - FooGetterAtComponent: [ - Index<0>, - Index<1>, - ], - FooGetterAtComponent: - Index<3>, - BarGetterAtComponent: [ - (Index<0>, Index<1>), - (Index<1>, Index<0>), - ], - BarGetterAtComponent: - (Index<3>, Index<4>), - [ - FooGetterAtComponent, - BarGetterAtComponent, - ]: [ - (Index<5>, Index<6>), - (Index<7>, Index<8>), - ] + expand_check_context(output) { + insta::assert_snapshot!(output, @r#" + trait CanUseContext< + __Component__, + __Params__: ?Sized, + >: CanUseComponent<__Component__, __Params__> {} + impl CanUseContext for Context {} + impl CanUseContext for Context {} + impl CanUseContext> for Context {} + impl CanUseContext> for Context {} + impl CanUseContext> for Context {} + trait CanUseContext2< + __Component__, + __Params__: ?Sized, + >: CanUseComponent<__Component__, __Params__> {} + impl CanUseContext2, Index<1>)> for Context {} + impl CanUseContext2, Index<0>)> for Context {} + impl CanUseContext2, Index<4>)> for Context {} + impl CanUseContext2, Index<6>)> for Context {} + impl CanUseContext2, Index<8>)> for Context {} + impl CanUseContext2, Index<6>)> for Context {} + impl CanUseContext2, Index<8>)> for Context {} + trait CanUseDummyField< + __Component__, + __Params__: ?Sized, + >: IsProviderFor<__Component__, Context, __Params__> {} + impl CanUseDummyField> for UseField {} + impl CanUseDummyField> + for UseField {} + impl CanUseDummyField> for UseField {} + impl CanUseDummyField> + for UseField {} + impl CanUseDummyField> for UseField {} + impl CanUseDummyField> + for UseField {} + impl CanUseDummyField, Index<1>)> + for UseField {} + impl CanUseDummyField, Index<1>)> + for UseField {} + impl CanUseDummyField, Index<0>)> + for UseField {} + impl CanUseDummyField, Index<0>)> + for UseField {} + impl CanUseDummyField, Index<4>)> + for UseField {} + impl CanUseDummyField, Index<4>)> + for UseField {} + impl CanUseDummyField, Index<6>)> + for UseField {} + impl CanUseDummyField, Index<6>)> + for UseField {} + impl CanUseDummyField, Index<8>)> + for UseField {} + impl CanUseDummyField, Index<8>)> + for UseField {} + impl CanUseDummyField, Index<6>)> + for UseField {} + impl CanUseDummyField, Index<6>)> + for UseField {} + impl CanUseDummyField, Index<8>)> + for UseField {} + impl CanUseDummyField, Index<8>)> + for UseField {} + "#) } } } @@ -662,7 +798,8 @@ mod generic_check_components { use cgp::prelude::*; use cgp_macro_test_util::{ - snapshot_cgp_getter, snapshot_cgp_type, snapshot_delegate_components, + snapshot_cgp_getter, snapshot_cgp_type, snapshot_check_components, + snapshot_delegate_components, }; snapshot_cgp_type! { @@ -1316,13 +1453,32 @@ mod generic_check_components { } } - check_components! { - <'a, I> Context - where - I: Clone, - { - FooGetterAtComponent: &'a I, - BarGetterAtComponent: (I, &'a Index<0>), + snapshot_check_components! { + check_components! { + <'a, I> Context + where + I: Clone, + { + FooGetterAtComponent: &'a I, + BarGetterAtComponent: (I, &'a Index<0>), + } + } + + expand_check_context(output) { + insta::assert_snapshot!(output, @" + trait __CheckContext< + __Component__, + __Params__: ?Sized, + >: CanUseComponent<__Component__, __Params__> {} + impl<'a, I> __CheckContext for Context + where + I: Clone, + {} + impl<'a, I> __CheckContext, (I, &'a Index<0>)> for Context + where + I: Clone, + {} + ") } } } diff --git a/crates/tests/cgp-tests/src/tests/delegate_and_check_components.rs b/crates/tests/cgp-tests/src/tests/delegate_and_check_components.rs index bcfe4e46..956e1967 100644 --- a/crates/tests/cgp-tests/src/tests/delegate_and_check_components.rs +++ b/crates/tests/cgp-tests/src/tests/delegate_and_check_components.rs @@ -2,7 +2,9 @@ mod basic_delegate_and_check_components { use cgp::prelude::*; - use cgp_macro_test_util::{snapshot_cgp_getter, snapshot_cgp_type}; + use cgp_macro_test_util::{ + snapshot_cgp_getter, snapshot_cgp_type, snapshot_delegate_and_check_components, + }; snapshot_cgp_type! { #[cgp_type] @@ -264,18 +266,53 @@ mod basic_delegate_and_check_components { pub name: String, } - delegate_and_check_components! { - #[check_trait(CheckMyContext)] - MyContext { - NameTypeProviderComponent: UseType, - NameGetterComponent: UseField, + snapshot_delegate_and_check_components! { + delegate_and_check_components! { + #[check_trait(CheckMyContext)] + MyContext { + NameTypeProviderComponent: UseType, + NameGetterComponent: UseField, + } + } + + expand_my_context(output) { + insta::assert_snapshot!(output, @r#" + impl DelegateComponent for MyContext { + type Delegate = UseType; + } + impl< + __Context__, + __Params__, + > IsProviderFor for MyContext + where + UseType: IsProviderFor, + {} + impl DelegateComponent for MyContext { + type Delegate = UseField; + } + impl<__Context__, __Params__> IsProviderFor + for MyContext + where + UseField< + Symbol!("name"), + >: IsProviderFor, + {} + trait CheckMyContext< + __Component__, + __Params__: ?Sized, + >: CanUseComponent<__Component__, __Params__> {} + impl CheckMyContext for MyContext {} + impl CheckMyContext for MyContext {} + "#) } } } mod generic_delegate_and_check_components { use cgp::prelude::*; - use cgp_macro_test_util::{snapshot_cgp_getter, snapshot_cgp_type}; + use cgp_macro_test_util::{ + snapshot_cgp_getter, snapshot_cgp_type, snapshot_delegate_and_check_components, + }; snapshot_cgp_type! { #[cgp_type] @@ -537,11 +574,48 @@ mod generic_delegate_and_check_components { pub name: T, } - delegate_and_check_components! { - - MyContext { - NameTypeProviderComponent: UseType, - NameGetterComponent: UseField, + snapshot_delegate_and_check_components! { + delegate_and_check_components! { + + MyContext { + NameTypeProviderComponent: UseType, + NameGetterComponent: UseField, + } + } + + expand_my_context(output) { + insta::assert_snapshot!(output, @r#" + impl DelegateComponent for MyContext { + type Delegate = UseType; + } + impl< + T, + __Context__, + __Params__, + > IsProviderFor for MyContext + where + UseType: IsProviderFor, + {} + impl DelegateComponent for MyContext { + type Delegate = UseField; + } + impl< + T, + __Context__, + __Params__, + > IsProviderFor for MyContext + where + UseField< + Symbol!("name"), + >: IsProviderFor, + {} + trait __CanUseMyContext< + __Component__, + __Params__: ?Sized, + >: CanUseComponent<__Component__, __Params__> {} + impl __CanUseMyContext for MyContext {} + impl __CanUseMyContext for MyContext {} + "#) } } } diff --git a/crates/tests/cgp-tests/src/tests/has_field/chain.rs b/crates/tests/cgp-tests/src/tests/has_field/chain.rs index 9b003809..c606a256 100644 --- a/crates/tests/cgp-tests/src/tests/has_field/chain.rs +++ b/crates/tests/cgp-tests/src/tests/has_field/chain.rs @@ -79,7 +79,7 @@ fn test_chained_getter_with_inner_life() { mod deeply_nested_getter { use cgp::core::field::impls::ChainGetters; use cgp::prelude::*; - use cgp_macro_test_util::snapshot_cgp_getter; + use cgp_macro_test_util::{snapshot_cgp_getter, snapshot_delegate_and_check_components}; #[derive(HasField)] pub struct A { @@ -236,16 +236,50 @@ mod deeply_nested_getter { } } - delegate_and_check_components! { - MyContext { - NameGetterComponent: WithProvider< - ChainGetters, - UseField, - UseField, - UseField, - UseField - ]>> + snapshot_delegate_and_check_components! { + delegate_and_check_components! { + MyContext { + NameGetterComponent: WithProvider< + ChainGetters, + UseField, + UseField, + UseField, + UseField + ]>> + } + } + + expand_my_context(output) { + insta::assert_snapshot!(output, @r#" + impl DelegateComponent for MyContext { + type Delegate = WithProvider< + ChainGetters< + Product![ + UseField < Symbol!("a") >, UseField < Symbol!("b") >, UseField < + Symbol!("c") >, UseField < Symbol!("d") >, UseField < Symbol!("name") > + ], + >, + >; + } + impl<__Context__, __Params__> IsProviderFor + for MyContext + where + WithProvider< + ChainGetters< + Product![ + UseField < Symbol!("a") >, UseField < Symbol!("b") >, UseField < + Symbol!("c") >, UseField < Symbol!("d") >, UseField < Symbol!("name") > + ], + >, + >: IsProviderFor, + {} + trait __CanUseMyContext< + __Component__, + __Params__: ?Sized, + >: CanUseComponent<__Component__, __Params__> {} + impl __CanUseMyContext for MyContext {} + "#) } } diff --git a/crates/tests/cgp-tests/src/tests/use_delegate/getter.rs b/crates/tests/cgp-tests/src/tests/use_delegate/getter.rs index 88d687f1..f40b5064 100644 --- a/crates/tests/cgp-tests/src/tests/use_delegate/getter.rs +++ b/crates/tests/cgp-tests/src/tests/use_delegate/getter.rs @@ -453,64 +453,159 @@ snapshot_cgp_getter! { } } -#[test] -pub fn test_derive_delegate() { +mod derive_delegate { + use core::marker::PhantomData; + + use cgp::prelude::*; + use cgp_macro_test_util::{snapshot_check_components, snapshot_delegate_and_check_components}; + + use super::*; + #[derive(HasField)] pub struct MyContext { pub foo: u64, pub bar: String, } - delegate_and_check_components! { - MyContext { - #[check_params( - (Index<1>, Index<0>), - (Index<0>, Index<1>), - )] - FooTypeProviderAtComponent: UseDelegate< - new FooTypes { - Index<1>: UseType, - Index<0>: UseType, - } - >, + snapshot_delegate_and_check_components! { + delegate_and_check_components! { + MyContext { + #[check_params( + (Index<1>, Index<0>), + (Index<0>, Index<1>), + )] + FooTypeProviderAtComponent: UseDelegate< + new FooTypes { + Index<1>: UseType, + Index<0>: UseType, + } + >, - #[check_params( - (Index<1>, Index<0>), - (Index<0>, Index<1>), - )] - FooGetterAtComponent: UseDelegate< - new FooGetters { - Index<1>: UseField, - Index<0>: UseField, - } - > + #[check_params( + (Index<1>, Index<0>), + (Index<0>, Index<1>), + )] + FooGetterAtComponent: UseDelegate< + new FooGetters { + Index<1>: UseField, + Index<0>: UseField, + } + > + } + } + + expand_my_context(output) { + insta::assert_snapshot!(output, @r#" + impl DelegateComponent for MyContext { + type Delegate = UseDelegate; + } + impl< + __Context__, + __Params__, + > IsProviderFor for MyContext + where + UseDelegate< + FooTypes, + >: IsProviderFor, + {} + pub struct FooTypes; + impl DelegateComponent> for FooTypes { + type Delegate = UseType; + } + impl<__Context__, __Params__> IsProviderFor, __Context__, __Params__> + for FooTypes + where + UseType: IsProviderFor, __Context__, __Params__>, + {} + impl DelegateComponent> for FooTypes { + type Delegate = UseType; + } + impl<__Context__, __Params__> IsProviderFor, __Context__, __Params__> + for FooTypes + where + UseType: IsProviderFor, __Context__, __Params__>, + {} + impl DelegateComponent for MyContext { + type Delegate = UseDelegate; + } + impl< + __Context__, + __Params__, + > IsProviderFor for MyContext + where + UseDelegate< + FooGetters, + >: IsProviderFor, + {} + pub struct FooGetters; + impl DelegateComponent> for FooGetters { + type Delegate = UseField; + } + impl<__Context__, __Params__> IsProviderFor, __Context__, __Params__> + for FooGetters + where + UseField: IsProviderFor, __Context__, __Params__>, + {} + impl DelegateComponent> for FooGetters { + type Delegate = UseField; + } + impl<__Context__, __Params__> IsProviderFor, __Context__, __Params__> + for FooGetters + where + UseField: IsProviderFor, __Context__, __Params__>, + {} + trait __CanUseMyContext< + __Component__, + __Params__: ?Sized, + >: CanUseComponent<__Component__, __Params__> {} + impl __CanUseMyContext, Index<0>)> for MyContext {} + impl __CanUseMyContext, Index<1>)> for MyContext {} + impl __CanUseMyContext, Index<0>)> for MyContext {} + impl __CanUseMyContext, Index<1>)> for MyContext {} + "#) } } - check_components! { - #[check_trait(CanUseMyContext)] - MyContext { - FooGetterAtComponent: [ - (Index<1>, Index<0>), - (Index<0>, Index<1>), - ] + snapshot_check_components! { + check_components! { + #[check_trait(CanUseMyContext)] + MyContext { + FooGetterAtComponent: [ + (Index<1>, Index<0>), + (Index<0>, Index<1>), + ] + } + } + + expand_check_my_context(output) { + insta::assert_snapshot!(output, @" + trait CanUseMyContext< + __Component__, + __Params__: ?Sized, + >: CanUseComponent<__Component__, __Params__> {} + impl CanUseMyContext, Index<0>)> for MyContext {} + impl CanUseMyContext, Index<1>)> for MyContext {} + ") } } - let context = MyContext { - foo: 42, - bar: "Bar".into(), - }; + #[test] + pub fn test_derive_delegate() { + let context = MyContext { + foo: 42, + bar: "Bar".into(), + }; - assert_eq!(context.foo_at(PhantomData::<(Index<1>, Index<0>)>), &42); - assert_eq!(context.foo_at(PhantomData::<(Index<0>, Index<1>)>), "Bar"); + assert_eq!(context.foo_at(PhantomData::<(Index<1>, Index<0>)>), &42); + assert_eq!(context.foo_at(PhantomData::<(Index<0>, Index<1>)>), "Bar"); + } } mod derive_delegate2 { use core::marker::PhantomData; use cgp::prelude::*; - use cgp_macro_test_util::snapshot_delegate_components; + use cgp_macro_test_util::{snapshot_check_components, snapshot_delegate_components}; use super::*; @@ -614,12 +709,25 @@ mod derive_delegate2 { } } - check_components! { - MyContext { - FooGetterAtComponent: [ - (Index<1>, Index<0>), - (Index<0>, Index<1>), - ] + snapshot_check_components! { + check_components! { + MyContext { + FooGetterAtComponent: [ + (Index<1>, Index<0>), + (Index<0>, Index<1>), + ] + } + } + + expand_check_my_context(output) { + insta::assert_snapshot!(output, @" + trait __CheckMyContext< + __Component__, + __Params__: ?Sized, + >: CanUseComponent<__Component__, __Params__> {} + impl __CheckMyContext, Index<0>)> for MyContext {} + impl __CheckMyContext, Index<1>)> for MyContext {} + ") } } diff --git a/crates/tests/cgp-tests/tests/component_tests/abstract_types/basic.rs b/crates/tests/cgp-tests/tests/component_tests/abstract_types/basic.rs index 73945946..3be3ab9c 100644 --- a/crates/tests/cgp-tests/tests/component_tests/abstract_types/basic.rs +++ b/crates/tests/cgp-tests/tests/component_tests/abstract_types/basic.rs @@ -3,7 +3,7 @@ use std::ops::Mul; use cgp::core::error::ErrorTypeProviderComponent; use cgp::prelude::*; -use cgp_macro_test_util::snapshot_cgp_type; +use cgp_macro_test_util::{snapshot_cgp_type, snapshot_delegate_and_check_components}; snapshot_cgp_type! { #[cgp_type] @@ -132,13 +132,59 @@ pub struct Rectangle { pub height: f64, } -delegate_and_check_components! { - Rectangle { - ErrorTypeProviderComponent: - UseType, - ScalarTypeProviderComponent: - UseType, - AreaCalculatorComponent: - RectangleArea, +snapshot_delegate_and_check_components! { + delegate_and_check_components! { + Rectangle { + ErrorTypeProviderComponent: + UseType, + ScalarTypeProviderComponent: + UseType, + AreaCalculatorComponent: + RectangleArea, + } + } + + expand_rectangle(output) { + insta::assert_snapshot!(output, @" + impl DelegateComponent for Rectangle { + type Delegate = UseType; + } + impl< + __Context__, + __Params__, + > IsProviderFor for Rectangle + where + UseType< + Infallible, + >: IsProviderFor, + {} + impl DelegateComponent for Rectangle { + type Delegate = UseType; + } + impl< + __Context__, + __Params__, + > IsProviderFor for Rectangle + where + UseType: IsProviderFor, + {} + impl DelegateComponent for Rectangle { + type Delegate = RectangleArea; + } + impl< + __Context__, + __Params__, + > IsProviderFor for Rectangle + where + RectangleArea: IsProviderFor, + {} + trait __CanUseRectangle< + __Component__, + __Params__: ?Sized, + >: CanUseComponent<__Component__, __Params__> {} + impl __CanUseRectangle for Rectangle {} + impl __CanUseRectangle for Rectangle {} + impl __CanUseRectangle for Rectangle {} + ") } } diff --git a/crates/tests/cgp-tests/tests/component_tests/abstract_types/extend.rs b/crates/tests/cgp-tests/tests/component_tests/abstract_types/extend.rs index aac4927d..ecd29bd3 100644 --- a/crates/tests/cgp-tests/tests/component_tests/abstract_types/extend.rs +++ b/crates/tests/cgp-tests/tests/component_tests/abstract_types/extend.rs @@ -3,7 +3,7 @@ use std::ops::Mul; use cgp::core::error::ErrorTypeProviderComponent; use cgp::prelude::*; -use cgp_macro_test_util::snapshot_cgp_type; +use cgp_macro_test_util::{snapshot_cgp_type, snapshot_delegate_and_check_components}; snapshot_cgp_type! { #[cgp_type] @@ -136,13 +136,59 @@ pub struct Rectangle { pub height: f64, } -delegate_and_check_components! { - Rectangle { - ErrorTypeProviderComponent: - UseType, - ScalarTypeProviderComponent: - UseType, - AreaCalculatorComponent: - RectangleArea, +snapshot_delegate_and_check_components! { + delegate_and_check_components! { + Rectangle { + ErrorTypeProviderComponent: + UseType, + ScalarTypeProviderComponent: + UseType, + AreaCalculatorComponent: + RectangleArea, + } + } + + expand_rectangle(output) { + insta::assert_snapshot!(output, @" + impl DelegateComponent for Rectangle { + type Delegate = UseType; + } + impl< + __Context__, + __Params__, + > IsProviderFor for Rectangle + where + UseType< + Infallible, + >: IsProviderFor, + {} + impl DelegateComponent for Rectangle { + type Delegate = UseType; + } + impl< + __Context__, + __Params__, + > IsProviderFor for Rectangle + where + UseType: IsProviderFor, + {} + impl DelegateComponent for Rectangle { + type Delegate = RectangleArea; + } + impl< + __Context__, + __Params__, + > IsProviderFor for Rectangle + where + RectangleArea: IsProviderFor, + {} + trait __CanUseRectangle< + __Component__, + __Params__: ?Sized, + >: CanUseComponent<__Component__, __Params__> {} + impl __CanUseRectangle for Rectangle {} + impl __CanUseRectangle for Rectangle {} + impl __CanUseRectangle for Rectangle {} + ") } } diff --git a/crates/tests/cgp-tests/tests/component_tests/abstract_types/foreign.rs b/crates/tests/cgp-tests/tests/component_tests/abstract_types/foreign.rs index c1608cb1..94c983d1 100644 --- a/crates/tests/cgp-tests/tests/component_tests/abstract_types/foreign.rs +++ b/crates/tests/cgp-tests/tests/component_tests/abstract_types/foreign.rs @@ -3,7 +3,7 @@ use std::ops::Mul; use cgp::core::error::ErrorTypeProviderComponent; use cgp::prelude::*; -use cgp_macro_test_util::snapshot_cgp_type; +use cgp_macro_test_util::{snapshot_cgp_type, snapshot_check_components}; snapshot_cgp_type! { #[cgp_type] @@ -147,8 +147,20 @@ delegate_components! { } } -check_components! { - Rectangle { - AreaCalculatorComponent: Types, +snapshot_check_components! { + check_components! { + Rectangle { + AreaCalculatorComponent: Types, + } + } + + expand_check_rectangle(output) { + insta::assert_snapshot!(output, @" + trait __CheckRectangle< + __Component__, + __Params__: ?Sized, + >: CanUseComponent<__Component__, __Params__> {} + impl __CheckRectangle for Rectangle {} + ") } } diff --git a/crates/tests/cgp-tests/tests/component_tests/abstract_types/self_referential.rs b/crates/tests/cgp-tests/tests/component_tests/abstract_types/self_referential.rs index 341e4de6..8c0dba27 100644 --- a/crates/tests/cgp-tests/tests/component_tests/abstract_types/self_referential.rs +++ b/crates/tests/cgp-tests/tests/component_tests/abstract_types/self_referential.rs @@ -1,7 +1,7 @@ use core::ops::Mul; use cgp::prelude::*; -use cgp_macro_test_util::snapshot_cgp_type; +use cgp_macro_test_util::{snapshot_cgp_type, snapshot_check_components}; snapshot_cgp_type! { #[cgp_type] @@ -116,8 +116,20 @@ delegate_components! { } } -check_components! { - App { - ScalarTypeProviderComponent, +snapshot_check_components! { + check_components! { + App { + ScalarTypeProviderComponent, + } + } + + expand_check_app(output) { + insta::assert_snapshot!(output, @" + trait __CheckApp< + __Component__, + __Params__: ?Sized, + >: CanUseComponent<__Component__, __Params__> {} + impl __CheckApp for App {} + ") } } diff --git a/crates/tests/cgp-tests/tests/component_tests/cgp_component/constant.rs b/crates/tests/cgp-tests/tests/component_tests/cgp_component/constant.rs index 39c8c866..cfa119fe 100644 --- a/crates/tests/cgp-tests/tests/component_tests/cgp_component/constant.rs +++ b/crates/tests/cgp-tests/tests/component_tests/cgp_component/constant.rs @@ -1,6 +1,7 @@ -use cgp::prelude::*; +mod basic_const { + use cgp::prelude::*; + use cgp_macro_test_util::snapshot_delegate_and_check_components; -pub fn test_component_with_const() { #[cgp_component(ConstantGetter)] pub trait HasConstant { const CONSTANT: u64; @@ -15,18 +16,44 @@ pub fn test_component_with_const() { pub struct MyContext; - delegate_and_check_components! { - MyContext { - ConstantGetterComponent: UseConstant<42>, + snapshot_delegate_and_check_components! { + delegate_and_check_components! { + MyContext { + ConstantGetterComponent: UseConstant<42>, + } + } + + expand_my_context(output) { + insta::assert_snapshot!(output, @" + impl DelegateComponent for MyContext { + type Delegate = UseConstant<42>; + } + impl< + __Context__, + __Params__, + > IsProviderFor for MyContext + where + UseConstant<42>: IsProviderFor, + {} + trait __CanUseMyContext< + __Component__, + __Params__: ?Sized, + >: CanUseComponent<__Component__, __Params__> {} + impl __CanUseMyContext for MyContext {} + ") } } +} + +pub fn test_component_with_const() { + use basic_const::{HasConstant, MyContext}; assert_eq!(::CONSTANT, 42); } mod generic_const { use cgp::prelude::*; - use cgp_macro_test_util::snapshot_cgp_type; + use cgp_macro_test_util::{snapshot_cgp_type, snapshot_check_components}; snapshot_cgp_type! { #[cgp_type] @@ -156,9 +183,21 @@ mod generic_const { } } - check_components! { - MyContext { - ConstantGetterComponent, + snapshot_check_components! { + check_components! { + MyContext { + ConstantGetterComponent, + } + } + + expand_check_my_context(output) { + insta::assert_snapshot!(output, @" + trait __CheckMyContext< + __Component__, + __Params__: ?Sized, + >: CanUseComponent<__Component__, __Params__> {} + impl __CheckMyContext for MyContext {} + ") } } } diff --git a/crates/tests/cgp-tests/tests/component_tests/cgp_component/lifetime.rs b/crates/tests/cgp-tests/tests/component_tests/cgp_component/lifetime.rs index 1085b31e..01de0b16 100644 --- a/crates/tests/cgp-tests/tests/component_tests/cgp_component/lifetime.rs +++ b/crates/tests/cgp-tests/tests/component_tests/cgp_component/lifetime.rs @@ -1,5 +1,5 @@ use cgp::prelude::*; -use cgp_macro_test_util::snapshot_cgp_component; +use cgp_macro_test_util::{snapshot_cgp_component, snapshot_check_components}; snapshot_cgp_component! { #[cgp_component(ReferenceGetter)] @@ -130,9 +130,21 @@ delegate_components! { } } -check_components! { - <'a> App<'a> { - ReferenceGetterComponent: - (Life<'a>, str), +snapshot_check_components! { + check_components! { + <'a> App<'a> { + ReferenceGetterComponent: + (Life<'a>, str), + } + } + + expand_check_app(output) { + insta::assert_snapshot!(output, @" + trait __CheckApp< + __Component__, + __Params__: ?Sized, + >: CanUseComponent<__Component__, __Params__> {} + impl<'a> __CheckApp, str)> for App<'a> {} + ") } } diff --git a/crates/tests/cgp-tests/tests/component_tests/cgp_impl/implicit_args/basic.rs b/crates/tests/cgp-tests/tests/component_tests/cgp_impl/implicit_args/basic.rs index 99d88075..88594614 100644 --- a/crates/tests/cgp-tests/tests/component_tests/cgp_impl/implicit_args/basic.rs +++ b/crates/tests/cgp-tests/tests/component_tests/cgp_impl/implicit_args/basic.rs @@ -1,4 +1,5 @@ use cgp::prelude::*; +use cgp_macro_test_util::snapshot_delegate_and_check_components; #[cgp_component(AreaCalculator)] pub trait CanCalculateArea { @@ -18,9 +19,31 @@ pub struct Rectangle { pub height: f64, } -delegate_and_check_components! { - Rectangle { - AreaCalculatorComponent: - RectangleArea, +snapshot_delegate_and_check_components! { + delegate_and_check_components! { + Rectangle { + AreaCalculatorComponent: + RectangleArea, + } + } + + expand_rectangle(output) { + insta::assert_snapshot!(output, @" + impl DelegateComponent for Rectangle { + type Delegate = RectangleArea; + } + impl< + __Context__, + __Params__, + > IsProviderFor for Rectangle + where + RectangleArea: IsProviderFor, + {} + trait __CanUseRectangle< + __Component__, + __Params__: ?Sized, + >: CanUseComponent<__Component__, __Params__> {} + impl __CanUseRectangle for Rectangle {} + ") } } diff --git a/crates/tests/cgp-tests/tests/component_tests/cgp_impl/implicit_args/generics.rs b/crates/tests/cgp-tests/tests/component_tests/cgp_impl/implicit_args/generics.rs index 5032ca21..5e4a2d5b 100644 --- a/crates/tests/cgp-tests/tests/component_tests/cgp_impl/implicit_args/generics.rs +++ b/crates/tests/cgp-tests/tests/component_tests/cgp_impl/implicit_args/generics.rs @@ -1,6 +1,7 @@ use core::ops::Mul; use cgp::prelude::*; +use cgp_macro_test_util::snapshot_delegate_and_check_components; #[cgp_component(AreaCalculator)] pub trait CanCalculateArea { @@ -23,10 +24,32 @@ pub struct Rectangle { pub height: f64, } -delegate_and_check_components! { - Rectangle { - #[check_params(f64)] - AreaCalculatorComponent: - RectangleArea, +snapshot_delegate_and_check_components! { + delegate_and_check_components! { + Rectangle { + #[check_params(f64)] + AreaCalculatorComponent: + RectangleArea, + } + } + + expand_rectangle(output) { + insta::assert_snapshot!(output, @" + impl DelegateComponent for Rectangle { + type Delegate = RectangleArea; + } + impl< + __Context__, + __Params__, + > IsProviderFor for Rectangle + where + RectangleArea: IsProviderFor, + {} + trait __CanUseRectangle< + __Component__, + __Params__: ?Sized, + >: CanUseComponent<__Component__, __Params__> {} + impl __CanUseRectangle for Rectangle {} + ") } } diff --git a/crates/tests/cgp-tests/tests/component_tests/cgp_impl/implicit_args/import.rs b/crates/tests/cgp-tests/tests/component_tests/cgp_impl/implicit_args/import.rs index 58c566b1..b8fe907f 100644 --- a/crates/tests/cgp-tests/tests/component_tests/cgp_impl/implicit_args/import.rs +++ b/crates/tests/cgp-tests/tests/component_tests/cgp_impl/implicit_args/import.rs @@ -1,5 +1,5 @@ use cgp::prelude::*; -use cgp_macro_test_util::snapshot_cgp_fn; +use cgp_macro_test_util::{snapshot_cgp_fn, snapshot_delegate_and_check_components}; #[cgp_component(AreaCalculator)] pub trait CanCalculateArea { @@ -82,9 +82,35 @@ pub struct Rectangle { pub height: f64, } -delegate_and_check_components! { - Rectangle { - AreaCalculatorComponent: - RectangleAreaCalculator, +snapshot_delegate_and_check_components! { + delegate_and_check_components! { + Rectangle { + AreaCalculatorComponent: + RectangleAreaCalculator, + } + } + + expand_rectangle(output) { + insta::assert_snapshot!(output, @" + impl DelegateComponent for Rectangle { + type Delegate = RectangleAreaCalculator; + } + impl< + __Context__, + __Params__, + > IsProviderFor for Rectangle + where + RectangleAreaCalculator: IsProviderFor< + AreaCalculatorComponent, + __Context__, + __Params__, + >, + {} + trait __CanUseRectangle< + __Component__, + __Params__: ?Sized, + >: CanUseComponent<__Component__, __Params__> {} + impl __CanUseRectangle for Rectangle {} + ") } } diff --git a/crates/tests/cgp-tests/tests/component_tests/cgp_impl/shape.rs b/crates/tests/cgp-tests/tests/component_tests/cgp_impl/shape.rs index 24c5b9a4..2a9fc0cd 100644 --- a/crates/tests/cgp-tests/tests/component_tests/cgp_impl/shape.rs +++ b/crates/tests/cgp-tests/tests/component_tests/cgp_impl/shape.rs @@ -1,7 +1,9 @@ use core::f64::consts::PI; use cgp::prelude::*; -use cgp_macro_test_util::snapshot_cgp_fn; +use cgp_macro_test_util::{ + snapshot_cgp_fn, snapshot_check_components, snapshot_delegate_and_check_components, +}; snapshot_cgp_fn! { #[cgp_fn] @@ -198,10 +200,36 @@ pub struct PlainRectangle { pub height: f64, } -delegate_and_check_components! { - PlainRectangle { - AreaCalculatorComponent: - RectangleAreaCalculator, +snapshot_delegate_and_check_components! { + delegate_and_check_components! { + PlainRectangle { + AreaCalculatorComponent: + RectangleAreaCalculator, + } + } + + expand_plain_rectangle(output) { + insta::assert_snapshot!(output, @" + impl DelegateComponent for PlainRectangle { + type Delegate = RectangleAreaCalculator; + } + impl< + __Context__, + __Params__, + > IsProviderFor for PlainRectangle + where + RectangleAreaCalculator: IsProviderFor< + AreaCalculatorComponent, + __Context__, + __Params__, + >, + {} + trait __CanUsePlainRectangle< + __Component__, + __Params__: ?Sized, + >: CanUseComponent<__Component__, __Params__> {} + impl __CanUsePlainRectangle for PlainRectangle {} + ") } } @@ -212,10 +240,34 @@ pub struct ScaledRectangle { pub height: f64, } -delegate_and_check_components! { - ScaledRectangle { - AreaCalculatorComponent: - ScaledAreaCalculator, +snapshot_delegate_and_check_components! { + delegate_and_check_components! { + ScaledRectangle { + AreaCalculatorComponent: + ScaledAreaCalculator, + } + } + + expand_scaled_rectangle(output) { + insta::assert_snapshot!(output, @" + impl DelegateComponent for ScaledRectangle { + type Delegate = ScaledAreaCalculator; + } + impl< + __Context__, + __Params__, + > IsProviderFor for ScaledRectangle + where + ScaledAreaCalculator< + RectangleAreaCalculator, + >: IsProviderFor, + {} + trait __CanUseScaledRectangle< + __Component__, + __Params__: ?Sized, + >: CanUseComponent<__Component__, __Params__> {} + impl __CanUseScaledRectangle for ScaledRectangle {} + ") } } @@ -224,10 +276,36 @@ pub struct PlainCircle { pub radius: f64, } -delegate_and_check_components! { - PlainCircle { - AreaCalculatorComponent: - CircleAreaCalculator, +snapshot_delegate_and_check_components! { + delegate_and_check_components! { + PlainCircle { + AreaCalculatorComponent: + CircleAreaCalculator, + } + } + + expand_plain_circle(output) { + insta::assert_snapshot!(output, @" + impl DelegateComponent for PlainCircle { + type Delegate = CircleAreaCalculator; + } + impl< + __Context__, + __Params__, + > IsProviderFor for PlainCircle + where + CircleAreaCalculator: IsProviderFor< + AreaCalculatorComponent, + __Context__, + __Params__, + >, + {} + trait __CanUsePlainCircle< + __Component__, + __Params__: ?Sized, + >: CanUseComponent<__Component__, __Params__> {} + impl __CanUsePlainCircle for PlainCircle {} + ") } } @@ -237,21 +315,60 @@ pub struct ScaledCircle { pub radius: f64, } -delegate_and_check_components! { - ScaledCircle { - AreaCalculatorComponent: - ScaledAreaCalculator, +snapshot_delegate_and_check_components! { + delegate_and_check_components! { + ScaledCircle { + AreaCalculatorComponent: + ScaledAreaCalculator, + } + } + + expand_scaled_circle(output) { + insta::assert_snapshot!(output, @" + impl DelegateComponent for ScaledCircle { + type Delegate = ScaledAreaCalculator; + } + impl< + __Context__, + __Params__, + > IsProviderFor for ScaledCircle + where + ScaledAreaCalculator< + CircleAreaCalculator, + >: IsProviderFor, + {} + trait __CanUseScaledCircle< + __Component__, + __Params__: ?Sized, + >: CanUseComponent<__Component__, __Params__> {} + impl __CanUseScaledCircle for ScaledCircle {} + ") } } -check_components! { - #[check_trait(CheckScaledRectangleProviders)] - #[check_providers( - RectangleAreaCalculator, - ScaledAreaCalculator, - )] - ScaledRectangle { - AreaCalculatorComponent, +snapshot_check_components! { + check_components! { + #[check_trait(CheckScaledRectangleProviders)] + #[check_providers( + RectangleAreaCalculator, + ScaledAreaCalculator, + )] + ScaledRectangle { + AreaCalculatorComponent, + } + } + + expand_check_scaled_rectangle_providers(output) { + insta::assert_snapshot!(output, @" + trait CheckScaledRectangleProviders< + __Component__, + __Params__: ?Sized, + >: IsProviderFor<__Component__, ScaledRectangle, __Params__> {} + impl CheckScaledRectangleProviders + for RectangleAreaCalculator {} + impl CheckScaledRectangleProviders + for ScaledAreaCalculator {} + ") } } diff --git a/crates/tests/cgp-tests/tests/extensible_data_tests/variants/shape.rs b/crates/tests/cgp-tests/tests/extensible_data_tests/variants/shape.rs index d3bc4f8a..d2024e6c 100644 --- a/crates/tests/cgp-tests/tests/extensible_data_tests/variants/shape.rs +++ b/crates/tests/cgp-tests/tests/extensible_data_tests/variants/shape.rs @@ -8,7 +8,7 @@ use cgp::extra::dispatch::{ }; use cgp::extra::handler::{NoCode, UseInputDelegate}; use cgp::prelude::*; -use cgp_macro_test_util::snapshot_delegate_components; +use cgp_macro_test_util::{snapshot_check_components, snapshot_delegate_components}; #[derive(Debug, PartialEq, CgpData)] pub enum Shape { @@ -263,11 +263,24 @@ snapshot_delegate_components! { } } -check_components! { - App { - ComputerComponent: [ - ((), Shape), - ((), ShapePlus), - ], +snapshot_check_components! { + check_components! { + App { + ComputerComponent: [ + ((), Shape), + ((), ShapePlus), + ], + } + } + + expand_check_app(output) { + insta::assert_snapshot!(output, @" + trait __CheckApp< + __Component__, + __Params__: ?Sized, + >: CanUseComponent<__Component__, __Params__> {} + impl __CheckApp for App {} + impl __CheckApp for App {} + ") } } diff --git a/crates/tests/cgp-tests/tests/handler_tests/pipe.rs b/crates/tests/cgp-tests/tests/handler_tests/pipe.rs index eea3df73..68e8fdfb 100644 --- a/crates/tests/cgp-tests/tests/handler_tests/pipe.rs +++ b/crates/tests/cgp-tests/tests/handler_tests/pipe.rs @@ -3,7 +3,7 @@ mod pipe_computers { use cgp::extra::handler::{CanCompute, Computer, ComputerComponent, PipeHandlers}; use cgp::prelude::*; - use cgp_macro_test_util::snapshot_delegate_components; + use cgp_macro_test_util::{snapshot_check_components, snapshot_delegate_components}; #[cgp_new_provider] impl Computer for Multiply @@ -74,10 +74,22 @@ mod pipe_computers { } } - check_components! { - - MyContext { - ComputerComponent: (Tag, u64), + snapshot_check_components! { + check_components! { + + MyContext { + ComputerComponent: (Tag, u64), + } + } + + expand_check_pipe_computers(output) { + insta::assert_snapshot!(output, @" + trait __CheckMyContext< + __Component__, + __Params__: ?Sized, + >: CanUseComponent<__Component__, __Params__> {} + impl __CheckMyContext for MyContext {} + ") } } @@ -104,7 +116,7 @@ mod pipe_handlers { CanHandle, Computer, Handler, HandlerComponent, PipeHandlers, Promote, PromoteAsync, }; use cgp::prelude::*; - use cgp_macro_test_util::snapshot_delegate_components; + use cgp_macro_test_util::{snapshot_check_components, snapshot_delegate_components}; use futures::executor::block_on; #[cgp_new_provider] @@ -193,10 +205,22 @@ mod pipe_handlers { } } - check_components! { - - MyContext { - HandlerComponent: (Tag, u64), + snapshot_check_components! { + check_components! { + + MyContext { + HandlerComponent: (Tag, u64), + } + } + + expand_check_pipe_handlers(output) { + insta::assert_snapshot!(output, @" + trait __CheckMyContext< + __Component__, + __Params__: ?Sized, + >: CanUseComponent<__Component__, __Params__> {} + impl __CheckMyContext for MyContext {} + ") } } diff --git a/crates/tests/cgp-tests/tests/namespace_tests/multi_param.rs b/crates/tests/cgp-tests/tests/namespace_tests/multi_param.rs index b834a6dc..436d082e 100644 --- a/crates/tests/cgp-tests/tests/namespace_tests/multi_param.rs +++ b/crates/tests/cgp-tests/tests/namespace_tests/multi_param.rs @@ -1,6 +1,7 @@ use cgp::prelude::*; use cgp_macro_test_util::{ - snapshot_cgp_component, snapshot_cgp_impl, snapshot_delegate_components, + snapshot_cgp_component, snapshot_cgp_impl, snapshot_check_components, + snapshot_delegate_components, }; snapshot_cgp_component! { @@ -215,14 +216,28 @@ snapshot_delegate_components! { } } -check_components! { - AppA { - FooProviderComponent: [ - <'a> (Life<'a>, String, u32), - <'a> (Life<'a>, bool, String), - ], - FooProviderComponent: - <'a> (Life<'a>, bool, bool), +snapshot_check_components! { + check_components! { + AppA { + FooProviderComponent: [ + <'a> (Life<'a>, String, u32), + <'a> (Life<'a>, bool, String), + ], + FooProviderComponent: + <'a> (Life<'a>, bool, bool), + } + } + + expand_check_app_a(output) { + insta::assert_snapshot!(output, @" + trait __CheckAppA< + __Component__, + __Params__: ?Sized, + >: CanUseComponent<__Component__, __Params__> {} + impl<'a> __CheckAppA, String, u32)> for AppA {} + impl<'a> __CheckAppA, bool, String)> for AppA {} + impl<'a> __CheckAppA, bool, bool)> for AppA {} + ") } } @@ -328,11 +343,24 @@ snapshot_delegate_components! { } } -check_components! { - <'a> AppB { - FooProviderComponent: [ - (Life<'a>, String, u64), - (Life<'a>, bool, String), - ], +snapshot_check_components! { + check_components! { + <'a> AppB { + FooProviderComponent: [ + (Life<'a>, String, u64), + (Life<'a>, bool, String), + ], + } + } + + expand_check_app_b(output) { + insta::assert_snapshot!(output, @" + trait __CheckAppB< + __Component__, + __Params__: ?Sized, + >: CanUseComponent<__Component__, __Params__> {} + impl<'a> __CheckAppB, String, u64)> for AppB {} + impl<'a> __CheckAppB, bool, String)> for AppB {} + ") } } diff --git a/crates/tests/cgp-tests/tests/namespace_tests/namespace.rs b/crates/tests/cgp-tests/tests/namespace_tests/namespace.rs index 6fed3734..96f69787 100644 --- a/crates/tests/cgp-tests/tests/namespace_tests/namespace.rs +++ b/crates/tests/cgp-tests/tests/namespace_tests/namespace.rs @@ -1,7 +1,9 @@ use cgp::core::error::{ErrorRaiserComponent, ErrorTypeProviderComponent}; use cgp::extra::error::ReturnError; use cgp::prelude::*; -use cgp_macro_test_util::{snapshot_cgp_component, snapshot_delegate_components}; +use cgp_macro_test_util::{ + snapshot_cgp_component, snapshot_check_components, snapshot_delegate_components, +}; pub struct MyComponents; @@ -252,8 +254,20 @@ snapshot_delegate_components! { } } -check_components! { - App { - ErrorRaiserComponent: String, +snapshot_check_components! { + check_components! { + App { + ErrorRaiserComponent: String, + } + } + + expand_check_app(output) { + insta::assert_snapshot!(output, @" + trait __CheckApp< + __Component__, + __Params__: ?Sized, + >: CanUseComponent<__Component__, __Params__> {} + impl __CheckApp for App {} + ") } } diff --git a/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/basic.rs b/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/basic.rs index 41dcf87b..55f4813e 100644 --- a/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/basic.rs +++ b/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/basic.rs @@ -1,6 +1,7 @@ use cgp::prelude::*; use cgp_macro_test_util::{ - snapshot_cgp_component, snapshot_cgp_impl, snapshot_cgp_namespace, snapshot_delegate_components, + snapshot_cgp_component, snapshot_cgp_impl, snapshot_cgp_namespace, snapshot_check_components, + snapshot_delegate_components, }; snapshot_cgp_component! { @@ -289,9 +290,22 @@ snapshot_delegate_components! { } } -check_components! { - App { - FooProviderComponent, - BarProviderComponent, +snapshot_check_components! { + check_components! { + App { + FooProviderComponent, + BarProviderComponent, + } + } + + expand_check_app(output) { + insta::assert_snapshot!(output, @" + trait __CheckApp< + __Component__, + __Params__: ?Sized, + >: CanUseComponent<__Component__, __Params__> {} + impl __CheckApp for App {} + impl __CheckApp for App {} + ") } } diff --git a/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/default_impls.rs b/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/default_impls.rs index 456b2f53..c801a4cb 100644 --- a/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/default_impls.rs +++ b/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/default_impls.rs @@ -1,6 +1,6 @@ use cgp::core::component::DefaultImpls1; use cgp::prelude::*; -use cgp_macro_test_util::snapshot_delegate_components; +use cgp_macro_test_util::{snapshot_check_components, snapshot_delegate_components}; use cgp_tests::namespaces::default_impls::{ DefaultShowComponents, ExtendedNamespace, ShowImplComponent, ShowWithDisplay, }; @@ -115,12 +115,25 @@ snapshot_delegate_components! { } } -check_components! { - AppA { - ShowImplComponent: [ - String, - u64, - ] +snapshot_check_components! { + check_components! { + AppA { + ShowImplComponent: [ + String, + u64, + ] + } + } + + expand_check_app_a(output) { + insta::assert_snapshot!(output, @" + trait __CheckAppA< + __Component__, + __Params__: ?Sized, + >: CanUseComponent<__Component__, __Params__> {} + impl __CheckAppA for AppA {} + impl __CheckAppA for AppA {} + ") } } @@ -199,12 +212,25 @@ snapshot_delegate_components! { } } -check_components! { - AppB { - ShowImplComponent: [ - String, - u64, - ] +snapshot_check_components! { + check_components! { + AppB { + ShowImplComponent: [ + String, + u64, + ] + } + } + + expand_check_app_b(output) { + insta::assert_snapshot!(output, @" + trait __CheckAppB< + __Component__, + __Params__: ?Sized, + >: CanUseComponent<__Component__, __Params__> {} + impl __CheckAppB for AppB {} + impl __CheckAppB for AppB {} + ") } } @@ -318,12 +344,26 @@ snapshot_delegate_components! { } } -check_components! { - AppC { - ShowImplComponent: [ - String, - u64, - u32, - ] +snapshot_check_components! { + check_components! { + AppC { + ShowImplComponent: [ + String, + u64, + u32, + ] + } + } + + expand_check_app_c(output) { + insta::assert_snapshot!(output, @" + trait __CheckAppC< + __Component__, + __Params__: ?Sized, + >: CanUseComponent<__Component__, __Params__> {} + impl __CheckAppC for AppC {} + impl __CheckAppC for AppC {} + impl __CheckAppC for AppC {} + ") } } diff --git a/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/multi_namespace.rs b/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/multi_namespace.rs index 80075503..77d4e9ac 100644 --- a/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/multi_namespace.rs +++ b/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/multi_namespace.rs @@ -1,6 +1,7 @@ use cgp::prelude::*; use cgp_macro_test_util::{ - snapshot_cgp_component, snapshot_cgp_impl, snapshot_cgp_namespace, snapshot_delegate_components, + snapshot_cgp_component, snapshot_cgp_impl, snapshot_cgp_namespace, snapshot_check_components, + snapshot_delegate_components, }; pub struct MyApp; @@ -355,10 +356,23 @@ snapshot_delegate_components! { } } -check_components! { - App { - FooProviderComponent, - BarProviderComponent, +snapshot_check_components! { + check_components! { + App { + FooProviderComponent, + BarProviderComponent, + } + } + + expand_check_app(output) { + insta::assert_snapshot!(output, @" + trait __CheckApp< + __Component__, + __Params__: ?Sized, + >: CanUseComponent<__Component__, __Params__> {} + impl __CheckApp for App {} + impl __CheckApp for App {} + ") } } @@ -486,9 +500,22 @@ snapshot_delegate_components! { } } -check_components! { - OtherApp { - FooProviderComponent, - BarProviderComponent, +snapshot_check_components! { + check_components! { + OtherApp { + FooProviderComponent, + BarProviderComponent, + } + } + + expand_check_other_app(output) { + insta::assert_snapshot!(output, @" + trait __CheckOtherApp< + __Component__, + __Params__: ?Sized, + >: CanUseComponent<__Component__, __Params__> {} + impl __CheckOtherApp for OtherApp {} + impl __CheckOtherApp for OtherApp {} + ") } } diff --git a/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/symbol_path.rs b/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/symbol_path.rs index 53d46c33..c398d71a 100644 --- a/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/symbol_path.rs +++ b/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/symbol_path.rs @@ -1,6 +1,7 @@ use cgp::prelude::*; use cgp_macro_test_util::{ - snapshot_cgp_component, snapshot_cgp_impl, snapshot_cgp_namespace, snapshot_delegate_components, + snapshot_cgp_component, snapshot_cgp_impl, snapshot_cgp_namespace, snapshot_check_components, + snapshot_delegate_components, }; snapshot_cgp_component! { @@ -369,9 +370,22 @@ snapshot_delegate_components! { } } -check_components! { - App { - FooProviderComponent, - BarProviderComponent, +snapshot_check_components! { + check_components! { + App { + FooProviderComponent, + BarProviderComponent, + } + } + + expand_check_app(output) { + insta::assert_snapshot!(output, @" + trait __CheckApp< + __Component__, + __Params__: ?Sized, + >: CanUseComponent<__Component__, __Params__> {} + impl __CheckApp for App {} + impl __CheckApp for App {} + ") } } diff --git a/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/type_path.rs b/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/type_path.rs index 7e402354..7704cc92 100644 --- a/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/type_path.rs +++ b/crates/tests/cgp-tests/tests/namespace_tests/namespace_macro/type_path.rs @@ -1,6 +1,7 @@ use cgp::prelude::*; use cgp_macro_test_util::{ - snapshot_cgp_component, snapshot_cgp_impl, snapshot_cgp_namespace, snapshot_delegate_components, + snapshot_cgp_component, snapshot_cgp_impl, snapshot_cgp_namespace, snapshot_check_components, + snapshot_delegate_components, }; pub struct MyApp; @@ -307,9 +308,22 @@ snapshot_delegate_components! { } } -check_components! { - App { - FooProviderComponent, - BarProviderComponent, +snapshot_check_components! { + check_components! { + App { + FooProviderComponent, + BarProviderComponent, + } + } + + expand_check_app(output) { + insta::assert_snapshot!(output, @" + trait __CheckApp< + __Component__, + __Params__: ?Sized, + >: CanUseComponent<__Component__, __Params__> {} + impl __CheckApp for App {} + impl __CheckApp for App {} + ") } } diff --git a/crates/tests/cgp-tests/tests/namespace_tests/open.rs b/crates/tests/cgp-tests/tests/namespace_tests/open.rs index adfcdc34..b7b08be2 100644 --- a/crates/tests/cgp-tests/tests/namespace_tests/open.rs +++ b/crates/tests/cgp-tests/tests/namespace_tests/open.rs @@ -1,6 +1,7 @@ use cgp::prelude::*; use cgp_macro_test_util::{ - snapshot_cgp_component, snapshot_cgp_impl, snapshot_delegate_components, + snapshot_cgp_component, snapshot_cgp_impl, snapshot_check_components, + snapshot_delegate_components, }; pub struct App; @@ -400,16 +401,33 @@ snapshot_delegate_components! { } } -check_components! { - App { - FooProviderComponent: - String, - BarProviderComponent: [ - u32, - u64, - bool, - usize, - isize, - ], +snapshot_check_components! { + check_components! { + App { + FooProviderComponent: + String, + BarProviderComponent: [ + u32, + u64, + bool, + usize, + isize, + ], + } + } + + expand_check_app(output) { + insta::assert_snapshot!(output, @" + trait __CheckApp< + __Component__, + __Params__: ?Sized, + >: CanUseComponent<__Component__, __Params__> {} + impl __CheckApp for App {} + impl __CheckApp for App {} + impl __CheckApp for App {} + impl __CheckApp for App {} + impl __CheckApp for App {} + impl __CheckApp for App {} + ") } } diff --git a/crates/tests/cgp-tests/tests/namespace_tests/redirect.rs b/crates/tests/cgp-tests/tests/namespace_tests/redirect.rs index c0bb0a53..527e4cf2 100644 --- a/crates/tests/cgp-tests/tests/namespace_tests/redirect.rs +++ b/crates/tests/cgp-tests/tests/namespace_tests/redirect.rs @@ -1,6 +1,7 @@ use cgp::prelude::*; use cgp_macro_test_util::{ - snapshot_cgp_component, snapshot_cgp_impl, snapshot_delegate_components, + snapshot_cgp_component, snapshot_cgp_impl, snapshot_check_components, + snapshot_delegate_components, }; snapshot_cgp_component! { @@ -182,8 +183,20 @@ snapshot_delegate_components! { } } -check_components! { - App { - FooProviderComponent, +snapshot_check_components! { + check_components! { + App { + FooProviderComponent, + } + } + + expand_check_app(output) { + insta::assert_snapshot!(output, @" + trait __CheckApp< + __Component__, + __Params__: ?Sized, + >: CanUseComponent<__Component__, __Params__> {} + impl __CheckApp for App {} + ") } } diff --git a/crates/tests/cgp-tests/tests/preset_tests/basic/consumer_delegate.rs b/crates/tests/cgp-tests/tests/preset_tests/basic/consumer_delegate.rs index 12130a7f..b65926c9 100644 --- a/crates/tests/cgp-tests/tests/preset_tests/basic/consumer_delegate.rs +++ b/crates/tests/cgp-tests/tests/preset_tests/basic/consumer_delegate.rs @@ -1,4 +1,5 @@ use cgp::prelude::*; +use cgp_macro_test_util::snapshot_check_components; use crate::preset_tests::basic::components::{ BarTypeProviderComponent, FooGetterComponent, FooTypeProviderComponent, HasBar, @@ -18,11 +19,25 @@ impl HasBar for MyContext { } } -check_components! { - MyContext { - FooTypeProviderComponent, - BarTypeProviderComponent, - FooGetterComponent, +snapshot_check_components! { + check_components! { + MyContext { + FooTypeProviderComponent, + BarTypeProviderComponent, + FooGetterComponent, + } + } + + expand_check_my_context(output) { + insta::assert_snapshot!(output, @" + trait __CheckMyContext< + __Component__, + __Params__: ?Sized, + >: CanUseComponent<__Component__, __Params__> {} + impl __CheckMyContext for MyContext {} + impl __CheckMyContext for MyContext {} + impl __CheckMyContext for MyContext {} + ") } } diff --git a/crates/tests/cgp-tests/tests/preset_tests/basic/contexts.rs b/crates/tests/cgp-tests/tests/preset_tests/basic/contexts.rs index 79dc6cf2..bd379bbf 100644 --- a/crates/tests/cgp-tests/tests/preset_tests/basic/contexts.rs +++ b/crates/tests/cgp-tests/tests/preset_tests/basic/contexts.rs @@ -1,5 +1,5 @@ use cgp::prelude::*; -use cgp_macro_test_util::snapshot_delegate_components; +use cgp_macro_test_util::{snapshot_check_components, snapshot_delegate_components}; use crate::preset_tests::basic::components::{ BarGetterComponent, BarTypeProviderComponent, FooGetterComponent, FooTypeProviderComponent, @@ -34,12 +34,27 @@ snapshot_delegate_components! { } } -check_components! { - MyContext { - FooTypeProviderComponent, - BarTypeProviderComponent, - FooGetterComponent, - BarGetterComponent, +snapshot_check_components! { + check_components! { + MyContext { + FooTypeProviderComponent, + BarTypeProviderComponent, + FooGetterComponent, + BarGetterComponent, + } + } + + expand_check_my_context(output) { + insta::assert_snapshot!(output, @" + trait __CheckMyContext< + __Component__, + __Params__: ?Sized, + >: CanUseComponent<__Component__, __Params__> {} + impl __CheckMyContext for MyContext {} + impl __CheckMyContext for MyContext {} + impl __CheckMyContext for MyContext {} + impl __CheckMyContext for MyContext {} + ") } } diff --git a/crates/tests/cgp-tests/tests/preset_tests/generics/consumer_delegate.rs b/crates/tests/cgp-tests/tests/preset_tests/generics/consumer_delegate.rs index 55bd3295..4515d852 100644 --- a/crates/tests/cgp-tests/tests/preset_tests/generics/consumer_delegate.rs +++ b/crates/tests/cgp-tests/tests/preset_tests/generics/consumer_delegate.rs @@ -1,4 +1,5 @@ use cgp::prelude::*; +use cgp_macro_test_util::snapshot_check_components; use crate::preset_tests::generics::components::{ BarGetterComponent, BarTypeProviderComponent, FooGetterComponent, FooTypeProviderComponent, @@ -12,18 +13,45 @@ pub struct MyContext { pub bar: T, } -check_components! { - #[check_trait(CanUseMyContext)] - MyContext { - FooTypeProviderComponent, - BarTypeProviderComponent, - BarGetterComponent, +snapshot_check_components! { + check_components! { + #[check_trait(CanUseMyContext)] + MyContext { + FooTypeProviderComponent, + BarTypeProviderComponent, + BarGetterComponent, + } + } + + expand_check_my_context(output) { + insta::assert_snapshot!(output, @" + trait CanUseMyContext< + __Component__, + __Params__: ?Sized, + >: CanUseComponent<__Component__, __Params__> {} + impl CanUseMyContext for MyContext {} + impl CanUseMyContext for MyContext {} + impl CanUseMyContext for MyContext {} + ") } } -check_components! { - #[check_trait(CanUseFooGetter)] - MyContext { - FooGetterComponent>: Index, +snapshot_check_components! { + check_components! { + #[check_trait(CanUseFooGetter)] + MyContext { + FooGetterComponent>: Index, + } + } + + expand_check_my_context_2(output) { + insta::assert_snapshot!(output, @" + trait CanUseFooGetter< + __Component__, + __Params__: ?Sized, + >: CanUseComponent<__Component__, __Params__> {} + impl CanUseFooGetter>, Index> + for MyContext {} + ") } } diff --git a/crates/tests/cgp-tests/tests/preset_tests/generics/contexts.rs b/crates/tests/cgp-tests/tests/preset_tests/generics/contexts.rs index 55bd3295..4515d852 100644 --- a/crates/tests/cgp-tests/tests/preset_tests/generics/contexts.rs +++ b/crates/tests/cgp-tests/tests/preset_tests/generics/contexts.rs @@ -1,4 +1,5 @@ use cgp::prelude::*; +use cgp_macro_test_util::snapshot_check_components; use crate::preset_tests::generics::components::{ BarGetterComponent, BarTypeProviderComponent, FooGetterComponent, FooTypeProviderComponent, @@ -12,18 +13,45 @@ pub struct MyContext { pub bar: T, } -check_components! { - #[check_trait(CanUseMyContext)] - MyContext { - FooTypeProviderComponent, - BarTypeProviderComponent, - BarGetterComponent, +snapshot_check_components! { + check_components! { + #[check_trait(CanUseMyContext)] + MyContext { + FooTypeProviderComponent, + BarTypeProviderComponent, + BarGetterComponent, + } + } + + expand_check_my_context(output) { + insta::assert_snapshot!(output, @" + trait CanUseMyContext< + __Component__, + __Params__: ?Sized, + >: CanUseComponent<__Component__, __Params__> {} + impl CanUseMyContext for MyContext {} + impl CanUseMyContext for MyContext {} + impl CanUseMyContext for MyContext {} + ") } } -check_components! { - #[check_trait(CanUseFooGetter)] - MyContext { - FooGetterComponent>: Index, +snapshot_check_components! { + check_components! { + #[check_trait(CanUseFooGetter)] + MyContext { + FooGetterComponent>: Index, + } + } + + expand_check_my_context_2(output) { + insta::assert_snapshot!(output, @" + trait CanUseFooGetter< + __Component__, + __Params__: ?Sized, + >: CanUseComponent<__Component__, __Params__> {} + impl CanUseFooGetter>, Index> + for MyContext {} + ") } } diff --git a/crates/tests/cgp-tests/tests/preset_tests/generics_inheritance/contexts.rs b/crates/tests/cgp-tests/tests/preset_tests/generics_inheritance/contexts.rs index 84248ef6..ef2052bc 100644 --- a/crates/tests/cgp-tests/tests/preset_tests/generics_inheritance/contexts.rs +++ b/crates/tests/cgp-tests/tests/preset_tests/generics_inheritance/contexts.rs @@ -1,4 +1,5 @@ use cgp::prelude::*; +use cgp_macro_test_util::snapshot_check_components; use crate::preset_tests::generics_inheritance::components::{ BarGetterComponent, BarTypeProviderComponent, FooGetterComponent, FooTypeProviderComponent, @@ -12,19 +13,45 @@ pub struct MyContext { pub bar: (), } -check_components! { - MyContext { - FooTypeProviderComponent, - BarTypeProviderComponent, +snapshot_check_components! { + check_components! { + MyContext { + FooTypeProviderComponent, + BarTypeProviderComponent, + } + } + + expand_check_my_context(output) { + insta::assert_snapshot!(output, @" + trait __CheckMyContext< + __Component__, + __Params__: ?Sized, + >: CanUseComponent<__Component__, __Params__> {} + impl __CheckMyContext for MyContext {} + impl __CheckMyContext for MyContext {} + ") } } -check_components! { - #[check_trait(CanUseFooGetter)] - MyContext { - [ - FooGetterComponent, - BarGetterComponent, - ]: I, +snapshot_check_components! { + check_components! { + #[check_trait(CanUseFooGetter)] + MyContext { + [ + FooGetterComponent, + BarGetterComponent, + ]: I, + } + } + + expand_check_my_context_2(output) { + insta::assert_snapshot!(output, @" + trait CanUseFooGetter< + __Component__, + __Params__: ?Sized, + >: CanUseComponent<__Component__, __Params__> {} + impl CanUseFooGetter, I> for MyContext {} + impl CanUseFooGetter, I> for MyContext {} + ") } } diff --git a/crates/tests/cgp-tests/tests/preset_tests/inheritance/contexts.rs b/crates/tests/cgp-tests/tests/preset_tests/inheritance/contexts.rs index cda5816c..86b4b6f7 100644 --- a/crates/tests/cgp-tests/tests/preset_tests/inheritance/contexts.rs +++ b/crates/tests/cgp-tests/tests/preset_tests/inheritance/contexts.rs @@ -1,4 +1,5 @@ use cgp::prelude::*; +use cgp_macro_test_util::snapshot_check_components; use crate::preset_tests::basic::components::{ BarGetterComponent, BarTypeProviderComponent, FooGetterComponent, FooTypeProviderComponent, @@ -12,12 +13,27 @@ pub struct MyContext { pub bar: (), } -check_components! { - MyContext { - FooTypeProviderComponent, - BarTypeProviderComponent, - FooGetterComponent, - BarGetterComponent, +snapshot_check_components! { + check_components! { + MyContext { + FooTypeProviderComponent, + BarTypeProviderComponent, + FooGetterComponent, + BarGetterComponent, + } + } + + expand_check_my_context(output) { + insta::assert_snapshot!(output, @" + trait __CheckMyContext< + __Component__, + __Params__: ?Sized, + >: CanUseComponent<__Component__, __Params__> {} + impl __CheckMyContext for MyContext {} + impl __CheckMyContext for MyContext {} + impl __CheckMyContext for MyContext {} + impl __CheckMyContext for MyContext {} + ") } } diff --git a/crates/tests/cgp-tests/tests/preset_tests/nested_inheritance/contexts.rs b/crates/tests/cgp-tests/tests/preset_tests/nested_inheritance/contexts.rs index da718ab4..da5aaa69 100644 --- a/crates/tests/cgp-tests/tests/preset_tests/nested_inheritance/contexts.rs +++ b/crates/tests/cgp-tests/tests/preset_tests/nested_inheritance/contexts.rs @@ -1,4 +1,5 @@ use cgp::prelude::*; +use cgp_macro_test_util::snapshot_check_components; use crate::preset_tests::basic::components::{ BarGetterComponent, BarTypeProviderComponent, FooGetterComponent, FooTypeProviderComponent, @@ -14,12 +15,27 @@ pub struct MyContext { pub bar: (), } -check_components! { - MyContext { - FooTypeProviderComponent, - BarTypeProviderComponent, - FooGetterComponent, - BarGetterComponent, +snapshot_check_components! { + check_components! { + MyContext { + FooTypeProviderComponent, + BarTypeProviderComponent, + FooGetterComponent, + BarGetterComponent, + } + } + + expand_check_my_context(output) { + insta::assert_snapshot!(output, @" + trait __CheckMyContext< + __Component__, + __Params__: ?Sized, + >: CanUseComponent<__Component__, __Params__> {} + impl __CheckMyContext for MyContext {} + impl __CheckMyContext for MyContext {} + impl __CheckMyContext for MyContext {} + impl __CheckMyContext for MyContext {} + ") } } diff --git a/crates/tests/cgp-tests/tests/preset_tests/wrapped/context.rs b/crates/tests/cgp-tests/tests/preset_tests/wrapped/context.rs index 17c9a17d..5a1ab8a3 100644 --- a/crates/tests/cgp-tests/tests/preset_tests/wrapped/context.rs +++ b/crates/tests/cgp-tests/tests/preset_tests/wrapped/context.rs @@ -2,7 +2,7 @@ use core::convert::Infallible; use cgp::core::error::{ErrorRaiserComponent, ErrorTypeProviderComponent}; use cgp::prelude::*; -use cgp_macro_test_util::snapshot_delegate_components; +use cgp_macro_test_util::{snapshot_check_components, snapshot_delegate_components}; use crate::preset_tests::wrapped::preset::{BoxError, ErrorHandlerPreset}; @@ -50,12 +50,26 @@ snapshot_delegate_components! { } } -check_components! { - MyContext { - ErrorRaiserComponent: [ - BoxError, - Infallible, - std::io::Error, - ] +snapshot_check_components! { + check_components! { + MyContext { + ErrorRaiserComponent: [ + BoxError, + Infallible, + std::io::Error, + ] + } + } + + expand_check_my_context(output) { + insta::assert_snapshot!(output, @" + trait __CheckMyContext< + __Component__, + __Params__: ?Sized, + >: CanUseComponent<__Component__, __Params__> {} + impl __CheckMyContext for MyContext {} + impl __CheckMyContext for MyContext {} + impl __CheckMyContext for MyContext {} + ") } } From 7787737c951d54004e92b2a4f0eb5d0e68d3e402 Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Fri, 19 Jun 2026 22:32:37 +0200 Subject: [PATCH 26/31] Add StatementMacroSnapshot --- .../snapshot_delegate_components.rs | 5 +-- .../cgp-macro-test-util-lib/src/keywords.rs | 3 ++ .../macros/cgp-macro-test-util-lib/src/lib.rs | 1 + .../src/types/delegate_components.rs | 4 +-- .../types/{snapshot.rs => macro_snapshot.rs} | 0 .../cgp-macro-test-util-lib/src/types/mod.rs | 8 ++--- .../src/types/statement_snapshot.rs | 36 +++++++++++++++++++ 7 files changed, 48 insertions(+), 9 deletions(-) create mode 100644 crates/macros/cgp-macro-test-util-lib/src/keywords.rs rename crates/macros/cgp-macro-test-util-lib/src/types/{snapshot.rs => macro_snapshot.rs} (100%) create mode 100644 crates/macros/cgp-macro-test-util-lib/src/types/statement_snapshot.rs diff --git a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_delegate_components.rs b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_delegate_components.rs index eee7be95..52048f92 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_delegate_components.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_delegate_components.rs @@ -1,10 +1,11 @@ use proc_macro2::TokenStream; use syn::parse2; -use crate::types::AssertDelegateComponents; +use crate::keywords::DelegateComponents; +use crate::types::StatementMacroSnapshot; pub fn snapshot_delegate_components(body: TokenStream) -> syn::Result { - let item: AssertDelegateComponents = parse2(body)?; + let item: StatementMacroSnapshot = parse2(body)?; let output = cgp_macro_lib::delegate_components(item.body.clone())?; diff --git a/crates/macros/cgp-macro-test-util-lib/src/keywords.rs b/crates/macros/cgp-macro-test-util-lib/src/keywords.rs new file mode 100644 index 00000000..82a33387 --- /dev/null +++ b/crates/macros/cgp-macro-test-util-lib/src/keywords.rs @@ -0,0 +1,3 @@ +use cgp_macro_core::define_keyword; + +define_keyword!(DelegateComponents, "delegate_components"); diff --git a/crates/macros/cgp-macro-test-util-lib/src/lib.rs b/crates/macros/cgp-macro-test-util-lib/src/lib.rs index 632e4687..a7817a6a 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/lib.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/lib.rs @@ -1,3 +1,4 @@ pub mod entrypoints; pub mod functions; +pub mod keywords; pub mod types; diff --git a/crates/macros/cgp-macro-test-util-lib/src/types/delegate_components.rs b/crates/macros/cgp-macro-test-util-lib/src/types/delegate_components.rs index f2efe94d..21fb3cc0 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/types/delegate_components.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/types/delegate_components.rs @@ -1,14 +1,12 @@ -use cgp_macro_core::define_keyword; use cgp_macro_core::types::keyword::Keyword; use proc_macro2::TokenStream; use syn::braced; use syn::parse::{Parse, ParseStream}; use syn::token::Not; +use crate::keywords::DelegateComponents; use crate::types::MacroSnapshot; -define_keyword!(DelegateComponents, "delegate_components"); - pub struct AssertDelegateComponents { pub body: TokenStream, pub snapshot: MacroSnapshot, diff --git a/crates/macros/cgp-macro-test-util-lib/src/types/snapshot.rs b/crates/macros/cgp-macro-test-util-lib/src/types/macro_snapshot.rs similarity index 100% rename from crates/macros/cgp-macro-test-util-lib/src/types/snapshot.rs rename to crates/macros/cgp-macro-test-util-lib/src/types/macro_snapshot.rs diff --git a/crates/macros/cgp-macro-test-util-lib/src/types/mod.rs b/crates/macros/cgp-macro-test-util-lib/src/types/mod.rs index 173e146a..adeb4e7e 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/types/mod.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/types/mod.rs @@ -7,8 +7,8 @@ mod cgp_namespace; mod cgp_type; mod check_components; mod delegate_and_check_components; -mod delegate_components; -mod snapshot; +mod macro_snapshot; +mod statement_snapshot; pub use cgp_auto_getter::*; pub use cgp_component::*; @@ -19,5 +19,5 @@ pub use cgp_namespace::*; pub use cgp_type::*; pub use check_components::*; pub use delegate_and_check_components::*; -pub use delegate_components::*; -pub use snapshot::*; +pub use macro_snapshot::*; +pub use statement_snapshot::*; diff --git a/crates/macros/cgp-macro-test-util-lib/src/types/statement_snapshot.rs b/crates/macros/cgp-macro-test-util-lib/src/types/statement_snapshot.rs new file mode 100644 index 00000000..7370eca0 --- /dev/null +++ b/crates/macros/cgp-macro-test-util-lib/src/types/statement_snapshot.rs @@ -0,0 +1,36 @@ +use core::marker::PhantomData; + +use cgp_macro_core::traits::IsKeyword; +use cgp_macro_core::types::keyword::Keyword; +use proc_macro2::TokenStream; +use syn::braced; +use syn::parse::{Parse, ParseStream}; +use syn::token::Not; + +use crate::types::MacroSnapshot; + +pub struct StatementMacroSnapshot { + pub body: TokenStream, + pub snapshot: MacroSnapshot, + pub phantom: PhantomData, +} + +impl Parse for StatementMacroSnapshot { + fn parse(input: ParseStream) -> syn::Result { + let _: Keyword = input.parse()?; + let _: Not = input.parse()?; + + let body = { + let body; + braced!(body in input); + body.parse()? + }; + + let snapshot = input.parse()?; + Ok(Self { + body, + snapshot, + phantom: PhantomData, + }) + } +} From e02ea720479abd64ea1c421273d42b8fc6b3e2a4 Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Fri, 19 Jun 2026 22:36:39 +0200 Subject: [PATCH 27/31] Add AttributeMacroSnapshot --- .../src/entrypoints/snapshot_cgp_component.rs | 5 +-- .../src/functions/parse_attribute.rs | 23 ++++++++++++ .../cgp-macro-test-util-lib/src/keywords.rs | 2 ++ .../src/types/attribute_snapshot.rs | 36 +++++++++++++++++++ .../cgp-macro-test-util-lib/src/types/mod.rs | 2 ++ 5 files changed, 66 insertions(+), 2 deletions(-) create mode 100644 crates/macros/cgp-macro-test-util-lib/src/types/attribute_snapshot.rs diff --git a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_component.rs b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_component.rs index 1ccd3f9c..98ec3b8b 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_component.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_component.rs @@ -2,10 +2,11 @@ use proc_macro2::TokenStream; use quote::ToTokens; use syn::parse2; -use crate::types::SnapshotCgpComponent; +use crate::keywords::CgpComponent; +use crate::types::AttributeMacroSnapshot; pub fn snapshot_cgp_component(body: TokenStream) -> syn::Result { - let item: SnapshotCgpComponent = parse2(body)?; + let item: AttributeMacroSnapshot = parse2(body)?; let output = cgp_macro_lib::cgp_component(item.attr, item.body.to_token_stream())?; diff --git a/crates/macros/cgp-macro-test-util-lib/src/functions/parse_attribute.rs b/crates/macros/cgp-macro-test-util-lib/src/functions/parse_attribute.rs index b17019b4..ce30900a 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/functions/parse_attribute.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/functions/parse_attribute.rs @@ -1,3 +1,5 @@ +use cgp_macro_core::traits::IsKeyword; +use cgp_macro_core::types::keyword::Keyword; use proc_macro2::TokenStream; use syn::parse::ParseStream; use syn::token::Paren; @@ -29,3 +31,24 @@ pub fn parse_attribute(expected_keyword: &str, input: ParseStream) -> syn::Resul Ok(body) } + +pub fn parse_attribute_with_keyword(input: ParseStream) -> syn::Result { + let outer_body; + bracketed!(outer_body in input); + + let _: Keyword = outer_body.parse()?; + + let body = if outer_body.is_empty() { + TokenStream::new() + } else if outer_body.peek(Paren) { + let inner_body; + parenthesized!(inner_body in outer_body); + inner_body.parse()? + } else { + let inner_body; + braced!(inner_body in outer_body); + inner_body.parse()? + }; + + Ok(body) +} diff --git a/crates/macros/cgp-macro-test-util-lib/src/keywords.rs b/crates/macros/cgp-macro-test-util-lib/src/keywords.rs index 82a33387..e4741e2e 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/keywords.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/keywords.rs @@ -1,3 +1,5 @@ use cgp_macro_core::define_keyword; define_keyword!(DelegateComponents, "delegate_components"); + +define_keyword!(CgpComponent, "cgp_component"); diff --git a/crates/macros/cgp-macro-test-util-lib/src/types/attribute_snapshot.rs b/crates/macros/cgp-macro-test-util-lib/src/types/attribute_snapshot.rs new file mode 100644 index 00000000..7baf3db4 --- /dev/null +++ b/crates/macros/cgp-macro-test-util-lib/src/types/attribute_snapshot.rs @@ -0,0 +1,36 @@ +use core::marker::PhantomData; + +use cgp_macro_core::traits::IsKeyword; +use proc_macro2::TokenStream; +use syn::ItemTrait; +use syn::parse::{Parse, ParseStream}; +use syn::token::Pound; + +use crate::functions::parse_attribute_with_keyword; +use crate::types::MacroSnapshot; + +pub struct AttributeMacroSnapshot { + pub attr: TokenStream, + pub body: ItemTrait, + pub snapshot: MacroSnapshot, + pub phantom: PhantomData, +} + +impl Parse for AttributeMacroSnapshot { + fn parse(input: ParseStream) -> syn::Result { + let _: Pound = input.parse()?; + + let attr = parse_attribute_with_keyword::(input)?; + + let body = input.parse()?; + + let snapshot = input.parse()?; + + Ok(Self { + attr, + body, + snapshot, + phantom: PhantomData, + }) + } +} diff --git a/crates/macros/cgp-macro-test-util-lib/src/types/mod.rs b/crates/macros/cgp-macro-test-util-lib/src/types/mod.rs index adeb4e7e..f13dc46b 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/types/mod.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/types/mod.rs @@ -1,3 +1,4 @@ +mod attribute_snapshot; mod cgp_auto_getter; mod cgp_component; mod cgp_fn; @@ -10,6 +11,7 @@ mod delegate_and_check_components; mod macro_snapshot; mod statement_snapshot; +pub use attribute_snapshot::*; pub use cgp_auto_getter::*; pub use cgp_component::*; pub use cgp_fn::*; From 1907737e21200bc69665799b85dea85cb0f88732 Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Fri, 19 Jun 2026 22:38:08 +0200 Subject: [PATCH 28/31] Remove SnapshotCgpComponent --- .../src/types/cgp_component.rs | 31 ------------------- .../cgp-macro-test-util-lib/src/types/mod.rs | 2 -- 2 files changed, 33 deletions(-) delete mode 100644 crates/macros/cgp-macro-test-util-lib/src/types/cgp_component.rs diff --git a/crates/macros/cgp-macro-test-util-lib/src/types/cgp_component.rs b/crates/macros/cgp-macro-test-util-lib/src/types/cgp_component.rs deleted file mode 100644 index 522d641f..00000000 --- a/crates/macros/cgp-macro-test-util-lib/src/types/cgp_component.rs +++ /dev/null @@ -1,31 +0,0 @@ -use proc_macro2::TokenStream; -use syn::ItemTrait; -use syn::parse::{Parse, ParseStream}; -use syn::token::Pound; - -use crate::functions::parse_attribute; -use crate::types::MacroSnapshot; - -pub struct SnapshotCgpComponent { - pub attr: TokenStream, - pub body: ItemTrait, - pub snapshot: MacroSnapshot, -} - -impl Parse for SnapshotCgpComponent { - fn parse(input: ParseStream) -> syn::Result { - let _: Pound = input.parse()?; - - let attr = parse_attribute("cgp_component", input)?; - - let body = input.parse()?; - - let snapshot = input.parse()?; - - Ok(Self { - attr, - body, - snapshot, - }) - } -} diff --git a/crates/macros/cgp-macro-test-util-lib/src/types/mod.rs b/crates/macros/cgp-macro-test-util-lib/src/types/mod.rs index f13dc46b..4050b8fd 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/types/mod.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/types/mod.rs @@ -1,6 +1,5 @@ mod attribute_snapshot; mod cgp_auto_getter; -mod cgp_component; mod cgp_fn; mod cgp_getter; mod cgp_impl; @@ -13,7 +12,6 @@ mod statement_snapshot; pub use attribute_snapshot::*; pub use cgp_auto_getter::*; -pub use cgp_component::*; pub use cgp_fn::*; pub use cgp_getter::*; pub use cgp_impl::*; From 110e174f3681efd34090f2a4cd291948e6937a16 Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Fri, 19 Jun 2026 22:47:15 +0200 Subject: [PATCH 29/31] Migrate all other macros --- .../entrypoints/snapshot_cgp_auto_getter.rs | 7 +++-- .../src/entrypoints/snapshot_cgp_component.rs | 4 +-- .../src/entrypoints/snapshot_cgp_fn.rs | 7 +++-- .../src/entrypoints/snapshot_cgp_getter.rs | 7 +++-- .../src/entrypoints/snapshot_cgp_impl.rs | 7 +++-- .../src/entrypoints/snapshot_cgp_namespace.rs | 5 +-- .../src/entrypoints/snapshot_cgp_type.rs | 7 +++-- .../entrypoints/snapshot_check_components.rs | 5 +-- .../snapshot_delegate_and_check_components.rs | 5 +-- .../src/functions/parse_attribute.rs | 29 +---------------- .../cgp-macro-test-util-lib/src/keywords.rs | 18 ++++++++++- .../src/types/attribute_snapshot.rs | 7 ++--- .../src/types/cgp_auto_getter.rs | 31 ------------------- .../src/types/cgp_fn.rs | 31 ------------------- .../src/types/cgp_getter.rs | 31 ------------------- .../src/types/cgp_impl.rs | 31 ------------------- .../src/types/cgp_namespace.rs | 31 ------------------- .../src/types/cgp_type.rs | 31 ------------------- .../src/types/check_components.rs | 31 ------------------- .../types/delegate_and_check_components.rs | 31 ------------------- .../src/types/delegate_components.rs | 29 ----------------- .../cgp-macro-test-util-lib/src/types/mod.rs | 16 ---------- 22 files changed, 52 insertions(+), 349 deletions(-) delete mode 100644 crates/macros/cgp-macro-test-util-lib/src/types/cgp_auto_getter.rs delete mode 100644 crates/macros/cgp-macro-test-util-lib/src/types/cgp_fn.rs delete mode 100644 crates/macros/cgp-macro-test-util-lib/src/types/cgp_getter.rs delete mode 100644 crates/macros/cgp-macro-test-util-lib/src/types/cgp_impl.rs delete mode 100644 crates/macros/cgp-macro-test-util-lib/src/types/cgp_namespace.rs delete mode 100644 crates/macros/cgp-macro-test-util-lib/src/types/cgp_type.rs delete mode 100644 crates/macros/cgp-macro-test-util-lib/src/types/check_components.rs delete mode 100644 crates/macros/cgp-macro-test-util-lib/src/types/delegate_and_check_components.rs delete mode 100644 crates/macros/cgp-macro-test-util-lib/src/types/delegate_components.rs diff --git a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_auto_getter.rs b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_auto_getter.rs index c626ec9b..0225408c 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_auto_getter.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_auto_getter.rs @@ -1,11 +1,12 @@ use proc_macro2::TokenStream; use quote::ToTokens; -use syn::parse2; +use syn::{ItemTrait, parse2}; -use crate::types::SnapshotCgpAutoGetter; +use crate::keywords::CgpAutoGetter; +use crate::types::AttributeMacroSnapshot; pub fn snapshot_cgp_auto_getter(body: TokenStream) -> syn::Result { - let item: SnapshotCgpAutoGetter = parse2(body)?; + let item: AttributeMacroSnapshot = parse2(body)?; let output = cgp_macro_lib::cgp_auto_getter(item.attr, item.body.to_token_stream())?; diff --git a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_component.rs b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_component.rs index 98ec3b8b..36b74092 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_component.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_component.rs @@ -1,12 +1,12 @@ use proc_macro2::TokenStream; use quote::ToTokens; -use syn::parse2; +use syn::{ItemTrait, parse2}; use crate::keywords::CgpComponent; use crate::types::AttributeMacroSnapshot; pub fn snapshot_cgp_component(body: TokenStream) -> syn::Result { - let item: AttributeMacroSnapshot = parse2(body)?; + let item: AttributeMacroSnapshot = parse2(body)?; let output = cgp_macro_lib::cgp_component(item.attr, item.body.to_token_stream())?; diff --git a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_fn.rs b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_fn.rs index 9b96b777..68fe6002 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_fn.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_fn.rs @@ -1,11 +1,12 @@ use proc_macro2::TokenStream; use quote::ToTokens; -use syn::parse2; +use syn::{ItemFn, parse2}; -use crate::types::SnapshotCgpFn; +use crate::keywords::CgpFn; +use crate::types::AttributeMacroSnapshot; pub fn snapshot_cgp_fn(body: TokenStream) -> syn::Result { - let item: SnapshotCgpFn = parse2(body)?; + let item: AttributeMacroSnapshot = parse2(body)?; let output = cgp_macro_lib::cgp_fn(item.attr, item.body.to_token_stream())?; diff --git a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_getter.rs b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_getter.rs index e17951f4..bc2a615b 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_getter.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_getter.rs @@ -1,11 +1,12 @@ use proc_macro2::TokenStream; use quote::ToTokens; -use syn::parse2; +use syn::{ItemTrait, parse2}; -use crate::types::SnapshotCgpGetter; +use crate::keywords::CgpGetter; +use crate::types::AttributeMacroSnapshot; pub fn snapshot_cgp_getter(body: TokenStream) -> syn::Result { - let item: SnapshotCgpGetter = parse2(body)?; + let item: AttributeMacroSnapshot = parse2(body)?; let output = cgp_macro_lib::cgp_getter(item.attr, item.body.to_token_stream())?; diff --git a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_impl.rs b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_impl.rs index 46812a57..6711cad7 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_impl.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_impl.rs @@ -1,11 +1,12 @@ use proc_macro2::TokenStream; use quote::ToTokens; -use syn::parse2; +use syn::{ItemImpl, parse2}; -use crate::types::SnapshotCgpImpl; +use crate::keywords::CgpImpl; +use crate::types::AttributeMacroSnapshot; pub fn snapshot_cgp_impl(body: TokenStream) -> syn::Result { - let item: SnapshotCgpImpl = parse2(body)?; + let item: AttributeMacroSnapshot = parse2(body)?; let output = cgp_macro_lib::cgp_impl(item.attr, item.body.to_token_stream())?; diff --git a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_namespace.rs b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_namespace.rs index 307ed59d..82e1870f 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_namespace.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_namespace.rs @@ -1,10 +1,11 @@ use proc_macro2::TokenStream; use syn::parse2; -use crate::types::AssertCgpNamespace; +use crate::keywords::CgpNamespace; +use crate::types::StatementMacroSnapshot; pub fn snapshot_cgp_namespace(body: TokenStream) -> syn::Result { - let item: AssertCgpNamespace = parse2(body)?; + let item: StatementMacroSnapshot = parse2(body)?; let output = cgp_macro_lib::cgp_namespace(item.body.clone())?; diff --git a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_type.rs b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_type.rs index 4b5c3676..1f09cecd 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_type.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_type.rs @@ -1,11 +1,12 @@ use proc_macro2::TokenStream; use quote::ToTokens; -use syn::parse2; +use syn::{ItemTrait, parse2}; -use crate::types::SnapshotCgpType; +use crate::keywords::CgpType; +use crate::types::AttributeMacroSnapshot; pub fn snapshot_cgp_type(body: TokenStream) -> syn::Result { - let item: SnapshotCgpType = parse2(body)?; + let item: AttributeMacroSnapshot = parse2(body)?; let output = cgp_macro_lib::cgp_type(item.attr, item.body.to_token_stream())?; diff --git a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_check_components.rs b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_check_components.rs index ebcbf7e6..f60047fe 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_check_components.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_check_components.rs @@ -1,10 +1,11 @@ use proc_macro2::TokenStream; use syn::parse2; -use crate::types::AssertCheckComponents; +use crate::keywords::CheckComponents; +use crate::types::StatementMacroSnapshot; pub fn snapshot_check_components(body: TokenStream) -> syn::Result { - let item: AssertCheckComponents = parse2(body)?; + let item: StatementMacroSnapshot = parse2(body)?; let output = cgp_macro_lib::check_components(item.body.clone())?; diff --git a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_delegate_and_check_components.rs b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_delegate_and_check_components.rs index 64a014e5..92f2c748 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_delegate_and_check_components.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_delegate_and_check_components.rs @@ -1,10 +1,11 @@ use proc_macro2::TokenStream; use syn::parse2; -use crate::types::AssertDelegateAndCheckComponents; +use crate::keywords::DelegateAndCheckComponents; +use crate::types::StatementMacroSnapshot; pub fn snapshot_delegate_and_check_components(body: TokenStream) -> syn::Result { - let item: AssertDelegateAndCheckComponents = parse2(body)?; + let item: StatementMacroSnapshot = parse2(body)?; let output = cgp_macro_lib::delegate_and_check_components(item.body.clone())?; diff --git a/crates/macros/cgp-macro-test-util-lib/src/functions/parse_attribute.rs b/crates/macros/cgp-macro-test-util-lib/src/functions/parse_attribute.rs index ce30900a..85259f88 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/functions/parse_attribute.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/functions/parse_attribute.rs @@ -3,34 +3,7 @@ use cgp_macro_core::types::keyword::Keyword; use proc_macro2::TokenStream; use syn::parse::ParseStream; use syn::token::Paren; -use syn::{Error, Ident, braced, bracketed, parenthesized}; - -pub fn parse_attribute(expected_keyword: &str, input: ParseStream) -> syn::Result { - let outer_body; - bracketed!(outer_body in input); - - let keyword: Ident = outer_body.parse()?; - if keyword != expected_keyword { - return Err(Error::new( - keyword.span(), - format!("expect attribute with keyword {expected_keyword}, but got {keyword}"), - )); - } - - let body = if outer_body.is_empty() { - TokenStream::new() - } else if outer_body.peek(Paren) { - let inner_body; - parenthesized!(inner_body in outer_body); - inner_body.parse()? - } else { - let inner_body; - braced!(inner_body in outer_body); - inner_body.parse()? - }; - - Ok(body) -} +use syn::{braced, bracketed, parenthesized}; pub fn parse_attribute_with_keyword(input: ParseStream) -> syn::Result { let outer_body; diff --git a/crates/macros/cgp-macro-test-util-lib/src/keywords.rs b/crates/macros/cgp-macro-test-util-lib/src/keywords.rs index e4741e2e..98397af8 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/keywords.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/keywords.rs @@ -1,5 +1,21 @@ use cgp_macro_core::define_keyword; +define_keyword!(CgpComponent, "cgp_component"); + +define_keyword!(CgpAutoGetter, "cgp_auto_getter"); + +define_keyword!(CgpGetter, "cgp_getter"); + +define_keyword!(CgpImpl, "cgp_impl"); + +define_keyword!(CgpFn, "cgp_fn"); + +define_keyword!(CgpType, "cgp_type"); + +define_keyword!(CgpNamespace, "cgp_namespace"); + define_keyword!(DelegateComponents, "delegate_components"); -define_keyword!(CgpComponent, "cgp_component"); +define_keyword!(CheckComponents, "check_components"); + +define_keyword!(DelegateAndCheckComponents, "delegate_and_check_components"); diff --git a/crates/macros/cgp-macro-test-util-lib/src/types/attribute_snapshot.rs b/crates/macros/cgp-macro-test-util-lib/src/types/attribute_snapshot.rs index 7baf3db4..16e89776 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/types/attribute_snapshot.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/types/attribute_snapshot.rs @@ -2,21 +2,20 @@ use core::marker::PhantomData; use cgp_macro_core::traits::IsKeyword; use proc_macro2::TokenStream; -use syn::ItemTrait; use syn::parse::{Parse, ParseStream}; use syn::token::Pound; use crate::functions::parse_attribute_with_keyword; use crate::types::MacroSnapshot; -pub struct AttributeMacroSnapshot { +pub struct AttributeMacroSnapshot { pub attr: TokenStream, - pub body: ItemTrait, + pub body: Item, pub snapshot: MacroSnapshot, pub phantom: PhantomData, } -impl Parse for AttributeMacroSnapshot { +impl Parse for AttributeMacroSnapshot { fn parse(input: ParseStream) -> syn::Result { let _: Pound = input.parse()?; diff --git a/crates/macros/cgp-macro-test-util-lib/src/types/cgp_auto_getter.rs b/crates/macros/cgp-macro-test-util-lib/src/types/cgp_auto_getter.rs deleted file mode 100644 index f73bd2a2..00000000 --- a/crates/macros/cgp-macro-test-util-lib/src/types/cgp_auto_getter.rs +++ /dev/null @@ -1,31 +0,0 @@ -use proc_macro2::TokenStream; -use syn::ItemTrait; -use syn::parse::{Parse, ParseStream}; -use syn::token::Pound; - -use crate::functions::parse_attribute; -use crate::types::MacroSnapshot; - -pub struct SnapshotCgpAutoGetter { - pub attr: TokenStream, - pub body: ItemTrait, - pub snapshot: MacroSnapshot, -} - -impl Parse for SnapshotCgpAutoGetter { - fn parse(input: ParseStream) -> syn::Result { - let _: Pound = input.parse()?; - - let attr = parse_attribute("cgp_auto_getter", input)?; - - let body = input.parse()?; - - let snapshot = input.parse()?; - - Ok(Self { - attr, - body, - snapshot, - }) - } -} diff --git a/crates/macros/cgp-macro-test-util-lib/src/types/cgp_fn.rs b/crates/macros/cgp-macro-test-util-lib/src/types/cgp_fn.rs deleted file mode 100644 index d742b492..00000000 --- a/crates/macros/cgp-macro-test-util-lib/src/types/cgp_fn.rs +++ /dev/null @@ -1,31 +0,0 @@ -use proc_macro2::TokenStream; -use syn::ItemFn; -use syn::parse::{Parse, ParseStream}; -use syn::token::Pound; - -use crate::functions::parse_attribute; -use crate::types::MacroSnapshot; - -pub struct SnapshotCgpFn { - pub attr: TokenStream, - pub body: ItemFn, - pub snapshot: MacroSnapshot, -} - -impl Parse for SnapshotCgpFn { - fn parse(input: ParseStream) -> syn::Result { - let _: Pound = input.parse()?; - - let attr = parse_attribute("cgp_fn", input)?; - - let body = input.parse()?; - - let snapshot = input.parse()?; - - Ok(Self { - attr, - body, - snapshot, - }) - } -} diff --git a/crates/macros/cgp-macro-test-util-lib/src/types/cgp_getter.rs b/crates/macros/cgp-macro-test-util-lib/src/types/cgp_getter.rs deleted file mode 100644 index 8d49fb7c..00000000 --- a/crates/macros/cgp-macro-test-util-lib/src/types/cgp_getter.rs +++ /dev/null @@ -1,31 +0,0 @@ -use proc_macro2::TokenStream; -use syn::ItemTrait; -use syn::parse::{Parse, ParseStream}; -use syn::token::Pound; - -use crate::functions::parse_attribute; -use crate::types::MacroSnapshot; - -pub struct SnapshotCgpGetter { - pub attr: TokenStream, - pub body: ItemTrait, - pub snapshot: MacroSnapshot, -} - -impl Parse for SnapshotCgpGetter { - fn parse(input: ParseStream) -> syn::Result { - let _: Pound = input.parse()?; - - let attr = parse_attribute("cgp_getter", input)?; - - let body = input.parse()?; - - let snapshot = input.parse()?; - - Ok(Self { - attr, - body, - snapshot, - }) - } -} diff --git a/crates/macros/cgp-macro-test-util-lib/src/types/cgp_impl.rs b/crates/macros/cgp-macro-test-util-lib/src/types/cgp_impl.rs deleted file mode 100644 index 22b19922..00000000 --- a/crates/macros/cgp-macro-test-util-lib/src/types/cgp_impl.rs +++ /dev/null @@ -1,31 +0,0 @@ -use proc_macro2::TokenStream; -use syn::ItemImpl; -use syn::parse::{Parse, ParseStream}; -use syn::token::Pound; - -use crate::functions::parse_attribute; -use crate::types::MacroSnapshot; - -pub struct SnapshotCgpImpl { - pub attr: TokenStream, - pub body: ItemImpl, - pub snapshot: MacroSnapshot, -} - -impl Parse for SnapshotCgpImpl { - fn parse(input: ParseStream) -> syn::Result { - let _: Pound = input.parse()?; - - let attr = parse_attribute("cgp_impl", input)?; - - let body = input.parse()?; - - let snapshot = input.parse()?; - - Ok(Self { - attr, - body, - snapshot, - }) - } -} diff --git a/crates/macros/cgp-macro-test-util-lib/src/types/cgp_namespace.rs b/crates/macros/cgp-macro-test-util-lib/src/types/cgp_namespace.rs deleted file mode 100644 index 0f2c59ac..00000000 --- a/crates/macros/cgp-macro-test-util-lib/src/types/cgp_namespace.rs +++ /dev/null @@ -1,31 +0,0 @@ -use cgp_macro_core::define_keyword; -use cgp_macro_core::types::keyword::Keyword; -use proc_macro2::TokenStream; -use syn::braced; -use syn::parse::{Parse, ParseStream}; -use syn::token::Not; - -use crate::types::MacroSnapshot; - -define_keyword!(CgpNamespace, "cgp_namespace"); - -pub struct AssertCgpNamespace { - pub body: TokenStream, - pub snapshot: MacroSnapshot, -} - -impl Parse for AssertCgpNamespace { - fn parse(input: ParseStream) -> syn::Result { - let _: Keyword = input.parse()?; - let _: Not = input.parse()?; - - let body = { - let body; - braced!(body in input); - body.parse()? - }; - - let snapshot = input.parse()?; - Ok(Self { body, snapshot }) - } -} diff --git a/crates/macros/cgp-macro-test-util-lib/src/types/cgp_type.rs b/crates/macros/cgp-macro-test-util-lib/src/types/cgp_type.rs deleted file mode 100644 index 99200b81..00000000 --- a/crates/macros/cgp-macro-test-util-lib/src/types/cgp_type.rs +++ /dev/null @@ -1,31 +0,0 @@ -use proc_macro2::TokenStream; -use syn::ItemTrait; -use syn::parse::{Parse, ParseStream}; -use syn::token::Pound; - -use crate::functions::parse_attribute; -use crate::types::MacroSnapshot; - -pub struct SnapshotCgpType { - pub attr: TokenStream, - pub body: ItemTrait, - pub snapshot: MacroSnapshot, -} - -impl Parse for SnapshotCgpType { - fn parse(input: ParseStream) -> syn::Result { - let _: Pound = input.parse()?; - - let attr = parse_attribute("cgp_type", input)?; - - let body = input.parse()?; - - let snapshot = input.parse()?; - - Ok(Self { - attr, - body, - snapshot, - }) - } -} diff --git a/crates/macros/cgp-macro-test-util-lib/src/types/check_components.rs b/crates/macros/cgp-macro-test-util-lib/src/types/check_components.rs deleted file mode 100644 index bc088ff8..00000000 --- a/crates/macros/cgp-macro-test-util-lib/src/types/check_components.rs +++ /dev/null @@ -1,31 +0,0 @@ -use cgp_macro_core::define_keyword; -use cgp_macro_core::types::keyword::Keyword; -use proc_macro2::TokenStream; -use syn::braced; -use syn::parse::{Parse, ParseStream}; -use syn::token::Not; - -use crate::types::MacroSnapshot; - -define_keyword!(CheckComponents, "check_components"); - -pub struct AssertCheckComponents { - pub body: TokenStream, - pub snapshot: MacroSnapshot, -} - -impl Parse for AssertCheckComponents { - fn parse(input: ParseStream) -> syn::Result { - let _: Keyword = input.parse()?; - let _: Not = input.parse()?; - - let body = { - let body; - braced!(body in input); - body.parse()? - }; - - let snapshot = input.parse()?; - Ok(Self { body, snapshot }) - } -} diff --git a/crates/macros/cgp-macro-test-util-lib/src/types/delegate_and_check_components.rs b/crates/macros/cgp-macro-test-util-lib/src/types/delegate_and_check_components.rs deleted file mode 100644 index 8b886fa6..00000000 --- a/crates/macros/cgp-macro-test-util-lib/src/types/delegate_and_check_components.rs +++ /dev/null @@ -1,31 +0,0 @@ -use cgp_macro_core::define_keyword; -use cgp_macro_core::types::keyword::Keyword; -use proc_macro2::TokenStream; -use syn::braced; -use syn::parse::{Parse, ParseStream}; -use syn::token::Not; - -use crate::types::MacroSnapshot; - -define_keyword!(DelegateAndCheckComponents, "delegate_and_check_components"); - -pub struct AssertDelegateAndCheckComponents { - pub body: TokenStream, - pub snapshot: MacroSnapshot, -} - -impl Parse for AssertDelegateAndCheckComponents { - fn parse(input: ParseStream) -> syn::Result { - let _: Keyword = input.parse()?; - let _: Not = input.parse()?; - - let body = { - let body; - braced!(body in input); - body.parse()? - }; - - let snapshot = input.parse()?; - Ok(Self { body, snapshot }) - } -} diff --git a/crates/macros/cgp-macro-test-util-lib/src/types/delegate_components.rs b/crates/macros/cgp-macro-test-util-lib/src/types/delegate_components.rs deleted file mode 100644 index 21fb3cc0..00000000 --- a/crates/macros/cgp-macro-test-util-lib/src/types/delegate_components.rs +++ /dev/null @@ -1,29 +0,0 @@ -use cgp_macro_core::types::keyword::Keyword; -use proc_macro2::TokenStream; -use syn::braced; -use syn::parse::{Parse, ParseStream}; -use syn::token::Not; - -use crate::keywords::DelegateComponents; -use crate::types::MacroSnapshot; - -pub struct AssertDelegateComponents { - pub body: TokenStream, - pub snapshot: MacroSnapshot, -} - -impl Parse for AssertDelegateComponents { - fn parse(input: ParseStream) -> syn::Result { - let _: Keyword = input.parse()?; - let _: Not = input.parse()?; - - let body = { - let body; - braced!(body in input); - body.parse()? - }; - - let snapshot = input.parse()?; - Ok(Self { body, snapshot }) - } -} diff --git a/crates/macros/cgp-macro-test-util-lib/src/types/mod.rs b/crates/macros/cgp-macro-test-util-lib/src/types/mod.rs index 4050b8fd..ffef9d53 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/types/mod.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/types/mod.rs @@ -1,23 +1,7 @@ mod attribute_snapshot; -mod cgp_auto_getter; -mod cgp_fn; -mod cgp_getter; -mod cgp_impl; -mod cgp_namespace; -mod cgp_type; -mod check_components; -mod delegate_and_check_components; mod macro_snapshot; mod statement_snapshot; pub use attribute_snapshot::*; -pub use cgp_auto_getter::*; -pub use cgp_fn::*; -pub use cgp_getter::*; -pub use cgp_impl::*; -pub use cgp_namespace::*; -pub use cgp_type::*; -pub use check_components::*; -pub use delegate_and_check_components::*; pub use macro_snapshot::*; pub use statement_snapshot::*; From 550ea30e5f7997d5a90d864e64491f9f9db942af Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Fri, 19 Jun 2026 22:55:05 +0200 Subject: [PATCH 30/31] Add `snapshot_cgp_provider!` macro --- .../src/entrypoints/mod.rs | 4 + .../entrypoints/snapshot_cgp_new_provider.rs | 14 ++ .../src/entrypoints/snapshot_cgp_provider.rs | 14 ++ .../cgp-macro-test-util-lib/src/keywords.rs | 4 + crates/macros/cgp-macro-test-util/README.md | 65 ++++- crates/macros/cgp-macro-test-util/src/lib.rs | 14 ++ .../tests/cgp-tests/src/tests/async/spawn.rs | 237 ++++++++++++++---- crates/tests/cgp-tests/src/tests/compose.rs | 146 ++++++++--- .../component_tests/cgp_component/constant.rs | 52 +++- .../component_tests/cgp_component/lifetime.rs | 40 ++- .../extensible_data_tests/variants/basic.rs | 44 +++- .../cgp-tests/tests/handler_tests/pipe.rs | 172 ++++++++++--- 12 files changed, 658 insertions(+), 148 deletions(-) create mode 100644 crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_new_provider.rs create mode 100644 crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_provider.rs diff --git a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/mod.rs b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/mod.rs index 2e6b30d7..cca0dee2 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/mod.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/mod.rs @@ -4,6 +4,8 @@ mod snapshot_cgp_fn; mod snapshot_cgp_getter; mod snapshot_cgp_impl; mod snapshot_cgp_namespace; +mod snapshot_cgp_new_provider; +mod snapshot_cgp_provider; mod snapshot_cgp_type; mod snapshot_check_components; mod snapshot_delegate_and_check_components; @@ -15,6 +17,8 @@ pub use snapshot_cgp_fn::*; pub use snapshot_cgp_getter::*; pub use snapshot_cgp_impl::*; pub use snapshot_cgp_namespace::*; +pub use snapshot_cgp_new_provider::*; +pub use snapshot_cgp_provider::*; pub use snapshot_cgp_type::*; pub use snapshot_check_components::*; pub use snapshot_delegate_and_check_components::*; diff --git a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_new_provider.rs b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_new_provider.rs new file mode 100644 index 00000000..2b8e97c0 --- /dev/null +++ b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_new_provider.rs @@ -0,0 +1,14 @@ +use proc_macro2::TokenStream; +use quote::ToTokens; +use syn::{ItemImpl, parse2}; + +use crate::keywords::CgpNewProvider; +use crate::types::AttributeMacroSnapshot; + +pub fn snapshot_cgp_new_provider(body: TokenStream) -> syn::Result { + let item: AttributeMacroSnapshot = parse2(body)?; + + let output = cgp_macro_lib::cgp_new_provider(item.attr, item.body.to_token_stream())?; + + item.snapshot.wrap_output(output) +} diff --git a/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_provider.rs b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_provider.rs new file mode 100644 index 00000000..43fc0937 --- /dev/null +++ b/crates/macros/cgp-macro-test-util-lib/src/entrypoints/snapshot_cgp_provider.rs @@ -0,0 +1,14 @@ +use proc_macro2::TokenStream; +use quote::ToTokens; +use syn::{ItemImpl, parse2}; + +use crate::keywords::CgpProvider; +use crate::types::AttributeMacroSnapshot; + +pub fn snapshot_cgp_provider(body: TokenStream) -> syn::Result { + let item: AttributeMacroSnapshot = parse2(body)?; + + let output = cgp_macro_lib::cgp_provider(item.attr, item.body.to_token_stream())?; + + item.snapshot.wrap_output(output) +} diff --git a/crates/macros/cgp-macro-test-util-lib/src/keywords.rs b/crates/macros/cgp-macro-test-util-lib/src/keywords.rs index 98397af8..91c69aaf 100644 --- a/crates/macros/cgp-macro-test-util-lib/src/keywords.rs +++ b/crates/macros/cgp-macro-test-util-lib/src/keywords.rs @@ -8,6 +8,10 @@ define_keyword!(CgpGetter, "cgp_getter"); define_keyword!(CgpImpl, "cgp_impl"); +define_keyword!(CgpProvider, "cgp_provider"); + +define_keyword!(CgpNewProvider, "cgp_new_provider"); + define_keyword!(CgpFn, "cgp_fn"); define_keyword!(CgpType, "cgp_type"); diff --git a/crates/macros/cgp-macro-test-util/README.md b/crates/macros/cgp-macro-test-util/README.md index e766b75d..800346c4 100644 --- a/crates/macros/cgp-macro-test-util/README.md +++ b/crates/macros/cgp-macro-test-util/README.md @@ -59,6 +59,8 @@ snapshot output is guaranteed to match what the production macros generate. | --------------------------- | --------------------- | | `snapshot_cgp_component!` | `#[cgp_component]` | | `snapshot_cgp_impl!` | `#[cgp_impl]` | +| `snapshot_cgp_provider!` | `#[cgp_provider]` | +| `snapshot_cgp_new_provider!`| `#[cgp_new_provider]` | | `snapshot_cgp_auto_getter!` | `#[cgp_auto_getter]` | | `snapshot_cgp_getter!` | `#[cgp_getter]` | | `snapshot_cgp_fn!` | `#[cgp_fn]` | @@ -163,6 +165,64 @@ snapshot_cgp_impl! { } ``` +### `snapshot_cgp_provider!` + +Wraps `#[cgp_provider]` provider impls. The item under test is the full provider +`impl` written exactly as you would normally write it under `#[cgp_provider]` — +the provider struct itself is expected to already be defined elsewhere: + +```rust +pub struct GreetHello; + +snapshot_cgp_provider! { + #[cgp_provider] + impl Greeter for GreetHello + where + Context: HasName, + { + fn greet(context: &Context) { + println!("Hello, {}!", context.name()); + } + } + + expand_greet_hello(output) { + assert_snapshot!(output, @"...") + } +} +``` + +Both the default form `#[cgp_provider]` and the explicit component name form +`#[cgp_provider(GreeterComponent)]` are accepted, mirroring the real macro. In +addition to re-emitting the provider impl, the snapshot captures the generated +`IsProviderFor` impl. + +### `snapshot_cgp_new_provider!` + +Has the identical shape as `snapshot_cgp_provider!`, but wraps +`#[cgp_new_provider]`, which additionally defines the provider struct. The +snapshot therefore also captures the generated `struct` definition: + +```rust +snapshot_cgp_new_provider! { + #[cgp_new_provider] + impl Greeter for GreetHello + where + Context: HasName, + { + fn greet(context: &Context) { + println!("Hello, {}!", context.name()); + } + } + + expand_greet_hello(output) { + assert_snapshot!(output, @"...") + } +} +``` + +Both the default form `#[cgp_new_provider]` and the explicit component name form +`#[cgp_new_provider(GreeterComponent)]` are accepted, mirroring the real macro. + ### `snapshot_cgp_auto_getter!` / `snapshot_cgp_getter!` ```rust @@ -382,9 +442,8 @@ When migrating an existing macro test, two situations come up: ## Notes / limitations -- Snapshot macros exist only for the ten macros listed above. Other CGP macros - (`#[cgp_provider]`, `#[cgp_preset]`, …) are not (yet) snapshot-wrapped and are - left as-is. +- Snapshot macros exist only for the macros listed above. Other CGP macros + (`#[cgp_preset]`, …) are not (yet) snapshot-wrapped and are left as-is. - The pretty-printing is done with [`prettyplease`](https://crates.io/crates/prettyplease), and any macro-prelude noise is stripped beforehand diff --git a/crates/macros/cgp-macro-test-util/src/lib.rs b/crates/macros/cgp-macro-test-util/src/lib.rs index 5878264a..0b32b625 100644 --- a/crates/macros/cgp-macro-test-util/src/lib.rs +++ b/crates/macros/cgp-macro-test-util/src/lib.rs @@ -22,6 +22,20 @@ pub fn snapshot_cgp_impl(body: TokenStream) -> TokenStream { .into() } +#[proc_macro] +pub fn snapshot_cgp_provider(body: TokenStream) -> TokenStream { + entrypoints::snapshot_cgp_provider(body.into()) + .unwrap_or_else(syn::Error::into_compile_error) + .into() +} + +#[proc_macro] +pub fn snapshot_cgp_new_provider(body: TokenStream) -> TokenStream { + entrypoints::snapshot_cgp_new_provider(body.into()) + .unwrap_or_else(syn::Error::into_compile_error) + .into() +} + #[proc_macro] pub fn snapshot_cgp_fn(body: TokenStream) -> TokenStream { entrypoints::snapshot_cgp_fn(body.into()) diff --git a/crates/tests/cgp-tests/src/tests/async/spawn.rs b/crates/tests/cgp-tests/src/tests/async/spawn.rs index 81a8e314..5490700f 100644 --- a/crates/tests/cgp-tests/src/tests/async/spawn.rs +++ b/crates/tests/cgp-tests/src/tests/async/spawn.rs @@ -18,7 +18,8 @@ use cgp::extra::run::{ }; use cgp::prelude::*; use cgp_macro_test_util::{ - snapshot_cgp_component, snapshot_cgp_type, snapshot_delegate_components, + snapshot_cgp_component, snapshot_cgp_new_provider, snapshot_cgp_provider, snapshot_cgp_type, + snapshot_delegate_components, }; use futures::executor::block_on; @@ -565,68 +566,186 @@ snapshot_cgp_component! { // Abstract providers can be implemented without Send bounds -#[cgp_new_provider(RunnerComponent)] -impl Runner for RunWithFooBar -where - Context: CanFetchFoo + CanFetchBar + CanRunFooBar, -{ - async fn run(context: &Context, _code: PhantomData) -> Result<(), Context::Error> { - let foo = context.fetch_foo().await?; - let bar = context.fetch_bar().await?; +snapshot_cgp_new_provider! { + #[cgp_new_provider(RunnerComponent)] + impl Runner for RunWithFooBar + where + Context: CanFetchFoo + CanFetchBar + CanRunFooBar, + { + async fn run(context: &Context, _code: PhantomData) -> Result<(), Context::Error> { + let foo = context.fetch_foo().await?; + let bar = context.fetch_bar().await?; - context.run_foo_bar(&foo, &bar).await?; + context.run_foo_bar(&foo, &bar).await?; - Ok(()) + Ok(()) + } + } + + expand_run_with_foo_bar(output) { + insta::assert_snapshot!(output, @" + impl Runner for RunWithFooBar + where + Context: CanFetchFoo + CanFetchBar + CanRunFooBar, + { + async fn run( + context: &Context, + _code: PhantomData, + ) -> Result<(), Context::Error> { + let foo = context.fetch_foo().await?; + let bar = context.fetch_bar().await?; + context.run_foo_bar(&foo, &bar).await?; + Ok(()) + } + } + impl IsProviderFor for RunWithFooBar + where + Context: CanFetchFoo + CanFetchBar + CanRunFooBar, + {} + pub struct RunWithFooBar; + ") } } -#[cgp_new_provider(RunnerComponent)] -impl Runner for SpawnAndRun -where - Context: 'static + Send + Clone + CanSendRun, -{ - async fn run(context: &Context, _code: PhantomData) -> Result<(), Context::Error> { - let context = context.clone(); +snapshot_cgp_new_provider! { + #[cgp_new_provider(RunnerComponent)] + impl Runner for SpawnAndRun + where + Context: 'static + Send + Clone + CanSendRun, + { + async fn run(context: &Context, _code: PhantomData) -> Result<(), Context::Error> { + let context = context.clone(); - dummy_spawn(async move { - let _ = context.send_run(PhantomData).await; - }); + dummy_spawn(async move { + let _ = context.send_run(PhantomData).await; + }); - Ok(()) + Ok(()) + } + } + + expand_spawn_and_run(output) { + insta::assert_snapshot!(output, @" + impl Runner for SpawnAndRun + where + Context: 'static + Send + Clone + CanSendRun, + { + async fn run( + context: &Context, + _code: PhantomData, + ) -> Result<(), Context::Error> { + let context = context.clone(); + dummy_spawn(async move { + let _ = context.send_run(PhantomData).await; + }); + Ok(()) + } + } + impl IsProviderFor + for SpawnAndRun + where + Context: 'static + Send + Clone + CanSendRun, + {} + pub struct SpawnAndRun(pub ::core::marker::PhantomData<(InCode)>); + ") } } -#[cgp_new_provider] -impl FooFetcher for DummyFetchFoo -where - Context: HasFooType + HasErrorType, -{ - async fn fetch_foo(_context: &Context) -> Result { - Ok(Default::default()) +snapshot_cgp_new_provider! { + #[cgp_new_provider] + impl FooFetcher for DummyFetchFoo + where + Context: HasFooType + HasErrorType, + { + async fn fetch_foo(_context: &Context) -> Result { + Ok(Default::default()) + } + } + + expand_dummy_fetch_foo(output) { + insta::assert_snapshot!(output, @" + impl FooFetcher for DummyFetchFoo + where + Context: HasFooType + HasErrorType, + { + async fn fetch_foo(_context: &Context) -> Result { + Ok(Default::default()) + } + } + impl IsProviderFor for DummyFetchFoo + where + Context: HasFooType + HasErrorType, + {} + pub struct DummyFetchFoo; + ") } } -#[cgp_new_provider] -impl BarFetcher for DummyFetchBar -where - Context: HasBarType + HasErrorType, -{ - async fn fetch_bar(_context: &Context) -> Result { - Ok(Default::default()) +snapshot_cgp_new_provider! { + #[cgp_new_provider] + impl BarFetcher for DummyFetchBar + where + Context: HasBarType + HasErrorType, + { + async fn fetch_bar(_context: &Context) -> Result { + Ok(Default::default()) + } + } + + expand_dummy_fetch_bar(output) { + insta::assert_snapshot!(output, @" + impl BarFetcher for DummyFetchBar + where + Context: HasBarType + HasErrorType, + { + async fn fetch_bar(_context: &Context) -> Result { + Ok(Default::default()) + } + } + impl IsProviderFor for DummyFetchBar + where + Context: HasBarType + HasErrorType, + {} + pub struct DummyFetchBar; + ") } } -#[cgp_new_provider] -impl FooBarRunner for DummyRunFoobar -where - Context: HasFooType + HasBarType + HasErrorType, -{ - async fn run_foo_bar( - _context: &Context, - _foo: &Context::Foo, - _bar: &Context::Bar, - ) -> Result<(), Context::Error> { - Ok(()) +snapshot_cgp_new_provider! { + #[cgp_new_provider] + impl FooBarRunner for DummyRunFoobar + where + Context: HasFooType + HasBarType + HasErrorType, + { + async fn run_foo_bar( + _context: &Context, + _foo: &Context::Foo, + _bar: &Context::Bar, + ) -> Result<(), Context::Error> { + Ok(()) + } + } + + expand_dummy_run_foo_bar(output) { + insta::assert_snapshot!(output, @" + impl FooBarRunner for DummyRunFoobar + where + Context: HasFooType + HasBarType + HasErrorType, + { + async fn run_foo_bar( + _context: &Context, + _foo: &Context::Foo, + _bar: &Context::Bar, + ) -> Result<(), Context::Error> { + Ok(()) + } + } + impl IsProviderFor for DummyRunFoobar + where + Context: HasFooType + HasBarType + HasErrorType, + {} + pub struct DummyRunFoobar; + ") } } @@ -757,10 +876,26 @@ snapshot_delegate_components! { // call to Runner that is implemented by `RunWithFooBar`. // With the concrete context known, the Send bound can be found in the concrete future. -#[cgp_provider] -impl SendRunner for App { - async fn send_run(context: &App, code: PhantomData) -> Result<(), Infallible> { - context.run(code).await +snapshot_cgp_provider! { + #[cgp_provider] + impl SendRunner for App { + async fn send_run(context: &App, code: PhantomData) -> Result<(), Infallible> { + context.run(code).await + } + } + + expand_app_send_runner(output) { + insta::assert_snapshot!(output, @" + impl SendRunner for App { + async fn send_run( + context: &App, + code: PhantomData, + ) -> Result<(), Infallible> { + context.run(code).await + } + } + impl IsProviderFor for App {} + ") } } diff --git a/crates/tests/cgp-tests/src/tests/compose.rs b/crates/tests/cgp-tests/src/tests/compose.rs index 2ca25ba5..79eac769 100644 --- a/crates/tests/cgp-tests/src/tests/compose.rs +++ b/crates/tests/cgp-tests/src/tests/compose.rs @@ -2,6 +2,7 @@ use core::fmt::Display; use cgp::extra::handler::{ComputerRef, ComputerRefComponent}; use cgp::prelude::*; +use cgp_macro_test_util::snapshot_cgp_new_provider; pub fn first_name_to_string(context: &Context) -> String where @@ -33,43 +34,132 @@ pub fn concate_outputs( move |context| format!("{} {}", fn_a(context), fn_b(context)) } -#[cgp_new_provider] -impl ComputerRef for FirstNameToString -where - Context: HasField, -{ - type Output = String; +snapshot_cgp_new_provider! { + #[cgp_new_provider] + impl ComputerRef for FirstNameToString + where + Context: HasField, + { + type Output = String; - fn compute_ref(context: &Context, _code: PhantomData, _input: &Input) -> String { - context.get_field(PhantomData).to_string() + fn compute_ref(context: &Context, _code: PhantomData, _input: &Input) -> String { + context.get_field(PhantomData).to_string() + } + } + + expand_first_name_to_string(output) { + insta::assert_snapshot!(output, @r#" + impl ComputerRef for FirstNameToString + where + Context: HasField, + { + type Output = String; + fn compute_ref( + context: &Context, + _code: PhantomData, + _input: &Input, + ) -> String { + context.get_field(PhantomData).to_string() + } + } + impl IsProviderFor + for FirstNameToString + where + Context: HasField, + {} + pub struct FirstNameToString; + "#) } } -#[cgp_new_provider] -impl ComputerRef for LastNameToString -where - Context: HasField, -{ - type Output = String; +snapshot_cgp_new_provider! { + #[cgp_new_provider] + impl ComputerRef for LastNameToString + where + Context: HasField, + { + type Output = String; + + fn compute_ref(context: &Context, _code: PhantomData, _input: &Input) -> String { + context.get_field(PhantomData).to_string() + } + } - fn compute_ref(context: &Context, _code: PhantomData, _input: &Input) -> String { - context.get_field(PhantomData).to_string() + expand_last_name_to_string(output) { + insta::assert_snapshot!(output, @r#" + impl ComputerRef for LastNameToString + where + Context: HasField, + { + type Output = String; + fn compute_ref( + context: &Context, + _code: PhantomData, + _input: &Input, + ) -> String { + context.get_field(PhantomData).to_string() + } + } + impl IsProviderFor + for LastNameToString + where + Context: HasField, + {} + pub struct LastNameToString; + "#) } } -#[cgp_new_provider] -impl ComputerRef - for ConcatOutputs -where - ProviderA: ComputerRef, - ProviderB: ComputerRef, -{ - type Output = String; +snapshot_cgp_new_provider! { + #[cgp_new_provider] + impl ComputerRef + for ConcatOutputs + where + ProviderA: ComputerRef, + ProviderB: ComputerRef, + { + type Output = String; + + fn compute_ref(context: &Context, code: PhantomData, input: &Input) -> String { + let output_a = ProviderA::compute_ref(context, code, input); + let output_b = ProviderB::compute_ref(context, code, input); + format!("{output_a} {output_b}") + } + } - fn compute_ref(context: &Context, code: PhantomData, input: &Input) -> String { - let output_a = ProviderA::compute_ref(context, code, input); - let output_b = ProviderB::compute_ref(context, code, input); - format!("{output_a} {output_b}") + expand_concat_outputs(output) { + insta::assert_snapshot!(output, @r#" + impl ComputerRef + for ConcatOutputs + where + ProviderA: ComputerRef, + ProviderB: ComputerRef, + { + type Output = String; + fn compute_ref(context: &Context, code: PhantomData, input: &Input) -> String { + let output_a = ProviderA::compute_ref(context, code, input); + let output_b = ProviderB::compute_ref(context, code, input); + format!("{output_a} {output_b}") + } + } + impl< + Context, + Code, + Input, + ProviderA, + ProviderB, + > IsProviderFor + for ConcatOutputs + where + ProviderA: IsProviderFor + + ComputerRef, + ProviderB: IsProviderFor + + ComputerRef, + {} + pub struct ConcatOutputs( + pub ::core::marker::PhantomData<(ProviderA, ProviderB)>, + ); + "#) } } diff --git a/crates/tests/cgp-tests/tests/component_tests/cgp_component/constant.rs b/crates/tests/cgp-tests/tests/component_tests/cgp_component/constant.rs index cfa119fe..7c1e18bf 100644 --- a/crates/tests/cgp-tests/tests/component_tests/cgp_component/constant.rs +++ b/crates/tests/cgp-tests/tests/component_tests/cgp_component/constant.rs @@ -1,6 +1,6 @@ mod basic_const { use cgp::prelude::*; - use cgp_macro_test_util::snapshot_delegate_and_check_components; + use cgp_macro_test_util::{snapshot_cgp_provider, snapshot_delegate_and_check_components}; #[cgp_component(ConstantGetter)] pub trait HasConstant { @@ -9,9 +9,21 @@ mod basic_const { pub struct UseConstant; - #[cgp_provider] - impl ConstantGetter for UseConstant { - const CONSTANT: u64 = CONSTANT; + snapshot_cgp_provider! { + #[cgp_provider] + impl ConstantGetter for UseConstant { + const CONSTANT: u64 = CONSTANT; + } + + expand_use_constant(output) { + insta::assert_snapshot!(output, @" + impl ConstantGetter for UseConstant { + const CONSTANT: u64 = CONSTANT; + } + impl IsProviderFor + for UseConstant {} + ") + } } pub struct MyContext; @@ -53,7 +65,7 @@ pub fn test_component_with_const() { mod generic_const { use cgp::prelude::*; - use cgp_macro_test_util::{snapshot_cgp_type, snapshot_check_components}; + use cgp_macro_test_util::{snapshot_cgp_provider, snapshot_cgp_type, snapshot_check_components}; snapshot_cgp_type! { #[cgp_type] @@ -166,12 +178,30 @@ mod generic_const { pub struct UseConstant; - #[cgp_provider] - impl ConstantGetter for UseConstant - where - Context: HasUnitType, - { - const CONSTANT: u64 = CONSTANT; + snapshot_cgp_provider! { + #[cgp_provider] + impl ConstantGetter for UseConstant + where + Context: HasUnitType, + { + const CONSTANT: u64 = CONSTANT; + } + + expand_use_constant(output) { + insta::assert_snapshot!(output, @" + impl ConstantGetter for UseConstant + where + Context: HasUnitType, + { + const CONSTANT: u64 = CONSTANT; + } + impl IsProviderFor + for UseConstant + where + Context: HasUnitType, + {} + ") + } } pub struct MyContext; diff --git a/crates/tests/cgp-tests/tests/component_tests/cgp_component/lifetime.rs b/crates/tests/cgp-tests/tests/component_tests/cgp_component/lifetime.rs index 01de0b16..b43145c4 100644 --- a/crates/tests/cgp-tests/tests/component_tests/cgp_component/lifetime.rs +++ b/crates/tests/cgp-tests/tests/component_tests/cgp_component/lifetime.rs @@ -1,5 +1,5 @@ use cgp::prelude::*; -use cgp_macro_test_util::{snapshot_cgp_component, snapshot_check_components}; +use cgp_macro_test_util::{snapshot_cgp_component, snapshot_cgp_provider, snapshot_check_components}; snapshot_cgp_component! { #[cgp_component(ReferenceGetter)] @@ -102,13 +102,37 @@ snapshot_cgp_component! { } } -#[cgp_provider] -impl<'a, Context, Tag, T: 'a + ?Sized> ReferenceGetter<'a, Context, T> for UseField -where - Context: HasField, -{ - fn get_reference(context: &Context) -> &'a T { - context.get_field(PhantomData) +snapshot_cgp_provider! { + #[cgp_provider] + impl<'a, Context, Tag, T: 'a + ?Sized> ReferenceGetter<'a, Context, T> for UseField + where + Context: HasField, + { + fn get_reference(context: &Context) -> &'a T { + context.get_field(PhantomData) + } + } + + expand_use_field_reference_getter(output) { + insta::assert_snapshot!(output, @" + impl<'a, Context, Tag, T: 'a + ?Sized> ReferenceGetter<'a, Context, T> for UseField + where + Context: HasField, + { + fn get_reference(context: &Context) -> &'a T { + context.get_field(PhantomData) + } + } + impl< + 'a, + Context, + Tag, + T: 'a + ?Sized, + > IsProviderFor, T)> for UseField + where + Context: HasField, + {} + ") } } diff --git a/crates/tests/cgp-tests/tests/extensible_data_tests/variants/basic.rs b/crates/tests/cgp-tests/tests/extensible_data_tests/variants/basic.rs index 1781bb62..e15fe018 100644 --- a/crates/tests/cgp-tests/tests/extensible_data_tests/variants/basic.rs +++ b/crates/tests/cgp-tests/tests/extensible_data_tests/variants/basic.rs @@ -12,7 +12,7 @@ use cgp::extra::handler::{ Computer, ComputerComponent, ComputerRef, ComputerRefComponent, PromoteAsync, }; use cgp::prelude::*; -use cgp_macro_test_util::snapshot_delegate_components; +use cgp_macro_test_util::{snapshot_cgp_new_provider, snapshot_delegate_components}; use futures::executor::block_on; #[derive(Debug, Eq, PartialEq, CgpData)] @@ -232,15 +232,41 @@ fn test_dispatch_values_ref() { ); } -#[cgp_new_provider] -impl Computer for ValueToString -where - Value: Display, -{ - type Output = String; +snapshot_cgp_new_provider! { + #[cgp_new_provider] + impl Computer for ValueToString + where + Value: Display, + { + type Output = String; + + fn compute(_context: &Context, _code: PhantomData, input: &Value) -> Self::Output { + input.to_string() + } + } - fn compute(_context: &Context, _code: PhantomData, input: &Value) -> Self::Output { - input.to_string() + expand_value_to_string(output) { + insta::assert_snapshot!(output, @" + impl Computer for ValueToString + where + Value: Display, + { + type Output = String; + fn compute( + _context: &Context, + _code: PhantomData, + input: &Value, + ) -> Self::Output { + input.to_string() + } + } + impl IsProviderFor + for ValueToString + where + Value: Display, + {} + pub struct ValueToString; + ") } } diff --git a/crates/tests/cgp-tests/tests/handler_tests/pipe.rs b/crates/tests/cgp-tests/tests/handler_tests/pipe.rs index 68e8fdfb..23765c1a 100644 --- a/crates/tests/cgp-tests/tests/handler_tests/pipe.rs +++ b/crates/tests/cgp-tests/tests/handler_tests/pipe.rs @@ -3,29 +3,75 @@ mod pipe_computers { use cgp::extra::handler::{CanCompute, Computer, ComputerComponent, PipeHandlers}; use cgp::prelude::*; - use cgp_macro_test_util::{snapshot_check_components, snapshot_delegate_components}; + use cgp_macro_test_util::{ + snapshot_cgp_new_provider, snapshot_check_components, snapshot_delegate_components, + }; - #[cgp_new_provider] - impl Computer for Multiply - where - Context: HasField, - { - type Output = u64; + snapshot_cgp_new_provider! { + #[cgp_new_provider] + impl Computer for Multiply + where + Context: HasField, + { + type Output = u64; - fn compute(context: &Context, _tag: PhantomData, input: u64) -> u64 { - input * context.get_field(PhantomData) + fn compute(context: &Context, _tag: PhantomData, input: u64) -> u64 { + input * context.get_field(PhantomData) + } + } + + expand_multiply(output) { + insta::assert_snapshot!(output, @" + impl Computer for Multiply + where + Context: HasField, + { + type Output = u64; + fn compute(context: &Context, _tag: PhantomData, input: u64) -> u64 { + input * context.get_field(PhantomData) + } + } + impl IsProviderFor + for Multiply + where + Context: HasField, + {} + pub struct Multiply(pub ::core::marker::PhantomData<(Field)>); + ") } } - #[cgp_new_provider] - impl Computer for Add - where - Context: HasField, - { - type Output = u64; + snapshot_cgp_new_provider! { + #[cgp_new_provider] + impl Computer for Add + where + Context: HasField, + { + type Output = u64; - fn compute(context: &Context, _tag: PhantomData, input: u64) -> u64 { - input + context.get_field(PhantomData) + fn compute(context: &Context, _tag: PhantomData, input: u64) -> u64 { + input + context.get_field(PhantomData) + } + } + + expand_add(output) { + insta::assert_snapshot!(output, @" + impl Computer for Add + where + Context: HasField, + { + type Output = u64; + fn compute(context: &Context, _tag: PhantomData, input: u64) -> u64 { + input + context.get_field(PhantomData) + } + } + impl IsProviderFor + for Add + where + Context: HasField, + {} + pub struct Add(pub ::core::marker::PhantomData<(Field)>); + ") } } @@ -116,34 +162,84 @@ mod pipe_handlers { CanHandle, Computer, Handler, HandlerComponent, PipeHandlers, Promote, PromoteAsync, }; use cgp::prelude::*; - use cgp_macro_test_util::{snapshot_check_components, snapshot_delegate_components}; + use cgp_macro_test_util::{ + snapshot_cgp_new_provider, snapshot_check_components, snapshot_delegate_components, + }; use futures::executor::block_on; - #[cgp_new_provider] - impl Handler for Multiply - where - Context: HasErrorType + HasField, - { - type Output = u64; + snapshot_cgp_new_provider! { + #[cgp_new_provider] + impl Handler for Multiply + where + Context: HasErrorType + HasField, + { + type Output = u64; - async fn handle( - context: &Context, - _tag: PhantomData, - input: u64, - ) -> Result { - Ok(input * context.get_field(PhantomData)) + async fn handle( + context: &Context, + _tag: PhantomData, + input: u64, + ) -> Result { + Ok(input * context.get_field(PhantomData)) + } + } + + expand_multiply(output) { + insta::assert_snapshot!(output, @" + impl Handler for Multiply + where + Context: HasErrorType + HasField, + { + type Output = u64; + async fn handle( + context: &Context, + _tag: PhantomData, + input: u64, + ) -> Result { + Ok(input * context.get_field(PhantomData)) + } + } + impl IsProviderFor + for Multiply + where + Context: HasErrorType + HasField, + {} + pub struct Multiply(pub ::core::marker::PhantomData<(Field)>); + ") } } - #[cgp_new_provider] - impl Computer for Add - where - Context: HasField, - { - type Output = u64; + snapshot_cgp_new_provider! { + #[cgp_new_provider] + impl Computer for Add + where + Context: HasField, + { + type Output = u64; - fn compute(context: &Context, _tag: PhantomData, input: u64) -> u64 { - input + context.get_field(PhantomData) + fn compute(context: &Context, _tag: PhantomData, input: u64) -> u64 { + input + context.get_field(PhantomData) + } + } + + expand_add(output) { + insta::assert_snapshot!(output, @" + impl Computer for Add + where + Context: HasField, + { + type Output = u64; + fn compute(context: &Context, _tag: PhantomData, input: u64) -> u64 { + input + context.get_field(PhantomData) + } + } + impl IsProviderFor + for Add + where + Context: HasField, + {} + pub struct Add(pub ::core::marker::PhantomData<(Field)>); + ") } } From 61e6d012fcc23e04dc6b4cde2acee39c143ebc15 Mon Sep 17 00:00:00 2001 From: Soares Chen Date: Fri, 19 Jun 2026 23:09:00 +0200 Subject: [PATCH 31/31] Fix formatting --- .../cgp-tests/tests/component_tests/cgp_component/constant.rs | 4 +++- .../cgp-tests/tests/component_tests/cgp_component/lifetime.rs | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/crates/tests/cgp-tests/tests/component_tests/cgp_component/constant.rs b/crates/tests/cgp-tests/tests/component_tests/cgp_component/constant.rs index 7c1e18bf..85d6117a 100644 --- a/crates/tests/cgp-tests/tests/component_tests/cgp_component/constant.rs +++ b/crates/tests/cgp-tests/tests/component_tests/cgp_component/constant.rs @@ -65,7 +65,9 @@ pub fn test_component_with_const() { mod generic_const { use cgp::prelude::*; - use cgp_macro_test_util::{snapshot_cgp_provider, snapshot_cgp_type, snapshot_check_components}; + use cgp_macro_test_util::{ + snapshot_cgp_provider, snapshot_cgp_type, snapshot_check_components, + }; snapshot_cgp_type! { #[cgp_type] diff --git a/crates/tests/cgp-tests/tests/component_tests/cgp_component/lifetime.rs b/crates/tests/cgp-tests/tests/component_tests/cgp_component/lifetime.rs index b43145c4..6806116e 100644 --- a/crates/tests/cgp-tests/tests/component_tests/cgp_component/lifetime.rs +++ b/crates/tests/cgp-tests/tests/component_tests/cgp_component/lifetime.rs @@ -1,5 +1,7 @@ use cgp::prelude::*; -use cgp_macro_test_util::{snapshot_cgp_component, snapshot_cgp_provider, snapshot_check_components}; +use cgp_macro_test_util::{ + snapshot_cgp_component, snapshot_cgp_provider, snapshot_check_components, +}; snapshot_cgp_component! { #[cgp_component(ReferenceGetter)]