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