Skip to content

Commit 6a1eddf

Browse files
IvanGoncharovleebyron
authored andcommitted
Add 'lexographicSortSchema' (#1208)
1 parent a722af7 commit 6a1eddf

File tree

4 files changed

+568
-0
lines changed

4 files changed

+568
-0
lines changed

src/index.js

+2
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,8 @@ export {
326326
// Extends an existing GraphQLSchema from a parsed GraphQL Schema
327327
// language AST.
328328
extendSchema,
329+
// Sort a GraphQLSchema.
330+
lexographicSortSchema,
329331
// Print a GraphQLSchema to GraphQL Schema language.
330332
printSchema,
331333
// Prints the built-in introspection schema in the Schema Language
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,364 @@
1+
/**
2+
* Copyright (c) 2015-present, Facebook, Inc.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
import { describe, it } from 'mocha';
9+
import { expect } from 'chai';
10+
import dedent from '../../jsutils/dedent';
11+
import { printSchema } from '../schemaPrinter';
12+
import { buildSchema } from '../buildASTSchema';
13+
import { lexographicSortSchema } from '../lexographicSortSchema';
14+
15+
function sortSDL(sdl) {
16+
const schema = buildSchema(sdl);
17+
return printSchema(lexographicSortSchema(schema));
18+
}
19+
20+
describe('lexographicSortSchema', () => {
21+
it('sort fields', () => {
22+
const sorted = sortSDL(dedent`
23+
input Bar {
24+
barB: String
25+
barA: String
26+
barC: String
27+
}
28+
29+
interface FooInterface {
30+
fooB: String
31+
fooA: String
32+
fooC: String
33+
}
34+
35+
type FooType implements FooInterface {
36+
fooC: String
37+
fooA: String
38+
fooB: String
39+
}
40+
41+
type Query {
42+
dummy(arg: Bar): FooType
43+
}
44+
`);
45+
46+
expect(sorted).to.equal(dedent`
47+
input Bar {
48+
barA: String
49+
barB: String
50+
barC: String
51+
}
52+
53+
interface FooInterface {
54+
fooA: String
55+
fooB: String
56+
fooC: String
57+
}
58+
59+
type FooType implements FooInterface {
60+
fooA: String
61+
fooB: String
62+
fooC: String
63+
}
64+
65+
type Query {
66+
dummy(arg: Bar): FooType
67+
}
68+
`);
69+
});
70+
71+
it('sort implemented interfaces', () => {
72+
const sorted = sortSDL(dedent`
73+
interface FooA {
74+
dummy: String
75+
}
76+
77+
interface FooB {
78+
dummy: String
79+
}
80+
81+
interface FooC {
82+
dummy: String
83+
}
84+
85+
type Query implements FooB & FooA & FooC {
86+
dummy: String
87+
}
88+
`);
89+
90+
expect(sorted).to.equal(dedent`
91+
interface FooA {
92+
dummy: String
93+
}
94+
95+
interface FooB {
96+
dummy: String
97+
}
98+
99+
interface FooC {
100+
dummy: String
101+
}
102+
103+
type Query implements FooA & FooB & FooC {
104+
dummy: String
105+
}
106+
`);
107+
});
108+
109+
it('sort types in union', () => {
110+
const sorted = sortSDL(dedent`
111+
type FooA {
112+
dummy: String
113+
}
114+
115+
type FooB {
116+
dummy: String
117+
}
118+
119+
type FooC {
120+
dummy: String
121+
}
122+
123+
union FooUnion = FooB | FooA | FooC
124+
125+
type Query {
126+
dummy: FooUnion
127+
}
128+
`);
129+
130+
expect(sorted).to.equal(dedent`
131+
type FooA {
132+
dummy: String
133+
}
134+
135+
type FooB {
136+
dummy: String
137+
}
138+
139+
type FooC {
140+
dummy: String
141+
}
142+
143+
union FooUnion = FooA | FooB | FooC
144+
145+
type Query {
146+
dummy: FooUnion
147+
}
148+
`);
149+
});
150+
151+
it('sort enum values', () => {
152+
const sorted = sortSDL(dedent`
153+
enum Foo {
154+
B
155+
C
156+
A
157+
}
158+
159+
type Query {
160+
dummy: Foo
161+
}
162+
`);
163+
164+
expect(sorted).to.equal(dedent`
165+
enum Foo {
166+
A
167+
B
168+
C
169+
}
170+
171+
type Query {
172+
dummy: Foo
173+
}
174+
`);
175+
});
176+
177+
it('sort field arguments', () => {
178+
const sorted = sortSDL(dedent`
179+
type Query {
180+
dummy(argB: Int, argA: String, argC: Float): ID
181+
}
182+
`);
183+
184+
expect(sorted).to.equal(dedent`
185+
type Query {
186+
dummy(argA: String, argB: Int, argC: Float): ID
187+
}
188+
`);
189+
});
190+
191+
it('sort types', () => {
192+
const sorted = sortSDL(dedent`
193+
type Query {
194+
dummy(arg1: FooF, arg2: FooA, arg3: FooG): FooD
195+
}
196+
197+
type FooC implements FooE {
198+
dummy: String
199+
}
200+
201+
enum FooG {
202+
enumValue
203+
}
204+
205+
scalar FooA
206+
207+
input FooF {
208+
dummy: String
209+
}
210+
211+
union FooD = FooC | FooB
212+
213+
interface FooE {
214+
dummy: String
215+
}
216+
217+
type FooB {
218+
dummy: String
219+
}
220+
`);
221+
222+
expect(sorted).to.equal(dedent`
223+
scalar FooA
224+
225+
type FooB {
226+
dummy: String
227+
}
228+
229+
type FooC implements FooE {
230+
dummy: String
231+
}
232+
233+
union FooD = FooB | FooC
234+
235+
interface FooE {
236+
dummy: String
237+
}
238+
239+
input FooF {
240+
dummy: String
241+
}
242+
243+
enum FooG {
244+
enumValue
245+
}
246+
247+
type Query {
248+
dummy(arg1: FooF, arg2: FooA, arg3: FooG): FooD
249+
}
250+
`);
251+
});
252+
253+
it('sort directive arguments', () => {
254+
const sorted = sortSDL(dedent`
255+
directive @test(argC: Float, argA: String, argB: Int) on FIELD
256+
257+
type Query {
258+
dummy: String
259+
}
260+
`);
261+
262+
expect(sorted).to.equal(dedent`
263+
directive @test(argA: String, argB: Int, argC: Float) on FIELD
264+
265+
type Query {
266+
dummy: String
267+
}
268+
`);
269+
});
270+
271+
it('sort directive locations', () => {
272+
const sorted = sortSDL(dedent`
273+
directive @test(argC: Float, argA: String, argB: Int) on UNION | FIELD | ENUM
274+
275+
type Query {
276+
dummy: String
277+
}
278+
`);
279+
280+
expect(sorted).to.equal(dedent`
281+
directive @test(argA: String, argB: Int, argC: Float) on ENUM | FIELD | UNION
282+
283+
type Query {
284+
dummy: String
285+
}
286+
`);
287+
});
288+
289+
it('sort directives', () => {
290+
const sorted = sortSDL(dedent`
291+
directive @fooC on FIELD
292+
293+
directive @fooB on UNION
294+
295+
directive @fooA on ENUM
296+
297+
type Query {
298+
dummy: String
299+
}
300+
`);
301+
302+
expect(sorted).to.equal(dedent`
303+
directive @fooA on ENUM
304+
305+
directive @fooB on UNION
306+
307+
directive @fooC on FIELD
308+
309+
type Query {
310+
dummy: String
311+
}
312+
`);
313+
});
314+
315+
it('sort recursive types', () => {
316+
const sorted = sortSDL(dedent`
317+
interface FooC {
318+
fooB: FooB
319+
fooA: FooA
320+
fooC: FooC
321+
}
322+
323+
type FooB implements FooC {
324+
fooB: FooB
325+
fooA: FooA
326+
}
327+
328+
type FooA implements FooC {
329+
fooB: FooB
330+
fooA: FooA
331+
}
332+
333+
type Query {
334+
fooC: FooC
335+
fooB: FooB
336+
fooA: FooA
337+
}
338+
`);
339+
340+
expect(sorted).to.equal(dedent`
341+
type FooA implements FooC {
342+
fooA: FooA
343+
fooB: FooB
344+
}
345+
346+
type FooB implements FooC {
347+
fooA: FooA
348+
fooB: FooB
349+
}
350+
351+
interface FooC {
352+
fooA: FooA
353+
fooB: FooB
354+
fooC: FooC
355+
}
356+
357+
type Query {
358+
fooA: FooA
359+
fooB: FooB
360+
fooC: FooC
361+
}
362+
`);
363+
});
364+
});

src/utilities/index.js

+3
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ export { buildASTSchema, buildSchema, getDescription } from './buildASTSchema';
5353
// Extends an existing GraphQLSchema from a parsed GraphQL Schema language AST.
5454
export { extendSchema } from './extendSchema';
5555

56+
// Sort a GraphQLSchema.
57+
export { lexographicSortSchema } from './lexographicSortSchema';
58+
5659
// Print a GraphQLSchema to GraphQL Schema language.
5760
export {
5861
printSchema,

0 commit comments

Comments
 (0)