Don't assume lookaheads are always fields
Fixes https://github.com/graphql-rust/juniper/issues/398.
This commit is contained in:
parent
55a9a0a2ce
commit
4016d38d3d
3 changed files with 85 additions and 15 deletions
67
integration_tests/juniper_tests/src/issue_398.rs
Normal file
67
integration_tests/juniper_tests/src/issue_398.rs
Normal 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();
|
||||||
|
}
|
|
@ -4,3 +4,5 @@ mod codegen;
|
||||||
mod custom_scalar;
|
mod custom_scalar;
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod issue_371;
|
mod issue_371;
|
||||||
|
#[cfg(test)]
|
||||||
|
mod issue_398;
|
||||||
|
|
|
@ -518,22 +518,23 @@ where
|
||||||
};
|
};
|
||||||
self.parent_selection_set
|
self.parent_selection_set
|
||||||
.map(|p| {
|
.map(|p| {
|
||||||
let p = p
|
let found_field = p.iter().find(|&x| {
|
||||||
.iter()
|
match *x {
|
||||||
.find(|&x| {
|
Selection::Field(ref field) => {
|
||||||
match *x {
|
let field = &field.item;
|
||||||
Selection::Field(ref field) => {
|
// TODO: support excludes.
|
||||||
let field = &field.item;
|
let name = field.name.item;
|
||||||
// TODO: support excludes.
|
let alias = field.alias.as_ref().map(|a| a.item);
|
||||||
let name = field.name.item;
|
alias.unwrap_or(name) == field_name
|
||||||
let alias = field.alias.as_ref().map(|a| a.item);
|
|
||||||
alias.unwrap_or(name) == field_name
|
|
||||||
}
|
|
||||||
_ => false,
|
|
||||||
}
|
}
|
||||||
})
|
_ => false,
|
||||||
.expect("lookahead to find the field");
|
}
|
||||||
LookAheadSelection::build_from_selection(&p, self.variables, self.fragments)
|
});
|
||||||
|
if let Some(p) = found_field {
|
||||||
|
LookAheadSelection::build_from_selection(&p, self.variables, self.fragments)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.filter(|s| s.is_some())
|
.filter(|s| s.is_some())
|
||||||
.unwrap_or_else(|| {
|
.unwrap_or_else(|| {
|
||||||
|
|
Loading…
Reference in a new issue