Skip to content

Commit 0d2889c

Browse files
committed
Bring back tests for valueFromAST
1 parent b476eac commit 0d2889c

File tree

1 file changed

+254
-1
lines changed

1 file changed

+254
-1
lines changed

src/utilities/__tests__/valueFromAST-test.js

Lines changed: 254 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,43 @@
33
import { expect } from 'chai';
44
import { describe, it } from 'mocha';
55

6+
import type { ObjMap } from '../../jsutils/ObjMap';
7+
import { invariant } from '../../jsutils/invariant';
8+
import { identityFunc } from '../../jsutils/identityFunc';
9+
610
import { parseValue } from '../../language/parser';
7-
import { GraphQLBoolean } from '../../type/scalars';
11+
12+
import type { GraphQLInputType } from '../../type/definition';
13+
import {
14+
GraphQLInt,
15+
GraphQLFloat,
16+
GraphQLString,
17+
GraphQLBoolean,
18+
GraphQLID,
19+
} from '../../type/scalars';
20+
import {
21+
GraphQLList,
22+
GraphQLNonNull,
23+
GraphQLScalarType,
24+
GraphQLEnumType,
25+
GraphQLInputObjectType,
26+
} from '../../type/definition';
27+
828
import { valueFromAST } from '../valueFromAST';
929

1030
import { expectWarning } from './expectWarning';
1131

1232
describe('valueFromAST', () => {
33+
function expectValueFrom(
34+
valueText: string,
35+
type: GraphQLInputType,
36+
variables?: ObjMap<mixed>,
37+
) {
38+
const ast = parseValue(valueText);
39+
const value = valueFromAST(ast, type, variables);
40+
return expect(value);
41+
}
42+
1343
it('warns about deprecation', () => {
1444
expectWarning(() =>
1545
valueFromAST(parseValue('true'), GraphQLBoolean),
@@ -21,4 +51,227 @@ describe('valueFromAST', () => {
2151
it('rejects empty input', () => {
2252
expect(valueFromAST(null, GraphQLBoolean)).to.deep.equal(undefined);
2353
});
54+
55+
it('converts according to input coercion rules', () => {
56+
expectValueFrom('true', GraphQLBoolean).to.equal(true);
57+
expectValueFrom('false', GraphQLBoolean).to.equal(false);
58+
expectValueFrom('123', GraphQLInt).to.equal(123);
59+
expectValueFrom('123', GraphQLFloat).to.equal(123);
60+
expectValueFrom('123.456', GraphQLFloat).to.equal(123.456);
61+
expectValueFrom('"abc123"', GraphQLString).to.equal('abc123');
62+
expectValueFrom('123456', GraphQLID).to.equal('123456');
63+
expectValueFrom('"123456"', GraphQLID).to.equal('123456');
64+
});
65+
66+
it('does not convert when input coercion rules reject a value', () => {
67+
expectValueFrom('123', GraphQLBoolean).to.equal(undefined);
68+
expectValueFrom('123.456', GraphQLInt).to.equal(undefined);
69+
expectValueFrom('true', GraphQLInt).to.equal(undefined);
70+
expectValueFrom('"123"', GraphQLInt).to.equal(undefined);
71+
expectValueFrom('"123"', GraphQLFloat).to.equal(undefined);
72+
expectValueFrom('123', GraphQLString).to.equal(undefined);
73+
expectValueFrom('true', GraphQLString).to.equal(undefined);
74+
expectValueFrom('123.456', GraphQLString).to.equal(undefined);
75+
});
76+
77+
it('convert using parseLiteral from a custom scalar type', () => {
78+
const passthroughScalar = new GraphQLScalarType({
79+
name: 'PassthroughScalar',
80+
parseLiteral(node) {
81+
invariant(node.kind === 'StringValue');
82+
return node.value;
83+
},
84+
parseValue: identityFunc,
85+
});
86+
87+
expectValueFrom('"value"', passthroughScalar).to.equal('value');
88+
89+
const throwScalar = new GraphQLScalarType({
90+
name: 'ThrowScalar',
91+
parseLiteral() {
92+
throw new Error('Test');
93+
},
94+
parseValue: identityFunc,
95+
});
96+
97+
expectValueFrom('value', throwScalar).to.equal(undefined);
98+
99+
const returnUndefinedScalar = new GraphQLScalarType({
100+
name: 'ReturnUndefinedScalar',
101+
parseLiteral() {
102+
return undefined;
103+
},
104+
parseValue: identityFunc,
105+
});
106+
107+
expectValueFrom('value', returnUndefinedScalar).to.equal(undefined);
108+
});
109+
110+
it('converts enum values according to input coercion rules', () => {
111+
const testEnum = new GraphQLEnumType({
112+
name: 'TestColor',
113+
values: {
114+
RED: { value: 1 },
115+
GREEN: { value: 2 },
116+
BLUE: { value: 3 },
117+
NULL: { value: null },
118+
NAN: { value: NaN },
119+
NO_CUSTOM_VALUE: { value: undefined },
120+
},
121+
});
122+
123+
expectValueFrom('RED', testEnum).to.equal(1);
124+
expectValueFrom('BLUE', testEnum).to.equal(3);
125+
expectValueFrom('3', testEnum).to.equal(undefined);
126+
expectValueFrom('"BLUE"', testEnum).to.equal(undefined);
127+
expectValueFrom('null', testEnum).to.equal(null);
128+
expectValueFrom('NULL', testEnum).to.equal(null);
129+
expectValueFrom('NULL', new GraphQLNonNull(testEnum)).to.equal(null);
130+
expectValueFrom('NAN', testEnum).to.deep.equal(NaN);
131+
expectValueFrom('NO_CUSTOM_VALUE', testEnum).to.equal('NO_CUSTOM_VALUE');
132+
});
133+
134+
// Boolean!
135+
const nonNullBool = new GraphQLNonNull(GraphQLBoolean);
136+
// [Boolean]
137+
const listOfBool = new GraphQLList(GraphQLBoolean);
138+
// [Boolean!]
139+
const listOfNonNullBool = new GraphQLList(nonNullBool);
140+
// [Boolean]!
141+
const nonNullListOfBool = new GraphQLNonNull(listOfBool);
142+
// [Boolean!]!
143+
const nonNullListOfNonNullBool = new GraphQLNonNull(listOfNonNullBool);
144+
145+
it('coerces to null unless non-null', () => {
146+
expectValueFrom('null', GraphQLBoolean).to.equal(null);
147+
expectValueFrom('null', nonNullBool).to.equal(undefined);
148+
});
149+
150+
it('coerces lists of values', () => {
151+
expectValueFrom('true', listOfBool).to.deep.equal([true]);
152+
expectValueFrom('123', listOfBool).to.equal(undefined);
153+
expectValueFrom('null', listOfBool).to.equal(null);
154+
expectValueFrom('[true, false]', listOfBool).to.deep.equal([true, false]);
155+
expectValueFrom('[true, 123]', listOfBool).to.equal(undefined);
156+
expectValueFrom('[true, null]', listOfBool).to.deep.equal([true, null]);
157+
expectValueFrom('{ true: true }', listOfBool).to.equal(undefined);
158+
});
159+
160+
it('coerces non-null lists of values', () => {
161+
expectValueFrom('true', nonNullListOfBool).to.deep.equal([true]);
162+
expectValueFrom('123', nonNullListOfBool).to.equal(undefined);
163+
expectValueFrom('null', nonNullListOfBool).to.equal(undefined);
164+
expectValueFrom('[true, false]', nonNullListOfBool).to.deep.equal([
165+
true,
166+
false,
167+
]);
168+
expectValueFrom('[true, 123]', nonNullListOfBool).to.equal(undefined);
169+
expectValueFrom('[true, null]', nonNullListOfBool).to.deep.equal([
170+
true,
171+
null,
172+
]);
173+
});
174+
175+
it('coerces lists of non-null values', () => {
176+
expectValueFrom('true', listOfNonNullBool).to.deep.equal([true]);
177+
expectValueFrom('123', listOfNonNullBool).to.equal(undefined);
178+
expectValueFrom('null', listOfNonNullBool).to.equal(null);
179+
expectValueFrom('[true, false]', listOfNonNullBool).to.deep.equal([
180+
true,
181+
false,
182+
]);
183+
expectValueFrom('[true, 123]', listOfNonNullBool).to.equal(undefined);
184+
expectValueFrom('[true, null]', listOfNonNullBool).to.equal(undefined);
185+
});
186+
187+
it('coerces non-null lists of non-null values', () => {
188+
expectValueFrom('true', nonNullListOfNonNullBool).to.deep.equal([true]);
189+
expectValueFrom('123', nonNullListOfNonNullBool).to.equal(undefined);
190+
expectValueFrom('null', nonNullListOfNonNullBool).to.equal(undefined);
191+
expectValueFrom('[true, false]', nonNullListOfNonNullBool).to.deep.equal([
192+
true,
193+
false,
194+
]);
195+
expectValueFrom('[true, 123]', nonNullListOfNonNullBool).to.equal(
196+
undefined,
197+
);
198+
expectValueFrom('[true, null]', nonNullListOfNonNullBool).to.equal(
199+
undefined,
200+
);
201+
});
202+
203+
const testInputObj = new GraphQLInputObjectType({
204+
name: 'TestInput',
205+
fields: {
206+
int: { type: GraphQLInt, defaultValue: 42 },
207+
bool: { type: GraphQLBoolean },
208+
requiredBool: { type: nonNullBool },
209+
},
210+
});
211+
212+
it('coerces input objects according to input coercion rules', () => {
213+
expectValueFrom('null', testInputObj).to.equal(null);
214+
expectValueFrom('123', testInputObj).to.equal(undefined);
215+
expectValueFrom('[]', testInputObj).to.equal(undefined);
216+
expectValueFrom(
217+
'{ int: 123, requiredBool: false }',
218+
testInputObj,
219+
).to.deep.equal({
220+
int: 123,
221+
requiredBool: false,
222+
});
223+
expectValueFrom(
224+
'{ bool: true, requiredBool: false }',
225+
testInputObj,
226+
).to.deep.equal({
227+
int: 42,
228+
bool: true,
229+
requiredBool: false,
230+
});
231+
expectValueFrom('{ int: true, requiredBool: true }', testInputObj).to.equal(
232+
undefined,
233+
);
234+
expectValueFrom('{ requiredBool: null }', testInputObj).to.equal(undefined);
235+
expectValueFrom('{ bool: true }', testInputObj).to.equal(undefined);
236+
});
237+
238+
it('accepts variable values assuming already coerced', () => {
239+
expectValueFrom('$var', GraphQLBoolean, {}).to.equal(undefined);
240+
expectValueFrom('$var', GraphQLBoolean, { var: true }).to.equal(true);
241+
expectValueFrom('$var', GraphQLBoolean, { var: null }).to.equal(null);
242+
expectValueFrom('$var', nonNullBool, { var: null }).to.equal(undefined);
243+
});
244+
245+
it('asserts variables are provided as items in lists', () => {
246+
expectValueFrom('[ $foo ]', listOfBool, {}).to.deep.equal([null]);
247+
expectValueFrom('[ $foo ]', listOfNonNullBool, {}).to.equal(undefined);
248+
expectValueFrom('[ $foo ]', listOfNonNullBool, {
249+
foo: true,
250+
}).to.deep.equal([true]);
251+
// Note: variables are expected to have already been coerced, so we
252+
// do not expect the singleton wrapping behavior for variables.
253+
expectValueFrom('$foo', listOfNonNullBool, { foo: true }).to.equal(true);
254+
expectValueFrom('$foo', listOfNonNullBool, { foo: [true] }).to.deep.equal([
255+
true,
256+
]);
257+
});
258+
259+
it('omits input object fields for unprovided variables', () => {
260+
expectValueFrom(
261+
'{ int: $foo, bool: $foo, requiredBool: true }',
262+
testInputObj,
263+
{},
264+
).to.deep.equal({ int: 42, requiredBool: true });
265+
266+
expectValueFrom('{ requiredBool: $foo }', testInputObj, {}).to.equal(
267+
undefined,
268+
);
269+
270+
expectValueFrom('{ requiredBool: $foo }', testInputObj, {
271+
foo: true,
272+
}).to.deep.equal({
273+
int: 42,
274+
requiredBool: true,
275+
});
276+
});
24277
});

0 commit comments

Comments
 (0)