Add enum input value tests and improve validation
This commit is contained in:
parent
b3a750ffa5
commit
478c7b7819
3 changed files with 158 additions and 1 deletions
146
src/executor_tests/enums.rs
Normal file
146
src/executor_tests/enums.rs
Normal file
|
@ -0,0 +1,146 @@
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use value::Value;
|
||||||
|
use ast::InputValue;
|
||||||
|
use schema::model::RootNode;
|
||||||
|
use ::GraphQLError::ValidationError;
|
||||||
|
use validation::RuleError;
|
||||||
|
use parser::SourcePosition;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
enum Color { Red, Green, Blue }
|
||||||
|
struct TestType;
|
||||||
|
|
||||||
|
graphql_enum!(Color {
|
||||||
|
Color::Red => "RED",
|
||||||
|
Color::Green => "GREEN",
|
||||||
|
Color::Blue => "BLUE",
|
||||||
|
});
|
||||||
|
|
||||||
|
graphql_object!(TestType: () |&self| {
|
||||||
|
field to_string(color: Color) -> String {
|
||||||
|
format!("Color::{:?}", color)
|
||||||
|
}
|
||||||
|
|
||||||
|
field a_color() -> Color {
|
||||||
|
Color::Red
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
fn run_variable_query<F>(query: &str, vars: HashMap<String, InputValue>, f: F)
|
||||||
|
where F: Fn(&HashMap<String, Value>) -> ()
|
||||||
|
{
|
||||||
|
let schema = RootNode::new(TestType, ());
|
||||||
|
|
||||||
|
let (result, errs) = ::execute(query, None, &schema, &vars, &())
|
||||||
|
.expect("Execution failed");
|
||||||
|
|
||||||
|
assert_eq!(errs, []);
|
||||||
|
|
||||||
|
println!("Result: {:?}", result);
|
||||||
|
|
||||||
|
let obj = result.as_object_value().expect("Result is not an object");
|
||||||
|
|
||||||
|
f(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn run_query<F>(query: &str, f: F)
|
||||||
|
where F: Fn(&HashMap<String, Value>) -> ()
|
||||||
|
{
|
||||||
|
run_variable_query(query, HashMap::new(), f);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn accepts_enum_literal() {
|
||||||
|
run_query(
|
||||||
|
"{ toString(color: RED) }",
|
||||||
|
|result| {
|
||||||
|
assert_eq!(
|
||||||
|
result.get("toString"),
|
||||||
|
Some(&Value::string("Color::Red")));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn serializes_as_output() {
|
||||||
|
run_query(
|
||||||
|
"{ aColor }",
|
||||||
|
|result| {
|
||||||
|
assert_eq!(
|
||||||
|
result.get("aColor"),
|
||||||
|
Some(&Value::string("RED")));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn does_not_accept_string_literals() {
|
||||||
|
let schema = RootNode::new(TestType, ());
|
||||||
|
|
||||||
|
let query = r#"{ toString(color: "RED") }"#;
|
||||||
|
let vars = vec![
|
||||||
|
].into_iter().collect();
|
||||||
|
|
||||||
|
let error = ::execute(query, None, &schema, &vars, &())
|
||||||
|
.unwrap_err();
|
||||||
|
|
||||||
|
assert_eq!(error, ValidationError(vec![
|
||||||
|
RuleError::new(
|
||||||
|
r#"Invalid value for argument "color", expected type "Color!""#,
|
||||||
|
&[SourcePosition::new(18, 0, 18)],
|
||||||
|
),
|
||||||
|
]));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn accepts_strings_in_variables() {
|
||||||
|
run_variable_query(
|
||||||
|
"{ toString(color: RED) }",
|
||||||
|
vec![
|
||||||
|
("color".to_owned(), InputValue::string("RED")),
|
||||||
|
].into_iter().collect(),
|
||||||
|
|result| {
|
||||||
|
assert_eq!(
|
||||||
|
result.get("toString"),
|
||||||
|
Some(&Value::string("Color::Red")));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn does_not_accept_incorrect_enum_name_in_variables() {
|
||||||
|
let schema = RootNode::new(TestType, ());
|
||||||
|
|
||||||
|
let query = r#"query q($color: Color!) { toString(color: $color) }"#;
|
||||||
|
let vars = vec![
|
||||||
|
("color".to_owned(), InputValue::string("BLURPLE")),
|
||||||
|
].into_iter().collect();
|
||||||
|
|
||||||
|
let error = ::execute(query, None, &schema, &vars, &())
|
||||||
|
.unwrap_err();
|
||||||
|
|
||||||
|
assert_eq!(error, ValidationError(vec![
|
||||||
|
RuleError::new(
|
||||||
|
r#"Variable "$color" got invalid value. Invalid value for enum "Color"."#,
|
||||||
|
&[SourcePosition::new(8, 0, 8)],
|
||||||
|
),
|
||||||
|
]));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn does_not_accept_incorrect_type_in_variables() {
|
||||||
|
let schema = RootNode::new(TestType, ());
|
||||||
|
|
||||||
|
let query = r#"query q($color: Color!) { toString(color: $color) }"#;
|
||||||
|
let vars = vec![
|
||||||
|
("color".to_owned(), InputValue::int(123)),
|
||||||
|
].into_iter().collect();
|
||||||
|
|
||||||
|
let error = ::execute(query, None, &schema, &vars, &())
|
||||||
|
.unwrap_err();
|
||||||
|
|
||||||
|
assert_eq!(error, ValidationError(vec![
|
||||||
|
RuleError::new(
|
||||||
|
r#"Variable "$color" got invalid value. Expected "Color", found not a string or enum."#,
|
||||||
|
&[SourcePosition::new(8, 0, 8)],
|
||||||
|
),
|
||||||
|
]));
|
||||||
|
}
|
|
@ -1,2 +1,3 @@
|
||||||
mod introspection;
|
mod introspection;
|
||||||
mod variables;
|
mod variables;
|
||||||
|
mod enums;
|
||||||
|
|
|
@ -162,7 +162,17 @@ fn unify_enum<'a>(
|
||||||
path: &Path<'a>,
|
path: &Path<'a>,
|
||||||
) {
|
) {
|
||||||
match value {
|
match value {
|
||||||
&InputValue::String(_) | &InputValue::Enum(_) => (),
|
&InputValue::String(ref name) | &InputValue::Enum(ref name) => {
|
||||||
|
if !meta.values.iter().any(|ev| &ev.name == name) {
|
||||||
|
push_unification_error(
|
||||||
|
errors,
|
||||||
|
var_name,
|
||||||
|
var_pos,
|
||||||
|
path,
|
||||||
|
&format!(r#"Invalid value for enum "{}""#, meta.name),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
_ => push_unification_error(
|
_ => push_unification_error(
|
||||||
errors,
|
errors,
|
||||||
var_name,
|
var_name,
|
||||||
|
|
Loading…
Reference in a new issue