diff --git a/Cargo.lock b/Cargo.lock index e98a3270c5..ebae154c53 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -514,6 +514,17 @@ dependencies = [ "alloc-stdlib", ] +[[package]] +name = "bstr" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "234113d19d0d7d613b40e86fb654acf958910802bcceab913a4f9e7cda03b1a4" +dependencies = [ + "memchr", + "regex-automata", + "serde", +] + [[package]] name = "built" version = "0.7.7" @@ -863,6 +874,18 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "console" +version = "0.15.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "054ccb5b10f9f2cbf51eb355ca1d05c2d279ce1804688d0db74b4733a5aeafd8" +dependencies = [ + "encode_unicode", + "libc", + "once_cell", + "windows-sys 0.59.0", +] + [[package]] name = "convert_case" version = "0.4.0" @@ -1394,6 +1417,12 @@ version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ef6b89e5b37196644d8796de5268852ff179b44e96276cf4290264843743bb7" +[[package]] +name = "encode_unicode" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" + [[package]] name = "encoding_rs" version = "0.8.35" @@ -3238,7 +3267,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34" dependencies = [ "cfg-if", - "windows-targets 0.48.5", + "windows-targets 0.52.6", ] [[package]] @@ -3594,10 +3623,12 @@ dependencies = [ "convert_case 0.7.1", "graphene-core", "indoc", + "prettyplease", "proc-macro-crate 3.3.0", "proc-macro-error2", "proc-macro2", "quote", + "similar-asserts", "syn 2.0.99", ] @@ -4491,6 +4522,16 @@ dependencies = [ "yansi", ] +[[package]] +name = "prettyplease" +version = "0.2.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6837b9e10d61f45f987d50808f83d1ee3d206c66acf650c3e4ae2e1f6ddedf55" +dependencies = [ + "proc-macro2", + "syn 2.0.99", +] + [[package]] name = "proc-macro-crate" version = "1.3.1" @@ -5571,6 +5612,26 @@ dependencies = [ "quote", ] +[[package]] +name = "similar" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbbb5d9659141646ae647b42fe094daf6c6192d1620870b449d9557f748b2daa" +dependencies = [ + "bstr", + "unicode-segmentation", +] + +[[package]] +name = "similar-asserts" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b441962c817e33508847a22bd82f03a30cff43642dc2fae8b050566121eb9a" +dependencies = [ + "console", + "similar", +] + [[package]] name = "simplecss" version = "0.2.2" diff --git a/node-graph/node-macro/Cargo.toml b/node-graph/node-macro/Cargo.toml index b63ce4927d..90bc86495f 100644 --- a/node-graph/node-macro/Cargo.toml +++ b/node-graph/node-macro/Cargo.toml @@ -26,4 +26,5 @@ proc-macro-error2 = "2" [dev-dependencies] graphene-core = { workspace = true } - +similar-asserts = "1.7.0" +prettyplease = "0.2" diff --git a/node-graph/node-macro/src/lib.rs b/node-graph/node-macro/src/lib.rs index 1a87ce2cf9..ee2c6aab8c 100644 --- a/node-graph/node-macro/src/lib.rs +++ b/node-graph/node-macro/src/lib.rs @@ -28,3 +28,124 @@ pub fn node(attr: TokenStream, item: TokenStream) -> TokenStream { pub fn derive_choice_type(input_item: TokenStream) -> TokenStream { TokenStream::from(derive_choice_type::derive_choice_type_impl(input_item.into()).unwrap_or_else(|err| err.to_compile_error())) } + +#[cfg(test)] +mod tests { + use super::*; + use proc_macro2::TokenStream; + use quote::quote; + use similar_asserts::assert_eq; + + fn token_stream_to_string(token_stream: TokenStream) -> String { + prettyplease::unparse(&syn::parse2(token_stream).unwrap()) + } + + #[test] + fn test_node_end_to_end() { + let attr = quote!(category("Math: Arithmetic"), path(graphene_core::TestNode), skip_impl); + let input = quote!( + /// Multi + /// Line + fn add(a: f64, b: f64) -> f64 { + a + b + } + ); + let parsed = parsing::new_node_fn(attr, input).into(); + + let expected = quote! { + /// Underlying implementation for [#struct_name] + #[inline] + #[allow(clippy::too_many_arguments)] + pub(crate) fn add<'n>(a: f64, b: f64) -> f64 { + a + b + } + #[automatically_derived] + impl<'n, Node0, F0> graphene_core::Node<'n, f64> for _add_mod::AddNode + where + F0: core::future::Future + graphene_core::WasmNotSend + 'n, + for<'all> f64: graphene_core::WasmNotSend, + Node0: graphene_core::Node<'n, f64, Output = F0> + graphene_core::WasmNotSync, + f64: 'n, + { + type Output = graphene_core::registry::DynFuture<'n, f64>; + #[inline] + fn eval(&'n self, __input: f64) -> Self::Output { + Box::pin(async move { + use graphene_core::misc::Clampable; + let b = self.b.eval(__input.clone()).await; + self::add(__input, b) + }) + } + } + #[doc(inline)] + pub use _add_mod::AddNode; + #[doc(hidden)] + #[doc(hidden)] + mod _add_mod { + use super::*; + use graphene_core as gcore; + use gcore::{ + Node, NodeIOTypes, concrete, fn_type, fn_type_fut, future, ProtoNodeIdentifier, + WasmNotSync, NodeIO, + }; + use gcore::value::ClonedNode; + use gcore::ops::TypeNode; + use gcore::registry::{ + NodeMetadata, FieldMetadata, NODE_REGISTRY, NODE_METADATA, DynAnyNode, + DowncastBothNode, DynFuture, TypeErasedBox, PanicNode, RegistryValueSource, + RegistryWidgetOverride, + }; + use gcore::ctor::ctor; + static _IMPORT_STUB_ADD_MOD: core::marker::PhantomData<()> = core::marker::PhantomData; + #[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] + pub struct AddNode { + pub(super) b: Node0, + } + #[automatically_derived] + impl<'n, Node0> AddNode { + #[allow(clippy::too_many_arguments)] + pub fn new(b: Node0) -> Self { + Self { b } + } + } + #[cfg_attr(not(target_arch = "wasm32"), ctor)] + fn register_metadata() { + let metadata = NodeMetadata { + display_name: "Add", + category: Some("Math: Arithmetic"), + description: "Multi\nLine\n", + properties: None, + fields: vec![ + FieldMetadata { + name: "B", + widget_override:RegistryWidgetOverride::None, + description: "", + exposed: false, + value_source: RegistryValueSource::None, + default_type: None, + number_min: None, + number_max: None, + number_mode_range: None, + number_display_decimal_places: None, + number_step: None, + unit: None, + }, + ], + }; + NODE_METADATA + .lock() + .unwrap() + .insert( + format!( + "{}::{}", stringify!(graphene_core::TestNode) .replace(' ', ""), + stringify!(AddNode) + ), + metadata, + ); + } + } + }; + + assert_eq!(token_stream_to_string(expected), token_stream_to_string(parsed)); + } +}