Skip to content

Commit fd8598d

Browse files
committed
Merge pull request #296 from jjergus/master
Validate: Unique variable names
2 parents 9234c6d + 089caad commit fd8598d

File tree

3 files changed

+94
-0
lines changed

3 files changed

+94
-0
lines changed
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/**
2+
* Copyright (c) 2015, Facebook, Inc.
3+
* All rights reserved.
4+
*
5+
* This source code is licensed under the BSD-style license found in the
6+
* LICENSE file in the root directory of this source tree. An additional grant
7+
* of patent rights can be found in the PATENTS file in the same directory.
8+
*/
9+
10+
import { describe, it } from 'mocha';
11+
import { expectPassesRule, expectFailsRule } from './harness';
12+
import {
13+
UniqueVariableNames,
14+
duplicateVariableMessage,
15+
} from '../rules/UniqueVariableNames';
16+
17+
18+
function duplicateVariable(name, l1, c1, l2, c2) {
19+
return {
20+
message: duplicateVariableMessage(name),
21+
locations: [ { line: l1, column: c1 }, { line: l2, column: c2 } ],
22+
};
23+
}
24+
25+
describe('Validate: Unique variable names', () => {
26+
27+
it('unique variable names', () => {
28+
expectPassesRule(UniqueVariableNames, `
29+
query A($x: Int, $y: String) { __typename }
30+
query B($x: String, $y: Int) { __typename }
31+
`);
32+
});
33+
34+
it('duplicate variable names', () => {
35+
expectFailsRule(UniqueVariableNames, `
36+
query A($x: Int, $x: Int, $x: String) { __typename }
37+
query B($x: String, $x: Int) { __typename }
38+
query C($x: Int, $x: Int) { __typename }
39+
`, [
40+
duplicateVariable('x', 2, 16, 2, 25),
41+
duplicateVariable('x', 2, 16, 2, 34),
42+
duplicateVariable('x', 3, 16, 3, 28),
43+
duplicateVariable('x', 4, 16, 4, 25)
44+
]);
45+
});
46+
47+
});
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/* @flow */
2+
/**
3+
* Copyright (c) 2015, Facebook, Inc.
4+
* All rights reserved.
5+
*
6+
* This source code is licensed under the BSD-style license found in the
7+
* LICENSE file in the root directory of this source tree. An additional grant
8+
* of patent rights can be found in the PATENTS file in the same directory.
9+
*/
10+
11+
import type { ValidationContext } from '../index';
12+
import type { VariableDefinition } from '../../language/ast';
13+
import { GraphQLError } from '../../error';
14+
15+
16+
export function duplicateVariableMessage(variableName: string): string {
17+
return `There can be only one variable named "${variableName}".`;
18+
}
19+
20+
/**
21+
* Unique variable names
22+
*
23+
* A GraphQL operation is only valid if all its variables are uniquely named.
24+
*/
25+
export function UniqueVariableNames(context: ValidationContext): any {
26+
let knownVariableNames = Object.create(null);
27+
return {
28+
OperationDefinition() {
29+
knownVariableNames = Object.create(null);
30+
},
31+
VariableDefinition(node: VariableDefinition) {
32+
const variableName = node.variable.name.value;
33+
if (knownVariableNames[variableName]) {
34+
context.reportError(new GraphQLError(
35+
duplicateVariableMessage(variableName),
36+
[ knownVariableNames[variableName], node.variable.name ]
37+
));
38+
} else {
39+
knownVariableNames[variableName] = node.variable.name;
40+
}
41+
}
42+
};
43+
}

src/validation/specifiedRules.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ import { PossibleFragmentSpreads } from './rules/PossibleFragmentSpreads';
4444
// Spec Section: "Fragments must not form cycles"
4545
import { NoFragmentCycles } from './rules/NoFragmentCycles';
4646

47+
// Spec Section: "Variable Uniqueness"
48+
import { UniqueVariableNames } from './rules/UniqueVariableNames';
49+
4750
// Spec Section: "All Variable Used Defined"
4851
import { NoUndefinedVariables } from './rules/NoUndefinedVariables';
4952

@@ -97,6 +100,7 @@ export const specifiedRules: Array<(context: ValidationContext) => any> = [
97100
NoUnusedFragments,
98101
PossibleFragmentSpreads,
99102
NoFragmentCycles,
103+
UniqueVariableNames,
100104
NoUndefinedVariables,
101105
NoUnusedVariables,
102106
KnownDirectives,

0 commit comments

Comments
 (0)