diff options
author | HampusM <hampus@hampusmat.com> | 2022-11-11 16:45:06 +0100 |
---|---|---|
committer | HampusM <hampus@hampusmat.com> | 2022-11-11 16:45:06 +0100 |
commit | 974451ffd6ae89ba94956c2c116dcfea0ab9da6b (patch) | |
tree | b2b7bfcfe7056d93733636e5b4106c347c544092 /macros/src/declare_interface_args.rs | |
parent | 8036395385c32e8b2e143ad671ca55ab104a5df0 (diff) |
test: add unit tests for parsing declare_interface macro args
Diffstat (limited to 'macros/src/declare_interface_args.rs')
-rw-r--r-- | macros/src/declare_interface_args.rs | 130 |
1 files changed, 124 insertions, 6 deletions
diff --git a/macros/src/declare_interface_args.rs b/macros/src/declare_interface_args.rs index 529a114..bc15d2e 100644 --- a/macros/src/declare_interface_args.rs +++ b/macros/src/declare_interface_args.rs @@ -1,4 +1,4 @@ -use syn::parse::{Parse, ParseStream, Result}; +use syn::parse::{Parse, ParseStream}; use syn::punctuated::Punctuated; use syn::{Token, TypePath}; @@ -16,7 +16,7 @@ pub struct DeclareInterfaceArgs impl Parse for DeclareInterfaceArgs { - fn parse(input: ParseStream) -> Result<Self> + fn parse(input: ParseStream) -> syn::Result<Self> { let implementation: TypePath = input.parse()?; @@ -30,12 +30,11 @@ impl Parse for DeclareInterfaceArgs let flags = Punctuated::<MacroFlag, Token![,]>::parse_terminated(input)?; for flag in &flags { - let flag_str = flag.flag.to_string(); + let flag_name = flag.flag.to_string(); - if !DECLARE_INTERFACE_FLAGS.contains(&flag_str.as_str()) { + if !DECLARE_INTERFACE_FLAGS.contains(&flag_name.as_str()) { return Err(input.error(format!( - "Unknown flag '{}'. Expected one of [ {} ]", - flag_str, + "Unknown flag '{flag_name}'. Expected one of [ {} ]", DECLARE_INTERFACE_FLAGS.join(",") ))); } @@ -62,3 +61,122 @@ impl Parse for DeclareInterfaceArgs }) } } + +#[cfg(test)] +mod tests +{ + use std::error::Error; + + use proc_macro2::Span; + use quote::{format_ident, quote}; + use syn::{parse2, LitBool}; + + use super::*; + use crate::test_utils; + + #[test] + fn can_parse_with_no_flags() -> Result<(), Box<dyn Error>> + { + let input_args = quote! { + Foo -> IFoo + }; + + let decl_interface_args = parse2::<DeclareInterfaceArgs>(input_args)?; + + assert_eq!( + decl_interface_args.implementation, + TypePath { + qself: None, + path: test_utils::create_path(&[test_utils::create_path_segment( + format_ident!("Foo"), + &[] + )]) + } + ); + + assert_eq!( + decl_interface_args.interface, + TypePath { + qself: None, + path: test_utils::create_path(&[test_utils::create_path_segment( + format_ident!("IFoo"), + &[] + )]) + } + ); + + assert!(decl_interface_args.flags.is_empty()); + + Ok(()) + } + + #[test] + fn can_parse_with_flags() -> Result<(), Box<dyn Error>> + { + let input_args = quote! { + Foobar -> IFoobar, async = true + }; + + let decl_interface_args = parse2::<DeclareInterfaceArgs>(input_args)?; + + assert_eq!( + decl_interface_args.implementation, + TypePath { + qself: None, + path: test_utils::create_path(&[test_utils::create_path_segment( + format_ident!("Foobar"), + &[] + )]) + } + ); + + assert_eq!( + decl_interface_args.interface, + TypePath { + qself: None, + path: test_utils::create_path(&[test_utils::create_path_segment( + format_ident!("IFoobar"), + &[] + )]) + } + ); + + assert_eq!( + decl_interface_args.flags, + Punctuated::from_iter(vec![MacroFlag { + flag: format_ident!("async"), + is_on: LitBool::new(true, Span::call_site()) + }]) + ); + + Ok(()) + } + + #[test] + fn cannot_parse_with_invalid_flag() + { + let input_args = quote! { + Foobar -> IFoobar, xyz = false, async = true + }; + + assert!(matches!(parse2::<DeclareInterfaceArgs>(input_args), Err(_))); + } + + #[test] + fn cannot_parse_with_duplicate_flag() + { + assert!(matches!( + parse2::<DeclareInterfaceArgs>(quote! { + Foobar -> IFoobar, async = true, async = true + }), + Err(_) + )); + + assert!(matches!( + parse2::<DeclareInterfaceArgs>(quote! { + Foobar -> IFoobar, async = true, async = false + }), + Err(_) + )); + } +} |