diff --git a/core/src/util/ident_list.rs b/core/src/util/ident_list.rs index d81697c..4da04a9 100644 --- a/core/src/util/ident_list.rs +++ b/core/src/util/ident_list.rs @@ -52,10 +52,50 @@ impl FromMeta for IdentList { if let NestedMeta::Meta(Meta::Word(ref ident)) = *nmi { idents.push(ident.clone()); } else { - return Err(Error::unexpected_type("non-word")); + return Err(Error::unexpected_type("non-word").with_span(nmi)); } } Ok(IdentList(idents)) } } + +#[cfg(test)] +mod tests { + use super::IdentList; + use proc_macro2::TokenStream; + use FromMeta; + + /// parse a string as a syn::Meta instance. + fn pm(tokens: TokenStream) -> ::std::result::Result { + let attribute: syn::Attribute = parse_quote!(#[#tokens]); + attribute.interpret_meta().ok_or("Unable to parse".into()) + } + + fn fm(tokens: TokenStream) -> T { + FromMeta::from_meta(&pm(tokens).expect("Tests should pass well-formed input")) + .expect("Tests should pass valid input") + } + + #[test] + fn succeeds() { + let idents = fm::(quote!(ignore(Debug, Clone, Eq))); + assert_eq!( + idents.to_strings(), + vec![ + String::from("Debug"), + String::from("Clone"), + String::from("Eq") + ] + ); + } + + /// Check that the parser rejects non-word members of the list, and that the error + /// has an associated span. + #[test] + fn fails_non_word() { + let input = IdentList::from_meta(&pm(quote!(ignore(Debug, Clone = false))).unwrap()); + let err = input.unwrap_err(); + assert!(err.has_span()); + } +}