Skip to content

Commit 93c0b25

Browse files
RomanHotsiyleebyron
authored andcommitted
Fix identation (#916)
* Add dedent jsutil * Fix identation in tests interpolation strings
1 parent fa44c33 commit 93c0b25

File tree

8 files changed

+1392
-1357
lines changed

8 files changed

+1392
-1357
lines changed

src/jsutils/dedent.js

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/* @flow */
2+
/**
3+
* Copyright (c) 2017, Facebook, Inc.
4+
* All rights reserved.
5+
*
6+
* This source code is licensed under the BSD-style license found in the
7+
* LICENSE file in the root directory of this source tree. An additional grant
8+
* of patent rights can be found in the PATENTS file in the same directory.
9+
*/
10+
11+
/**
12+
* fixes identation by removing leading spaces from each line
13+
*/
14+
function fixIdent(str: string): string {
15+
const indent = /^\n?( *)/.exec(str)[1]; // figure out ident
16+
return str
17+
.replace(RegExp('^' + indent, 'mg'), '') // remove ident
18+
.replace(/^\n*/m, '') // remove leading newline
19+
.replace(/ *$/, ''); // remove trailing spaces
20+
}
21+
22+
/**
23+
* An ES6 string tag that fixes identation. Also removes leading newlines
24+
* but keeps trailing ones
25+
*
26+
* Example usage:
27+
* const str = dedent`
28+
* {
29+
* test
30+
* }
31+
* `
32+
* str === "{\n test\n}\n";
33+
*/
34+
export default function dedent(
35+
strings: string | { raw: [string]},
36+
...values: Array<string>
37+
) {
38+
const raw = typeof strings === 'string' ? [ strings ] : strings.raw;
39+
let res = '';
40+
// interpolation
41+
for (let i = 0; i < raw.length; i++) {
42+
res += raw[i].replace(/\\`/g, '`'); // handle escaped backticks
43+
44+
if (i < values.length) {
45+
res += values[i];
46+
}
47+
}
48+
49+
return fixIdent(res);
50+
}

src/language/__tests__/parser-test.js

+19-16
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import { parse, parseValue, parseType } from '../parser';
1414
import { Source } from '../source';
1515
import { readFileSync } from 'fs';
1616
import { join } from 'path';
17+
import dedent from '../../jsutils/dedent';
1718

1819
describe('Parser', () => {
1920

@@ -36,12 +37,12 @@ describe('Parser', () => {
3637
caughtError = error;
3738
}
3839

39-
expect(caughtError.message).to.equal(
40-
`Syntax Error GraphQL request (1:2) Expected Name, found <EOF>
40+
expect(caughtError.message).to.equal(dedent`
41+
Syntax Error GraphQL request (1:2) Expected Name, found <EOF>
4142
42-
1: {
43-
^
44-
`
43+
1: {
44+
^
45+
`
4546
);
4647

4748
expect(caughtError.positions).to.deep.equal([ 1 ]);
@@ -51,10 +52,10 @@ describe('Parser', () => {
5152
]);
5253

5354
expect(
54-
() => parse(
55-
`{ ...MissingOn }
56-
fragment MissingOn Type
57-
`)
55+
() => parse(dedent`
56+
{ ...MissingOn }
57+
fragment MissingOn Type
58+
`)
5859
).to.throw(
5960
'Syntax Error GraphQL request (2:20) Expected "on", found Name "Type"'
6061
);
@@ -154,13 +155,15 @@ fragment MissingOn Type
154155
fragmentName = 'a';
155156
}
156157
expect(() => {
157-
parse(`query ${keyword} {
158-
... ${fragmentName}
159-
... on ${keyword} { field }
160-
}
161-
fragment ${fragmentName} on Type {
162-
${keyword}(${keyword}: $${keyword}) @${keyword}(${keyword}: ${keyword})
163-
}`
158+
parse(dedent`
159+
query ${keyword} {
160+
... ${fragmentName}
161+
... on ${keyword} { field }
162+
}
163+
fragment ${fragmentName} on Type {
164+
${keyword}(${keyword}: $${keyword})
165+
@${keyword}(${keyword}: ${keyword})
166+
}`
164167
);
165168
}).to.not.throw();
166169
});

src/language/__tests__/printer-test.js

+72-71
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { parse } from '../parser';
1313
import { readFileSync } from 'fs';
1414
import { print } from '../printer';
1515
import { join } from 'path';
16+
import dedent from '../../jsutils/dedent';
1617

1718
describe('Printer', () => {
1819
it('does not alter ast', () => {
@@ -36,40 +37,40 @@ describe('Printer', () => {
3637

3738
it('correctly prints non-query operations without name', () => {
3839
const queryAstShorthanded = parse('query { id, name }');
39-
expect(print(queryAstShorthanded)).to.equal(
40-
`{
41-
id
42-
name
43-
}
44-
`);
40+
expect(print(queryAstShorthanded)).to.equal(dedent`
41+
{
42+
id
43+
name
44+
}
45+
`);
4546

4647
const mutationAst = parse('mutation { id, name }');
47-
expect(print(mutationAst)).to.equal(
48-
`mutation {
49-
id
50-
name
51-
}
52-
`);
48+
expect(print(mutationAst)).to.equal(dedent`
49+
mutation {
50+
id
51+
name
52+
}
53+
`);
5354

5455
const queryAstWithArtifacts = parse(
5556
'query ($foo: TestType) @testDirective { id, name }'
5657
);
57-
expect(print(queryAstWithArtifacts)).to.equal(
58-
`query ($foo: TestType) @testDirective {
59-
id
60-
name
61-
}
62-
`);
58+
expect(print(queryAstWithArtifacts)).to.equal(dedent`
59+
query ($foo: TestType) @testDirective {
60+
id
61+
name
62+
}
63+
`);
6364

6465
const mutationAstWithArtifacts = parse(
6566
'mutation ($foo: TestType) @testDirective { id, name }'
6667
);
67-
expect(print(mutationAstWithArtifacts)).to.equal(
68-
`mutation ($foo: TestType) @testDirective {
69-
id
70-
name
71-
}
72-
`);
68+
expect(print(mutationAstWithArtifacts)).to.equal(dedent`
69+
mutation ($foo: TestType) @testDirective {
70+
id
71+
name
72+
}
73+
`);
7374
});
7475

7576

@@ -84,58 +85,58 @@ describe('Printer', () => {
8485

8586
const printed = print(ast);
8687

87-
expect(printed).to.equal(
88-
`query queryName($foo: ComplexType, $site: Site = MOBILE) {
89-
whoever123is: node(id: [123, 456]) {
90-
id
91-
... on User @defer {
92-
field2 {
93-
id
94-
alias: field1(first: 10, after: $foo) @include(if: $foo) {
88+
expect(printed).to.equal(dedent`
89+
query queryName($foo: ComplexType, $site: Site = MOBILE) {
90+
whoever123is: node(id: [123, 456]) {
9591
id
96-
...frag
92+
... on User @defer {
93+
field2 {
94+
id
95+
alias: field1(first: 10, after: $foo) @include(if: $foo) {
96+
id
97+
...frag
98+
}
99+
}
100+
}
101+
... @skip(unless: $foo) {
102+
id
103+
}
104+
... {
105+
id
106+
}
97107
}
98108
}
99-
}
100-
... @skip(unless: $foo) {
101-
id
102-
}
103-
... {
104-
id
105-
}
106-
}
107-
}
108-
109-
mutation likeStory {
110-
like(story: 123) @defer {
111-
story {
112-
id
113-
}
114-
}
115-
}
116-
117-
subscription StoryLikeSubscription($input: StoryLikeSubscribeInput) {
118-
storyLikeSubscribe(input: $input) {
119-
story {
120-
likers {
121-
count
109+
110+
mutation likeStory {
111+
like(story: 123) @defer {
112+
story {
113+
id
114+
}
115+
}
116+
}
117+
118+
subscription StoryLikeSubscription($input: StoryLikeSubscribeInput) {
119+
storyLikeSubscribe(input: $input) {
120+
story {
121+
likers {
122+
count
123+
}
124+
likeSentence {
125+
text
126+
}
127+
}
128+
}
129+
}
130+
131+
fragment frag on Friend {
132+
foo(size: $size, bar: $b, obj: {key: "value"})
122133
}
123-
likeSentence {
124-
text
134+
135+
{
136+
unnamed(truthy: true, falsey: false, nullish: null)
137+
query
125138
}
126-
}
127-
}
128-
}
129-
130-
fragment frag on Friend {
131-
foo(size: $size, bar: $b, obj: {key: "value"})
132-
}
133-
134-
{
135-
unnamed(truthy: true, falsey: false, nullish: null)
136-
query
137-
}
138-
`);
139+
`);
139140

140141
});
141142
});

0 commit comments

Comments
 (0)