Skip to content

Commit

Permalink
Merge pull request #33 from jnwng/jw/apollo-fragments
Browse files Browse the repository at this point in the history
Taking into account Apollo fragment interpolation
  • Loading branch information
helfer authored Jan 23, 2017
2 parents 0fb2d29 + 3cbddfb commit af0fd0c
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 7 deletions.
20 changes: 18 additions & 2 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -269,12 +269,24 @@ function replaceExpressions(node, context, env) {

node.quasis.forEach((element, i) => {
const chunk = element.value.cooked;
const value = node.expressions[i];

chunks.push(chunk);

if (!element.tail) {
const value = node.expressions[i];
if (!env || env === 'apollo') {
// In Apollo, interpolation is only valid outside top-level structures like `query` or `mutation`.
// We'll check to make sure there's an equivalent set of opening and closing brackets, otherwise
// we're attempting to do an invalid interpolation.
if ((chunk.split('{').length - 1) !== (chunk.split('}').length - 1)) {
context.report({
node: value,
message: 'Invalid interpolation - fragment interpolation must occur outside of the brackets.',
});
throw new Error('Invalid interpolation');
}
}

if (!element.tail) {
// Preserve location of errors by replacing with exactly the same length
const nameLength = value.end - value.start;

Expand All @@ -294,6 +306,10 @@ function replaceExpressions(node, context, env) {
// Ellipsis cancels out extra characters
const placeholder = strWithLen(nameLength);
chunks.push('...' + placeholder);
} else if (!env || env === 'apollo') {
// In Apollo, fragment interpolation is only valid outside of brackets
// Since we don't know what we'd interpolate here (that occurs at runtime),
// we're not going to do anything with this interpolation.
} else {
// Invalid interpolation
context.report({
Expand Down
76 changes: 71 additions & 5 deletions test/makeRule.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,15 @@ const parserOptions = {
options,
parserOptions,
code: 'const x = gql.segmented`height: 12px;`'
}
},
{
options,
parserOptions,
code: 'const x = gql`{ number } ${x}`',
},
],

invalid: [

{
options,
parserOptions,
Expand All @@ -73,8 +77,10 @@ const parserOptions = {
parserOptions,
code: 'const x = gql`{ ${x} }`',
errors: [{
message: 'Invalid interpolation - not a valid fragment or variable.',
type: 'Identifier'
message: 'Invalid interpolation - fragment interpolation must occur outside of the brackets.',
type: 'Identifier',
line: 1,
column: 19
}]
},
]
Expand Down Expand Up @@ -120,13 +126,50 @@ const parserOptions = {
code: 'const x = myGraphQLTag`{ ${x} }`',
errors: [{
type: 'Identifier',
message: 'Invalid interpolation - not a valid fragment or variable.'
message: 'Invalid interpolation - fragment interpolation must occur outside of the brackets.'
}]
},
]
});
}

{
const options = [
{ schemaJson, env: 'apollo' },
];

ruleTester.run('apollo', rule, {
valid: [
{
options,
parserOptions,
code: 'const x = gql`{ number } ${x}`',
},
],

invalid: [
{
options,
parserOptions,
code: 'const x = gql`query { ${x} }`',
errors: [{
message: 'Invalid interpolation - fragment interpolation must occur outside of the brackets.',
type: 'Identifier'
}]
},
{
options,
parserOptions,
code: 'const x = gql`query }{ ${x}`',
errors: [{
message: 'Syntax Error GraphQL (1:7) Expected {, found }',
type: 'TaggedTemplateExpression'
}]
}
],
})
}

{
const options = [
{ schemaJson, env: 'lokka' },
Expand Down Expand Up @@ -263,6 +306,29 @@ const parserOptions = {
column: 19
}]
},
{
options,
parserOptions,
code: `
client.query(gql\`
{
allFilms {
films {
\${filmInfo}
}
}
}
\`).then(result => {
console.log(result.allFilms.films);
});
`,
errors: [{
message: 'Invalid interpolation - not a valid fragment or variable.',
type: 'Identifier',
line: 6,
column: 21
}]
},
]
});
}
Expand Down

0 comments on commit af0fd0c

Please sign in to comment.