Add tests for the general args macro

This commit is contained in:
Magnus Hallin 2016-10-16 11:33:51 +02:00
parent 9f5294ad3e
commit 6cc124d075
3 changed files with 490 additions and 54 deletions

View file

@ -5,16 +5,17 @@ macro_rules! __graphql__args {
( @as_expr, $e:expr) => { $e };
( @as_pattern, $p:pat) => { $p };
(
@assign_arg_vars,
$args:ident, $executorvar:ident, &mut $exec:ident
) => {
let __graphql__args!(@as_pattern, $exec) = &mut $executorvar;
( @assign_arg_vars, $args:ident, $executorvar:ident, , $($rest:tt)* ) => {
__graphql__args!(@assign_arg_vars, $args, $executorvar, $($rest)*);
};
( @assign_arg_vars, $args:ident, $executorvar:ident, ) => {
();
};
(
@assign_arg_vars,
$args:ident, $executorvar:ident, &mut $exec:ident, $($rest:tt)*
$args:ident, $executorvar:ident, &mut $exec:ident $($rest:tt)*
) => {
let __graphql__args!(@as_pattern, $exec) = &mut $executorvar;
__graphql__args!(@assign_arg_vars, $args, $executorvar, $($rest)*);
@ -23,7 +24,7 @@ macro_rules! __graphql__args {
(
@assign_arg_vars,
$args:ident, $executorvar:ident,
$name:ident : Option<$ty:ty> as $desc:expr, $($rest:tt)*
$name:ident : Option<$ty:ty> as $desc:tt $($rest:tt)*
) => {
let $name: Option<$ty> = $args
.get(&$crate::to_snake_case(stringify!($name)))
@ -31,16 +32,6 @@ macro_rules! __graphql__args {
__graphql__args!(@assign_arg_vars, $args, $executorvar, $($rest)*);
};
(
@assign_arg_vars,
$args:ident, $executorvar:ident,
$name:ident : Option<$ty:ty> as $desc:expr
) => {
let $name: Option<$ty> = $args
.get(&$crate::to_snake_case(stringify!($name)))
.unwrap_or(None);
};
(
@assign_arg_vars,
$args:ident, $executorvar:ident,
@ -62,20 +53,24 @@ macro_rules! __graphql__args {
.expect("Argument missing - validation must have failed");
};
( @assign_arg_vars, $args:ident, $executorvar:ident, ) => {
();
};
(
@apply_args,
$reg:expr, $base:expr, ( &mut executor )
) => {
( @apply_args, $reg:expr, $base:expr, ( ) ) => {
$base
};
(
@apply_args,
$reg:expr, $base:expr, ( &mut executor , $( $rest:tt )* )
$reg:expr, $base:expr, ( , $( $rest:tt )* )
) => {
__graphql__args!(
@apply_args,
$reg,
$base,
( $($rest)* ))
};
(
@apply_args,
$reg:expr, $base:expr, ( &mut executor $( $rest:tt )* )
) => {
__graphql__args!(
@apply_args,
@ -102,24 +97,14 @@ macro_rules! __graphql__args {
$reg,
$base.argument($reg.arg_with_default::<$t>(
&$crate::to_snake_case(stringify!($name)),
&__graphql__args!(@as_expr, $default)))
.description($desc),
&__graphql__args!(@as_expr, $default))),
( $($rest)* ))
};
(
@apply_args,
$reg:expr, $base:expr, ( $name:ident = $default:tt : $t:ty as $desc:expr )
) => {
$base.argument($reg.arg_with_default::<$t>(
&$crate::to_snake_case(stringify!($name)),
&__graphql__args!(@as_expr, $default))
.description($desc))
};
(
@apply_args,
$reg:expr, $base:expr, ( $name:ident = $default:tt : $t:ty as $desc:expr , $( $rest:tt )* )
$reg:expr, $base:expr,
( $name:ident = $default:tt : $t:ty as $desc:tt $( $rest:tt )* )
) => {
__graphql__args!(
@apply_args,
@ -153,17 +138,7 @@ macro_rules! __graphql__args {
(
@apply_args,
$reg:expr, $base:expr, ( $name:ident : $t:ty as $desc:expr )
) => {
$base.argument(
$reg.arg::<$t>(
&$crate::to_snake_case(stringify!($name)))
.description($desc))
};
(
@apply_args,
$reg:expr, $base:expr, ( $name:ident : $t:ty as $desc:expr , $( $rest:tt )* )
$reg:expr, $base:expr, ( $name:ident : $t:ty as $desc:tt $( $rest:tt )* )
) => {
__graphql__args!(
@apply_args,
@ -174,8 +149,4 @@ macro_rules! __graphql__args {
.description($desc)),
( $($rest)* ))
};
( @apply_args, $reg:expr, $base:expr, ( ) ) => {
$base
};
}

464
src/macros/tests/args.rs Normal file
View file

@ -0,0 +1,464 @@
use std::collections::HashMap;
use executor::FieldResult;
use value::Value;
use schema::model::RootNode;
struct Root;
/*
Syntax to validate:
* No args at all
* Executor arg vs. no executor arg
* Single arg vs. multi arg
* Trailing comma vs. no trailing comma
* Default value vs. no default value
* Description vs. no description
*/
graphql_object!(Root: () as "Root" |&self| {
field simple() -> FieldResult<i64> { Ok(0) }
field exec_arg(&mut executor) -> FieldResult<i64> { Ok(0) }
field exec_arg_and_more(&mut executor, arg: i64) -> FieldResult<i64> { Ok(0) }
field single_arg(arg: i64) -> FieldResult<i64> { Ok(0) }
field multi_args(
arg1: i64,
arg2: i64
) -> FieldResult<i64> { Ok(0) }
field multi_args_trailing_comma(
arg1: i64,
arg2: i64,
) -> FieldResult<i64> { Ok(0) }
field single_arg_descr(arg: i64 as "The arg") -> FieldResult<i64> { Ok(0) }
field multi_args_descr(
arg1: i64 as "The first arg",
arg2: i64 as "The second arg"
) -> FieldResult<i64> { Ok(0) }
field multi_args_descr_trailing_comma(
arg1: i64 as "The first arg",
arg2: i64 as "The second arg",
) -> FieldResult<i64> { Ok(0) }
field arg_with_default(arg = 123: i64) -> FieldResult<i64> { Ok(0) }
field multi_args_with_default(
arg1 = 123: i64,
arg2 = 456: i64
) -> FieldResult<i64> { Ok(0) }
field multi_args_with_default_trailing_comma(
arg1 = 123: i64,
arg2 = 456: i64,
) -> FieldResult<i64> { Ok(0) }
field arg_with_default_descr(arg = 123: i64 as "The arg") -> FieldResult<i64> { Ok(0) }
field multi_args_with_default_descr(
arg1 = 123: i64 as "The first arg",
arg2 = 456: i64 as "The second arg"
) -> FieldResult<i64> { Ok(0) }
field multi_args_with_default_trailing_comma_descr(
arg1 = 123: i64 as "The first arg",
arg2 = 456: i64 as "The second arg",
) -> FieldResult<i64> { Ok(0) }
});
fn run_args_info_query<F>(field_name: &str, f: F)
where F: Fn(&Vec<Value>) -> ()
{
let doc = r#"
{
__type(name: "Root") {
fields {
name
args {
name
description
defaultValue
type {
name
ofType {
name
}
}
}
}
}
}
"#;
let schema = RootNode::new(Root {}, ());
let (result, errs) = ::execute(doc, None, &schema, &HashMap::new(), &())
.expect("Execution failed");
assert_eq!(errs, []);
println!("Result: {:?}", result);
let type_info = result
.as_object_value().expect("Result is not an object")
.get("__type").expect("__type field missing")
.as_object_value().expect("__type field not an object value");
let fields = type_info
.get("fields").expect("fields field missing")
.as_list_value().expect("fields not a list");
let field = fields
.into_iter().filter(
|f| f.as_object_value().expect("Field not an object")
.get("name").expect("name field missing from field")
.as_string_value().expect("name is not a string")
== field_name)
.next().expect("Field not found")
.as_object_value().expect("Field is not an object");
println!("Field: {:?}", field);
let args = field
.get("args").expect("args missing from field")
.as_list_value().expect("args is not a list");
println!("Args: {:?}", args);
f(args);
}
#[test]
fn introspect_field_simple() {
run_args_info_query("simple", |args| {
assert_eq!(args.len(), 0);
});
}
#[test]
fn introspect_field_exec_arg() {
run_args_info_query("execArg", |args| {
assert_eq!(args.len(), 0);
});
}
#[test]
fn introspect_field_exec_arg_and_more() {
run_args_info_query("execArgAndMore", |args| {
assert_eq!(args.len(), 1);
assert!(args.contains(&Value::object(vec![
("name", Value::string("arg")),
("description", Value::null()),
("defaultValue", Value::null()),
("type", Value::object(vec![
("name", Value::null()),
("ofType", Value::object(vec![
("name", Value::string("Int")),
].into_iter().collect())),
].into_iter().collect())),
].into_iter().collect())));
});
}
#[test]
fn introspect_field_single_arg() {
run_args_info_query("singleArg", |args| {
assert_eq!(args.len(), 1);
assert!(args.contains(&Value::object(vec![
("name", Value::string("arg")),
("description", Value::null()),
("defaultValue", Value::null()),
("type", Value::object(vec![
("name", Value::null()),
("ofType", Value::object(vec![
("name", Value::string("Int")),
].into_iter().collect())),
].into_iter().collect())),
].into_iter().collect())));
});
}
#[test]
fn introspect_field_multi_args() {
run_args_info_query("multiArgs", |args| {
assert_eq!(args.len(), 2);
assert!(args.contains(&Value::object(vec![
("name", Value::string("arg1")),
("description", Value::null()),
("defaultValue", Value::null()),
("type", Value::object(vec![
("name", Value::null()),
("ofType", Value::object(vec![
("name", Value::string("Int")),
].into_iter().collect())),
].into_iter().collect())),
].into_iter().collect())));
assert!(args.contains(&Value::object(vec![
("name", Value::string("arg2")),
("description", Value::null()),
("defaultValue", Value::null()),
("type", Value::object(vec![
("name", Value::null()),
("ofType", Value::object(vec![
("name", Value::string("Int")),
].into_iter().collect())),
].into_iter().collect())),
].into_iter().collect())));
});
}
#[test]
fn introspect_field_multi_args_trailing_comma() {
run_args_info_query("multiArgsTrailingComma", |args| {
assert_eq!(args.len(), 2);
assert!(args.contains(&Value::object(vec![
("name", Value::string("arg1")),
("description", Value::null()),
("defaultValue", Value::null()),
("type", Value::object(vec![
("name", Value::null()),
("ofType", Value::object(vec![
("name", Value::string("Int")),
].into_iter().collect())),
].into_iter().collect())),
].into_iter().collect())));
assert!(args.contains(&Value::object(vec![
("name", Value::string("arg2")),
("description", Value::null()),
("defaultValue", Value::null()),
("type", Value::object(vec![
("name", Value::null()),
("ofType", Value::object(vec![
("name", Value::string("Int")),
].into_iter().collect())),
].into_iter().collect())),
].into_iter().collect())));
});
}
#[test]
fn introspect_field_single_arg_descr() {
run_args_info_query("singleArgDescr", |args| {
assert_eq!(args.len(), 1);
assert!(args.contains(&Value::object(vec![
("name", Value::string("arg")),
("description", Value::string("The arg")),
("defaultValue", Value::null()),
("type", Value::object(vec![
("name", Value::null()),
("ofType", Value::object(vec![
("name", Value::string("Int")),
].into_iter().collect())),
].into_iter().collect())),
].into_iter().collect())));
});
}
#[test]
fn introspect_field_multi_args_descr() {
run_args_info_query("multiArgsDescr", |args| {
assert_eq!(args.len(), 2);
assert!(args.contains(&Value::object(vec![
("name", Value::string("arg1")),
("description", Value::string("The first arg")),
("defaultValue", Value::null()),
("type", Value::object(vec![
("name", Value::null()),
("ofType", Value::object(vec![
("name", Value::string("Int")),
].into_iter().collect())),
].into_iter().collect())),
].into_iter().collect())));
assert!(args.contains(&Value::object(vec![
("name", Value::string("arg2")),
("description", Value::string("The second arg")),
("defaultValue", Value::null()),
("type", Value::object(vec![
("name", Value::null()),
("ofType", Value::object(vec![
("name", Value::string("Int")),
].into_iter().collect())),
].into_iter().collect())),
].into_iter().collect())));
});
}
#[test]
fn introspect_field_multi_args_descr_trailing_comma() {
run_args_info_query("multiArgsDescrTrailingComma", |args| {
assert_eq!(args.len(), 2);
assert!(args.contains(&Value::object(vec![
("name", Value::string("arg1")),
("description", Value::string("The first arg")),
("defaultValue", Value::null()),
("type", Value::object(vec![
("name", Value::null()),
("ofType", Value::object(vec![
("name", Value::string("Int")),
].into_iter().collect())),
].into_iter().collect())),
].into_iter().collect())));
assert!(args.contains(&Value::object(vec![
("name", Value::string("arg2")),
("description", Value::string("The second arg")),
("defaultValue", Value::null()),
("type", Value::object(vec![
("name", Value::null()),
("ofType", Value::object(vec![
("name", Value::string("Int")),
].into_iter().collect())),
].into_iter().collect())),
].into_iter().collect())));
});
}
#[test]
fn introspect_field_arg_with_default() {
run_args_info_query("argWithDefault", |args| {
assert_eq!(args.len(), 1);
assert!(args.contains(&Value::object(vec![
("name", Value::string("arg")),
("description", Value::null()),
("defaultValue", Value::string("123")),
("type", Value::object(vec![
("name", Value::string("Int")),
("ofType", Value::null()),
].into_iter().collect())),
].into_iter().collect())));
});
}
#[test]
fn introspect_field_multi_args_with_default() {
run_args_info_query("multiArgsWithDefault", |args| {
assert_eq!(args.len(), 2);
assert!(args.contains(&Value::object(vec![
("name", Value::string("arg1")),
("description", Value::null()),
("defaultValue", Value::string("123")),
("type", Value::object(vec![
("name", Value::string("Int")),
("ofType", Value::null()),
].into_iter().collect())),
].into_iter().collect())));
assert!(args.contains(&Value::object(vec![
("name", Value::string("arg2")),
("description", Value::null()),
("defaultValue", Value::string("456")),
("type", Value::object(vec![
("name", Value::string("Int")),
("ofType", Value::null()),
].into_iter().collect())),
].into_iter().collect())));
});
}
#[test]
fn introspect_field_multi_args_with_default_trailing_comma() {
run_args_info_query("multiArgsWithDefaultTrailingComma", |args| {
assert_eq!(args.len(), 2);
assert!(args.contains(&Value::object(vec![
("name", Value::string("arg1")),
("description", Value::null()),
("defaultValue", Value::string("123")),
("type", Value::object(vec![
("name", Value::string("Int")),
("ofType", Value::null()),
].into_iter().collect())),
].into_iter().collect())));
assert!(args.contains(&Value::object(vec![
("name", Value::string("arg2")),
("description", Value::null()),
("defaultValue", Value::string("456")),
("type", Value::object(vec![
("name", Value::string("Int")),
("ofType", Value::null()),
].into_iter().collect())),
].into_iter().collect())));
});
}
#[test]
fn introspect_field_arg_with_default_descr() {
run_args_info_query("argWithDefaultDescr", |args| {
assert_eq!(args.len(), 1);
assert!(args.contains(&Value::object(vec![
("name", Value::string("arg")),
("description", Value::string("The arg")),
("defaultValue", Value::string("123")),
("type", Value::object(vec![
("name", Value::string("Int")),
("ofType", Value::null()),
].into_iter().collect())),
].into_iter().collect())));
});
}
#[test]
fn introspect_field_multi_args_with_default_descr() {
run_args_info_query("multiArgsWithDefaultDescr", |args| {
assert_eq!(args.len(), 2);
assert!(args.contains(&Value::object(vec![
("name", Value::string("arg1")),
("description", Value::string("The first arg")),
("defaultValue", Value::string("123")),
("type", Value::object(vec![
("name", Value::string("Int")),
("ofType", Value::null()),
].into_iter().collect())),
].into_iter().collect())));
assert!(args.contains(&Value::object(vec![
("name", Value::string("arg2")),
("description", Value::string("The second arg")),
("defaultValue", Value::string("456")),
("type", Value::object(vec![
("name", Value::string("Int")),
("ofType", Value::null()),
].into_iter().collect())),
].into_iter().collect())));
});
}
#[test]
fn introspect_field_multi_args_with_default_trailing_comma_descr() {
run_args_info_query("multiArgsWithDefaultTrailingCommaDescr", |args| {
assert_eq!(args.len(), 2);
assert!(args.contains(&Value::object(vec![
("name", Value::string("arg1")),
("description", Value::string("The first arg")),
("defaultValue", Value::string("123")),
("type", Value::object(vec![
("name", Value::string("Int")),
("ofType", Value::null()),
].into_iter().collect())),
].into_iter().collect())));
assert!(args.contains(&Value::object(vec![
("name", Value::string("arg2")),
("description", Value::string("The second arg")),
("defaultValue", Value::string("456")),
("type", Value::object(vec![
("name", Value::string("Int")),
("ofType", Value::null()),
].into_iter().collect())),
].into_iter().collect())));
});
}

View file

@ -1,3 +1,4 @@
mod enums;
mod scalar;
#[allow(dead_code)] mod input_object;
mod args;