@@ -4,14 +4,24 @@ import { describe, it } from 'mocha';
44import { invariant } from '../../jsutils/invariant.js' ;
55import type { ReadOnlyObjMap } from '../../jsutils/ObjMap.js' ;
66
7- import type { ValueNode } from '../../language/ast.js' ;
7+ import type {
8+ FragmentArgumentNode ,
9+ FragmentSpreadNode ,
10+ ValueNode ,
11+ VariableDefinitionNode ,
12+ } from '../../language/ast.js' ;
13+ import { Kind } from '../../language/kinds.js' ;
814import { Parser , parseValue as _parseValue } from '../../language/parser.js' ;
915import { TokenKind } from '../../language/tokenKind.js' ;
1016
1117import { GraphQLInt } from '../../type/scalars.js' ;
1218import { GraphQLSchema } from '../../type/schema.js' ;
1319
14- import { getVariableValues } from '../../execution/values.js' ;
20+ import { getVariableSignature } from '../../execution/getVariableSignature.js' ;
21+ import {
22+ getFragmentVariableValues ,
23+ getVariableValues ,
24+ } from '../../execution/values.js' ;
1525
1626import { replaceVariables } from '../replaceVariables.js' ;
1727
@@ -20,17 +30,51 @@ function parseValue(ast: string): ValueNode {
2030}
2131
2232function testVariables ( variableDefs : string , inputs : ReadOnlyObjMap < unknown > ) {
23- const parser = new Parser ( variableDefs , { noLocation : true } ) ;
24- parser . expectToken ( TokenKind . SOF ) ;
2533 const variableValuesOrErrors = getVariableValues (
2634 new GraphQLSchema ( { types : [ GraphQLInt ] } ) ,
27- parser . parseVariableDefinitions ( ) ?? [ ] ,
35+ parseVariableDefinitions ( variableDefs ) ,
2836 inputs ,
2937 ) ;
3038 invariant ( variableValuesOrErrors . variableValues !== undefined ) ;
3139 return variableValuesOrErrors . variableValues ;
3240}
3341
42+ function parseVariableDefinitions (
43+ variableDefs : string ,
44+ ) : ReadonlyArray < VariableDefinitionNode > {
45+ const parser = new Parser ( variableDefs , { noLocation : true } ) ;
46+ parser . expectToken ( TokenKind . SOF ) ;
47+ return parser . parseVariableDefinitions ( ) ?? [ ] ;
48+ }
49+
50+ function testFragmentVariables ( variableDefs : string , fragmentArgs : string ) {
51+ const schema = new GraphQLSchema ( { types : [ GraphQLInt ] } ) ;
52+ const fragmentSignatures = Object . create ( null ) ;
53+ for ( const varDef of parseVariableDefinitions ( variableDefs ) ) {
54+ const signature = getVariableSignature ( schema , varDef ) ;
55+ fragmentSignatures [ signature . name ] = signature ;
56+ }
57+ const spread : FragmentSpreadNode = {
58+ kind : Kind . FRAGMENT_SPREAD ,
59+ name : { kind : Kind . NAME , value : 'TestFragment' } ,
60+ arguments : parseFragmentArguments ( fragmentArgs ) ,
61+ } ;
62+ return getFragmentVariableValues (
63+ spread ,
64+ fragmentSignatures ,
65+ Object . create ( null ) ,
66+ undefined ,
67+ ) ;
68+ }
69+
70+ function parseFragmentArguments (
71+ fragmentArguments : string ,
72+ ) : ReadonlyArray < FragmentArgumentNode > {
73+ const parser = new Parser ( fragmentArguments , { noLocation : true } ) ;
74+ parser . expectToken ( TokenKind . SOF ) ;
75+ return parser . parseFragmentArguments ( ) ?? [ ] ;
76+ }
77+
3478describe ( 'replaceVariables' , ( ) => {
3579 describe ( 'Operation Variables' , ( ) => {
3680 it ( 'does not change simple AST' , ( ) => {
@@ -96,7 +140,7 @@ describe('replaceVariables', () => {
96140 describe ( 'Fragment Variables' , ( ) => {
97141 it ( 'replaces simple Fragment Variables' , ( ) => {
98142 const ast = parseValue ( '$var' ) ;
99- const fragmentVars = testVariables ( '($var: Int)' , { var : 123 } ) ;
143+ const fragmentVars = testFragmentVariables ( '($var: Int)' , `( var: 123)` ) ;
100144 expect ( replaceVariables ( ast , undefined , fragmentVars ) ) . to . deep . equal (
101145 parseValue ( '123' ) ,
102146 ) ;
@@ -105,15 +149,15 @@ describe('replaceVariables', () => {
105149 it ( 'replaces simple Fragment Variables even when overlapping with Operation Variables' , ( ) => {
106150 const ast = parseValue ( '$var' ) ;
107151 const operationVars = testVariables ( '($var: Int)' , { var : 123 } ) ;
108- const fragmentVars = testVariables ( '($var: Int)' , { var : 456 } ) ;
152+ const fragmentVars = testFragmentVariables ( '($var: Int)' , '( var: 456)' ) ;
109153 expect ( replaceVariables ( ast , operationVars , fragmentVars ) ) . to . deep . equal (
110154 parseValue ( '456' ) ,
111155 ) ;
112156 } ) ;
113157
114158 it ( 'replaces Fragment Variables with default values' , ( ) => {
115159 const ast = parseValue ( '$var' ) ;
116- const fragmentVars = testVariables ( '($var: Int = 123)' , { } ) ;
160+ const fragmentVars = testFragmentVariables ( '($var: Int = 123)' , '' ) ;
117161 expect ( replaceVariables ( ast , undefined , fragmentVars ) ) . to . deep . equal (
118162 parseValue ( '123' ) ,
119163 ) ;
@@ -122,15 +166,15 @@ describe('replaceVariables', () => {
122166 it ( 'replaces Fragment Variables with default values even when overlapping with Operation Variables' , ( ) => {
123167 const ast = parseValue ( '$var' ) ;
124168 const operationVars = testVariables ( '($var: Int = 123)' , { } ) ;
125- const fragmentVars = testVariables ( '($var: Int = 456)' , { } ) ;
169+ const fragmentVars = testFragmentVariables ( '($var: Int = 456)' , '' ) ;
126170 expect ( replaceVariables ( ast , operationVars , fragmentVars ) ) . to . deep . equal (
127171 parseValue ( '456' ) ,
128172 ) ;
129173 } ) ;
130174
131175 it ( 'replaces nested Fragment Variables' , ( ) => {
132176 const ast = parseValue ( '{ foo: [ $var ], bar: $var }' ) ;
133- const fragmentVars = testVariables ( '($var: Int)' , { var : 123 } ) ;
177+ const fragmentVars = testFragmentVariables ( '($var: Int)' , '( var: 123)' ) ;
134178 expect ( replaceVariables ( ast , undefined , fragmentVars ) ) . to . deep . equal (
135179 parseValue ( '{ foo: [ 123 ], bar: 123 }' ) ,
136180 ) ;
@@ -139,7 +183,7 @@ describe('replaceVariables', () => {
139183 it ( 'replaces nested Fragment Variables even when overlapping with Operation Variables' , ( ) => {
140184 const ast = parseValue ( '{ foo: [ $var ], bar: $var }' ) ;
141185 const operationVars = testVariables ( '($var: Int)' , { var : 123 } ) ;
142- const fragmentVars = testVariables ( '($var: Int)' , { var : 456 } ) ;
186+ const fragmentVars = testFragmentVariables ( '($var: Int)' , '( var: 456)' ) ;
143187 expect ( replaceVariables ( ast , operationVars , fragmentVars ) ) . to . deep . equal (
144188 parseValue ( '{ foo: [ 456 ], bar: 456 }' ) ,
145189 ) ;
@@ -155,7 +199,7 @@ describe('replaceVariables', () => {
155199 it ( 'replaces missing Fragment Variables with null even when overlapping with Operation Variables' , ( ) => {
156200 const ast = parseValue ( '$var' ) ;
157201 const operationVars = testVariables ( '($var: Int)' , { var : 123 } ) ;
158- const fragmentVars = testVariables ( '($var: Int)' , { } ) ;
202+ const fragmentVars = testFragmentVariables ( '($var: Int)' , '' ) ;
159203 expect ( replaceVariables ( ast , operationVars , fragmentVars ) ) . to . deep . equal (
160204 parseValue ( 'null' ) ,
161205 ) ;
@@ -171,7 +215,7 @@ describe('replaceVariables', () => {
171215 it ( 'replaces missing Fragment Variables in lists with null even when overlapping with Operation Variables' , ( ) => {
172216 const ast = parseValue ( '[1, $var]' ) ;
173217 const operationVars = testVariables ( '($var: Int)' , { var : 123 } ) ;
174- const fragmentVars = testVariables ( '($var: Int)' , { } ) ;
218+ const fragmentVars = testFragmentVariables ( '($var: Int)' , '' ) ;
175219 expect ( replaceVariables ( ast , operationVars , fragmentVars ) ) . to . deep . equal (
176220 parseValue ( '[1, null]' ) ,
177221 ) ;
@@ -187,7 +231,7 @@ describe('replaceVariables', () => {
187231 it ( 'omits missing Fragment Variables from objects even when overlapping with Operation Variables' , ( ) => {
188232 const ast = parseValue ( '{ foo: 1, bar: $var }' ) ;
189233 const operationVars = testVariables ( '($var: Int)' , { var : 123 } ) ;
190- const fragmentVars = testVariables ( '($var: Int)' , { } ) ;
234+ const fragmentVars = testFragmentVariables ( '($var: Int)' , '' ) ;
191235 expect ( replaceVariables ( ast , operationVars , fragmentVars ) ) . to . deep . equal (
192236 parseValue ( '{ foo: 1 }' ) ,
193237 ) ;
0 commit comments