zenspec 0.1.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 +7 -0
- data/CHANGELOG.md +5 -0
- data/CODE_OF_CONDUCT.md +132 -0
- data/LICENSE.txt +21 -0
- data/README.md +637 -0
- data/Rakefile +12 -0
- data/examples/progress_loader_demo.rb +113 -0
- data/lib/zenspec/formatters/progress_bar_formatter.rb +433 -0
- data/lib/zenspec/formatters/progress_formatter.rb +146 -0
- data/lib/zenspec/helpers/graphql_helpers.rb +103 -0
- data/lib/zenspec/helpers.rb +10 -0
- data/lib/zenspec/matchers/graphql_matchers.rb +358 -0
- data/lib/zenspec/matchers/graphql_type_matchers.rb +554 -0
- data/lib/zenspec/matchers/interactor_matchers.rb +216 -0
- data/lib/zenspec/matchers.rb +12 -0
- data/lib/zenspec/progress_loader.rb +155 -0
- data/lib/zenspec/railtie.rb +26 -0
- data/lib/zenspec/shoulda_config.rb +17 -0
- data/lib/zenspec/version.rb +5 -0
- data/lib/zenspec.rb +14 -0
- data/sig/zenspec.rbs +4 -0
- metadata +121 -0
|
@@ -0,0 +1,554 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "rspec/expectations"
|
|
4
|
+
|
|
5
|
+
module Zenspec
|
|
6
|
+
module Matchers
|
|
7
|
+
module GraphQLTypeMatchers
|
|
8
|
+
# Matcher for checking if a GraphQL type has a specific field with type and arguments
|
|
9
|
+
#
|
|
10
|
+
# @example
|
|
11
|
+
# expect(UserType).to have_field(:id).of_type("ID!")
|
|
12
|
+
# expect(UserType).to have_field(:name).of_type("String!")
|
|
13
|
+
# expect(UserType).to have_field(:posts).of_type("[Post!]!")
|
|
14
|
+
# expect(UserType).to have_field(:posts).with_argument(:limit, "Int")
|
|
15
|
+
#
|
|
16
|
+
RSpec::Matchers.define :have_field do |field_name|
|
|
17
|
+
match do |type|
|
|
18
|
+
@field_name = field_name.to_s
|
|
19
|
+
@type = type
|
|
20
|
+
|
|
21
|
+
# Get the field from the type
|
|
22
|
+
@field = get_field(type, @field_name)
|
|
23
|
+
return false unless @field
|
|
24
|
+
|
|
25
|
+
# Check field type if specified
|
|
26
|
+
if @expected_type
|
|
27
|
+
actual_type = field_type_string(@field)
|
|
28
|
+
return false unless actual_type == @expected_type
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Check arguments if specified
|
|
32
|
+
if @expected_arguments && @expected_arguments.any?
|
|
33
|
+
@expected_arguments.all? do |arg_name, arg_type|
|
|
34
|
+
check_argument(arg_name, arg_type)
|
|
35
|
+
end
|
|
36
|
+
else
|
|
37
|
+
true
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
chain :of_type do |expected_type|
|
|
42
|
+
@expected_type = expected_type
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
chain :with_argument do |arg_name, arg_type|
|
|
46
|
+
@expected_arguments ||= {}
|
|
47
|
+
@expected_arguments[arg_name.to_s] = arg_type
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
failure_message do
|
|
51
|
+
if !@field
|
|
52
|
+
"expected #{type_name(@type)} to have field #{@field_name.inspect}, but it does not"
|
|
53
|
+
elsif @expected_type && field_type_string(@field) != @expected_type
|
|
54
|
+
"expected field #{@field_name.inspect} to have type #{@expected_type.inspect}, " \
|
|
55
|
+
"got #{field_type_string(@field).inspect}"
|
|
56
|
+
elsif @expected_arguments
|
|
57
|
+
missing_or_wrong = find_mismatched_arguments
|
|
58
|
+
"expected field #{@field_name.inspect} to have arguments #{@expected_arguments.inspect}, " \
|
|
59
|
+
"but #{missing_or_wrong.inspect} did not match"
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
private
|
|
64
|
+
|
|
65
|
+
def get_field(type, field_name)
|
|
66
|
+
if type.respond_to?(:fields)
|
|
67
|
+
type.fields[field_name]
|
|
68
|
+
elsif type.respond_to?(:get_field)
|
|
69
|
+
type.get_field(field_name)
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def field_type_string(field)
|
|
74
|
+
return nil unless field
|
|
75
|
+
|
|
76
|
+
type = field.type
|
|
77
|
+
type_to_string(type)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def type_to_string(type)
|
|
81
|
+
case type
|
|
82
|
+
when GraphQL::Schema::NonNull
|
|
83
|
+
"#{type_to_string(type.of_type)}!"
|
|
84
|
+
when GraphQL::Schema::List
|
|
85
|
+
"[#{type_to_string(type.of_type)}]"
|
|
86
|
+
when GraphQL::Schema::Member
|
|
87
|
+
type.graphql_name
|
|
88
|
+
else
|
|
89
|
+
# Handle wrapped types from graphql-ruby
|
|
90
|
+
if type.respond_to?(:unwrap)
|
|
91
|
+
unwrapped = type.unwrap
|
|
92
|
+
base_name = unwrapped.respond_to?(:graphql_name) ? unwrapped.graphql_name : unwrapped.to_s
|
|
93
|
+
|
|
94
|
+
# Build the type string with wrappers
|
|
95
|
+
result = base_name
|
|
96
|
+
result = "[#{result}]" if list?(type)
|
|
97
|
+
result = "#{result}!" if non_null?(type)
|
|
98
|
+
result
|
|
99
|
+
elsif type.respond_to?(:graphql_name)
|
|
100
|
+
type.graphql_name
|
|
101
|
+
else
|
|
102
|
+
type.to_s
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def list?(type)
|
|
108
|
+
type.is_a?(GraphQL::Schema::List) ||
|
|
109
|
+
(type.respond_to?(:list?) && type.list?)
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def non_null?(type)
|
|
113
|
+
type.is_a?(GraphQL::Schema::NonNull) ||
|
|
114
|
+
(type.respond_to?(:non_null?) && type.non_null?)
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def check_argument(arg_name, expected_type)
|
|
118
|
+
return false unless @field.respond_to?(:arguments)
|
|
119
|
+
|
|
120
|
+
arg = @field.arguments[arg_name]
|
|
121
|
+
return false unless arg
|
|
122
|
+
|
|
123
|
+
if expected_type
|
|
124
|
+
actual_type = type_to_string(arg.type)
|
|
125
|
+
actual_type == expected_type
|
|
126
|
+
else
|
|
127
|
+
true
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
def find_mismatched_arguments
|
|
132
|
+
return {} unless @expected_arguments
|
|
133
|
+
|
|
134
|
+
@expected_arguments.select do |arg_name, expected_type|
|
|
135
|
+
!check_argument(arg_name, expected_type)
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def type_name(type)
|
|
140
|
+
if type.respond_to?(:graphql_name)
|
|
141
|
+
type.graphql_name
|
|
142
|
+
elsif type.respond_to?(:name)
|
|
143
|
+
type.name
|
|
144
|
+
else
|
|
145
|
+
type.to_s
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
# Matcher for checking if an enum has specific values
|
|
151
|
+
#
|
|
152
|
+
# @example
|
|
153
|
+
# expect(StatusEnum).to have_enum_values("ACTIVE", "INACTIVE", "PENDING")
|
|
154
|
+
#
|
|
155
|
+
RSpec::Matchers.define :have_enum_values do |*expected_values|
|
|
156
|
+
match do |enum_type|
|
|
157
|
+
@enum_type = enum_type
|
|
158
|
+
@expected_values = expected_values.map(&:to_s)
|
|
159
|
+
|
|
160
|
+
actual_values = get_enum_values(enum_type)
|
|
161
|
+
@actual_values = actual_values
|
|
162
|
+
|
|
163
|
+
@expected_values.all? { |value| actual_values.include?(value) }
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
failure_message do
|
|
167
|
+
missing_values = @expected_values - @actual_values
|
|
168
|
+
"expected #{enum_name(@enum_type)} to have values #{@expected_values.inspect}, " \
|
|
169
|
+
"but #{missing_values.inspect} were missing. " \
|
|
170
|
+
"Actual values: #{@actual_values.inspect}"
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
private
|
|
174
|
+
|
|
175
|
+
def get_enum_values(enum_type)
|
|
176
|
+
if enum_type.respond_to?(:values)
|
|
177
|
+
# GraphQL::EnumType or GraphQL::Schema::Enum
|
|
178
|
+
if enum_type.values.is_a?(Hash)
|
|
179
|
+
enum_type.values.keys.map(&:to_s)
|
|
180
|
+
elsif enum_type.values.is_a?(Array)
|
|
181
|
+
enum_type.values.map { |v| v.respond_to?(:graphql_name) ? v.graphql_name : v.to_s }
|
|
182
|
+
else
|
|
183
|
+
[]
|
|
184
|
+
end
|
|
185
|
+
else
|
|
186
|
+
[]
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
def enum_name(enum_type)
|
|
191
|
+
if enum_type.respond_to?(:graphql_name)
|
|
192
|
+
enum_type.graphql_name
|
|
193
|
+
elsif enum_type.respond_to?(:name)
|
|
194
|
+
enum_type.name
|
|
195
|
+
else
|
|
196
|
+
enum_type.to_s
|
|
197
|
+
end
|
|
198
|
+
end
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
# Matcher for checking if a field has a specific argument with type
|
|
202
|
+
#
|
|
203
|
+
# @example
|
|
204
|
+
# expect(UserType.fields["posts"]).to have_argument(:limit).of_type("Int")
|
|
205
|
+
# expect(UserType.fields["posts"]).to have_argument(:status).of_type("Status!")
|
|
206
|
+
# expect(QueryType.fields["users"]).to have_argument(:filter).of_type("UserFilterInput")
|
|
207
|
+
#
|
|
208
|
+
RSpec::Matchers.define :have_argument do |arg_name|
|
|
209
|
+
match do |field|
|
|
210
|
+
@field = field
|
|
211
|
+
@arg_name = arg_name.to_s
|
|
212
|
+
|
|
213
|
+
# Get the argument
|
|
214
|
+
@argument = get_argument(field, @arg_name)
|
|
215
|
+
return false unless @argument
|
|
216
|
+
|
|
217
|
+
# Check argument type if specified
|
|
218
|
+
if @expected_type
|
|
219
|
+
actual_type = argument_type_string(@argument)
|
|
220
|
+
return false unless actual_type == @expected_type
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
true
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
chain :of_type do |expected_type|
|
|
227
|
+
@expected_type = expected_type
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
failure_message do
|
|
231
|
+
if !@argument
|
|
232
|
+
field_name = @field.respond_to?(:name) ? @field.name : @field.to_s
|
|
233
|
+
"expected field #{field_name.inspect} to have argument #{@arg_name.inspect}, but it does not"
|
|
234
|
+
elsif @expected_type && argument_type_string(@argument) != @expected_type
|
|
235
|
+
"expected argument #{@arg_name.inspect} to have type #{@expected_type.inspect}, " \
|
|
236
|
+
"got #{argument_type_string(@argument).inspect}"
|
|
237
|
+
end
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
private
|
|
241
|
+
|
|
242
|
+
def get_argument(field, arg_name)
|
|
243
|
+
return nil unless field.respond_to?(:arguments)
|
|
244
|
+
|
|
245
|
+
field.arguments[arg_name]
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
def argument_type_string(argument)
|
|
249
|
+
return nil unless argument
|
|
250
|
+
|
|
251
|
+
type = argument.type
|
|
252
|
+
type_to_string(type)
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
def type_to_string(type)
|
|
256
|
+
case type
|
|
257
|
+
when GraphQL::Schema::NonNull
|
|
258
|
+
"#{type_to_string(type.of_type)}!"
|
|
259
|
+
when GraphQL::Schema::List
|
|
260
|
+
"[#{type_to_string(type.of_type)}]"
|
|
261
|
+
when GraphQL::Schema::Member
|
|
262
|
+
type.graphql_name
|
|
263
|
+
else
|
|
264
|
+
# Handle wrapped types from graphql-ruby
|
|
265
|
+
if type.respond_to?(:unwrap)
|
|
266
|
+
unwrapped = type.unwrap
|
|
267
|
+
base_name = unwrapped.respond_to?(:graphql_name) ? unwrapped.graphql_name : unwrapped.to_s
|
|
268
|
+
|
|
269
|
+
# Build the type string with wrappers
|
|
270
|
+
result = base_name
|
|
271
|
+
result = "[#{result}]" if list?(type)
|
|
272
|
+
result = "#{result}!" if non_null?(type)
|
|
273
|
+
result
|
|
274
|
+
elsif type.respond_to?(:graphql_name)
|
|
275
|
+
type.graphql_name
|
|
276
|
+
else
|
|
277
|
+
type.to_s
|
|
278
|
+
end
|
|
279
|
+
end
|
|
280
|
+
end
|
|
281
|
+
|
|
282
|
+
def list?(type)
|
|
283
|
+
type.is_a?(GraphQL::Schema::List) ||
|
|
284
|
+
(type.respond_to?(:list?) && type.list?)
|
|
285
|
+
end
|
|
286
|
+
|
|
287
|
+
def non_null?(type)
|
|
288
|
+
type.is_a?(GraphQL::Schema::NonNull) ||
|
|
289
|
+
(type.respond_to?(:non_null?) && type.non_null?)
|
|
290
|
+
end
|
|
291
|
+
end
|
|
292
|
+
|
|
293
|
+
# Matcher for checking if a schema has a specific query field
|
|
294
|
+
#
|
|
295
|
+
# @example
|
|
296
|
+
# expect(schema).to have_query(:user).with_argument(:id, "ID!")
|
|
297
|
+
# expect(schema).to have_query(:users).of_type("[User!]!")
|
|
298
|
+
#
|
|
299
|
+
RSpec::Matchers.define :have_query do |query_name|
|
|
300
|
+
match do |schema|
|
|
301
|
+
@schema = schema
|
|
302
|
+
@query_name = query_name.to_s
|
|
303
|
+
|
|
304
|
+
# Get the query type
|
|
305
|
+
query_type = get_query_type(schema)
|
|
306
|
+
return false unless query_type
|
|
307
|
+
|
|
308
|
+
# Get the field
|
|
309
|
+
@field = get_field(query_type, @query_name)
|
|
310
|
+
return false unless @field
|
|
311
|
+
|
|
312
|
+
# Check field type if specified
|
|
313
|
+
if @expected_type
|
|
314
|
+
actual_type = field_type_string(@field)
|
|
315
|
+
return false unless actual_type == @expected_type
|
|
316
|
+
end
|
|
317
|
+
|
|
318
|
+
# Check arguments if specified
|
|
319
|
+
if @expected_arguments && @expected_arguments.any?
|
|
320
|
+
@expected_arguments.all? do |arg_name, arg_type|
|
|
321
|
+
check_argument(arg_name, arg_type)
|
|
322
|
+
end
|
|
323
|
+
else
|
|
324
|
+
true
|
|
325
|
+
end
|
|
326
|
+
end
|
|
327
|
+
|
|
328
|
+
chain :of_type do |expected_type|
|
|
329
|
+
@expected_type = expected_type
|
|
330
|
+
end
|
|
331
|
+
|
|
332
|
+
chain :with_argument do |arg_name, arg_type|
|
|
333
|
+
@expected_arguments ||= {}
|
|
334
|
+
@expected_arguments[arg_name.to_s] = arg_type
|
|
335
|
+
end
|
|
336
|
+
|
|
337
|
+
failure_message do
|
|
338
|
+
if !get_query_type(@schema)
|
|
339
|
+
"expected schema to have a query type, but it does not"
|
|
340
|
+
elsif !@field
|
|
341
|
+
"expected schema query to have field #{@query_name.inspect}, but it does not"
|
|
342
|
+
elsif @expected_type && field_type_string(@field) != @expected_type
|
|
343
|
+
"expected query field #{@query_name.inspect} to have type #{@expected_type.inspect}, " \
|
|
344
|
+
"got #{field_type_string(@field).inspect}"
|
|
345
|
+
elsif @expected_arguments
|
|
346
|
+
"expected query field #{@query_name.inspect} to have arguments #{@expected_arguments.inspect}"
|
|
347
|
+
end
|
|
348
|
+
end
|
|
349
|
+
|
|
350
|
+
private
|
|
351
|
+
|
|
352
|
+
def get_query_type(schema)
|
|
353
|
+
schema.respond_to?(:query) ? schema.query : nil
|
|
354
|
+
end
|
|
355
|
+
|
|
356
|
+
def get_field(type, field_name)
|
|
357
|
+
if type.respond_to?(:fields)
|
|
358
|
+
type.fields[field_name]
|
|
359
|
+
elsif type.respond_to?(:get_field)
|
|
360
|
+
type.get_field(field_name)
|
|
361
|
+
end
|
|
362
|
+
end
|
|
363
|
+
|
|
364
|
+
def field_type_string(field)
|
|
365
|
+
return nil unless field
|
|
366
|
+
|
|
367
|
+
type = field.type
|
|
368
|
+
type_to_string(type)
|
|
369
|
+
end
|
|
370
|
+
|
|
371
|
+
def type_to_string(type)
|
|
372
|
+
case type
|
|
373
|
+
when GraphQL::Schema::NonNull
|
|
374
|
+
"#{type_to_string(type.of_type)}!"
|
|
375
|
+
when GraphQL::Schema::List
|
|
376
|
+
"[#{type_to_string(type.of_type)}]"
|
|
377
|
+
when GraphQL::Schema::Member
|
|
378
|
+
type.graphql_name
|
|
379
|
+
else
|
|
380
|
+
if type.respond_to?(:unwrap)
|
|
381
|
+
unwrapped = type.unwrap
|
|
382
|
+
base_name = unwrapped.respond_to?(:graphql_name) ? unwrapped.graphql_name : unwrapped.to_s
|
|
383
|
+
|
|
384
|
+
result = base_name
|
|
385
|
+
result = "[#{result}]" if list?(type)
|
|
386
|
+
result = "#{result}!" if non_null?(type)
|
|
387
|
+
result
|
|
388
|
+
elsif type.respond_to?(:graphql_name)
|
|
389
|
+
type.graphql_name
|
|
390
|
+
else
|
|
391
|
+
type.to_s
|
|
392
|
+
end
|
|
393
|
+
end
|
|
394
|
+
end
|
|
395
|
+
|
|
396
|
+
def list?(type)
|
|
397
|
+
type.is_a?(GraphQL::Schema::List) ||
|
|
398
|
+
(type.respond_to?(:list?) && type.list?)
|
|
399
|
+
end
|
|
400
|
+
|
|
401
|
+
def non_null?(type)
|
|
402
|
+
type.is_a?(GraphQL::Schema::NonNull) ||
|
|
403
|
+
(type.respond_to?(:non_null?) && type.non_null?)
|
|
404
|
+
end
|
|
405
|
+
|
|
406
|
+
def check_argument(arg_name, expected_type)
|
|
407
|
+
return false unless @field.respond_to?(:arguments)
|
|
408
|
+
|
|
409
|
+
arg = @field.arguments[arg_name]
|
|
410
|
+
return false unless arg
|
|
411
|
+
|
|
412
|
+
if expected_type
|
|
413
|
+
actual_type = type_to_string(arg.type)
|
|
414
|
+
actual_type == expected_type
|
|
415
|
+
else
|
|
416
|
+
true
|
|
417
|
+
end
|
|
418
|
+
end
|
|
419
|
+
end
|
|
420
|
+
|
|
421
|
+
# Matcher for checking if a schema has a specific mutation field
|
|
422
|
+
#
|
|
423
|
+
# @example
|
|
424
|
+
# expect(schema).to have_mutation(:createUser).with_argument(:input, "CreateUserInput!")
|
|
425
|
+
# expect(schema).to have_mutation(:deleteUser).of_type("DeleteUserPayload!")
|
|
426
|
+
#
|
|
427
|
+
RSpec::Matchers.define :have_mutation do |mutation_name|
|
|
428
|
+
match do |schema|
|
|
429
|
+
@schema = schema
|
|
430
|
+
@mutation_name = mutation_name.to_s
|
|
431
|
+
|
|
432
|
+
# Get the mutation type
|
|
433
|
+
mutation_type = get_mutation_type(schema)
|
|
434
|
+
return false unless mutation_type
|
|
435
|
+
|
|
436
|
+
# Get the field
|
|
437
|
+
@field = get_field(mutation_type, @mutation_name)
|
|
438
|
+
return false unless @field
|
|
439
|
+
|
|
440
|
+
# Check field type if specified
|
|
441
|
+
if @expected_type
|
|
442
|
+
actual_type = field_type_string(@field)
|
|
443
|
+
return false unless actual_type == @expected_type
|
|
444
|
+
end
|
|
445
|
+
|
|
446
|
+
# Check arguments if specified
|
|
447
|
+
if @expected_arguments && @expected_arguments.any?
|
|
448
|
+
@expected_arguments.all? do |arg_name, arg_type|
|
|
449
|
+
check_argument(arg_name, arg_type)
|
|
450
|
+
end
|
|
451
|
+
else
|
|
452
|
+
true
|
|
453
|
+
end
|
|
454
|
+
end
|
|
455
|
+
|
|
456
|
+
chain :of_type do |expected_type|
|
|
457
|
+
@expected_type = expected_type
|
|
458
|
+
end
|
|
459
|
+
|
|
460
|
+
chain :with_argument do |arg_name, arg_type|
|
|
461
|
+
@expected_arguments ||= {}
|
|
462
|
+
@expected_arguments[arg_name.to_s] = arg_type
|
|
463
|
+
end
|
|
464
|
+
|
|
465
|
+
failure_message do
|
|
466
|
+
if !get_mutation_type(@schema)
|
|
467
|
+
"expected schema to have a mutation type, but it does not"
|
|
468
|
+
elsif !@field
|
|
469
|
+
"expected schema mutation to have field #{@mutation_name.inspect}, but it does not"
|
|
470
|
+
elsif @expected_type && field_type_string(@field) != @expected_type
|
|
471
|
+
"expected mutation field #{@mutation_name.inspect} to have type #{@expected_type.inspect}, " \
|
|
472
|
+
"got #{field_type_string(@field).inspect}"
|
|
473
|
+
elsif @expected_arguments
|
|
474
|
+
"expected mutation field #{@mutation_name.inspect} to have arguments #{@expected_arguments.inspect}"
|
|
475
|
+
end
|
|
476
|
+
end
|
|
477
|
+
|
|
478
|
+
private
|
|
479
|
+
|
|
480
|
+
def get_mutation_type(schema)
|
|
481
|
+
schema.respond_to?(:mutation) ? schema.mutation : nil
|
|
482
|
+
end
|
|
483
|
+
|
|
484
|
+
def get_field(type, field_name)
|
|
485
|
+
if type.respond_to?(:fields)
|
|
486
|
+
type.fields[field_name]
|
|
487
|
+
elsif type.respond_to?(:get_field)
|
|
488
|
+
type.get_field(field_name)
|
|
489
|
+
end
|
|
490
|
+
end
|
|
491
|
+
|
|
492
|
+
def field_type_string(field)
|
|
493
|
+
return nil unless field
|
|
494
|
+
|
|
495
|
+
type = field.type
|
|
496
|
+
type_to_string(type)
|
|
497
|
+
end
|
|
498
|
+
|
|
499
|
+
def type_to_string(type)
|
|
500
|
+
case type
|
|
501
|
+
when GraphQL::Schema::NonNull
|
|
502
|
+
"#{type_to_string(type.of_type)}!"
|
|
503
|
+
when GraphQL::Schema::List
|
|
504
|
+
"[#{type_to_string(type.of_type)}]"
|
|
505
|
+
when GraphQL::Schema::Member
|
|
506
|
+
type.graphql_name
|
|
507
|
+
else
|
|
508
|
+
if type.respond_to?(:unwrap)
|
|
509
|
+
unwrapped = type.unwrap
|
|
510
|
+
base_name = unwrapped.respond_to?(:graphql_name) ? unwrapped.graphql_name : unwrapped.to_s
|
|
511
|
+
|
|
512
|
+
result = base_name
|
|
513
|
+
result = "[#{result}]" if list?(type)
|
|
514
|
+
result = "#{result}!" if non_null?(type)
|
|
515
|
+
result
|
|
516
|
+
elsif type.respond_to?(:graphql_name)
|
|
517
|
+
type.graphql_name
|
|
518
|
+
else
|
|
519
|
+
type.to_s
|
|
520
|
+
end
|
|
521
|
+
end
|
|
522
|
+
end
|
|
523
|
+
|
|
524
|
+
def list?(type)
|
|
525
|
+
type.is_a?(GraphQL::Schema::List) ||
|
|
526
|
+
(type.respond_to?(:list?) && type.list?)
|
|
527
|
+
end
|
|
528
|
+
|
|
529
|
+
def non_null?(type)
|
|
530
|
+
type.is_a?(GraphQL::Schema::NonNull) ||
|
|
531
|
+
(type.respond_to?(:non_null?) && type.non_null?)
|
|
532
|
+
end
|
|
533
|
+
|
|
534
|
+
def check_argument(arg_name, expected_type)
|
|
535
|
+
return false unless @field.respond_to?(:arguments)
|
|
536
|
+
|
|
537
|
+
arg = @field.arguments[arg_name]
|
|
538
|
+
return false unless arg
|
|
539
|
+
|
|
540
|
+
if expected_type
|
|
541
|
+
actual_type = type_to_string(arg.type)
|
|
542
|
+
actual_type == expected_type
|
|
543
|
+
else
|
|
544
|
+
true
|
|
545
|
+
end
|
|
546
|
+
end
|
|
547
|
+
end
|
|
548
|
+
end
|
|
549
|
+
end
|
|
550
|
+
end
|
|
551
|
+
|
|
552
|
+
RSpec.configure do |config|
|
|
553
|
+
config.include Zenspec::Matchers::GraphQLTypeMatchers
|
|
554
|
+
end
|