graphql 1.4.2 → 1.4.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: 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