Format entire codebase with rustfmt
This commit is contained in:
parent
406bdaa55c
commit
d00e74bb4e
74 changed files with 2910 additions and 1786 deletions
|
@ -402,9 +402,9 @@ impl InputValue {
|
|||
(&Null, &Null) => true,
|
||||
(&Int(i1), &Int(i2)) => i1 == i2,
|
||||
(&Float(f1), &Float(f2)) => f1 == f2,
|
||||
(&String(ref s1), &String(ref s2)) |
|
||||
(&Enum(ref s1), &Enum(ref s2)) |
|
||||
(&Variable(ref s1), &Variable(ref s2)) => s1 == s2,
|
||||
(&String(ref s1), &String(ref s2))
|
||||
| (&Enum(ref s1), &Enum(ref s2))
|
||||
| (&Variable(ref s1), &Variable(ref s2)) => s1 == s2,
|
||||
(&Boolean(b1), &Boolean(b2)) => b1 == b2,
|
||||
(&List(ref l1), &List(ref l2)) => l1.iter()
|
||||
.zip(l2.iter())
|
||||
|
|
|
@ -68,15 +68,21 @@ impl Eq for ExecutionError {}
|
|||
|
||||
impl PartialOrd for ExecutionError {
|
||||
fn partial_cmp(&self, other: &ExecutionError) -> Option<Ordering> {
|
||||
(&self.location, &self.path, &self.error.message)
|
||||
.partial_cmp(&(&other.location, &other.path, &other.error.message))
|
||||
(&self.location, &self.path, &self.error.message).partial_cmp(&(
|
||||
&other.location,
|
||||
&other.path,
|
||||
&other.error.message,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
impl Ord for ExecutionError {
|
||||
fn cmp(&self, other: &ExecutionError) -> Ordering {
|
||||
(&self.location, &self.path, &self.error.message)
|
||||
.cmp(&(&other.location, &other.path, &other.error.message))
|
||||
(&self.location, &self.path, &self.error.message).cmp(&(
|
||||
&other.location,
|
||||
&other.path,
|
||||
&other.error.message,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -213,7 +219,8 @@ impl<'a, T: GraphQLType, C> IntoResolvable<'a, T, C> for FieldResult<(&'a T::Con
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, T: GraphQLType, C> IntoResolvable<'a, Option<T>, C> for FieldResult<Option<(&'a T::Context, T)>> {
|
||||
impl<'a, T: GraphQLType, C> IntoResolvable<'a, Option<T>, C>
|
||||
for FieldResult<Option<(&'a T::Context, T)>> {
|
||||
fn into(self, _: &'a C) -> FieldResult<Option<(&'a T::Context, Option<T>)>> {
|
||||
self.map(|o| o.map(|(ctx, v)| (ctx, Some(v))))
|
||||
}
|
||||
|
@ -329,8 +336,10 @@ impl<'a, CtxT> Executor<'a, CtxT> {
|
|||
current_type: self.schema.make_type(
|
||||
&self.current_type
|
||||
.innermost_concrete()
|
||||
.field_by_name(field_name).expect("Field not found on inner type")
|
||||
.field_type),
|
||||
.field_by_name(field_name)
|
||||
.expect("Field not found on inner type")
|
||||
.field_type,
|
||||
),
|
||||
schema: self.schema,
|
||||
context: self.context,
|
||||
errors: self.errors,
|
||||
|
@ -478,8 +487,8 @@ where
|
|||
return Err(GraphQLError::MultipleOperationsProvided);
|
||||
}
|
||||
|
||||
let move_op = operation_name.is_none() ||
|
||||
op.item.name.as_ref().map(|s| s.item.as_ref()) == operation_name;
|
||||
let move_op = operation_name.is_none()
|
||||
|| op.item.name.as_ref().map(|s| s.item.as_ref()) == operation_name;
|
||||
|
||||
if move_op {
|
||||
operation = Some(op);
|
||||
|
@ -525,7 +534,10 @@ where
|
|||
|
||||
let root_type = match op.item.operation_type {
|
||||
OperationType::Query => root_node.schema.query_type(),
|
||||
OperationType::Mutation => root_node.schema.mutation_type().expect("No mutation type found")
|
||||
OperationType::Mutation => root_node
|
||||
.schema
|
||||
.mutation_type()
|
||||
.expect("No mutation type found"),
|
||||
};
|
||||
|
||||
let executor = Executor {
|
||||
|
|
|
@ -73,47 +73,50 @@ fn scalar_skip_true() {
|
|||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#[test]
|
||||
fn fragment_spread_include_true() {
|
||||
run_query("{ a, ...Frag @include(if: true) } fragment Frag on TestType { b }",
|
||||
|result| {
|
||||
assert_eq!(result.get("a"), Some(&Value::string("a")));
|
||||
assert_eq!(result.get("b"), Some(&Value::string("b")));
|
||||
});
|
||||
run_query(
|
||||
"{ a, ...Frag @include(if: true) } fragment Frag on TestType { b }",
|
||||
|result| {
|
||||
assert_eq!(result.get("a"), Some(&Value::string("a")));
|
||||
assert_eq!(result.get("b"), Some(&Value::string("b")));
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn fragment_spread_include_false() {
|
||||
run_query("{ a, ...Frag @include(if: false) } fragment Frag on TestType { b }",
|
||||
|result| {
|
||||
assert_eq!(result.get("a"), Some(&Value::string("a")));
|
||||
assert_eq!(result.get("b"), None);
|
||||
});
|
||||
run_query(
|
||||
"{ a, ...Frag @include(if: false) } fragment Frag on TestType { b }",
|
||||
|result| {
|
||||
assert_eq!(result.get("a"), Some(&Value::string("a")));
|
||||
assert_eq!(result.get("b"), None);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn fragment_spread_skip_false() {
|
||||
run_query("{ a, ...Frag @skip(if: false) } fragment Frag on TestType { b }",
|
||||
|result| {
|
||||
assert_eq!(result.get("a"), Some(&Value::string("a")));
|
||||
assert_eq!(result.get("b"), Some(&Value::string("b")));
|
||||
});
|
||||
run_query(
|
||||
"{ a, ...Frag @skip(if: false) } fragment Frag on TestType { b }",
|
||||
|result| {
|
||||
assert_eq!(result.get("a"), Some(&Value::string("a")));
|
||||
assert_eq!(result.get("b"), Some(&Value::string("b")));
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn fragment_spread_skip_true() {
|
||||
run_query("{ a, ...Frag @skip(if: true) } fragment Frag on TestType { b }",
|
||||
|result| {
|
||||
assert_eq!(result.get("a"), Some(&Value::string("a")));
|
||||
assert_eq!(result.get("b"), None);
|
||||
});
|
||||
run_query(
|
||||
"{ a, ...Frag @skip(if: true) } fragment Frag on TestType { b }",
|
||||
|result| {
|
||||
assert_eq!(result.get("a"), Some(&Value::string("a")));
|
||||
assert_eq!(result.get("b"), None);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#[test]
|
||||
fn inline_fragment_include_true() {
|
||||
run_query(
|
||||
|
@ -152,9 +155,6 @@ fn inline_fragment_skip_true() {
|
|||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#[test]
|
||||
fn anonymous_inline_fragment_include_true() {
|
||||
run_query("{ a, ... @include(if: true) { b } }", |result| {
|
||||
|
@ -187,9 +187,6 @@ fn anonymous_inline_fragment_skip_true() {
|
|||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#[test]
|
||||
fn scalar_include_true_skip_true() {
|
||||
run_query("{ a, b @include(if: true) @skip(if: true) }", |result| {
|
||||
|
|
|
@ -55,18 +55,14 @@ where
|
|||
#[test]
|
||||
fn accepts_enum_literal() {
|
||||
run_query("{ toString(color: RED) }", |result| {
|
||||
assert_eq!(
|
||||
result.get("toString"),
|
||||
Some(&Value::string("Color::Red")));
|
||||
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")));
|
||||
assert_eq!(result.get("aColor"), Some(&Value::string("RED")));
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -79,26 +75,26 @@ fn does_not_accept_string_literals() {
|
|||
|
||||
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)],
|
||||
),
|
||||
]));
|
||||
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(
|
||||
"query q($color: Color!) { toString(color: $color) }",
|
||||
vec![
|
||||
("color".to_owned(), InputValue::string("RED")),
|
||||
].into_iter()
|
||||
vec![("color".to_owned(), InputValue::string("RED"))]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
|result| {
|
||||
assert_eq!(
|
||||
result.get("toString"),
|
||||
Some(&Value::string("Color::Red")));
|
||||
assert_eq!(result.get("toString"), Some(&Value::string("Color::Red")));
|
||||
},
|
||||
);
|
||||
}
|
||||
|
@ -108,19 +104,21 @@ fn does_not_accept_incorrect_enum_name_in_variables() {
|
|||
let schema = RootNode::new(TestType, EmptyMutation::<()>::new());
|
||||
|
||||
let query = r#"query q($color: Color!) { toString(color: $color) }"#;
|
||||
let vars = vec![
|
||||
("color".to_owned(), InputValue::string("BLURPLE")),
|
||||
].into_iter()
|
||||
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)],
|
||||
),
|
||||
]));
|
||||
assert_eq!(
|
||||
error,
|
||||
ValidationError(vec![
|
||||
RuleError::new(
|
||||
r#"Variable "$color" got invalid value. Invalid value for enum "Color"."#,
|
||||
&[SourcePosition::new(8, 0, 8)],
|
||||
),
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -128,17 +126,19 @@ fn does_not_accept_incorrect_type_in_variables() {
|
|||
let schema = RootNode::new(TestType, EmptyMutation::<()>::new());
|
||||
|
||||
let query = r#"query q($color: Color!) { toString(color: $color) }"#;
|
||||
let vars = vec![
|
||||
("color".to_owned(), InputValue::int(123)),
|
||||
].into_iter()
|
||||
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![
|
||||
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)],
|
||||
),
|
||||
]));
|
||||
])
|
||||
);
|
||||
}
|
||||
|
|
|
@ -61,9 +61,8 @@ mod field_execution {
|
|||
e
|
||||
}";
|
||||
|
||||
let vars = vec![
|
||||
("size".to_owned(), InputValue::int(100))
|
||||
].into_iter()
|
||||
let vars = vec![("size".to_owned(), InputValue::int(100))]
|
||||
.into_iter()
|
||||
.collect();
|
||||
|
||||
let (result, errs) = ::execute(doc, None, &schema, &vars, &()).expect("Execution failed");
|
||||
|
@ -74,39 +73,60 @@ mod field_execution {
|
|||
|
||||
assert_eq!(
|
||||
result,
|
||||
Value::object(vec![
|
||||
("a", Value::string("Apple")),
|
||||
("b", Value::string("Banana")),
|
||||
("x", Value::string("Cookie")),
|
||||
("d", Value::string("Donut")),
|
||||
("e", Value::string("Egg")),
|
||||
("f", Value::string("Fish")),
|
||||
("pic", Value::string("Pic of size: 100")),
|
||||
("deep", Value::object(vec![
|
||||
("a", Value::string("Already Been Done")),
|
||||
("b", Value::string("Boring")),
|
||||
("c", Value::list(vec![
|
||||
Value::string("Contrived"),
|
||||
Value::null(),
|
||||
Value::string("Confusing"),
|
||||
])),
|
||||
("deeper", Value::list(vec![
|
||||
Value::object(vec![
|
||||
("a", Value::string("Apple")),
|
||||
("b", Value::string("Banana")),
|
||||
].into_iter().collect()),
|
||||
Value::null(),
|
||||
Value::object(vec![
|
||||
("a", Value::string("Apple")),
|
||||
("b", Value::string("Banana")),
|
||||
].into_iter().collect()),
|
||||
])),
|
||||
].into_iter().collect())),
|
||||
].into_iter().collect()));
|
||||
Value::object(
|
||||
vec![
|
||||
("a", Value::string("Apple")),
|
||||
("b", Value::string("Banana")),
|
||||
("x", Value::string("Cookie")),
|
||||
("d", Value::string("Donut")),
|
||||
("e", Value::string("Egg")),
|
||||
("f", Value::string("Fish")),
|
||||
("pic", Value::string("Pic of size: 100")),
|
||||
(
|
||||
"deep",
|
||||
Value::object(
|
||||
vec![
|
||||
("a", Value::string("Already Been Done")),
|
||||
("b", Value::string("Boring")),
|
||||
(
|
||||
"c",
|
||||
Value::list(vec![
|
||||
Value::string("Contrived"),
|
||||
Value::null(),
|
||||
Value::string("Confusing"),
|
||||
]),
|
||||
),
|
||||
(
|
||||
"deeper",
|
||||
Value::list(vec![
|
||||
Value::object(
|
||||
vec![
|
||||
("a", Value::string("Apple")),
|
||||
("b", Value::string("Banana")),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
Value::null(),
|
||||
Value::object(
|
||||
vec![
|
||||
("a", Value::string("Apple")),
|
||||
("b", Value::string("Banana")),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
]),
|
||||
),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
),
|
||||
].into_iter()
|
||||
.collect()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
mod merge_parallel_fragments {
|
||||
use value::Value;
|
||||
use schema::model::RootNode;
|
||||
|
@ -145,19 +165,35 @@ mod merge_parallel_fragments {
|
|||
|
||||
assert_eq!(
|
||||
result,
|
||||
Value::object(vec![
|
||||
("a", Value::string("Apple")),
|
||||
("b", Value::string("Banana")),
|
||||
("deep", Value::object(vec![
|
||||
Value::object(
|
||||
vec![
|
||||
("a", Value::string("Apple")),
|
||||
("b", Value::string("Banana")),
|
||||
("deeper", Value::object(vec![
|
||||
("b", Value::string("Banana")),
|
||||
("c", Value::string("Cherry")),
|
||||
].into_iter().collect())),
|
||||
(
|
||||
"deep",
|
||||
Value::object(
|
||||
vec![
|
||||
("b", Value::string("Banana")),
|
||||
(
|
||||
"deeper",
|
||||
Value::object(
|
||||
vec![
|
||||
("b", Value::string("Banana")),
|
||||
("c", Value::string("Cherry")),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
),
|
||||
("c", Value::string("Cherry")),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
),
|
||||
("c", Value::string("Cherry")),
|
||||
].into_iter().collect())),
|
||||
("c", Value::string("Cherry")),
|
||||
].into_iter().collect()));
|
||||
].into_iter()
|
||||
.collect()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -202,9 +238,12 @@ mod threads_context_correctly {
|
|||
|
||||
assert_eq!(
|
||||
result,
|
||||
Value::object(vec![
|
||||
("a", Value::string("Context value")),
|
||||
].into_iter().collect()));
|
||||
Value::object(
|
||||
vec![("a", Value::string("Context value"))]
|
||||
.into_iter()
|
||||
.collect()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -272,8 +311,18 @@ mod dynamic_context_switching {
|
|||
|
||||
let ctx = OuterContext {
|
||||
items: vec![
|
||||
(0, InnerContext { value: "First value".to_owned() }),
|
||||
(1, InnerContext { value: "Second value".to_owned() }),
|
||||
(
|
||||
0,
|
||||
InnerContext {
|
||||
value: "First value".to_owned(),
|
||||
},
|
||||
),
|
||||
(
|
||||
1,
|
||||
InnerContext {
|
||||
value: "Second value".to_owned(),
|
||||
},
|
||||
),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
};
|
||||
|
@ -286,12 +335,21 @@ mod dynamic_context_switching {
|
|||
|
||||
assert_eq!(
|
||||
result,
|
||||
Value::object(vec![
|
||||
("first", Value::object(vec![
|
||||
("value", Value::string("First value")),
|
||||
].into_iter().collect())),
|
||||
("missing", Value::null()),
|
||||
].into_iter().collect()));
|
||||
Value::object(
|
||||
vec![
|
||||
(
|
||||
"first",
|
||||
Value::object(
|
||||
vec![("value", Value::string("First value"))]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
),
|
||||
),
|
||||
("missing", Value::null()),
|
||||
].into_iter()
|
||||
.collect()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -307,8 +365,18 @@ mod dynamic_context_switching {
|
|||
|
||||
let ctx = OuterContext {
|
||||
items: vec![
|
||||
(0, InnerContext { value: "First value".to_owned() }),
|
||||
(1, InnerContext { value: "Second value".to_owned() }),
|
||||
(
|
||||
0,
|
||||
InnerContext {
|
||||
value: "First value".to_owned(),
|
||||
},
|
||||
),
|
||||
(
|
||||
1,
|
||||
InnerContext {
|
||||
value: "Second value".to_owned(),
|
||||
},
|
||||
),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
};
|
||||
|
@ -321,11 +389,20 @@ mod dynamic_context_switching {
|
|||
|
||||
assert_eq!(
|
||||
result,
|
||||
Value::object(vec![
|
||||
("first", Value::object(vec![
|
||||
("value", Value::string("First value")),
|
||||
].into_iter().collect())),
|
||||
].into_iter().collect()));
|
||||
Value::object(
|
||||
vec![
|
||||
(
|
||||
"first",
|
||||
Value::object(
|
||||
vec![("value", Value::string("First value"))]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
),
|
||||
),
|
||||
].into_iter()
|
||||
.collect()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -341,21 +418,34 @@ mod dynamic_context_switching {
|
|||
|
||||
let ctx = OuterContext {
|
||||
items: vec![
|
||||
(0, InnerContext { value: "First value".to_owned() }),
|
||||
(1, InnerContext { value: "Second value".to_owned() }),
|
||||
(
|
||||
0,
|
||||
InnerContext {
|
||||
value: "First value".to_owned(),
|
||||
},
|
||||
),
|
||||
(
|
||||
1,
|
||||
InnerContext {
|
||||
value: "Second value".to_owned(),
|
||||
},
|
||||
),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
};
|
||||
|
||||
let (result, errs) = ::execute(doc, None, &schema, &vars, &ctx).expect("Execution failed");
|
||||
|
||||
assert_eq!(errs, vec![
|
||||
ExecutionError::new(
|
||||
SourcePosition::new(25, 2, 12),
|
||||
&["missing"],
|
||||
FieldError::new("Could not find key 2", Value::null()),
|
||||
),
|
||||
]);
|
||||
assert_eq!(
|
||||
errs,
|
||||
vec![
|
||||
ExecutionError::new(
|
||||
SourcePosition::new(25, 2, 12),
|
||||
&["missing"],
|
||||
FieldError::new("Could not find key 2", Value::null()),
|
||||
),
|
||||
]
|
||||
);
|
||||
|
||||
println!("Result: {:?}", result);
|
||||
|
||||
|
@ -377,33 +467,55 @@ mod dynamic_context_switching {
|
|||
|
||||
let ctx = OuterContext {
|
||||
items: vec![
|
||||
(0, InnerContext { value: "First value".to_owned() }),
|
||||
(1, InnerContext { value: "Second value".to_owned() }),
|
||||
(
|
||||
0,
|
||||
InnerContext {
|
||||
value: "First value".to_owned(),
|
||||
},
|
||||
),
|
||||
(
|
||||
1,
|
||||
InnerContext {
|
||||
value: "Second value".to_owned(),
|
||||
},
|
||||
),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
};
|
||||
|
||||
let (result, errs) = ::execute(doc, None, &schema, &vars, &ctx).expect("Execution failed");
|
||||
|
||||
assert_eq!(errs, [
|
||||
ExecutionError::new(
|
||||
SourcePosition::new(123, 4, 12),
|
||||
&["tooLarge"],
|
||||
FieldError::new("Key too large: 200", Value::null()),
|
||||
),
|
||||
]);
|
||||
assert_eq!(
|
||||
errs,
|
||||
[
|
||||
ExecutionError::new(
|
||||
SourcePosition::new(123, 4, 12),
|
||||
&["tooLarge"],
|
||||
FieldError::new("Key too large: 200", Value::null()),
|
||||
),
|
||||
]
|
||||
);
|
||||
|
||||
println!("Result: {:?}", result);
|
||||
|
||||
assert_eq!(
|
||||
result,
|
||||
Value::object(vec![
|
||||
("first", Value::object(vec![
|
||||
("value", Value::string("First value")),
|
||||
].into_iter().collect())),
|
||||
("missing", Value::null()),
|
||||
("tooLarge", Value::null()),
|
||||
].into_iter().collect()));
|
||||
Value::object(
|
||||
vec![
|
||||
(
|
||||
"first",
|
||||
Value::object(
|
||||
vec![("value", Value::string("First value"))]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
),
|
||||
),
|
||||
("missing", Value::null()),
|
||||
("tooLarge", Value::null()),
|
||||
].into_iter()
|
||||
.collect()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -415,8 +527,18 @@ mod dynamic_context_switching {
|
|||
|
||||
let ctx = OuterContext {
|
||||
items: vec![
|
||||
(0, InnerContext { value: "First value".to_owned() }),
|
||||
(1, InnerContext { value: "Second value".to_owned() }),
|
||||
(
|
||||
0,
|
||||
InnerContext {
|
||||
value: "First value".to_owned(),
|
||||
},
|
||||
),
|
||||
(
|
||||
1,
|
||||
InnerContext {
|
||||
value: "Second value".to_owned(),
|
||||
},
|
||||
),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
};
|
||||
|
@ -429,11 +551,20 @@ mod dynamic_context_switching {
|
|||
|
||||
assert_eq!(
|
||||
result,
|
||||
Value::object(vec![
|
||||
("first", Value::object(vec![
|
||||
("value", Value::string("First value")),
|
||||
].into_iter().collect())),
|
||||
].into_iter().collect()));
|
||||
Value::object(
|
||||
vec![
|
||||
(
|
||||
"first",
|
||||
Value::object(
|
||||
vec![("value", Value::string("First value"))]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
),
|
||||
),
|
||||
].into_iter()
|
||||
.collect()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -473,7 +604,8 @@ mod propagates_errors_to_nullable_fields {
|
|||
|
||||
assert_eq!(
|
||||
result,
|
||||
graphql_value!({ "inner": { "nullableErrorField": None } }));
|
||||
graphql_value!({ "inner": { "nullableErrorField": None } })
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
errs,
|
||||
|
@ -483,7 +615,8 @@ mod propagates_errors_to_nullable_fields {
|
|||
&["inner", "nullableErrorField"],
|
||||
FieldError::new("Error for nullableErrorField", Value::null()),
|
||||
),
|
||||
]);
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -497,9 +630,7 @@ mod propagates_errors_to_nullable_fields {
|
|||
|
||||
println!("Result: {:?}", result);
|
||||
|
||||
assert_eq!(
|
||||
result,
|
||||
graphql_value!(None));
|
||||
assert_eq!(result, graphql_value!(None));
|
||||
|
||||
assert_eq!(
|
||||
errs,
|
||||
|
@ -509,7 +640,8 @@ mod propagates_errors_to_nullable_fields {
|
|||
&["inner", "nonNullableErrorField"],
|
||||
FieldError::new("Error for nonNullableErrorField", Value::null()),
|
||||
),
|
||||
]);
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -525,7 +657,8 @@ mod propagates_errors_to_nullable_fields {
|
|||
|
||||
assert_eq!(
|
||||
result,
|
||||
graphql_value!({ "inner": { "nullableField": None } }));
|
||||
graphql_value!({ "inner": { "nullableField": None } })
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
errs,
|
||||
|
@ -535,7 +668,8 @@ mod propagates_errors_to_nullable_fields {
|
|||
&["inner", "nullableField", "nonNullableErrorField"],
|
||||
FieldError::new("Error for nonNullableErrorField", Value::null()),
|
||||
),
|
||||
]);
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -549,9 +683,7 @@ mod propagates_errors_to_nullable_fields {
|
|||
|
||||
println!("Result: {:?}", result);
|
||||
|
||||
assert_eq!(
|
||||
result,
|
||||
graphql_value!(None));
|
||||
assert_eq!(result, graphql_value!(None));
|
||||
|
||||
assert_eq!(
|
||||
errs,
|
||||
|
@ -561,7 +693,8 @@ mod propagates_errors_to_nullable_fields {
|
|||
&["inner", "nonNullableField", "nonNullableErrorField"],
|
||||
FieldError::new("Error for nonNullableErrorField", Value::null()),
|
||||
),
|
||||
]);
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -577,7 +710,8 @@ mod propagates_errors_to_nullable_fields {
|
|||
|
||||
assert_eq!(
|
||||
result,
|
||||
graphql_value!({ "inner": { "nonNullableField": { "nullableErrorField": None } } }));
|
||||
graphql_value!({ "inner": { "nonNullableField": { "nullableErrorField": None } } })
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
errs,
|
||||
|
@ -587,7 +721,8 @@ mod propagates_errors_to_nullable_fields {
|
|||
&["inner", "nonNullableField", "nullableErrorField"],
|
||||
FieldError::new("Error for nullableErrorField", Value::null()),
|
||||
),
|
||||
]);
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -601,9 +736,7 @@ mod propagates_errors_to_nullable_fields {
|
|||
|
||||
println!("Result: {:?}", result);
|
||||
|
||||
assert_eq!(
|
||||
result,
|
||||
graphql_value!(None));
|
||||
assert_eq!(result, graphql_value!(None));
|
||||
|
||||
assert_eq!(
|
||||
errs,
|
||||
|
@ -613,7 +746,8 @@ mod propagates_errors_to_nullable_fields {
|
|||
&["inners", "nonNullableErrorField"],
|
||||
FieldError::new("Error for nonNullableErrorField", Value::null()),
|
||||
),
|
||||
]);
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -629,7 +763,8 @@ mod propagates_errors_to_nullable_fields {
|
|||
|
||||
assert_eq!(
|
||||
result,
|
||||
graphql_value!({ "nullableInners": [None, None, None, None, None] }));
|
||||
graphql_value!({ "nullableInners": [None, None, None, None, None] })
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
errs,
|
||||
|
@ -659,7 +794,8 @@ mod propagates_errors_to_nullable_fields {
|
|||
&["nullableInners", "nonNullableErrorField"],
|
||||
FieldError::new("Error for nonNullableErrorField", Value::null()),
|
||||
),
|
||||
]);
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -688,9 +824,8 @@ mod named_operations {
|
|||
|
||||
assert_eq!(
|
||||
result,
|
||||
Value::object(vec![
|
||||
("a", Value::string("b")),
|
||||
].into_iter().collect()));
|
||||
Value::object(vec![("a", Value::string("b"))].into_iter().collect())
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -706,9 +841,8 @@ mod named_operations {
|
|||
|
||||
assert_eq!(
|
||||
result,
|
||||
Value::object(vec![
|
||||
("a", Value::string("b")),
|
||||
].into_iter().collect()));
|
||||
Value::object(vec![("a", Value::string("b"))].into_iter().collect())
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -725,9 +859,8 @@ mod named_operations {
|
|||
|
||||
assert_eq!(
|
||||
result,
|
||||
Value::object(vec![
|
||||
("second", Value::string("b")),
|
||||
].into_iter().collect()));
|
||||
Value::object(vec![("second", Value::string("b"))].into_iter().collect())
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -80,8 +80,14 @@ mod interface {
|
|||
let schema = RootNode::new(
|
||||
Schema {
|
||||
pets: vec![
|
||||
Box::new(Dog { name: "Odie".to_owned(), woofs: true }),
|
||||
Box::new(Cat { name: "Garfield".to_owned(), meows: false }),
|
||||
Box::new(Dog {
|
||||
name: "Odie".to_owned(),
|
||||
woofs: true,
|
||||
}),
|
||||
Box::new(Cat {
|
||||
name: "Garfield".to_owned(),
|
||||
meows: false,
|
||||
}),
|
||||
],
|
||||
},
|
||||
EmptyMutation::<()>::new(),
|
||||
|
@ -109,24 +115,34 @@ mod interface {
|
|||
|
||||
assert_eq!(
|
||||
result,
|
||||
Value::object(vec![
|
||||
("pets", Value::list(vec![
|
||||
Value::object(vec![
|
||||
("name", Value::string("Odie")),
|
||||
("woofs", Value::boolean(true)),
|
||||
].into_iter().collect()),
|
||||
Value::object(vec![
|
||||
("name", Value::string("Garfield")),
|
||||
("meows", Value::boolean(false)),
|
||||
].into_iter().collect()),
|
||||
])),
|
||||
].into_iter().collect()));
|
||||
Value::object(
|
||||
vec![
|
||||
(
|
||||
"pets",
|
||||
Value::list(vec![
|
||||
Value::object(
|
||||
vec![
|
||||
("name", Value::string("Odie")),
|
||||
("woofs", Value::boolean(true)),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
Value::object(
|
||||
vec![
|
||||
("name", Value::string("Garfield")),
|
||||
("meows", Value::boolean(false)),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
]),
|
||||
),
|
||||
].into_iter()
|
||||
.collect()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
mod union {
|
||||
use value::Value;
|
||||
use schema::model::RootNode;
|
||||
|
@ -195,8 +211,14 @@ mod union {
|
|||
let schema = RootNode::new(
|
||||
Schema {
|
||||
pets: vec![
|
||||
Box::new(Dog { name: "Odie".to_owned(), woofs: true }),
|
||||
Box::new(Cat { name: "Garfield".to_owned(), meows: false }),
|
||||
Box::new(Dog {
|
||||
name: "Odie".to_owned(),
|
||||
woofs: true,
|
||||
}),
|
||||
Box::new(Cat {
|
||||
name: "Garfield".to_owned(),
|
||||
meows: false,
|
||||
}),
|
||||
],
|
||||
},
|
||||
EmptyMutation::<()>::new(),
|
||||
|
@ -226,19 +248,32 @@ mod union {
|
|||
|
||||
assert_eq!(
|
||||
result,
|
||||
Value::object(vec![
|
||||
("pets", Value::list(vec![
|
||||
Value::object(vec![
|
||||
("__typename", Value::string("Dog")),
|
||||
("name", Value::string("Odie")),
|
||||
("woofs", Value::boolean(true)),
|
||||
].into_iter().collect()),
|
||||
Value::object(vec![
|
||||
("__typename", Value::string("Cat")),
|
||||
("name", Value::string("Garfield")),
|
||||
("meows", Value::boolean(false)),
|
||||
].into_iter().collect()),
|
||||
])),
|
||||
].into_iter().collect()));
|
||||
Value::object(
|
||||
vec![
|
||||
(
|
||||
"pets",
|
||||
Value::list(vec![
|
||||
Value::object(
|
||||
vec![
|
||||
("__typename", Value::string("Dog")),
|
||||
("name", Value::string("Odie")),
|
||||
("woofs", Value::boolean(true)),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
Value::object(
|
||||
vec![
|
||||
("__typename", Value::string("Cat")),
|
||||
("name", Value::string("Garfield")),
|
||||
("meows", Value::boolean(false)),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
]),
|
||||
),
|
||||
].into_iter()
|
||||
.collect()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,19 +48,15 @@ enum EnumDescription {
|
|||
#[derive(GraphQLEnum)]
|
||||
#[graphql(_internal)]
|
||||
enum EnumValueDescription {
|
||||
#[graphql(description = "The FOO value")]
|
||||
Foo,
|
||||
#[graphql(description = "The BAR value")]
|
||||
Bar,
|
||||
#[graphql(description = "The FOO value")] Foo,
|
||||
#[graphql(description = "The BAR value")] Bar,
|
||||
}
|
||||
|
||||
#[derive(GraphQLEnum)]
|
||||
#[graphql(_internal)]
|
||||
enum EnumDeprecation {
|
||||
#[graphql(deprecated = "Please don't use FOO any more")]
|
||||
Foo,
|
||||
#[graphql(description = "The BAR value", deprecated = "Please don't use BAR any more")]
|
||||
Bar,
|
||||
#[graphql(deprecated = "Please don't use FOO any more")] Foo,
|
||||
#[graphql(description = "The BAR value", deprecated = "Please don't use BAR any more")] Bar,
|
||||
}
|
||||
|
||||
struct Root;
|
||||
|
@ -127,19 +123,29 @@ fn default_name_introspection() {
|
|||
|
||||
assert_eq!(values.len(), 2);
|
||||
|
||||
assert!(values.contains(&Value::object(vec![
|
||||
("name", Value::string("FOO")),
|
||||
("description", Value::null()),
|
||||
("isDeprecated", Value::boolean(false)),
|
||||
("deprecationReason", Value::null()),
|
||||
].into_iter().collect())));
|
||||
assert!(
|
||||
values.contains(&Value::object(
|
||||
vec![
|
||||
("name", Value::string("FOO")),
|
||||
("description", Value::null()),
|
||||
("isDeprecated", Value::boolean(false)),
|
||||
("deprecationReason", Value::null()),
|
||||
].into_iter()
|
||||
.collect()
|
||||
))
|
||||
);
|
||||
|
||||
assert!(values.contains(&Value::object(vec![
|
||||
("name", Value::string("BAR")),
|
||||
("description", Value::null()),
|
||||
("isDeprecated", Value::boolean(false)),
|
||||
("deprecationReason", Value::null()),
|
||||
].into_iter().collect())));
|
||||
assert!(
|
||||
values.contains(&Value::object(
|
||||
vec![
|
||||
("name", Value::string("BAR")),
|
||||
("description", Value::null()),
|
||||
("isDeprecated", Value::boolean(false)),
|
||||
("deprecationReason", Value::null()),
|
||||
].into_iter()
|
||||
.collect()
|
||||
))
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -166,19 +172,29 @@ fn named_introspection() {
|
|||
|
||||
assert_eq!(values.len(), 2);
|
||||
|
||||
assert!(values.contains(&Value::object(vec![
|
||||
("name", Value::string("FOO")),
|
||||
("description", Value::null()),
|
||||
("isDeprecated", Value::boolean(false)),
|
||||
("deprecationReason", Value::null()),
|
||||
].into_iter().collect())));
|
||||
assert!(
|
||||
values.contains(&Value::object(
|
||||
vec![
|
||||
("name", Value::string("FOO")),
|
||||
("description", Value::null()),
|
||||
("isDeprecated", Value::boolean(false)),
|
||||
("deprecationReason", Value::null()),
|
||||
].into_iter()
|
||||
.collect()
|
||||
))
|
||||
);
|
||||
|
||||
assert!(values.contains(&Value::object(vec![
|
||||
("name", Value::string("BAR")),
|
||||
("description", Value::null()),
|
||||
("isDeprecated", Value::boolean(false)),
|
||||
("deprecationReason", Value::null()),
|
||||
].into_iter().collect())));
|
||||
assert!(
|
||||
values.contains(&Value::object(
|
||||
vec![
|
||||
("name", Value::string("BAR")),
|
||||
("description", Value::null()),
|
||||
("isDeprecated", Value::boolean(false)),
|
||||
("deprecationReason", Value::null()),
|
||||
].into_iter()
|
||||
.collect()
|
||||
))
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -200,24 +216,37 @@ fn no_trailing_comma_introspection() {
|
|||
"#;
|
||||
|
||||
run_type_info_query(doc, |(type_info, values)| {
|
||||
assert_eq!(type_info.get("name"), Some(&Value::string("NoTrailingComma")));
|
||||
assert_eq!(
|
||||
type_info.get("name"),
|
||||
Some(&Value::string("NoTrailingComma"))
|
||||
);
|
||||
assert_eq!(type_info.get("description"), Some(&Value::null()));
|
||||
|
||||
assert_eq!(values.len(), 2);
|
||||
|
||||
assert!(values.contains(&Value::object(vec![
|
||||
("name", Value::string("FOO")),
|
||||
("description", Value::null()),
|
||||
("isDeprecated", Value::boolean(false)),
|
||||
("deprecationReason", Value::null()),
|
||||
].into_iter().collect())));
|
||||
assert!(
|
||||
values.contains(&Value::object(
|
||||
vec![
|
||||
("name", Value::string("FOO")),
|
||||
("description", Value::null()),
|
||||
("isDeprecated", Value::boolean(false)),
|
||||
("deprecationReason", Value::null()),
|
||||
].into_iter()
|
||||
.collect()
|
||||
))
|
||||
);
|
||||
|
||||
assert!(values.contains(&Value::object(vec![
|
||||
("name", Value::string("BAR")),
|
||||
("description", Value::null()),
|
||||
("isDeprecated", Value::boolean(false)),
|
||||
("deprecationReason", Value::null()),
|
||||
].into_iter().collect())));
|
||||
assert!(
|
||||
values.contains(&Value::object(
|
||||
vec![
|
||||
("name", Value::string("BAR")),
|
||||
("description", Value::null()),
|
||||
("isDeprecated", Value::boolean(false)),
|
||||
("deprecationReason", Value::null()),
|
||||
].into_iter()
|
||||
.collect()
|
||||
))
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -239,24 +268,40 @@ fn enum_description_introspection() {
|
|||
"#;
|
||||
|
||||
run_type_info_query(doc, |(type_info, values)| {
|
||||
assert_eq!(type_info.get("name"), Some(&Value::string("EnumDescription")));
|
||||
assert_eq!(type_info.get("description"), Some(&Value::string("A description of the enum itself")));
|
||||
assert_eq!(
|
||||
type_info.get("name"),
|
||||
Some(&Value::string("EnumDescription"))
|
||||
);
|
||||
assert_eq!(
|
||||
type_info.get("description"),
|
||||
Some(&Value::string("A description of the enum itself"))
|
||||
);
|
||||
|
||||
assert_eq!(values.len(), 2);
|
||||
|
||||
assert!(values.contains(&Value::object(vec![
|
||||
("name", Value::string("FOO")),
|
||||
("description", Value::null()),
|
||||
("isDeprecated", Value::boolean(false)),
|
||||
("deprecationReason", Value::null()),
|
||||
].into_iter().collect())));
|
||||
assert!(
|
||||
values.contains(&Value::object(
|
||||
vec![
|
||||
("name", Value::string("FOO")),
|
||||
("description", Value::null()),
|
||||
("isDeprecated", Value::boolean(false)),
|
||||
("deprecationReason", Value::null()),
|
||||
].into_iter()
|
||||
.collect()
|
||||
))
|
||||
);
|
||||
|
||||
assert!(values.contains(&Value::object(vec![
|
||||
("name", Value::string("BAR")),
|
||||
("description", Value::null()),
|
||||
("isDeprecated", Value::boolean(false)),
|
||||
("deprecationReason", Value::null()),
|
||||
].into_iter().collect())));
|
||||
assert!(
|
||||
values.contains(&Value::object(
|
||||
vec![
|
||||
("name", Value::string("BAR")),
|
||||
("description", Value::null()),
|
||||
("isDeprecated", Value::boolean(false)),
|
||||
("deprecationReason", Value::null()),
|
||||
].into_iter()
|
||||
.collect()
|
||||
))
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -278,24 +323,37 @@ fn enum_value_description_introspection() {
|
|||
"#;
|
||||
|
||||
run_type_info_query(doc, |(type_info, values)| {
|
||||
assert_eq!(type_info.get("name"), Some(&Value::string("EnumValueDescription")));
|
||||
assert_eq!(
|
||||
type_info.get("name"),
|
||||
Some(&Value::string("EnumValueDescription"))
|
||||
);
|
||||
assert_eq!(type_info.get("description"), Some(&Value::null()));
|
||||
|
||||
assert_eq!(values.len(), 2);
|
||||
|
||||
assert!(values.contains(&Value::object(vec![
|
||||
("name", Value::string("FOO")),
|
||||
("description", Value::string("The FOO value")),
|
||||
("isDeprecated", Value::boolean(false)),
|
||||
("deprecationReason", Value::null()),
|
||||
].into_iter().collect())));
|
||||
assert!(
|
||||
values.contains(&Value::object(
|
||||
vec![
|
||||
("name", Value::string("FOO")),
|
||||
("description", Value::string("The FOO value")),
|
||||
("isDeprecated", Value::boolean(false)),
|
||||
("deprecationReason", Value::null()),
|
||||
].into_iter()
|
||||
.collect()
|
||||
))
|
||||
);
|
||||
|
||||
assert!(values.contains(&Value::object(vec![
|
||||
("name", Value::string("BAR")),
|
||||
("description", Value::string("The BAR value")),
|
||||
("isDeprecated", Value::boolean(false)),
|
||||
("deprecationReason", Value::null()),
|
||||
].into_iter().collect())));
|
||||
assert!(
|
||||
values.contains(&Value::object(
|
||||
vec![
|
||||
("name", Value::string("BAR")),
|
||||
("description", Value::string("The BAR value")),
|
||||
("isDeprecated", Value::boolean(false)),
|
||||
("deprecationReason", Value::null()),
|
||||
].into_iter()
|
||||
.collect()
|
||||
))
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -317,24 +375,43 @@ fn enum_deprecation_introspection() {
|
|||
"#;
|
||||
|
||||
run_type_info_query(doc, |(type_info, values)| {
|
||||
assert_eq!(type_info.get("name"), Some(&Value::string("EnumDeprecation")));
|
||||
assert_eq!(
|
||||
type_info.get("name"),
|
||||
Some(&Value::string("EnumDeprecation"))
|
||||
);
|
||||
assert_eq!(type_info.get("description"), Some(&Value::null()));
|
||||
|
||||
assert_eq!(values.len(), 2);
|
||||
|
||||
assert!(values.contains(&Value::object(vec![
|
||||
("name", Value::string("FOO")),
|
||||
("description", Value::null()),
|
||||
("isDeprecated", Value::boolean(true)),
|
||||
("deprecationReason", Value::string("Please don't use FOO any more")),
|
||||
].into_iter().collect())));
|
||||
assert!(
|
||||
values.contains(&Value::object(
|
||||
vec![
|
||||
("name", Value::string("FOO")),
|
||||
("description", Value::null()),
|
||||
("isDeprecated", Value::boolean(true)),
|
||||
(
|
||||
"deprecationReason",
|
||||
Value::string("Please don't use FOO any more"),
|
||||
),
|
||||
].into_iter()
|
||||
.collect()
|
||||
))
|
||||
);
|
||||
|
||||
assert!(values.contains(&Value::object(vec![
|
||||
("name", Value::string("BAR")),
|
||||
("description", Value::string("The BAR value")),
|
||||
("isDeprecated", Value::boolean(true)),
|
||||
("deprecationReason", Value::string("Please don't use BAR any more")),
|
||||
].into_iter().collect())));
|
||||
assert!(
|
||||
values.contains(&Value::object(
|
||||
vec![
|
||||
("name", Value::string("BAR")),
|
||||
("description", Value::string("The BAR value")),
|
||||
("isDeprecated", Value::boolean(true)),
|
||||
(
|
||||
"deprecationReason",
|
||||
Value::string("Please don't use BAR any more"),
|
||||
),
|
||||
].into_iter()
|
||||
.collect()
|
||||
))
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -356,7 +433,10 @@ fn enum_deprecation_no_values_introspection() {
|
|||
"#;
|
||||
|
||||
run_type_info_query(doc, |(type_info, values)| {
|
||||
assert_eq!(type_info.get("name"), Some(&Value::string("EnumDeprecation")));
|
||||
assert_eq!(
|
||||
type_info.get("name"),
|
||||
Some(&Value::string("EnumDeprecation"))
|
||||
);
|
||||
assert_eq!(type_info.get("description"), Some(&Value::null()));
|
||||
|
||||
assert_eq!(values.len(), 0);
|
||||
|
|
|
@ -19,7 +19,7 @@ struct DefaultName {
|
|||
#[graphql(_internal)]
|
||||
struct NoTrailingComma {
|
||||
field_one: String,
|
||||
field_two: String
|
||||
field_two: String,
|
||||
}
|
||||
|
||||
#[derive(GraphQLInputObject, Debug)]
|
||||
|
@ -54,8 +54,7 @@ pub struct PublicWithDescription {
|
|||
|
||||
#[derive(GraphQLInputObject, Debug)]
|
||||
#[graphql(name = "APublicNamedInputObjectWithDescription",
|
||||
description = "Description for the input object",
|
||||
_internal)]
|
||||
description = "Description for the input object", _internal)]
|
||||
pub struct NamedPublicWithDescription {
|
||||
field_one: String,
|
||||
}
|
||||
|
@ -69,19 +68,15 @@ pub struct NamedPublic {
|
|||
#[derive(GraphQLInputObject, Debug)]
|
||||
#[graphql(_internal)]
|
||||
struct FieldDescription {
|
||||
#[graphql(description = "The first field")]
|
||||
field_one: String,
|
||||
#[graphql(description = "The second field")]
|
||||
field_two: String,
|
||||
#[graphql(description = "The first field")] field_one: String,
|
||||
#[graphql(description = "The second field")] field_two: String,
|
||||
}
|
||||
|
||||
#[derive(GraphQLInputObject, Debug)]
|
||||
#[graphql(_internal)]
|
||||
struct FieldWithDefaults {
|
||||
#[graphql(default = "123")]
|
||||
field_one: i32,
|
||||
#[graphql(default = "456", description = "The second field")]
|
||||
field_two: i32,
|
||||
#[graphql(default = "123")] field_one: i32,
|
||||
#[graphql(default = "456", description = "The second field")] field_two: i32,
|
||||
}
|
||||
|
||||
graphql_object!(Root: () |&self| {
|
||||
|
@ -159,27 +154,59 @@ fn default_name_introspection() {
|
|||
|
||||
assert_eq!(fields.len(), 2);
|
||||
|
||||
assert!(fields.contains(&Value::object(vec![
|
||||
("name", Value::string("fieldOne")),
|
||||
("description", Value::null()),
|
||||
("type", Value::object(vec![
|
||||
("ofType", Value::object(vec![
|
||||
("name", Value::string("String")),
|
||||
].into_iter().collect())),
|
||||
].into_iter().collect())),
|
||||
("defaultValue", Value::null()),
|
||||
].into_iter().collect())));
|
||||
assert!(
|
||||
fields.contains(&Value::object(
|
||||
vec![
|
||||
("name", Value::string("fieldOne")),
|
||||
("description", Value::null()),
|
||||
(
|
||||
"type",
|
||||
Value::object(
|
||||
vec![
|
||||
(
|
||||
"ofType",
|
||||
Value::object(
|
||||
vec![("name", Value::string("String"))]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
),
|
||||
),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
),
|
||||
("defaultValue", Value::null()),
|
||||
].into_iter()
|
||||
.collect()
|
||||
))
|
||||
);
|
||||
|
||||
assert!(fields.contains(&Value::object(vec![
|
||||
("name", Value::string("fieldTwo")),
|
||||
("description", Value::null()),
|
||||
("type", Value::object(vec![
|
||||
("ofType", Value::object(vec![
|
||||
("name", Value::string("String")),
|
||||
].into_iter().collect())),
|
||||
].into_iter().collect())),
|
||||
("defaultValue", Value::null()),
|
||||
].into_iter().collect())));
|
||||
assert!(
|
||||
fields.contains(&Value::object(
|
||||
vec![
|
||||
("name", Value::string("fieldTwo")),
|
||||
("description", Value::null()),
|
||||
(
|
||||
"type",
|
||||
Value::object(
|
||||
vec![
|
||||
(
|
||||
"ofType",
|
||||
Value::object(
|
||||
vec![("name", Value::string("String"))]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
),
|
||||
),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
),
|
||||
("defaultValue", Value::null()),
|
||||
].into_iter()
|
||||
.collect()
|
||||
))
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -187,9 +214,9 @@ fn default_name_introspection() {
|
|||
fn default_name_input_value() {
|
||||
let iv = InputValue::object(
|
||||
vec![
|
||||
("fieldOne", InputValue::string("number one")),
|
||||
("fieldTwo", InputValue::string("number two")),
|
||||
].into_iter()
|
||||
("fieldOne", InputValue::string("number one")),
|
||||
("fieldTwo", InputValue::string("number two")),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
);
|
||||
|
||||
|
@ -225,32 +252,67 @@ fn no_trailing_comma_introspection() {
|
|||
"#;
|
||||
|
||||
run_type_info_query(doc, |type_info, fields| {
|
||||
assert_eq!(type_info.get("name"), Some(&Value::string("NoTrailingComma")));
|
||||
assert_eq!(
|
||||
type_info.get("name"),
|
||||
Some(&Value::string("NoTrailingComma"))
|
||||
);
|
||||
assert_eq!(type_info.get("description"), Some(&Value::null()));
|
||||
|
||||
assert_eq!(fields.len(), 2);
|
||||
|
||||
assert!(fields.contains(&Value::object(vec![
|
||||
("name", Value::string("fieldOne")),
|
||||
("description", Value::null()),
|
||||
("type", Value::object(vec![
|
||||
("ofType", Value::object(vec![
|
||||
("name", Value::string("String")),
|
||||
].into_iter().collect())),
|
||||
].into_iter().collect())),
|
||||
("defaultValue", Value::null()),
|
||||
].into_iter().collect())));
|
||||
assert!(
|
||||
fields.contains(&Value::object(
|
||||
vec![
|
||||
("name", Value::string("fieldOne")),
|
||||
("description", Value::null()),
|
||||
(
|
||||
"type",
|
||||
Value::object(
|
||||
vec![
|
||||
(
|
||||
"ofType",
|
||||
Value::object(
|
||||
vec![("name", Value::string("String"))]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
),
|
||||
),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
),
|
||||
("defaultValue", Value::null()),
|
||||
].into_iter()
|
||||
.collect()
|
||||
))
|
||||
);
|
||||
|
||||
assert!(fields.contains(&Value::object(vec![
|
||||
("name", Value::string("fieldTwo")),
|
||||
("description", Value::null()),
|
||||
("type", Value::object(vec![
|
||||
("ofType", Value::object(vec![
|
||||
("name", Value::string("String")),
|
||||
].into_iter().collect())),
|
||||
].into_iter().collect())),
|
||||
("defaultValue", Value::null()),
|
||||
].into_iter().collect())));
|
||||
assert!(
|
||||
fields.contains(&Value::object(
|
||||
vec![
|
||||
("name", Value::string("fieldTwo")),
|
||||
("description", Value::null()),
|
||||
(
|
||||
"type",
|
||||
Value::object(
|
||||
vec![
|
||||
(
|
||||
"ofType",
|
||||
Value::object(
|
||||
vec![("name", Value::string("String"))]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
),
|
||||
),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
),
|
||||
("defaultValue", Value::null()),
|
||||
].into_iter()
|
||||
.collect()
|
||||
))
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -281,23 +343,44 @@ fn derive_introspection() {
|
|||
|
||||
assert_eq!(fields.len(), 1);
|
||||
|
||||
assert!(fields.contains(&Value::object(vec![
|
||||
("name", Value::string("fieldOne")),
|
||||
("description", Value::null()),
|
||||
("type", Value::object(vec![
|
||||
("ofType", Value::object(vec![
|
||||
("name", Value::string("String")),
|
||||
].into_iter().collect())),
|
||||
].into_iter().collect())),
|
||||
("defaultValue", Value::null()),
|
||||
].into_iter().collect())));
|
||||
assert!(
|
||||
fields.contains(&Value::object(
|
||||
vec![
|
||||
("name", Value::string("fieldOne")),
|
||||
("description", Value::null()),
|
||||
(
|
||||
"type",
|
||||
Value::object(
|
||||
vec![
|
||||
(
|
||||
"ofType",
|
||||
Value::object(
|
||||
vec![("name", Value::string("String"))]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
),
|
||||
),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
),
|
||||
("defaultValue", Value::null()),
|
||||
].into_iter()
|
||||
.collect()
|
||||
))
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn derive_derived() {
|
||||
assert_eq!(
|
||||
format!("{:?}", Derive { field_one: "test".to_owned() }),
|
||||
format!(
|
||||
"{:?}",
|
||||
Derive {
|
||||
field_one: "test".to_owned(),
|
||||
}
|
||||
),
|
||||
"Derive { field_one: \"test\" }"
|
||||
);
|
||||
}
|
||||
|
@ -324,21 +407,40 @@ fn named_introspection() {
|
|||
"#;
|
||||
|
||||
run_type_info_query(doc, |type_info, fields| {
|
||||
assert_eq!(type_info.get("name"), Some(&Value::string("ANamedInputObject")));
|
||||
assert_eq!(
|
||||
type_info.get("name"),
|
||||
Some(&Value::string("ANamedInputObject"))
|
||||
);
|
||||
assert_eq!(type_info.get("description"), Some(&Value::null()));
|
||||
|
||||
assert_eq!(fields.len(), 1);
|
||||
|
||||
assert!(fields.contains(&Value::object(vec![
|
||||
("name", Value::string("fieldOne")),
|
||||
("description", Value::null()),
|
||||
("type", Value::object(vec![
|
||||
("ofType", Value::object(vec![
|
||||
("name", Value::string("String")),
|
||||
].into_iter().collect())),
|
||||
].into_iter().collect())),
|
||||
("defaultValue", Value::null()),
|
||||
].into_iter().collect())));
|
||||
assert!(
|
||||
fields.contains(&Value::object(
|
||||
vec![
|
||||
("name", Value::string("fieldOne")),
|
||||
("description", Value::null()),
|
||||
(
|
||||
"type",
|
||||
Value::object(
|
||||
vec![
|
||||
(
|
||||
"ofType",
|
||||
Value::object(
|
||||
vec![("name", Value::string("String"))]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
),
|
||||
),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
),
|
||||
("defaultValue", Value::null()),
|
||||
].into_iter()
|
||||
.collect()
|
||||
))
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -365,20 +467,39 @@ fn description_introspection() {
|
|||
|
||||
run_type_info_query(doc, |type_info, fields| {
|
||||
assert_eq!(type_info.get("name"), Some(&Value::string("Description")));
|
||||
assert_eq!(type_info.get("description"), Some(&Value::string("Description for the input object")));
|
||||
assert_eq!(
|
||||
type_info.get("description"),
|
||||
Some(&Value::string("Description for the input object"))
|
||||
);
|
||||
|
||||
assert_eq!(fields.len(), 1);
|
||||
|
||||
assert!(fields.contains(&Value::object(vec![
|
||||
("name", Value::string("fieldOne")),
|
||||
("description", Value::null()),
|
||||
("type", Value::object(vec![
|
||||
("ofType", Value::object(vec![
|
||||
("name", Value::string("String")),
|
||||
].into_iter().collect())),
|
||||
].into_iter().collect())),
|
||||
("defaultValue", Value::null()),
|
||||
].into_iter().collect())));
|
||||
assert!(
|
||||
fields.contains(&Value::object(
|
||||
vec![
|
||||
("name", Value::string("fieldOne")),
|
||||
("description", Value::null()),
|
||||
(
|
||||
"type",
|
||||
Value::object(
|
||||
vec![
|
||||
(
|
||||
"ofType",
|
||||
Value::object(
|
||||
vec![("name", Value::string("String"))]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
),
|
||||
),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
),
|
||||
("defaultValue", Value::null()),
|
||||
].into_iter()
|
||||
.collect()
|
||||
))
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -404,32 +525,67 @@ fn field_description_introspection() {
|
|||
"#;
|
||||
|
||||
run_type_info_query(doc, |type_info, fields| {
|
||||
assert_eq!(type_info.get("name"), Some(&Value::string("FieldDescription")));
|
||||
assert_eq!(
|
||||
type_info.get("name"),
|
||||
Some(&Value::string("FieldDescription"))
|
||||
);
|
||||
assert_eq!(type_info.get("description"), Some(&Value::null()));
|
||||
|
||||
assert_eq!(fields.len(), 2);
|
||||
|
||||
assert!(fields.contains(&Value::object(vec![
|
||||
("name", Value::string("fieldOne")),
|
||||
("description", Value::string("The first field")),
|
||||
("type", Value::object(vec![
|
||||
("ofType", Value::object(vec![
|
||||
("name", Value::string("String")),
|
||||
].into_iter().collect())),
|
||||
].into_iter().collect())),
|
||||
("defaultValue", Value::null()),
|
||||
].into_iter().collect())));
|
||||
assert!(
|
||||
fields.contains(&Value::object(
|
||||
vec![
|
||||
("name", Value::string("fieldOne")),
|
||||
("description", Value::string("The first field")),
|
||||
(
|
||||
"type",
|
||||
Value::object(
|
||||
vec![
|
||||
(
|
||||
"ofType",
|
||||
Value::object(
|
||||
vec![("name", Value::string("String"))]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
),
|
||||
),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
),
|
||||
("defaultValue", Value::null()),
|
||||
].into_iter()
|
||||
.collect()
|
||||
))
|
||||
);
|
||||
|
||||
assert!(fields.contains(&Value::object(vec![
|
||||
("name", Value::string("fieldTwo")),
|
||||
("description", Value::string("The second field")),
|
||||
("type", Value::object(vec![
|
||||
("ofType", Value::object(vec![
|
||||
("name", Value::string("String")),
|
||||
].into_iter().collect())),
|
||||
].into_iter().collect())),
|
||||
("defaultValue", Value::null()),
|
||||
].into_iter().collect())));
|
||||
assert!(
|
||||
fields.contains(&Value::object(
|
||||
vec![
|
||||
("name", Value::string("fieldTwo")),
|
||||
("description", Value::string("The second field")),
|
||||
(
|
||||
"type",
|
||||
Value::object(
|
||||
vec![
|
||||
(
|
||||
"ofType",
|
||||
Value::object(
|
||||
vec![("name", Value::string("String"))]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
),
|
||||
),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
),
|
||||
("defaultValue", Value::null()),
|
||||
].into_iter()
|
||||
.collect()
|
||||
))
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -451,24 +607,39 @@ fn field_with_defaults_introspection() {
|
|||
"#;
|
||||
|
||||
run_type_info_query(doc, |type_info, fields| {
|
||||
assert_eq!(type_info.get("name"), Some(&Value::string("FieldWithDefaults")));
|
||||
assert_eq!(
|
||||
type_info.get("name"),
|
||||
Some(&Value::string("FieldWithDefaults"))
|
||||
);
|
||||
|
||||
assert_eq!(fields.len(), 2);
|
||||
|
||||
assert!(fields.contains(&Value::object(vec![
|
||||
("name", Value::string("fieldOne")),
|
||||
("type", Value::object(vec![
|
||||
("name", Value::string("Int")),
|
||||
].into_iter().collect())),
|
||||
("defaultValue", Value::string("123")),
|
||||
].into_iter().collect())));
|
||||
assert!(
|
||||
fields.contains(&Value::object(
|
||||
vec![
|
||||
("name", Value::string("fieldOne")),
|
||||
(
|
||||
"type",
|
||||
Value::object(vec![("name", Value::string("Int"))].into_iter().collect()),
|
||||
),
|
||||
("defaultValue", Value::string("123")),
|
||||
].into_iter()
|
||||
.collect()
|
||||
))
|
||||
);
|
||||
|
||||
assert!(fields.contains(&Value::object(vec![
|
||||
("name", Value::string("fieldTwo")),
|
||||
("type", Value::object(vec![
|
||||
("name", Value::string("Int")),
|
||||
].into_iter().collect())),
|
||||
("defaultValue", Value::string("456")),
|
||||
].into_iter().collect())));
|
||||
assert!(
|
||||
fields.contains(&Value::object(
|
||||
vec![
|
||||
("name", Value::string("fieldTwo")),
|
||||
(
|
||||
"type",
|
||||
Value::object(vec![("name", Value::string("Int"))].into_iter().collect()),
|
||||
),
|
||||
("defaultValue", Value::string("456")),
|
||||
].into_iter()
|
||||
.collect()
|
||||
))
|
||||
);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -80,11 +80,17 @@ fn test_execution() {
|
|||
|
||||
println!("Result: {:?}", result);
|
||||
|
||||
assert_eq!(result, Value::object(vec![
|
||||
("sampleEnum", Value::string("ONE")),
|
||||
("first", Value::int(123)),
|
||||
("second", Value::int(30)),
|
||||
].into_iter().collect()));
|
||||
assert_eq!(
|
||||
result,
|
||||
Value::object(
|
||||
vec![
|
||||
("sampleEnum", Value::string("ONE")),
|
||||
("first", Value::int(123)),
|
||||
("second", Value::int(30)),
|
||||
].into_iter()
|
||||
.collect()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -141,19 +147,29 @@ fn enum_introspection() {
|
|||
|
||||
assert_eq!(values.len(), 2);
|
||||
|
||||
assert!(values.contains(&Value::object(vec![
|
||||
("name", Value::string("ONE")),
|
||||
("description", Value::null()),
|
||||
("isDeprecated", Value::boolean(false)),
|
||||
("deprecationReason", Value::null()),
|
||||
].into_iter().collect())));
|
||||
assert!(
|
||||
values.contains(&Value::object(
|
||||
vec![
|
||||
("name", Value::string("ONE")),
|
||||
("description", Value::null()),
|
||||
("isDeprecated", Value::boolean(false)),
|
||||
("deprecationReason", Value::null()),
|
||||
].into_iter()
|
||||
.collect()
|
||||
))
|
||||
);
|
||||
|
||||
assert!(values.contains(&Value::object(vec![
|
||||
("name", Value::string("TWO")),
|
||||
("description", Value::null()),
|
||||
("isDeprecated", Value::boolean(false)),
|
||||
("deprecationReason", Value::null()),
|
||||
].into_iter().collect())));
|
||||
assert!(
|
||||
values.contains(&Value::object(
|
||||
vec![
|
||||
("name", Value::string("TWO")),
|
||||
("description", Value::null()),
|
||||
("isDeprecated", Value::boolean(false)),
|
||||
("deprecationReason", Value::null()),
|
||||
].into_iter()
|
||||
.collect()
|
||||
))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -208,9 +224,15 @@ fn interface_introspection() {
|
|||
.as_object_value()
|
||||
.expect("__type field not an object value");
|
||||
|
||||
assert_eq!(type_info.get("name"), Some(&Value::string("SampleInterface")));
|
||||
assert_eq!(
|
||||
type_info.get("name"),
|
||||
Some(&Value::string("SampleInterface"))
|
||||
);
|
||||
assert_eq!(type_info.get("kind"), Some(&Value::string("INTERFACE")));
|
||||
assert_eq!(type_info.get("description"), Some(&Value::string("A sample interface")));
|
||||
assert_eq!(
|
||||
type_info.get("description"),
|
||||
Some(&Value::string("A sample interface"))
|
||||
);
|
||||
assert_eq!(type_info.get("interfaces"), Some(&Value::null()));
|
||||
assert_eq!(type_info.get("enumValues"), Some(&Value::null()));
|
||||
assert_eq!(type_info.get("inputFields"), Some(&Value::null()));
|
||||
|
@ -224,9 +246,9 @@ fn interface_introspection() {
|
|||
|
||||
assert_eq!(possible_types.len(), 1);
|
||||
|
||||
assert!(possible_types.contains(&Value::object(vec![
|
||||
("name", Value::string("Root")),
|
||||
].into_iter().collect())));
|
||||
assert!(possible_types.contains(&Value::object(
|
||||
vec![("name", Value::string("Root"))].into_iter().collect()
|
||||
)));
|
||||
|
||||
let fields = type_info
|
||||
.get("fields")
|
||||
|
@ -236,21 +258,41 @@ fn interface_introspection() {
|
|||
|
||||
assert_eq!(fields.len(), 1);
|
||||
|
||||
assert!(fields.contains(&Value::object(vec![
|
||||
("name", Value::string("sampleEnum")),
|
||||
("description", Value::string("A sample field in the interface")),
|
||||
("args", Value::list(vec![])),
|
||||
("type", Value::object(vec![
|
||||
("name", Value::null()),
|
||||
("kind", Value::string("NON_NULL")),
|
||||
("ofType", Value::object(vec![
|
||||
("name", Value::string("SampleEnum")),
|
||||
("kind", Value::string("ENUM")),
|
||||
].into_iter().collect())),
|
||||
].into_iter().collect())),
|
||||
("isDeprecated", Value::boolean(false)),
|
||||
("deprecationReason", Value::null()),
|
||||
].into_iter().collect())));
|
||||
assert!(
|
||||
fields.contains(&Value::object(
|
||||
vec![
|
||||
("name", Value::string("sampleEnum")),
|
||||
(
|
||||
"description",
|
||||
Value::string("A sample field in the interface"),
|
||||
),
|
||||
("args", Value::list(vec![])),
|
||||
(
|
||||
"type",
|
||||
Value::object(
|
||||
vec![
|
||||
("name", Value::null()),
|
||||
("kind", Value::string("NON_NULL")),
|
||||
(
|
||||
"ofType",
|
||||
Value::object(
|
||||
vec![
|
||||
("name", Value::string("SampleEnum")),
|
||||
("kind", Value::string("ENUM")),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
),
|
||||
("isDeprecated", Value::boolean(false)),
|
||||
("deprecationReason", Value::null()),
|
||||
].into_iter()
|
||||
.collect()
|
||||
))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -318,14 +360,20 @@ fn object_introspection() {
|
|||
|
||||
assert_eq!(type_info.get("name"), Some(&Value::string("Root")));
|
||||
assert_eq!(type_info.get("kind"), Some(&Value::string("OBJECT")));
|
||||
assert_eq!(type_info.get("description"), Some(&Value::string("The root query object in the schema")));
|
||||
assert_eq!(
|
||||
type_info.get("description"),
|
||||
Some(&Value::string("The root query object in the schema"))
|
||||
);
|
||||
assert_eq!(
|
||||
type_info.get("interfaces"),
|
||||
Some(&Value::list(vec![
|
||||
Value::object(vec![
|
||||
("name", Value::string("SampleInterface")),
|
||||
].into_iter().collect()),
|
||||
])));
|
||||
Value::object(
|
||||
vec![("name", Value::string("SampleInterface"))]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
),
|
||||
]))
|
||||
);
|
||||
assert_eq!(type_info.get("enumValues"), Some(&Value::null()));
|
||||
assert_eq!(type_info.get("inputFields"), Some(&Value::null()));
|
||||
assert_eq!(type_info.get("ofType"), Some(&Value::null()));
|
||||
|
@ -341,62 +389,126 @@ fn object_introspection() {
|
|||
|
||||
println!("Fields: {:#?}", fields);
|
||||
|
||||
assert!(fields.contains(&Value::object(vec![
|
||||
("name", Value::string("sampleEnum")),
|
||||
("description", Value::null()),
|
||||
("args", Value::list(vec![])),
|
||||
("type", Value::object(vec![
|
||||
("name", Value::null()),
|
||||
("kind", Value::string("NON_NULL")),
|
||||
("ofType", Value::object(vec![
|
||||
("name", Value::string("SampleEnum")),
|
||||
("kind", Value::string("ENUM")),
|
||||
].into_iter().collect())),
|
||||
].into_iter().collect())),
|
||||
("isDeprecated", Value::boolean(false)),
|
||||
("deprecationReason", Value::null()),
|
||||
].into_iter().collect())));
|
||||
assert!(
|
||||
fields.contains(&Value::object(
|
||||
vec![
|
||||
("name", Value::string("sampleEnum")),
|
||||
("description", Value::null()),
|
||||
("args", Value::list(vec![])),
|
||||
(
|
||||
"type",
|
||||
Value::object(
|
||||
vec![
|
||||
("name", Value::null()),
|
||||
("kind", Value::string("NON_NULL")),
|
||||
(
|
||||
"ofType",
|
||||
Value::object(
|
||||
vec![
|
||||
("name", Value::string("SampleEnum")),
|
||||
("kind", Value::string("ENUM")),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
),
|
||||
("isDeprecated", Value::boolean(false)),
|
||||
("deprecationReason", Value::null()),
|
||||
].into_iter()
|
||||
.collect()
|
||||
))
|
||||
);
|
||||
|
||||
assert!(fields.contains(&Value::object(vec![
|
||||
("name", Value::string("sampleScalar")),
|
||||
("description", Value::string("A sample scalar field on the object")),
|
||||
("args", Value::list(vec![
|
||||
Value::object(vec![
|
||||
("name", Value::string("first")),
|
||||
("description", Value::string("The first number")),
|
||||
("type", Value::object(vec![
|
||||
("name", Value::null()),
|
||||
("kind", Value::string("NON_NULL")),
|
||||
("ofType", Value::object(vec![
|
||||
("name", Value::string("Int")),
|
||||
("kind", Value::string("SCALAR")),
|
||||
("ofType", Value::null()),
|
||||
].into_iter().collect())),
|
||||
].into_iter().collect())),
|
||||
("defaultValue", Value::null()),
|
||||
].into_iter().collect()),
|
||||
Value::object(vec![
|
||||
("name", Value::string("second")),
|
||||
("description", Value::string("The second number")),
|
||||
("type", Value::object(vec![
|
||||
("name", Value::string("Int")),
|
||||
("kind", Value::string("SCALAR")),
|
||||
("ofType", Value::null()),
|
||||
].into_iter().collect())),
|
||||
("defaultValue", Value::string("123")),
|
||||
].into_iter().collect()),
|
||||
])),
|
||||
("type", Value::object(vec![
|
||||
("name", Value::null()),
|
||||
("kind", Value::string("NON_NULL")),
|
||||
("ofType", Value::object(vec![
|
||||
("name", Value::string("SampleScalar")),
|
||||
("kind", Value::string("SCALAR")),
|
||||
].into_iter().collect())),
|
||||
].into_iter().collect())),
|
||||
("isDeprecated", Value::boolean(false)),
|
||||
("deprecationReason", Value::null()),
|
||||
].into_iter().collect())));
|
||||
assert!(
|
||||
fields.contains(&Value::object(
|
||||
vec![
|
||||
("name", Value::string("sampleScalar")),
|
||||
(
|
||||
"description",
|
||||
Value::string("A sample scalar field on the object"),
|
||||
),
|
||||
(
|
||||
"args",
|
||||
Value::list(vec![
|
||||
Value::object(
|
||||
vec![
|
||||
("name", Value::string("first")),
|
||||
("description", Value::string("The first number")),
|
||||
(
|
||||
"type",
|
||||
Value::object(
|
||||
vec![
|
||||
("name", Value::null()),
|
||||
("kind", Value::string("NON_NULL")),
|
||||
(
|
||||
"ofType",
|
||||
Value::object(
|
||||
vec![
|
||||
("name", Value::string("Int")),
|
||||
("kind", Value::string("SCALAR")),
|
||||
("ofType", Value::null()),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
),
|
||||
("defaultValue", Value::null()),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
Value::object(
|
||||
vec![
|
||||
("name", Value::string("second")),
|
||||
("description", Value::string("The second number")),
|
||||
(
|
||||
"type",
|
||||
Value::object(
|
||||
vec![
|
||||
("name", Value::string("Int")),
|
||||
("kind", Value::string("SCALAR")),
|
||||
("ofType", Value::null()),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
),
|
||||
("defaultValue", Value::string("123")),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
]),
|
||||
),
|
||||
(
|
||||
"type",
|
||||
Value::object(
|
||||
vec![
|
||||
("name", Value::null()),
|
||||
("kind", Value::string("NON_NULL")),
|
||||
(
|
||||
"ofType",
|
||||
Value::object(
|
||||
vec![
|
||||
("name", Value::string("SampleScalar")),
|
||||
("kind", Value::string("SCALAR")),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
),
|
||||
("isDeprecated", Value::boolean(false)),
|
||||
("deprecationReason", Value::null()),
|
||||
].into_iter()
|
||||
.collect()
|
||||
))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -431,15 +543,21 @@ fn scalar_introspection() {
|
|||
.get("__type")
|
||||
.expect("__type field missing");
|
||||
|
||||
assert_eq!(type_info, &Value::object(vec![
|
||||
("name", Value::string("SampleScalar")),
|
||||
("kind", Value::string("SCALAR")),
|
||||
("description", Value::null()),
|
||||
("fields", Value::null()),
|
||||
("interfaces", Value::null()),
|
||||
("possibleTypes", Value::null()),
|
||||
("enumValues", Value::null()),
|
||||
("inputFields", Value::null()),
|
||||
("ofType", Value::null()),
|
||||
].into_iter().collect()));
|
||||
assert_eq!(
|
||||
type_info,
|
||||
&Value::object(
|
||||
vec![
|
||||
("name", Value::string("SampleScalar")),
|
||||
("kind", Value::string("SCALAR")),
|
||||
("description", Value::null()),
|
||||
("fields", Value::null()),
|
||||
("interfaces", Value::null()),
|
||||
("possibleTypes", Value::null()),
|
||||
("enumValues", Value::null()),
|
||||
("inputFields", Value::null()),
|
||||
("ofType", Value::null()),
|
||||
].into_iter()
|
||||
.collect()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -62,5 +62,4 @@ pub fn graphiql_source(graphql_endpoint_url: &str) -> String {
|
|||
graphql_url = graphql_endpoint_url,
|
||||
stylesheet_source = stylesheet_source,
|
||||
fetcher_source = fetcher_source)
|
||||
|
||||
}
|
||||
|
|
|
@ -19,8 +19,7 @@ use executor::ExecutionError;
|
|||
#[derive(Deserialize, Clone, Serialize, PartialEq, Debug)]
|
||||
pub struct GraphQLRequest {
|
||||
query: String,
|
||||
#[serde(rename = "operationName")]
|
||||
operation_name: Option<String>,
|
||||
#[serde(rename = "operationName")] operation_name: Option<String>,
|
||||
variables: Option<InputValue>,
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
*/
|
||||
use chrono::prelude::*;
|
||||
|
||||
use ::Value;
|
||||
use Value;
|
||||
|
||||
#[doc(hidden)]
|
||||
pub static RFC3339_FORMAT: &'static str = "%Y-%m-%dT%H:%M:%S%.f%:z";
|
||||
|
@ -113,7 +113,9 @@ mod test {
|
|||
let input = ::InputValue::String(raw.to_string());
|
||||
|
||||
let parsed: DateTime<Utc> = ::FromInputValue::from_input_value(&input).unwrap();
|
||||
let expected = DateTime::parse_from_rfc3339(raw).unwrap().with_timezone(&Utc);
|
||||
let expected = DateTime::parse_from_rfc3339(raw)
|
||||
.unwrap()
|
||||
.with_timezone(&Utc);
|
||||
|
||||
assert_eq!(parsed, expected);
|
||||
}
|
||||
|
|
|
@ -47,9 +47,8 @@ impl<'a> ser::Serialize for GraphQLError<'a> {
|
|||
GraphQLError::NoOperationProvided => {
|
||||
serializer.serialize_str("Must provide an operation")
|
||||
}
|
||||
GraphQLError::MultipleOperationsProvided => serializer.serialize_str(
|
||||
"Must provide operation name if query contains multiple operations",
|
||||
),
|
||||
GraphQLError::MultipleOperationsProvided => serializer
|
||||
.serialize_str("Must provide operation name if query contains multiple operations"),
|
||||
GraphQLError::UnknownOperationName => serializer.serialize_str("Unknown operation"),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use url::Url;
|
||||
|
||||
use ::Value;
|
||||
use Value;
|
||||
|
||||
graphql_scalar!(Url {
|
||||
description: "Url"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use uuid::Uuid;
|
||||
|
||||
use ::Value;
|
||||
use Value;
|
||||
|
||||
graphql_scalar!(Uuid {
|
||||
description: "Uuid"
|
||||
|
@ -29,4 +29,4 @@ mod test {
|
|||
|
||||
assert_eq!(parsed, id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -212,5 +212,3 @@ impl<'a> From<Spanning<ParseError<'a>>> for GraphQLError<'a> {
|
|||
GraphQLError::ParseError(f)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -5,7 +5,12 @@ macro_rules! __graphql__build_field_matches {
|
|||
(
|
||||
$resolveargs:tt,
|
||||
( $( $acc:tt )* ),
|
||||
field deprecated $_reason:tt $name:ident $args:tt -> $t:ty as $desc:tt $body:block $( $rest:tt )*
|
||||
field deprecated $_reason:tt
|
||||
$name:ident
|
||||
$args:tt -> $t:ty
|
||||
as $desc:tt
|
||||
$body:block
|
||||
$( $rest:tt )*
|
||||
) => {
|
||||
__graphql__build_field_matches!(
|
||||
$resolveargs,
|
||||
|
@ -28,7 +33,12 @@ macro_rules! __graphql__build_field_matches {
|
|||
// field <name>(...) -> <type> as <description> { ... }
|
||||
(
|
||||
$resolveargs:tt,
|
||||
( $( $acc:tt )* ), field $name:ident $args:tt -> $t:ty as $desc:tt $body:block $( $rest:tt )*
|
||||
( $( $acc:tt )* ),
|
||||
field $name:ident
|
||||
$args:tt -> $t:ty
|
||||
as $desc:tt
|
||||
$body:block
|
||||
$( $rest:tt )*
|
||||
) => {
|
||||
__graphql__build_field_matches!(
|
||||
$resolveargs,
|
||||
|
@ -55,7 +65,10 @@ macro_rules! __graphql__build_field_matches {
|
|||
__graphql__build_field_matches!($resolveargs, $acc, $( $rest )*);
|
||||
};
|
||||
|
||||
( $resolveargs:tt, $acc:tt, instance_resolvers : | $execvar:pat | $resolvers:tt $( $rest:tt )*) => {
|
||||
( $resolveargs:tt,
|
||||
$acc:tt,
|
||||
instance_resolvers : | $execvar:pat | $resolvers:tt $( $rest:tt )*
|
||||
) => {
|
||||
__graphql__build_field_matches!($resolveargs, $acc, $( $rest )*);
|
||||
};
|
||||
|
||||
|
@ -79,7 +92,8 @@ macro_rules! __graphql__build_field_matches {
|
|||
|
||||
return ($crate::IntoResolvable::into(result, $executorvar.context())).and_then(
|
||||
|res| match res {
|
||||
Some((ctx, r)) => $executorvar.replaced_context(ctx).resolve_with_ctx(&(), &r),
|
||||
Some((ctx, r)) =>
|
||||
$executorvar.replaced_context(ctx).resolve_with_ctx(&(), &r),
|
||||
None => Ok($crate::Value::null()),
|
||||
})
|
||||
}
|
||||
|
|
|
@ -94,7 +94,11 @@ macro_rules! graphql_interface {
|
|||
(
|
||||
@ gather_meta,
|
||||
($reg:expr, $acc:expr, $info:expr, $descr:expr),
|
||||
field deprecated $reason:tt $name:ident $args:tt -> $t:ty as $desc:tt $body:block $( $rest:tt )*
|
||||
field deprecated $reason:tt
|
||||
$name:ident
|
||||
$args:tt -> $t:ty as $desc:tt
|
||||
$body:block
|
||||
$( $rest:tt )*
|
||||
) => {
|
||||
$acc.push(__graphql__args!(
|
||||
@apply_args,
|
||||
|
@ -177,7 +181,8 @@ macro_rules! graphql_interface {
|
|||
(
|
||||
@ gather_meta,
|
||||
($reg:expr, $acc:expr, $info:expr, $descr:expr),
|
||||
instance_resolvers : | $ctxtvar:pat | { $( $srctype:ty => $resolver:expr ),* $(,)* } $( $rest:tt )*
|
||||
instance_resolvers : | $ctxtvar:pat
|
||||
| { $( $srctype:ty => $resolver:expr ),* $(,)* } $( $rest:tt )*
|
||||
) => {
|
||||
$(
|
||||
let _ = $reg.get_type::<$srctype>(&());
|
||||
|
@ -190,7 +195,8 @@ macro_rules! graphql_interface {
|
|||
(
|
||||
@ concrete_type_name,
|
||||
($outname:tt, $ctxtarg:ident, $ctxttype:ty),
|
||||
instance_resolvers : | $ctxtvar:pat | { $( $srctype:ty => $resolver:expr ),* $(,)* } $( $rest:tt )*
|
||||
instance_resolvers : | $ctxtvar:pat
|
||||
| { $( $srctype:ty => $resolver:expr ),* $(,)* } $( $rest:tt )*
|
||||
) => {
|
||||
let $ctxtvar = &$ctxtarg;
|
||||
|
||||
|
@ -207,7 +213,8 @@ macro_rules! graphql_interface {
|
|||
(
|
||||
@ resolve_into_type,
|
||||
($outname:tt, $typenamearg:ident, $execarg:ident, $ctxttype:ty),
|
||||
instance_resolvers : | $ctxtvar:pat | { $( $srctype:ty => $resolver:expr ),* $(,)* } $( $rest:tt )*
|
||||
instance_resolvers : | $ctxtvar:pat
|
||||
| { $( $srctype:ty => $resolver:expr ),* $(,)* } $( $rest:tt )*
|
||||
) => {
|
||||
let $ctxtvar = &$execarg.context();
|
||||
|
||||
|
@ -241,10 +248,15 @@ macro_rules! graphql_interface {
|
|||
|
||||
#[allow(unused_assignments)]
|
||||
#[allow(unused_mut)]
|
||||
fn meta<'r>(info: &(), registry: &mut $crate::Registry<'r>) -> $crate::meta::MetaType<'r> {
|
||||
fn meta<'r>(
|
||||
info: &(),
|
||||
registry: &mut $crate::Registry<'r>
|
||||
) -> $crate::meta::MetaType<'r> {
|
||||
let mut fields = Vec::new();
|
||||
let mut description = None;
|
||||
graphql_interface!(@ gather_meta, (registry, fields, info, description), $($items)*);
|
||||
graphql_interface!(
|
||||
@ gather_meta, (registry, fields, info, description), $($items)*
|
||||
);
|
||||
let mut mt = registry.build_interface_type::<$name>(&(), &fields);
|
||||
|
||||
if let Some(description) = description {
|
||||
|
@ -256,7 +268,13 @@ macro_rules! graphql_interface {
|
|||
|
||||
#[allow(unused_variables)]
|
||||
#[allow(unused_mut)]
|
||||
fn resolve_field(&$mainself, info: &(), field: &str, args: &$crate::Arguments, mut executor: &$crate::Executor<Self::Context>) -> $crate::ExecutionResult {
|
||||
fn resolve_field(
|
||||
&$mainself,
|
||||
info: &(),
|
||||
field: &str,
|
||||
args: &$crate::Arguments,
|
||||
mut executor: &$crate::Executor<Self::Context>
|
||||
) -> $crate::ExecutionResult {
|
||||
__graphql__build_field_matches!(
|
||||
($outname, $mainself, field, args, executor),
|
||||
(),
|
||||
|
|
|
@ -246,7 +246,13 @@ macro_rules! graphql_object {
|
|||
(
|
||||
@gather_object_meta,
|
||||
$reg:expr, $acc:expr, $info:expr, $descr:expr, $ifaces:expr,
|
||||
field deprecated $reason:tt $name:ident $args:tt -> $t:ty as $desc:tt $body:block $( $rest:tt )*
|
||||
field deprecated
|
||||
$reason:tt
|
||||
$name:ident
|
||||
$args:tt -> $t:ty
|
||||
as $desc:tt
|
||||
$body:block
|
||||
$( $rest:tt )*
|
||||
) => {
|
||||
$acc.push(__graphql__args!(
|
||||
@apply_args,
|
||||
|
@ -376,7 +382,10 @@ macro_rules! graphql_object {
|
|||
|
||||
#[allow(unused_assignments)]
|
||||
#[allow(unused_mut)]
|
||||
fn meta<'r>(info: &(), registry: &mut $crate::Registry<'r>) -> $crate::meta::MetaType<'r> {
|
||||
fn meta<'r>(
|
||||
info: &(),
|
||||
registry: &mut $crate::Registry<'r>
|
||||
) -> $crate::meta::MetaType<'r> {
|
||||
let mut fields = Vec::new();
|
||||
let mut description = None;
|
||||
let mut interfaces: Option<Vec<$crate::Type>> = None;
|
||||
|
|
|
@ -71,7 +71,10 @@ macro_rules! graphql_scalar {
|
|||
Some(graphql_scalar!( @as_expr, $outname ))
|
||||
}
|
||||
|
||||
fn meta<'r>(info: &(), registry: &mut $crate::Registry<'r>) -> $crate::meta::MetaType<'r> {
|
||||
fn meta<'r>(
|
||||
info: &(),
|
||||
registry: &mut $crate::Registry<'r>
|
||||
) -> $crate::meta::MetaType<'r> {
|
||||
graphql_scalar!(
|
||||
@maybe_apply, $descr, description,
|
||||
registry.build_scalar_type::<Self>(info))
|
||||
|
|
|
@ -170,17 +170,31 @@ 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())));
|
||||
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()
|
||||
))
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -189,17 +203,31 @@ 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())));
|
||||
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()
|
||||
))
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -208,29 +236,57 @@ 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("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())));
|
||||
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()
|
||||
))
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -239,29 +295,57 @@ 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("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())));
|
||||
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()
|
||||
))
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -270,17 +354,31 @@ 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())));
|
||||
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()
|
||||
))
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -289,29 +387,57 @@ 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("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())));
|
||||
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()
|
||||
))
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -320,29 +446,57 @@ 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("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())));
|
||||
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()
|
||||
))
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -351,15 +505,24 @@ 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())));
|
||||
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()
|
||||
))
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -368,25 +531,43 @@ 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("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())));
|
||||
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()
|
||||
))
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -395,25 +576,43 @@ 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("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())));
|
||||
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()
|
||||
))
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -422,15 +621,24 @@ 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())));
|
||||
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()
|
||||
))
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -439,25 +647,43 @@ 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("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())));
|
||||
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()
|
||||
))
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -466,25 +692,43 @@ 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("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())));
|
||||
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()
|
||||
))
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -493,24 +737,45 @@ fn introspect_field_args_with_complex_default() {
|
|||
run_args_info_query("argsWithComplexDefault", |args| {
|
||||
assert_eq!(args.len(), 2);
|
||||
|
||||
assert!(args.contains(&Value::object(vec![
|
||||
("name", Value::string("arg1")),
|
||||
("description", Value::string("A string default argument")),
|
||||
("defaultValue", Value::string(r#""test""#)),
|
||||
("type", Value::object(vec![
|
||||
("name", Value::string("String")),
|
||||
("ofType", Value::null()),
|
||||
].into_iter().collect())),
|
||||
].into_iter().collect())));
|
||||
assert!(
|
||||
args.contains(&Value::object(
|
||||
vec![
|
||||
("name", Value::string("arg1")),
|
||||
("description", Value::string("A string default argument")),
|
||||
("defaultValue", Value::string(r#""test""#)),
|
||||
(
|
||||
"type",
|
||||
Value::object(
|
||||
vec![("name", Value::string("String")), ("ofType", Value::null())]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
),
|
||||
),
|
||||
].into_iter()
|
||||
.collect()
|
||||
))
|
||||
);
|
||||
|
||||
assert!(args.contains(&Value::object(vec![
|
||||
("name", Value::string("arg2")),
|
||||
("description", Value::string("An input object default argument")),
|
||||
("defaultValue", Value::string(r#"{x: 1}"#)),
|
||||
("type", Value::object(vec![
|
||||
("name", Value::string("Point")),
|
||||
("ofType", Value::null()),
|
||||
].into_iter().collect())),
|
||||
].into_iter().collect())));
|
||||
assert!(
|
||||
args.contains(&Value::object(
|
||||
vec![
|
||||
("name", Value::string("arg2")),
|
||||
(
|
||||
"description",
|
||||
Value::string("An input object default argument"),
|
||||
),
|
||||
("defaultValue", Value::string(r#"{x: 1}"#)),
|
||||
(
|
||||
"type",
|
||||
Value::object(
|
||||
vec![("name", Value::string("Point")), ("ofType", Value::null())]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
),
|
||||
),
|
||||
].into_iter()
|
||||
.collect()
|
||||
))
|
||||
);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -74,9 +74,8 @@ where
|
|||
}
|
||||
"#;
|
||||
let schema = RootNode::new(Root {}, EmptyMutation::<()>::new());
|
||||
let vars = vec![
|
||||
("typeName".to_owned(), InputValue::string(type_name)),
|
||||
].into_iter()
|
||||
let vars = vec![("typeName".to_owned(), InputValue::string(type_name))]
|
||||
.into_iter()
|
||||
.collect();
|
||||
|
||||
let (result, errs) = ::execute(doc, None, &schema, &vars, &()).expect("Execution failed");
|
||||
|
@ -143,7 +142,10 @@ fn introspect_interface_field_simple() {
|
|||
fn introspect_object_field_description() {
|
||||
run_field_info_query("Root", "description", |field| {
|
||||
assert_eq!(field.get("name"), Some(&Value::string("description")));
|
||||
assert_eq!(field.get("description"), Some(&Value::string("Field description")));
|
||||
assert_eq!(
|
||||
field.get("description"),
|
||||
Some(&Value::string("Field description"))
|
||||
);
|
||||
assert_eq!(field.get("isDeprecated"), Some(&Value::boolean(false)));
|
||||
assert_eq!(field.get("deprecationReason"), Some(&Value::null()));
|
||||
});
|
||||
|
@ -153,7 +155,10 @@ fn introspect_object_field_description() {
|
|||
fn introspect_interface_field_description() {
|
||||
run_field_info_query("Interface", "description", |field| {
|
||||
assert_eq!(field.get("name"), Some(&Value::string("description")));
|
||||
assert_eq!(field.get("description"), Some(&Value::string("Field description")));
|
||||
assert_eq!(
|
||||
field.get("description"),
|
||||
Some(&Value::string("Field description"))
|
||||
);
|
||||
assert_eq!(field.get("isDeprecated"), Some(&Value::boolean(false)));
|
||||
assert_eq!(field.get("deprecationReason"), Some(&Value::null()));
|
||||
});
|
||||
|
@ -165,7 +170,10 @@ fn introspect_object_field_deprecated() {
|
|||
assert_eq!(field.get("name"), Some(&Value::string("deprecated")));
|
||||
assert_eq!(field.get("description"), Some(&Value::null()));
|
||||
assert_eq!(field.get("isDeprecated"), Some(&Value::boolean(true)));
|
||||
assert_eq!(field.get("deprecationReason"), Some(&Value::string("Deprecation reason")));
|
||||
assert_eq!(
|
||||
field.get("deprecationReason"),
|
||||
Some(&Value::string("Deprecation reason"))
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -175,7 +183,10 @@ fn introspect_interface_field_deprecated() {
|
|||
assert_eq!(field.get("name"), Some(&Value::string("deprecated")));
|
||||
assert_eq!(field.get("description"), Some(&Value::null()));
|
||||
assert_eq!(field.get("isDeprecated"), Some(&Value::boolean(true)));
|
||||
assert_eq!(field.get("deprecationReason"), Some(&Value::string("Deprecation reason")));
|
||||
assert_eq!(
|
||||
field.get("deprecationReason"),
|
||||
Some(&Value::string("Deprecation reason"))
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -183,9 +194,15 @@ fn introspect_interface_field_deprecated() {
|
|||
fn introspect_object_field_deprecated_descr() {
|
||||
run_field_info_query("Root", "deprecatedDescr", |field| {
|
||||
assert_eq!(field.get("name"), Some(&Value::string("deprecatedDescr")));
|
||||
assert_eq!(field.get("description"), Some(&Value::string("Field description")));
|
||||
assert_eq!(
|
||||
field.get("description"),
|
||||
Some(&Value::string("Field description"))
|
||||
);
|
||||
assert_eq!(field.get("isDeprecated"), Some(&Value::boolean(true)));
|
||||
assert_eq!(field.get("deprecationReason"), Some(&Value::string("Deprecation reason")));
|
||||
assert_eq!(
|
||||
field.get("deprecationReason"),
|
||||
Some(&Value::string("Deprecation reason"))
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -193,8 +210,14 @@ fn introspect_object_field_deprecated_descr() {
|
|||
fn introspect_interface_field_deprecated_descr() {
|
||||
run_field_info_query("Interface", "deprecatedDescr", |field| {
|
||||
assert_eq!(field.get("name"), Some(&Value::string("deprecatedDescr")));
|
||||
assert_eq!(field.get("description"), Some(&Value::string("Field description")));
|
||||
assert_eq!(
|
||||
field.get("description"),
|
||||
Some(&Value::string("Field description"))
|
||||
);
|
||||
assert_eq!(field.get("isDeprecated"), Some(&Value::boolean(true)));
|
||||
assert_eq!(field.get("deprecationReason"), Some(&Value::string("Deprecation reason")));
|
||||
assert_eq!(
|
||||
field.get("deprecationReason"),
|
||||
Some(&Value::string("Deprecation reason"))
|
||||
);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -53,7 +53,6 @@ graphql_interface!(CustomName: () as "ACustomNamedInterface" |&self| {
|
|||
instance_resolvers: |_| { Concrete => Some(Concrete) }
|
||||
});
|
||||
|
||||
|
||||
graphql_interface!(<'a> WithLifetime<'a>: () as "WithLifetime" |&self| {
|
||||
field simple() -> i32 { 0 }
|
||||
instance_resolvers: |_| { Concrete => Some(Concrete) }
|
||||
|
@ -64,7 +63,6 @@ graphql_interface!(<T> WithGenerics<T>: () as "WithGenerics" |&self| {
|
|||
instance_resolvers: |_| { Concrete => Some(Concrete) }
|
||||
});
|
||||
|
||||
|
||||
graphql_interface!(DescriptionFirst: () |&self| {
|
||||
description: "A description"
|
||||
|
||||
|
@ -97,7 +95,6 @@ graphql_interface!(CommasWithTrailing: () |&self| {
|
|||
description: "A description",
|
||||
});
|
||||
|
||||
|
||||
graphql_interface!(CommasOnMeta: () |&self| {
|
||||
instance_resolvers: |_| { Concrete => Some(Concrete) }
|
||||
description: "A description",
|
||||
|
@ -105,7 +102,6 @@ graphql_interface!(CommasOnMeta: () |&self| {
|
|||
field simple() -> i32 { 0 }
|
||||
});
|
||||
|
||||
|
||||
graphql_interface!(ResolversWithTrailingComma: () |&self| {
|
||||
instance_resolvers: |_| { Concrete => Some(Concrete), }
|
||||
description: "A description",
|
||||
|
@ -132,7 +128,6 @@ graphql_object!(<'a> Root: () as "Root" |&self| {
|
|||
|
||||
});
|
||||
|
||||
|
||||
fn run_type_info_query<F>(type_name: &str, f: F)
|
||||
where
|
||||
F: Fn(&OrderMap<String, Value>, &Vec<Value>) -> (),
|
||||
|
@ -149,9 +144,8 @@ where
|
|||
}
|
||||
"#;
|
||||
let schema = RootNode::new(Root {}, EmptyMutation::<()>::new());
|
||||
let vars = vec![
|
||||
("typeName".to_owned(), InputValue::string(type_name)),
|
||||
].into_iter()
|
||||
let vars = vec![("typeName".to_owned(), InputValue::string(type_name))]
|
||||
.into_iter()
|
||||
.collect();
|
||||
|
||||
let (result, errs) = ::execute(doc, None, &schema, &vars, &()).expect("Execution failed");
|
||||
|
@ -180,12 +174,19 @@ where
|
|||
#[test]
|
||||
fn introspect_custom_name() {
|
||||
run_type_info_query("ACustomNamedInterface", |object, fields| {
|
||||
assert_eq!(object.get("name"), Some(&Value::string("ACustomNamedInterface")));
|
||||
assert_eq!(
|
||||
object.get("name"),
|
||||
Some(&Value::string("ACustomNamedInterface"))
|
||||
);
|
||||
assert_eq!(object.get("description"), Some(&Value::null()));
|
||||
|
||||
assert!(fields.contains(&Value::object(vec![
|
||||
("name", Value::string("simple")),
|
||||
].into_iter().collect())));
|
||||
assert!(
|
||||
fields.contains(&Value::object(
|
||||
vec![("name", Value::string("simple"))]
|
||||
.into_iter()
|
||||
.collect()
|
||||
))
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -195,9 +196,13 @@ fn introspect_with_lifetime() {
|
|||
assert_eq!(object.get("name"), Some(&Value::string("WithLifetime")));
|
||||
assert_eq!(object.get("description"), Some(&Value::null()));
|
||||
|
||||
assert!(fields.contains(&Value::object(vec![
|
||||
("name", Value::string("simple")),
|
||||
].into_iter().collect())));
|
||||
assert!(
|
||||
fields.contains(&Value::object(
|
||||
vec![("name", Value::string("simple"))]
|
||||
.into_iter()
|
||||
.collect()
|
||||
))
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -207,9 +212,13 @@ fn introspect_with_generics() {
|
|||
assert_eq!(object.get("name"), Some(&Value::string("WithGenerics")));
|
||||
assert_eq!(object.get("description"), Some(&Value::null()));
|
||||
|
||||
assert!(fields.contains(&Value::object(vec![
|
||||
("name", Value::string("simple")),
|
||||
].into_iter().collect())));
|
||||
assert!(
|
||||
fields.contains(&Value::object(
|
||||
vec![("name", Value::string("simple"))]
|
||||
.into_iter()
|
||||
.collect()
|
||||
))
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -217,11 +226,18 @@ fn introspect_with_generics() {
|
|||
fn introspect_description_first() {
|
||||
run_type_info_query("DescriptionFirst", |object, fields| {
|
||||
assert_eq!(object.get("name"), Some(&Value::string("DescriptionFirst")));
|
||||
assert_eq!(object.get("description"), Some(&Value::string("A description")));
|
||||
assert_eq!(
|
||||
object.get("description"),
|
||||
Some(&Value::string("A description"))
|
||||
);
|
||||
|
||||
assert!(fields.contains(&Value::object(vec![
|
||||
("name", Value::string("simple")),
|
||||
].into_iter().collect())));
|
||||
assert!(
|
||||
fields.contains(&Value::object(
|
||||
vec![("name", Value::string("simple"))]
|
||||
.into_iter()
|
||||
.collect()
|
||||
))
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -229,11 +245,18 @@ fn introspect_description_first() {
|
|||
fn introspect_fields_first() {
|
||||
run_type_info_query("FieldsFirst", |object, fields| {
|
||||
assert_eq!(object.get("name"), Some(&Value::string("FieldsFirst")));
|
||||
assert_eq!(object.get("description"), Some(&Value::string("A description")));
|
||||
assert_eq!(
|
||||
object.get("description"),
|
||||
Some(&Value::string("A description"))
|
||||
);
|
||||
|
||||
assert!(fields.contains(&Value::object(vec![
|
||||
("name", Value::string("simple")),
|
||||
].into_iter().collect())));
|
||||
assert!(
|
||||
fields.contains(&Value::object(
|
||||
vec![("name", Value::string("simple"))]
|
||||
.into_iter()
|
||||
.collect()
|
||||
))
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -241,23 +264,40 @@ fn introspect_fields_first() {
|
|||
fn introspect_interfaces_first() {
|
||||
run_type_info_query("InterfacesFirst", |object, fields| {
|
||||
assert_eq!(object.get("name"), Some(&Value::string("InterfacesFirst")));
|
||||
assert_eq!(object.get("description"), Some(&Value::string("A description")));
|
||||
assert_eq!(
|
||||
object.get("description"),
|
||||
Some(&Value::string("A description"))
|
||||
);
|
||||
|
||||
assert!(fields.contains(&Value::object(vec![
|
||||
("name", Value::string("simple")),
|
||||
].into_iter().collect())));
|
||||
assert!(
|
||||
fields.contains(&Value::object(
|
||||
vec![("name", Value::string("simple"))]
|
||||
.into_iter()
|
||||
.collect()
|
||||
))
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn introspect_commas_with_trailing() {
|
||||
run_type_info_query("CommasWithTrailing", |object, fields| {
|
||||
assert_eq!(object.get("name"), Some(&Value::string("CommasWithTrailing")));
|
||||
assert_eq!(object.get("description"), Some(&Value::string("A description")));
|
||||
assert_eq!(
|
||||
object.get("name"),
|
||||
Some(&Value::string("CommasWithTrailing"))
|
||||
);
|
||||
assert_eq!(
|
||||
object.get("description"),
|
||||
Some(&Value::string("A description"))
|
||||
);
|
||||
|
||||
assert!(fields.contains(&Value::object(vec![
|
||||
("name", Value::string("simple")),
|
||||
].into_iter().collect())));
|
||||
assert!(
|
||||
fields.contains(&Value::object(
|
||||
vec![("name", Value::string("simple"))]
|
||||
.into_iter()
|
||||
.collect()
|
||||
))
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -265,22 +305,39 @@ fn introspect_commas_with_trailing() {
|
|||
fn introspect_commas_on_meta() {
|
||||
run_type_info_query("CommasOnMeta", |object, fields| {
|
||||
assert_eq!(object.get("name"), Some(&Value::string("CommasOnMeta")));
|
||||
assert_eq!(object.get("description"), Some(&Value::string("A description")));
|
||||
assert_eq!(
|
||||
object.get("description"),
|
||||
Some(&Value::string("A description"))
|
||||
);
|
||||
|
||||
assert!(fields.contains(&Value::object(vec![
|
||||
("name", Value::string("simple")),
|
||||
].into_iter().collect())));
|
||||
assert!(
|
||||
fields.contains(&Value::object(
|
||||
vec![("name", Value::string("simple"))]
|
||||
.into_iter()
|
||||
.collect()
|
||||
))
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn introspect_resolvers_with_trailing_comma() {
|
||||
run_type_info_query("ResolversWithTrailingComma", |object, fields| {
|
||||
assert_eq!(object.get("name"), Some(&Value::string("ResolversWithTrailingComma")));
|
||||
assert_eq!(object.get("description"), Some(&Value::string("A description")));
|
||||
assert_eq!(
|
||||
object.get("name"),
|
||||
Some(&Value::string("ResolversWithTrailingComma"))
|
||||
);
|
||||
assert_eq!(
|
||||
object.get("description"),
|
||||
Some(&Value::string("A description"))
|
||||
);
|
||||
|
||||
assert!(fields.contains(&Value::object(vec![
|
||||
("name", Value::string("simple")),
|
||||
].into_iter().collect())));
|
||||
assert!(
|
||||
fields.contains(&Value::object(
|
||||
vec![("name", Value::string("simple"))]
|
||||
.into_iter()
|
||||
.collect()
|
||||
))
|
||||
);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -4,6 +4,3 @@ mod field;
|
|||
mod object;
|
||||
mod interface;
|
||||
mod union;
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ use ast::InputValue;
|
|||
use value::Value;
|
||||
use schema::model::RootNode;
|
||||
use types::scalars::EmptyMutation;
|
||||
use executor::{FieldResult, Context};
|
||||
use executor::{Context, FieldResult};
|
||||
|
||||
/*
|
||||
|
||||
|
@ -46,7 +46,6 @@ graphql_object!(CustomName: () as "ACustomNamedType" |&self| {
|
|||
field simple() -> i32 { 0 }
|
||||
});
|
||||
|
||||
|
||||
graphql_object!(<'a> WithLifetime<'a>: () as "WithLifetime" |&self| {
|
||||
field simple() -> i32 { 0 }
|
||||
});
|
||||
|
@ -55,7 +54,6 @@ graphql_object!(<T> WithGenerics<T>: () as "WithGenerics" |&self| {
|
|||
field simple() -> i32 { 0 }
|
||||
});
|
||||
|
||||
|
||||
graphql_interface!(Interface: () |&self| {
|
||||
field simple() -> i32 { 0 }
|
||||
|
||||
|
@ -96,7 +94,6 @@ graphql_object!(CommasWithTrailing: () |&self| {
|
|||
description: "A description",
|
||||
});
|
||||
|
||||
|
||||
graphql_object!(CommasOnMeta: () |&self| {
|
||||
interfaces: [Interface],
|
||||
description: "A description",
|
||||
|
@ -108,15 +105,25 @@ struct InnerContext;
|
|||
impl Context for InnerContext {}
|
||||
|
||||
struct InnerType;
|
||||
graphql_object!(InnerType: InnerContext |&self| {
|
||||
});
|
||||
graphql_object!(InnerType: InnerContext | &self | {});
|
||||
|
||||
struct CtxSwitcher;
|
||||
graphql_object!(CtxSwitcher: InnerContext |&self| {
|
||||
field ctx_switch_always(&executor) -> (&InnerContext, InnerType) { (executor.context(), InnerType) }
|
||||
field ctx_switch_opt(&executor) -> Option<(&InnerContext, InnerType)> { Some((executor.context(), InnerType)) }
|
||||
field ctx_switch_res(&executor) -> FieldResult<(&InnerContext, InnerType)> { Ok((executor.context(), InnerType)) }
|
||||
field ctx_switch_res_opt(&executor) -> FieldResult<Option<(&InnerContext, InnerType)>> { Ok(Some((executor.context(), InnerType))) }
|
||||
field ctx_switch_always(&executor) -> (&InnerContext, InnerType) {
|
||||
(executor.context(), InnerType)
|
||||
}
|
||||
|
||||
field ctx_switch_opt(&executor) -> Option<(&InnerContext, InnerType)> {
|
||||
Some((executor.context(), InnerType))
|
||||
}
|
||||
|
||||
field ctx_switch_res(&executor) -> FieldResult<(&InnerContext, InnerType)> {
|
||||
Ok((executor.context(), InnerType))
|
||||
}
|
||||
|
||||
field ctx_switch_res_opt(&executor) -> FieldResult<Option<(&InnerContext, InnerType)>> {
|
||||
Ok(Some((executor.context(), InnerType)))
|
||||
}
|
||||
});
|
||||
|
||||
graphql_object!(<'a> Root: InnerContext as "Root" |&self| {
|
||||
|
@ -135,7 +142,6 @@ graphql_object!(<'a> Root: InnerContext as "Root" |&self| {
|
|||
field ctx_switcher() -> CtxSwitcher { CtxSwitcher {} }
|
||||
});
|
||||
|
||||
|
||||
fn run_type_info_query<F>(type_name: &str, f: F)
|
||||
where
|
||||
F: Fn(&OrderMap<String, Value>, &Vec<Value>) -> (),
|
||||
|
@ -164,12 +170,12 @@ where
|
|||
}
|
||||
"#;
|
||||
let schema = RootNode::new(Root {}, EmptyMutation::<InnerContext>::new());
|
||||
let vars = vec![
|
||||
("typeName".to_owned(), InputValue::string(type_name)),
|
||||
].into_iter()
|
||||
let vars = vec![("typeName".to_owned(), InputValue::string(type_name))]
|
||||
.into_iter()
|
||||
.collect();
|
||||
|
||||
let (result, errs) = ::execute(doc, None, &schema, &vars, &InnerContext).expect("Execution failed");
|
||||
let (result, errs) =
|
||||
::execute(doc, None, &schema, &vars, &InnerContext).expect("Execution failed");
|
||||
|
||||
assert_eq!(errs, []);
|
||||
|
||||
|
@ -238,13 +244,22 @@ fn introspect_with_generics() {
|
|||
fn introspect_description_first() {
|
||||
run_type_info_query("DescriptionFirst", |object, fields| {
|
||||
assert_eq!(object.get("name"), Some(&Value::string("DescriptionFirst")));
|
||||
assert_eq!(object.get("description"), Some(&Value::string("A description")));
|
||||
assert_eq!(object.get("interfaces"), Some(&Value::list(vec![
|
||||
Value::object(vec![
|
||||
("name", Value::string("Interface")),
|
||||
("kind", Value::string("INTERFACE")),
|
||||
].into_iter().collect()),
|
||||
])));
|
||||
assert_eq!(
|
||||
object.get("description"),
|
||||
Some(&Value::string("A description"))
|
||||
);
|
||||
assert_eq!(
|
||||
object.get("interfaces"),
|
||||
Some(&Value::list(vec![
|
||||
Value::object(
|
||||
vec![
|
||||
("name", Value::string("Interface")),
|
||||
("kind", Value::string("INTERFACE")),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
]))
|
||||
);
|
||||
|
||||
assert!(fields.contains(&graphql_value!({
|
||||
"name": "simple",
|
||||
|
@ -257,13 +272,22 @@ fn introspect_description_first() {
|
|||
fn introspect_fields_first() {
|
||||
run_type_info_query("FieldsFirst", |object, fields| {
|
||||
assert_eq!(object.get("name"), Some(&Value::string("FieldsFirst")));
|
||||
assert_eq!(object.get("description"), Some(&Value::string("A description")));
|
||||
assert_eq!(object.get("interfaces"), Some(&Value::list(vec![
|
||||
Value::object(vec![
|
||||
("name", Value::string("Interface")),
|
||||
("kind", Value::string("INTERFACE")),
|
||||
].into_iter().collect()),
|
||||
])));
|
||||
assert_eq!(
|
||||
object.get("description"),
|
||||
Some(&Value::string("A description"))
|
||||
);
|
||||
assert_eq!(
|
||||
object.get("interfaces"),
|
||||
Some(&Value::list(vec![
|
||||
Value::object(
|
||||
vec![
|
||||
("name", Value::string("Interface")),
|
||||
("kind", Value::string("INTERFACE")),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
]))
|
||||
);
|
||||
|
||||
assert!(fields.contains(&graphql_value!({
|
||||
"name": "simple",
|
||||
|
@ -276,13 +300,22 @@ fn introspect_fields_first() {
|
|||
fn introspect_interfaces_first() {
|
||||
run_type_info_query("InterfacesFirst", |object, fields| {
|
||||
assert_eq!(object.get("name"), Some(&Value::string("InterfacesFirst")));
|
||||
assert_eq!(object.get("description"), Some(&Value::string("A description")));
|
||||
assert_eq!(object.get("interfaces"), Some(&Value::list(vec![
|
||||
Value::object(vec![
|
||||
("name", Value::string("Interface")),
|
||||
("kind", Value::string("INTERFACE")),
|
||||
].into_iter().collect()),
|
||||
])));
|
||||
assert_eq!(
|
||||
object.get("description"),
|
||||
Some(&Value::string("A description"))
|
||||
);
|
||||
assert_eq!(
|
||||
object.get("interfaces"),
|
||||
Some(&Value::list(vec![
|
||||
Value::object(
|
||||
vec![
|
||||
("name", Value::string("Interface")),
|
||||
("kind", Value::string("INTERFACE")),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
]))
|
||||
);
|
||||
|
||||
assert!(fields.contains(&graphql_value!({
|
||||
"name": "simple",
|
||||
|
@ -294,14 +327,26 @@ fn introspect_interfaces_first() {
|
|||
#[test]
|
||||
fn introspect_commas_with_trailing() {
|
||||
run_type_info_query("CommasWithTrailing", |object, fields| {
|
||||
assert_eq!(object.get("name"), Some(&Value::string("CommasWithTrailing")));
|
||||
assert_eq!(object.get("description"), Some(&Value::string("A description")));
|
||||
assert_eq!(object.get("interfaces"), Some(&Value::list(vec![
|
||||
Value::object(vec![
|
||||
("name", Value::string("Interface")),
|
||||
("kind", Value::string("INTERFACE")),
|
||||
].into_iter().collect()),
|
||||
])));
|
||||
assert_eq!(
|
||||
object.get("name"),
|
||||
Some(&Value::string("CommasWithTrailing"))
|
||||
);
|
||||
assert_eq!(
|
||||
object.get("description"),
|
||||
Some(&Value::string("A description"))
|
||||
);
|
||||
assert_eq!(
|
||||
object.get("interfaces"),
|
||||
Some(&Value::list(vec![
|
||||
Value::object(
|
||||
vec![
|
||||
("name", Value::string("Interface")),
|
||||
("kind", Value::string("INTERFACE")),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
]))
|
||||
);
|
||||
|
||||
assert!(fields.contains(&graphql_value!({
|
||||
"name": "simple",
|
||||
|
@ -314,13 +359,22 @@ fn introspect_commas_with_trailing() {
|
|||
fn introspect_commas_on_meta() {
|
||||
run_type_info_query("CommasOnMeta", |object, fields| {
|
||||
assert_eq!(object.get("name"), Some(&Value::string("CommasOnMeta")));
|
||||
assert_eq!(object.get("description"), Some(&Value::string("A description")));
|
||||
assert_eq!(object.get("interfaces"), Some(&Value::list(vec![
|
||||
Value::object(vec![
|
||||
("name", Value::string("Interface")),
|
||||
("kind", Value::string("INTERFACE")),
|
||||
].into_iter().collect()),
|
||||
])));
|
||||
assert_eq!(
|
||||
object.get("description"),
|
||||
Some(&Value::string("A description"))
|
||||
);
|
||||
assert_eq!(
|
||||
object.get("interfaces"),
|
||||
Some(&Value::list(vec![
|
||||
Value::object(
|
||||
vec![
|
||||
("name", Value::string("Interface")),
|
||||
("kind", Value::string("INTERFACE")),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
]))
|
||||
);
|
||||
|
||||
assert!(fields.contains(&graphql_value!({
|
||||
"name": "simple",
|
||||
|
|
|
@ -157,7 +157,13 @@ fn scalar_description_introspection() {
|
|||
"#;
|
||||
|
||||
run_type_info_query(doc, |type_info| {
|
||||
assert_eq!(type_info.get("name"), Some(&Value::string("ScalarDescription")));
|
||||
assert_eq!(type_info.get("description"), Some(&Value::string("A sample scalar, represented as an integer")));
|
||||
assert_eq!(
|
||||
type_info.get("name"),
|
||||
Some(&Value::string("ScalarDescription"))
|
||||
);
|
||||
assert_eq!(
|
||||
type_info.get("description"),
|
||||
Some(&Value::string("A sample scalar, represented as an integer"))
|
||||
);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -109,7 +109,6 @@ graphql_object!(<'a> Root: () as "Root" |&self| {
|
|||
}
|
||||
});
|
||||
|
||||
|
||||
fn run_type_info_query<F>(type_name: &str, f: F)
|
||||
where
|
||||
F: Fn(&OrderMap<String, Value>, &Vec<Value>) -> (),
|
||||
|
@ -126,9 +125,8 @@ where
|
|||
}
|
||||
"#;
|
||||
let schema = RootNode::new(Root {}, EmptyMutation::<()>::new());
|
||||
let vars = vec![
|
||||
("typeName".to_owned(), InputValue::string(type_name)),
|
||||
].into_iter()
|
||||
let vars = vec![("typeName".to_owned(), InputValue::string(type_name))]
|
||||
.into_iter()
|
||||
.collect();
|
||||
|
||||
let (result, errs) = ::execute(doc, None, &schema, &vars, &()).expect("Execution failed");
|
||||
|
@ -154,16 +152,19 @@ where
|
|||
f(type_info, possible_types);
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
fn introspect_custom_name() {
|
||||
run_type_info_query("ACustomNamedUnion", |union, possible_types| {
|
||||
assert_eq!(union.get("name"), Some(&Value::string("ACustomNamedUnion")));
|
||||
assert_eq!(union.get("description"), Some(&Value::null()));
|
||||
|
||||
assert!(possible_types.contains(&Value::object(vec![
|
||||
("name", Value::string("Concrete")),
|
||||
].into_iter().collect())));
|
||||
assert!(
|
||||
possible_types.contains(&Value::object(
|
||||
vec![("name", Value::string("Concrete"))]
|
||||
.into_iter()
|
||||
.collect()
|
||||
))
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -173,9 +174,13 @@ fn introspect_with_lifetime() {
|
|||
assert_eq!(union.get("name"), Some(&Value::string("WithLifetime")));
|
||||
assert_eq!(union.get("description"), Some(&Value::null()));
|
||||
|
||||
assert!(possible_types.contains(&Value::object(vec![
|
||||
("name", Value::string("Concrete")),
|
||||
].into_iter().collect())));
|
||||
assert!(
|
||||
possible_types.contains(&Value::object(
|
||||
vec![("name", Value::string("Concrete"))]
|
||||
.into_iter()
|
||||
.collect()
|
||||
))
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -185,9 +190,13 @@ fn introspect_with_generics() {
|
|||
assert_eq!(union.get("name"), Some(&Value::string("WithGenerics")));
|
||||
assert_eq!(union.get("description"), Some(&Value::null()));
|
||||
|
||||
assert!(possible_types.contains(&Value::object(vec![
|
||||
("name", Value::string("Concrete")),
|
||||
].into_iter().collect())));
|
||||
assert!(
|
||||
possible_types.contains(&Value::object(
|
||||
vec![("name", Value::string("Concrete"))]
|
||||
.into_iter()
|
||||
.collect()
|
||||
))
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -195,11 +204,18 @@ fn introspect_with_generics() {
|
|||
fn introspect_description_first() {
|
||||
run_type_info_query("DescriptionFirst", |union, possible_types| {
|
||||
assert_eq!(union.get("name"), Some(&Value::string("DescriptionFirst")));
|
||||
assert_eq!(union.get("description"), Some(&Value::string("A description")));
|
||||
assert_eq!(
|
||||
union.get("description"),
|
||||
Some(&Value::string("A description"))
|
||||
);
|
||||
|
||||
assert!(possible_types.contains(&Value::object(vec![
|
||||
("name", Value::string("Concrete")),
|
||||
].into_iter().collect())));
|
||||
assert!(
|
||||
possible_types.contains(&Value::object(
|
||||
vec![("name", Value::string("Concrete"))]
|
||||
.into_iter()
|
||||
.collect()
|
||||
))
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -207,34 +223,61 @@ fn introspect_description_first() {
|
|||
fn introspect_resolvers_first() {
|
||||
run_type_info_query("ResolversFirst", |union, possible_types| {
|
||||
assert_eq!(union.get("name"), Some(&Value::string("ResolversFirst")));
|
||||
assert_eq!(union.get("description"), Some(&Value::string("A description")));
|
||||
assert_eq!(
|
||||
union.get("description"),
|
||||
Some(&Value::string("A description"))
|
||||
);
|
||||
|
||||
assert!(possible_types.contains(&Value::object(vec![
|
||||
("name", Value::string("Concrete")),
|
||||
].into_iter().collect())));
|
||||
assert!(
|
||||
possible_types.contains(&Value::object(
|
||||
vec![("name", Value::string("Concrete"))]
|
||||
.into_iter()
|
||||
.collect()
|
||||
))
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn introspect_commas_with_trailing() {
|
||||
run_type_info_query("CommasWithTrailing", |union, possible_types| {
|
||||
assert_eq!(union.get("name"), Some(&Value::string("CommasWithTrailing")));
|
||||
assert_eq!(union.get("description"), Some(&Value::string("A description")));
|
||||
assert_eq!(
|
||||
union.get("name"),
|
||||
Some(&Value::string("CommasWithTrailing"))
|
||||
);
|
||||
assert_eq!(
|
||||
union.get("description"),
|
||||
Some(&Value::string("A description"))
|
||||
);
|
||||
|
||||
assert!(possible_types.contains(&Value::object(vec![
|
||||
("name", Value::string("Concrete")),
|
||||
].into_iter().collect())));
|
||||
assert!(
|
||||
possible_types.contains(&Value::object(
|
||||
vec![("name", Value::string("Concrete"))]
|
||||
.into_iter()
|
||||
.collect()
|
||||
))
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn introspect_resolvers_with_trailing_comma() {
|
||||
run_type_info_query("ResolversWithTrailingComma", |union, possible_types| {
|
||||
assert_eq!(union.get("name"), Some(&Value::string("ResolversWithTrailingComma")));
|
||||
assert_eq!(union.get("description"), Some(&Value::string("A description")));
|
||||
assert_eq!(
|
||||
union.get("name"),
|
||||
Some(&Value::string("ResolversWithTrailingComma"))
|
||||
);
|
||||
assert_eq!(
|
||||
union.get("description"),
|
||||
Some(&Value::string("A description"))
|
||||
);
|
||||
|
||||
assert!(possible_types.contains(&Value::object(vec![
|
||||
("name", Value::string("Concrete")),
|
||||
].into_iter().collect())));
|
||||
assert!(
|
||||
possible_types.contains(&Value::object(
|
||||
vec![("name", Value::string("Concrete"))]
|
||||
.into_iter()
|
||||
.collect()
|
||||
))
|
||||
);
|
||||
});
|
||||
}
|
||||
|
|
|
@ -40,7 +40,8 @@ macro_rules! graphql_union {
|
|||
(
|
||||
@ gather_meta,
|
||||
($reg:expr, $acc:expr, $descr:expr),
|
||||
instance_resolvers: | $ctxtvar:pat | { $( $srctype:ty => $resolver:expr ),* $(,)* } $( $rest:tt )*
|
||||
instance_resolvers: | $ctxtvar:pat
|
||||
| { $( $srctype:ty => $resolver:expr ),* $(,)* } $( $rest:tt )*
|
||||
) => {
|
||||
$acc = vec![
|
||||
$(
|
||||
|
@ -56,7 +57,8 @@ macro_rules! graphql_union {
|
|||
(
|
||||
@ concrete_type_name,
|
||||
($outname:tt, $ctxtarg:ident, $ctxttype:ty),
|
||||
instance_resolvers: | $ctxtvar:pat | { $( $srctype:ty => $resolver:expr ),* $(,)* } $( $rest:tt )*
|
||||
instance_resolvers: | $ctxtvar:pat
|
||||
| { $( $srctype:ty => $resolver:expr ),* $(,)* } $( $rest:tt )*
|
||||
) => {
|
||||
let $ctxtvar = &$ctxtarg;
|
||||
|
||||
|
@ -74,7 +76,8 @@ macro_rules! graphql_union {
|
|||
(
|
||||
@ resolve_into_type,
|
||||
($outname:tt, $typenamearg:ident, $execarg:ident, $ctxttype:ty),
|
||||
instance_resolvers: | $ctxtvar:pat | { $( $srctype:ty => $resolver:expr ),* $(,)* } $( $rest:tt )*
|
||||
instance_resolvers: | $ctxtvar:pat
|
||||
| { $( $srctype:ty => $resolver:expr ),* $(,)* } $( $rest:tt )*
|
||||
) => {
|
||||
let $ctxtvar = &$execarg.context();
|
||||
|
||||
|
|
|
@ -32,9 +32,9 @@ fn parse_definition<'a>(parser: &mut Parser<'a>) -> UnlocatedParseResult<'a, Def
|
|||
Token::CurlyOpen | Token::Name("query") | Token::Name("mutation") => Ok(
|
||||
Definition::Operation(try!(parse_operation_definition(parser))),
|
||||
),
|
||||
Token::Name("fragment") => Ok(Definition::Fragment(
|
||||
try!(parse_fragment_definition(parser)),
|
||||
)),
|
||||
Token::Name("fragment") => Ok(Definition::Fragment(try!(parse_fragment_definition(
|
||||
parser
|
||||
)))),
|
||||
_ => Err(parser.next()?.map(ParseError::UnexpectedToken)),
|
||||
}
|
||||
}
|
||||
|
@ -237,13 +237,12 @@ fn parse_arguments<'a>(parser: &mut Parser<'a>) -> OptionParseResult<'a, Argumen
|
|||
Ok(None)
|
||||
} else {
|
||||
Ok(Some(
|
||||
try!(
|
||||
parser
|
||||
.delimited_nonempty_list(&Token::ParenOpen, parse_argument, &Token::ParenClose)
|
||||
).map(|args| {
|
||||
Arguments {
|
||||
items: args.into_iter().map(|s| s.item).collect(),
|
||||
}
|
||||
try!(parser.delimited_nonempty_list(
|
||||
&Token::ParenOpen,
|
||||
parse_argument,
|
||||
&Token::ParenClose
|
||||
)).map(|args| Arguments {
|
||||
items: args.into_iter().map(|s| s.item).collect(),
|
||||
}),
|
||||
))
|
||||
}
|
||||
|
@ -282,10 +281,8 @@ fn parse_variable_definitions<'a>(
|
|||
&Token::ParenOpen,
|
||||
parse_variable_definition,
|
||||
&Token::ParenClose
|
||||
)).map(|defs| {
|
||||
VariableDefinitions {
|
||||
items: defs.into_iter().map(|s| s.item).collect(),
|
||||
}
|
||||
)).map(|defs| VariableDefinitions {
|
||||
items: defs.into_iter().map(|s| s.item).collect(),
|
||||
}),
|
||||
))
|
||||
}
|
||||
|
|
|
@ -127,9 +127,8 @@ impl<'a> Lexer<'a> {
|
|||
|
||||
let start_pos = self.position.clone();
|
||||
|
||||
self.next_char().expect(
|
||||
"Internal error in GraphQL lexer: emit_single_char reached EOF",
|
||||
);
|
||||
self.next_char()
|
||||
.expect("Internal error in GraphQL lexer: emit_single_char reached EOF");
|
||||
|
||||
Spanning::single_width(&start_pos, t)
|
||||
}
|
||||
|
@ -345,12 +344,12 @@ impl<'a> Lexer<'a> {
|
|||
));
|
||||
}
|
||||
|
||||
let code_point = try!(u32::from_str_radix(escape, 16).map_err(|_| {
|
||||
Spanning::zero_width(
|
||||
let code_point = try!(
|
||||
u32::from_str_radix(escape, 16).map_err(|_| Spanning::zero_width(
|
||||
start_pos,
|
||||
LexerError::UnknownEscapeSequence("\\u".to_owned() + escape),
|
||||
)
|
||||
}));
|
||||
))
|
||||
);
|
||||
|
||||
char::from_u32(code_point).ok_or_else(|| {
|
||||
Spanning::zero_width(
|
||||
|
@ -392,10 +391,12 @@ impl<'a> Lexer<'a> {
|
|||
|
||||
let mantissa = frac_part
|
||||
.map(|f| f as f64)
|
||||
.map(|frac| if frac > 0f64 {
|
||||
frac / 10f64.powf(frac.log10().floor() + 1f64)
|
||||
} else {
|
||||
0f64
|
||||
.map(|frac| {
|
||||
if frac > 0f64 {
|
||||
frac / 10f64.powf(frac.log10().floor() + 1f64)
|
||||
} else {
|
||||
0f64
|
||||
}
|
||||
})
|
||||
.map(|m| if int_part < 0 { -m } else { m });
|
||||
|
||||
|
@ -472,9 +473,8 @@ impl<'a> Lexer<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
i32::from_str_radix(&self.source[start_idx..end_idx + 1], 10).map_err(|_| {
|
||||
Spanning::zero_width(&start_pos, LexerError::InvalidNumber)
|
||||
})
|
||||
i32::from_str_radix(&self.source[start_idx..end_idx + 1], 10)
|
||||
.map_err(|_| Spanning::zero_width(&start_pos, LexerError::InvalidNumber))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -171,10 +171,12 @@ impl<'a> Parser<'a> {
|
|||
Spanning {
|
||||
item: Token::Name(_),
|
||||
..
|
||||
} => Ok(self.next()?.map(|token| if let Token::Name(name) = token {
|
||||
name
|
||||
} else {
|
||||
panic!("Internal parse error in `expect_name`");
|
||||
} => Ok(self.next()?.map(|token| {
|
||||
if let Token::Name(name) = token {
|
||||
name
|
||||
} else {
|
||||
panic!("Internal parse error in `expect_name`");
|
||||
}
|
||||
})),
|
||||
Spanning {
|
||||
item: Token::EndOfFile,
|
||||
|
|
|
@ -4,7 +4,6 @@ use ast::InputValue;
|
|||
use parser::{Lexer, Parser, SourcePosition, Spanning};
|
||||
use parser::value::parse_value_literal;
|
||||
|
||||
|
||||
fn parse_value(s: &str) -> Spanning<InputValue> {
|
||||
let mut lexer = Lexer::new(s);
|
||||
let mut parser = Parser::new(&mut lexer).expect(&format!("Lexer error on input {:#?}", s));
|
||||
|
|
|
@ -33,10 +33,12 @@ pub fn parse_value_literal<'a>(
|
|||
Spanning {
|
||||
item: Token::String(_),
|
||||
..
|
||||
} => Ok(parser.next()?.map(|t| if let Token::String(s) = t {
|
||||
InputValue::string(s)
|
||||
} else {
|
||||
panic!("Internal parser error");
|
||||
} => Ok(parser.next()?.map(|t| {
|
||||
if let Token::String(s) = t {
|
||||
InputValue::string(s)
|
||||
} else {
|
||||
panic!("Internal parser error");
|
||||
}
|
||||
})),
|
||||
Spanning {
|
||||
item: Token::Name("true"),
|
||||
|
@ -53,38 +55,30 @@ pub fn parse_value_literal<'a>(
|
|||
Spanning {
|
||||
item: Token::Name(name),
|
||||
..
|
||||
} => Ok(
|
||||
parser
|
||||
.next()?
|
||||
.map(|_| InputValue::enum_value(name.to_owned())),
|
||||
),
|
||||
} => Ok(parser
|
||||
.next()?
|
||||
.map(|_| InputValue::enum_value(name.to_owned()))),
|
||||
_ => Err(parser.next()?.map(ParseError::UnexpectedToken)),
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_list_literal<'a>(parser: &mut Parser<'a>, is_const: bool) -> ParseResult<'a, InputValue> {
|
||||
Ok(
|
||||
try!(parser.delimited_list(
|
||||
&Token::BracketOpen,
|
||||
|p| parse_value_literal(p, is_const),
|
||||
&Token::BracketClose
|
||||
)).map(InputValue::parsed_list),
|
||||
)
|
||||
Ok(try!(parser.delimited_list(
|
||||
&Token::BracketOpen,
|
||||
|p| parse_value_literal(p, is_const),
|
||||
&Token::BracketClose
|
||||
)).map(InputValue::parsed_list))
|
||||
}
|
||||
|
||||
fn parse_object_literal<'a>(
|
||||
parser: &mut Parser<'a>,
|
||||
is_const: bool,
|
||||
) -> ParseResult<'a, InputValue> {
|
||||
Ok(
|
||||
try!(parser.delimited_list(
|
||||
&Token::CurlyOpen,
|
||||
|p| parse_object_field(p, is_const),
|
||||
&Token::CurlyClose
|
||||
)).map(|items| {
|
||||
InputValue::parsed_object(items.into_iter().map(|s| s.item).collect())
|
||||
}),
|
||||
)
|
||||
Ok(try!(parser.delimited_list(
|
||||
&Token::CurlyOpen,
|
||||
|p| parse_object_field(p, is_const),
|
||||
&Token::CurlyClose
|
||||
)).map(|items| InputValue::parsed_object(items.into_iter().map(|s| s.item).collect())))
|
||||
}
|
||||
|
||||
fn parse_object_field<'a>(
|
||||
|
|
|
@ -8,85 +8,62 @@ use types::base::TypeKind;
|
|||
|
||||
/// Scalar type metadata
|
||||
pub struct ScalarMeta<'a> {
|
||||
#[doc(hidden)]
|
||||
pub name: Cow<'a, str>,
|
||||
#[doc(hidden)]
|
||||
pub description: Option<String>,
|
||||
#[doc(hidden)]
|
||||
pub try_parse_fn: Box<Fn(&InputValue) -> bool + Send + Sync>,
|
||||
#[doc(hidden)] pub name: Cow<'a, str>,
|
||||
#[doc(hidden)] pub description: Option<String>,
|
||||
#[doc(hidden)] pub try_parse_fn: Box<Fn(&InputValue) -> bool + Send + Sync>,
|
||||
}
|
||||
|
||||
/// List type metadata
|
||||
#[derive(Debug)]
|
||||
pub struct ListMeta<'a> {
|
||||
#[doc(hidden)]
|
||||
pub of_type: Type<'a>,
|
||||
#[doc(hidden)] pub of_type: Type<'a>,
|
||||
}
|
||||
|
||||
/// Nullable type metadata
|
||||
#[derive(Debug)]
|
||||
pub struct NullableMeta<'a> {
|
||||
#[doc(hidden)]
|
||||
pub of_type: Type<'a>,
|
||||
#[doc(hidden)] pub of_type: Type<'a>,
|
||||
}
|
||||
|
||||
/// Object type metadata
|
||||
#[derive(Debug)]
|
||||
pub struct ObjectMeta<'a> {
|
||||
#[doc(hidden)]
|
||||
pub name: Cow<'a, str>,
|
||||
#[doc(hidden)]
|
||||
pub description: Option<String>,
|
||||
#[doc(hidden)]
|
||||
pub fields: Vec<Field<'a>>,
|
||||
#[doc(hidden)]
|
||||
pub interface_names: Vec<String>,
|
||||
#[doc(hidden)] pub name: Cow<'a, str>,
|
||||
#[doc(hidden)] pub description: Option<String>,
|
||||
#[doc(hidden)] pub fields: Vec<Field<'a>>,
|
||||
#[doc(hidden)] pub interface_names: Vec<String>,
|
||||
}
|
||||
|
||||
/// Enum type metadata
|
||||
pub struct EnumMeta<'a> {
|
||||
#[doc(hidden)]
|
||||
pub name: Cow<'a, str>,
|
||||
#[doc(hidden)]
|
||||
pub description: Option<String>,
|
||||
#[doc(hidden)]
|
||||
pub values: Vec<EnumValue>,
|
||||
#[doc(hidden)]
|
||||
pub try_parse_fn: Box<Fn(&InputValue) -> bool + Send + Sync>,
|
||||
#[doc(hidden)] pub name: Cow<'a, str>,
|
||||
#[doc(hidden)] pub description: Option<String>,
|
||||
#[doc(hidden)] pub values: Vec<EnumValue>,
|
||||
#[doc(hidden)] pub try_parse_fn: Box<Fn(&InputValue) -> bool + Send + Sync>,
|
||||
}
|
||||
|
||||
/// Interface type metadata
|
||||
#[derive(Debug)]
|
||||
pub struct InterfaceMeta<'a> {
|
||||
#[doc(hidden)]
|
||||
pub name: Cow<'a, str>,
|
||||
#[doc(hidden)]
|
||||
pub description: Option<String>,
|
||||
#[doc(hidden)]
|
||||
pub fields: Vec<Field<'a>>,
|
||||
#[doc(hidden)] pub name: Cow<'a, str>,
|
||||
#[doc(hidden)] pub description: Option<String>,
|
||||
#[doc(hidden)] pub fields: Vec<Field<'a>>,
|
||||
}
|
||||
|
||||
/// Union type metadata
|
||||
#[derive(Debug)]
|
||||
pub struct UnionMeta<'a> {
|
||||
#[doc(hidden)]
|
||||
pub name: Cow<'a, str>,
|
||||
#[doc(hidden)]
|
||||
pub description: Option<String>,
|
||||
#[doc(hidden)]
|
||||
pub of_type_names: Vec<String>,
|
||||
#[doc(hidden)] pub name: Cow<'a, str>,
|
||||
#[doc(hidden)] pub description: Option<String>,
|
||||
#[doc(hidden)] pub of_type_names: Vec<String>,
|
||||
}
|
||||
|
||||
/// Input object metadata
|
||||
pub struct InputObjectMeta<'a> {
|
||||
#[doc(hidden)]
|
||||
pub name: Cow<'a, str>,
|
||||
#[doc(hidden)]
|
||||
pub description: Option<String>,
|
||||
#[doc(hidden)]
|
||||
pub input_fields: Vec<Argument<'a>>,
|
||||
#[doc(hidden)]
|
||||
pub try_parse_fn: Box<Fn(&InputValue) -> bool + Send + Sync>,
|
||||
#[doc(hidden)] pub name: Cow<'a, str>,
|
||||
#[doc(hidden)] pub description: Option<String>,
|
||||
#[doc(hidden)] pub input_fields: Vec<Argument<'a>>,
|
||||
#[doc(hidden)] pub try_parse_fn: Box<Fn(&InputValue) -> bool + Send + Sync>,
|
||||
}
|
||||
|
||||
/// A placeholder for not-yet-registered types
|
||||
|
@ -95,59 +72,40 @@ pub struct InputObjectMeta<'a> {
|
|||
/// is inserted into a registry to indicate existence.
|
||||
#[derive(Debug)]
|
||||
pub struct PlaceholderMeta<'a> {
|
||||
#[doc(hidden)]
|
||||
pub of_type: Type<'a>,
|
||||
#[doc(hidden)] pub of_type: Type<'a>,
|
||||
}
|
||||
|
||||
/// Generic type metadata
|
||||
#[derive(Debug)]
|
||||
pub enum MetaType<'a> {
|
||||
#[doc(hidden)]
|
||||
Scalar(ScalarMeta<'a>),
|
||||
#[doc(hidden)]
|
||||
List(ListMeta<'a>),
|
||||
#[doc(hidden)]
|
||||
Nullable(NullableMeta<'a>),
|
||||
#[doc(hidden)]
|
||||
Object(ObjectMeta<'a>),
|
||||
#[doc(hidden)]
|
||||
Enum(EnumMeta<'a>),
|
||||
#[doc(hidden)]
|
||||
Interface(InterfaceMeta<'a>),
|
||||
#[doc(hidden)]
|
||||
Union(UnionMeta<'a>),
|
||||
#[doc(hidden)]
|
||||
InputObject(InputObjectMeta<'a>),
|
||||
#[doc(hidden)]
|
||||
Placeholder(PlaceholderMeta<'a>),
|
||||
#[doc(hidden)] Scalar(ScalarMeta<'a>),
|
||||
#[doc(hidden)] List(ListMeta<'a>),
|
||||
#[doc(hidden)] Nullable(NullableMeta<'a>),
|
||||
#[doc(hidden)] Object(ObjectMeta<'a>),
|
||||
#[doc(hidden)] Enum(EnumMeta<'a>),
|
||||
#[doc(hidden)] Interface(InterfaceMeta<'a>),
|
||||
#[doc(hidden)] Union(UnionMeta<'a>),
|
||||
#[doc(hidden)] InputObject(InputObjectMeta<'a>),
|
||||
#[doc(hidden)] Placeholder(PlaceholderMeta<'a>),
|
||||
}
|
||||
|
||||
/// Metadata for a field
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Field<'a> {
|
||||
#[doc(hidden)]
|
||||
pub name: String,
|
||||
#[doc(hidden)]
|
||||
pub description: Option<String>,
|
||||
#[doc(hidden)]
|
||||
pub arguments: Option<Vec<Argument<'a>>>,
|
||||
#[doc(hidden)]
|
||||
pub field_type: Type<'a>,
|
||||
#[doc(hidden)]
|
||||
pub deprecation_reason: Option<String>,
|
||||
#[doc(hidden)] pub name: String,
|
||||
#[doc(hidden)] pub description: Option<String>,
|
||||
#[doc(hidden)] pub arguments: Option<Vec<Argument<'a>>>,
|
||||
#[doc(hidden)] pub field_type: Type<'a>,
|
||||
#[doc(hidden)] pub deprecation_reason: Option<String>,
|
||||
}
|
||||
|
||||
/// Metadata for an argument to a field
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Argument<'a> {
|
||||
#[doc(hidden)]
|
||||
pub name: String,
|
||||
#[doc(hidden)]
|
||||
pub description: Option<String>,
|
||||
#[doc(hidden)]
|
||||
pub arg_type: Type<'a>,
|
||||
#[doc(hidden)]
|
||||
pub default_value: Option<InputValue>,
|
||||
#[doc(hidden)] pub name: String,
|
||||
#[doc(hidden)] pub description: Option<String>,
|
||||
#[doc(hidden)] pub arg_type: Type<'a>,
|
||||
#[doc(hidden)] pub default_value: Option<InputValue>,
|
||||
}
|
||||
|
||||
/// Metadata for a single value in an enum
|
||||
|
@ -174,12 +132,12 @@ impl<'a> MetaType<'a> {
|
|||
/// Lists, non-null wrappers, and placeholders don't have names.
|
||||
pub fn name(&self) -> Option<&str> {
|
||||
match *self {
|
||||
MetaType::Scalar(ScalarMeta { ref name, .. }) |
|
||||
MetaType::Object(ObjectMeta { ref name, .. }) |
|
||||
MetaType::Enum(EnumMeta { ref name, .. }) |
|
||||
MetaType::Interface(InterfaceMeta { ref name, .. }) |
|
||||
MetaType::Union(UnionMeta { ref name, .. }) |
|
||||
MetaType::InputObject(InputObjectMeta { ref name, .. }) => Some(name),
|
||||
MetaType::Scalar(ScalarMeta { ref name, .. })
|
||||
| MetaType::Object(ObjectMeta { ref name, .. })
|
||||
| MetaType::Enum(EnumMeta { ref name, .. })
|
||||
| MetaType::Interface(InterfaceMeta { ref name, .. })
|
||||
| MetaType::Union(UnionMeta { ref name, .. })
|
||||
| MetaType::InputObject(InputObjectMeta { ref name, .. }) => Some(name),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
@ -191,20 +149,20 @@ impl<'a> MetaType<'a> {
|
|||
match *self {
|
||||
MetaType::Scalar(ScalarMeta {
|
||||
ref description, ..
|
||||
}) |
|
||||
MetaType::Object(ObjectMeta {
|
||||
})
|
||||
| MetaType::Object(ObjectMeta {
|
||||
ref description, ..
|
||||
}) |
|
||||
MetaType::Enum(EnumMeta {
|
||||
})
|
||||
| MetaType::Enum(EnumMeta {
|
||||
ref description, ..
|
||||
}) |
|
||||
MetaType::Interface(InterfaceMeta {
|
||||
})
|
||||
| MetaType::Interface(InterfaceMeta {
|
||||
ref description, ..
|
||||
}) |
|
||||
MetaType::Union(UnionMeta {
|
||||
})
|
||||
| MetaType::Union(UnionMeta {
|
||||
ref description, ..
|
||||
}) |
|
||||
MetaType::InputObject(InputObjectMeta {
|
||||
})
|
||||
| MetaType::InputObject(InputObjectMeta {
|
||||
ref description, ..
|
||||
}) => description.as_ref(),
|
||||
_ => None,
|
||||
|
@ -234,8 +192,8 @@ impl<'a> MetaType<'a> {
|
|||
/// Only objects and interfaces have fields. This method always returns `None` for other types.
|
||||
pub fn field_by_name(&self, name: &str) -> Option<&Field> {
|
||||
match *self {
|
||||
MetaType::Object(ObjectMeta { ref fields, .. }) |
|
||||
MetaType::Interface(InterfaceMeta { ref fields, .. }) => {
|
||||
MetaType::Object(ObjectMeta { ref fields, .. })
|
||||
| MetaType::Interface(InterfaceMeta { ref fields, .. }) => {
|
||||
fields.iter().find(|f| f.name == name)
|
||||
}
|
||||
_ => None,
|
||||
|
@ -257,12 +215,12 @@ impl<'a> MetaType<'a> {
|
|||
/// Construct a `Type` literal instance based on the metadata
|
||||
pub fn as_type(&self) -> Type<'a> {
|
||||
match *self {
|
||||
MetaType::Scalar(ScalarMeta { ref name, .. }) |
|
||||
MetaType::Object(ObjectMeta { ref name, .. }) |
|
||||
MetaType::Enum(EnumMeta { ref name, .. }) |
|
||||
MetaType::Interface(InterfaceMeta { ref name, .. }) |
|
||||
MetaType::Union(UnionMeta { ref name, .. }) |
|
||||
MetaType::InputObject(InputObjectMeta { ref name, .. }) => {
|
||||
MetaType::Scalar(ScalarMeta { ref name, .. })
|
||||
| MetaType::Object(ObjectMeta { ref name, .. })
|
||||
| MetaType::Enum(EnumMeta { ref name, .. })
|
||||
| MetaType::Interface(InterfaceMeta { ref name, .. })
|
||||
| MetaType::Union(UnionMeta { ref name, .. })
|
||||
| MetaType::InputObject(InputObjectMeta { ref name, .. }) => {
|
||||
Type::NonNullNamed(name.clone())
|
||||
}
|
||||
MetaType::List(ListMeta { ref of_type }) => {
|
||||
|
@ -287,11 +245,11 @@ impl<'a> MetaType<'a> {
|
|||
match *self {
|
||||
MetaType::Scalar(ScalarMeta {
|
||||
ref try_parse_fn, ..
|
||||
}) |
|
||||
MetaType::Enum(EnumMeta {
|
||||
})
|
||||
| MetaType::Enum(EnumMeta {
|
||||
ref try_parse_fn, ..
|
||||
}) |
|
||||
MetaType::InputObject(InputObjectMeta {
|
||||
})
|
||||
| MetaType::InputObject(InputObjectMeta {
|
||||
ref try_parse_fn, ..
|
||||
}) => Some(try_parse_fn),
|
||||
_ => None,
|
||||
|
@ -345,7 +303,9 @@ impl<'a> ScalarMeta<'a> {
|
|||
ScalarMeta {
|
||||
name: name,
|
||||
description: None,
|
||||
try_parse_fn: Box::new(|v: &InputValue| <T as FromInputValue>::from_input_value(v).is_some()),
|
||||
try_parse_fn: Box::new(|v: &InputValue| {
|
||||
<T as FromInputValue>::from_input_value(v).is_some()
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -431,7 +391,9 @@ impl<'a> EnumMeta<'a> {
|
|||
name: name,
|
||||
description: None,
|
||||
values: values.to_vec(),
|
||||
try_parse_fn: Box::new(|v: &InputValue| <T as FromInputValue>::from_input_value(v).is_some()),
|
||||
try_parse_fn: Box::new(|v: &InputValue| {
|
||||
<T as FromInputValue>::from_input_value(v).is_some()
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -510,7 +472,9 @@ impl<'a> InputObjectMeta<'a> {
|
|||
name: name,
|
||||
description: None,
|
||||
input_fields: input_fields.to_vec(),
|
||||
try_parse_fn: Box::new(|v: &InputValue| <T as FromInputValue>::from_input_value(v).is_some()),
|
||||
try_parse_fn: Box::new(|v: &InputValue| {
|
||||
<T as FromInputValue>::from_input_value(v).is_some()
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -13,16 +13,11 @@ use schema::meta::{Argument, InterfaceMeta, MetaType, ObjectMeta, PlaceholderMet
|
|||
/// This brings the mutation and query types together, and provides the
|
||||
/// predefined metadata fields.
|
||||
pub struct RootNode<'a, QueryT: GraphQLType, MutationT: GraphQLType> {
|
||||
#[doc(hidden)]
|
||||
pub query_type: QueryT,
|
||||
#[doc(hidden)]
|
||||
pub query_info: QueryT::TypeInfo,
|
||||
#[doc(hidden)]
|
||||
pub mutation_type: MutationT,
|
||||
#[doc(hidden)]
|
||||
pub mutation_info: MutationT::TypeInfo,
|
||||
#[doc(hidden)]
|
||||
pub schema: SchemaType<'a>,
|
||||
#[doc(hidden)] pub query_type: QueryT,
|
||||
#[doc(hidden)] pub query_info: QueryT::TypeInfo,
|
||||
#[doc(hidden)] pub mutation_type: MutationT,
|
||||
#[doc(hidden)] pub mutation_info: MutationT::TypeInfo,
|
||||
#[doc(hidden)] pub schema: SchemaType<'a>,
|
||||
}
|
||||
|
||||
/// Metadata for a schema
|
||||
|
@ -55,12 +50,9 @@ pub enum DirectiveLocation {
|
|||
Query,
|
||||
Mutation,
|
||||
Field,
|
||||
#[graphql(name = "FRAGMENT_DEFINITION")]
|
||||
FragmentDefinition,
|
||||
#[graphql(name = "FRAGMENT_SPREAD")]
|
||||
FragmentSpread,
|
||||
#[graphql(name = "INLINE_SPREAD")]
|
||||
InlineFragment,
|
||||
#[graphql(name = "FRAGMENT_DEFINITION")] FragmentDefinition,
|
||||
#[graphql(name = "FRAGMENT_SPREAD")] FragmentSpread,
|
||||
#[graphql(name = "INLINE_SPREAD")] InlineFragment,
|
||||
}
|
||||
|
||||
impl<'a, QueryT, MutationT> RootNode<'a, QueryT, MutationT>
|
||||
|
@ -277,9 +269,9 @@ impl<'a> SchemaType<'a> {
|
|||
}
|
||||
|
||||
pub fn is_possible_type(&self, abstract_type: &MetaType, possible_type: &MetaType) -> bool {
|
||||
self.possible_types(abstract_type).into_iter().any(|t| {
|
||||
(t as *const MetaType) == (possible_type as *const MetaType)
|
||||
})
|
||||
self.possible_types(abstract_type)
|
||||
.into_iter()
|
||||
.any(|t| (t as *const MetaType) == (possible_type as *const MetaType))
|
||||
}
|
||||
|
||||
pub fn is_subtype<'b>(&self, sub_type: &Type<'b>, super_type: &Type<'b>) -> bool {
|
||||
|
@ -290,14 +282,14 @@ impl<'a> SchemaType<'a> {
|
|||
}
|
||||
|
||||
match (super_type, sub_type) {
|
||||
(&NonNullNamed(ref super_name), &NonNullNamed(ref sub_name)) |
|
||||
(&Named(ref super_name), &Named(ref sub_name)) |
|
||||
(&Named(ref super_name), &NonNullNamed(ref sub_name)) => {
|
||||
(&NonNullNamed(ref super_name), &NonNullNamed(ref sub_name))
|
||||
| (&Named(ref super_name), &Named(ref sub_name))
|
||||
| (&Named(ref super_name), &NonNullNamed(ref sub_name)) => {
|
||||
self.is_named_subtype(sub_name, super_name)
|
||||
}
|
||||
(&NonNullList(ref super_inner), &NonNullList(ref sub_inner)) |
|
||||
(&List(ref super_inner), &List(ref sub_inner)) |
|
||||
(&List(ref super_inner), &NonNullList(ref sub_inner)) => {
|
||||
(&NonNullList(ref super_inner), &NonNullList(ref sub_inner))
|
||||
| (&List(ref super_inner), &List(ref sub_inner))
|
||||
| (&List(ref super_inner), &NonNullList(ref sub_inner)) => {
|
||||
self.is_subtype(sub_inner, super_inner)
|
||||
}
|
||||
_ => false,
|
||||
|
|
|
@ -142,11 +142,15 @@ graphql_object!(<'a> TypeType<'a>: SchemaType<'a> as "__Type" |&self| {
|
|||
.filter_map(|tn| schema.type_by_name(tn))
|
||||
.collect())
|
||||
}
|
||||
TypeType::Concrete(&MetaType::Interface(InterfaceMeta { name: ref iface_name, .. })) => {
|
||||
TypeType::Concrete(&MetaType::Interface(InterfaceMeta{name: ref iface_name, .. })) => {
|
||||
Some(schema.concrete_type_list()
|
||||
.iter()
|
||||
.filter_map(|&ct|
|
||||
if let MetaType::Object(ObjectMeta { ref name, ref interface_names, .. }) = *ct {
|
||||
if let MetaType::Object(ObjectMeta{
|
||||
ref name,
|
||||
ref interface_names,
|
||||
..
|
||||
}) = *ct {
|
||||
if interface_names.contains(&iface_name.to_string()) {
|
||||
schema.type_by_name(name)
|
||||
} else { None }
|
||||
|
@ -232,7 +236,6 @@ graphql_object!(EnumValue: () as "__EnumValue" |&self| {
|
|||
}
|
||||
});
|
||||
|
||||
|
||||
graphql_object!(<'a> DirectiveType<'a>: SchemaType<'a> as "__Directive" |&self| {
|
||||
field name() -> &String {
|
||||
&self.name
|
||||
|
@ -270,4 +273,3 @@ graphql_object!(<'a> DirectiveType<'a>: SchemaType<'a> as "__Directive" |&self|
|
|||
self.locations.contains(&DirectiveLocation::Field)
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -5,8 +5,7 @@ use std::collections::HashMap;
|
|||
#[derive(GraphQLEnum, Copy, Clone, Eq, PartialEq, Debug)]
|
||||
#[graphql(_internal)]
|
||||
pub enum Episode {
|
||||
#[graphql(name = "NEW_HOPE")]
|
||||
NewHope,
|
||||
#[graphql(name = "NEW_HOPE")] NewHope,
|
||||
Empire,
|
||||
Jedi,
|
||||
}
|
||||
|
|
|
@ -83,7 +83,6 @@ graphql_object!(<'a> &'a Droid: Database as "Droid" |&self| {
|
|||
}
|
||||
});
|
||||
|
||||
|
||||
graphql_object!(Database: Database as "Query" |&self| {
|
||||
description: "The root query object of the schema"
|
||||
|
||||
|
|
|
@ -328,7 +328,8 @@ fn resolve_selection_set_into<T, CtxT>(
|
|||
selection_set: &[Selection],
|
||||
executor: &Executor<CtxT>,
|
||||
result: &mut OrderMap<String, Value>,
|
||||
) -> bool where
|
||||
) -> bool
|
||||
where
|
||||
T: GraphQLType<Context = CtxT>,
|
||||
{
|
||||
let meta_type = executor
|
||||
|
@ -441,7 +442,8 @@ fn resolve_selection_set_into<T, CtxT>(
|
|||
|
||||
let sub_exec = executor.type_sub_executor(
|
||||
fragment.type_condition.as_ref().map(|c| c.item),
|
||||
Some(&fragment.selection_set[..]));
|
||||
Some(&fragment.selection_set[..]),
|
||||
);
|
||||
|
||||
if let Some(ref type_condition) = fragment.type_condition {
|
||||
let sub_result = instance.resolve_into_type(
|
||||
|
@ -472,7 +474,7 @@ fn resolve_selection_set_into<T, CtxT>(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
|
@ -491,8 +493,8 @@ fn is_excluded(directives: &Option<Vec<Spanning<Directive>>>, vars: &Variables)
|
|||
.next()
|
||||
.unwrap();
|
||||
|
||||
if (directive.name.item == "skip" && condition) ||
|
||||
(directive.name.item == "include" && !condition)
|
||||
if (directive.name.item == "skip" && condition)
|
||||
|| (directive.name.item == "include" && !condition)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -152,9 +152,15 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
fn resolve_into_list<T: GraphQLType, I: Iterator<Item=T>>(executor: &Executor<T::Context>, info: &T::TypeInfo, iter: I) -> Value {
|
||||
let stop_on_null = executor.current_type()
|
||||
.list_contents().expect("Current type is not a list type")
|
||||
fn resolve_into_list<T: GraphQLType, I: Iterator<Item = T>>(
|
||||
executor: &Executor<T::Context>,
|
||||
info: &T::TypeInfo,
|
||||
iter: I,
|
||||
) -> Value {
|
||||
let stop_on_null = executor
|
||||
.current_type()
|
||||
.list_contents()
|
||||
.expect("Current type is not a list type")
|
||||
.is_non_null();
|
||||
|
||||
let mut result = Vec::new();
|
||||
|
@ -169,4 +175,4 @@ fn resolve_into_list<T: GraphQLType, I: Iterator<Item=T>>(executor: &Executor<T:
|
|||
}
|
||||
|
||||
Value::list(result)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,7 +44,6 @@ graphql_scalar!(ID as "ID" {
|
|||
}
|
||||
});
|
||||
|
||||
|
||||
graphql_scalar!(String as "String" {
|
||||
resolve(&self) -> Value {
|
||||
Value::string(self)
|
||||
|
@ -58,7 +57,6 @@ graphql_scalar!(String as "String" {
|
|||
}
|
||||
});
|
||||
|
||||
|
||||
impl<'a> GraphQLType for &'a str {
|
||||
type Context = ();
|
||||
type TypeInfo = ();
|
||||
|
@ -82,8 +80,6 @@ impl<'a> ToInputValue for &'a str {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
graphql_scalar!(bool as "Boolean" {
|
||||
resolve(&self) -> Value {
|
||||
Value::boolean(*self)
|
||||
|
@ -97,7 +93,6 @@ graphql_scalar!(bool as "Boolean" {
|
|||
}
|
||||
});
|
||||
|
||||
|
||||
graphql_scalar!(i32 as "Int" {
|
||||
resolve(&self) -> Value {
|
||||
Value::int(*self)
|
||||
|
@ -111,7 +106,6 @@ graphql_scalar!(i32 as "Int" {
|
|||
}
|
||||
});
|
||||
|
||||
|
||||
graphql_scalar!(f64 as "Float" {
|
||||
resolve(&self) -> Value {
|
||||
Value::float(*self)
|
||||
|
@ -126,7 +120,6 @@ graphql_scalar!(f64 as "Float" {
|
|||
}
|
||||
});
|
||||
|
||||
|
||||
impl GraphQLType for () {
|
||||
type Context = ();
|
||||
type TypeInfo = ();
|
||||
|
@ -146,7 +139,6 @@ impl FromInputValue for () {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/// Utility type to define read-only schemas
|
||||
///
|
||||
/// If you instantiate `RootNode` with this as the mutation, no mutation will be
|
||||
|
|
|
@ -31,26 +31,29 @@ pub fn is_valid_literal_value(
|
|||
|
||||
match *arg_value {
|
||||
InputValue::Null | InputValue::Variable(_) => true,
|
||||
ref v @ InputValue::Int(_) |
|
||||
ref v @ InputValue::Float(_) |
|
||||
ref v @ InputValue::String(_) |
|
||||
ref v @ InputValue::Boolean(_) |
|
||||
ref v @ InputValue::Enum(_) => if let Some(parse_fn) = t.input_value_parse_fn() {
|
||||
ref v @ InputValue::Int(_)
|
||||
| ref v @ InputValue::Float(_)
|
||||
| ref v @ InputValue::String(_)
|
||||
| ref v @ InputValue::Boolean(_)
|
||||
| ref v @ InputValue::Enum(_) => if let Some(parse_fn) = t.input_value_parse_fn() {
|
||||
parse_fn(v)
|
||||
} else {
|
||||
false
|
||||
},
|
||||
InputValue::List(_) => false,
|
||||
InputValue::Object(ref obj) => if let MetaType::InputObject(InputObjectMeta {
|
||||
ref input_fields, ..
|
||||
ref input_fields,
|
||||
..
|
||||
}) = *t
|
||||
{
|
||||
let mut remaining_required_fields = input_fields
|
||||
.iter()
|
||||
.filter_map(|f| if f.arg_type.is_non_null() {
|
||||
Some(&f.name)
|
||||
} else {
|
||||
None
|
||||
.filter_map(|f| {
|
||||
if f.arg_type.is_non_null() {
|
||||
Some(&f.name)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.collect::<HashSet<_>>();
|
||||
|
||||
|
|
|
@ -277,9 +277,7 @@ fn push_unification_error<'a>(
|
|||
errors.push(RuleError::new(
|
||||
&format!(
|
||||
r#"Variable "${}" got invalid value. {}{}."#,
|
||||
var_name,
|
||||
path,
|
||||
message,
|
||||
var_name, path, message,
|
||||
),
|
||||
&[var_pos.clone()],
|
||||
));
|
||||
|
|
|
@ -60,12 +60,10 @@ impl<'a> Visitor<'a> for ArgumentsOfCorrectType<'a> {
|
|||
fn error_message(arg_name: &str, type_name: &str) -> String {
|
||||
format!(
|
||||
"Invalid value for argument \"{}\", expected type \"{}\"",
|
||||
arg_name,
|
||||
type_name
|
||||
arg_name, type_name
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{error_message, factory};
|
||||
|
|
|
@ -43,16 +43,14 @@ impl<'a> Visitor<'a> for DefaultValuesOfCorrectType {
|
|||
fn type_error_message(arg_name: &str, type_name: &str) -> String {
|
||||
format!(
|
||||
"Invalid default value for argument \"{}\", expected type \"{}\"",
|
||||
arg_name,
|
||||
type_name
|
||||
arg_name, type_name
|
||||
)
|
||||
}
|
||||
|
||||
fn non_null_error_message(arg_name: &str, type_name: &str) -> String {
|
||||
format!(
|
||||
"Argument \"{}\" has type \"{}\" and is not nullable, so it't can't have a default value",
|
||||
arg_name,
|
||||
type_name
|
||||
arg_name, type_name
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,6 @@ impl<'a> Visitor<'a> for FieldsOnCorrectType {
|
|||
let type_name = parent_type.name().unwrap_or("<unknown>");
|
||||
|
||||
if parent_type.field_by_name(field_name.item).is_none() {
|
||||
|
||||
match *parent_type {
|
||||
MetaType::Union(..) => {
|
||||
// You can query for `__typename` on a union,
|
||||
|
|
|
@ -55,8 +55,7 @@ fn error_message(fragment_name: Option<&str>, on_type: &str) -> String {
|
|||
if let Some(name) = fragment_name {
|
||||
format!(
|
||||
r#"Fragment "{}" cannot condition non composite type "{}"#,
|
||||
name,
|
||||
on_type
|
||||
name, on_type
|
||||
)
|
||||
} else {
|
||||
format!(
|
||||
|
|
|
@ -23,14 +23,14 @@ impl<'a> Visitor<'a> for KnownArgumentNames<'a> {
|
|||
ctx: &mut ValidatorContext<'a>,
|
||||
directive: &'a Spanning<Directive>,
|
||||
) {
|
||||
self.current_args = ctx.schema.directive_by_name(directive.item.name.item).map(
|
||||
|d| {
|
||||
self.current_args = ctx.schema
|
||||
.directive_by_name(directive.item.name.item)
|
||||
.map(|d| {
|
||||
(
|
||||
ArgumentPosition::Directive(directive.item.name.item),
|
||||
&d.arguments,
|
||||
)
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
fn exit_directive(&mut self, _: &mut ValidatorContext<'a>, _: &'a Spanning<Directive>) {
|
||||
|
@ -84,17 +84,14 @@ impl<'a> Visitor<'a> for KnownArgumentNames<'a> {
|
|||
fn field_error_message(arg_name: &str, field_name: &str, type_name: &str) -> String {
|
||||
format!(
|
||||
r#"Unknown argument "{}" on field "{}" of type "{}""#,
|
||||
arg_name,
|
||||
field_name,
|
||||
type_name
|
||||
arg_name, field_name, type_name
|
||||
)
|
||||
}
|
||||
|
||||
fn directive_error_message(arg_name: &str, directive_name: &str) -> String {
|
||||
format!(
|
||||
r#"Unknown argument "{}" on directive "{}""#,
|
||||
arg_name,
|
||||
directive_name
|
||||
arg_name, directive_name
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -132,8 +132,7 @@ fn unknown_error_message(directive_name: &str) -> String {
|
|||
fn misplaced_error_message(directive_name: &str, location: &DirectiveLocation) -> String {
|
||||
format!(
|
||||
r#"Directive "{}" may not be used on {}"#,
|
||||
directive_name,
|
||||
location
|
||||
directive_name, location
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -150,8 +150,7 @@ fn error_message(var_name: &str, op_name: Option<&str>) -> String {
|
|||
if let Some(op_name) = op_name {
|
||||
format!(
|
||||
r#"Variable "${}" is not defined by operation "{}""#,
|
||||
var_name,
|
||||
op_name
|
||||
var_name, op_name
|
||||
)
|
||||
} else {
|
||||
format!(r#"Variable "${}" is not defined"#, var_name)
|
||||
|
|
|
@ -140,8 +140,7 @@ fn error_message(var_name: &str, op_name: Option<&str>) -> String {
|
|||
if let Some(op_name) = op_name {
|
||||
format!(
|
||||
r#"Variable "${}" is not defined by operation "{}""#,
|
||||
var_name,
|
||||
op_name
|
||||
var_name, op_name
|
||||
)
|
||||
} else {
|
||||
format!(r#"Variable "${}" is not defined"#, var_name)
|
||||
|
|
|
@ -204,18 +204,21 @@ impl<'a> OverlappingFieldsCanBeMerged<'a> {
|
|||
};
|
||||
|
||||
{
|
||||
if self.compared_fragments
|
||||
.borrow()
|
||||
.contains(fragment_name1, fragment_name2, mutually_exclusive)
|
||||
{
|
||||
if self.compared_fragments.borrow().contains(
|
||||
fragment_name1,
|
||||
fragment_name2,
|
||||
mutually_exclusive,
|
||||
) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
self.compared_fragments
|
||||
.borrow_mut()
|
||||
.insert(fragment_name1, fragment_name2, mutually_exclusive);
|
||||
self.compared_fragments.borrow_mut().insert(
|
||||
fragment_name1,
|
||||
fragment_name2,
|
||||
mutually_exclusive,
|
||||
);
|
||||
}
|
||||
|
||||
let (field_map1, fragment_names1) =
|
||||
|
@ -338,9 +341,9 @@ impl<'a> OverlappingFieldsCanBeMerged<'a> {
|
|||
let AstAndDef(ref parent_type1, ast1, ref def1) = *field1;
|
||||
let AstAndDef(ref parent_type2, ast2, ref def2) = *field2;
|
||||
|
||||
let mutually_exclusive = parents_mutually_exclusive ||
|
||||
(parent_type1 != parent_type2 && self.is_object_type(ctx, *parent_type1) &&
|
||||
self.is_object_type(ctx, *parent_type2));
|
||||
let mutually_exclusive = parents_mutually_exclusive
|
||||
|| (parent_type1 != parent_type2 && self.is_object_type(ctx, *parent_type1)
|
||||
&& self.is_object_type(ctx, *parent_type2));
|
||||
|
||||
if !mutually_exclusive {
|
||||
let name1 = &ast1.item.name.item;
|
||||
|
@ -350,9 +353,10 @@ impl<'a> OverlappingFieldsCanBeMerged<'a> {
|
|||
return Some(Conflict(
|
||||
ConflictReason(
|
||||
response_name.to_owned(),
|
||||
ConflictReasonMessage::Message(
|
||||
format!("{} and {} are different fields", name1, name2),
|
||||
),
|
||||
ConflictReasonMessage::Message(format!(
|
||||
"{} and {} are different fields",
|
||||
name1, name2
|
||||
)),
|
||||
),
|
||||
vec![ast1.start.clone()],
|
||||
vec![ast2.start.clone()],
|
||||
|
@ -379,9 +383,10 @@ impl<'a> OverlappingFieldsCanBeMerged<'a> {
|
|||
return Some(Conflict(
|
||||
ConflictReason(
|
||||
response_name.to_owned(),
|
||||
ConflictReasonMessage::Message(
|
||||
format!("they return conflicting types {} and {}", t1, t2),
|
||||
),
|
||||
ConflictReasonMessage::Message(format!(
|
||||
"they return conflicting types {} and {}",
|
||||
t1, t2
|
||||
)),
|
||||
),
|
||||
vec![ast1.start.clone()],
|
||||
vec![ast2.start.clone()],
|
||||
|
@ -389,8 +394,7 @@ impl<'a> OverlappingFieldsCanBeMerged<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
if let (&Some(ref s1), &Some(ref s2)) =
|
||||
(&ast1.item.selection_set, &ast2.item.selection_set)
|
||||
if let (&Some(ref s1), &Some(ref s2)) = (&ast1.item.selection_set, &ast2.item.selection_set)
|
||||
{
|
||||
let conflicts = self.find_conflicts_between_sub_selection_sets(
|
||||
mutually_exclusive,
|
||||
|
@ -506,17 +510,17 @@ impl<'a> OverlappingFieldsCanBeMerged<'a> {
|
|||
|
||||
fn is_type_conflict(&self, ctx: &ValidatorContext<'a>, t1: &Type, t2: &Type) -> bool {
|
||||
match (t1, t2) {
|
||||
(&Type::List(ref inner1), &Type::List(ref inner2)) |
|
||||
(&Type::NonNullList(ref inner1), &Type::NonNullList(ref inner2)) => {
|
||||
(&Type::List(ref inner1), &Type::List(ref inner2))
|
||||
| (&Type::NonNullList(ref inner1), &Type::NonNullList(ref inner2)) => {
|
||||
self.is_type_conflict(ctx, inner1, inner2)
|
||||
}
|
||||
(&Type::NonNullNamed(ref n1), &Type::NonNullNamed(ref n2)) |
|
||||
(&Type::Named(ref n1), &Type::Named(ref n2)) => {
|
||||
(&Type::NonNullNamed(ref n1), &Type::NonNullNamed(ref n2))
|
||||
| (&Type::Named(ref n1), &Type::Named(ref n2)) => {
|
||||
let ct1 = ctx.schema.concrete_type_by_name(n1);
|
||||
let ct2 = ctx.schema.concrete_type_by_name(n2);
|
||||
|
||||
if ct1.map(|ct| ct.is_leaf()).unwrap_or(false) ||
|
||||
ct2.map(|ct| ct.is_leaf()).unwrap_or(false)
|
||||
if ct1.map(|ct| ct.is_leaf()).unwrap_or(false)
|
||||
|| ct2.map(|ct| ct.is_leaf()).unwrap_or(false)
|
||||
{
|
||||
n1 != n2
|
||||
} else {
|
||||
|
@ -1755,9 +1759,7 @@ mod tests {
|
|||
RuleError::new(
|
||||
&error_message(
|
||||
"scalar",
|
||||
&Message(
|
||||
"they return conflicting types String! and String".to_owned(),
|
||||
),
|
||||
&Message("they return conflicting types String! and String".to_owned()),
|
||||
),
|
||||
&[
|
||||
SourcePosition::new(100, 4, 18),
|
||||
|
|
|
@ -78,16 +78,13 @@ fn error_message(frag_name: Option<&str>, parent_type_name: &str, frag_type: &st
|
|||
format!(
|
||||
"Fragment \"{}\" cannot be spread here as objects of type \
|
||||
\"{}\" can never be of type \"{}\"",
|
||||
frag_name,
|
||||
parent_type_name,
|
||||
frag_type
|
||||
frag_name, parent_type_name, frag_type
|
||||
)
|
||||
} else {
|
||||
format!(
|
||||
"Fragment cannot be spread here as objects of type \"{}\" \
|
||||
can never be of type \"{}\"",
|
||||
parent_type_name,
|
||||
frag_type
|
||||
parent_type_name, frag_type
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,8 +20,8 @@ impl<'a> Visitor<'a> for ProvidedNonNullArguments {
|
|||
}) = ctx.parent_type().and_then(|t| t.field_by_name(field_name))
|
||||
{
|
||||
for meta_arg in meta_args {
|
||||
if meta_arg.arg_type.is_non_null() &&
|
||||
field
|
||||
if meta_arg.arg_type.is_non_null()
|
||||
&& field
|
||||
.item
|
||||
.arguments
|
||||
.as_ref()
|
||||
|
@ -54,8 +54,8 @@ impl<'a> Visitor<'a> for ProvidedNonNullArguments {
|
|||
}) = ctx.schema.directive_by_name(directive_name)
|
||||
{
|
||||
for meta_arg in meta_args {
|
||||
if meta_arg.arg_type.is_non_null() &&
|
||||
directive
|
||||
if meta_arg.arg_type.is_non_null()
|
||||
&& directive
|
||||
.item
|
||||
.arguments
|
||||
.as_ref()
|
||||
|
@ -79,18 +79,14 @@ impl<'a> Visitor<'a> for ProvidedNonNullArguments {
|
|||
fn field_error_message(field_name: &str, arg_name: &str, type_name: &str) -> String {
|
||||
format!(
|
||||
r#"Field "{}" argument "{}" of type "{}" is required but not provided"#,
|
||||
field_name,
|
||||
arg_name,
|
||||
type_name
|
||||
field_name, arg_name, type_name
|
||||
)
|
||||
}
|
||||
|
||||
fn directive_error_message(directive_name: &str, arg_name: &str, type_name: &str) -> String {
|
||||
format!(
|
||||
r#"Directive "@{}" argument "{}" of type "{}" is required but not provided"#,
|
||||
directive_name,
|
||||
arg_name,
|
||||
type_name
|
||||
directive_name, arg_name, type_name
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -39,8 +39,7 @@ impl<'a> Visitor<'a> for ScalarLeafs {
|
|||
fn no_allowed_error_message(field_name: &str, type_name: &str) -> String {
|
||||
format!(
|
||||
r#"Field "{}" must not have a selection since type {} has no subfields"#,
|
||||
field_name,
|
||||
type_name
|
||||
field_name, type_name
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -30,8 +30,7 @@ impl<'a> Visitor<'a> for UniqueVariableNames {
|
|||
fn error_message(var_name: &str, type_name: &str) -> String {
|
||||
format!(
|
||||
"Variable \"{}\" cannot be of non-input type \"{}\"",
|
||||
var_name,
|
||||
type_name
|
||||
var_name, type_name
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -148,9 +148,7 @@ impl<'a> Visitor<'a> for VariableInAllowedPosition<'a> {
|
|||
fn error_message(var_name: &str, type_name: &str, expected_type_name: &str) -> String {
|
||||
format!(
|
||||
"Variable \"{}\" of type \"{}\" used in position expecting type \"{}\"",
|
||||
var_name,
|
||||
type_name,
|
||||
expected_type_name
|
||||
var_name, type_name, expected_type_name
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -236,10 +236,7 @@ impl GraphQLType for Cat {
|
|||
|
||||
registry
|
||||
.build_object_type::<Self>(i, fields)
|
||||
.interfaces(&[
|
||||
registry.get_type::<Being>(i),
|
||||
registry.get_type::<Pet>(i),
|
||||
])
|
||||
.interfaces(&[registry.get_type::<Being>(i), registry.get_type::<Pet>(i)])
|
||||
.into_meta()
|
||||
}
|
||||
}
|
||||
|
@ -434,9 +431,7 @@ impl GraphQLType for ComplicatedArgs {
|
|||
.argument(registry.arg::<Option<ID>>("idArg", i)),
|
||||
registry
|
||||
.field::<Option<String>>("stringListArgField", i)
|
||||
.argument(
|
||||
registry.arg::<Option<Vec<Option<String>>>>("stringListArg", i),
|
||||
),
|
||||
.argument(registry.arg::<Option<Vec<Option<String>>>>("stringListArg", i)),
|
||||
registry
|
||||
.field::<Option<String>>("complexArgField", i)
|
||||
.argument(registry.arg::<Option<ComplexInput>>("complexArg", i)),
|
||||
|
|
|
@ -3,7 +3,6 @@ use ast::{Directive, Document, Field, Fragment, FragmentSpread, InlineFragment,
|
|||
use parser::Spanning;
|
||||
use validation::ValidatorContext;
|
||||
|
||||
|
||||
#[doc(hidden)]
|
||||
pub trait Visitor<'a> {
|
||||
fn enter_document(&mut self, _: &mut ValidatorContext<'a>, _: &'a Document) {}
|
||||
|
|
|
@ -22,26 +22,29 @@ fn visit_definitions<'a, V: Visitor<'a>>(
|
|||
for def in d {
|
||||
let def_type = match *def {
|
||||
Definition::Fragment(Spanning {
|
||||
item: Fragment {
|
||||
type_condition: Spanning { item: name, .. },
|
||||
..
|
||||
},
|
||||
item:
|
||||
Fragment {
|
||||
type_condition: Spanning { item: name, .. },
|
||||
..
|
||||
},
|
||||
..
|
||||
}) => Some(Type::NonNullNamed(Cow::Borrowed(name))),
|
||||
Definition::Operation(Spanning {
|
||||
item: Operation {
|
||||
operation_type: OperationType::Query,
|
||||
..
|
||||
},
|
||||
item:
|
||||
Operation {
|
||||
operation_type: OperationType::Query,
|
||||
..
|
||||
},
|
||||
..
|
||||
}) => Some(Type::NonNullNamed(Cow::Borrowed(
|
||||
ctx.schema.concrete_query_type().name().unwrap(),
|
||||
))),
|
||||
Definition::Operation(Spanning {
|
||||
item: Operation {
|
||||
operation_type: OperationType::Mutation,
|
||||
..
|
||||
},
|
||||
item:
|
||||
Operation {
|
||||
operation_type: OperationType::Mutation,
|
||||
..
|
||||
},
|
||||
..
|
||||
}) => ctx.schema
|
||||
.concrete_mutation_type()
|
||||
|
@ -284,8 +287,10 @@ fn visit_input_value<'a, V: Visitor<'a>>(
|
|||
_ => None,
|
||||
});
|
||||
|
||||
ctx.with_pushed_input_type(inner_type.as_ref(), |ctx| for value in ls {
|
||||
visit_input_value(v, ctx, value);
|
||||
ctx.with_pushed_input_type(inner_type.as_ref(), |ctx| {
|
||||
for value in ls {
|
||||
visit_input_value(v, ctx, value);
|
||||
}
|
||||
})
|
||||
}
|
||||
_ => (),
|
||||
|
|
|
@ -125,13 +125,18 @@ impl ToInputValue for Value {
|
|||
Value::Float(f) => InputValue::Float(f),
|
||||
Value::String(ref s) => InputValue::String(s.clone()),
|
||||
Value::Boolean(b) => InputValue::Boolean(b),
|
||||
Value::List(ref l) => {
|
||||
InputValue::List(l.iter().map(|x| Spanning::unlocated(x.to_input_value())).collect())
|
||||
}
|
||||
Value::List(ref l) => InputValue::List(
|
||||
l.iter()
|
||||
.map(|x| Spanning::unlocated(x.to_input_value()))
|
||||
.collect(),
|
||||
),
|
||||
Value::Object(ref o) => InputValue::Object(
|
||||
o.iter()
|
||||
.map(|(k, v)| {
|
||||
(Spanning::unlocated(k.clone()), Spanning::unlocated(v.to_input_value()))
|
||||
(
|
||||
Spanning::unlocated(k.clone()),
|
||||
Spanning::unlocated(v.to_input_value()),
|
||||
)
|
||||
})
|
||||
.collect(),
|
||||
),
|
||||
|
@ -169,11 +174,14 @@ impl From<f64> for Value {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T> From<Option<T>> for Value where Value: From<T> {
|
||||
impl<T> From<Option<T>> for Value
|
||||
where
|
||||
Value: From<T>,
|
||||
{
|
||||
fn from(v: Option<T>) -> Value {
|
||||
match v {
|
||||
Some(v) => Value::from(v),
|
||||
None => Value::null()
|
||||
None => Value::null(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -215,52 +223,34 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn value_macro_string() {
|
||||
assert_eq!(
|
||||
graphql_value!("test"),
|
||||
Value::string("test")
|
||||
);
|
||||
assert_eq!(graphql_value!("test"), Value::string("test"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn value_macro_int() {
|
||||
assert_eq!(
|
||||
graphql_value!(123),
|
||||
Value::int(123)
|
||||
);
|
||||
assert_eq!(graphql_value!(123), Value::int(123));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn value_macro_float() {
|
||||
assert_eq!(
|
||||
graphql_value!(123.5),
|
||||
Value::float(123.5)
|
||||
);
|
||||
assert_eq!(graphql_value!(123.5), Value::float(123.5));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn value_macro_boolean() {
|
||||
assert_eq!(
|
||||
graphql_value!(false),
|
||||
Value::boolean(false)
|
||||
);
|
||||
assert_eq!(graphql_value!(false), Value::boolean(false));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn value_macro_option() {
|
||||
assert_eq!(
|
||||
graphql_value!(Some("test")),
|
||||
Value::string("test")
|
||||
);
|
||||
assert_eq!(
|
||||
graphql_value!(None),
|
||||
Value::null()
|
||||
);
|
||||
assert_eq!(graphql_value!(Some("test")), Value::string("test"));
|
||||
assert_eq!(graphql_value!(None), Value::null());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn value_macro_list() {
|
||||
assert_eq!(
|
||||
graphql_value!([ 123, "Test", false ]),
|
||||
graphql_value!([123, "Test", false]),
|
||||
Value::list(vec![
|
||||
Value::int(123),
|
||||
Value::string("Test"),
|
||||
|
@ -268,10 +258,10 @@ mod tests {
|
|||
])
|
||||
);
|
||||
assert_eq!(
|
||||
graphql_value!([ 123, [ 456 ], 789 ]),
|
||||
graphql_value!([123, [456], 789]),
|
||||
Value::list(vec![
|
||||
Value::int(123),
|
||||
Value::list(vec![ Value::int(456) ]),
|
||||
Value::list(vec![Value::int(456)]),
|
||||
Value::int(789),
|
||||
])
|
||||
);
|
||||
|
@ -281,10 +271,11 @@ mod tests {
|
|||
fn value_macro_object() {
|
||||
assert_eq!(
|
||||
graphql_value!({ "key": 123, "next": true }),
|
||||
Value::object(vec![
|
||||
("key", Value::int(123)),
|
||||
("next", Value::boolean(true)),
|
||||
].into_iter().collect())
|
||||
Value::object(
|
||||
vec![("key", Value::int(123)), ("next", Value::boolean(true))]
|
||||
.into_iter()
|
||||
.collect()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@ use quote::Tokens;
|
|||
|
||||
use util::*;
|
||||
|
||||
|
||||
#[derive(Default, Debug)]
|
||||
struct EnumAttrs {
|
||||
name: Option<String>,
|
||||
|
@ -14,7 +13,7 @@ struct EnumAttrs {
|
|||
|
||||
impl EnumAttrs {
|
||||
fn from_input(input: &DeriveInput) -> EnumAttrs {
|
||||
let mut res = EnumAttrs{
|
||||
let mut res = EnumAttrs {
|
||||
name: None,
|
||||
description: None,
|
||||
/// Flag to specify whether the calling crate is the "juniper" crate itself.
|
||||
|
@ -38,8 +37,8 @@ impl EnumAttrs {
|
|||
res.internal = true;
|
||||
continue;
|
||||
}
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
panic!(format!(
|
||||
"Unknown attribute for #[derive(GraphQLEnum)]: {:?}",
|
||||
|
@ -87,7 +86,6 @@ impl EnumVariantAttrs {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
pub fn impl_enum(ast: &syn::DeriveInput) -> Tokens {
|
||||
let variants = match ast.body {
|
||||
Body::Enum(ref var) => var,
|
||||
|
@ -171,7 +169,9 @@ pub fn impl_enum(ast: &syn::DeriveInput) -> Tokens {
|
|||
Some(#name)
|
||||
}
|
||||
|
||||
fn meta<'r>(_: &(), registry: &mut _juniper::Registry<'r>) -> _juniper::meta::MetaType<'r> {
|
||||
fn meta<'r>(_: &(), registry: &mut _juniper::Registry<'r>)
|
||||
-> _juniper::meta::MetaType<'r>
|
||||
{
|
||||
let meta = registry.build_enum_type::<#ident>(&(), &[
|
||||
#(#values)*
|
||||
]);
|
||||
|
@ -179,7 +179,12 @@ pub fn impl_enum(ast: &syn::DeriveInput) -> Tokens {
|
|||
meta.into_meta()
|
||||
}
|
||||
|
||||
fn resolve(&self, _: &(), _: Option<&[_juniper::Selection]>, _: &_juniper::Executor<Self::Context>) -> _juniper::Value {
|
||||
fn resolve(
|
||||
&self,
|
||||
_: &(),
|
||||
_: Option<&[_juniper::Selection]>,
|
||||
_: &_juniper::Executor<Self::Context>
|
||||
) -> _juniper::Value {
|
||||
match self {
|
||||
#(#resolves)*
|
||||
}
|
||||
|
|
|
@ -4,7 +4,6 @@ use quote::Tokens;
|
|||
|
||||
use util::*;
|
||||
|
||||
|
||||
#[derive(Default, Debug)]
|
||||
struct ObjAttrs {
|
||||
name: Option<String>,
|
||||
|
@ -33,8 +32,8 @@ impl ObjAttrs {
|
|||
res.internal = true;
|
||||
continue;
|
||||
}
|
||||
},
|
||||
_ => {},
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
panic!(format!(
|
||||
"Unknown attribute for #[derive(GraphQLInputObject)]: {:?}",
|
||||
|
@ -80,7 +79,7 @@ impl ObjFieldAttrs {
|
|||
continue;
|
||||
}
|
||||
}
|
||||
_ => {},
|
||||
_ => {}
|
||||
}
|
||||
panic!(format!(
|
||||
"Unknown attribute for #[derive(GraphQLInputObject)]: {:?}",
|
||||
|
@ -144,7 +143,7 @@ pub fn impl_input_object(ast: &syn::DeriveInput) -> Tokens {
|
|||
|
||||
let default = {
|
||||
if field_attrs.default {
|
||||
Some(quote! { Default::default() } )
|
||||
Some(quote! { Default::default() })
|
||||
} else {
|
||||
match field_attrs.default_expr {
|
||||
Some(ref def) => match syn::parse_token_trees(def) {
|
||||
|
@ -221,7 +220,10 @@ pub fn impl_input_object(ast: &syn::DeriveInput) -> Tokens {
|
|||
Some(#name)
|
||||
}
|
||||
|
||||
fn meta<'r>(_: &(), registry: &mut _juniper::Registry<'r>) -> _juniper::meta::MetaType<'r> {
|
||||
fn meta<'r>(
|
||||
_: &(),
|
||||
registry: &mut _juniper::Registry<'r>
|
||||
) -> _juniper::meta::MetaType<'r> {
|
||||
let fields = &[
|
||||
#(#meta_fields)*
|
||||
];
|
||||
|
|
|
@ -135,7 +135,6 @@ pub fn impl_object(ast: &syn::DeriveInput) -> Tokens {
|
|||
|
||||
// Build from_input clause.
|
||||
|
||||
|
||||
let resolver = quote!{
|
||||
#name => executor.resolve_with_ctx(&(), &self.#field_ident),
|
||||
};
|
||||
|
@ -155,7 +154,10 @@ pub fn impl_object(ast: &syn::DeriveInput) -> Tokens {
|
|||
#name.to_string()
|
||||
}
|
||||
|
||||
fn meta<'r>(_: &(), registry: &mut ::juniper::Registry<'r>) -> ::juniper::meta::MetaType<'r> {
|
||||
fn meta<'r>(
|
||||
_: &(),
|
||||
registry: &mut ::juniper::Registry<'r>
|
||||
) -> ::juniper::meta::MetaType<'r> {
|
||||
let fields = &[
|
||||
#(#meta_fields)*
|
||||
];
|
||||
|
@ -164,8 +166,13 @@ pub fn impl_object(ast: &syn::DeriveInput) -> Tokens {
|
|||
builder.into_meta()
|
||||
}
|
||||
|
||||
fn resolve_field(&self, _: &(), field_name: &str, _: &::juniper::Arguments, executor: &::juniper::Executor<Self::Context>)
|
||||
-> ::juniper::ExecutionResult
|
||||
fn resolve_field(
|
||||
&self,
|
||||
_: &(),
|
||||
field_name: &str,
|
||||
_: &::juniper::Arguments,
|
||||
executor: &::juniper::Executor<Self::Context>
|
||||
) -> ::juniper::ExecutionResult
|
||||
{
|
||||
|
||||
match field_name {
|
||||
|
|
|
@ -7,9 +7,9 @@
|
|||
#![recursion_limit = "1024"]
|
||||
|
||||
extern crate proc_macro;
|
||||
extern crate syn;
|
||||
#[macro_use]
|
||||
extern crate quote;
|
||||
extern crate syn;
|
||||
|
||||
mod util;
|
||||
mod derive_enum;
|
||||
|
|
|
@ -87,8 +87,7 @@ pub(crate) fn to_upper_snake_case(s: &str) -> String {
|
|||
for c in s.chars() {
|
||||
if c == '_' {
|
||||
last_lower = false;
|
||||
}
|
||||
else if c.is_lowercase() {
|
||||
} else if c.is_lowercase() {
|
||||
last_lower = true;
|
||||
} else if c.is_uppercase() {
|
||||
if last_lower {
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
extern crate iron;
|
||||
extern crate mount;
|
||||
extern crate logger;
|
||||
extern crate serde;
|
||||
extern crate juniper;
|
||||
extern crate juniper_iron;
|
||||
extern crate logger;
|
||||
extern crate mount;
|
||||
extern crate serde;
|
||||
|
||||
use std::env;
|
||||
|
||||
|
|
|
@ -101,13 +101,13 @@ supported.
|
|||
|
||||
*/
|
||||
|
||||
extern crate serde_json;
|
||||
extern crate juniper;
|
||||
extern crate urlencoded;
|
||||
#[macro_use]
|
||||
extern crate iron;
|
||||
#[cfg(test)]
|
||||
extern crate iron_test;
|
||||
extern crate juniper;
|
||||
extern crate serde_json;
|
||||
extern crate urlencoded;
|
||||
|
||||
use iron::prelude::*;
|
||||
use iron::middleware::Handler;
|
||||
|
@ -151,14 +151,11 @@ pub struct GraphiQLHandler {
|
|||
graphql_url: String,
|
||||
}
|
||||
|
||||
|
||||
fn get_single_value<T>(mut values: Vec<T>) -> IronResult<T> {
|
||||
if values.len() == 1 {
|
||||
Ok(values.remove(0))
|
||||
} else {
|
||||
Err(
|
||||
GraphQLIronError::InvalidData("Duplicate URL query parameter").into(),
|
||||
)
|
||||
Err(GraphQLIronError::InvalidData("Duplicate URL query parameter").into())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -172,22 +169,22 @@ fn parse_url_param(params: Option<Vec<String>>) -> IronResult<Option<String>> {
|
|||
|
||||
fn parse_variable_param(params: Option<Vec<String>>) -> IronResult<Option<InputValue>> {
|
||||
if let Some(values) = params {
|
||||
Ok(serde_json::from_str::<InputValue>(
|
||||
get_single_value(values)?.as_ref(),
|
||||
).map(Some)
|
||||
.map_err(GraphQLIronError::Serde)?)
|
||||
Ok(
|
||||
serde_json::from_str::<InputValue>(get_single_value(values)?.as_ref())
|
||||
.map(Some)
|
||||
.map_err(GraphQLIronError::Serde)?,
|
||||
)
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl<'a, CtxFactory, Query, Mutation, CtxT> GraphQLHandler<'a, CtxFactory, Query, Mutation, CtxT>
|
||||
where
|
||||
CtxFactory: Fn(&mut Request) -> CtxT + Send + Sync + 'static,
|
||||
CtxT: 'static,
|
||||
Query: GraphQLType<Context = CtxT, TypeInfo=()> + Send + Sync + 'static,
|
||||
Mutation: GraphQLType<Context = CtxT, TypeInfo=()> + Send + Sync + 'static,
|
||||
Query: GraphQLType<Context = CtxT, TypeInfo = ()> + Send + Sync + 'static,
|
||||
Mutation: GraphQLType<Context = CtxT, TypeInfo = ()> + Send + Sync + 'static,
|
||||
{
|
||||
/// Build a new GraphQL handler
|
||||
///
|
||||
|
@ -202,7 +199,6 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
fn handle_get(&self, req: &mut Request) -> IronResult<http::GraphQLRequest> {
|
||||
let url_query_string = req.get_mut::<UrlEncodedQuery>()
|
||||
.map_err(|e| GraphQLIronError::Url(e))?;
|
||||
|
@ -223,9 +219,10 @@ where
|
|||
let mut request_payload = String::new();
|
||||
itry!(req.body.read_to_string(&mut request_payload));
|
||||
|
||||
Ok(serde_json::from_str::<http::GraphQLRequest>(
|
||||
request_payload.as_str(),
|
||||
).map_err(|err| GraphQLIronError::Serde(err))?)
|
||||
Ok(
|
||||
serde_json::from_str::<http::GraphQLRequest>(request_payload.as_str())
|
||||
.map_err(|err| GraphQLIronError::Serde(err))?,
|
||||
)
|
||||
}
|
||||
|
||||
fn execute(&self, context: &CtxT, request: http::GraphQLRequest) -> IronResult<Response> {
|
||||
|
@ -258,8 +255,8 @@ impl<'a, CtxFactory, Query, Mutation, CtxT> Handler
|
|||
where
|
||||
CtxFactory: Fn(&mut Request) -> CtxT + Send + Sync + 'static,
|
||||
CtxT: 'static,
|
||||
Query: GraphQLType<Context = CtxT, TypeInfo=()> + Send + Sync + 'static,
|
||||
Mutation: GraphQLType<Context = CtxT, TypeInfo=()> + Send + Sync + 'static,
|
||||
Query: GraphQLType<Context = CtxT, TypeInfo = ()> + Send + Sync + 'static,
|
||||
Mutation: GraphQLType<Context = CtxT, TypeInfo = ()> + Send + Sync + 'static,
|
||||
'a: 'static,
|
||||
{
|
||||
fn handle(&self, mut req: &mut Request) -> IronResult<Response> {
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
#![feature(plugin)]
|
||||
#![plugin(rocket_codegen)]
|
||||
|
||||
extern crate rocket;
|
||||
extern crate juniper;
|
||||
extern crate juniper_rocket;
|
||||
extern crate rocket;
|
||||
|
||||
use rocket::response::content;
|
||||
use rocket::State;
|
||||
|
|
|
@ -40,8 +40,8 @@ Check the LICENSE file for details.
|
|||
#![plugin(rocket_codegen)]
|
||||
|
||||
extern crate juniper;
|
||||
extern crate serde_json;
|
||||
extern crate rocket;
|
||||
extern crate serde_json;
|
||||
|
||||
use std::io::{Cursor, Read};
|
||||
use std::error::Error;
|
||||
|
@ -123,9 +123,8 @@ impl<'f> FromForm<'f> for GraphQLRequest {
|
|||
}
|
||||
"operation_name" => {
|
||||
if operation_name.is_some() {
|
||||
return Err(
|
||||
"Operation name parameter must not occur more than once".to_owned(),
|
||||
);
|
||||
return Err("Operation name parameter must not occur more than once"
|
||||
.to_owned());
|
||||
} else {
|
||||
match value.url_decode() {
|
||||
Ok(v) => operation_name = Some(v),
|
||||
|
@ -135,20 +134,15 @@ impl<'f> FromForm<'f> for GraphQLRequest {
|
|||
}
|
||||
"variables" => {
|
||||
if variables.is_some() {
|
||||
return Err(
|
||||
"Variables parameter must not occur more than once".to_owned(),
|
||||
);
|
||||
return Err("Variables parameter must not occur more than once".to_owned());
|
||||
} else {
|
||||
let decoded;
|
||||
match value.url_decode() {
|
||||
Ok(v) => decoded = v,
|
||||
Err(e) => return Err(e.description().to_string()),
|
||||
}
|
||||
variables = Some(serde_json::from_str::<InputValue>(&decoded).map_err(
|
||||
|err| {
|
||||
err.description().to_owned()
|
||||
},
|
||||
)?);
|
||||
variables = Some(serde_json::from_str::<InputValue>(&decoded)
|
||||
.map_err(|err| err.description().to_owned())?);
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
|
@ -160,9 +154,11 @@ impl<'f> FromForm<'f> for GraphQLRequest {
|
|||
}
|
||||
|
||||
if let Some(query) = query {
|
||||
Ok(GraphQLRequest(
|
||||
http::GraphQLRequest::new(query, operation_name, variables),
|
||||
))
|
||||
Ok(GraphQLRequest(http::GraphQLRequest::new(
|
||||
query,
|
||||
operation_name,
|
||||
variables,
|
||||
)))
|
||||
} else {
|
||||
Err("Query parameter missing".to_owned())
|
||||
}
|
||||
|
@ -193,13 +189,11 @@ impl<'r> Responder<'r> for GraphQLResponse {
|
|||
fn respond_to(self, _: &Request) -> Result<Response<'r>, Status> {
|
||||
let GraphQLResponse(status, body) = self;
|
||||
|
||||
Ok(
|
||||
Response::build()
|
||||
.header(ContentType::new("application", "json"))
|
||||
.status(status)
|
||||
.sized_body(Cursor::new(body))
|
||||
.finalize(),
|
||||
)
|
||||
Ok(Response::build()
|
||||
.header(ContentType::new("application", "json"))
|
||||
.status(status)
|
||||
.sized_body(Cursor::new(body))
|
||||
.finalize())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -208,7 +202,7 @@ mod fromform_tests {
|
|||
use super::*;
|
||||
use std::str;
|
||||
use juniper::InputValue;
|
||||
use rocket::request::{FromForm, FormItems};
|
||||
use rocket::request::{FormItems, FromForm};
|
||||
|
||||
fn check_error(input: &str, error: &str, strict: bool) {
|
||||
let mut items = FormItems::from(input);
|
||||
|
@ -224,16 +218,16 @@ mod fromform_tests {
|
|||
|
||||
#[test]
|
||||
fn test_no_query() {
|
||||
check_error("operation_name=foo&variables={}", "Query parameter missing", false);
|
||||
check_error(
|
||||
"operation_name=foo&variables={}",
|
||||
"Query parameter missing",
|
||||
false,
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_strict() {
|
||||
check_error(
|
||||
"query=test&foo=bar",
|
||||
"Prohibited extra field \'foo\'",
|
||||
true,
|
||||
);
|
||||
check_error("query=test&foo=bar", "Prohibited extra field \'foo\'", true);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
|
@ -9,8 +9,7 @@ use juniper::{self, FromInputValue, GraphQLType, InputValue, ToInputValue};
|
|||
enum SomeEnum {
|
||||
Regular,
|
||||
|
||||
#[graphql(name = "full", description = "field descr", deprecated = "depr")]
|
||||
Full,
|
||||
#[graphql(name = "full", description = "field descr", deprecated = "depr")] Full,
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -26,14 +25,20 @@ fn test_derived_enum() {
|
|||
assert_eq!(meta.description(), Some(&"enum descr".to_string()));
|
||||
|
||||
// Test Regular variant.
|
||||
assert_eq!(SomeEnum::Regular.to_input_value(), InputValue::String("REGULAR".into()));
|
||||
assert_eq!(
|
||||
SomeEnum::Regular.to_input_value(),
|
||||
InputValue::String("REGULAR".into())
|
||||
);
|
||||
assert_eq!(
|
||||
FromInputValue::from_input_value(&InputValue::String("REGULAR".into())),
|
||||
Some(SomeEnum::Regular)
|
||||
);
|
||||
|
||||
// Test FULL variant.
|
||||
assert_eq!(SomeEnum::Full.to_input_value(), InputValue::String("full".into()));
|
||||
assert_eq!(
|
||||
SomeEnum::Full.to_input_value(),
|
||||
InputValue::String("full".into())
|
||||
);
|
||||
assert_eq!(
|
||||
FromInputValue::from_input_value(&InputValue::String("full".into())),
|
||||
Some(SomeEnum::Full)
|
||||
|
|
|
@ -8,11 +8,9 @@ use juniper::{self, FromInputValue, GraphQLType, InputValue};
|
|||
#[graphql(name = "MyInput", description = "input descr")]
|
||||
struct Input {
|
||||
regular_field: String,
|
||||
#[graphql(name = "haha", default = "33", description = "haha descr")]
|
||||
c: i32,
|
||||
#[graphql(name = "haha", default = "33", description = "haha descr")] c: i32,
|
||||
|
||||
#[graphql(default)]
|
||||
other: Option<bool>,
|
||||
#[graphql(default)] other: Option<bool>,
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -32,11 +30,14 @@ fn test_derived_input_object() {
|
|||
})).unwrap();
|
||||
|
||||
let output_no_defaults: Input = FromInputValue::from_input_value(&input_no_defaults).unwrap();
|
||||
assert_eq!(output_no_defaults, Input{
|
||||
regular_field: "a".into(),
|
||||
c: 33,
|
||||
other: None,
|
||||
});
|
||||
assert_eq!(
|
||||
output_no_defaults,
|
||||
Input {
|
||||
regular_field: "a".into(),
|
||||
c: 33,
|
||||
other: None,
|
||||
}
|
||||
);
|
||||
|
||||
// Test with all values supplied.
|
||||
|
||||
|
@ -47,9 +48,12 @@ fn test_derived_input_object() {
|
|||
})).unwrap();
|
||||
|
||||
let output: Input = FromInputValue::from_input_value(&input).unwrap();
|
||||
assert_eq!(output, Input{
|
||||
regular_field: "a".into(),
|
||||
c: 55,
|
||||
other: Some(true),
|
||||
});
|
||||
assert_eq!(
|
||||
output,
|
||||
Input {
|
||||
regular_field: "a".into(),
|
||||
c: 55,
|
||||
other: Some(true),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
|
|
@ -8,8 +8,7 @@ use juniper::{self, execute, EmptyMutation, GraphQLType, RootNode, Value, Variab
|
|||
#[graphql(name = "MyObj", description = "obj descr")]
|
||||
struct Obj {
|
||||
regular_field: bool,
|
||||
#[graphql(name = "renamedField", description = "descr", deprecation = "field descr")]
|
||||
c: i32,
|
||||
#[graphql(name = "renamedField", description = "descr", deprecation = "field descr")] c: i32,
|
||||
}
|
||||
|
||||
#[derive(GraphQLObject, Debug, PartialEq)]
|
||||
|
@ -59,14 +58,26 @@ fn test_derived_object() {
|
|||
let schema = RootNode::new(Query, EmptyMutation::<()>::new());
|
||||
|
||||
assert_eq!(
|
||||
execute(doc, None, &schema, &Variables::new(), &()),
|
||||
Ok((Value::object(vec![
|
||||
("obj", Value::object(vec![
|
||||
("regularField", Value::boolean(true)),
|
||||
("renamedField", Value::int(22)),
|
||||
].into_iter().collect())),
|
||||
].into_iter().collect()),
|
||||
vec![])));
|
||||
execute(doc, None, &schema, &Variables::new(), &()),
|
||||
Ok((
|
||||
Value::object(
|
||||
vec![
|
||||
(
|
||||
"obj",
|
||||
Value::object(
|
||||
vec![
|
||||
("regularField", Value::boolean(true)),
|
||||
("renamedField", Value::int(22)),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
),
|
||||
].into_iter()
|
||||
.collect()
|
||||
),
|
||||
vec![]
|
||||
))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -85,13 +96,31 @@ fn test_derived_object_nested() {
|
|||
|
||||
assert_eq!(
|
||||
execute(doc, None, &schema, &Variables::new(), &()),
|
||||
Ok((Value::object(vec![
|
||||
("nested", Value::object(vec![
|
||||
("obj", Value::object(vec![
|
||||
("regularField", Value::boolean(false)),
|
||||
("renamedField", Value::int(333)),
|
||||
].into_iter().collect())
|
||||
)].into_iter().collect())),
|
||||
].into_iter().collect()),
|
||||
vec![])));
|
||||
Ok((
|
||||
Value::object(
|
||||
vec![
|
||||
(
|
||||
"nested",
|
||||
Value::object(
|
||||
vec![
|
||||
(
|
||||
"obj",
|
||||
Value::object(
|
||||
vec![
|
||||
("regularField", Value::boolean(false)),
|
||||
("renamedField", Value::int(333)),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
),
|
||||
].into_iter()
|
||||
.collect(),
|
||||
),
|
||||
),
|
||||
].into_iter()
|
||||
.collect()
|
||||
),
|
||||
vec![]
|
||||
))
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue