graphql 1.7.2 → 1.7.3

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: 2fb4d91df18b66c7d1c4a9c712ee771aedb00655
4
- data.tar.gz: c787072c016f6995c4742f086cabe05d6d8c931b
3
+ metadata.gz: '08e688c4046aa3130fe9f427f810356abc25abfc'
4
+ data.tar.gz: d2896b9042f2bab1dffd256551082168aa52288d
5
5
  SHA512:
6
- metadata.gz: 58bee87006d10dfc306e17733770d899a93113c5836e30bba8443330afd2131d49e1a35a24606e20a69762b16450a0b779c7cd5dba03b46d70fa880f7e3b560c
7
- data.tar.gz: 6369f05cdb38c7d960abab0bd927794f122ac7d82e8c8c422d044ede6d5f099ccd28c532f044ae69a8b89af97306866720996ae1591142e8f9e93bfea89a0b24
6
+ metadata.gz: 624eb16565591d5df45dc69df9dc5cc7fa6b97ca9ff4d3745427df47e979a15e889458689f1e52d9f8a553b0974f738cb2cff703d1fc98dcc25cfbffee36f408
7
+ data.tar.gz: 0421334ac91f05b8a0adf48199b811eb81efbcfd4a0c543bf3ff58248e9db3c4c1ba036d5cbeffca69fcb12e10d07e88fa0cf9896cbfd081b884da5d62f5aa8c
@@ -43,7 +43,7 @@ module GraphQL
43
43
  when GraphQL::Execution::Lazy
44
44
  "(unresolved)"
45
45
  else
46
- obj.inspect
46
+ "#{obj.inspect}"
47
47
  end
48
48
  end
49
49
  end
@@ -87,7 +87,7 @@ module GraphQL
87
87
  rows << [
88
88
  "#{position}",
89
89
  "#{field_name}#{field_alias ? " as #{field_alias}" : ""}",
90
- ctx.object.inspect,
90
+ "#{ctx.object.inspect}",
91
91
  ctx.irep_node.arguments.to_h.inspect,
92
92
  Backtrace::InspectResult.inspect(top && @override_value ? @override_value : ctx.value),
93
93
  ]
@@ -107,7 +107,7 @@ module GraphQL
107
107
  rows << [
108
108
  "#{position}",
109
109
  "#{op_type}#{op_name ? " #{op_name}" : ""}",
110
- query.root_value.inspect,
110
+ "#{query.root_value.inspect}",
111
111
  query.variables.to_h.inspect,
112
112
  Backtrace::InspectResult.inspect(query.context.value),
113
113
  ]
@@ -96,7 +96,7 @@ module GraphQL
96
96
  end
97
97
  end
98
98
 
99
- arguments_class.instantiate_arguments(input_values)
99
+ arguments_class.new(input_values)
100
100
  end
101
101
 
102
102
  # @api private
@@ -1,48 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
  module GraphQL
3
3
  class Query
4
- class StaticArguments
5
- attr_reader :argument_definitions
6
-
7
- def initialize(argument_definitions:)
8
- @argument_definitions = argument_definitions
9
- end
10
-
11
- def instantiate_arguments(values)
12
- arg_class.new(values, argument_definitions: argument_definitions)
13
- end
14
-
15
- private
16
-
17
- def arg_class
18
- @arg_class ||= begin
19
- klass = Class.new(GraphQL::Query::Arguments).instance_exec(self) do |static_arguments|
20
- static_arguments.argument_definitions.each do |_arg_name, arg_definition|
21
- expose_as = arg_definition.expose_as.to_s
22
-
23
- # Don't define a helper method if it would override something.
24
- if instance_methods.include?(expose_as)
25
- warn(
26
- "Unable to define a helper for argument with name '#{expose_as}' "\
27
- "as this is a reserved name. If you're using an argument such as "\
28
- "`argument #{expose_as}`, consider renaming this argument.`"
29
- )
30
- next
31
- end
32
-
33
- define_method(expose_as) do
34
- self[expose_as]
35
- end
36
- end
37
-
38
- self
39
- end
40
-
41
- klass
42
- end
43
- end
44
- end
45
-
46
4
  # Read-only access to values, normalizing all keys to strings
47
5
  #
48
6
  # {Arguments} recursively wraps the input in {Arguments} instances.
@@ -50,8 +8,32 @@ module GraphQL
50
8
  extend GraphQL::Delegate
51
9
 
52
10
  def self.construct_arguments_class(argument_owner)
53
- arguments_class = GraphQL::Query::StaticArguments.new(argument_definitions: argument_owner.arguments)
54
- argument_owner.arguments_class = arguments_class
11
+ argument_definitions = argument_owner.arguments
12
+ argument_owner.arguments_class = Class.new(self) do
13
+ self.argument_definitions = argument_definitions
14
+
15
+ def initialize(values)
16
+ super(values, argument_definitions: self.class.argument_definitions)
17
+ end
18
+
19
+ argument_definitions.each do |_arg_name, arg_definition|
20
+ expose_as = arg_definition.expose_as.to_s
21
+
22
+ # Don't define a helper method if it would override something.
23
+ if instance_methods.include?(expose_as)
24
+ warn(
25
+ "Unable to define a helper for argument with name '#{expose_as}' "\
26
+ "as this is a reserved name. If you're using an argument such as "\
27
+ "`argument #{expose_as}`, consider renaming this argument.`"
28
+ )
29
+ next
30
+ end
31
+
32
+ define_method(expose_as) do
33
+ self[expose_as]
34
+ end
35
+ end
36
+ end
55
37
  end
56
38
 
57
39
  def initialize(values, argument_definitions:)
@@ -105,6 +87,10 @@ module GraphQL
105
87
 
106
88
  NO_ARGS = self.new({}, argument_definitions: [])
107
89
 
90
+ class << self
91
+ attr_accessor :argument_definitions
92
+ end
93
+
108
94
  private
109
95
 
110
96
  class ArgumentValue
@@ -129,7 +115,7 @@ module GraphQL
129
115
  wrap_value(value, arg_defn_type.of_type)
130
116
  when GraphQL::InputObjectType
131
117
  if value.is_a?(Hash)
132
- self.class.new(value, argument_definitions: arg_defn_type.arguments)
118
+ arg_defn_type.arguments_class.new(value)
133
119
  else
134
120
  value
135
121
  end
@@ -105,7 +105,7 @@ module GraphQL
105
105
  end
106
106
  end
107
107
 
108
- argument_owner.arguments_class.instantiate_arguments(values_hash)
108
+ argument_owner.arguments_class.new(values_hash)
109
109
  end
110
110
  end
111
111
  end
@@ -140,6 +140,10 @@ module GraphQL
140
140
  raise NotImplementedError, "must return a cursor for this object/connection pair"
141
141
  end
142
142
 
143
+ def inspect
144
+ "#<GraphQL::Relay::Connection @parent=#{@parent.inspect} @arguments=#{@arguments.to_h.inspect}>"
145
+ end
146
+
143
147
  private
144
148
 
145
149
  # Return a sanitized `arguments[arg_name]` (don't allow negatives)
@@ -4,7 +4,7 @@ module GraphQL
4
4
  # Mostly an internal concern.
5
5
  #
6
6
  # Wraps an object as a `node`, and exposes a connection-specific `cursor`.
7
- class Edge < GraphQL::ObjectType
7
+ class Edge
8
8
  attr_reader :node, :connection
9
9
  def initialize(node, connection)
10
10
  @node = node
@@ -18,6 +18,10 @@ module GraphQL
18
18
  def parent
19
19
  @parent ||= connection.parent
20
20
  end
21
+
22
+ def inspect
23
+ "#<GraphQL::Relay::Edge (#{parent.inspect} => #{node.inspect})>"
24
+ end
21
25
  end
22
26
  end
23
27
  end
@@ -104,10 +104,13 @@ module GraphQL
104
104
  end
105
105
 
106
106
  def visit_field_on_type(type_defn, field_defn, dynamic_field: false)
107
- instrumented_field_defn = @field_instrumenters.reduce(field_defn) do |defn, inst|
108
- inst.instrument(type_defn, defn)
109
- end
110
- if !dynamic_field
107
+ if dynamic_field
108
+ # Don't apply instrumentation to dynamic fields since they're shared constants
109
+ instrumented_field_defn = field_defn
110
+ else
111
+ instrumented_field_defn = @field_instrumenters.reduce(field_defn) do |defn, inst|
112
+ inst.instrument(type_defn, defn)
113
+ end
111
114
  @instrumented_field_map[type_defn.name][instrumented_field_defn.name] = instrumented_field_defn
112
115
  end
113
116
  @type_reference_map[instrumented_field_defn.type.unwrap.name] << instrumented_field_defn
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module GraphQL
3
- VERSION = "1.7.2"
3
+ VERSION = "1.7.3"
4
4
  end
@@ -16,11 +16,25 @@ describe GraphQL::Backtrace do
16
16
  end
17
17
  end
18
18
 
19
+ class ErrorAnalyzer
20
+ def call(_memo, visit_type, irep_node)
21
+ if irep_node.name == "raiseError"
22
+ raise GraphQL::AnalysisError, "this should not be wrapped by a backtrace, but instead, returned to the client"
23
+ end
24
+ end
25
+ end
26
+
27
+ class NilInspectObject
28
+ # Oops, this is evil, but it happens and we should handle it.
29
+ def inspect; nil; end
30
+ end
31
+
19
32
  let(:resolvers) {
20
33
  {
21
34
  "Query" => {
22
35
  "field1" => Proc.new { :something },
23
36
  "field2" => Proc.new { :something },
37
+ "nilInspect" => Proc.new { NilInspectObject.new },
24
38
  },
25
39
  "Thing" => {
26
40
  "listField" => Proc.new { :not_a_list },
@@ -36,6 +50,7 @@ describe GraphQL::Backtrace do
36
50
  type Query {
37
51
  field1: Thing
38
52
  field2: OtherThing
53
+ nilInspect: Thing
39
54
  }
40
55
 
41
56
  type Thing {
@@ -49,6 +64,7 @@ describe GraphQL::Backtrace do
49
64
  GRAPHQL
50
65
  GraphQL::Schema.from_definition(defn, default_resolve: resolvers).redefine {
51
66
  lazy_resolve(LazyError, :raise_err)
67
+ query_analyzer(ErrorAnalyzer.new)
52
68
  }
53
69
  }
54
70
 
@@ -103,7 +119,7 @@ describe GraphQL::Backtrace do
103
119
  assert_includes err.message, rendered_table
104
120
  # The message includes the original error message
105
121
  assert_includes err.message, "This is broken: Boom"
106
- assert_includes err.message, "spec/graphql/backtrace_spec.rb:27", "It includes the original backtrace"
122
+ assert_includes err.message, "spec/graphql/backtrace_spec.rb:41", "It includes the original backtrace"
107
123
  assert_includes err.message, "more lines"
108
124
  end
109
125
 
@@ -133,6 +149,26 @@ describe GraphQL::Backtrace do
133
149
  ].join("\n")
134
150
  assert_includes err.message, rendered_table
135
151
  end
152
+
153
+ it "returns analysis errors to the client" do
154
+ res = schema.execute("query raiseError { __typename }")
155
+ assert_equal "this should not be wrapped by a backtrace, but instead, returned to the client", res["errors"].first["message"]
156
+ end
157
+
158
+ it "always stringifies the #inspect response" do
159
+ err = assert_raises(GraphQL::Backtrace::TracedError) {
160
+ schema.execute("query { nilInspect { raiseField(message: \"pop!\") } }")
161
+ }
162
+
163
+ rendered_table = [
164
+ 'Loc | Field | Object | Arguments | Result',
165
+ '1:22 | Thing.raiseField | | {"message"=>"pop!"} | #<RuntimeError: This is broken: pop!>',
166
+ '1:9 | Query.nilInspect | nil | {} | {}',
167
+ '1:1 | query | nil | {} | {}',
168
+ ].join("\n")
169
+
170
+ assert_includes(err.message, rendered_table)
171
+ end
136
172
  end
137
173
 
138
174
  # This will get brittle when execution code moves between files
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+ require "spec_helper"
3
+
4
+ describe GraphQL::Introspection::TypeByNameField do
5
+ describe "after instrumentation" do
6
+ # Just make sure it returns a new object, not the original field
7
+ class DupInstrumenter
8
+ def self.instrument(t, f)
9
+ f.redefine {
10
+ resolve ->(o, a, c) { :no_op }
11
+ }
12
+ end
13
+ end
14
+
15
+ class ArgAnalyzer
16
+ def call(_, _, node)
17
+ if node.ast_node.is_a?(GraphQL::Language::Nodes::Field)
18
+ node.arguments
19
+ end
20
+ end
21
+ end
22
+
23
+ let(:instrumented_schema) {
24
+ # This was probably assigned earlier in the test suite, but to simulate an application, clear it.
25
+ GraphQL::Introspection::TypeByNameField.arguments_class = nil
26
+
27
+ Dummy::Schema.redefine {
28
+ instrument(:field, DupInstrumenter)
29
+ query_analyzer(ArgAnalyzer.new)
30
+ }
31
+ }
32
+
33
+ it "still works with __type" do
34
+ res = instrumented_schema.execute("{ __type(name: \"X\") { name } }")
35
+ assert_equal({"data"=>{"__type"=>nil}}, res)
36
+ end
37
+ end
38
+ end
@@ -90,13 +90,15 @@ describe GraphQL::Query::Arguments do
90
90
  argument :b, test_input_type
91
91
  argument :c, types.Int # will be a hash
92
92
  end
93
+ GraphQL::Query::Arguments.construct_arguments_class(test_input_type)
94
+ test_input_type
93
95
  }
94
96
  it "wraps input objects, but not other hashes" do
95
97
  args = GraphQL::Query::Arguments.new(
96
98
  {a: 1, b: {a: 2}, c: {a: 3}},
97
99
  argument_definitions: input_type.arguments
98
100
  )
99
- assert_instance_of GraphQL::Query::Arguments, args["b"]
101
+ assert_kind_of GraphQL::Query::Arguments, args["b"]
100
102
  assert_instance_of Hash, args["c"]
101
103
  end
102
104
  end
@@ -304,7 +306,7 @@ describe GraphQL::Query::Arguments do
304
306
  assert_equal nil, input_object.arguments_class
305
307
 
306
308
  GraphQL::Query::Arguments.construct_arguments_class(input_object)
307
- args = input_object.arguments_class.instantiate_arguments({foo: 3, bar: -90})
309
+ args = input_object.arguments_class.new({foo: 3, bar: -90})
308
310
 
309
311
  assert_equal 3, args.foo
310
312
  assert_equal -90, args.bar
@@ -49,6 +49,17 @@ describe GraphQL::Relay::BaseConnection do
49
49
  end
50
50
  end
51
51
 
52
+ describe "#inspect" do
53
+ it "inspects nicely" do
54
+ args = {
55
+ first: 1,
56
+ last: -1,
57
+ }
58
+ conn = GraphQL::Relay::BaseConnection.new([], args, context: context)
59
+ assert_equal "#<GraphQL::Relay::Connection @parent=nil @arguments={:first=>1, :last=>-1}>", conn.inspect
60
+ end
61
+ end
62
+
52
63
  describe "#encode / #decode" do
53
64
  module ReverseEncoder
54
65
  module_function
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+ require "spec_helper"
3
+
4
+ describe GraphQL::Relay::Edge do
5
+ it "inspects nicely" do
6
+ connection = OpenStruct.new(parent: "Parent")
7
+ edge = GraphQL::Relay::Edge.new("Node", connection)
8
+ assert_equal '#<GraphQL::Relay::Edge ("Parent" => "Node")>', edge.inspect
9
+ end
10
+ end
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: 1.7.2
4
+ version: 1.7.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robert Mosolgo
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-09-20 00:00:00.000000000 Z
11
+ date: 2017-09-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: benchmark-ips
@@ -568,6 +568,7 @@ files:
568
568
  - spec/graphql/introspection/input_value_type_spec.rb
569
569
  - spec/graphql/introspection/introspection_query_spec.rb
570
570
  - spec/graphql/introspection/schema_type_spec.rb
571
+ - spec/graphql/introspection/type_by_name_field_spec.rb
571
572
  - spec/graphql/introspection/type_type_spec.rb
572
573
  - spec/graphql/language/definition_slice_spec.rb
573
574
  - spec/graphql/language/equality_spec.rb
@@ -593,6 +594,7 @@ files:
593
594
  - spec/graphql/relay/connection_instrumentation_spec.rb
594
595
  - spec/graphql/relay/connection_resolve_spec.rb
595
596
  - spec/graphql/relay/connection_type_spec.rb
597
+ - spec/graphql/relay/edge_spec.rb
596
598
  - spec/graphql/relay/mutation_spec.rb
597
599
  - spec/graphql/relay/node_spec.rb
598
600
  - spec/graphql/relay/page_info_spec.rb
@@ -728,6 +730,7 @@ test_files:
728
730
  - spec/graphql/introspection/input_value_type_spec.rb
729
731
  - spec/graphql/introspection/introspection_query_spec.rb
730
732
  - spec/graphql/introspection/schema_type_spec.rb
733
+ - spec/graphql/introspection/type_by_name_field_spec.rb
731
734
  - spec/graphql/introspection/type_type_spec.rb
732
735
  - spec/graphql/language/definition_slice_spec.rb
733
736
  - spec/graphql/language/equality_spec.rb
@@ -753,6 +756,7 @@ test_files:
753
756
  - spec/graphql/relay/connection_instrumentation_spec.rb
754
757
  - spec/graphql/relay/connection_resolve_spec.rb
755
758
  - spec/graphql/relay/connection_type_spec.rb
759
+ - spec/graphql/relay/edge_spec.rb
756
760
  - spec/graphql/relay/mutation_spec.rb
757
761
  - spec/graphql/relay/node_spec.rb
758
762
  - spec/graphql/relay/page_info_spec.rb