Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Taking into account Apollo fragment interpolation #33

Merged
merged 2 commits into from
Jan 23, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 18 additions & 2 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -257,12 +257,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 @@ -282,6 +294,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