From 335d853060330a49338aecf05d12eb5972c356e7 Mon Sep 17 00:00:00 2001 From: J Henry Waugh Date: Sat, 12 Sep 2020 17:20:51 -0500 Subject: [PATCH] Unit tests for rename + getter/setter/indexer --- codegen/src/test/module.rs | 260 +++++++++++++++++++++++++++++++++++++ 1 file changed, 260 insertions(+) diff --git a/codegen/src/test/module.rs b/codegen/src/test/module.rs index 35e3a6cb..e830600e 100644 --- a/codegen/src/test/module.rs +++ b/codegen/src/test/module.rs @@ -1131,6 +1131,67 @@ mod generate_tests { assert_streams_eq(item_mod.generate(), expected_tokens); } + #[test] + fn one_getter_and_rename_fn_module() { + let input_tokens: TokenStream = quote! { + pub mod one_fn { + #[rhai_fn(name = "square", get = "square")] + pub fn int_foo(x: &mut u64) -> u64 { + (*x) * (*x) + } + } + }; + + let expected_tokens = quote! { + pub mod one_fn { + pub fn int_foo(x: &mut u64) -> u64 { + (*x) * (*x) + } + #[allow(unused_imports)] + use super::*; + #[allow(unused_mut)] + pub fn rhai_module_generate() -> Module { + let mut m = Module::new(); + m.set_fn("square", FnAccess::Public, &[core::any::TypeId::of::()], + CallableFunction::from_plugin(int_foo_token())); + m.set_fn("get$square", FnAccess::Public, &[core::any::TypeId::of::()], + CallableFunction::from_plugin(int_foo_token())); + m + } + #[allow(non_camel_case_types)] + struct int_foo_token(); + impl PluginFunction for int_foo_token { + fn call(&self, + args: &mut [&mut Dynamic], pos: Position + ) -> Result> { + debug_assert_eq!(args.len(), 1usize, + "wrong arg count: {} != {}", args.len(), 1usize); + let arg0: &mut _ = &mut args[0usize].write_lock::().unwrap(); + Ok(Dynamic::from(int_foo(arg0))) + } + + fn is_method_call(&self) -> bool { true } + fn is_varadic(&self) -> bool { false } + fn clone_boxed(&self) -> Box { + Box::new(int_foo_token()) + } + fn input_types(&self) -> Box<[TypeId]> { + new_vec![TypeId::of::()].into_boxed_slice() + } + } + pub fn int_foo_token_callable() -> CallableFunction { + CallableFunction::from_plugin(int_foo_token()) + } + pub fn int_foo_token_input_types() -> Box<[TypeId]> { + int_foo_token().input_types() + } + } + }; + + let item_mod = syn::parse2::(input_tokens).unwrap(); + assert_streams_eq(item_mod.generate(), expected_tokens); + } + #[test] fn one_setter_fn_module() { let input_tokens: TokenStream = quote! { @@ -1190,6 +1251,67 @@ mod generate_tests { assert_streams_eq(item_mod.generate(), expected_tokens); } + #[test] + fn one_setter_and_rename_fn_module() { + let input_tokens: TokenStream = quote! { + pub mod one_fn { + #[rhai_fn(name = "set_sq", set = "squared")] + pub fn int_foo(x: &mut u64) { + *x = (*x) * (*x) + } + } + }; + + let expected_tokens = quote! { + pub mod one_fn { + pub fn int_foo(x: &mut u64) { + *x = (*x) * (*x) + } + #[allow(unused_imports)] + use super::*; + #[allow(unused_mut)] + pub fn rhai_module_generate() -> Module { + let mut m = Module::new(); + m.set_fn("set_sq", FnAccess::Public, &[core::any::TypeId::of::()], + CallableFunction::from_plugin(int_foo_token())); + m.set_fn("set$squared", FnAccess::Public, &[core::any::TypeId::of::()], + CallableFunction::from_plugin(int_foo_token())); + m + } + #[allow(non_camel_case_types)] + struct int_foo_token(); + impl PluginFunction for int_foo_token { + fn call(&self, + args: &mut [&mut Dynamic], pos: Position + ) -> Result> { + debug_assert_eq!(args.len(), 1usize, + "wrong arg count: {} != {}", args.len(), 1usize); + let arg0: &mut _ = &mut args[0usize].write_lock::().unwrap(); + Ok(Dynamic::from(int_foo(arg0))) + } + + fn is_method_call(&self) -> bool { true } + fn is_varadic(&self) -> bool { false } + fn clone_boxed(&self) -> Box { + Box::new(int_foo_token()) + } + fn input_types(&self) -> Box<[TypeId]> { + new_vec![TypeId::of::()].into_boxed_slice() + } + } + pub fn int_foo_token_callable() -> CallableFunction { + CallableFunction::from_plugin(int_foo_token()) + } + pub fn int_foo_token_input_types() -> Box<[TypeId]> { + int_foo_token().input_types() + } + } + }; + + let item_mod = syn::parse2::(input_tokens).unwrap(); + assert_streams_eq(item_mod.generate(), expected_tokens); + } + #[test] fn one_index_getter_fn_module() { let input_tokens: TokenStream = quote! { @@ -1253,6 +1375,73 @@ mod generate_tests { assert_streams_eq(item_mod.generate(), expected_tokens); } + #[test] + fn one_index_getter_and_rename_fn_module() { + let input_tokens: TokenStream = quote! { + pub mod one_index_fn { + #[rhai_fn(name = "get", index_get)] + pub fn get_by_index(x: &mut MyCollection, i: u64) -> FLOAT { + x.get(i) + } + } + }; + + let expected_tokens = quote! { + pub mod one_index_fn { + pub fn get_by_index(x: &mut MyCollection, i: u64) -> FLOAT { + x.get(i) + } + #[allow(unused_imports)] + use super::*; + #[allow(unused_mut)] + pub fn rhai_module_generate() -> Module { + let mut m = Module::new(); + m.set_fn("get", FnAccess::Public, + &[core::any::TypeId::of::(), + core::any::TypeId::of::()], + CallableFunction::from_plugin(get_by_index_token())); + m.set_fn("index$get$", FnAccess::Public, + &[core::any::TypeId::of::(), + core::any::TypeId::of::()], + CallableFunction::from_plugin(get_by_index_token())); + m + } + #[allow(non_camel_case_types)] + struct get_by_index_token(); + impl PluginFunction for get_by_index_token { + fn call(&self, + args: &mut [&mut Dynamic], pos: Position + ) -> Result> { + debug_assert_eq!(args.len(), 2usize, + "wrong arg count: {} != {}", args.len(), 2usize); + let arg1 = mem::take(args[1usize]).clone().cast::(); + let arg0: &mut _ = &mut args[0usize].write_lock::().unwrap(); + Ok(Dynamic::from(get_by_index(arg0, arg1))) + } + + fn is_method_call(&self) -> bool { true } + fn is_varadic(&self) -> bool { false } + fn clone_boxed(&self) -> Box { + Box::new(get_by_index_token()) + } + fn input_types(&self) -> Box<[TypeId]> { + new_vec![TypeId::of::(), + TypeId::of::()].into_boxed_slice() + } + } + pub fn get_by_index_token_callable() -> CallableFunction { + CallableFunction::from_plugin(get_by_index_token()) + } + pub fn get_by_index_token_input_types() -> Box<[TypeId]> { + get_by_index_token().input_types() + } + } + }; + + let item_mod = syn::parse2::(input_tokens).unwrap(); + assert_streams_eq(item_mod.generate(), expected_tokens); + } + #[test] fn one_index_setter_fn_module() { let input_tokens: TokenStream = quote! { @@ -1319,6 +1508,77 @@ mod generate_tests { assert_streams_eq(item_mod.generate(), expected_tokens); } + #[test] + fn one_index_setter_and_rename_fn_module() { + let input_tokens: TokenStream = quote! { + pub mod one_index_fn { + #[rhai_fn(name = "set", index_set)] + pub fn set_by_index(x: &mut MyCollection, i: u64, item: FLOAT) { + x.entry(i).set(item) + } + } + }; + + let expected_tokens = quote! { + pub mod one_index_fn { + pub fn set_by_index(x: &mut MyCollection, i: u64, item: FLOAT) { + x.entry(i).set(item) + } + #[allow(unused_imports)] + use super::*; + #[allow(unused_mut)] + pub fn rhai_module_generate() -> Module { + let mut m = Module::new(); + m.set_fn("set", FnAccess::Public, + &[core::any::TypeId::of::(), + core::any::TypeId::of::(), + core::any::TypeId::of::()], + CallableFunction::from_plugin(set_by_index_token())); + m.set_fn("index$set$", FnAccess::Public, + &[core::any::TypeId::of::(), + core::any::TypeId::of::(), + core::any::TypeId::of::()], + CallableFunction::from_plugin(set_by_index_token())); + m + } + #[allow(non_camel_case_types)] + struct set_by_index_token(); + impl PluginFunction for set_by_index_token { + fn call(&self, + args: &mut [&mut Dynamic], pos: Position + ) -> Result> { + debug_assert_eq!(args.len(), 3usize, + "wrong arg count: {} != {}", args.len(), 3usize); + let arg1 = mem::take(args[1usize]).clone().cast::(); + let arg2 = mem::take(args[2usize]).clone().cast::(); + let arg0: &mut _ = &mut args[0usize].write_lock::().unwrap(); + Ok(Dynamic::from(set_by_index(arg0, arg1, arg2))) + } + + fn is_method_call(&self) -> bool { true } + fn is_varadic(&self) -> bool { false } + fn clone_boxed(&self) -> Box { + Box::new(set_by_index_token()) + } + fn input_types(&self) -> Box<[TypeId]> { + new_vec![TypeId::of::(), + TypeId::of::(), + TypeId::of::()].into_boxed_slice() + } + } + pub fn set_by_index_token_callable() -> CallableFunction { + CallableFunction::from_plugin(set_by_index_token()) + } + pub fn set_by_index_token_input_types() -> Box<[TypeId]> { + set_by_index_token().input_types() + } + } + }; + + let item_mod = syn::parse2::(input_tokens).unwrap(); + assert_streams_eq(item_mod.generate(), expected_tokens); + } + #[test] fn one_constant_nested_module() { let input_tokens: TokenStream = quote! {