graphql-schema_comparator 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 510c4140ffe9cca7a012282eabc3570cae2bf084
4
- data.tar.gz: 2b1236ab94f83ed213f73afc9dcb941a5ac7e097
3
+ metadata.gz: de7ab5aa8da6dcfe86369cab4a4278f4e243365e
4
+ data.tar.gz: a0cf175638ba9b983a793555514c3c51a91c6725
5
5
  SHA512:
6
- metadata.gz: 2734f4d3159c8b0e0851aacd92e94f016d8aeebdffa4ec33a8473436bb8347dfcf72e8b4c0d821243426f267092efcf2bf1571d83f7f04a3ac598e377da65801
7
- data.tar.gz: b00933509012e0c900b6ced4e40c48a09c4ff06278ba9cd5a6a3109d70f6f5d879737f448171da4c9ce0e4c23e2383c7f6b94bd4bc06a0f7d077c166dc931582
6
+ metadata.gz: cc5dd38fb9f71124dd18323a1ceb8e123994476bee91a134854140e160075a515c0975fb60fc662d918ea7deac6e0b6c48a015da5afb53a14191a22de8514837
7
+ data.tar.gz: c9f9ca7b7672748246ee7519b35e06f36b49ad55fba891699249de86107518fac2f0033afe22e2ae8529b5d4f9b9ba17a31aa701a977ab9a9ae8bcdf9ba2d095
data/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.3.0 (Oct 14 2017)
4
+
5
+ ### New features
6
+
7
+ - Top level Directive definitions are now diffed, but not directives used on definitions (Coming soon)
8
+ - Base class for changes added.
9
+
10
+ ### breaking changes
11
+
12
+ - `breaking` method on change objects has been renamed `breaking?` for style
13
+
14
+ ### Bug fixes
15
+
16
+ - Fix message for `EnumValueRemoved` (#5)
17
+
3
18
  ## 0.2.0 (Aug 18 2017)
4
19
 
5
20
  ### New features
@@ -1,9 +1,21 @@
1
1
  require "graphql"
2
+
2
3
  require "graphql/schema_comparator/version"
3
- require "graphql/schema_comparator/diff/schema"
4
4
  require "graphql/schema_comparator/changes"
5
5
  require "graphql/schema_comparator/result"
6
6
 
7
+ require "graphql/schema_comparator/diff/schema"
8
+ require "graphql/schema_comparator/diff/argument"
9
+ require "graphql/schema_comparator/diff/directive"
10
+ require "graphql/schema_comparator/diff/directive_argument"
11
+ require "graphql/schema_comparator/diff/enum"
12
+ require "graphql/schema_comparator/diff/field"
13
+ require "graphql/schema_comparator/diff/input_object"
14
+ require "graphql/schema_comparator/diff/input_field"
15
+ require "graphql/schema_comparator/diff/object_type"
16
+ require "graphql/schema_comparator/diff/interface"
17
+ require "graphql/schema_comparator/diff/union"
18
+
7
19
  module GraphQL
8
20
  module SchemaComparator
9
21
  def self.compare(old_schema, new_schema)
@@ -1,36 +1,52 @@
1
1
  module GraphQL
2
2
  module SchemaComparator
3
3
  module Changes
4
- # Breaking Changes
4
+ class AbstractChange
5
+ def message
6
+ raise NotImplementedError
7
+ end
8
+
9
+ def breaking?
10
+ raise NotImplementedError
11
+ end
12
+ end
5
13
 
6
- class TypeRemoved
7
- attr_reader :removed_type, :breaking
14
+ class TypeRemoved < AbstractChange
15
+ attr_reader :removed_type
8
16
 
9
17
  def initialize(removed_type)
10
18
  @removed_type = removed_type
11
19
  @breaking = true
12
20
  end
13
21
 
22
+ def breaking?
23
+ !!@breaking
24
+ end
25
+
14
26
  def message
15
- "#{removed_type.name} was removed"
27
+ "`#{removed_type.name}` was removed"
16
28
  end
17
29
  end
18
30
 
19
- class DirectiveRemoved
20
- attr_reader :removed_directive, :breaking
31
+ class DirectiveRemoved < AbstractChange
32
+ attr_reader :directive
21
33
 
22
- def initialize(removed_directive)
23
- @removed_directive = removed_directive
34
+ def initialize(directive)
35
+ @directive = directive
24
36
  @breaking = true
25
37
  end
26
38
 
27
39
  def message
28
- "#{removed_directive.name} was removed"
40
+ "`#{directive.name}` was removed"
41
+ end
42
+
43
+ def breaking?
44
+ !!@breaking
29
45
  end
30
46
  end
31
47
 
32
- class TypeKindChanged
33
- attr_reader :old_type, :new_type, :breaking
48
+ class TypeKindChanged < AbstractChange
49
+ attr_reader :old_type, :new_type
34
50
 
35
51
  def initialize(old_type, new_type)
36
52
  @old_type = old_type
@@ -41,10 +57,14 @@ module GraphQL
41
57
  def message
42
58
  "`#{old_type.name}` kind changed from `#{old_type.kind}` to `#{new_type.kind}`"
43
59
  end
60
+
61
+ def breaking?
62
+ !!@breaking
63
+ end
44
64
  end
45
65
 
46
- class EnumValueRemoved
47
- attr_reader :enum_value, :enum_type, :breaking
66
+ class EnumValueRemoved < AbstractChange
67
+ attr_reader :enum_value, :enum_type
48
68
 
49
69
  def initialize(enum_type, enum_value)
50
70
  @enum_value = enum_value
@@ -55,10 +75,14 @@ module GraphQL
55
75
  def message
56
76
  "Enum value `#{enum_value.name}` was removed from enum `#{enum_type.name}`"
57
77
  end
78
+
79
+ def breaking?
80
+ !!@breaking
81
+ end
58
82
  end
59
83
 
60
- class UnionMemberRemoved
61
- attr_reader :union_type, :union_member, :breaking
84
+ class UnionMemberRemoved < AbstractChange
85
+ attr_reader :union_type, :union_member
62
86
 
63
87
  def initialize(union_type, union_member)
64
88
  @union_member = union_member
@@ -69,10 +93,14 @@ module GraphQL
69
93
  def message
70
94
  "Union member `#{union_member.name}` was removed from Union type `#{union_type.name}`"
71
95
  end
96
+
97
+ def breaking?
98
+ !!@breaking
99
+ end
72
100
  end
73
101
 
74
- class InputFieldRemoved
75
- attr_reader :input_object_type, :field, :breaking
102
+ class InputFieldRemoved < AbstractChange
103
+ attr_reader :input_object_type, :field
76
104
 
77
105
  def initialize(input_object_type, field)
78
106
  @input_object_type = input_object_type
@@ -83,10 +111,14 @@ module GraphQL
83
111
  def message
84
112
  "Input field `#{field.name}` was removed from input object type `#{input_object_type.name}`"
85
113
  end
114
+
115
+ def breaking?
116
+ !!@breaking
117
+ end
86
118
  end
87
119
 
88
- class FieldArgumentRemoved
89
- attr_reader :object_type, :field, :argument, :breaking
120
+ class FieldArgumentRemoved < AbstractChange
121
+ attr_reader :object_type, :field, :argument
90
122
 
91
123
  def initialize(object_type, field, argument)
92
124
  @object_type = object_type
@@ -98,14 +130,32 @@ module GraphQL
98
130
  def message
99
131
  "Argument `#{argument.name}: #{argument.type}` was removed from field `#{object_type.name}.#{field.name}`"
100
132
  end
133
+
134
+ def breaking?
135
+ !!@breaking
136
+ end
101
137
  end
102
138
 
103
- # TODO
104
- # class DirectiveArgumentRemoved
105
- # end
139
+ class DirectiveArgumentRemoved < AbstractChange
140
+ attr_reader :directive, :argument
141
+
142
+ def initialize(directive, argument)
143
+ @directive = directive
144
+ @argument = argument
145
+ @breaking = true
146
+ end
106
147
 
107
- class SchemaQueryTypeChanged
108
- attr_reader :old_schema, :new_schema, :breaking
148
+ def message
149
+ "Argument `#{argument.name}` was removed from directive `#{directive.name}`"
150
+ end
151
+
152
+ def breaking?
153
+ !!@breaking
154
+ end
155
+ end
156
+
157
+ class SchemaQueryTypeChanged < AbstractChange
158
+ attr_reader :old_schema, :new_schema
109
159
 
110
160
  def initialize(old_schema, new_schema)
111
161
  @old_schema = old_schema
@@ -116,10 +166,14 @@ module GraphQL
116
166
  def message
117
167
  "Schema query root has changed from `#{old_schema.query.name}` to `#{new_schema.query.name}`"
118
168
  end
169
+
170
+ def breaking?
171
+ !!@breaking
172
+ end
119
173
  end
120
174
 
121
- class FieldRemoved
122
- attr_reader :object_type, :field, :breaking
175
+ class FieldRemoved < AbstractChange
176
+ attr_reader :object_type, :field
123
177
 
124
178
  def initialize(object_type, field)
125
179
  @object_type = object_type
@@ -130,14 +184,32 @@ module GraphQL
130
184
  def message
131
185
  "Field `#{field.name}` was removed from object type `#{object_type.name}`"
132
186
  end
187
+
188
+ def breaking?
189
+ !!@breaking
190
+ end
133
191
  end
134
192
 
135
- # TODO
136
- # class DirectiveLocationRemoved
137
- # end
193
+ class DirectiveLocationRemoved < AbstractChange
194
+ attr_reader :directive, :location
195
+
196
+ def initialize(directive, location)
197
+ @directive = directive
198
+ @location = location
199
+ @breaking = true
200
+ end
201
+
202
+ def message
203
+ "Location `#{location}` was removed from directive `#{directive.name}`"
204
+ end
205
+
206
+ def breaking?
207
+ !!@breaking
208
+ end
209
+ end
138
210
 
139
- class ObjectTypeInterfaceRemoved
140
- attr_reader :interface, :object_type, :breaking
211
+ class ObjectTypeInterfaceRemoved < AbstractChange
212
+ attr_reader :interface, :object_type
141
213
 
142
214
  def initialize(interface, object_type)
143
215
  @interface = interface
@@ -148,12 +220,14 @@ module GraphQL
148
220
  def message
149
221
  "`#{object_type.name}` object type no longer implements `#{interface.name}` interface"
150
222
  end
151
- end
152
223
 
153
- # Non-Breaking Changes
224
+ def breaking?
225
+ !!@breaking
226
+ end
227
+ end
154
228
 
155
- class TypeAdded
156
- attr_reader :type, :breaking
229
+ class TypeAdded < AbstractChange
230
+ attr_reader :type
157
231
 
158
232
  def initialize(type)
159
233
  @type = type
@@ -163,18 +237,31 @@ module GraphQL
163
237
  def message
164
238
  "Type `#{type.name}` was added"
165
239
  end
240
+
241
+ def breaking?
242
+ !!@breaking
243
+ end
166
244
  end
167
245
 
168
- class DirectiveAdded
169
- attr_reader :breaking
246
+ class DirectiveAdded < AbstractChange
247
+ attr_reader :directive
170
248
 
171
- def initialize(*)
249
+ def initialize(directive)
250
+ @directive = directive
172
251
  @breaking = false
173
252
  end
253
+
254
+ def message
255
+ "Directive `#{directive.name}` was added"
256
+ end
257
+
258
+ def breaking?
259
+ !!@breaking
260
+ end
174
261
  end
175
262
 
176
- class TypeDescriptionChanged
177
- attr_reader :old_type, :new_type, :breaking
263
+ class TypeDescriptionChanged < AbstractChange
264
+ attr_reader :old_type, :new_type
178
265
 
179
266
  def initialize(old_type, new_type)
180
267
  @old_type = old_type
@@ -185,10 +272,14 @@ module GraphQL
185
272
  def message
186
273
  "Description `#{old_type.description}` on type `#{old_type.name}` has changed to `#{new_type.description}`"
187
274
  end
275
+
276
+ def breaking?
277
+ !!@breaking
278
+ end
188
279
  end
189
280
 
190
- class EnumValueAdded
191
- attr_reader :enum_type, :enum_value, :breaking
281
+ class EnumValueAdded < AbstractChange
282
+ attr_reader :enum_type, :enum_value
192
283
 
193
284
  def initialize(enum_type, enum_value)
194
285
  @enum_type = enum_type
@@ -199,20 +290,26 @@ module GraphQL
199
290
  def message
200
291
  "Enum value `#{enum_value.name}` was added to enum `#{enum_type.name}`"
201
292
  end
293
+
294
+ def breaking?
295
+ !!@breaking
296
+ end
202
297
  end
203
298
 
204
- class EnumValueDescriptionChanged
299
+ # TODO
300
+ class EnumValueDescriptionChanged < AbstractChange
205
301
  def initialize(*)
206
302
  end
207
303
  end
208
304
 
209
- class EnumValueDeprecated
305
+ # TODO
306
+ class EnumValueDeprecated < AbstractChange
210
307
  def initialize(*)
211
308
  end
212
309
  end
213
310
 
214
- class UnionMemberAdded
215
- attr_reader :union_type, :union_member, :breaking
311
+ class UnionMemberAdded < AbstractChange
312
+ attr_reader :union_type, :union_member
216
313
 
217
314
  def initialize(union_type, union_member)
218
315
  @union_member = union_member
@@ -223,10 +320,14 @@ module GraphQL
223
320
  def message
224
321
  "Union member `#{union_member.name}` was added to Union type `#{union_type.name}`"
225
322
  end
323
+
324
+ def breaking?
325
+ !!@breaking
326
+ end
226
327
  end
227
328
 
228
- class InputFieldDescriptionChanged
229
- attr_reader :input_type, :old_field, :new_field, :breaking
329
+ class InputFieldDescriptionChanged < AbstractChange
330
+ attr_reader :input_type, :old_field, :new_field
230
331
 
231
332
  def initialize(input_type, old_field, new_field)
232
333
  @input_type = input_type
@@ -239,15 +340,33 @@ module GraphQL
239
340
  "Input field `#{input_type.name}.#{old_field.name}` description changed"\
240
341
  " from `#{old_field.description}` to `#{new_field.description}`"
241
342
  end
343
+
344
+ def breaking?
345
+ !!@breaking
346
+ end
242
347
  end
243
348
 
244
- class DirectiveDescriptionChanged
245
- def initialize(*)
349
+ class DirectiveDescriptionChanged < AbstractChange
350
+ attr_reader :old_directive, :new_directive
351
+
352
+ def initialize(old_directive, new_directive)
353
+ @old_directive = old_directive
354
+ @new_directive = new_directive
355
+ @breaking = false
356
+ end
357
+
358
+ def message
359
+ "Directive `#{new_directive.name}` description changed"\
360
+ " from `#{old_directive.description}` to `#{new_directive.description}`"
361
+ end
362
+
363
+ def breaking?
364
+ !!@breaking
246
365
  end
247
366
  end
248
367
 
249
- class FieldDescriptionChanged
250
- attr_reader :type, :old_field, :new_field, :breaking
368
+ class FieldDescriptionChanged < AbstractChange
369
+ attr_reader :type, :old_field, :new_field
251
370
 
252
371
  def initialize(type, old_field, new_field)
253
372
  @type = type
@@ -260,10 +379,14 @@ module GraphQL
260
379
  "Field `#{type.name}.#{old_field.name}` description changed"\
261
380
  " from `#{old_field.description}` to `#{new_field.description}`"
262
381
  end
382
+
383
+ def breaking?
384
+ !!@breaking
385
+ end
263
386
  end
264
387
 
265
- class FieldArgumentDescriptionChanged
266
- attr_reader :type, :field, :old_argument, :new_argument, :breaking
388
+ class FieldArgumentDescriptionChanged < AbstractChange
389
+ attr_reader :type, :field, :old_argument, :new_argument
267
390
 
268
391
  def initialize(type, field, old_argument, new_argument)
269
392
  @type = type
@@ -277,15 +400,34 @@ module GraphQL
277
400
  "Description for argument `#{new_argument.name}` on field `#{type.name}.#{field.name}` changed"\
278
401
  " from `#{old_argument.description}` to `#{new_argument.description}`"
279
402
  end
403
+
404
+ def breaking?
405
+ !!@breaking
406
+ end
280
407
  end
281
408
 
282
- class DirectiveArgumentDescriptionChanged
283
- def initialize(*)
409
+ class DirectiveArgumentDescriptionChanged < AbstractChange
410
+ attr_reader :directive, :old_argument, :new_argument
411
+
412
+ def initialize(directive, old_argument, new_argument)
413
+ @directive = directive
414
+ @old_argument = old_argument
415
+ @new_argument = new_argument
416
+ @breaking = false
417
+ end
418
+
419
+ def message
420
+ "Description for argument `#{new_argument.name}` on directive `#{directive.name}` changed"\
421
+ " from `#{old_argument.description}` to `#{new_argument.description}`"
422
+ end
423
+
424
+ def breaking?
425
+ !!@breaking
284
426
  end
285
427
  end
286
428
 
287
- class FieldDeprecationChanged
288
- attr_reader :type, :old_field, :new_field, :breaking
429
+ class FieldDeprecationChanged < AbstractChange
430
+ attr_reader :type, :old_field, :new_field
289
431
 
290
432
  def initialize(type, old_field, new_field)
291
433
  @type = type
@@ -298,10 +440,14 @@ module GraphQL
298
440
  "Deprecation reason on field `#{type.name}.#{new_field.name}` has changed "\
299
441
  "from `#{old_field.deprecation_reason}` to `#{new_field.deprecation_reason}`"
300
442
  end
443
+
444
+ def breaking?
445
+ !!@breaking
446
+ end
301
447
  end
302
448
 
303
- class InputFieldDefaultChanged
304
- attr_reader :input_type, :old_field, :new_field, :breaking
449
+ class InputFieldDefaultChanged < AbstractChange
450
+ attr_reader :input_type, :old_field, :new_field
305
451
 
306
452
  def initialize(input_type, old_field, new_field)
307
453
  @input_type = input_type
@@ -314,10 +460,14 @@ module GraphQL
314
460
  "Input field `#{input_type.name}.#{old_field.name}` default changed"\
315
461
  " from `#{old_field.default_value}` to `#{new_field.default_value}`"
316
462
  end
463
+
464
+ def breaking?
465
+ !!@breaking
466
+ end
317
467
  end
318
468
 
319
- class FieldArgumentDefaultChanged
320
- attr_reader :type, :field, :old_argument, :new_argument, :breaking
469
+ class FieldArgumentDefaultChanged < AbstractChange
470
+ attr_reader :type, :field, :old_argument, :new_argument
321
471
 
322
472
  def initialize(type, field, old_argument, new_argument)
323
473
  @type = type
@@ -331,15 +481,34 @@ module GraphQL
331
481
  "Default value for argument `#{new_argument.name}` on field `#{type.name}.#{field.name}` changed"\
332
482
  " from `#{old_argument.default_value}` to `#{new_argument.default_value}`"
333
483
  end
484
+
485
+ def breaking?
486
+ !!@breaking
487
+ end
334
488
  end
335
489
 
336
- class DirectiveArgumentDefaultChanged
337
- def initialize(*)
490
+ class DirectiveArgumentDefaultChanged < AbstractChange
491
+ attr_reader :directive, :old_argument, :new_argument
492
+
493
+ def initialize(directive, old_argument, new_argument)
494
+ @directive = directive
495
+ @old_argument = old_argument
496
+ @new_argument = new_argument
497
+ @breaking = false
498
+ end
499
+
500
+ def message
501
+ "Default value for argument `#{new_argument.name}` on directive `#{directive.name}` changed"\
502
+ " from `#{old_argument.default_value}` to `#{new_argument.default_value}`"
503
+ end
504
+
505
+ def breaking?
506
+ !!@breaking
338
507
  end
339
508
  end
340
509
 
341
- class ObjectTypeInterfaceAdded
342
- attr_reader :interface, :object_type, :breaking
510
+ class ObjectTypeInterfaceAdded < AbstractChange
511
+ attr_reader :interface, :object_type
343
512
 
344
513
  def initialize(interface, object_type)
345
514
  @interface = interface
@@ -350,10 +519,14 @@ module GraphQL
350
519
  def message
351
520
  "`#{object_type.name}` object implements `#{interface.name}` interface"
352
521
  end
522
+
523
+ def breaking?
524
+ !!@breaking
525
+ end
353
526
  end
354
527
 
355
- class FieldAdded
356
- attr_reader :object_type, :field, :breaking
528
+ class FieldAdded < AbstractChange
529
+ attr_reader :object_type, :field
357
530
 
358
531
  def initialize(object_type, field)
359
532
  @object_type = object_type
@@ -364,137 +537,176 @@ module GraphQL
364
537
  def message
365
538
  "Field `#{field.name}` was added to object type `#{object_type.name}`"
366
539
  end
540
+
541
+ def breaking?
542
+ !!@breaking
543
+ end
367
544
  end
368
545
 
369
- class DirectiveLocationAdded
370
- def initialize(*)
546
+ class DirectiveLocationAdded < AbstractChange
547
+ attr_reader :directive, :location
548
+
549
+ def initialize(directive, location)
550
+ @directive = directive
551
+ @location = location
552
+ @breaking = false
553
+ end
554
+
555
+ def message
556
+ "Location `#{location}` was added to directive `#{directive.name}`"
557
+ end
558
+
559
+ def breaking?
560
+ !!@breaking
371
561
  end
372
562
  end
373
563
 
374
- class FieldAstDirectiveAdded
564
+ # TODO
565
+ class FieldAstDirectiveAdded < AbstractChange
375
566
  def initialize(*)
376
567
  end
377
568
  end
378
569
 
379
- class FieldAstDirectiveRemoved
570
+ # TODO
571
+ class FieldAstDirectiveRemoved < AbstractChange
380
572
  def initialize(*)
381
573
  end
382
574
  end
383
575
 
384
- class EnumValueAstDirectiveAdded
576
+ # TODO
577
+ class EnumValueAstDirectiveAdded < AbstractChange
385
578
  def initialize(*)
386
579
  end
387
580
  end
388
581
 
389
- class EnumValueAstDirectiveRemoved
582
+ # TODO
583
+ class EnumValueAstDirectiveRemoved < AbstractChange
390
584
  def initialize(*)
391
585
  end
392
586
  end
393
587
 
394
- class InputFieldAstDirectiveAdded
588
+ # TODO
589
+ class InputFieldAstDirectiveAdded < AbstractChange
395
590
  def initialize(*)
396
591
  end
397
592
  end
398
593
 
399
- class InputFieldAstDirectiveRemoved
594
+ # TODO
595
+ class InputFieldAstDirectiveRemoved < AbstractChange
400
596
  def initialize(*)
401
597
  end
402
598
  end
403
599
 
404
- class DirectiveArgumentAstDirectiveAdded
600
+ # TODO
601
+ class DirectiveArgumentAstDirectiveAdded < AbstractChange
405
602
  def initialize(*)
406
603
  end
407
604
  end
408
605
 
409
- class DirectiveArgumentAstDirectiveRemoved
606
+ # TODO
607
+ class DirectiveArgumentAstDirectiveRemoved < AbstractChange
410
608
  def initialize(*)
411
609
  end
412
610
  end
413
611
 
414
- class FieldArgumentAstDirectiveAdded
612
+ # TODO
613
+ class FieldArgumentAstDirectiveAdded < AbstractChange
415
614
  def initialize(*)
416
615
  end
417
616
  end
418
617
 
419
- class FieldArgumentAstDirectiveRemoved
618
+ # TODO
619
+ class FieldArgumentAstDirectiveRemoved < AbstractChange
420
620
  def initialize(*)
421
621
  end
422
622
  end
423
623
 
424
- class ObjectTypeAstDirectiveAdded
624
+ # TODO
625
+ class ObjectTypeAstDirectiveAdded < AbstractChange
425
626
  def initialize(*)
426
627
  end
427
628
  end
428
629
 
429
- class ObjectTypeAstDirectiveRemoved
630
+ # TODO
631
+ class ObjectTypeAstDirectiveRemoved < AbstractChange
430
632
  def initialize(*)
431
633
  end
432
634
  end
433
635
 
434
- class InterfaceTypeAstDirectiveAdded
636
+ # TODO
637
+ class InterfaceTypeAstDirectiveAdded < AbstractChange
435
638
  def initialize(*)
436
639
  end
437
640
  end
438
641
 
439
- class InterfaceTypeAstDirectiveRemoved
642
+ # TODO
643
+ class InterfaceTypeAstDirectiveRemoved < AbstractChange
440
644
  def initialize(*)
441
645
  end
442
646
  end
443
647
 
444
- class UnionTypeAstDirectiveAdded
648
+ # TODO
649
+ class UnionTypeAstDirectiveAdded < AbstractChange
445
650
  def initialize(*)
446
651
  end
447
652
  end
448
653
 
449
- class UnionTypeAstDirectiveRemoved
654
+ # TODO
655
+ class UnionTypeAstDirectiveRemoved < AbstractChange
450
656
  def initialize(*)
451
657
  end
452
658
  end
453
659
 
454
- class EnumTypeAstDirectiveAdded
660
+ # TODO
661
+ class EnumTypeAstDirectiveAdded < AbstractChange
455
662
  def initialize(*)
456
663
  end
457
664
  end
458
665
 
459
- class EnumTypeAstDirectiveRemoved
666
+ # TODO
667
+ class EnumTypeAstDirectiveRemoved < AbstractChange
460
668
  def initialize(*)
461
669
  end
462
670
  end
463
671
 
464
- class ScalarTypeAstDirectiveAdded
672
+ # TODO
673
+ class ScalarTypeAstDirectiveAdded < AbstractChange
465
674
  def initialize(*)
466
675
  end
467
676
  end
468
677
 
469
- class ScalarTypeAstDirectiveRemoved
678
+ # TODO
679
+ class ScalarTypeAstDirectiveRemoved < AbstractChange
470
680
  def initialize(*)
471
681
  end
472
682
  end
473
683
 
474
- class InputObjectTypeAstDirectiveAdded
684
+ # TODO
685
+ class InputObjectTypeAstDirectiveAdded < AbstractChange
475
686
  def initialize(*)
476
687
  end
477
688
  end
478
689
 
479
- class InputObjectTypeAstDirectiveRemoved
690
+ # TODO
691
+ class InputObjectTypeAstDirectiveRemoved < AbstractChange
480
692
  def initialize(*)
481
693
  end
482
694
  end
483
695
 
484
- class SchemaAstDirectiveAdded
696
+ # TODO
697
+ class SchemaAstDirectiveAdded < AbstractChange
485
698
  def initialize(*)
486
699
  end
487
700
  end
488
701
 
489
- class SchemaAstDirectiveRemoved
702
+ # TODO
703
+ class SchemaAstDirectiveRemoved < AbstractChange
490
704
  def initialize(*)
491
705
  end
492
706
  end
493
707
 
494
- # Maybe Breaking
495
-
496
- class InputFieldAdded
497
- attr_reader :input_object_type, :field, :breaking
708
+ class InputFieldAdded < AbstractChange
709
+ attr_reader :input_object_type, :field
498
710
 
499
711
  def initialize(input_object_type, field)
500
712
  @input_object_type = input_object_type
@@ -505,10 +717,14 @@ module GraphQL
505
717
  def message
506
718
  "Input field `#{field.name}` was added to input object type `#{input_object_type.name}`"
507
719
  end
720
+
721
+ def breaking?
722
+ !!@breaking
723
+ end
508
724
  end
509
725
 
510
- class FieldArgumentAdded
511
- attr_reader :type, :field, :argument, :breaking
726
+ class FieldArgumentAdded < AbstractChange
727
+ attr_reader :type, :field, :argument
512
728
 
513
729
  def initialize(type, field, argument)
514
730
  @type = type
@@ -521,15 +737,32 @@ module GraphQL
521
737
  def message
522
738
  "Argument `#{argument.name}: #{argument.type}` added to field `#{type.name}.#{field.name}`"
523
739
  end
740
+
741
+ def breaking?
742
+ !!@breaking
743
+ end
524
744
  end
525
745
 
526
- class DirectiveArgumentAdded
527
- def initialize(*)
746
+ class DirectiveArgumentAdded < AbstractChange
747
+ attr_reader :directive, :argument
748
+
749
+ def initialize(directive, argument)
750
+ @directive = directive
751
+ @argument = argument
752
+ @breaking = false
753
+ end
754
+
755
+ def message
756
+ "Argument `#{argument.name}` was added to directive `#{directive.name}`"
757
+ end
758
+
759
+ def breaking?
760
+ !!@breaking
528
761
  end
529
762
  end
530
763
 
531
- class InputFieldTypeChanged
532
- attr_reader :input_type, :old_input_field, :new_input_field, :breaking
764
+ class InputFieldTypeChanged < AbstractChange
765
+ attr_reader :input_type, :old_input_field, :new_input_field
533
766
 
534
767
  def initialize(input_type, old_input_field, new_input_field)
535
768
  @input_type = input_type
@@ -541,10 +774,14 @@ module GraphQL
541
774
  def message
542
775
  "Input field `#{input_type}.#{old_input_field.name}` changed type from #{old_input_field.type} to #{new_input_field.type}"
543
776
  end
777
+
778
+ def breaking?
779
+ !!@breaking
780
+ end
544
781
  end
545
782
 
546
- class FieldArgumentTypeChanged
547
- attr_reader :type, :field, :old_argument, :new_argument, :breaking
783
+ class FieldArgumentTypeChanged < AbstractChange
784
+ attr_reader :type, :field, :old_argument, :new_argument
548
785
 
549
786
  def initialize(type, field, old_argument, new_argument)
550
787
  @type = type
@@ -558,15 +795,34 @@ module GraphQL
558
795
  "Type for argument `#{new_argument.name}` on field `#{type.name}.#{field.name}` changed"\
559
796
  " from `#{old_argument.type}` to `#{new_argument.type}`"
560
797
  end
798
+
799
+ def breaking?
800
+ !!@breaking
801
+ end
561
802
  end
562
803
 
563
- class DirectiveArgumentTypeChanged
564
- def initialize(*)
804
+ class DirectiveArgumentTypeChanged < AbstractChange
805
+ attr_reader :directive, :old_argument, :new_argument
806
+
807
+ def initialize(directive, old_argument, new_argument)
808
+ @directive = directive
809
+ @old_argument = old_argument
810
+ @new_argument = new_argument
811
+ @breaking = false
812
+ end
813
+
814
+ def message
815
+ "Type for argument `#{new_argument.name}` on directive `#{directive.name}` changed"\
816
+ " from `#{old_argument.type}` to `#{new_argument.type}`"
817
+ end
818
+
819
+ def breaking?
820
+ !!@breaking
565
821
  end
566
822
  end
567
823
 
568
- class FieldTypeChanged
569
- attr_reader :type, :old_field, :new_field, :breaking
824
+ class FieldTypeChanged < AbstractChange
825
+ attr_reader :type, :old_field, :new_field
570
826
 
571
827
  def initialize(type, old_field, new_field)
572
828
  @type = type
@@ -578,10 +834,14 @@ module GraphQL
578
834
  def message
579
835
  "Field `#{type}.#{old_field.name}` changed type from `#{old_field.type}` to `#{new_field.type}`"
580
836
  end
837
+
838
+ def breaking?
839
+ !!@breaking
840
+ end
581
841
  end
582
842
 
583
- class SchemaMutationTypeChanged
584
- attr_reader :old_schema, :new_schema, :breaking
843
+ class SchemaMutationTypeChanged < AbstractChange
844
+ attr_reader :old_schema, :new_schema
585
845
 
586
846
  def initialize(old_schema, new_schema)
587
847
  @old_schema = old_schema
@@ -592,9 +852,13 @@ module GraphQL
592
852
  def message
593
853
  "Schema mutation root has changed from `#{old_schema.mutation}` to `#{new_schema.mutation}`"
594
854
  end
855
+
856
+ def breaking?
857
+ !!@breaking
858
+ end
595
859
  end
596
860
 
597
- class SchemaSubscriptionTypeChanged
861
+ class SchemaSubscriptionTypeChanged < AbstractChange
598
862
  def initialize(old_schema, new_schema)
599
863
  @old_schema = old_schema
600
864
  @new_schema = new_schema
@@ -604,6 +868,10 @@ module GraphQL
604
868
  def message
605
869
  "Schema subscription type has changed from `#{old_schema.subscription}` to `#{new_schema.subscription}`"
606
870
  end
871
+
872
+ def breaking?
873
+ !!@breaking
874
+ end
607
875
  end
608
876
  end
609
877
  end
@@ -0,0 +1,63 @@
1
+ module GraphQL
2
+ module SchemaComparator
3
+ module Diff
4
+ class Directive
5
+ def initialize(old_directive, new_directive)
6
+ @old_directive = old_directive
7
+ @new_directive = new_directive
8
+ @old_arguments = old_directive.arguments
9
+ @new_arguments = new_directive.arguments
10
+ end
11
+
12
+ def diff
13
+ changes = []
14
+
15
+ if old_directive.description != new_directive.description
16
+ changes << Changes::DirectiveDescriptionChanged.new(old_directive, new_directive)
17
+ end
18
+
19
+ changes += removed_locations.map { |location| Changes::DirectiveLocationRemoved.new(new_directive, location) }
20
+ changes += added_locations.map { |location| Changes::DirectiveLocationAdded.new(new_directive, location) }
21
+ changes += added_arguments.map { |argument| Changes::DirectiveArgumentAdded.new(new_directive, argument) }
22
+ changes += removed_arguments.map { |argument| Changes::DirectiveArgumentRemoved.new(new_directive, argument) }
23
+
24
+ each_common_argument do |old_argument, new_argument|
25
+ changes += Diff::DirectiveArgument.new(new_directive, old_argument, new_argument).diff
26
+ end
27
+
28
+ changes
29
+ end
30
+
31
+ private
32
+
33
+ def removed_locations
34
+ (old_directive.locations - new_directive.locations)
35
+ end
36
+
37
+ def added_locations
38
+ (new_directive.locations - old_directive.locations)
39
+ end
40
+
41
+ def removed_arguments
42
+ old_arguments.values.select { |arg| !new_arguments[arg.name] }
43
+ end
44
+
45
+ def added_arguments
46
+ new_arguments.values.select { |arg| !old_arguments[arg.name] }
47
+ end
48
+
49
+ def each_common_argument(&block)
50
+ intersection = old_arguments.keys & new_arguments.keys
51
+ intersection.each do |common_arg|
52
+ old_arg = new_directive.arguments[common_arg]
53
+ new_arg = old_directive.arguments[common_arg]
54
+
55
+ block.call(old_arg, new_arg)
56
+ end
57
+ end
58
+
59
+ attr_reader(:old_directive, :new_directive, :old_arguments, :new_arguments)
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,37 @@
1
+ module GraphQL
2
+ module SchemaComparator
3
+ module Diff
4
+ class DirectiveArgument
5
+ def initialize(directive, old_arg, new_arg)
6
+ @directive = directive
7
+ @old_arg = old_arg
8
+ @new_arg = new_arg
9
+ end
10
+
11
+ def diff
12
+ changes = []
13
+
14
+ if old_arg.description != new_arg.description
15
+ changes << Changes::DirectiveArgumentDescriptionChanged.new(directive, old_arg, new_arg)
16
+ end
17
+
18
+ if old_arg.default_value != new_arg.default_value
19
+ changes << Changes::DirectiveArgumentDefaultChanged.new(directive, old_arg, new_arg)
20
+ end
21
+
22
+ if old_arg.type != new_arg.type
23
+ changes << Changes::DirectiveArgumentTypeChanged.new(directive, old_arg, new_arg)
24
+ end
25
+
26
+ # TODO directives on directive arguments
27
+
28
+ changes
29
+ end
30
+
31
+ private
32
+
33
+ attr_reader(:directive, :new_arg, :old_arg)
34
+ end
35
+ end
36
+ end
37
+ end
@@ -36,8 +36,6 @@ module GraphQL
36
36
  changes += Diff::Argument.new(new_type, new_field, old_arg, new_arg).diff
37
37
  end
38
38
 
39
- # TODO: directives
40
-
41
39
  changes
42
40
  end
43
41
 
@@ -1,12 +1,3 @@
1
- require "graphql/schema_comparator/diff/enum"
2
- require "graphql/schema_comparator/diff/union"
3
- require "graphql/schema_comparator/diff/input_object"
4
- require "graphql/schema_comparator/diff/input_field"
5
- require "graphql/schema_comparator/diff/object_type"
6
- require "graphql/schema_comparator/diff/interface"
7
- require "graphql/schema_comparator/diff/field"
8
- require "graphql/schema_comparator/diff/argument"
9
-
10
1
  module GraphQL
11
2
  module SchemaComparator
12
3
  module Diff
@@ -17,6 +8,9 @@ module GraphQL
17
8
 
18
9
  @old_types = old_schema.types
19
10
  @new_types = new_schema.types
11
+
12
+ @old_directives = old_schema.directives
13
+ @new_directives = new_schema.directives
20
14
  end
21
15
 
22
16
  def diff
@@ -86,8 +80,16 @@ module GraphQL
86
80
  end
87
81
 
88
82
  def changes_in_directives
89
- # TODO
90
- []
83
+ changes = []
84
+
85
+ changes += removed_directives.map { |directive| Changes::DirectiveRemoved.new(directive) }
86
+ changes += added_directives.map { |directive| Changes::DirectiveAdded.new(directive) }
87
+
88
+ each_common_directive do |old_directive, new_directive|
89
+ changes += Diff::Directive.new(old_directive, new_directive).diff
90
+ end
91
+
92
+ changes
91
93
  end
92
94
 
93
95
  private
@@ -110,7 +112,25 @@ module GraphQL
110
112
  (new_types.keys - old_types.keys).map { |type_name| new_schema.types[type_name] }
111
113
  end
112
114
 
113
- attr_reader :old_schema, :new_schema, :old_types, :new_types
115
+ def removed_directives
116
+ (old_directives.keys - new_directives.keys).map { |directive_name| old_schema.directives[directive_name] }
117
+ end
118
+
119
+ def added_directives
120
+ (new_directives.keys - old_directives.keys).map { |directive_name| new_schema.directives[directive_name] }
121
+ end
122
+
123
+ def each_common_directive(&block)
124
+ intersection = old_directives.keys & new_directives.keys
125
+ intersection.each do |common_directive_name|
126
+ old_directive = old_schema.directives[common_directive_name]
127
+ new_directive = new_schema.directives[common_directive_name]
128
+
129
+ block.call(old_directive, new_directive)
130
+ end
131
+ end
132
+
133
+ attr_reader :old_schema, :new_schema, :old_types, :new_types, :old_directives, :new_directives
114
134
  end
115
135
  end
116
136
  end
@@ -4,8 +4,8 @@ module GraphQL
4
4
  attr_reader :changes, :breaking_changes, :non_breaking_changes
5
5
 
6
6
  def initialize(changes)
7
- @changes = changes.sort_by { |c| [c.breaking ? 1 : 2, c.message] }
8
- @breaking_changes, @non_breaking_changes = @changes.partition(&:breaking)
7
+ @changes = changes.sort_by { |c| [c.breaking? ? 1 : 2, c.message] }
8
+ @breaking_changes, @non_breaking_changes = @changes.partition(&:breaking?)
9
9
  end
10
10
 
11
11
  def identical?
@@ -1,5 +1,5 @@
1
1
  module GraphQL
2
2
  module SchemaComparator
3
- VERSION = "0.2.0"
3
+ VERSION = "0.3.0"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: graphql-schema_comparator
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Marc-Andre Giroux
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-08-18 00:00:00.000000000 Z
11
+ date: 2017-10-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: graphql
@@ -118,8 +118,11 @@ files:
118
118
  - lib/graphql/schema_comparator.rb
119
119
  - lib/graphql/schema_comparator/changes.rb
120
120
  - lib/graphql/schema_comparator/diff/argument.rb
121
+ - lib/graphql/schema_comparator/diff/directive.rb
122
+ - lib/graphql/schema_comparator/diff/directive_argument.rb
121
123
  - lib/graphql/schema_comparator/diff/enum.rb
122
124
  - lib/graphql/schema_comparator/diff/field.rb
125
+ - lib/graphql/schema_comparator/diff/has_directives.rb
123
126
  - lib/graphql/schema_comparator/diff/input_field.rb
124
127
  - lib/graphql/schema_comparator/diff/input_object.rb
125
128
  - lib/graphql/schema_comparator/diff/interface.rb
@@ -149,7 +152,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
149
152
  version: '0'
150
153
  requirements: []
151
154
  rubyforge_project:
152
- rubygems_version: 2.6.10
155
+ rubygems_version: 2.6.13
153
156
  signing_key:
154
157
  specification_version: 4
155
158
  summary: Compare GraphQL schemas and get the changes that happened.