Skip to content

Commit

Permalink
simplify schema in defer tests (#3881)
Browse files Browse the repository at this point in the history
  • Loading branch information
robrichard authored Apr 15, 2023
1 parent 418a0c8 commit 75114af
Showing 1 changed file with 92 additions and 68 deletions.
160 changes: 92 additions & 68 deletions src/execution/__tests__/defer-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,7 @@ const friendType = new GraphQLObjectType({
fields: {
id: { type: GraphQLID },
name: { type: GraphQLString },
promiseNonNullErrorField: {
type: new GraphQLNonNull(GraphQLString),
resolve: () => Promise.resolve(null),
},
nonNullName: { type: new GraphQLNonNull(GraphQLString) },
},
name: 'Friend',
});
Expand All @@ -40,64 +37,36 @@ const friends = [
{ name: 'C-3PO', id: 4 },
];

const hero = { name: 'Luke', id: 1, friends };

const heroType = new GraphQLObjectType({
fields: {
id: { type: GraphQLID },
name: { type: GraphQLString },
slowField: {
type: GraphQLString,
resolve: async () => {
await resolveOnNextTick();
return 'slow';
},
},
errorField: {
type: GraphQLString,
resolve: () => {
throw new Error('bad');
},
},
nonNullErrorField: {
type: new GraphQLNonNull(GraphQLString),
resolve: () => null,
},
promiseNonNullErrorField: {
type: new GraphQLNonNull(GraphQLString),
resolve: () => Promise.resolve(null),
},
nonNullName: { type: new GraphQLNonNull(GraphQLString) },
friends: {
type: new GraphQLList(friendType),
resolve: () => friends,
},
asyncFriends: {
type: new GraphQLList(friendType),
async *resolve() {
yield await Promise.resolve(friends[0]);
},
},
},
name: 'Hero',
});

const hero = { name: 'Luke', id: 1 };

const query = new GraphQLObjectType({
fields: {
hero: {
type: heroType,
resolve: () => hero,
},
},
name: 'Query',
});

const schema = new GraphQLSchema({ query });

async function complete(document: DocumentNode) {
async function complete(document: DocumentNode, rootValue: unknown = { hero }) {
const result = await experimentalExecuteIncrementally({
schema,
document,
rootValue: {},
rootValue,
});

if ('initialResult' in result) {
Expand Down Expand Up @@ -244,11 +213,18 @@ describe('Execute: defer directive', () => {
}
fragment QueryFragment on Query {
hero {
errorField
name
}
}
`);
const result = await complete(document);
const result = await complete(document, {
hero: {
...hero,
name: () => {
throw new Error('bad');
},
},
});

expectJSON(result).toDeepEqual([
{
Expand All @@ -260,14 +236,14 @@ describe('Execute: defer directive', () => {
{
data: {
hero: {
errorField: null,
name: null,
},
},
errors: [
{
message: 'bad',
locations: [{ line: 7, column: 11 }],
path: ['hero', 'errorField'],
path: ['hero', 'name'],
},
],
path: [],
Expand Down Expand Up @@ -440,10 +416,17 @@ describe('Execute: defer directive', () => {
}
}
fragment NameFragment on Hero {
errorField
name
}
`);
const result = await complete(document);
const result = await complete(document, {
hero: {
...hero,
name: () => {
throw new Error('bad');
},
},
});
expectJSON(result).toDeepEqual([
{
data: { hero: { id: '1' } },
Expand All @@ -452,13 +435,13 @@ describe('Execute: defer directive', () => {
{
incremental: [
{
data: { errorField: null },
data: { name: null },
path: ['hero'],
errors: [
{
message: 'bad',
locations: [{ line: 9, column: 9 }],
path: ['hero', 'errorField'],
path: ['hero', 'name'],
},
],
},
Expand All @@ -476,10 +459,15 @@ describe('Execute: defer directive', () => {
}
}
fragment NameFragment on Hero {
nonNullErrorField
nonNullName
}
`);
const result = await complete(document);
const result = await complete(document, {
hero: {
...hero,
nonNullName: () => null,
},
});
expectJSON(result).toDeepEqual([
{
data: { hero: { id: '1' } },
Expand All @@ -493,9 +481,9 @@ describe('Execute: defer directive', () => {
errors: [
{
message:
'Cannot return null for non-nullable field Hero.nonNullErrorField.',
'Cannot return null for non-nullable field Hero.nonNullName.',
locations: [{ line: 9, column: 9 }],
path: ['hero', 'nonNullErrorField'],
path: ['hero', 'nonNullName'],
},
],
},
Expand All @@ -508,27 +496,32 @@ describe('Execute: defer directive', () => {
const document = parse(`
query HeroNameQuery {
hero {
nonNullErrorField
nonNullName
...NameFragment @defer
}
}
fragment NameFragment on Hero {
id
}
`);
const result = await complete(document);
const result = await complete(document, {
hero: {
...hero,
nonNullName: () => null,
},
});
expectJSON(result).toDeepEqual({
errors: [
{
message:
'Cannot return null for non-nullable field Hero.nonNullErrorField.',
'Cannot return null for non-nullable field Hero.nonNullName.',
locations: [
{
line: 4,
column: 11,
},
],
path: ['hero', 'nonNullErrorField'],
path: ['hero', 'nonNullName'],
},
],
data: {
Expand All @@ -545,10 +538,15 @@ describe('Execute: defer directive', () => {
}
}
fragment NameFragment on Hero {
promiseNonNullErrorField
nonNullName
}
`);
const result = await complete(document);
const result = await complete(document, {
hero: {
...hero,
nonNullName: () => Promise.resolve(null),
},
});
expectJSON(result).toDeepEqual([
{
data: { hero: { id: '1' } },
Expand All @@ -562,9 +560,9 @@ describe('Execute: defer directive', () => {
errors: [
{
message:
'Cannot return null for non-nullable field Hero.promiseNonNullErrorField.',
'Cannot return null for non-nullable field Hero.nonNullName.',
locations: [{ line: 9, column: 9 }],
path: ['hero', 'promiseNonNullErrorField'],
path: ['hero', 'nonNullName'],
},
],
},
Expand All @@ -582,7 +580,7 @@ describe('Execute: defer directive', () => {
}
}
fragment NameFragment on Hero {
slowField
name
friends {
...NestedFragment @defer
}
Expand All @@ -591,7 +589,15 @@ describe('Execute: defer directive', () => {
name
}
`);
const result = await complete(document);
const result = await complete(document, {
hero: {
...hero,
name: async () => {
await resolveOnNextTick();
return 'slow';
},
},
});
expectJSON(result).toDeepEqual([
{
data: {
Expand All @@ -602,7 +608,7 @@ describe('Execute: defer directive', () => {
{
incremental: [
{
data: { slowField: 'slow', friends: [{}, {}, {}] },
data: { name: 'slow', friends: [{}, {}, {}] },
path: ['hero'],
},
],
Expand Down Expand Up @@ -671,8 +677,8 @@ describe('Execute: defer directive', () => {
const document = parse(`
query {
hero {
asyncFriends {
promiseNonNullErrorField
friends {
nonNullName
...NameFragment @defer
}
}
Expand All @@ -681,19 +687,29 @@ describe('Execute: defer directive', () => {
name
}
`);
const result = await complete(document);
const result = await complete(document, {
hero: {
...hero,
async *friends() {
yield await Promise.resolve({
...friends[0],
nonNullName: () => Promise.resolve(null),
});
},
},
});
expectJSON(result).toDeepEqual({
data: {
hero: {
asyncFriends: [null],
friends: [null],
},
},
errors: [
{
message:
'Cannot return null for non-nullable field Friend.promiseNonNullErrorField.',
'Cannot return null for non-nullable field Friend.nonNullName.',
locations: [{ line: 5, column: 11 }],
path: ['hero', 'asyncFriends', 0, 'promiseNonNullErrorField'],
path: ['hero', 'friends', 0, 'nonNullName'],
},
],
});
Expand All @@ -719,15 +735,23 @@ describe('Execute: defer directive', () => {
it('original execute function resolves to error if anything is deferred and something else is async', async () => {
const doc = `
query Deferred {
hero { slowField }
hero { name }
... @defer { hero { id } }
}
`;
await expectPromise(
execute({
schema,
document: parse(doc),
rootValue: {},
rootValue: {
hero: {
...hero,
name: async () => {
await resolveOnNextTick();
return 'slow';
},
},
},
}),
).toRejectWith(
'Executing this GraphQL operation would unexpectedly produce multiple payloads (due to @defer or @stream directive)',
Expand Down

0 comments on commit 75114af

Please sign in to comment.