Fixed a bug in fragment query. #114

This commit is contained in:
Sunli 2020-05-27 15:23:53 +08:00
parent afb2061392
commit 019580595c
2 changed files with 96 additions and 2 deletions

View File

@ -3,7 +3,6 @@ use crate::extensions::{Extension, ResolveInfo};
use crate::parser::query::{Selection, TypeCondition};
use crate::{ContextSelectionSet, Error, ObjectType, QueryError, Result};
use futures::{future, TryFutureExt};
use std::iter::FromIterator;
#[allow(missing_docs)]
pub async fn do_resolve<'a, T: ObjectType + Send + Sync>(
@ -13,7 +12,18 @@ pub async fn do_resolve<'a, T: ObjectType + Send + Sync>(
let mut futures = Vec::new();
collect_fields(ctx, root, &mut futures)?;
let res = futures::future::try_join_all(futures).await?;
let map = serde_json::Map::from_iter(res);
let mut map = serde_json::Map::new();
for (name, value) in res {
match (map.remove(&name), value) {
(Some(serde_json::Value::Object(mut a)), serde_json::Value::Object(b)) => {
a.extend(b);
map.insert(name, a.into());
}
(_, b) => {
map.insert(name, b);
}
}
}
Ok(map.into())
}

84
tests/fields_merge.rs Normal file
View File

@ -0,0 +1,84 @@
use async_graphql::*;
#[async_std::test]
pub async fn test_field_merge() {
struct Query;
#[Object]
impl Query {
async fn value1(&self) -> i32 {
1
}
async fn value2(&self) -> i32 {
2
}
async fn value3(&self) -> i32 {
3
}
}
let schema = Schema::new(Query, EmptyMutation, EmptySubscription);
let query = r#"
{
value1
... { value2 }
... A
}
fragment A on Query {
value3
}
"#;
assert_eq!(
schema.execute(&query).await.unwrap().data,
serde_json::json!({
"value1": 1,
"value2": 2,
"value3": 3,
})
);
}
#[async_std::test]
pub async fn test_field_object_merge() {
#[SimpleObject]
struct MyObject {
a: i32,
b: i32,
c: i32,
}
struct Query;
#[Object]
impl Query {
async fn obj(&self) -> MyObject {
MyObject { a: 1, b: 2, c: 3 }
}
}
let schema = Schema::new(Query, EmptyMutation, EmptySubscription);
let query = r#"
{
obj { a }
... { obj { b } }
... A
}
fragment A on Query {
obj { c }
}
"#;
assert_eq!(
schema.execute(&query).await.unwrap().data,
serde_json::json!({
"obj": {
"a": 1,
"b": 2,
"c": 3,
}
})
);
}