Fix the problem that the Registry::create_dummy_type function may overwrite the keys of the registered type. #316

This commit is contained in:
Sunli 2020-10-20 19:55:10 +08:00
parent 65c8b74f7a
commit 8edd59ffdb
2 changed files with 62 additions and 2 deletions

View File

@ -293,8 +293,22 @@ impl Registry {
let mut dummy_registry = Registry::default();
T::create_type_info(&mut dummy_registry);
if let Some(ty) = dummy_registry.types.remove(&*T::type_name()) {
self.types.extend(dummy_registry.types);
self.implements.extend(dummy_registry.implements);
// Do not overwrite existing types.
for (name, ty) in dummy_registry.types {
if !self.types.contains_key(&name) {
self.types.insert(name, ty);
}
}
// Do not overwrite existing implements.
for (name, interfaces) in dummy_registry.implements {
if let Some(current_interfaces) = self.implements.get_mut(&name) {
current_interfaces.extend(interfaces);
} else {
self.implements.insert(name, interfaces);
}
}
ty
} else {
unreachable!()

View File

@ -290,3 +290,49 @@ pub async fn test_merged_entity() {
})
);
}
#[async_std::test]
pub async fn test_issue_316() {
#[derive(SimpleObject)]
struct Fruit {
id: ID,
name: String,
}
struct Query;
#[Object]
impl Query {
#[graphql(entity)]
async fn get_fruit(&self, id: ID) -> Fruit {
Fruit {
id,
name: "Apple".into(),
}
}
}
#[derive(Default)]
struct Mutation1;
#[Object]
impl Mutation1 {
async fn action1(&self) -> Fruit {
Fruit {
id: ID("hello".into()),
name: "Apple".into(),
}
}
}
#[derive(MergedObject, Default)]
struct Mutation(Mutation1);
// This works
let schema = Schema::new(Query, Mutation1, EmptySubscription);
assert!(schema.execute("{ _service { sdl }}").await.is_ok());
// This fails
let schema = Schema::new(Query, Mutation::default(), EmptySubscription);
assert!(schema.execute("{ _service { sdl }}").await.is_ok());
}