graphql 1.4.2 → 1.4.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fe097cf7f88ed8a62ed53cc4fb3df2943a7a26e7
4
- data.tar.gz: 66c7f5ef3707ffdf91a8e15b5fd94319c6799f6c
3
+ metadata.gz: cda98acc4cef5d2d8e4c9c77cd9ac5f5139cc38a
4
+ data.tar.gz: 184b72d444de078b443453bca6f0a4d64d8cf0b9
5
5
  SHA512:
6
- metadata.gz: 6f922011419b6a8dcaed84c2088c0323681b27b283881339a021aeee0ae21b3d5d68da6da75dffe317d5db3514a2e0f5b7f9143553d2b3fef4d27ebeb36f45ae
7
- data.tar.gz: e109b93bd6d60ef1e57dd09e64260b1fc89aa728c01153ec703bc73e2232ba628df78e8188dba57b98a57b81a214aa750cd6f85c4f364a9db487dec85a8d9ead
6
+ metadata.gz: cf7c368fd8d9ef704580aa2956e2813db1e3efbd748f1d9836d58b17ae5afaca3df2d623750dd9546688e42ab1cb5c0be26f6bbe46ea3f7d837788c8fc00fe92
7
+ data.tar.gz: ce531eb4ad6cd87b947c9c5fbd68d5cd14fef266950a3448e02659d02e8bc7db10c7d9d206ea12751d059c01392ed952facf938c3cddfd53dfb21404b554d83f
@@ -16,22 +16,13 @@ module GraphQL
16
16
  if definition
17
17
  definition.call(@target, *args, &block)
18
18
  else
19
- p "Failed to find config #{name} in #{inspect}"
20
- super
19
+ msg = "#{@target.class.name} can't define '#{name}'"
20
+ raise NoMethodError, msg, caller
21
21
  end
22
22
  end
23
23
 
24
24
  def respond_to_missing?(name, include_private = false)
25
- return true if @dictionary[name]
26
- super
27
- end
28
-
29
- def to_s
30
- inspect
31
- end
32
-
33
- def inspect
34
- "<DefinedObjectProxy #{@target} (#{@dictionary.keys})>"
25
+ @dictionary[name] || super
35
26
  end
36
27
  end
37
28
  end
@@ -126,18 +126,22 @@ module GraphQL
126
126
  :type, :arguments,
127
127
  :property, :hash_key, :complexity, :mutation,
128
128
  :relay_node_field,
129
+ :relay_nodes_field,
129
130
  argument: GraphQL::Define::AssignArgument
130
131
 
131
132
  ensure_defined(
132
133
  :name, :deprecation_reason, :description, :description=, :property, :hash_key, :mutation, :arguments, :complexity,
133
134
  :resolve, :resolve=, :lazy_resolve, :lazy_resolve=, :lazy_resolve_proc, :resolve_proc,
134
135
  :type, :type=, :name=, :property=, :hash_key=,
135
- :relay_node_field,
136
+ :relay_node_field, :relay_nodes_field,
136
137
  )
137
138
 
138
139
  # @return [Boolean] True if this is the Relay find-by-id field
139
140
  attr_accessor :relay_node_field
140
141
 
142
+ # @return [Boolean] True if this is the Relay find-by-ids field
143
+ attr_accessor :relay_nodes_field
144
+
141
145
  # @return [<#call(obj, args, ctx)>] A proc-like object which can be called to return the field's value
142
146
  attr_reader :resolve_proc
143
147
 
@@ -990,7 +990,7 @@ end
990
990
  def self.record_comment(ts, te, meta)
991
991
  token = GraphQL::Language::Token.new(
992
992
  name: :COMMENT,
993
- value: meta[:data][ts...te].pack("c*"),
993
+ value: meta[:data][ts...te].pack("c*").force_encoding("UTF-8"),
994
994
  line: meta[:line],
995
995
  col: meta[:col],
996
996
  prev_token: meta[:previous_token],
@@ -1004,7 +1004,7 @@ end
1004
1004
  def self.emit(token_name, ts, te, meta)
1005
1005
  meta[:tokens] << token = GraphQL::Language::Token.new(
1006
1006
  name: token_name,
1007
- value: meta[:data][ts...te].pack("c*"),
1007
+ value: meta[:data][ts...te].pack("c*").force_encoding("UTF-8"),
1008
1008
  line: meta[:line],
1009
1009
  col: meta[:col],
1010
1010
  prev_token: meta[:previous_token],
@@ -145,7 +145,7 @@ module GraphQL
145
145
  def self.record_comment(ts, te, meta)
146
146
  token = GraphQL::Language::Token.new(
147
147
  name: :COMMENT,
148
- value: meta[:data][ts...te].pack("c*"),
148
+ value: meta[:data][ts...te].pack("c*").force_encoding("UTF-8"),
149
149
  line: meta[:line],
150
150
  col: meta[:col],
151
151
  prev_token: meta[:previous_token],
@@ -159,7 +159,7 @@ module GraphQL
159
159
  def self.emit(token_name, ts, te, meta)
160
160
  meta[:tokens] << token = GraphQL::Language::Token.new(
161
161
  name: token_name,
162
- value: meta[:data][ts...te].pack("c*"),
162
+ value: meta[:data][ts...te].pack("c*").force_encoding("UTF-8"),
163
163
  line: meta[:line],
164
164
  col: meta[:col],
165
165
  prev_token: meta[:previous_token],
@@ -177,23 +177,23 @@ module GraphQL
177
177
  def call(obj, args, ctx)
178
178
  mutation_result = @resolve.call(obj, args[:input], ctx)
179
179
 
180
- if mutation_result.is_a?(GraphQL::ExecutionError)
181
- ctx.add_error(mutation_result)
182
- mutation_result = nil
183
- end
184
-
185
180
  if ctx.schema.lazy?(mutation_result)
186
181
  @mutation.field.prepare_lazy(mutation_result, args, ctx).then { |inner_obj|
187
- build_result(inner_obj, args)
182
+ build_result(inner_obj, args, ctx)
188
183
  }
189
184
  else
190
- build_result(mutation_result, args)
185
+ build_result(mutation_result, args, ctx)
191
186
  end
192
187
  end
193
188
 
194
189
  private
195
190
 
196
- def build_result(mutation_result, args)
191
+ def build_result(mutation_result, args, ctx)
192
+ if mutation_result.is_a?(GraphQL::ExecutionError)
193
+ ctx.add_error(mutation_result)
194
+ mutation_result = nil
195
+ end
196
+
197
197
  if @wrap_result
198
198
  @mutation.result_class.new(client_mutation_id: args[:input][:clientMutationId], result: mutation_result)
199
199
  else
@@ -17,13 +17,30 @@ module GraphQL
17
17
  end
18
18
  end
19
19
 
20
+ def self.plural_field
21
+ GraphQL::Field.define do
22
+ type(!types[GraphQL::Relay::Node.interface])
23
+ description("Fetches a list of objects given a list of IDs.")
24
+ argument(:ids, !types[!types.ID], "IDs of the objects.")
25
+ resolve(GraphQL::Relay::Node::FindNodes)
26
+ relay_nodes_field(true)
27
+ end
28
+ end
29
+
20
30
  # @return [GraphQL::InterfaceType] The interface which all Relay types must implement
21
31
  def self.interface
22
32
  @interface ||= GraphQL::InterfaceType.define do
23
- name "Node"
24
- description "An object with an ID."
25
- field :id, !types.ID, "ID of the object."
26
- default_relay true
33
+ name("Node")
34
+ description("An object with an ID.")
35
+ field(:id, !types.ID, "ID of the object.")
36
+ default_relay(true)
37
+ end
38
+ end
39
+
40
+ # A field resolve for finding objects by IDs
41
+ module FindNodes
42
+ def self.call(obj, args, ctx)
43
+ args[:ids].map { |id| ctx.query.schema.object_from_id(id, ctx) }
27
44
  end
28
45
  end
29
46
 
@@ -132,7 +132,7 @@ module GraphQL
132
132
 
133
133
  SCHEMA_CAN_RESOLVE_TYPES = ->(schema) {
134
134
  if schema.types.values.any? { |type| type.kind.resolves? } && schema.resolve_type_proc.nil?
135
- "schema contains Interfaces or Unions, so you must define a `resolve_type (obj, ctx) -> { ... }` function"
135
+ "schema contains Interfaces or Unions, so you must define a `resolve_type -> (obj, ctx) { ... }` function"
136
136
  else
137
137
  # :+1:
138
138
  end
@@ -141,7 +141,7 @@ module GraphQL
141
141
  SCHEMA_CAN_FETCH_IDS = ->(schema) {
142
142
  has_node_field = schema.query && schema.query.all_fields.any?(&:relay_node_field)
143
143
  if has_node_field && schema.object_from_id_proc.nil?
144
- "schema contains `node(id:...)` field, so you must define a `object_from_id (id, ctx) -> { ... }` function"
144
+ "schema contains `node(id:...)` field, so you must define a `object_from_id -> (id, ctx) { ... }` function"
145
145
  else
146
146
  # :rocket:
147
147
  end
@@ -150,7 +150,7 @@ module GraphQL
150
150
  SCHEMA_CAN_GENERATE_IDS = ->(schema) {
151
151
  has_id_field = schema.types.values.any? { |t| t.kind.fields? && t.all_fields.any? { |f| f.resolve_proc.is_a?(GraphQL::Relay::GlobalIdResolve) } }
152
152
  if has_id_field && schema.id_from_object_proc.nil?
153
- "schema contains `global_id_field`, so you must define a `id_from_object (obj, type, ctx) -> { ... }` function"
153
+ "schema contains `global_id_field`, so you must define a `id_from_object -> (obj, type, ctx) { ... }` function"
154
154
  else
155
155
  # :ok_hand:
156
156
  end
@@ -1,4 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
  module GraphQL
3
- VERSION = "1.4.2"
3
+ VERSION = "1.4.3"
4
4
  end
@@ -115,4 +115,22 @@ describe GraphQL::Define::InstanceDefinable do
115
115
  assert_equal :green, arugula.metadata[:color]
116
116
  end
117
117
  end
118
+
119
+ describe "typos" do
120
+ it "provides the right class name, method name and line number" do
121
+ err = assert_raises(NoMethodError) {
122
+ beet = Garden::Vegetable.define {
123
+ name "Beet"
124
+ nonsense :Blah
125
+ }
126
+ beet.name
127
+ }
128
+ assert_includes err.message, "Garden::Vegetable"
129
+ assert_includes err.message, "nonsense"
130
+ first_backtrace = err.backtrace.first
131
+ # This is the offset from the assertion to the `nonsense` call,
132
+ # it might change when this test changes:
133
+ assert_includes first_backtrace, "#{__LINE__ - 9}"
134
+ end
135
+ end
118
136
  end
@@ -190,5 +190,28 @@ describe GraphQL::Relay::Mutation do
190
190
 
191
191
  assert_equal(expected, result)
192
192
  end
193
+
194
+ it "supports raising an error in a lazy callback" do
195
+ result = star_wars_query(query_string, "clientMutationId" => "5678", "shipName" => "Ebon Hawk")
196
+
197
+ expected = {
198
+ "data" => {
199
+ "introduceShip" => {
200
+ "clientMutationId" => "5678",
201
+ "shipEdge" => nil,
202
+ "faction" => nil,
203
+ }
204
+ },
205
+ "errors" => [
206
+ {
207
+ "message" => "💥",
208
+ "locations" => [ { "line" => 3 , "column" => 7}],
209
+ "path" => ["introduceShip"]
210
+ }
211
+ ]
212
+ }
213
+
214
+ assert_equal(expected, result)
215
+ end
193
216
  end
194
217
  end
@@ -56,7 +56,6 @@ describe GraphQL::Relay::Node do
56
56
  end
57
57
  end
58
58
 
59
-
60
59
  it 'finds objects by id' do
61
60
  id = GraphQL::Schema::UniqueWithinType.encode("Faction", "1")
62
61
  result = star_wars_query(%|{
@@ -91,4 +90,58 @@ describe GraphQL::Relay::Node do
91
90
  assert_equal(expected, result)
92
91
  end
93
92
  end
93
+
94
+ describe ".plural_identifying_field" do
95
+ it 'finds objects by ids' do
96
+ id = GraphQL::Schema::UniqueWithinType.encode("Faction", "1")
97
+ id2 = GraphQL::Schema::UniqueWithinType.encode("Faction", "2")
98
+
99
+ result = star_wars_query(%|{
100
+ nodes(ids: ["#{id}", "#{id2}"]) {
101
+ id,
102
+ ... on Faction {
103
+ name
104
+ ships(first: 1) {
105
+ edges {
106
+ node {
107
+ name
108
+ }
109
+ }
110
+ }
111
+ }
112
+ }
113
+ }|)
114
+
115
+ expected = {
116
+ "data" => {
117
+ "nodes" => [{
118
+ "id"=>"RmFjdGlvbi0x",
119
+ "name"=>"Alliance to Restore the Republic",
120
+ "ships"=>{
121
+ "edges"=>[
122
+ {"node"=>{
123
+ "name" => "X-Wing"
124
+ }
125
+ }
126
+ ]
127
+ }
128
+ }, {
129
+ "id" => "RmFjdGlvbi0y",
130
+ "name" => "Galactic Empire",
131
+ "ships" => {
132
+ "edges" => [
133
+ { "node" => { "name" => "TIE Fighter" } }
134
+ ]
135
+ }
136
+ }]
137
+ }
138
+ }
139
+
140
+ assert_equal(expected, result)
141
+ end
142
+
143
+ it 'is marked as relay_nodes_field' do
144
+ assert GraphQL::Relay::Node.plural_field.relay_nodes_field
145
+ end
146
+ end
94
147
  end
@@ -161,7 +161,8 @@ module StarWars
161
161
  faction_id = inputs["factionId"]
162
162
  if inputs["shipName"] == 'Millennium Falcon'
163
163
  GraphQL::ExecutionError.new("Sorry, Millennium Falcon ship is reserved")
164
-
164
+ elsif inputs["shipName"] == "Ebon Hawk"
165
+ LazyWrapper.new { raise GraphQL::ExecutionError.new("💥")}
165
166
  else
166
167
  ship = DATA.create_ship(inputs["shipName"], faction_id)
167
168
  faction = DATA["Faction"][faction_id]
@@ -183,9 +184,16 @@ module StarWars
183
184
 
184
185
 
185
186
  class LazyWrapper
186
- attr_reader :value
187
- def initialize(value)
188
- @value = value
187
+ def initialize(value = nil, &block)
188
+ if block_given?
189
+ @lazy_value = block
190
+ else
191
+ @value = value
192
+ end
193
+ end
194
+
195
+ def value
196
+ @resolved_value = @value || @lazy_value.call
189
197
  end
190
198
  end
191
199
 
@@ -210,6 +218,7 @@ module StarWars
210
218
  end
211
219
 
212
220
  field :node, GraphQL::Relay::Node.field
221
+ field :nodes, GraphQL::Relay::Node.plural_field
213
222
  end
214
223
 
215
224
  MutationType = GraphQL::ObjectType.define do
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.4.2
4
+ version: 1.4.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-01-23 00:00:00.000000000 Z
11
+ date: 2017-02-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: codeclimate-test-reporter