Skip to content

Commit

Permalink
Comment in VariablesAreInputTypesRule
Browse files Browse the repository at this point in the history
  • Loading branch information
mjmahone committed Dec 30, 2022
1 parent 87332ed commit 1a5126b
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 7 deletions.
13 changes: 12 additions & 1 deletion src/validation/ValidationContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ interface VariableUsage {
readonly node: VariableNode;
readonly type: Maybe<GraphQLInputType>;
readonly defaultValue: Maybe<unknown>;
readonly argumentDefinition: Maybe<VariableDefinitionNode>;
}
interface DefinedVariable {
readonly variableDefinition: VariableDefinitionNode;
Expand Down Expand Up @@ -151,7 +152,9 @@ export class ASTValidationContext {
const variableDefinedOperations: ObjMap<Array<DefinedVariable>> = {};
visit(this._ast, {
OperationDefinition(operation) {
for (const varDef of operation.variableDefinitions ?? []) {
/* c8 ignore next */
const variableDefinitions = operation.variableDefinitions ?? [];
for (const varDef of variableDefinitions) {
if (!variableDefinedOperations[varDef.variable.name.value]) {
variableDefinedOperations[varDef.variable.name.value] = [];
}
Expand Down Expand Up @@ -238,10 +241,18 @@ export class ValidationContext extends ASTValidationContext {
visitWithTypeInfo(typeInfo, {
VariableDefinition: () => false,
Variable(variable) {
const argumentDefinition =
node.kind === Kind.FRAGMENT_DEFINITION
? node.argumentDefinitions?.find(
(argDef) =>
argDef.variable.name.value === variable.name.value,
)
: undefined;
newUsages.push({
node: variable,
type: typeInfo.getInputType(),
defaultValue: typeInfo.getDefaultValue(),
argumentDefinition,
});
},
}),
Expand Down
31 changes: 26 additions & 5 deletions src/validation/__tests__/VariablesInAllowedPositionRule-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -356,6 +356,13 @@ describe('Validate: Variables are in allowed positions', () => {
dog @include(if: $boolVar)
}`);
});

it('undefined in directive with default value with option', () => {
expectValid(`
{
dog @include(if: $x)
}`);
});
});

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

it('Boolean => Boolean with default value', () => {
expectValid(`
query Query($booleanArg: Boolean)
{
complicatedArgs {
...A(b: $booleanArg)
}
}
fragment A($b: Boolean = true) on ComplicatedArgs {
booleanArgField(booleanArg: $b)
}
`);
});

it('Boolean => Boolean!', () => {
expectErrors(`
query Query($fb: Boolean)
query Query($ab: Boolean)
{
complicatedArgs {
...A(b: $fb)
...A(b: $ab)
}
}
fragment A($b: Boolean!) on ComplicatedArgs {
Expand All @@ -387,10 +408,10 @@ describe('Validate: Variables are in allowed positions', () => {
`).toDeepEqual([
{
message:
'Variable "$booleanArg" of type "Boolean" used in position expecting type "Boolean!".',
'Variable "$ab" of type "Boolean" used in position expecting type "Boolean!".',
locations: [
{ line: 2, column: 21 },
{ line: 4, column: 47 },
{ line: 5, column: 21 },
],
},
]);
Expand All @@ -412,7 +433,7 @@ describe('Validate: Variables are in allowed positions', () => {
'Variable "$intVar" of type "Int" used in position expecting type "Int!".',
locations: [
{ line: 2, column: 21 },
{ line: 4, column: 47 },
{ line: 4, column: 21 },
],
},
]);
Expand Down
5 changes: 4 additions & 1 deletion src/validation/rules/NoUndefinedVariablesRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@ export function NoUndefinedVariablesRule(
);

const usages = context.getRecursiveVariableUsages(operation);
for (const { node } of usages) {
for (const { node, argumentDefinition } of usages) {
if (argumentDefinition) {
continue;
}
const varName = node.name.value;
if (!variableNameDefined.has(varName)) {
context.reportError(
Expand Down
2 changes: 2 additions & 0 deletions src/validation/rules/VariablesAreInputTypesRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import type { ValidationContext } from '../ValidationContext.js';
* A GraphQL operation is only valid if all the variables it defines are of
* input types (scalar, enum, or input object).
*
* Similarly, all fragment defined arguments must be of input types.
*
* See https://spec.graphql.org/draft/#sec-Variables-Are-Input-Types
*/
export function VariablesAreInputTypesRule(
Expand Down

0 comments on commit 1a5126b

Please sign in to comment.