Skip to content

Commit 4c059f6

Browse files
committed
Alternative approach for findSchemaChanges
1 parent 0254e5f commit 4c059f6

File tree

5 files changed

+295
-10
lines changed

5 files changed

+295
-10
lines changed

src/index.ts

+3
Original file line numberDiff line numberDiff line change
@@ -472,8 +472,10 @@ export {
472472
// Compares two GraphQLSchemas and detects breaking changes.
473473
BreakingChangeType,
474474
DangerousChangeType,
475+
SafeChangeType,
475476
findBreakingChanges,
476477
findDangerousChanges,
478+
findSchemaChanges,
477479
} from './utilities/index.js';
478480

479481
export type {
@@ -501,6 +503,7 @@ export type {
501503
IntrospectionDirective,
502504
BuildSchemaOptions,
503505
BreakingChange,
506+
SafeChange,
504507
DangerousChange,
505508
TypedQueryDocumentNode,
506509
} from './utilities/index.js';

src/utilities/__tests__/findBreakingChanges-test.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import {
1616
DangerousChangeType,
1717
findBreakingChanges,
1818
findDangerousChanges,
19-
} from '../findBreakingChanges.js';
19+
} from '../findSchemaChanges.js';
2020

2121
describe('findBreakingChanges', () => {
2222
it('should detect if a type was removed or not', () => {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
import { expect } from 'chai';
2+
import { describe, it } from 'mocha';
3+
4+
import { buildSchema } from '../buildASTSchema.js';
5+
import { findSchemaChanges, SafeChangeType } from '../findSchemaChanges.js';
6+
7+
describe('findSchemaChanges', () => {
8+
it('should detect if a type was added', () => {
9+
const newSchema = buildSchema(`
10+
type Type1
11+
type Type2
12+
`);
13+
14+
const oldSchema = buildSchema(`
15+
type Type1
16+
`);
17+
expect(findSchemaChanges(oldSchema, newSchema)).to.deep.equal([
18+
{
19+
type: SafeChangeType.TYPE_ADDED,
20+
description: 'Type2 was added.',
21+
},
22+
]);
23+
});
24+
25+
it('should detect if a field was added', () => {
26+
const oldSchema = buildSchema(`
27+
type Query {
28+
foo: String
29+
}
30+
`);
31+
32+
const newSchema = buildSchema(`
33+
type Query {
34+
foo: String
35+
bar: String
36+
}
37+
`);
38+
expect(findSchemaChanges(oldSchema, newSchema)).to.deep.equal([
39+
{
40+
type: SafeChangeType.FIELD_ADDED,
41+
description: 'Field Query.bar was added.',
42+
},
43+
]);
44+
});
45+
46+
it('should detect if a default value was added', () => {
47+
const oldSchema = buildSchema(`
48+
type Query {
49+
foo(x: String): String
50+
}
51+
`);
52+
53+
const newSchema = buildSchema(`
54+
type Query {
55+
foo(x: String = "bar"): String
56+
}
57+
`);
58+
expect(findSchemaChanges(oldSchema, newSchema)).to.deep.equal([
59+
{
60+
type: SafeChangeType.ARG_DEFAULT_VALUE_ADDED,
61+
description: 'Query.foo(x:) added a defaultValue "bar".',
62+
},
63+
]);
64+
});
65+
66+
it('should detect if an arg value changes safely', () => {
67+
const oldSchema = buildSchema(`
68+
type Query {
69+
foo(x: String!): String
70+
}
71+
`);
72+
73+
const newSchema = buildSchema(`
74+
type Query {
75+
foo(x: String): String
76+
}
77+
`);
78+
expect(findSchemaChanges(oldSchema, newSchema)).to.deep.equal([
79+
{
80+
type: SafeChangeType.ARG_CHANGED_KIND_SAFE,
81+
description:
82+
'Argument Query.foo(x:) has changed type from String! to String.',
83+
},
84+
]);
85+
});
86+
87+
it('should detect if a directive was added', () => {
88+
const oldSchema = buildSchema(`
89+
type Query {
90+
foo: String
91+
}
92+
`);
93+
94+
const newSchema = buildSchema(`
95+
directive @Foo on FIELD_DEFINITION
96+
97+
type Query {
98+
foo: String
99+
}
100+
`);
101+
expect(findSchemaChanges(oldSchema, newSchema)).to.deep.equal([
102+
{
103+
description: 'Directive @Foo was added.',
104+
type: SafeChangeType.DIRECTIVE_ADDED,
105+
},
106+
]);
107+
});
108+
109+
it('should detect if a directive becomes repeatable', () => {
110+
const oldSchema = buildSchema(`
111+
directive @Foo on FIELD_DEFINITION
112+
113+
type Query {
114+
foo: String
115+
}
116+
`);
117+
118+
const newSchema = buildSchema(`
119+
directive @Foo repeatable on FIELD_DEFINITION
120+
121+
type Query {
122+
foo: String
123+
}
124+
`);
125+
expect(findSchemaChanges(oldSchema, newSchema)).to.deep.equal([
126+
{
127+
description: 'Repeatable flag was added to @Foo.',
128+
type: SafeChangeType.DIRECTIVE_REPEATABLE_ADDED,
129+
},
130+
]);
131+
});
132+
133+
it('should detect if a directive adds locations', () => {
134+
const oldSchema = buildSchema(`
135+
directive @Foo on FIELD_DEFINITION
136+
137+
type Query {
138+
foo: String
139+
}
140+
`);
141+
142+
const newSchema = buildSchema(`
143+
directive @Foo on FIELD_DEFINITION | QUERY
144+
145+
type Query {
146+
foo: String
147+
}
148+
`);
149+
expect(findSchemaChanges(oldSchema, newSchema)).to.deep.equal([
150+
{
151+
description: 'QUERY was added to @Foo.',
152+
type: SafeChangeType.DIRECTIVE_LOCATION_ADDED,
153+
},
154+
]);
155+
});
156+
157+
it('should detect if a directive arg gets added', () => {
158+
const oldSchema = buildSchema(`
159+
directive @Foo on FIELD_DEFINITION
160+
161+
type Query {
162+
foo: String
163+
}
164+
`);
165+
166+
const newSchema = buildSchema(`
167+
directive @Foo(arg1: String) on FIELD_DEFINITION
168+
169+
type Query {
170+
foo: String
171+
}
172+
`);
173+
expect(findSchemaChanges(oldSchema, newSchema)).to.deep.equal([
174+
{
175+
description: 'An optional argument @Foo(arg1:) was added.',
176+
type: SafeChangeType.OPTIONAL_DIRECTIVE_ARG_ADDED,
177+
},
178+
]);
179+
});
180+
});

0 commit comments

Comments
 (0)