Don't assume lookaheads are always fields

Fixes https://github.com/graphql-rust/juniper/issues/398.
This commit is contained in:
Christian Legnitto 2019-07-24 16:17:20 -06:00 committed by theduke
parent 55a9a0a2ce
commit 4016d38d3d
3 changed files with 85 additions and 15 deletions

View file

@ -0,0 +1,67 @@
// Original author of this test is <https://github.com/davidpdrsn>.
use juniper::*;
struct Query;
#[juniper::object]
impl Query {
fn users(executor: &Executor) -> Vec<User> {
// This doesn't cause a panic
executor.look_ahead();
vec![User {
country: Country { id: 1 },
}]
}
}
struct User {
country: Country,
}
#[juniper::object]
impl User {
fn country(&self, executor: &Executor) -> &Country {
// This panics!
executor.look_ahead();
&self.country
}
}
struct Country {
id: i32,
}
#[juniper::object]
impl Country {
fn id(&self) -> i32 {
self.id
}
}
type Schema = juniper::RootNode<'static, Query, EmptyMutation<()>>;
#[test]
fn it_works() {
let _ = juniper::execute(
r#"
query Query {
users {
...userFields
}
}
fragment userFields on User {
country {
id
}
}
"#,
None,
&Schema::new(Query, EmptyMutation::new()),
&Variables::new(),
&(),
)
.unwrap();
}

View file

@ -4,3 +4,5 @@ mod codegen;
mod custom_scalar;
#[cfg(test)]
mod issue_371;
#[cfg(test)]
mod issue_398;

View file

@ -518,9 +518,7 @@ where
};
self.parent_selection_set
.map(|p| {
let p = p
.iter()
.find(|&x| {
let found_field = p.iter().find(|&x| {
match *x {
Selection::Field(ref field) => {
let field = &field.item;
@ -531,9 +529,12 @@ where
}
_ => false,
}
})
.expect("lookahead to find the field");
});
if let Some(p) = found_field {
LookAheadSelection::build_from_selection(&p, self.variables, self.fragments)
} else {
None
}
})
.filter(|s| s.is_some())
.unwrap_or_else(|| {