Fixes Issue 914 (#915)
* Add failing tests * Fix failing test * cargo fmt
This commit is contained in:
parent
5225b9e06c
commit
5ae930bfc7
3 changed files with 136 additions and 3 deletions
119
integration_tests/juniper_tests/src/issue_914.rs
Normal file
119
integration_tests/juniper_tests/src/issue_914.rs
Normal file
|
@ -0,0 +1,119 @@
|
|||
use juniper::*;
|
||||
|
||||
struct Query;
|
||||
|
||||
#[derive(GraphQLObject)]
|
||||
struct Foo {
|
||||
bar: Bar,
|
||||
}
|
||||
|
||||
#[derive(GraphQLObject)]
|
||||
struct Bar {
|
||||
a: i32,
|
||||
b: i32,
|
||||
baz: Baz,
|
||||
}
|
||||
|
||||
#[derive(GraphQLObject)]
|
||||
struct Baz {
|
||||
c: i32,
|
||||
d: i32,
|
||||
}
|
||||
|
||||
#[graphql_object]
|
||||
impl Query {
|
||||
fn foo() -> Foo {
|
||||
let baz = Baz { c: 1, d: 2 };
|
||||
let bar = Bar { a: 1, b: 2, baz };
|
||||
Foo { bar }
|
||||
}
|
||||
}
|
||||
|
||||
type Schema = juniper::RootNode<'static, Query, EmptyMutation, EmptySubscription>;
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_fragments_with_nested_objects_dont_override_previous_selections() {
|
||||
let query = r#"
|
||||
query Query {
|
||||
foo {
|
||||
...BarA
|
||||
...BarB
|
||||
...BazC
|
||||
...BazD
|
||||
}
|
||||
}
|
||||
|
||||
fragment BarA on Foo {
|
||||
bar {
|
||||
a
|
||||
}
|
||||
}
|
||||
|
||||
fragment BarB on Foo {
|
||||
bar {
|
||||
b
|
||||
}
|
||||
}
|
||||
|
||||
fragment BazC on Foo {
|
||||
bar {
|
||||
baz {
|
||||
c
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fragment BazD on Foo {
|
||||
bar {
|
||||
baz {
|
||||
d
|
||||
}
|
||||
}
|
||||
}
|
||||
"#;
|
||||
|
||||
let (async_value, errors) = juniper::execute(
|
||||
query,
|
||||
None,
|
||||
&Schema::new(Query, EmptyMutation::new(), EmptySubscription::new()),
|
||||
&Variables::new(),
|
||||
&(),
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
assert_eq!(errors.len(), 0);
|
||||
|
||||
let (sync_value, errors) = juniper::execute_sync(
|
||||
query,
|
||||
None,
|
||||
&Schema::new(Query, EmptyMutation::new(), EmptySubscription::new()),
|
||||
&Variables::new(),
|
||||
&(),
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(errors.len(), 0);
|
||||
|
||||
assert_eq!(async_value, sync_value);
|
||||
|
||||
let bar = async_value
|
||||
.as_object_value()
|
||||
.unwrap()
|
||||
.get_field_value("foo")
|
||||
.unwrap()
|
||||
.as_object_value()
|
||||
.unwrap()
|
||||
.get_field_value("bar")
|
||||
.unwrap()
|
||||
.as_object_value()
|
||||
.unwrap();
|
||||
assert!(bar.contains_field("a"), "Field a should be selected");
|
||||
assert!(bar.contains_field("b"), "Field b should be selected");
|
||||
|
||||
let baz = bar
|
||||
.get_field_value("baz")
|
||||
.unwrap()
|
||||
.as_object_value()
|
||||
.unwrap();
|
||||
assert!(baz.contains_field("c"), "Field c should be selected");
|
||||
assert!(baz.contains_field("d"), "Field d should be selected");
|
||||
}
|
|
@ -19,4 +19,6 @@ mod issue_407;
|
|||
#[cfg(test)]
|
||||
mod issue_500;
|
||||
#[cfg(test)]
|
||||
mod issue_914;
|
||||
#[cfg(test)]
|
||||
mod pre_parse;
|
||||
|
|
|
@ -28,14 +28,26 @@ impl<S> Object<S> {
|
|||
|
||||
/// Add a new field with a value
|
||||
///
|
||||
/// If there is already a field with the same name the old value
|
||||
/// is returned
|
||||
/// If there is already a field for the given key
|
||||
/// any both values are objects, they are merged.
|
||||
///
|
||||
/// Otherwise the existing value is replaced and
|
||||
/// returned.
|
||||
pub fn add_field<K>(&mut self, k: K, value: Value<S>) -> Option<Value<S>>
|
||||
where
|
||||
K: Into<String>,
|
||||
for<'a> &'a str: PartialEq<K>,
|
||||
{
|
||||
self.key_value_list.insert(k.into(), value)
|
||||
let key: String = k.into();
|
||||
match (value, self.key_value_list.get_mut(&key)) {
|
||||
(Value::<S>::Object(obj_val), Some(Value::<S>::Object(existing_obj))) => {
|
||||
for (key, val) in obj_val.into_iter() {
|
||||
existing_obj.add_field::<String>(key, val);
|
||||
}
|
||||
None
|
||||
}
|
||||
(non_obj_val, _) => self.key_value_list.insert(key, non_obj_val),
|
||||
}
|
||||
}
|
||||
|
||||
/// Check if the object already contains a field with the given name
|
||||
|
|
Loading…
Reference in a new issue