Skip to content

Commit

Permalink
Add 'lexographicSortSchema' (#1208)
Browse files Browse the repository at this point in the history
  • Loading branch information
IvanGoncharov authored and leebyron committed Jan 29, 2018
1 parent a722af7 commit 6a1eddf
Show file tree
Hide file tree
Showing 4 changed files with 568 additions and 0 deletions.
2 changes: 2 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,8 @@ export {
// Extends an existing GraphQLSchema from a parsed GraphQL Schema
// language AST.
extendSchema,
// Sort a GraphQLSchema.
lexographicSortSchema,
// Print a GraphQLSchema to GraphQL Schema language.
printSchema,
// Prints the built-in introspection schema in the Schema Language
Expand Down
364 changes: 364 additions & 0 deletions src/utilities/__tests__/lexographicSortSchema-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,364 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

import { describe, it } from 'mocha';
import { expect } from 'chai';
import dedent from '../../jsutils/dedent';
import { printSchema } from '../schemaPrinter';
import { buildSchema } from '../buildASTSchema';
import { lexographicSortSchema } from '../lexographicSortSchema';

function sortSDL(sdl) {
const schema = buildSchema(sdl);
return printSchema(lexographicSortSchema(schema));
}

describe('lexographicSortSchema', () => {
it('sort fields', () => {
const sorted = sortSDL(dedent`
input Bar {
barB: String
barA: String
barC: String
}
interface FooInterface {
fooB: String
fooA: String
fooC: String
}
type FooType implements FooInterface {
fooC: String
fooA: String
fooB: String
}
type Query {
dummy(arg: Bar): FooType
}
`);

expect(sorted).to.equal(dedent`
input Bar {
barA: String
barB: String
barC: String
}
interface FooInterface {
fooA: String
fooB: String
fooC: String
}
type FooType implements FooInterface {
fooA: String
fooB: String
fooC: String
}
type Query {
dummy(arg: Bar): FooType
}
`);
});

it('sort implemented interfaces', () => {
const sorted = sortSDL(dedent`
interface FooA {
dummy: String
}
interface FooB {
dummy: String
}
interface FooC {
dummy: String
}
type Query implements FooB & FooA & FooC {
dummy: String
}
`);

expect(sorted).to.equal(dedent`
interface FooA {
dummy: String
}
interface FooB {
dummy: String
}
interface FooC {
dummy: String
}
type Query implements FooA & FooB & FooC {
dummy: String
}
`);
});

it('sort types in union', () => {
const sorted = sortSDL(dedent`
type FooA {
dummy: String
}
type FooB {
dummy: String
}
type FooC {
dummy: String
}
union FooUnion = FooB | FooA | FooC
type Query {
dummy: FooUnion
}
`);

expect(sorted).to.equal(dedent`
type FooA {
dummy: String
}
type FooB {
dummy: String
}
type FooC {
dummy: String
}
union FooUnion = FooA | FooB | FooC
type Query {
dummy: FooUnion
}
`);
});

it('sort enum values', () => {
const sorted = sortSDL(dedent`
enum Foo {
B
C
A
}
type Query {
dummy: Foo
}
`);

expect(sorted).to.equal(dedent`
enum Foo {
A
B
C
}
type Query {
dummy: Foo
}
`);
});

it('sort field arguments', () => {
const sorted = sortSDL(dedent`
type Query {
dummy(argB: Int, argA: String, argC: Float): ID
}
`);

expect(sorted).to.equal(dedent`
type Query {
dummy(argA: String, argB: Int, argC: Float): ID
}
`);
});

it('sort types', () => {
const sorted = sortSDL(dedent`
type Query {
dummy(arg1: FooF, arg2: FooA, arg3: FooG): FooD
}
type FooC implements FooE {
dummy: String
}
enum FooG {
enumValue
}
scalar FooA
input FooF {
dummy: String
}
union FooD = FooC | FooB
interface FooE {
dummy: String
}
type FooB {
dummy: String
}
`);

expect(sorted).to.equal(dedent`
scalar FooA
type FooB {
dummy: String
}
type FooC implements FooE {
dummy: String
}
union FooD = FooB | FooC
interface FooE {
dummy: String
}
input FooF {
dummy: String
}
enum FooG {
enumValue
}
type Query {
dummy(arg1: FooF, arg2: FooA, arg3: FooG): FooD
}
`);
});

it('sort directive arguments', () => {
const sorted = sortSDL(dedent`
directive @test(argC: Float, argA: String, argB: Int) on FIELD
type Query {
dummy: String
}
`);

expect(sorted).to.equal(dedent`
directive @test(argA: String, argB: Int, argC: Float) on FIELD
type Query {
dummy: String
}
`);
});

it('sort directive locations', () => {
const sorted = sortSDL(dedent`
directive @test(argC: Float, argA: String, argB: Int) on UNION | FIELD | ENUM
type Query {
dummy: String
}
`);

expect(sorted).to.equal(dedent`
directive @test(argA: String, argB: Int, argC: Float) on ENUM | FIELD | UNION
type Query {
dummy: String
}
`);
});

it('sort directives', () => {
const sorted = sortSDL(dedent`
directive @fooC on FIELD
directive @fooB on UNION
directive @fooA on ENUM
type Query {
dummy: String
}
`);

expect(sorted).to.equal(dedent`
directive @fooA on ENUM
directive @fooB on UNION
directive @fooC on FIELD
type Query {
dummy: String
}
`);
});

it('sort recursive types', () => {
const sorted = sortSDL(dedent`
interface FooC {
fooB: FooB
fooA: FooA
fooC: FooC
}
type FooB implements FooC {
fooB: FooB
fooA: FooA
}
type FooA implements FooC {
fooB: FooB
fooA: FooA
}
type Query {
fooC: FooC
fooB: FooB
fooA: FooA
}
`);

expect(sorted).to.equal(dedent`
type FooA implements FooC {
fooA: FooA
fooB: FooB
}
type FooB implements FooC {
fooA: FooA
fooB: FooB
}
interface FooC {
fooA: FooA
fooB: FooB
fooC: FooC
}
type Query {
fooA: FooA
fooB: FooB
fooC: FooC
}
`);
});
});
3 changes: 3 additions & 0 deletions src/utilities/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ export { buildASTSchema, buildSchema, getDescription } from './buildASTSchema';
// Extends an existing GraphQLSchema from a parsed GraphQL Schema language AST.
export { extendSchema } from './extendSchema';

// Sort a GraphQLSchema.
export { lexographicSortSchema } from './lexographicSortSchema';

// Print a GraphQLSchema to GraphQL Schema language.
export {
printSchema,
Expand Down
Loading

0 comments on commit 6a1eddf

Please sign in to comment.