graphql 1.5.15 → 1.6.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.
Files changed (76) hide show
  1. checksums.yaml +4 -4
  2. data/lib/graphql.rb +4 -19
  3. data/lib/graphql/analysis/analyze_query.rb +27 -2
  4. data/lib/graphql/analysis/query_complexity.rb +10 -11
  5. data/lib/graphql/argument.rb +7 -6
  6. data/lib/graphql/backwards_compatibility.rb +47 -0
  7. data/lib/graphql/compatibility/execution_specification.rb +14 -0
  8. data/lib/graphql/compatibility/execution_specification/specification_schema.rb +6 -1
  9. data/lib/graphql/compatibility/lazy_execution_specification.rb +19 -0
  10. data/lib/graphql/compatibility/lazy_execution_specification/lazy_schema.rb +15 -6
  11. data/lib/graphql/directive.rb +1 -6
  12. data/lib/graphql/execution.rb +1 -0
  13. data/lib/graphql/execution/execute.rb +174 -160
  14. data/lib/graphql/execution/field_result.rb +5 -1
  15. data/lib/graphql/execution/lazy.rb +2 -2
  16. data/lib/graphql/execution/lazy/resolve.rb +8 -11
  17. data/lib/graphql/execution/multiplex.rb +134 -0
  18. data/lib/graphql/execution/selection_result.rb +5 -0
  19. data/lib/graphql/field.rb +1 -8
  20. data/lib/graphql/filter.rb +53 -0
  21. data/lib/graphql/internal_representation/node.rb +11 -6
  22. data/lib/graphql/internal_representation/rewrite.rb +3 -3
  23. data/lib/graphql/query.rb +160 -78
  24. data/lib/graphql/query/arguments.rb +14 -25
  25. data/lib/graphql/query/arguments_cache.rb +6 -13
  26. data/lib/graphql/query/context.rb +28 -10
  27. data/lib/graphql/query/executor.rb +1 -0
  28. data/lib/graphql/query/literal_input.rb +10 -4
  29. data/lib/graphql/query/null_context.rb +1 -1
  30. data/lib/graphql/query/serial_execution/field_resolution.rb +5 -1
  31. data/lib/graphql/query/validation_pipeline.rb +12 -7
  32. data/lib/graphql/query/variables.rb +1 -1
  33. data/lib/graphql/rake_task.rb +140 -0
  34. data/lib/graphql/relay/array_connection.rb +29 -48
  35. data/lib/graphql/relay/base_connection.rb +9 -7
  36. data/lib/graphql/relay/mutation.rb +0 -11
  37. data/lib/graphql/relay/mutation/instrumentation.rb +2 -2
  38. data/lib/graphql/relay/mutation/resolve.rb +7 -10
  39. data/lib/graphql/relay/relation_connection.rb +98 -61
  40. data/lib/graphql/scalar_type.rb +1 -15
  41. data/lib/graphql/schema.rb +90 -25
  42. data/lib/graphql/schema/build_from_definition.rb +22 -23
  43. data/lib/graphql/schema/build_from_definition/resolve_map.rb +70 -0
  44. data/lib/graphql/schema/build_from_definition/resolve_map/default_resolve.rb +47 -0
  45. data/lib/graphql/schema/middleware_chain.rb +1 -1
  46. data/lib/graphql/schema/printer.rb +2 -1
  47. data/lib/graphql/schema/timeout_middleware.rb +6 -6
  48. data/lib/graphql/schema/type_map.rb +1 -1
  49. data/lib/graphql/schema/warden.rb +5 -9
  50. data/lib/graphql/static_validation/definition_dependencies.rb +1 -1
  51. data/lib/graphql/version.rb +1 -1
  52. data/spec/graphql/analysis/analyze_query_spec.rb +2 -2
  53. data/spec/graphql/analysis/max_query_complexity_spec.rb +28 -0
  54. data/spec/graphql/argument_spec.rb +3 -3
  55. data/spec/graphql/execution/lazy_spec.rb +8 -114
  56. data/spec/graphql/execution/multiplex_spec.rb +131 -0
  57. data/spec/graphql/internal_representation/rewrite_spec.rb +10 -0
  58. data/spec/graphql/query/arguments_spec.rb +14 -16
  59. data/spec/graphql/query/context_spec.rb +14 -1
  60. data/spec/graphql/query/literal_input_spec.rb +19 -13
  61. data/spec/graphql/query/variables_spec.rb +1 -1
  62. data/spec/graphql/query_spec.rb +12 -1
  63. data/spec/graphql/rake_task_spec.rb +57 -0
  64. data/spec/graphql/relay/array_connection_spec.rb +24 -3
  65. data/spec/graphql/relay/connection_instrumentation_spec.rb +23 -0
  66. data/spec/graphql/relay/mutation_spec.rb +2 -10
  67. data/spec/graphql/relay/page_info_spec.rb +2 -2
  68. data/spec/graphql/relay/relation_connection_spec.rb +167 -3
  69. data/spec/graphql/schema/build_from_definition_spec.rb +93 -19
  70. data/spec/graphql/schema/warden_spec.rb +80 -0
  71. data/spec/graphql/schema_spec.rb +26 -2
  72. data/spec/spec_helper.rb +4 -2
  73. data/spec/support/lazy_helpers.rb +152 -0
  74. data/spec/support/star_wars/schema.rb +23 -0
  75. metadata +28 -3
  76. data/lib/graphql/schema/mask.rb +0 -55
@@ -1,4 +1,6 @@
1
1
  # frozen_string_literal: true
2
+ require "graphql/schema/build_from_definition/resolve_map"
3
+
2
4
  module GraphQL
3
5
  class Schema
4
6
  module BuildFromDefinition
@@ -23,24 +25,6 @@ module GraphQL
23
25
  end
24
26
  end
25
27
 
26
- # @api private
27
- class ResolveMap
28
- def initialize(resolve_hash)
29
- @resolve_hash = resolve_hash
30
- end
31
-
32
- def call(type, field, obj, args, ctx)
33
- type_hash = @resolve_hash[type.name]
34
- type_hash && (resolver = type_hash[field.name])
35
-
36
- if resolver.nil?
37
- raise(KeyError, "resolver not found for #{type.name}.#{field.name}")
38
- else
39
- resolver.call(obj, args, ctx)
40
- end
41
- end
42
- end
43
-
44
28
  # @api private
45
29
  module Builder
46
30
  extend self
@@ -72,7 +56,7 @@ module GraphQL
72
56
  when GraphQL::Language::Nodes::UnionTypeDefinition
73
57
  types[definition.name] = build_union_type(definition, type_resolver)
74
58
  when GraphQL::Language::Nodes::ScalarTypeDefinition
75
- types[definition.name] = build_scalar_type(definition, type_resolver)
59
+ types[definition.name] = build_scalar_type(definition, type_resolver, default_resolve: default_resolve)
76
60
  when GraphQL::Language::Nodes::InputObjectTypeDefinition
77
61
  types[definition.name] = build_input_object_type(definition, type_resolver)
78
62
  when GraphQL::Language::Nodes::DirectiveDefinition
@@ -107,17 +91,23 @@ module GraphQL
107
91
 
108
92
  raise InvalidDocumentError.new('Must provide schema definition with query type or a type named Query.') unless query_root_type
109
93
 
110
- Schema.define do
94
+ schema = Schema.define do
111
95
  raise_definition_error true
112
96
 
113
97
  query query_root_type
114
98
  mutation mutation_root_type
115
99
  subscription subscription_root_type
116
100
  orphan_types types.values
117
- resolve_type NullResolveType
101
+ if default_resolve.respond_to?(:resolve_type)
102
+ resolve_type(default_resolve.method(:resolve_type))
103
+ else
104
+ resolve_type(NullResolveType)
105
+ end
118
106
 
119
107
  directives directives.values
120
108
  end
109
+
110
+ schema
121
111
  end
122
112
 
123
113
  NullResolveType = ->(obj, ctx) {
@@ -151,12 +141,21 @@ module GraphQL
151
141
  reason.value
152
142
  end
153
143
 
154
- def build_scalar_type(scalar_type_definition, type_resolver)
155
- GraphQL::ScalarType.define(
144
+ def build_scalar_type(scalar_type_definition, type_resolver, default_resolve:)
145
+ scalar_type = GraphQL::ScalarType.define(
156
146
  name: scalar_type_definition.name,
157
147
  description: scalar_type_definition.description,
158
148
  coerce: NullScalarCoerce,
159
149
  )
150
+
151
+ if default_resolve.respond_to?(:coerce_input)
152
+ scalar_type = scalar_type.redefine(
153
+ coerce_input: ->(val, ctx) { default_resolve.coerce_input(scalar_type, val, ctx) },
154
+ coerce_result: ->(val, ctx) { default_resolve.coerce_result(scalar_type, val, ctx) },
155
+ )
156
+ end
157
+
158
+ scalar_type
160
159
  end
161
160
 
162
161
  def build_union_type(union_type_definition, type_resolver)
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+ require "graphql/schema/build_from_definition/resolve_map/default_resolve"
3
+
4
+ module GraphQL
5
+ class Schema
6
+ module BuildFromDefinition
7
+ # Wrap a user-provided hash of resolution behavior for easy access at runtime.
8
+ #
9
+ # Coerce scalar values by:
10
+ # - Checking for a function in the map like `{ Date: { coerce_input: ->(val, ctx) { ... }, coerce_result: ->(val, ctx) { ... } } }`
11
+ # - Falling back to a passthrough
12
+ #
13
+ # Interface/union resolution can be provided as a `resolve_type:` key.
14
+ #
15
+ # @api private
16
+ class ResolveMap
17
+ def initialize(user_resolve_hash)
18
+ @resolve_hash = Hash.new do |h, k|
19
+ # For each type name, provide a new hash if one wasn't given:
20
+ h[k] = Hash.new do |h2, k2|
21
+ if k2 == "coerce_input" || k2 == "coerce_result"
22
+ # This isn't an object field, it's a scalar coerce function.
23
+ # Use a passthrough
24
+ Builder::NullScalarCoerce
25
+ else
26
+ # For each field, provide a resolver that will
27
+ # make runtime checks & replace itself
28
+ h2[k2] = DefaultResolve.new(h2, k2)
29
+ end
30
+ end
31
+ end
32
+ @user_resolve_hash = user_resolve_hash
33
+ # User-provided resolve functions take priority over the default:
34
+ @user_resolve_hash.each do |type_name, fields|
35
+ type_name_s = type_name.to_s
36
+ case fields
37
+ when Hash
38
+ fields.each do |field_name, resolve_fn|
39
+ @resolve_hash[type_name_s][field_name.to_s] = resolve_fn
40
+ end
41
+ when Proc
42
+ # for example, __resolve_type
43
+ @resolve_hash[type_name_s] = fields
44
+ end
45
+ end
46
+
47
+ # Check the normalized hash, not the user input:
48
+ if @resolve_hash.key?("resolve_type")
49
+ define_singleton_method :resolve_type do |type, ctx|
50
+ @resolve_hash.fetch("resolve_type").call(type, ctx)
51
+ end
52
+ end
53
+ end
54
+
55
+ def call(type, field, obj, args, ctx)
56
+ resolver = @resolve_hash[type.name][field.name]
57
+ resolver.call(obj, args, ctx)
58
+ end
59
+
60
+ def coerce_input(type, value, ctx)
61
+ @resolve_hash[type.name]["coerce_input"].call(value, ctx)
62
+ end
63
+
64
+ def coerce_result(type, value, ctx)
65
+ @resolve_hash[type.name]["coerce_result"].call(value, ctx)
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+ module GraphQL
3
+ class Schema
4
+ module BuildFromDefinition
5
+ class ResolveMap
6
+ class DefaultResolve
7
+ def initialize(field_map, field_name)
8
+ @field_map = field_map
9
+ @field_name = field_name
10
+ end
11
+
12
+ # Make some runtime checks about
13
+ # how `obj` implements the `field_name`.
14
+ #
15
+ # Create a new resolve function according to that implementation, then:
16
+ # - update `field_map` with this implementation
17
+ # - call the implementation now (to satisfy this field execution)
18
+ #
19
+ # If `obj` doesn't implement `field_name`, raise an error.
20
+ def call(obj, args, ctx)
21
+ method_name = @field_name
22
+ if !obj.respond_to?(method_name)
23
+ raise KeyError, "Can't resolve field #{method_name} on #{obj}"
24
+ else
25
+ method_arity = obj.method(method_name).arity
26
+ resolver = case method_arity
27
+ when 0, -1
28
+ # -1 Handles method_missing, eg openstruct
29
+ ->(o, a, c) { o.public_send(method_name) }
30
+ when 1
31
+ ->(o, a, c) { o.public_send(method_name, a) }
32
+ when 2
33
+ ->(o, a, c) { o.public_send(method_name, a, c) }
34
+ else
35
+ raise "Unexpected resolve arity: #{method_arity}. Must be 0, 1, 2"
36
+ end
37
+ # Call the resolver directly next time
38
+ @field_map[method_name] = resolver
39
+ # Call through this time
40
+ resolver.call(obj, args, ctx)
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -5,7 +5,7 @@ module GraphQL
5
5
  #
6
6
  # Steps should call `next_step.call` to continue the chain, or _not_ call it to stop the chain.
7
7
  class MiddlewareChain
8
- extend GraphQL::Delegate
8
+ extend Forwardable
9
9
 
10
10
  # @return [Array<#call(*args)>] Steps in this chain, will be called with arguments and `next_middleware`
11
11
  attr_reader :steps, :final_step
@@ -49,7 +49,8 @@ module GraphQL
49
49
  @context = context
50
50
 
51
51
  blacklist = build_blacklist(only, except, introspection: introspection)
52
- @warden = GraphQL::Schema::Warden.new(blacklist, schema: @schema, context: @context)
52
+ filter = GraphQL::Filter.new(except: blacklist)
53
+ @warden = GraphQL::Schema::Warden.new(filter, schema: @schema, context: @context)
53
54
  end
54
55
 
55
56
  # Return the GraphQL schema string for the introspection type system
@@ -24,18 +24,18 @@ module GraphQL
24
24
  # end
25
25
  #
26
26
  class TimeoutMiddleware
27
- # This key is used for storing timeout data in the {Query::Context} instance
28
- DEFAULT_CONTEXT_KEY = :__timeout_at__
29
27
  # @param max_seconds [Numeric] how many seconds the query should be allowed to resolve new fields
30
- # @param context_key [Symbol] what key should be used to read and write to the query context
31
- def initialize(max_seconds:, context_key: DEFAULT_CONTEXT_KEY, &block)
28
+ def initialize(max_seconds:, context_key: nil, &block)
32
29
  @max_seconds = max_seconds
33
- @context_key = context_key
30
+ if context_key
31
+ warn("TimeoutMiddleware's `context_key` is ignored, timeout data is now stored in isolated storage")
32
+ end
34
33
  @error_handler = block
35
34
  end
36
35
 
37
36
  def call(parent_type, parent_object, field_definition, field_args, query_context)
38
- timeout_at = query_context[@context_key] ||= Time.now + @max_seconds
37
+ ns = query_context.namespace(TimeoutMiddleware)
38
+ timeout_at = ns[:timeout_at] ||= Time.now + @max_seconds
39
39
 
40
40
  if timeout_at < Time.now
41
41
  on_timeout(parent_type, parent_object, field_definition, field_args, query_context)
@@ -8,7 +8,7 @@ module GraphQL
8
8
  #
9
9
  # If you want a type, but want to handle the undefined case, use {#fetch}.
10
10
  class TypeMap
11
- extend GraphQL::Delegate
11
+ extend Forwardable
12
12
  def_delegators :@storage, :key?, :keys, :values, :to_h, :fetch, :each, :each_value
13
13
 
14
14
  def initialize
@@ -1,21 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
  module GraphQL
3
3
  class Schema
4
- # Restrict access to a {GraphQL::Schema} with a user-defined mask.
5
- #
6
- # The mask is object that responds to `#visible?(schema_member)`.
4
+ # Restrict access to a {GraphQL::Schema} with a user-defined filter.
7
5
  #
8
6
  # When validating and executing a query, all access to schema members
9
7
  # should go through a warden. If you access the schema directly,
10
8
  # you may show a client something that it shouldn't be allowed to see.
11
9
  #
12
- # Masks can be provided in {Schema#execute} (or {Query#initialize}) with the `mask:` keyword.
13
- #
14
10
  # @example Hidding private fields
15
11
  # private_members = -> (member, ctx) { member.metadata[:private] }
16
12
  # result = Schema.execute(query_string, except: private_members)
17
13
  #
18
- # @example Custom mask implementation
14
+ # @example Custom filter implementation
19
15
  # # It must respond to `#call(member)`.
20
16
  # class MissingRequiredFlags
21
17
  # def initialize(user)
@@ -38,13 +34,13 @@ module GraphQL
38
34
  #
39
35
  # @api private
40
36
  class Warden
41
- # @param mask [<#call(member)>] Objects are hidden when `.call(member, ctx)` returns true
37
+ # @param filter [<#call(member)>] Objects are hidden when `.call(member, ctx)` returns true
42
38
  # @param context [GraphQL::Query::Context]
43
39
  # @param schema [GraphQL::Schema]
44
40
  # @param deep_check [Boolean]
45
- def initialize(mask, context:, schema:)
41
+ def initialize(filter, context:, schema:)
46
42
  @schema = schema
47
- @visibility_cache = read_through { |m| !mask.call(m, context) }
43
+ @visibility_cache = read_through { |m| filter.call(m, context) }
48
44
  end
49
45
 
50
46
  # @return [Array<GraphQL::BaseType>] Visible types in the schema
@@ -103,7 +103,7 @@ module GraphQL
103
103
  end
104
104
 
105
105
  class NodeWithPath
106
- extend GraphQL::Delegate
106
+ extend Forwardable
107
107
  attr_reader :node, :path
108
108
  def initialize(node, path)
109
109
  @node = node
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module GraphQL
3
- VERSION = "1.5.15"
3
+ VERSION = "1.6.0"
4
4
  end
@@ -9,7 +9,7 @@ describe GraphQL::Analysis do
9
9
 
10
10
  def call(memo, visit_type, irep_node)
11
11
  if visit_type == :enter
12
- memo + [irep_node.return_type]
12
+ memo + [irep_node.return_type.unwrap]
13
13
  else
14
14
  memo
15
15
  end
@@ -83,7 +83,7 @@ describe GraphQL::Analysis do
83
83
  memo ||= Hash.new { |h,k| h[k] = 0 }
84
84
  if visit_type == :enter
85
85
  if irep_node.ast_node.is_a?(GraphQL::Language::Nodes::Field)
86
- if irep_node.definition.resolve_proc.is_a?(GraphQL::Relay::ConnectionResolve)
86
+ if irep_node.definition.connection?
87
87
  memo[:connection] ||= 0
88
88
  memo[:connection] += 1
89
89
  else
@@ -60,4 +60,32 @@ describe GraphQL::Analysis::MaxQueryComplexity do
60
60
  assert_equal "Query has complexity of 10, which exceeds max complexity of 7", result["errors"][0]["message"]
61
61
  end
62
62
  end
63
+
64
+ describe "across a multiplex" do
65
+ before do
66
+ Dummy::Schema.max_complexity = 9
67
+ end
68
+
69
+ let(:queries) { 5.times.map { |n| { query: "{ cheese(id: #{n}) { id } }" } } }
70
+
71
+ it "returns errors for all queries" do
72
+ results = Dummy::Schema.multiplex(queries)
73
+ assert_equal 5, results.length
74
+ err_msg = "Query has complexity of 10, which exceeds max complexity of 9"
75
+ results.each do |res|
76
+ assert_equal err_msg, res["errors"][0]["message"]
77
+ end
78
+ end
79
+
80
+ describe "with a local override" do
81
+ it "uses the override" do
82
+ results = Dummy::Schema.multiplex(queries, max_complexity: 10)
83
+ assert_equal 5, results.length
84
+ results.each do |res|
85
+ assert_equal true, res.key?("data")
86
+ assert_equal false, res.key?("errors")
87
+ end
88
+ end
89
+ end
90
+ end
63
91
  end
@@ -60,14 +60,14 @@ describe GraphQL::Argument do
60
60
 
61
61
  describe "prepare" do
62
62
  it "accepts a prepare proc and calls it to generate the prepared value" do
63
- prepare_proc = Proc.new { |arg| arg + 1 }
63
+ prepare_proc = Proc.new { |arg, ctx| arg + ctx[:val] }
64
64
  argument = GraphQL::Argument.define(name: :plusOne, type: GraphQL::INT_TYPE, prepare: prepare_proc)
65
- assert_equal argument.prepare(1), 2
65
+ assert_equal argument.prepare(1, {val: 1}), 2
66
66
  end
67
67
 
68
68
  it "returns the value itself if no prepare proc is provided" do
69
69
  argument = GraphQL::Argument.define(name: :someNumber, type: GraphQL::INT_TYPE)
70
- assert_equal argument.prepare(1), 1
70
+ assert_equal argument.prepare(1, nil), 1
71
71
  end
72
72
  end
73
73
  end
@@ -2,117 +2,11 @@
2
2
  require "spec_helper"
3
3
 
4
4
  describe GraphQL::Execution::Lazy do
5
- class Wrapper
6
- def initialize(item = nil, &block)
7
- if block
8
- @block = block
9
- else
10
- @item = item
11
- end
12
- end
13
-
14
- def item
15
- if @block
16
- @item = @block.call()
17
- @block = nil
18
- end
19
- @item
20
- end
21
- end
22
-
23
- class SumAll
24
- attr_reader :own_value
25
- attr_accessor :value
26
-
27
- def initialize(ctx, own_value)
28
- @own_value = own_value
29
- @all = ctx[:__sum_all__] ||= []
30
- @all << self
31
- end
32
-
33
- def value
34
- @value ||= begin
35
- total_value = @all.map(&:own_value).reduce(&:+)
36
- @all.each { |v| v.value = total_value}
37
- @all.clear
38
- total_value
39
- end
40
- @value
41
- end
42
- end
43
-
44
- LazySum = GraphQL::ObjectType.define do
45
- name "LazySum"
46
- field :value, types.Int do
47
- resolve ->(o, a, c) { o == 13 ? nil : o }
48
- end
49
- field :nestedSum, !LazySum do
50
- argument :value, !types.Int
51
- resolve ->(o, args, c) {
52
- if args[:value] == 13
53
- Wrapper.new(nil)
54
- else
55
- SumAll.new(c, o + args[:value])
56
- end
57
- }
58
- end
59
-
60
- field :nullableNestedSum, LazySum do
61
- argument :value, types.Int
62
- resolve ->(o, args, c) {
63
- if args[:value] == 13
64
- Wrapper.new(nil)
65
- else
66
- SumAll.new(c, o + args[:value])
67
- end
68
- }
69
- end
70
- end
71
-
72
- LazyQuery = GraphQL::ObjectType.define do
73
- name "Query"
74
- field :int, !types.Int do
75
- argument :value, !types.Int
76
- argument :plus, types.Int, default_value: 0
77
- resolve ->(o, a, c) { Wrapper.new(a[:value] + a[:plus])}
78
- end
79
-
80
- field :nestedSum, !LazySum do
81
- argument :value, !types.Int
82
- resolve ->(o, args, c) { SumAll.new(c, args[:value]) }
83
- end
84
-
85
- field :nullableNestedSum, LazySum do
86
- argument :value, types.Int
87
- resolve ->(o, args, c) {
88
- if args[:value] == 13
89
- Wrapper.new { raise GraphQL::ExecutionError.new("13 is unlucky") }
90
- else
91
- SumAll.new(c, args[:value])
92
- end
93
- }
94
- end
95
-
96
- field :listSum, types[LazySum] do
97
- argument :values, types[types.Int]
98
- resolve ->(o, args, c) { args[:values] }
99
- end
100
- end
101
-
102
- LazySchema = GraphQL::Schema.define do
103
- query(LazyQuery)
104
- mutation(LazyQuery)
105
- lazy_resolve(Wrapper, :item)
106
- lazy_resolve(SumAll, :value)
107
- end
108
-
109
- def run_query(query_str)
110
- LazySchema.execute(query_str)
111
- end
5
+ include LazyHelpers
112
6
 
113
7
  describe "resolving" do
114
8
  it "calls value handlers" do
115
- res = run_query('{ int(value: 2, plus: 1)}')
9
+ res = run_query('{ int(value: 2, plus: 1) }')
116
10
  assert_equal 3, res["data"]["int"]
117
11
  end
118
12
 
@@ -234,16 +128,16 @@ describe GraphQL::Execution::Lazy do
234
128
  end
235
129
 
236
130
  describe "LazyMethodMap" do
237
- class SubWrapper < Wrapper; end
131
+ class SubWrapper < LazyHelpers::Wrapper; end
238
132
 
239
133
  let(:map) { GraphQL::Execution::Lazy::LazyMethodMap.new }
240
134
 
241
135
  it "finds methods for classes and subclasses" do
242
- map.set(Wrapper, :item)
243
- map.set(SumAll, :value)
244
- b = Wrapper.new(1)
245
- sub_b = Wrapper.new(2)
246
- s = SumAll.new({}, 3)
136
+ map.set(LazyHelpers::Wrapper, :item)
137
+ map.set(LazyHelpers::SumAll, :value)
138
+ b = LazyHelpers::Wrapper.new(1)
139
+ sub_b = LazyHelpers::Wrapper.new(2)
140
+ s = LazyHelpers::SumAll.new({}, 3)
247
141
  assert_equal(:item, map.get(b))
248
142
  assert_equal(:item, map.get(sub_b))
249
143
  assert_equal(:value, map.get(s))