Add enum input value tests and improve validation

This commit is contained in:
Magnus Hallin 2016-11-12 10:24:23 +01:00
parent b3a750ffa5
commit 478c7b7819
3 changed files with 158 additions and 1 deletions

146
src/executor_tests/enums.rs Normal file
View 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)],
),
]));
}

View file

@ -1,2 +1,3 @@
mod introspection;
mod variables;
mod enums;

View file

@ -162,7 +162,17 @@ fn unify_enum<'a>(
path: &Path<'a>,
) {
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(
errors,
var_name,