Skip to content

Commit

Permalink
fix batch execute fragment handling.
Browse files Browse the repository at this point in the history
  • Loading branch information
gmac committed Sep 27, 2021
1 parent 31b0416 commit 44ba4cb
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 2 deletions.
19 changes: 17 additions & 2 deletions packages/batch-execute/src/mergeRequests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,12 +118,18 @@ function prefixRequest(prefix: string, request: ExecutionRequest): ExecutionRequ
let prefixedDocument = aliasTopLevelFields(prefix, request.document);

const executionVariableNames = Object.keys(executionVariables);
const hasFragmentDefinitions = request.document.definitions.some(def => isFragmentDefinition(def));
const fragmentSpreadImpl: Record<string, boolean> = {};

if (executionVariableNames.length > 0) {
if (executionVariableNames.length > 0 || hasFragmentDefinitions) {
prefixedDocument = visit(prefixedDocument, {
[Kind.VARIABLE]: prefixNode,
[Kind.FRAGMENT_DEFINITION]: prefixNode,
[Kind.FRAGMENT_SPREAD]: prefixNode,
[Kind.FRAGMENT_SPREAD]: node => {
node = prefixNodeName(node, prefix);
fragmentSpreadImpl[node.name.value] = true;
return node;
},
}) as DocumentNode;
}

Expand All @@ -133,6 +139,15 @@ function prefixRequest(prefix: string, request: ExecutionRequest): ExecutionRequ
prefixedVariables[prefix + variableName] = executionVariables[variableName];
}

if (hasFragmentDefinitions) {
prefixedDocument = {
...prefixedDocument,
definitions: prefixedDocument.definitions.filter(def => {
return !isFragmentDefinition(def) || fragmentSpreadImpl[def.name.value];
}),
};
}

return {
document: prefixedDocument,
variables: prefixedVariables,
Expand Down
32 changes: 32 additions & 0 deletions packages/batch-execute/tests/batchExecute.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ describe('batch execution', () => {
field2: String
field3(input: String): String
boom(message: String): String
widget: Widget
}
type Widget {
name: String
}
`,
resolvers: {
Expand All @@ -29,6 +33,7 @@ describe('batch execution', () => {
field2: () => '2',
field3: (_root, { input }) => String(input),
boom: (_root, { message }) => new Error(message),
widget: () => ({ name: 'wingnut' }),
},
},
});
Expand Down Expand Up @@ -111,6 +116,33 @@ describe('batch execution', () => {
expect(executorCalls).toEqual(1);
});

it('renames fragment definitions and spreads', async () => {
const [first, second] = await Promise.all([
batchExec({ document: parse('fragment A on Widget { name } query{ widget { ...A } }') }),
batchExec({ document: parse('fragment A on Widget { name } query{ widget { ...A } }') }),
]) as ExecutionResult[];

const squishedDoc = executorDocument?.replace(/\s+/g, ' ');
expect(squishedDoc).toMatch('_0_widget: widget { ..._0_A }');
expect(squishedDoc).toMatch('_1_widget: widget { ..._1_A }');
expect(squishedDoc).toMatch('fragment _0_A on Widget');
expect(squishedDoc).toMatch('fragment _1_A on Widget');
expect(first?.data).toEqual({ widget: { name: 'wingnut' } });
expect(second?.data).toEqual({ widget: { name: 'wingnut' } });
expect(executorCalls).toEqual(1);
});

it('removes expanded root fragment definitions', async () => {
const [first, second] = await Promise.all([
batchExec({ document: parse('fragment A on Query { field1 } query{ ...A }') }),
batchExec({ document: parse('fragment A on Query { field2 } query{ ...A }') }),
]) as ExecutionResult[];

expect(first?.data).toEqual({ field1: '1' });
expect(second?.data).toEqual({ field2: '2' });
expect(executorCalls).toEqual(1);
});

it('preserves pathed errors in the final result', async () => {
const [first, second] = await Promise.all([
batchExec({ document: parse('{ first: boom(message: "first error") }') }),
Expand Down

0 comments on commit 44ba4cb

Please sign in to comment.