graphql-schema_comparator 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
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.