graphql 1.13.25 → 2.0.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.

Potentially problematic release.


This version of graphql might be problematic. Click here for more details.

Files changed (196) hide show
  1. checksums.yaml +4 -4
  2. data/lib/graphql/analysis/ast/query_complexity.rb +1 -1
  3. data/lib/graphql/analysis/ast/query_depth.rb +0 -1
  4. data/lib/graphql/analysis/ast/visitor.rb +1 -1
  5. data/lib/graphql/analysis/ast.rb +0 -10
  6. data/lib/graphql/analysis.rb +0 -7
  7. data/lib/graphql/backtrace/table.rb +0 -18
  8. data/lib/graphql/backtrace/tracer.rb +1 -2
  9. data/lib/graphql/backtrace.rb +2 -8
  10. data/lib/graphql/dig.rb +1 -1
  11. data/lib/graphql/execution/errors.rb +1 -9
  12. data/lib/graphql/execution/interpreter/runtime.rb +6 -13
  13. data/lib/graphql/execution/interpreter.rb +0 -22
  14. data/lib/graphql/execution/lazy.rb +1 -1
  15. data/lib/graphql/execution/lookahead.rb +6 -13
  16. data/lib/graphql/execution/multiplex.rb +50 -107
  17. data/lib/graphql/execution.rb +11 -3
  18. data/lib/graphql/introspection/directive_type.rb +2 -2
  19. data/lib/graphql/introspection/dynamic_fields.rb +3 -8
  20. data/lib/graphql/introspection/entry_points.rb +2 -15
  21. data/lib/graphql/introspection/field_type.rb +1 -1
  22. data/lib/graphql/introspection/schema_type.rb +2 -2
  23. data/lib/graphql/introspection/type_type.rb +5 -5
  24. data/lib/graphql/language/document_from_schema_definition.rb +0 -17
  25. data/lib/graphql/language/nodes.rb +0 -3
  26. data/lib/graphql/pagination/connections.rb +2 -28
  27. data/lib/graphql/pagination/relation_connection.rb +0 -2
  28. data/lib/graphql/query/context.rb +1 -185
  29. data/lib/graphql/query/input_validation_result.rb +0 -9
  30. data/lib/graphql/query/literal_input.rb +8 -13
  31. data/lib/graphql/query/validation_pipeline.rb +6 -34
  32. data/lib/graphql/query/variable_validation_error.rb +2 -2
  33. data/lib/graphql/query/variables.rb +8 -31
  34. data/lib/graphql/query.rb +5 -34
  35. data/lib/graphql/railtie.rb +0 -104
  36. data/lib/graphql/relay/range_add.rb +0 -4
  37. data/lib/graphql/relay.rb +0 -15
  38. data/lib/graphql/schema/addition.rb +1 -8
  39. data/lib/graphql/schema/argument.rb +6 -28
  40. data/lib/graphql/schema/build_from_definition.rb +7 -9
  41. data/lib/graphql/schema/directive.rb +1 -22
  42. data/lib/graphql/schema/enum.rb +3 -19
  43. data/lib/graphql/schema/enum_value.rb +1 -23
  44. data/lib/graphql/schema/field.rb +22 -221
  45. data/lib/graphql/schema/input_object.rb +17 -65
  46. data/lib/graphql/schema/interface.rb +1 -30
  47. data/lib/graphql/schema/introspection_system.rb +3 -8
  48. data/lib/graphql/schema/late_bound_type.rb +2 -2
  49. data/lib/graphql/schema/list.rb +3 -24
  50. data/lib/graphql/schema/loader.rb +0 -1
  51. data/lib/graphql/schema/member/base_dsl_methods.rb +1 -6
  52. data/lib/graphql/schema/member/build_type.rb +4 -6
  53. data/lib/graphql/schema/member/has_arguments.rb +16 -20
  54. data/lib/graphql/schema/member/has_fields.rb +3 -3
  55. data/lib/graphql/schema/member/has_interfaces.rb +1 -13
  56. data/lib/graphql/schema/member/validates_input.rb +2 -2
  57. data/lib/graphql/schema/member.rb +0 -6
  58. data/lib/graphql/schema/mutation.rb +0 -9
  59. data/lib/graphql/schema/non_null.rb +3 -9
  60. data/lib/graphql/schema/object.rb +0 -40
  61. data/lib/graphql/schema/relay_classic_mutation.rb +17 -28
  62. data/lib/graphql/schema/scalar.rb +1 -16
  63. data/lib/graphql/schema/union.rb +0 -16
  64. data/lib/graphql/schema/warden.rb +3 -12
  65. data/lib/graphql/schema/wrapper.rb +0 -5
  66. data/lib/graphql/schema.rb +106 -945
  67. data/lib/graphql/static_validation/base_visitor.rb +4 -21
  68. data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +12 -12
  69. data/lib/graphql/static_validation/validator.rb +2 -24
  70. data/lib/graphql/static_validation.rb +0 -2
  71. data/lib/graphql/subscriptions/default_subscription_resolve_extension.rb +38 -1
  72. data/lib/graphql/subscriptions/event.rb +1 -1
  73. data/lib/graphql/subscriptions/instrumentation.rb +0 -51
  74. data/lib/graphql/subscriptions.rb +4 -13
  75. data/lib/graphql/tracing/data_dog_tracing.rb +16 -20
  76. data/lib/graphql/tracing/platform_tracing.rb +4 -32
  77. data/lib/graphql/tracing.rb +0 -1
  78. data/lib/graphql/types/relay/connection_behaviors.rb +2 -6
  79. data/lib/graphql/types/relay/default_relay.rb +0 -10
  80. data/lib/graphql/types/relay/node_behaviors.rb +5 -1
  81. data/lib/graphql/types/relay.rb +0 -2
  82. data/lib/graphql/types/string.rb +1 -1
  83. data/lib/graphql/version.rb +1 -1
  84. data/lib/graphql.rb +1 -66
  85. metadata +28 -164
  86. data/lib/graphql/analysis/analyze_query.rb +0 -98
  87. data/lib/graphql/analysis/field_usage.rb +0 -45
  88. data/lib/graphql/analysis/max_query_complexity.rb +0 -26
  89. data/lib/graphql/analysis/max_query_depth.rb +0 -26
  90. data/lib/graphql/analysis/query_complexity.rb +0 -88
  91. data/lib/graphql/analysis/query_depth.rb +0 -43
  92. data/lib/graphql/analysis/reducer_state.rb +0 -48
  93. data/lib/graphql/argument.rb +0 -131
  94. data/lib/graphql/authorization.rb +0 -82
  95. data/lib/graphql/backtrace/legacy_tracer.rb +0 -56
  96. data/lib/graphql/backwards_compatibility.rb +0 -61
  97. data/lib/graphql/base_type.rb +0 -232
  98. data/lib/graphql/boolean_type.rb +0 -2
  99. data/lib/graphql/compatibility/execution_specification/counter_schema.rb +0 -53
  100. data/lib/graphql/compatibility/execution_specification/specification_schema.rb +0 -200
  101. data/lib/graphql/compatibility/execution_specification.rb +0 -436
  102. data/lib/graphql/compatibility/lazy_execution_specification/lazy_schema.rb +0 -111
  103. data/lib/graphql/compatibility/lazy_execution_specification.rb +0 -215
  104. data/lib/graphql/compatibility/query_parser_specification/parse_error_specification.rb +0 -87
  105. data/lib/graphql/compatibility/query_parser_specification/query_assertions.rb +0 -79
  106. data/lib/graphql/compatibility/query_parser_specification.rb +0 -266
  107. data/lib/graphql/compatibility/schema_parser_specification.rb +0 -682
  108. data/lib/graphql/compatibility.rb +0 -5
  109. data/lib/graphql/define/assign_argument.rb +0 -12
  110. data/lib/graphql/define/assign_connection.rb +0 -13
  111. data/lib/graphql/define/assign_enum_value.rb +0 -18
  112. data/lib/graphql/define/assign_global_id_field.rb +0 -11
  113. data/lib/graphql/define/assign_mutation_function.rb +0 -34
  114. data/lib/graphql/define/assign_object_field.rb +0 -42
  115. data/lib/graphql/define/defined_object_proxy.rb +0 -53
  116. data/lib/graphql/define/instance_definable.rb +0 -255
  117. data/lib/graphql/define/no_definition_error.rb +0 -7
  118. data/lib/graphql/define/non_null_with_bang.rb +0 -16
  119. data/lib/graphql/define/type_definer.rb +0 -31
  120. data/lib/graphql/define.rb +0 -31
  121. data/lib/graphql/deprecated_dsl.rb +0 -55
  122. data/lib/graphql/directive/deprecated_directive.rb +0 -2
  123. data/lib/graphql/directive/include_directive.rb +0 -2
  124. data/lib/graphql/directive/skip_directive.rb +0 -2
  125. data/lib/graphql/directive.rb +0 -107
  126. data/lib/graphql/enum_type.rb +0 -133
  127. data/lib/graphql/execution/execute.rb +0 -333
  128. data/lib/graphql/execution/flatten.rb +0 -40
  129. data/lib/graphql/execution/typecast.rb +0 -50
  130. data/lib/graphql/field/resolve.rb +0 -59
  131. data/lib/graphql/field.rb +0 -226
  132. data/lib/graphql/float_type.rb +0 -2
  133. data/lib/graphql/function.rb +0 -128
  134. data/lib/graphql/id_type.rb +0 -2
  135. data/lib/graphql/input_object_type.rb +0 -138
  136. data/lib/graphql/int_type.rb +0 -2
  137. data/lib/graphql/interface_type.rb +0 -72
  138. data/lib/graphql/internal_representation/document.rb +0 -27
  139. data/lib/graphql/internal_representation/node.rb +0 -206
  140. data/lib/graphql/internal_representation/print.rb +0 -51
  141. data/lib/graphql/internal_representation/rewrite.rb +0 -184
  142. data/lib/graphql/internal_representation/scope.rb +0 -88
  143. data/lib/graphql/internal_representation/visit.rb +0 -36
  144. data/lib/graphql/internal_representation.rb +0 -7
  145. data/lib/graphql/list_type.rb +0 -80
  146. data/lib/graphql/non_null_type.rb +0 -71
  147. data/lib/graphql/object_type.rb +0 -130
  148. data/lib/graphql/query/arguments.rb +0 -189
  149. data/lib/graphql/query/arguments_cache.rb +0 -24
  150. data/lib/graphql/query/executor.rb +0 -52
  151. data/lib/graphql/query/serial_execution/field_resolution.rb +0 -92
  152. data/lib/graphql/query/serial_execution/operation_resolution.rb +0 -19
  153. data/lib/graphql/query/serial_execution/selection_resolution.rb +0 -23
  154. data/lib/graphql/query/serial_execution/value_resolution.rb +0 -87
  155. data/lib/graphql/query/serial_execution.rb +0 -40
  156. data/lib/graphql/relay/array_connection.rb +0 -83
  157. data/lib/graphql/relay/base_connection.rb +0 -189
  158. data/lib/graphql/relay/connection_instrumentation.rb +0 -54
  159. data/lib/graphql/relay/connection_resolve.rb +0 -43
  160. data/lib/graphql/relay/connection_type.rb +0 -54
  161. data/lib/graphql/relay/edge.rb +0 -27
  162. data/lib/graphql/relay/edge_type.rb +0 -19
  163. data/lib/graphql/relay/edges_instrumentation.rb +0 -39
  164. data/lib/graphql/relay/global_id_resolve.rb +0 -17
  165. data/lib/graphql/relay/mongo_relation_connection.rb +0 -50
  166. data/lib/graphql/relay/mutation/instrumentation.rb +0 -23
  167. data/lib/graphql/relay/mutation/resolve.rb +0 -56
  168. data/lib/graphql/relay/mutation/result.rb +0 -38
  169. data/lib/graphql/relay/mutation.rb +0 -106
  170. data/lib/graphql/relay/node.rb +0 -39
  171. data/lib/graphql/relay/page_info.rb +0 -7
  172. data/lib/graphql/relay/relation_connection.rb +0 -188
  173. data/lib/graphql/relay/type_extensions.rb +0 -32
  174. data/lib/graphql/scalar_type.rb +0 -91
  175. data/lib/graphql/schema/catchall_middleware.rb +0 -35
  176. data/lib/graphql/schema/default_parse_error.rb +0 -10
  177. data/lib/graphql/schema/default_type_error.rb +0 -17
  178. data/lib/graphql/schema/member/accepts_definition.rb +0 -164
  179. data/lib/graphql/schema/member/cached_graphql_definition.rb +0 -58
  180. data/lib/graphql/schema/member/instrumentation.rb +0 -131
  181. data/lib/graphql/schema/middleware_chain.rb +0 -82
  182. data/lib/graphql/schema/possible_types.rb +0 -44
  183. data/lib/graphql/schema/rescue_middleware.rb +0 -60
  184. data/lib/graphql/schema/timeout_middleware.rb +0 -88
  185. data/lib/graphql/schema/traversal.rb +0 -228
  186. data/lib/graphql/schema/validation.rb +0 -313
  187. data/lib/graphql/static_validation/default_visitor.rb +0 -15
  188. data/lib/graphql/static_validation/no_validate_visitor.rb +0 -10
  189. data/lib/graphql/string_type.rb +0 -2
  190. data/lib/graphql/subscriptions/subscription_root.rb +0 -76
  191. data/lib/graphql/tracing/skylight_tracing.rb +0 -70
  192. data/lib/graphql/types/relay/node_field.rb +0 -24
  193. data/lib/graphql/types/relay/nodes_field.rb +0 -43
  194. data/lib/graphql/union_type.rb +0 -115
  195. data/lib/graphql/upgrader/member.rb +0 -937
  196. data/lib/graphql/upgrader/schema.rb +0 -38
@@ -1,436 +0,0 @@
1
- # frozen_string_literal: true
2
- require "graphql/compatibility/execution_specification/counter_schema"
3
- require "graphql/compatibility/execution_specification/specification_schema"
4
-
5
- module GraphQL
6
- module Compatibility
7
- # Test an execution strategy. This spec is not meant as a development aid.
8
- # Rather, when the strategy _works_, run it here to see if it has any differences
9
- # from the built-in strategy.
10
- #
11
- # - Custom scalar input / output
12
- # - Null propagation
13
- # - Query-level masking
14
- # - Directive support
15
- # - Typecasting
16
- # - Error handling (raise / return GraphQL::ExecutionError)
17
- # - Provides Irep & AST node to resolve fn
18
- # - Skipping fields
19
- #
20
- # Some things are explicitly _not_ tested here, because they're handled
21
- # by other parts of the system:
22
- #
23
- # - Schema definition (including types and fields)
24
- # - Parsing & parse errors
25
- # - AST -> IRep transformation (eg, fragment merging)
26
- # - Query validation and analysis
27
- # - Relay features
28
- #
29
- module ExecutionSpecification
30
- # Make a minitest suite for this execution strategy, making sure it
31
- # fulfills all the requirements of this library.
32
- # @param execution_strategy [<#new, #execute>] An execution strategy class
33
- # @return [Class<Minitest::Test>] A test suite for this execution strategy
34
- def self.build_suite(execution_strategy)
35
- GraphQL::Deprecation.warn "#{self} will be removed from GraphQL-Ruby 2.0. There is no replacement, please open an issue on GitHub if you need support."
36
- Class.new(Minitest::Test) do
37
- class << self
38
- attr_accessor :counter_schema, :specification_schema
39
- end
40
-
41
- self.specification_schema = SpecificationSchema.build(execution_strategy)
42
- self.counter_schema = CounterSchema.build(execution_strategy)
43
-
44
- def execute_query(query_string, **kwargs)
45
- kwargs[:root_value] = SpecificationSchema::DATA
46
- self.class.specification_schema.execute(query_string, **kwargs)
47
- end
48
-
49
- def test_it_fetches_data
50
- query_string = %|
51
- query getData($nodeId: ID = "1001") {
52
- flh: node(id: $nodeId) {
53
- __typename
54
- ... on Person {
55
- name @include(if: true)
56
- skippedName: name @skip(if: true)
57
- birthdate
58
- age(on: 1477660133)
59
- }
60
-
61
- ... on NamedEntity {
62
- ne_tn: __typename
63
- ne_n: name
64
- }
65
-
66
- ... on Organization {
67
- org_n: name
68
- }
69
- }
70
- }
71
- |
72
- res = execute_query(query_string)
73
-
74
- assert_equal nil, res["errors"], "It doesn't have an errors key"
75
-
76
- flh = res["data"]["flh"]
77
- assert_equal "Fannie Lou Hamer", flh["name"], "It returns values"
78
- assert_equal Time.new(1917, 10, 6).to_i, flh["birthdate"], "It returns custom scalars"
79
- assert_equal 99, flh["age"], "It runs resolve functions"
80
- assert_equal "Person", flh["__typename"], "It serves __typename"
81
- assert_equal "Person", flh["ne_tn"], "It serves __typename on interfaces"
82
- assert_equal "Fannie Lou Hamer", flh["ne_n"], "It serves interface fields"
83
- assert_equal false, flh.key?("skippedName"), "It obeys @skip"
84
- assert_equal false, flh.key?("org_n"), "It doesn't apply other type fields"
85
- end
86
-
87
- def test_it_iterates_over_each
88
- query_string = %|
89
- query getData($nodeId: ID = "1002") {
90
- node(id: $nodeId) {
91
- ... on Person {
92
- organizations { name }
93
- }
94
- }
95
- }
96
- |
97
-
98
- res = execute_query(query_string)
99
- assert_equal ["SNCC"], res["data"]["node"]["organizations"].map { |o| o["name"] }
100
- end
101
-
102
- def test_it_skips_skipped_fields
103
- query_str = <<-GRAPHQL
104
- {
105
- o3001: organization(id: "3001") { name }
106
- o2001: organization(id: "2001") { name }
107
- }
108
- GRAPHQL
109
-
110
- res = execute_query(query_str)
111
- assert_equal ["o2001"], res["data"].keys
112
- assert_equal false, res.key?("errors")
113
- end
114
-
115
- def test_it_propagates_nulls_to_field
116
- query_string = %|
117
- query getOrg($id: ID = "2001"){
118
- failure: node(id: $id) {
119
- ... on Organization {
120
- name
121
- leader { name }
122
- }
123
- }
124
- success: node(id: $id) {
125
- ... on Organization {
126
- name
127
- }
128
- }
129
- }
130
- |
131
- res = execute_query(query_string)
132
-
133
- failure = res["data"]["failure"]
134
- success = res["data"]["success"]
135
-
136
- assert_equal nil, failure, "It propagates nulls to the next nullable field"
137
- assert_equal({"name" => "SNCC"}, success, "It serves the same object if no invalid null is encountered")
138
- assert_equal 1, res["errors"].length , "It returns an error for the invalid null"
139
- end
140
-
141
- def test_it_propages_nulls_to_operation
142
- query_string = %|
143
- {
144
- foundOrg: organization(id: "2001") {
145
- name
146
- }
147
- organization(id: "2999") {
148
- name
149
- }
150
- }
151
- |
152
-
153
- res = execute_query(query_string)
154
- assert_equal nil, res["data"]
155
- assert_equal 1, res["errors"].length
156
- end
157
-
158
- def test_it_exposes_raised_and_returned_user_execution_errors
159
- query_string = %|
160
- {
161
- organization(id: "2001") {
162
- name
163
- returnedError
164
- raisedError
165
- }
166
- organizations {
167
- returnedError
168
- raisedError
169
- }
170
- }
171
- |
172
-
173
- res = execute_query(query_string)
174
-
175
- assert_equal "SNCC", res["data"]["organization"]["name"], "It runs the rest of the query"
176
-
177
- expected_errors = [
178
- {
179
- "message"=>"This error was returned",
180
- "locations"=>[{"line"=>5, "column"=>19}],
181
- "path"=>["organization", "returnedError"]
182
- },
183
- {
184
- "message"=>"This error was raised",
185
- "locations"=>[{"line"=>6, "column"=>19}],
186
- "path"=>["organization", "raisedError"]
187
- },
188
- {
189
- "message"=>"This error was raised",
190
- "locations"=>[{"line"=>10, "column"=>19}],
191
- "path"=>["organizations", 0, "raisedError"]
192
- },
193
- {
194
- "message"=>"This error was raised",
195
- "locations"=>[{"line"=>10, "column"=>19}],
196
- "path"=>["organizations", 1, "raisedError"]
197
- },
198
- {
199
- "message"=>"This error was returned",
200
- "locations"=>[{"line"=>9, "column"=>19}],
201
- "path"=>["organizations", 0, "returnedError"]
202
- },
203
- {
204
- "message"=>"This error was returned",
205
- "locations"=>[{"line"=>9, "column"=>19}],
206
- "path"=>["organizations", 1, "returnedError"]
207
- },
208
- ]
209
-
210
- expected_errors.each do |expected_err|
211
- assert_includes res["errors"], expected_err
212
- end
213
- end
214
-
215
- def test_it_applies_masking
216
- no_org = ->(member, ctx) { member.name == "Organization" }
217
- query_string = %|
218
- {
219
- node(id: "2001") {
220
- __typename
221
- }
222
- }|
223
-
224
- err = assert_raises(GraphQL::UnresolvedTypeError) {
225
- execute_query(query_string, except: no_org)
226
- }
227
-
228
- query_string = %|
229
- {
230
- organization(id: "2001") { name }
231
- }|
232
-
233
- res = execute_query(query_string, except: no_org)
234
-
235
- assert_equal nil, res["data"]
236
- assert_equal 1, res["errors"].length
237
- assert_equal "SNCC", err.value.name
238
- assert_equal GraphQL::Relay::Node.interface, err.field.type
239
- assert_equal 1, err.possible_types.length
240
- assert_equal "Organization", err.resolved_type.name
241
- assert_equal "Query", err.parent_type.name
242
-
243
- query_string = %|
244
- {
245
- __type(name: "Organization") { name }
246
- }|
247
-
248
- res = execute_query(query_string, except: no_org)
249
-
250
- assert_equal nil, res["data"]["__type"]
251
- assert_equal nil, res["errors"]
252
- end
253
-
254
- def test_it_provides_nodes_to_resolve
255
- query_string = %|
256
- {
257
- organization(id: "2001") {
258
- name
259
- nodePresence
260
- }
261
- }|
262
-
263
- res = execute_query(query_string)
264
- assert_equal "SNCC", res["data"]["organization"]["name"]
265
- assert_equal [true, true, false], res["data"]["organization"]["nodePresence"]
266
- end
267
-
268
- def test_it_runs_the_introspection_query
269
- execute_query(GraphQL::Introspection::INTROSPECTION_QUERY)
270
- end
271
-
272
- def test_it_propagates_deeply_nested_nulls
273
- query_string = %|
274
- {
275
- node(id: "1001") {
276
- ... on Person {
277
- name
278
- first_organization {
279
- leader {
280
- name
281
- }
282
- }
283
- }
284
- }
285
- }
286
- |
287
- res = execute_query(query_string)
288
- assert_equal nil, res["data"]["node"]
289
- assert_equal 1, res["errors"].length
290
- end
291
-
292
- def test_it_doesnt_add_errors_for_invalid_nulls_from_execution_errors
293
- query_string = %|
294
- query getOrg($id: ID = "2001"){
295
- failure: node(id: $id) {
296
- ... on Organization {
297
- name
298
- leader { name }
299
- }
300
- }
301
- }
302
- |
303
- res = execute_query(query_string, context: {return_error: true})
304
- error_messages = res["errors"].map { |e| e["message"] }
305
- assert_equal ["Error on Nullable"], error_messages
306
- end
307
-
308
- def test_it_only_resolves_fields_once_on_typed_fragments
309
- res = self.class.counter_schema.execute("
310
- {
311
- counter { count }
312
- ... on HasCounter {
313
- counter { count }
314
- }
315
- }
316
- ")
317
-
318
- expected_data = {
319
- "counter" => { "count" => 1 }
320
- }
321
- assert_equal expected_data, res["data"]
322
- assert_equal 1, self.class.counter_schema.metadata[:count]
323
-
324
- # Deep typed children are correctly distinguished:
325
- res = self.class.counter_schema.execute("
326
- {
327
- counter {
328
- ... on Counter {
329
- counter { count }
330
- }
331
- ... on AltCounter {
332
- counter { count, t: __typename }
333
- }
334
- }
335
- }
336
- ")
337
-
338
- expected_data = {
339
- "counter" => { "counter" => { "count" => 2 } }
340
- }
341
- assert_equal expected_data, res["data"]
342
- end
343
-
344
- def test_it_runs_middleware
345
- log = []
346
- query_string = %|
347
- {
348
- node(id: "2001") {
349
- __typename
350
- }
351
- }|
352
- execute_query(query_string, context: {middleware_log: log})
353
- assert_equal ["node", "__typename"], log
354
- end
355
-
356
- def test_it_uses_type_error_hooks_for_invalid_nulls
357
- log = []
358
- query_string = %|
359
- {
360
- node(id: "1001") {
361
- ... on Person {
362
- name
363
- first_organization {
364
- leader {
365
- name
366
- }
367
- }
368
- }
369
- }
370
- }|
371
-
372
- res = execute_query(query_string, context: { type_errors: log })
373
- assert_equal nil, res["data"]["node"]
374
- assert_equal [nil], log
375
- end
376
-
377
- def test_it_uses_type_error_hooks_for_failed_type_resolution
378
- log = []
379
- query_string = %|
380
- {
381
- node(id: "2003") {
382
- __typename
383
- }
384
- }|
385
-
386
- assert_raises(GraphQL::UnresolvedTypeError) {
387
- execute_query(query_string, context: { type_errors: log })
388
- }
389
-
390
- assert_equal [SpecificationSchema::BOGUS_NODE], log
391
- end
392
-
393
- def test_it_treats_failed_type_resolution_like_nil
394
- log = []
395
- ctx = { type_errors: log, gobble: true }
396
- query_string = %|
397
- {
398
- node(id: "2003") {
399
- __typename
400
- }
401
- }|
402
-
403
- res = execute_query(query_string, context: ctx)
404
-
405
- assert_equal nil, res["data"]["node"]
406
- assert_equal false, res.key?("errors")
407
- assert_equal [SpecificationSchema::BOGUS_NODE], log
408
-
409
- query_string_2 = %|
410
- {
411
- requiredNode(id: "2003") {
412
- __typename
413
- }
414
- }|
415
-
416
- res = execute_query(query_string_2, context: ctx)
417
-
418
- assert_equal nil, res["data"]
419
- assert_equal false, res.key?("errors")
420
- assert_equal [SpecificationSchema::BOGUS_NODE, SpecificationSchema::BOGUS_NODE], log
421
- end
422
-
423
- def test_it_skips_connections
424
- query_type = GraphQL::ObjectType.define do
425
- name "Query"
426
- connection :skipped, types[query_type], resolve: ->(o,a,c) { c.skip }
427
- end
428
- schema = GraphQL::Schema.define(query: query_type)
429
- res = schema.execute("{ skipped { __typename } }")
430
- assert_equal({"data" => nil}, res)
431
- end
432
- end
433
- end
434
- end
435
- end
436
- end
@@ -1,111 +0,0 @@
1
- # frozen_string_literal: true
2
- module GraphQL
3
- module Compatibility
4
- module LazyExecutionSpecification
5
- module LazySchema
6
- class LazyPush
7
- attr_reader :value
8
- def initialize(ctx, value)
9
- if value == 13
10
- @value = nil
11
- elsif value == 14
12
- @value = GraphQL::ExecutionError.new("oops!")
13
- elsif value == 15
14
- @skipped = true
15
- @value = ctx.skip
16
- else
17
- @value = value
18
- end
19
- @context = ctx
20
- pushes = @context[:lazy_pushes] ||= []
21
- if !@skipped
22
- pushes << @value
23
- end
24
- end
25
-
26
- def push
27
- if @skipped
28
- @value
29
- else
30
- if @context[:lazy_pushes].include?(@value)
31
- @context[:lazy_instrumentation] && @context[:lazy_instrumentation] << "PUSH"
32
- @context[:pushes] << @context[:lazy_pushes]
33
- @context[:lazy_pushes] = []
34
- end
35
- # Something that _behaves_ like this object, but isn't registered lazy
36
- OpenStruct.new(value: @value)
37
- end
38
- end
39
- end
40
-
41
- class LazyPushCollection
42
- def initialize(ctx, values)
43
- @ctx = ctx
44
- @values = values
45
- end
46
-
47
- def push
48
- @values.map { |v| LazyPush.new(@ctx, v) }
49
- end
50
-
51
- def value
52
- @values
53
- end
54
- end
55
-
56
- module LazyInstrumentation
57
- def self.instrument(type, field)
58
- prev_lazy_resolve = field.lazy_resolve_proc
59
- field.redefine {
60
- lazy_resolve ->(o, a, c) {
61
- result = prev_lazy_resolve.call(o, a, c)
62
- c[:lazy_instrumentation] && c[:lazy_instrumentation].push("#{type.name}.#{field.name}: #{o.value}")
63
- result
64
- }
65
- }
66
- end
67
- end
68
-
69
- def self.build(execution_strategy)
70
- lazy_push_type = GraphQL::ObjectType.define do
71
- name "LazyPush"
72
- field :value, !types.Int
73
- field :push, !lazy_push_type do
74
- argument :value, types.Int
75
- resolve ->(o, a, c) {
76
- LazyPush.new(c, a[:value])
77
- }
78
- end
79
- end
80
-
81
- query_type = GraphQL::ObjectType.define do
82
- name "Query"
83
- field :push, !lazy_push_type do
84
- argument :value, types.Int
85
- resolve ->(o, a, c) {
86
- LazyPush.new(c, a[:value])
87
- }
88
- end
89
-
90
- connection :pushes, lazy_push_type.connection_type do
91
- argument :values, types[types.Int], method_access: false
92
- resolve ->(o, a, c) {
93
- LazyPushCollection.new(c, a[:values])
94
- }
95
- end
96
- end
97
-
98
- GraphQL::Schema.define do
99
- query(query_type)
100
- mutation(query_type)
101
- query_execution_strategy(execution_strategy)
102
- mutation_execution_strategy(execution_strategy)
103
- lazy_resolve(LazyPush, :push)
104
- lazy_resolve(LazyPushCollection, :push)
105
- instrument(:field, LazyInstrumentation)
106
- end
107
- end
108
- end
109
- end
110
- end
111
- end