Skip to content

Commit

Permalink
fix: remove deduplicate fragments (fix #90) (#94)
Browse files Browse the repository at this point in the history
* fix: dedupe fragments (fix #90)

* fix coverage error
  • Loading branch information
FezVrasta authored and evenchange4 committed May 20, 2019
1 parent 87c5b9b commit e406153
Show file tree
Hide file tree
Showing 5 changed files with 203 additions and 4 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,13 @@
"test": "NODE_ENV='test' jest --coverage",
"test:watch": "npm run test -- --watch",
"flow": "flow",
"flow-coverage": "hsu-scripts flow --threshold 71",
"flow-coverage": "hsu-scripts flow --threshold 70",
"eslint": "eslint ./",
"format": "prettier --write '**/*.{js,json,md,css,yaml,yml}' '*.{js,json,md,css,yaml,yml}'",
"changelog": "conventional-changelog --infile ./CHANGELOG.md --same-file --release-count 0 --output-unreleased"
},
"dependencies": {
"@babel/template": "^7.4.4",
"babel-literal-to-ast": "^2.1.0",
"babel-plugin-macros": "^2.5.0",
"graphql-tag": "^2.10.1"
Expand Down
150 changes: 149 additions & 1 deletion src/__tests__/__snapshots__/macro.test.js.snap
Original file line number Diff line number Diff line change
@@ -1,5 +1,153 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`macros [gql] should handle duplicated fragments (issue#90): [gql] should handle duplicated fragments (issue#90) 1`] = `
import { gql } from 'graphql.macro';
const frag1 = gql\`fragment TestDuplicate on Bar { field }\`;
const frag2 = gql\`fragment TestDuplicate on Bar { field }\`;
const query = gql\`{ bar { fieldOne ...TestDuplicate } } \${frag1} \${frag2}\`;
↓ ↓ ↓ ↓ ↓ ↓
const frag1 = {
"kind": "Document",
"definitions": [{
"kind": "FragmentDefinition",
"name": {
"kind": "Name",
"value": "TestDuplicate"
},
"typeCondition": {
"kind": "NamedType",
"name": {
"kind": "Name",
"value": "Bar"
}
},
"directives": [],
"selectionSet": {
"kind": "SelectionSet",
"selections": [{
"kind": "Field",
"name": {
"kind": "Name",
"value": "field"
},
"arguments": [],
"directives": []
}]
}
}],
"loc": {
"start": 0,
"end": 39,
"source": {
"body": "fragment TestDuplicate on Bar { field }",
"name": "GraphQL request",
"locationOffset": {
"line": 1,
"column": 1
}
}
}
};
const frag2 = {
"kind": "Document",
"definitions": [{
"kind": "FragmentDefinition",
"name": {
"kind": "Name",
"value": "TestDuplicate"
},
"typeCondition": {
"kind": "NamedType",
"name": {
"kind": "Name",
"value": "Bar"
}
},
"directives": [],
"selectionSet": {
"kind": "SelectionSet",
"selections": [{
"kind": "Field",
"name": {
"kind": "Name",
"value": "field"
},
"arguments": [],
"directives": []
}]
}
}],
"loc": {
"start": 0,
"end": 39,
"source": {
"body": "fragment TestDuplicate on Bar { field }",
"name": "GraphQL request",
"locationOffset": {
"line": 1,
"column": 1
}
}
}
};
const query = {
"kind": "Document",
"definitions": [{
"kind": "OperationDefinition",
"operation": "query",
"variableDefinitions": [],
"directives": [],
"selectionSet": {
"kind": "SelectionSet",
"selections": [{
"kind": "Field",
"name": {
"kind": "Name",
"value": "bar"
},
"arguments": [],
"directives": [],
"selectionSet": {
"kind": "SelectionSet",
"selections": [{
"kind": "Field",
"name": {
"kind": "Name",
"value": "fieldOne"
},
"arguments": [],
"directives": []
}, {
"kind": "FragmentSpread",
"name": {
"kind": "Name",
"value": "TestDuplicate"
},
"directives": []
}]
}
}]
}
}].concat(frag1.definitions, frag2.definitions).reduce((acc, definition) => definition.kind !== "FragmentDefinition" || acc.find(curDef => curDef.name.value === definition.name.value) ? acc : acc.concat(definition), []),
"loc": {
"start": 0,
"end": 39,
"source": {
"body": "{ bar { fieldOne ...TestDuplicate } } ",
"name": "GraphQL request",
"locationOffset": {
"line": 1,
"column": 1
}
}
}
};
`;

exports[`macros [gql] with fragment: [gql] with fragment 1`] = `
import { gql } from 'graphql.macro';
Expand Down Expand Up @@ -114,7 +262,7 @@ const query = {
}
}]
}
}].concat(userFragment.definitions),
}].concat(userFragment.definitions).reduce((acc, definition) => definition.kind !== "FragmentDefinition" || acc.find(curDef => curDef.name.value === definition.name.value) ? acc : acc.concat(definition), []),
"loc": {
"start": 0,
"end": 82,
Expand Down
9 changes: 9 additions & 0 deletions src/__tests__/macro.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,15 @@ pluginTester({
\`;
`,
},
'[gql] should handle duplicated fragments (issue#90)': {
error: false,
code: `
import { gql } from '../macro';
const frag1 = gql\`fragment TestDuplicate on Bar { field }\`;
const frag2 = gql\`fragment TestDuplicate on Bar { field }\`;
const query = gql\`{ bar { fieldOne ...TestDuplicate } } $\{frag1} $\{frag2}\`;
`,
},
'[loader] without fragment': {
error: false,
code: `
Expand Down
22 changes: 20 additions & 2 deletions src/utils/compileWithFragment.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,18 @@
// @flow
import gqlTag from 'graphql-tag';
import serialize from 'babel-literal-to-ast';
import template from '@babel/template';

/**
* ref: https://github.com/gajus/babel-plugin-graphql-tag/blob/35edbae44990bf20be2de7139dc0ce5843f70bff/src/index.js#L25
*/
const uniqueFn = template.ast(`
(acc, definition) =>
definition.kind !== "FragmentDefinition" ||
acc.find(curDef => curDef.name.value === definition.name.value)
? acc
: acc.concat(definition)
`);

/**
* ref: https://github.com/leoasis/graphql-tag.macro
Expand All @@ -23,8 +35,14 @@ export default function compileWithFragment(
t.memberExpression(expression.node, t.identifier('definitions')),
);
definitionsProperty.value = t.callExpression(
t.memberExpression(definitionsArray, t.identifier('concat')),
concatDefinitions,
t.memberExpression(
t.callExpression(
t.memberExpression(definitionsArray, t.identifier('concat')),
concatDefinitions,
),
t.identifier('reduce'),
),
[t.toExpression(uniqueFn), t.arrayExpression([])],
);
}

Expand Down
23 changes: 23 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,11 @@
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.3.3.tgz#092d450db02bdb6ccb1ca8ffd47d8774a91aef87"
integrity sha512-xsH1CJoln2r74hR+y7cg2B5JCPaTh+Hd+EbBRk9nWGSNspuo6krjhX0Om6RnRQuIvFq8wVXCLKH3kwKDYhanSg==

"@babel/parser@^7.4.4":
version "7.4.4"
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.4.4.tgz#5977129431b8fe33471730d255ce8654ae1250b6"
integrity sha512-5pCS4mOsL+ANsFZGdvNLybx4wtqAZJ0MJjMHxvzI3bvIsz6sQvzW8XX92EYIkiPtIvcfG3Aj+Ir5VNyjnZhP7w==

"@babel/plugin-proposal-async-generator-functions@^7.2.0":
version "7.2.0"
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.2.0.tgz#b289b306669dce4ad20b0252889a15768c9d417e"
Expand Down Expand Up @@ -745,6 +750,15 @@
"@babel/parser" "^7.2.2"
"@babel/types" "^7.2.2"

"@babel/template@^7.4.4":
version "7.4.4"
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.4.4.tgz#f4b88d1225689a08f5bc3a17483545be9e4ed237"
integrity sha512-CiGzLN9KgAvgZsnivND7rkA+AeJ9JB0ciPOD4U59GKbQP2iQl+olF1l76kJOupqidozfZ32ghwBEJDhnk9MEcw==
dependencies:
"@babel/code-frame" "^7.0.0"
"@babel/parser" "^7.4.4"
"@babel/types" "^7.4.4"

"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.1.5", "@babel/traverse@^7.1.6", "@babel/traverse@^7.2.2", "@babel/traverse@^7.2.3":
version "7.2.3"
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.2.3.tgz#7ff50cefa9c7c0bd2d81231fdac122f3957748d8"
Expand Down Expand Up @@ -778,6 +792,15 @@
lodash "^4.17.11"
to-fast-properties "^2.0.0"

"@babel/types@^7.4.4":
version "7.4.4"
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.4.4.tgz#8db9e9a629bb7c29370009b4b779ed93fe57d5f0"
integrity sha512-dOllgYdnEFOebhkKCjzSVFqw/PmmB8pH6RGOWkY4GsboQNd47b1fBThBSwlHAq9alF9vc1M3+6oqR47R50L0tQ==
dependencies:
esutils "^2.0.2"
lodash "^4.17.11"
to-fast-properties "^2.0.0"

"@iamstarkov/listr-update-renderer@0.4.1":
version "0.4.1"
resolved "https://registry.yarnpkg.com/@iamstarkov/listr-update-renderer/-/listr-update-renderer-0.4.1.tgz#d7c48092a2dcf90fd672b6c8b458649cb350c77e"
Expand Down

0 comments on commit e406153

Please sign in to comment.