aboutsummaryrefslogtreecommitdiff
path: root/macros/src
diff options
context:
space:
mode:
authorHampusM <hampus@hampusmat.com>2022-10-09 20:41:09 +0200
committerHampusM <hampus@hampusmat.com>2022-10-09 20:42:07 +0200
commitfd5b6786d29d056ff0721a59435b50005f13f05c (patch)
tree3839ff2ffa99a14d1aefb952a55f1cb05aa0f09e /macros/src
parent5b0c6a52022e67a2d9cee251b3d08b9cb2b5f6cb (diff)
test: add more unit tests
Diffstat (limited to 'macros/src')
-rw-r--r--macros/src/fn_trait.rs91
-rw-r--r--macros/src/macro_flag.rs45
-rw-r--r--macros/src/util/iterator_ext.rs57
-rw-r--r--macros/src/util/string.rs14
4 files changed, 204 insertions, 3 deletions
diff --git a/macros/src/fn_trait.rs b/macros/src/fn_trait.rs
index 9820f02..a52a00d 100644
--- a/macros/src/fn_trait.rs
+++ b/macros/src/fn_trait.rs
@@ -5,7 +5,7 @@ use syn::token::Paren;
use syn::{parenthesized, parse_str, Ident, Token, TraitBound, Type};
/// A function trait. `dyn Fn(u32) -> String`
-#[derive(Debug, Clone)]
+#[derive(Debug, Clone, PartialEq, Eq)]
pub struct FnTrait
{
pub dyn_token: Token![dyn],
@@ -84,3 +84,92 @@ impl ToTokens for FnTrait
}
}
}
+
+#[cfg(test)]
+mod tests
+{
+ use std::error::Error;
+
+ use quote::{format_ident, quote};
+ use syn::token::{Dyn, RArrow};
+ use syn::{parse2, Path, PathSegment, TypePath};
+
+ use super::*;
+
+ fn create_path(segments: &[PathSegment]) -> Path
+ {
+ Path {
+ leading_colon: None,
+ segments: segments.iter().cloned().collect(),
+ }
+ }
+
+ fn create_type(path: Path) -> Type
+ {
+ Type::Path(TypePath { qself: None, path })
+ }
+
+ #[test]
+ fn can_parse_fn_trait() -> Result<(), Box<dyn Error>>
+ {
+ assert_eq!(
+ parse2::<FnTrait>(quote! {
+ dyn Fn(String, u32) -> Handle
+ })?,
+ FnTrait {
+ dyn_token: Dyn::default(),
+ trait_ident: format_ident!("Fn"),
+ paren_token: Paren::default(),
+ inputs: Punctuated::from_iter(vec![
+ create_type(create_path(&[PathSegment::from(format_ident!(
+ "String"
+ ))])),
+ create_type(create_path(&[PathSegment::from(format_ident!("u32"))]))
+ ]),
+ r_arrow_token: RArrow::default(),
+ output: create_type(create_path(&[PathSegment::from(format_ident!(
+ "Handle"
+ ))])),
+ trait_bounds: Punctuated::new()
+ }
+ );
+
+ assert!(parse2::<FnTrait>(quote! {
+ Fn(u32) -> Handle
+ })
+ .is_err());
+
+ Ok(())
+ }
+
+ #[test]
+ fn can_parse_fn_trait_to_tokens()
+ {
+ assert_eq!(
+ FnTrait {
+ dyn_token: Dyn::default(),
+ trait_ident: format_ident!("Fn"),
+ paren_token: Paren::default(),
+ inputs: Punctuated::from_iter(vec![
+ create_type(create_path(&[PathSegment::from(format_ident!(
+ "Bread"
+ ))])),
+ create_type(create_path(&[PathSegment::from(format_ident!(
+ "Cheese"
+ ))])),
+ create_type(create_path(&[PathSegment::from(format_ident!(
+ "Tomatoes"
+ ))]))
+ ]),
+ r_arrow_token: RArrow::default(),
+ output: create_type(create_path(&[PathSegment::from(format_ident!(
+ "Taco"
+ ))])),
+ trait_bounds: Punctuated::new()
+ }
+ .into_token_stream()
+ .to_string(),
+ "dyn Fn (Bread , Cheese , Tomatoes) -> Taco".to_string()
+ );
+ }
+}
diff --git a/macros/src/macro_flag.rs b/macros/src/macro_flag.rs
index 257a059..97a8ff2 100644
--- a/macros/src/macro_flag.rs
+++ b/macros/src/macro_flag.rs
@@ -1,7 +1,7 @@
use syn::parse::{Parse, ParseStream};
use syn::{Ident, LitBool, Token};
-#[derive(Debug)]
+#[derive(Debug, PartialEq, Eq)]
pub struct MacroFlag
{
pub flag: Ident,
@@ -25,3 +25,46 @@ impl Parse for MacroFlag
Ok(Self { flag, is_on })
}
}
+
+#[cfg(test)]
+mod tests
+{
+ use std::error::Error;
+
+ use proc_macro2::Span;
+ use quote::{format_ident, quote};
+ use syn::parse2;
+
+ use super::*;
+
+ #[test]
+ fn can_parse_macro_flag() -> Result<(), Box<dyn Error>>
+ {
+ assert_eq!(
+ parse2::<MacroFlag>(quote! {
+ more = true
+ })?,
+ MacroFlag {
+ flag: format_ident!("more"),
+ is_on: LitBool::new(true, Span::call_site())
+ }
+ );
+
+ assert_eq!(
+ parse2::<MacroFlag>(quote! {
+ do_something = false
+ })?,
+ MacroFlag {
+ flag: format_ident!("do_something"),
+ is_on: LitBool::new(false, Span::call_site())
+ }
+ );
+
+ assert!(parse2::<MacroFlag>(quote! {
+ 10 = false
+ })
+ .is_err());
+
+ Ok(())
+ }
+}
diff --git a/macros/src/util/iterator_ext.rs b/macros/src/util/iterator_ext.rs
index 86db6cb..5001068 100644
--- a/macros/src/util/iterator_ext.rs
+++ b/macros/src/util/iterator_ext.rs
@@ -9,7 +9,7 @@ pub trait IteratorExt<Item>
impl<Iter> IteratorExt<Iter::Item> for Iter
where
Iter: Iterator,
- Iter::Item: Eq + Hash + Copy,
+ Iter::Item: Eq + Hash + Clone,
{
fn find_duplicate(&mut self) -> Option<Iter::Item>
{
@@ -26,3 +26,58 @@ where
None
}
}
+
+#[cfg(test)]
+mod tests
+{
+ use super::*;
+
+ #[test]
+ fn can_find_duplicate()
+ {
+ #[derive(Debug, PartialEq, Eq, Clone, Hash)]
+ struct Fruit
+ {
+ name: String,
+ }
+
+ assert_eq!(
+ vec![
+ Fruit {
+ name: "Apple".to_string(),
+ },
+ Fruit {
+ name: "Banana".to_string(),
+ },
+ Fruit {
+ name: "Apple".to_string(),
+ },
+ Fruit {
+ name: "Orange".to_string(),
+ },
+ ]
+ .iter()
+ .find_duplicate(),
+ Some(&Fruit {
+ name: "Apple".to_string()
+ })
+ );
+
+ assert_eq!(
+ vec![
+ Fruit {
+ name: "Banana".to_string(),
+ },
+ Fruit {
+ name: "Apple".to_string(),
+ },
+ Fruit {
+ name: "Orange".to_string(),
+ },
+ ]
+ .iter()
+ .find_duplicate(),
+ None
+ );
+ }
+}
diff --git a/macros/src/util/string.rs b/macros/src/util/string.rs
index 90cccee..a04a021 100644
--- a/macros/src/util/string.rs
+++ b/macros/src/util/string.rs
@@ -10,3 +10,17 @@ pub fn camelcase_to_snakecase(camelcased: &str) -> String
.to_string()
.to_lowercase()
}
+
+#[cfg(test)]
+mod tests
+{
+ use super::*;
+
+ #[test]
+ fn camelcase_to_snakecase_works()
+ {
+ assert_eq!(camelcase_to_snakecase("LoginHandler"), "login_handler");
+
+ assert_eq!(camelcase_to_snakecase("Regex"), "regex");
+ }
+}