Skip to content

Commit 0147e0d

Browse files
support @defer on inline fragments
- add inline fragment test case - rename rest to initial
1 parent 267153e commit 0147e0d

File tree

3 files changed

+79
-16
lines changed

3 files changed

+79
-16
lines changed

src/__tests__/starWarsDeferredQuery-test.js

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,8 @@ describe('Star Wars Query Deferred Tests', () => {
106106
`;
107107

108108
const result = await graphql(StarWarsSchemaDeferStreamEnabled, query);
109-
const { patches: patchesIterable, ...rest } = result;
110-
expect(rest).to.deep.equal({
109+
const { patches: patchesIterable, ...initial } = result;
110+
expect(initial).to.deep.equal({
111111
data: {
112112
hero: {
113113
id: '2001',
@@ -149,6 +149,49 @@ describe('Star Wars Query Deferred Tests', () => {
149149
// TODO
150150
// describe('Using aliases to change the key in the response', () => {});
151151

152+
describe('Inline Fragments', () => {
153+
it('Allows us to defer an inline fragment', async () => {
154+
const query = `
155+
query UserFragment {
156+
human(id: "1003") {
157+
id
158+
... on Human @defer(label: "InlineDeferred"){
159+
name
160+
homePlanet
161+
}
162+
}
163+
}
164+
165+
`;
166+
const result = await graphql(StarWarsSchemaDeferStreamEnabled, query);
167+
const { patches: patchesIterable, ...initial } = result;
168+
expect(initial).to.deep.equal({
169+
data: {
170+
human: {
171+
id: '1003',
172+
},
173+
},
174+
});
175+
176+
const patches = [];
177+
178+
if (patchesIterable) {
179+
await forAwaitEach(patchesIterable, patch => {
180+
patches.push(patch);
181+
});
182+
}
183+
expect(patches).to.have.lengthOf(1);
184+
expect(patches[0]).to.deep.equal({
185+
label: 'InlineDeferred',
186+
path: ['human'],
187+
data: {
188+
name: 'Leia Organa',
189+
homePlanet: 'Alderaan',
190+
},
191+
});
192+
});
193+
});
194+
152195
describe('Uses fragments to express more complex queries', () => {
153196
it('Allows us to use a fragment to avoid duplicating content', async () => {
154197
const query = `
@@ -183,9 +226,9 @@ describe('Star Wars Query Deferred Tests', () => {
183226
}
184227
`;
185228
const result = await graphql(StarWarsSchemaDeferStreamEnabled, query);
186-
const { patches: patchesIterable, ...rest } = result;
229+
const { patches: patchesIterable, ...initial } = result;
187230

188-
expect(rest).to.deep.equal({
231+
expect(initial).to.deep.equal({
189232
data: {
190233
han: {
191234
__typename: 'Human',

src/execution/execute.js

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -545,26 +545,47 @@ export function collectFields(
545545
) {
546546
continue;
547547
}
548-
collectFields(
549-
exeContext,
550-
runtimeType,
551-
selection.selectionSet,
552-
fields,
553-
patches,
554-
visitedFragmentNames,
555-
);
548+
549+
const patchLabel = exeContext.schema.__experimentalDeferFragmentSpreads
550+
? getDeferredNodeLabel(exeContext, selection)
551+
: '';
552+
553+
if (patchLabel) {
554+
const { fields: patchFields } = collectFields(
555+
exeContext,
556+
runtimeType,
557+
selection.selectionSet,
558+
Object.create(null),
559+
patches,
560+
visitedFragmentNames,
561+
);
562+
patches.push({
563+
label: patchLabel,
564+
fields: patchFields,
565+
});
566+
} else {
567+
collectFields(
568+
exeContext,
569+
runtimeType,
570+
selection.selectionSet,
571+
fields,
572+
patches,
573+
visitedFragmentNames,
574+
);
575+
}
556576
break;
557577
}
558578
case Kind.FRAGMENT_SPREAD: {
559579
const fragName = selection.name.value;
560580

581+
if (!shouldIncludeNode(exeContext, selection)) {
582+
continue;
583+
}
584+
561585
const patchLabel = exeContext.schema.__experimentalDeferFragmentSpreads
562586
? getDeferredNodeLabel(exeContext, selection)
563587
: '';
564588

565-
if (!shouldIncludeNode(exeContext, selection)) {
566-
continue;
567-
}
568589
if (
569590
visitedFragmentNames[fragName] &&
570591
// Cannot continue in this case because fields must be recollected for patch

src/type/directives.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,6 @@ export const GraphQLDeferDirective = new GraphQLDirective({
176176
'Directs the executor to defer this fragment when the `if` argument is true or undefined.',
177177
locations: [
178178
DirectiveLocation.FRAGMENT_SPREAD,
179-
// TODO: Do we want to support on inline fragments? (Can we? How would you make label unique?)
180179
DirectiveLocation.INLINE_FRAGMENT,
181180
],
182181
args: {

0 commit comments

Comments
 (0)