Skip to content

Commit ef0f1ab

Browse files
Change devAsserts for checking source argument (#2784)
Motivation #2503 (comment)
1 parent 3fa32c9 commit ef0f1ab

File tree

7 files changed

+49
-43
lines changed

7 files changed

+49
-43
lines changed

src/language/__tests__/parser-test.js

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,6 @@ function expectSyntaxError(text: string) {
2121
}
2222

2323
describe('Parser', () => {
24-
it('asserts that a source to parse was provided', () => {
25-
// $FlowExpectedError[incompatible-call]
26-
expect(() => parse()).to.throw('Must provide Source. Received: undefined.');
27-
});
28-
29-
it('asserts that an invalid source to parse was provided', () => {
30-
// $FlowExpectedError[incompatible-call]
31-
expect(() => parse({})).to.throw('Must provide Source. Received: {}.');
32-
});
33-
3424
it('parse provides useful errors', () => {
3525
let caughtError;
3626
try {

src/language/__tests__/source-test.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,20 @@ import { describe, it } from 'mocha';
44
import { Source } from '../source';
55

66
describe('Source', () => {
7+
it('asserts that a body was provided', () => {
8+
// $FlowExpectedError[incompatible-call]
9+
expect(() => new Source()).to.throw(
10+
'Body must be a string. Received: undefined.',
11+
);
12+
});
13+
14+
it('asserts that a valid body was provided', () => {
15+
// $FlowExpectedError[incompatible-call]
16+
expect(() => new Source({})).to.throw(
17+
'Body must be a string. Received: {}.',
18+
);
19+
});
20+
721
it('can be Object.toStringified', () => {
822
const source = new Source('');
923

src/language/parser.js

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,3 @@
1-
import inspect from '../jsutils/inspect';
2-
import devAssert from '../jsutils/devAssert';
3-
41
import type { GraphQLError } from '../error/GraphQLError';
52
import { syntaxError } from '../error/syntaxError';
63

@@ -53,8 +50,8 @@ import type {
5350
} from './ast';
5451
import { Kind } from './kinds';
5552
import { Location } from './ast';
56-
import { Source } from './source';
5753
import { TokenKind } from './tokenKind';
54+
import { Source, isSource } from './source';
5855
import { DirectiveLocation } from './directiveLocation';
5956
import { Lexer, isPunctuatorTokenKind } from './lexer';
6057

@@ -178,11 +175,7 @@ export class Parser {
178175
_lexer: Lexer;
179176

180177
constructor(source: string | Source, options?: ParseOptions) {
181-
const sourceObj = typeof source === 'string' ? new Source(source) : source;
182-
devAssert(
183-
sourceObj instanceof Source,
184-
`Must provide Source. Received: ${inspect(sourceObj)}.`,
185-
);
178+
const sourceObj = isSource(source) ? source : new Source(source);
186179

187180
this._lexer = new Lexer(sourceObj);
188181
this._options = options;

src/language/source.d.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,10 @@ export class Source {
1616
locationOffset: Location;
1717
constructor(body: string, name?: string, locationOffset?: Location);
1818
}
19+
20+
/**
21+
* Test if the given value is a Source object.
22+
*
23+
* @internal
24+
*/
25+
export function isSource(source: any): source is Source;

src/language/source.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import { SYMBOL_TO_STRING_TAG } from '../polyfills/symbols';
22

3+
import inspect from '../jsutils/inspect';
34
import devAssert from '../jsutils/devAssert';
5+
import instanceOf from '../jsutils/instanceOf';
46

57
type Location = {|
68
line: number,
@@ -24,6 +26,11 @@ export class Source {
2426
name: string = 'GraphQL request',
2527
locationOffset: Location = { line: 1, column: 1 },
2628
): void {
29+
devAssert(
30+
typeof body === 'string',
31+
`Body must be a string. Received: ${inspect(body)}.`,
32+
);
33+
2734
this.body = body;
2835
this.name = name;
2936
this.locationOffset = locationOffset;
@@ -42,3 +49,15 @@ export class Source {
4249
return 'Source';
4350
}
4451
}
52+
53+
/**
54+
* Test if the given value is a Source object.
55+
*
56+
* @internal
57+
*/
58+
declare function isSource(source: mixed): boolean %checks(source instanceof
59+
Source);
60+
// eslint-disable-next-line no-redeclare
61+
export function isSource(source) {
62+
return instanceOf(source, Source);
63+
}

src/utilities/__tests__/stripIgnoredCharacters-test.js

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ import inspectStr from '../../__testUtils__/inspectStr';
66

77
import invariant from '../../jsutils/invariant';
88

9+
import { Lexer } from '../../language/lexer';
910
import { parse } from '../../language/parser';
1011
import { Source } from '../../language/source';
11-
import { Lexer } from '../../language/lexer';
1212

1313
import { stripIgnoredCharacters } from '../stripIgnoredCharacters';
1414

@@ -98,20 +98,6 @@ function expectStripped(docString: string) {
9898
}
9999

100100
describe('stripIgnoredCharacters', () => {
101-
it('asserts that a source was provided', () => {
102-
// $FlowExpectedError[incompatible-call]
103-
expect(() => stripIgnoredCharacters()).to.throw(
104-
'Must provide string or Source. Received: undefined.',
105-
);
106-
});
107-
108-
it('asserts that a valid source was provided', () => {
109-
// $FlowExpectedError[incompatible-call]
110-
expect(() => stripIgnoredCharacters({})).to.throw(
111-
'Must provide string or Source. Received: {}.',
112-
);
113-
});
114-
115101
it('strips ignored characters from GraphQL query document', () => {
116102
const query = dedent`
117103
query SomeQuery($foo: String!, $bar: String) {
@@ -130,6 +116,10 @@ describe('stripIgnoredCharacters', () => {
130116
);
131117
});
132118

119+
it('accepts Source object', () => {
120+
expect(stripIgnoredCharacters(new Source('{ a }'))).to.equal('{a}');
121+
});
122+
133123
it('strips ignored characters from GraphQL SDL document', () => {
134124
const sdl = dedent`
135125
"""

src/utilities/stripIgnoredCharacters.js

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
import inspect from '../jsutils/inspect';
2-
3-
import { Source } from '../language/source';
1+
import { Source, isSource } from '../language/source';
42
import { TokenKind } from '../language/tokenKind';
53
import { Lexer, isPunctuatorTokenKind } from '../language/lexer';
64
import {
@@ -61,12 +59,7 @@ import {
6159
* """Type description""" type Foo{"""Field description""" bar:String}
6260
*/
6361
export function stripIgnoredCharacters(source: string | Source): string {
64-
const sourceObj = typeof source === 'string' ? new Source(source) : source;
65-
if (!(sourceObj instanceof Source)) {
66-
throw new TypeError(
67-
`Must provide string or Source. Received: ${inspect(sourceObj)}.`,
68-
);
69-
}
62+
const sourceObj = isSource(source) ? source : new Source(source);
7063

7164
const body = sourceObj.body;
7265
const lexer = new Lexer(sourceObj);

0 commit comments

Comments
 (0)