Skip to content

Commit 042a56a

Browse files
committed
Comment in VariablesAreInputTypesRule
1 parent cd89e95 commit 042a56a

File tree

4 files changed

+44
-7
lines changed

4 files changed

+44
-7
lines changed

src/validation/ValidationContext.ts

+12-1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ interface VariableUsage {
3535
readonly node: VariableNode;
3636
readonly type: Maybe<GraphQLInputType>;
3737
readonly defaultValue: Maybe<unknown>;
38+
readonly argumentDefinition: Maybe<VariableDefinitionNode>;
3839
}
3940
interface DefinedVariable {
4041
readonly variableDefinition: VariableDefinitionNode;
@@ -151,7 +152,9 @@ export class ASTValidationContext {
151152
const variableDefinedOperations: ObjMap<Array<DefinedVariable>> = {};
152153
visit(this._ast, {
153154
OperationDefinition(operation) {
154-
for (const varDef of operation.variableDefinitions ?? []) {
155+
/* c8 ignore next */
156+
const variableDefinitions = operation.variableDefinitions ?? [];
157+
for (const varDef of variableDefinitions) {
155158
if (!variableDefinedOperations[varDef.variable.name.value]) {
156159
variableDefinedOperations[varDef.variable.name.value] = [];
157160
}
@@ -238,10 +241,18 @@ export class ValidationContext extends ASTValidationContext {
238241
visitWithTypeInfo(typeInfo, {
239242
VariableDefinition: () => false,
240243
Variable(variable) {
244+
const argumentDefinition =
245+
node.kind === Kind.FRAGMENT_DEFINITION
246+
? node.argumentDefinitions?.find(
247+
(argDef) =>
248+
argDef.variable.name.value === variable.name.value,
249+
)
250+
: undefined;
241251
newUsages.push({
242252
node: variable,
243253
type: typeInfo.getInputType(),
244254
defaultValue: typeInfo.getDefaultValue(),
255+
argumentDefinition,
245256
});
246257
},
247258
}),

src/validation/__tests__/VariablesInAllowedPositionRule-test.ts

+26-5
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,13 @@ describe('Validate: Variables are in allowed positions', () => {
356356
dog @include(if: $boolVar)
357357
}`);
358358
});
359+
360+
it('undefined in directive with default value with option', () => {
361+
expectValid(`
362+
{
363+
dog @include(if: $x)
364+
}`);
365+
});
359366
});
360367

361368
describe('Fragment arguments are validated', () => {
@@ -373,12 +380,26 @@ describe('Validate: Variables are in allowed positions', () => {
373380
`);
374381
});
375382

383+
it('Boolean => Boolean with default value', () => {
384+
expectValid(`
385+
query Query($booleanArg: Boolean)
386+
{
387+
complicatedArgs {
388+
...A(b: $booleanArg)
389+
}
390+
}
391+
fragment A($b: Boolean = true) on ComplicatedArgs {
392+
booleanArgField(booleanArg: $b)
393+
}
394+
`);
395+
});
396+
376397
it('Boolean => Boolean!', () => {
377398
expectErrors(`
378-
query Query($fb: Boolean)
399+
query Query($ab: Boolean)
379400
{
380401
complicatedArgs {
381-
...A(b: $fb)
402+
...A(b: $ab)
382403
}
383404
}
384405
fragment A($b: Boolean!) on ComplicatedArgs {
@@ -387,10 +408,10 @@ describe('Validate: Variables are in allowed positions', () => {
387408
`).toDeepEqual([
388409
{
389410
message:
390-
'Variable "$booleanArg" of type "Boolean" used in position expecting type "Boolean!".',
411+
'Variable "$ab" of type "Boolean" used in position expecting type "Boolean!".',
391412
locations: [
392413
{ line: 2, column: 21 },
393-
{ line: 4, column: 47 },
414+
{ line: 5, column: 21 },
394415
],
395416
},
396417
]);
@@ -412,7 +433,7 @@ describe('Validate: Variables are in allowed positions', () => {
412433
'Variable "$intVar" of type "Int" used in position expecting type "Int!".',
413434
locations: [
414435
{ line: 2, column: 21 },
415-
{ line: 4, column: 47 },
436+
{ line: 4, column: 21 },
416437
],
417438
},
418439
]);

src/validation/rules/NoUndefinedVariablesRule.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,10 @@ export function NoUndefinedVariablesRule(
2222
);
2323

2424
const usages = context.getRecursiveVariableUsages(operation);
25-
for (const { node } of usages) {
25+
for (const { node, argumentDefinition } of usages) {
26+
if (argumentDefinition) {
27+
continue;
28+
}
2629
const varName = node.name.value;
2730
if (!variableNameDefined.has(varName)) {
2831
context.reportError(

src/validation/rules/VariablesAreInputTypesRule.ts

+2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ import type { ValidationContext } from '../ValidationContext.js';
1616
* A GraphQL operation is only valid if all the variables it defines are of
1717
* input types (scalar, enum, or input object).
1818
*
19+
* Similarly, all fragment defined arguments must be of input types.
20+
*
1921
* See https://spec.graphql.org/draft/#sec-Variables-Are-Input-Types
2022
*/
2123
export function VariablesAreInputTypesRule(

0 commit comments

Comments
 (0)