Skip to content

Commit 7639100

Browse files
lilianammmatosrobrichard
authored andcommitted
support @defer on inline fragments
- add inline fragment test case - rename rest to initial
1 parent 1cc8f34 commit 7639100

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

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

568-
if (!shouldIncludeNode(exeContext, selection)) {
569-
continue;
570-
}
571592
if (
572593
visitedFragmentNames[fragName] &&
573594
// 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)