-
Notifications
You must be signed in to change notification settings - Fork 13
Allow unions of (non-interface) Objects #113
Conversation
src/ast/schemaPredicates.test.ts
Outdated
@@ -29,4 +29,8 @@ describe('SchemaPredicates', () => { | |||
expect(schemaPredicates.isFieldNullable('Todo', 'complete')).toBeTruthy(); | |||
expect(schemaPredicates.isFieldNullable('Todo', 'author')).toBeTruthy(); | |||
}); | |||
|
|||
it('should totally do that thing that Steven is struggling with', () => { | |||
expect(true).toBeTruthy(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So we are checking here whether we may have a UnionType
: https://github.com/FormidableLabs/urql-exchange-graphcache/blob/6e0f016beadf224249cfb5d9362ca979b484fc24/src/ast/schemaPredicates.ts#L98
You can probably add a case here that checks:
schemaPredicates.isInterfaceOfType('Todo', 'NoTodosError');
schemaPredicates.isInterfaceOfType('NoTodosError', 'Todo')
But I expect our bug to be here: https://github.com/FormidableLabs/urql-exchange-graphcache/blob/6e0f016beadf224249cfb5d9362ca979b484fc24/src/ast/schemaPredicates.ts#L47
We're assuming that typeCondition
(so ... on NoTodosError
) to be an abstract type when the check fails, but for unions it's actually a regular object type, so we'd have to also check whether we just get the same ObjectType
, so:
const abstractType = this.schema.getType(typeCondition);
+ if (abstractType instanceof GraphQLObjectType) {
+ return abstractType === objectType;
+ }
expectAbstractType(abstractType, typeCondition);
const objectType = this.schema.getType(typename);
expectObjectType(objectType, typename);
|
||
it('should handle unions of objects', () => { | ||
expect( | ||
schemaPredicates.isInterfaceOfType('LatestTodoResult', 'Todo') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, now it makes a little bit more sense to me; this would be the result of
type Todo {
}
type NoTodosError {
}
union LatestTodoResult = Todo | NoTodosError
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suppose we may want to rename this method now to sth like isMatchingCondition
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll refrain from commenting further on what does and doesn't make sense until I've spent some more time on GraphQL primitives. The fact that it was counterintuitive to me probably has more to do with that than the actual API.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To be honest, I can't really reason about how this test actually implies correctness. What's the failure path here?
@kitten @JoviDeCroock is there anything left to do on this? |
We might have to rebase with master so the CI can run correctly |
ab7bfeb
to
ba16147
Compare
Done :) |
schemaPredicates.isInterfaceOfType('LatestTodoResult', 'Todo') | ||
).toBeTruthy(); | ||
expect( | ||
schemaPredicates.isInterfaceOfType('LatestTodoResult', 'NoTodosError') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we're missing a test for this:
expect(
schemaPredicates.isInterfaceOfType('Todo', 'NoTodosError')
).toBeFalsy();
Also is LatestTodoResult
compared with NoTodosError
/ Todo
legal? As in are you able to write this in GraphQL? Because I'm not sure
fragment _ on LatestTodoResult {
}
Where LatestTodoResult
is obviously a union, hence a fragment shouldn't be able to match at all 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that should be ok, but should only yield __typename
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work, thank you so much for taking your time to resolve this!
As discussed on spectrum, starting repro here.