Skip to content

Commit 213c8a7

Browse files
Add Flow typing for 'print' function (#1702)
1 parent 7947145 commit 213c8a7

File tree

7 files changed

+64
-52
lines changed

7 files changed

+64
-52
lines changed

src/language/__tests__/printer-test.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @noflow
7+
* @flow strict
88
*/
99

1010
import { expect } from 'chai';
@@ -29,6 +29,7 @@ describe('Printer: Query document', () => {
2929

3030
it('produces helpful error messages', () => {
3131
const badAst1 = { random: 'Data' };
32+
// $DisableFlowOnNegativeTest
3233
expect(() => print(badAst1)).to.throw(
3334
'Invalid AST Node: { random: "Data" }',
3435
);
@@ -166,6 +167,7 @@ describe('Printer: Query document', () => {
166167
const printed = print(parse(kitchenSinkQuery));
167168

168169
expect(printed).to.equal(
170+
// $FlowFixMe
169171
dedent(String.raw`
170172
query queryName($foo: ComplexType, $site: Site = MOBILE) @onQuery {
171173
whoever123is: node(id: [123, 456]) {

src/language/__tests__/schema-printer-test.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ describe('Printer: SDL document', () => {
2525

2626
it('produces helpful error messages', () => {
2727
const badAst1 = { random: 'Data' };
28+
// $DisableFlowOnNegativeTest
2829
expect(() => print(badAst1)).to.throw(
2930
'Invalid AST Node: { random: "Data" }',
3031
);

src/language/printer.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,22 @@
44
* This source code is licensed under the MIT license found in the
55
* LICENSE file in the root directory of this source tree.
66
*
7-
* @noflow
7+
* @flow strict
88
*/
99

10+
import type { ASTNode } from './ast';
1011
import { visit } from './visitor';
1112

1213
/**
1314
* Converts an AST into a string, using one set of reasonable
1415
* formatting rules.
1516
*/
16-
export function print(ast) {
17+
export function print(ast: ASTNode): string {
1718
return visit(ast, { leave: printDocASTReducer });
1819
}
1920

20-
const printDocASTReducer = {
21+
// TODO: provide better type coverage in future
22+
const printDocASTReducer: any = {
2123
Name: node => node.value,
2224
Variable: node => '$' + node.name,
2325

src/type/introspection.js

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
*/
99

1010
import objectValues from '../polyfills/objectValues';
11-
import isInvalid from '../jsutils/isInvalid';
1211
import { astFromValue } from '../utilities/astFromValue';
1312
import { print } from '../language/printer';
1413
import {
@@ -348,10 +347,10 @@ export const __InputValue = new GraphQLObjectType({
348347
description:
349348
'A GraphQL-formatted string representing the default value for this ' +
350349
'input value.',
351-
resolve: inputVal =>
352-
isInvalid(inputVal.defaultValue)
353-
? null
354-
: print(astFromValue(inputVal.defaultValue, inputVal.type)),
350+
resolve(inputVal) {
351+
const valueAST = astFromValue(inputVal.defaultValue, inputVal.type);
352+
return valueAST ? print(valueAST) : null;
353+
},
355354
},
356355
}),
357356
});

src/utilities/__tests__/buildASTSchema-test.js

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,11 @@ function cycleSDL(sdl, options = {}) {
4242
return printSchema(schema, { commentDescriptions });
4343
}
4444

45+
function printNode(node) {
46+
invariant(node);
47+
return print(node);
48+
}
49+
4550
describe('Schema Builder', () => {
4651
it('can use built schema for limited execution', () => {
4752
const schema = buildASTSchema(
@@ -678,8 +683,9 @@ describe('Schema Builder', () => {
678683
679684
directive @test(arg: TestScalar) on FIELD
680685
`;
686+
const ast = parse(sdl, { noLocation: true });
681687

682-
const schema = buildSchema(sdl);
688+
const schema = buildASTSchema(ast);
683689
const query = assertObjectType(schema.getType('Query'));
684690
const testInput = assertInputObjectType(schema.getType('TestInput'));
685691
const testEnum = assertEnumType(schema.getType('TestEnum'));
@@ -702,28 +708,31 @@ describe('Schema Builder', () => {
702708
testScalar.astNode,
703709
testDirective.astNode,
704710
],
711+
loc: undefined,
705712
};
706-
expect(print(restoredSchemaAST)).to.be.equal(sdl);
713+
expect(restoredSchemaAST).to.be.deep.equal(ast);
707714

708715
const testField = query.getFields().testField;
709-
expect(print(testField.astNode)).to.equal(
716+
expect(printNode(testField.astNode)).to.equal(
710717
'testField(testArg: TestInput): TestUnion',
711718
);
712-
expect(print(testField.args[0].astNode)).to.equal('testArg: TestInput');
713-
expect(print(testInput.getFields().testInputField.astNode)).to.equal(
719+
expect(printNode(testField.args[0].astNode)).to.equal('testArg: TestInput');
720+
expect(printNode(testInput.getFields().testInputField.astNode)).to.equal(
714721
'testInputField: TestEnum',
715722
);
716723
const testEnumValue = testEnum.getValue('TEST_VALUE');
717724
invariant(testEnumValue);
718-
expect(print(testEnumValue.astNode)).to.equal('TEST_VALUE');
725+
expect(printNode(testEnumValue.astNode)).to.equal('TEST_VALUE');
719726

720-
expect(print(testInterface.getFields().interfaceField.astNode)).to.equal(
727+
expect(
728+
printNode(testInterface.getFields().interfaceField.astNode),
729+
).to.equal('interfaceField: String');
730+
expect(printNode(testType.getFields().interfaceField.astNode)).to.equal(
721731
'interfaceField: String',
722732
);
723-
expect(print(testType.getFields().interfaceField.astNode)).to.equal(
724-
'interfaceField: String',
733+
expect(printNode(testDirective.args[0].astNode)).to.equal(
734+
'arg: TestScalar',
725735
);
726-
expect(print(testDirective.args[0].astNode)).to.equal('arg: TestScalar');
727736
});
728737

729738
it('Root operation types with custom names', () => {

src/utilities/__tests__/extendSchema-test.js

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -157,13 +157,18 @@ const testSchemaDefinitions = testSchemaAST.definitions.map(print);
157157
function printTestSchemaChanges(extendedSchema) {
158158
const ast = parse(printSchema(extendedSchema));
159159
return print({
160-
...ast,
160+
kind: Kind.DOCUMENT,
161161
definitions: ast.definitions.filter(
162162
node => !testSchemaDefinitions.includes(print(node)),
163163
),
164164
});
165165
}
166166

167+
function printNode(node) {
168+
invariant(node);
169+
return print(node);
170+
}
171+
167172
describe('extendSchema', () => {
168173
it('returns the original schema when there are no type definitions', () => {
169174
const extendedSchema = extendTestSchema('{ field }');
@@ -476,49 +481,49 @@ describe('extendSchema', () => {
476481
).to.be.equal(printSchema(extendedTwiceSchema));
477482

478483
const newField = query.getFields().newField;
479-
expect(print(newField.astNode)).to.equal(
484+
expect(printNode(newField.astNode)).to.equal(
480485
'newField(testArg: TestInput): TestEnum',
481486
);
482-
expect(print(newField.args[0].astNode)).to.equal('testArg: TestInput');
483-
expect(print(query.getFields().oneMoreNewField.astNode)).to.equal(
487+
expect(printNode(newField.args[0].astNode)).to.equal('testArg: TestInput');
488+
expect(printNode(query.getFields().oneMoreNewField.astNode)).to.equal(
484489
'oneMoreNewField: TestUnion',
485490
);
486491

487492
const newValue = someEnum.getValue('NEW_VALUE');
488493
invariant(newValue);
489-
expect(print(newValue.astNode)).to.equal('NEW_VALUE');
494+
expect(printNode(newValue.astNode)).to.equal('NEW_VALUE');
490495

491496
const oneMoreNewValue = someEnum.getValue('ONE_MORE_NEW_VALUE');
492497
invariant(oneMoreNewValue);
493-
expect(print(oneMoreNewValue.astNode)).to.equal('ONE_MORE_NEW_VALUE');
494-
expect(print(someInput.getFields().newField.astNode)).to.equal(
498+
expect(printNode(oneMoreNewValue.astNode)).to.equal('ONE_MORE_NEW_VALUE');
499+
expect(printNode(someInput.getFields().newField.astNode)).to.equal(
495500
'newField: String',
496501
);
497-
expect(print(someInput.getFields().oneMoreNewField.astNode)).to.equal(
502+
expect(printNode(someInput.getFields().oneMoreNewField.astNode)).to.equal(
498503
'oneMoreNewField: String',
499504
);
500-
expect(print(someInterface.getFields().newField.astNode)).to.equal(
505+
expect(printNode(someInterface.getFields().newField.astNode)).to.equal(
501506
'newField: String',
502507
);
503-
expect(print(someInterface.getFields().oneMoreNewField.astNode)).to.equal(
504-
'oneMoreNewField: String',
505-
);
508+
expect(
509+
printNode(someInterface.getFields().oneMoreNewField.astNode),
510+
).to.equal('oneMoreNewField: String');
506511

507-
expect(print(testInput.getFields().testInputField.astNode)).to.equal(
512+
expect(printNode(testInput.getFields().testInputField.astNode)).to.equal(
508513
'testInputField: TestEnum',
509514
);
510515

511516
const testValue = testEnum.getValue('TEST_VALUE');
512517
invariant(testValue);
513-
expect(print(testValue.astNode)).to.equal('TEST_VALUE');
518+
expect(printNode(testValue.astNode)).to.equal('TEST_VALUE');
514519

515-
expect(print(testInterface.getFields().interfaceField.astNode)).to.equal(
516-
'interfaceField: String',
517-
);
518-
expect(print(testType.getFields().interfaceField.astNode)).to.equal(
520+
expect(
521+
printNode(testInterface.getFields().interfaceField.astNode),
522+
).to.equal('interfaceField: String');
523+
expect(printNode(testType.getFields().interfaceField.astNode)).to.equal(
519524
'interfaceField: String',
520525
);
521-
expect(print(testDirective.args[0].astNode)).to.equal('arg: Int');
526+
expect(printNode(testDirective.args[0].astNode)).to.equal('arg: Int');
522527
});
523528

524529
it('builds types with deprecated fields/values', () => {
@@ -1173,7 +1178,7 @@ describe('extendSchema', () => {
11731178

11741179
const queryType = schema.getQueryType();
11751180
expect(queryType).to.include({ name: 'Foo' });
1176-
expect(print(schema.astNode)).to.equal(extensionSDL);
1181+
expect(printNode(schema.astNode)).to.equal(extensionSDL);
11771182
});
11781183

11791184
it('adds new root types via schema extension', () => {

src/utilities/schemaPrinter.js

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@
99

1010
import flatMap from '../polyfills/flatMap';
1111
import objectValues from '../polyfills/objectValues';
12-
import isNullish from '../jsutils/isNullish';
13-
import isInvalid from '../jsutils/isInvalid';
1412
import { astFromValue } from '../utilities/astFromValue';
1513
import { print } from '../language/printer';
1614
import type { GraphQLSchema } from '../type/schema';
@@ -297,9 +295,10 @@ function printArgs(options, args, indentation = '') {
297295
}
298296

299297
function printInputValue(arg) {
298+
const defaultAST = astFromValue(arg.defaultValue, arg.type);
300299
let argDecl = arg.name + ': ' + String(arg.type);
301-
if (!isInvalid(arg.defaultValue)) {
302-
argDecl += ` = ${print(astFromValue(arg.defaultValue, arg.type))}`;
300+
if (defaultAST) {
301+
argDecl += ` = ${print(defaultAST)}`;
303302
}
304303
return argDecl;
305304
}
@@ -320,16 +319,11 @@ function printDeprecated(fieldOrEnumVal) {
320319
return '';
321320
}
322321
const reason = fieldOrEnumVal.deprecationReason;
323-
if (
324-
isNullish(reason) ||
325-
reason === '' ||
326-
reason === DEFAULT_DEPRECATION_REASON
327-
) {
328-
return ' @deprecated';
322+
const reasonAST = astFromValue(reason, GraphQLString);
323+
if (reasonAST && reason !== '' && reason !== DEFAULT_DEPRECATION_REASON) {
324+
return ' @deprecated(reason: ' + print(reasonAST) + ')';
329325
}
330-
return (
331-
' @deprecated(reason: ' + print(astFromValue(reason, GraphQLString)) + ')'
332-
);
326+
return ' @deprecated';
333327
}
334328
335329
function printDescription(

0 commit comments

Comments
 (0)