Skip to content

Commit 056875f

Browse files
authored
Merge pull request #5562 from rmosolgo/exec-next-test-cleanup
Exec next: clean up test compat patch
2 parents 8dac701 + 47ba83c commit 056875f

18 files changed

Lines changed: 190 additions & 71 deletions

lib/graphql/execution/batching/field_compatibility.rb

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -49,23 +49,6 @@ def resolve_batch(frs, objects, context, kwargs)
4949
return maybe_err
5050
end
5151
end
52-
if extras.include?(:lookahead)
53-
if kwargs.frozen?
54-
kwargs = kwargs.dup
55-
end
56-
kwargs[:lookahead] = Execution::Lookahead.new(
57-
query: context.query,
58-
ast_nodes: frs.ast_nodes || Array(frs.ast_node),
59-
field: self,
60-
)
61-
end
62-
63-
if extras.include?(:ast_node)
64-
if kwargs.frozen?
65-
kwargs = kwargs.dup
66-
end
67-
kwargs[:ast_node] = frs.ast_node
68-
end
6952

7053
if @owner.method_defined?(@resolver_method)
7154
results = []

lib/graphql/execution/batching/field_resolve_step.rb

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -168,8 +168,9 @@ def self.[](_key)
168168
end
169169

170170
def execute_field
171+
query = @selections_step.query
171172
field_name = @ast_node.name
172-
@field_definition = @selections_step.query.get_field(@parent_type, field_name) || raise("Invariant: no field found for #{@parent_type.to_type_signature}.#{ast_node.name}")
173+
@field_definition = query.get_field(@parent_type, field_name) || raise("Invariant: no field found for #{@parent_type.to_type_signature}.#{ast_node.name}")
173174
objects = @selections_step.objects
174175
if field_name == "__typename"
175176
# TODO handle custom introspection
@@ -179,10 +180,33 @@ def execute_field
179180
return
180181
end
181182

182-
@arguments = coerce_arguments(@field_definition, @ast_node.arguments) # rubocop:disable Development/ContextIsPassedCop
183+
if @field_definition.dynamic_introspection
184+
objects = @selections_step.graphql_objects
185+
end
183186

187+
@arguments = coerce_arguments(@field_definition, @ast_node.arguments) # rubocop:disable Development/ContextIsPassedCop
188+
@field_definition.extras.each do |extra|
189+
case extra
190+
when :lookahead
191+
if @arguments.frozen?
192+
@arguments = @arguments.dup
193+
end
194+
@arguments[:lookahead] = Execution::Lookahead.new(
195+
query: query,
196+
ast_nodes: ast_nodes,
197+
field: @field_definition,
198+
)
199+
when :ast_node
200+
if @arguments.frozen?
201+
@arguments = @arguments.dup
202+
end
203+
@arguments[:ast_node] = ast_node
204+
else
205+
raise ArgumentError, "This extra isn't supported yet: #{extra.inspect}. Open an issue on GraphQL-Ruby to add compatibility for it."
206+
end
207+
end
184208

185-
ctx = @selections_step.query.context
209+
ctx = query.context
186210

187211
if @runner.authorization && @runner.authorizes?(@field_definition, ctx)
188212
authorized_objects = []
@@ -198,12 +222,13 @@ def execute_field
198222
@object_is_authorized = AlwaysAuthorized
199223
end
200224

201-
ctx.query.current_trace.begin_execute_field(@field_definition, @arguments, authorized_objects, ctx.query)
225+
query.current_trace.begin_execute_field(@field_definition, @arguments, authorized_objects, query)
202226
@field_results = @field_definition.resolve_batch(self, authorized_objects, ctx, @arguments)
203-
ctx.query.current_trace.end_execute_field(@field_definition, @arguments, authorized_objects, ctx.query, @field_results)
227+
query.current_trace.end_execute_field(@field_definition, @arguments, authorized_objects, query, @field_results)
204228

205229
if @runner.resolves_lazies # TODO extract this
206230
lazies = false
231+
# TODO add a per-query cache of `.lazy?`
207232
@field_results.each do |field_result|
208233
if @runner.schema.lazy?(field_result)
209234
lazies = true

lib/graphql/introspection/dynamic_fields.rb

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,13 @@
22
module GraphQL
33
module Introspection
44
class DynamicFields < Introspection::BaseObject
5-
field :__typename, String, "The name of this type", null: false, dynamic_introspection: true
5+
field :__typename, String, "The name of this type", null: false, dynamic_introspection: true, resolve_each: true
66

77
def __typename
8+
self.class.__typename(object, context)
9+
end
10+
11+
def self.__typename(object, context)
812
object.class.graphql_name
913
end
1014
end

lib/graphql/introspection/entry_points.rb

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ module GraphQL
33
module Introspection
44
class EntryPoints < Introspection::BaseObject
55
field :__schema, GraphQL::Schema::LateBoundType.new("__Schema"), "This GraphQL schema", null: false, dynamic_introspection: true, resolve_static: :__schema
6-
field :__type, GraphQL::Schema::LateBoundType.new("__Type"), "A type in the GraphQL system", dynamic_introspection: true do
6+
field :__type, GraphQL::Schema::LateBoundType.new("__Type"), "A type in the GraphQL system", dynamic_introspection: true, resolve_static: :__type do
77
argument :name, String
88
end
99

@@ -19,6 +19,10 @@ def __schema
1919
end
2020

2121
def __type(name:)
22+
self.class.__type(context, name: name)
23+
end
24+
25+
def self.__type(context, name:)
2226
if context.types.reachable_type?(name) && (type = context.types.type(name))
2327
type
2428
elsif (type = context.schema.extra_types.find { |t| t.graphql_name == name })

spec/graphql/authorization_spec.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ class BaseInputObject < GraphQL::Schema::InputObject
3232

3333
class BaseField < GraphQL::Schema::Field
3434
argument_class BaseArgument
35+
include(GraphQL::Execution::Batching::FieldCompatibility) if TESTING_BATCHING
36+
3537
def visible?(context)
3638
super && (context[:hide] ? @name != "hidden" : true)
3739
end
@@ -351,6 +353,7 @@ class Schema < GraphQL::Schema
351353
mutation(Mutation)
352354
directive(Nothing)
353355
use GraphQL::Schema::Warden if ADD_WARDEN
356+
use GraphQL::Execution::Batching if TESTING_BATCHING
354357
lazy_resolve(Box, :value)
355358

356359
def self.unauthorized_object(err)

spec/graphql/dataloader/async_dataloader_spec.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ def fiber_local_context(key:)
143143

144144
query(Query)
145145
use GraphQL::Dataloader::AsyncDataloader
146+
use GraphQL::Execution::Batching if TESTING_BATCHING
146147
end
147148

148149
module AsyncDataloaderAssertions

spec/graphql/dataloader_spec.rb

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -137,8 +137,21 @@ def fetch(ids)
137137
end
138138
end
139139

140-
module Ingredient
140+
class BaseField < GraphQL::Schema::Field
141+
include(GraphQL::Execution::Batching::FieldCompatibility) if TESTING_BATCHING
142+
end
143+
144+
class BaseObject < GraphQL::Schema::Object
145+
field_class(BaseField)
146+
end
147+
148+
module BaseInterface
141149
include GraphQL::Schema::Interface
150+
field_class(BaseField)
151+
end
152+
153+
module Ingredient
154+
include BaseInterface
142155
field :name, String, null: false
143156
field :id, ID, null: false
144157

@@ -149,19 +162,19 @@ def name_by_scoped_context
149162
end
150163
end
151164

152-
class Grain < GraphQL::Schema::Object
165+
class Grain < BaseObject
153166
implements Ingredient
154167
end
155168

156-
class LeaveningAgent < GraphQL::Schema::Object
169+
class LeaveningAgent < BaseObject
157170
implements Ingredient
158171
end
159172

160-
class Dairy < GraphQL::Schema::Object
173+
class Dairy < BaseObject
161174
implements Ingredient
162175
end
163176

164-
class Recipe < GraphQL::Schema::Object
177+
class Recipe < BaseObject
165178
def self.authorized?(obj, ctx)
166179
ctx.dataloader.with(AuthorizedSource, ctx[:batched_calls_counter]).load(obj)
167180
end
@@ -188,7 +201,7 @@ def slow_ingredients
188201
end
189202
end
190203

191-
class Cookbook < GraphQL::Schema::Object
204+
class Cookbook < BaseObject
192205
field :featured_recipe, Recipe
193206

194207
def self.all_featured_recipe(objects, context)
@@ -200,7 +213,7 @@ def featured_recipe
200213
end
201214
end
202215

203-
class Query < GraphQL::Schema::Object
216+
class Query < BaseObject
204217
field :recipes, [Recipe], null: false, resolve_static: true
205218

206219
def self.recipes(context)
@@ -456,7 +469,7 @@ def resolve
456469
end
457470
end
458471

459-
class Mutation < GraphQL::Schema::Object
472+
class Mutation < BaseObject
460473
field :mutation_1, mutation: Mutation1
461474
field :mutation_2, mutation: Mutation2
462475
field :mutation_3, mutation: Mutation3
@@ -484,6 +497,7 @@ def self.resolve_type(type, obj, ctx)
484497

485498
orphan_types(Grain, Dairy, Recipe, LeaveningAgent)
486499
use GraphQL::Dataloader
500+
use GraphQL::Execution::Batching if TESTING_BATCHING
487501
lazy_resolve Proc, :call
488502

489503
class FieldTestError < StandardError; end
@@ -579,6 +593,7 @@ class Query < GraphQL::Schema::Object
579593

580594
query(Query)
581595
use GraphQL::Dataloader
596+
use GraphQL::Execution::Batching if TESTING_BATCHING
582597
end
583598

584599
module DataloaderAssertions

spec/graphql/execution/interpreter_spec.rb

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,20 @@ def value
1818
end
1919
end
2020

21-
class Expansion < GraphQL::Schema::Object
21+
class BaseField < GraphQL::Schema::Field
22+
include(GraphQL::Execution::Batching::FieldCompatibility) if TESTING_BATCHING
23+
end
24+
25+
class BaseObject < GraphQL::Schema::Object
26+
field_class(BaseField)
27+
end
28+
29+
module BaseInterface
30+
include GraphQL::Schema::Interface
31+
field_class(BaseField)
32+
end
33+
34+
class Expansion < BaseObject
2235
field :sym, String, null: false
2336
field :lazy_sym, String, null: false
2437
field :name, String, null: false
@@ -46,7 +59,7 @@ def always_cached_value
4659
end
4760
end
4861

49-
class Card < GraphQL::Schema::Object
62+
class Card < BaseObject
5063
field :name, String, null: false
5164
field :colors, "[InterpreterTest::Color]", null: false
5265
field :expansion, Expansion, null: false
@@ -78,7 +91,7 @@ def self.resolve_type(obj, ctx)
7891
end
7992
end
8093

81-
class FieldCounter < GraphQL::Schema::Object
94+
class FieldCounter < BaseObject
8295
implements GraphQL::Types::Relay::Node
8396

8497
field :field_counter, FieldCounter, null: false
@@ -139,7 +152,7 @@ def interpreter_context_for(key)
139152
end
140153
end
141154

142-
class Query < GraphQL::Schema::Object
155+
class Query < BaseObject
143156
# Try a root-level authorized hook that returns a lazy value
144157
def self.authorized?(obj, ctx)
145158
Box.new(value: true)
@@ -218,7 +231,7 @@ def field_counter; FieldCounter.generate_tag(context) ; end
218231
include GraphQL::Types::Relay::HasNodeField
219232
include GraphQL::Types::Relay::HasNodesField
220233

221-
class NestedQueryResult < GraphQL::Schema::Object
234+
class NestedQueryResult < BaseObject
222235
field :result, String
223236
field :current_path, [String]
224237
end
@@ -236,7 +249,7 @@ def nested_query(query:)
236249
end
237250
end
238251

239-
class Counter < GraphQL::Schema::Object
252+
class Counter < BaseObject
240253
field :value, Integer, null: false
241254

242255
def value
@@ -273,7 +286,7 @@ def counter
273286
end
274287
end
275288

276-
class Mutation < GraphQL::Schema::Object
289+
class Mutation < BaseObject
277290
field :increment_counter, Counter, null: false
278291

279292
def increment_counter
@@ -292,6 +305,7 @@ class Schema < GraphQL::Schema
292305
lazy_resolve(Box, :value)
293306
uses_raw_value(true)
294307
use GraphQL::Schema::AlwaysVisible
308+
use(GraphQL::Execution::Batching) if TESTING_BATCHING
295309

296310
def self.object_from_id(id, ctx)
297311
OpenStruct.new(id: id)

0 commit comments

Comments
 (0)