graphql 2.1.7 → 2.2.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.

Potentially problematic release.


This version of graphql might be problematic. Click here for more details.

@@ -337,14 +337,16 @@ module GraphQL
337
337
  print_string("union ")
338
338
  print_string(union_type.name)
339
339
  print_directives(union_type.directives)
340
- print_string(" = ")
341
- i = 0
342
- union_type.types.each do |t|
343
- if i > 0
344
- print_string(" | ")
340
+ if union_type.types.any?
341
+ print_string(" = ")
342
+ i = 0
343
+ union_type.types.each do |t|
344
+ if i > 0
345
+ print_string(" | ")
346
+ end
347
+ print_string(t.name)
348
+ i += 1
345
349
  end
346
- print_string(t.name)
347
- i += 1
348
350
  end
349
351
  end
350
352
 
@@ -353,12 +355,14 @@ module GraphQL
353
355
  print_string("enum ")
354
356
  print_string(enum_type.name)
355
357
  print_directives(enum_type.directives)
356
- print_string(" {\n")
357
- enum_type.values.each.with_index do |value, i|
358
- print_description(value, indent: " ", first_in_block: i == 0)
359
- print_enum_value_definition(value)
358
+ if enum_type.values.any?
359
+ print_string(" {\n")
360
+ enum_type.values.each.with_index do |value, i|
361
+ print_description(value, indent: " ", first_in_block: i == 0)
362
+ print_enum_value_definition(value)
363
+ end
364
+ print_string("}")
360
365
  end
361
- print_string("}")
362
366
  end
363
367
 
364
368
  def print_enum_value_definition(enum_value)
@@ -221,8 +221,13 @@ module GraphQL
221
221
  #
222
222
  # This will have to be called later, when the runtime object _is_ available.
223
223
  value
224
- else
224
+ elsif obj.respond_to?(@prepare)
225
225
  obj.public_send(@prepare, value)
226
+ elsif owner.respond_to?(@prepare)
227
+ owner.public_send(@prepare, value, context || obj.context)
228
+ else
229
+ raise "Invalid prepare for #{@owner.name}.name: #{@prepare.inspect}. "\
230
+ "Could not find prepare method #{@prepare} on #{obj.class} or #{owner}."
226
231
  end
227
232
  elsif @prepare.respond_to?(:call)
228
233
  @prepare.call(value, context || obj.context)
@@ -384,6 +384,11 @@ module GraphQL
384
384
  (superclass.respond_to?(:get_type) ? superclass.get_type(type_name, context) : nil)
385
385
  end
386
386
 
387
+ # @return [Boolean] Does this schema have _any_ definition for a type named `type_name`, regardless of visibility?
388
+ def has_defined_type?(type_name)
389
+ own_types.key?(type_name) || introspection_system.types.key?(type_name) || (superclass.respond_to?(:has_defined_type?) ? superclass.has_defined_type?(type_name) : false)
390
+ end
391
+
387
392
  # @api private
388
393
  attr_writer :connections
389
394
 
@@ -939,11 +944,7 @@ module GraphQL
939
944
  end
940
945
 
941
946
  def resolve_type(type, obj, ctx)
942
- if type.kind.object?
943
- type
944
- else
945
- raise GraphQL::RequiredImplementationMissingError, "#{self.name}.resolve_type(type, obj, ctx) must be implemented to use Union types or Interface types (tried to resolve: #{type.name})"
946
- end
947
+ raise GraphQL::RequiredImplementationMissingError, "#{self.name}.resolve_type(type, obj, ctx) must be implemented to use Union types, Interface types, or `loads:` (tried to resolve: #{type.name})"
947
948
  end
948
949
  # rubocop:enable Lint/DuplicateMethods
949
950
 
@@ -0,0 +1,125 @@
1
+ # frozen_string_literal: true
2
+ module GraphQL
3
+ module Testing
4
+ module Helpers
5
+ # @param schema_class [Class<GraphQL::Schema>]
6
+ # @return [Module] A helpers module which always uses the given schema
7
+ def self.for(schema_class)
8
+ Module.new do
9
+ include SchemaHelpers
10
+ @@schema_class_for_helpers = schema_class
11
+ end
12
+ end
13
+
14
+ class Error < GraphQL::Error
15
+ end
16
+
17
+ class TypeNotVisibleError < Error
18
+ def initialize(type_name:)
19
+ message = "`#{type_name}` should be `visible?` this field resolution and `context`, but it was not"
20
+ super(message)
21
+ end
22
+ end
23
+
24
+ class FieldNotVisibleError < Error
25
+ def initialize(type_name:, field_name:)
26
+ message = "`#{type_name}.#{field_name}` should be `visible?` for this resolution, but it was not"
27
+ super(message)
28
+ end
29
+ end
30
+
31
+ class TypeNotDefinedError < Error
32
+ def initialize(type_name:)
33
+ message = "No type named `#{type_name}` is defined; choose another type name or define this type."
34
+ super(message)
35
+ end
36
+ end
37
+
38
+ class FieldNotDefinedError < Error
39
+ def initialize(type_name:, field_name:)
40
+ message = "`#{type_name}` has no field named `#{field_name}`; pick another name or define this field."
41
+ super(message)
42
+ end
43
+ end
44
+
45
+ def run_graphql_field(schema, field_path, object, arguments: {}, context: {})
46
+ type_name, *field_names = field_path.split(".")
47
+ dummy_query = GraphQL::Query.new(schema, context: context)
48
+ query_context = dummy_query.context
49
+ object_type = dummy_query.get_type(type_name) # rubocop:disable Development/ContextIsPassedCop
50
+ if object_type
51
+ graphql_result = object
52
+ field_names.each do |field_name|
53
+ inner_object = graphql_result
54
+ graphql_result = object_type.wrap(inner_object, query_context)
55
+ if graphql_result.nil?
56
+ return nil
57
+ end
58
+ visible_field = dummy_query.get_field(object_type, field_name)
59
+ if visible_field
60
+ dummy_query.context.dataloader.run_isolated {
61
+ field_args = visible_field.coerce_arguments(graphql_result, arguments, query_context)
62
+ field_args = schema.sync_lazy(field_args)
63
+ graphql_result = visible_field.resolve(graphql_result, field_args.keyword_arguments, query_context)
64
+ graphql_result = schema.sync_lazy(graphql_result)
65
+ }
66
+ object_type = visible_field.type.unwrap
67
+ elsif object_type.all_field_definitions.any? { |f| f.graphql_name == field_name }
68
+ raise FieldNotVisibleError.new(field_name: field_name, type_name: type_name)
69
+ else
70
+ raise FieldNotDefinedError.new(type_name: type_name, field_name: field_name)
71
+ end
72
+ end
73
+ graphql_result
74
+ elsif schema.has_defined_type?(type_name)
75
+ raise TypeNotVisibleError.new(type_name: type_name)
76
+ else
77
+ raise TypeNotDefinedError.new(type_name: type_name)
78
+ end
79
+ end
80
+
81
+ def with_resolution_context(schema, type:, object:, context:{})
82
+ resolution_context = ResolutionAssertionContext.new(
83
+ self,
84
+ schema: schema,
85
+ type_name: type,
86
+ object: object,
87
+ context: context
88
+ )
89
+ yield(resolution_context)
90
+ end
91
+
92
+ class ResolutionAssertionContext
93
+ def initialize(test, type_name:, object:, schema:, context:)
94
+ @test = test
95
+ @type_name = type_name
96
+ @object = object
97
+ @schema = schema
98
+ @context = context
99
+ end
100
+
101
+
102
+ def run_graphql_field(field_name, arguments: {})
103
+ if @schema
104
+ @test.run_graphql_field(@schema, "#{@type_name}.#{field_name}", @object, arguments: arguments, context: @context)
105
+ else
106
+ @test.run_graphql_field("#{@type_name}.#{field_name}", @object, arguments: arguments, context: @context)
107
+ end
108
+ end
109
+ end
110
+
111
+ module SchemaHelpers
112
+ include Helpers
113
+
114
+ def run_graphql_field(field_path, object, arguments: {}, context: {})
115
+ super(@@schema_class_for_helpers, field_path, object, arguments: arguments, context: context)
116
+ end
117
+
118
+ def with_resolution_context(*args, **kwargs, &block)
119
+ # schema will be added later
120
+ super(nil, *args, **kwargs, &block)
121
+ end
122
+ end
123
+ end
124
+ end
125
+ end
@@ -0,0 +1,2 @@
1
+ # frozen_string_literal: true
2
+ require "graphql/testing/helpers"
@@ -15,6 +15,7 @@ module GraphQL
15
15
  @query = query
16
16
  end
17
17
 
18
+ # The Ruby parser doesn't call this method (`graphql/c_parser` does.)
18
19
  def lex(query_string:)
19
20
  yield
20
21
  end
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module GraphQL
3
- VERSION = "2.1.7"
3
+ VERSION = "2.2.0"
4
4
  end
data/lib/graphql.rb CHANGED
@@ -121,3 +121,4 @@ require "graphql/unauthorized_error"
121
121
  require "graphql/unauthorized_field_error"
122
122
  require "graphql/load_application_object_failed_error"
123
123
  require "graphql/deprecation"
124
+ require "graphql/testing"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: graphql
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.7
4
+ version: 2.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robert Mosolgo
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-12-04 00:00:00.000000000 Z
11
+ date: 2023-12-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: racc
@@ -270,6 +270,7 @@ files:
270
270
  - lib/generators/graphql/templates/base_input_object.erb
271
271
  - lib/generators/graphql/templates/base_interface.erb
272
272
  - lib/generators/graphql/templates/base_object.erb
273
+ - lib/generators/graphql/templates/base_resolver.erb
273
274
  - lib/generators/graphql/templates/base_scalar.erb
274
275
  - lib/generators/graphql/templates/base_union.erb
275
276
  - lib/generators/graphql/templates/enum.erb
@@ -308,6 +309,7 @@ files:
308
309
  - lib/graphql/backtrace/tracer.rb
309
310
  - lib/graphql/coercion_error.rb
310
311
  - lib/graphql/dataloader.rb
312
+ - lib/graphql/dataloader/async_dataloader.rb
311
313
  - lib/graphql/dataloader/null_dataloader.rb
312
314
  - lib/graphql/dataloader/request.rb
313
315
  - lib/graphql/dataloader/request_all.rb
@@ -359,7 +361,6 @@ files:
359
361
  - lib/graphql/language/lexer.rb
360
362
  - lib/graphql/language/nodes.rb
361
363
  - lib/graphql/language/parser.rb
362
- - lib/graphql/language/parser.y
363
364
  - lib/graphql/language/printer.rb
364
365
  - lib/graphql/language/sanitized_printer.rb
365
366
  - lib/graphql/language/static_visitor.rb
@@ -552,6 +553,8 @@ files:
552
553
  - lib/graphql/subscriptions/event.rb
553
554
  - lib/graphql/subscriptions/instrumentation.rb
554
555
  - lib/graphql/subscriptions/serialize.rb
556
+ - lib/graphql/testing.rb
557
+ - lib/graphql/testing/helpers.rb
555
558
  - lib/graphql/tracing.rb
556
559
  - lib/graphql/tracing/active_support_notifications_trace.rb
557
560
  - lib/graphql/tracing/active_support_notifications_tracing.rb