Add more unit tests for doc comments as descriptions

This commit is contained in:
Christian Legnitto 2018-06-07 23:52:13 -07:00 committed by theduke
parent 1fd5c10327
commit 4be687f73e

View file

@ -1,11 +1,5 @@
use syn::{
Attribute,
Meta,
MetaNameValue,
NestedMeta,
Lit,
};
use regex::Regex; use regex::Regex;
use syn::{Attribute, Lit, Meta, MetaNameValue, NestedMeta};
// Gets doc comment. // Gets doc comment.
pub fn get_doc_comment(attrs: &Vec<Attribute>) -> Option<String> { pub fn get_doc_comment(attrs: &Vec<Attribute>) -> Option<String> {
@ -20,6 +14,8 @@ pub fn get_doc_comment(attrs: &Vec<Attribute>) -> Option<String> {
// Concatenates doc strings into one string. // Concatenates doc strings into one string.
fn join_doc_strings(docs: &Vec<String>) -> String { fn join_doc_strings(docs: &Vec<String>) -> String {
let s: String = docs.iter() let s: String = docs.iter()
// Trim any extra spaces.
.map(|x| x.trim().to_string())
// Convert empty comments to newlines. // Convert empty comments to newlines.
.map(|x| if x == "" { "\n".to_string() } else { x.clone() }) .map(|x| if x == "" { "\n".to_string() } else { x.clone() })
.collect::<Vec<String>>() .collect::<Vec<String>>()
@ -32,13 +28,15 @@ fn join_doc_strings(docs: &Vec<String>) -> String {
fn get_doc_strings(items: &Vec<MetaNameValue>) -> Option<Vec<String>> { fn get_doc_strings(items: &Vec<MetaNameValue>) -> Option<Vec<String>> {
let mut docs = Vec::new(); let mut docs = Vec::new();
for item in items { for item in items {
if item.ident == "doc" {
match item.lit { match item.lit {
Lit::Str(ref strlit) => { Lit::Str(ref strlit) => {
docs.push(strlit.value().trim().to_string()); docs.push(strlit.value().to_string());
}, }
_ => panic!("doc attributes only have string literal"), _ => panic!("doc attributes only have string literal"),
} }
} }
}
if !docs.is_empty() { if !docs.is_empty() {
return Some(docs); return Some(docs);
} }
@ -50,9 +48,7 @@ fn get_doc_attr(attrs: &Vec<Attribute>) -> Option<Vec<MetaNameValue>> {
let mut docs = Vec::new(); let mut docs = Vec::new();
for attr in attrs { for attr in attrs {
match attr.interpret_meta() { match attr.interpret_meta() {
Some(Meta::NameValue(ref nv)) if nv.ident == "doc" => { Some(Meta::NameValue(ref nv)) if nv.ident == "doc" => docs.push(nv.clone()),
docs.push(nv.clone())
}
_ => {} _ => {}
} }
} }
@ -68,7 +64,7 @@ pub fn get_graphl_attr(attrs: &Vec<Attribute>) -> Option<Vec<NestedMeta>> {
match attr.interpret_meta() { match attr.interpret_meta() {
Some(Meta::List(ref list)) if list.ident == "graphql" => { Some(Meta::List(ref list)) if list.ident == "graphql" => {
return Some(list.nested.iter().map(|x| x.clone()).collect()); return Some(list.nested.iter().map(|x| x.clone()).collect());
}, }
_ => {} _ => {}
} }
} }
@ -79,9 +75,7 @@ pub fn keyed_item_value(item: &NestedMeta, name: &str, must_be_string: bool) ->
match item { match item {
&NestedMeta::Meta(Meta::NameValue(ref nameval)) if nameval.ident == name => { &NestedMeta::Meta(Meta::NameValue(ref nameval)) if nameval.ident == name => {
match &nameval.lit { match &nameval.lit {
&Lit::Str(ref strlit) => { &Lit::Str(ref strlit) => Some(strlit.value()),
Some(strlit.value())
},
_ => if must_be_string { _ => if must_be_string {
panic!(format!( panic!(format!(
"Invalid format for attribute \"{:?}\": expected a string", "Invalid format for attribute \"{:?}\": expected a string",
@ -91,7 +85,7 @@ pub fn keyed_item_value(item: &NestedMeta, name: &str, must_be_string: bool) ->
None None
}, },
} }
}, }
_ => None, _ => None,
} }
} }
@ -105,7 +99,8 @@ pub fn to_camel_case(s: &str) -> String {
if i > 0 && part.len() == 1 { if i > 0 && part.len() == 1 {
dest.push_str(&part.to_uppercase()); dest.push_str(&part.to_uppercase());
} else if i > 0 && part.len() > 1 { } else if i > 0 && part.len() > 1 {
let first = part.chars() let first = part
.chars()
.next() .next()
.unwrap() .unwrap()
.to_uppercase() .to_uppercase()
@ -122,19 +117,6 @@ pub fn to_camel_case(s: &str) -> String {
dest dest
} }
#[test]
fn test_to_camel_case() {
assert_eq!(&to_camel_case("test")[..], "test");
assert_eq!(&to_camel_case("_test")[..], "Test");
assert_eq!(&to_camel_case("first_second")[..], "firstSecond");
assert_eq!(&to_camel_case("first_")[..], "first");
assert_eq!(&to_camel_case("a_b_c")[..], "aBC");
assert_eq!(&to_camel_case("a_bc")[..], "aBc");
assert_eq!(&to_camel_case("a_b")[..], "aB");
assert_eq!(&to_camel_case("a")[..], "a");
assert_eq!(&to_camel_case("")[..], "");
}
pub(crate) fn to_upper_snake_case(s: &str) -> String { pub(crate) fn to_upper_snake_case(s: &str) -> String {
let mut last_lower = false; let mut last_lower = false;
let mut upper = String::new(); let mut upper = String::new();
@ -157,6 +139,133 @@ pub(crate) fn to_upper_snake_case(s: &str) -> String {
upper upper
} }
#[doc(hidden)]
pub fn is_valid_name(field_name: &str) -> bool {
lazy_static! {
static ref GRAPHQL_NAME_SPEC: Regex = Regex::new("^[_A-Za-z][_0-9A-Za-z]*$").unwrap();
}
GRAPHQL_NAME_SPEC.is_match(field_name)
}
#[cfg(test)]
mod test {
use super::*;
use quote::__rt::*;
use syn::{Ident, LitStr};
fn strs_to_strings(source: Vec<&str>) -> Vec<String> {
source
.iter()
.map(|x| x.to_string())
.collect::<Vec<String>>()
}
fn litstr(s: &str) -> Lit {
Lit::Str(LitStr::new(s, Span::call_site()))
}
fn ident(s: &str) -> Ident {
Ident::new(s, Span::call_site())
}
mod test_get_doc_strings {
use super::*;
#[test]
fn test_single() {
let result = get_doc_strings(&vec![MetaNameValue {
ident: ident("doc").into(),
eq_token: Default::default(),
lit: litstr("foo"),
}]);
assert_eq!(
&result.unwrap(),
Some(&strs_to_strings(vec!["foo"])).unwrap()
);
}
#[test]
fn test_many() {
let result = get_doc_strings(&vec![
MetaNameValue {
ident: ident("doc").into(),
eq_token: Default::default(),
lit: litstr("foo"),
},
MetaNameValue {
ident: ident("doc").into(),
eq_token: Default::default(),
lit: litstr("\n"),
},
MetaNameValue {
ident: ident("doc").into(),
eq_token: Default::default(),
lit: litstr("bar"),
},
]);
assert_eq!(
&result.unwrap(),
Some(&strs_to_strings(vec!["foo", "\n", "bar"])).unwrap()
);
}
#[test]
fn test_not_doc() {
let result = get_doc_strings(&vec![MetaNameValue {
ident: ident("blah").into(),
eq_token: Default::default(),
lit: litstr("foo"),
}]);
assert_eq!(&result, &None);
}
}
mod test_join_doc_strings {
use super::*;
#[test]
fn test_single() {
let result = join_doc_strings(&strs_to_strings(vec!["foo"]));
assert_eq!(&result, "foo");
}
#[test]
fn test_multiple() {
let result = join_doc_strings(&strs_to_strings(vec!["foo", "bar"]));
assert_eq!(&result, "foo bar");
}
#[test]
fn test_trims_spaces() {
let result = join_doc_strings(&strs_to_strings(vec![" foo ", "bar ", " baz"]));
assert_eq!(&result, "foo bar baz");
}
#[test]
fn test_empty() {
let result = join_doc_strings(&strs_to_strings(vec!["foo", "", "bar"]));
assert_eq!(&result, "foo\nbar");
}
#[test]
fn test_newline_spaces() {
let result = join_doc_strings(&strs_to_strings(vec!["foo ", "", " bar"]));
assert_eq!(&result, "foo\nbar");
}
}
#[test]
fn test_to_camel_case() {
assert_eq!(&to_camel_case("test")[..], "test");
assert_eq!(&to_camel_case("_test")[..], "Test");
assert_eq!(&to_camel_case("first_second")[..], "firstSecond");
assert_eq!(&to_camel_case("first_")[..], "first");
assert_eq!(&to_camel_case("a_b_c")[..], "aBC");
assert_eq!(&to_camel_case("a_bc")[..], "aBc");
assert_eq!(&to_camel_case("a_b")[..], "aB");
assert_eq!(&to_camel_case("a")[..], "a");
assert_eq!(&to_camel_case("")[..], "");
}
#[test] #[test]
fn test_to_upper_snake_case() { fn test_to_upper_snake_case() {
assert_eq!(to_upper_snake_case("abc"), "ABC"); assert_eq!(to_upper_snake_case("abc"), "ABC");
@ -169,14 +278,6 @@ fn test_to_upper_snake_case() {
assert_eq!(to_upper_snake_case("some_INpuT"), "SOME_INPU_T"); assert_eq!(to_upper_snake_case("some_INpuT"), "SOME_INPU_T");
} }
#[doc(hidden)]
pub fn is_valid_name(field_name: &str) -> bool {
lazy_static!{
static ref GRAPHQL_NAME_SPEC: Regex = Regex::new("^[_A-Za-z][_0-9A-Za-z]*$").unwrap();
}
GRAPHQL_NAME_SPEC.is_match(field_name)
}
#[test] #[test]
fn test_is_valid_name() { fn test_is_valid_name() {
assert_eq!(is_valid_name("yesItIs"), true); assert_eq!(is_valid_name("yesItIs"), true);
@ -189,3 +290,4 @@ fn test_is_valid_name(){
assert_eq!(is_valid_name("aTest"), true); assert_eq!(is_valid_name("aTest"), true);
assert_eq!(is_valid_name("__Atest90"), true); assert_eq!(is_valid_name("__Atest90"), true);
} }
}