Support __typename
for unions
See http://graphql.org/learn/queries/#meta-fields. Fixes https://github.com/graphql-rust/juniper/issues/112.
This commit is contained in:
parent
ca9d5c1c1a
commit
203af1ce98
2 changed files with 35 additions and 0 deletions
|
@ -204,6 +204,7 @@ mod union {
|
||||||
let doc = r"
|
let doc = r"
|
||||||
{
|
{
|
||||||
pets {
|
pets {
|
||||||
|
__typename
|
||||||
... on Dog {
|
... on Dog {
|
||||||
name
|
name
|
||||||
woofs
|
woofs
|
||||||
|
@ -228,10 +229,12 @@ mod union {
|
||||||
Value::object(vec![
|
Value::object(vec![
|
||||||
("pets", Value::list(vec![
|
("pets", Value::list(vec![
|
||||||
Value::object(vec![
|
Value::object(vec![
|
||||||
|
("__typename", Value::string("Dog")),
|
||||||
("name", Value::string("Odie")),
|
("name", Value::string("Odie")),
|
||||||
("woofs", Value::boolean(true)),
|
("woofs", Value::boolean(true)),
|
||||||
].into_iter().collect()),
|
].into_iter().collect()),
|
||||||
Value::object(vec![
|
Value::object(vec![
|
||||||
|
("__typename", Value::string("Cat")),
|
||||||
("name", Value::string("Garfield")),
|
("name", Value::string("Garfield")),
|
||||||
("meows", Value::boolean(false)),
|
("meows", Value::boolean(false)),
|
||||||
].into_iter().collect()),
|
].into_iter().collect()),
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use ast::Field;
|
use ast::Field;
|
||||||
|
use schema::meta::MetaType;
|
||||||
use validation::{ValidatorContext, Visitor};
|
use validation::{ValidatorContext, Visitor};
|
||||||
use parser::Spanning;
|
use parser::Spanning;
|
||||||
|
|
||||||
|
@ -16,6 +17,19 @@ 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 {
|
||||||
|
MetaType::Union(..) => {
|
||||||
|
// You can query for `__typename` on a union,
|
||||||
|
// but it isn't a field on the union...it is
|
||||||
|
// instead on the resulting object returned.
|
||||||
|
if field_name.item == "__typename" {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
|
||||||
context.report_error(
|
context.report_error(
|
||||||
&error_message(field_name.item, type_name),
|
&error_message(field_name.item, type_name),
|
||||||
&[field_name.start.clone()],
|
&[field_name.start.clone()],
|
||||||
|
@ -318,6 +332,24 @@ mod tests {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn typename_on_union() {
|
||||||
|
expect_passes_rule(
|
||||||
|
factory,
|
||||||
|
r#"
|
||||||
|
fragment objectFieldSelection on Pet {
|
||||||
|
__typename
|
||||||
|
... on Dog {
|
||||||
|
name
|
||||||
|
}
|
||||||
|
... on Cat {
|
||||||
|
name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn valid_field_in_inline_fragment() {
|
fn valid_field_in_inline_fragment() {
|
||||||
expect_passes_rule(
|
expect_passes_rule(
|
||||||
|
|
Loading…
Reference in a new issue