Skip to content

Commit a94e619

Browse files
support @defer on inline fragments
- add inline fragment test case - rename rest to initial
1 parent d09eda5 commit a94e619

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
@@ -549,26 +549,47 @@ export function collectFields(
549549
) {
550550
continue;
551551
}
552-
collectFields(
553-
exeContext,
554-
runtimeType,
555-
selection.selectionSet,
556-
fields,
557-
patches,
558-
visitedFragmentNames,
559-
);
552+
553+
const patchLabel = exeContext.schema.__experimentalDeferFragmentSpreads
554+
? getDeferredNodeLabel(exeContext, selection)
555+
: '';
556+
557+
if (patchLabel) {
558+
const { fields: patchFields } = collectFields(
559+
exeContext,
560+
runtimeType,
561+
selection.selectionSet,
562+
Object.create(null),
563+
patches,
564+
visitedFragmentNames,
565+
);
566+
patches.push({
567+
label: patchLabel,
568+
fields: patchFields,
569+
});
570+
} else {
571+
collectFields(
572+
exeContext,
573+
runtimeType,
574+
selection.selectionSet,
575+
fields,
576+
patches,
577+
visitedFragmentNames,
578+
);
579+
}
560580
break;
561581
}
562582
case Kind.FRAGMENT_SPREAD: {
563583
const fragName = selection.name.value;
564584

585+
if (!shouldIncludeNode(exeContext, selection)) {
586+
continue;
587+
}
588+
565589
const patchLabel = exeContext.schema.__experimentalDeferFragmentSpreads
566590
? getDeferredNodeLabel(exeContext, selection)
567591
: '';
568592

569-
if (!shouldIncludeNode(exeContext, selection)) {
570-
continue;
571-
}
572593
if (
573594
visitedFragmentNames[fragName] &&
574595
// 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
@@ -179,7 +179,6 @@ export const GraphQLDeferDirective = new GraphQLDirective({
179179
'Directs the executor to defer this fragment when the `if` argument is true or undefined.',
180180
locations: [
181181
DirectiveLocation.FRAGMENT_SPREAD,
182-
// TODO: Do we want to support on inline fragments? (Can we? How would you make label unique?)
183182
DirectiveLocation.INLINE_FRAGMENT,
184183
],
185184
args: {

0 commit comments

Comments
 (0)