graphql 1.13.24 → 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.
- checksums.yaml +4 -4
- data/lib/graphql/analysis/ast/query_complexity.rb +1 -1
- data/lib/graphql/analysis/ast/query_depth.rb +0 -1
- data/lib/graphql/analysis/ast/visitor.rb +1 -1
- data/lib/graphql/analysis/ast.rb +0 -10
- data/lib/graphql/analysis.rb +0 -7
- data/lib/graphql/backtrace/table.rb +0 -18
- data/lib/graphql/backtrace/tracer.rb +1 -2
- data/lib/graphql/backtrace.rb +2 -8
- data/lib/graphql/dig.rb +1 -1
- data/lib/graphql/execution/errors.rb +1 -9
- data/lib/graphql/execution/interpreter/runtime.rb +6 -13
- data/lib/graphql/execution/interpreter.rb +0 -22
- data/lib/graphql/execution/lazy.rb +1 -1
- data/lib/graphql/execution/lookahead.rb +6 -13
- data/lib/graphql/execution/multiplex.rb +50 -107
- data/lib/graphql/execution.rb +11 -3
- data/lib/graphql/introspection/directive_type.rb +2 -2
- data/lib/graphql/introspection/dynamic_fields.rb +3 -8
- data/lib/graphql/introspection/entry_points.rb +2 -15
- data/lib/graphql/introspection/field_type.rb +1 -1
- data/lib/graphql/introspection/schema_type.rb +2 -2
- data/lib/graphql/introspection/type_type.rb +5 -5
- data/lib/graphql/language/document_from_schema_definition.rb +0 -17
- data/lib/graphql/language/nodes.rb +0 -3
- data/lib/graphql/pagination/connections.rb +2 -28
- data/lib/graphql/query/context.rb +1 -185
- data/lib/graphql/query/input_validation_result.rb +0 -9
- data/lib/graphql/query/literal_input.rb +8 -13
- data/lib/graphql/query/validation_pipeline.rb +6 -34
- data/lib/graphql/query/variable_validation_error.rb +2 -2
- data/lib/graphql/query/variables.rb +8 -31
- data/lib/graphql/query.rb +5 -34
- data/lib/graphql/railtie.rb +0 -104
- data/lib/graphql/relay/range_add.rb +0 -4
- data/lib/graphql/relay.rb +0 -15
- data/lib/graphql/schema/addition.rb +1 -8
- data/lib/graphql/schema/argument.rb +6 -28
- data/lib/graphql/schema/build_from_definition.rb +7 -9
- data/lib/graphql/schema/directive.rb +1 -22
- data/lib/graphql/schema/enum.rb +3 -19
- data/lib/graphql/schema/enum_value.rb +1 -23
- data/lib/graphql/schema/field.rb +22 -221
- data/lib/graphql/schema/input_object.rb +17 -65
- data/lib/graphql/schema/interface.rb +1 -30
- data/lib/graphql/schema/introspection_system.rb +3 -8
- data/lib/graphql/schema/late_bound_type.rb +2 -2
- data/lib/graphql/schema/list.rb +3 -24
- data/lib/graphql/schema/loader.rb +0 -1
- data/lib/graphql/schema/member/base_dsl_methods.rb +1 -6
- data/lib/graphql/schema/member/build_type.rb +4 -6
- data/lib/graphql/schema/member/has_arguments.rb +16 -20
- data/lib/graphql/schema/member/has_fields.rb +3 -3
- data/lib/graphql/schema/member/has_interfaces.rb +1 -13
- data/lib/graphql/schema/member/validates_input.rb +2 -2
- data/lib/graphql/schema/member.rb +0 -6
- data/lib/graphql/schema/mutation.rb +0 -9
- data/lib/graphql/schema/non_null.rb +3 -9
- data/lib/graphql/schema/object.rb +0 -40
- data/lib/graphql/schema/relay_classic_mutation.rb +17 -28
- data/lib/graphql/schema/scalar.rb +1 -16
- data/lib/graphql/schema/union.rb +0 -16
- data/lib/graphql/schema/warden.rb +3 -12
- data/lib/graphql/schema/wrapper.rb +0 -5
- data/lib/graphql/schema.rb +106 -945
- data/lib/graphql/static_validation/base_visitor.rb +4 -21
- data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +12 -12
- data/lib/graphql/static_validation/validator.rb +2 -24
- data/lib/graphql/static_validation.rb +0 -2
- data/lib/graphql/subscriptions/default_subscription_resolve_extension.rb +38 -1
- data/lib/graphql/subscriptions/event.rb +1 -1
- data/lib/graphql/subscriptions/instrumentation.rb +0 -51
- data/lib/graphql/subscriptions.rb +4 -13
- data/lib/graphql/tracing/data_dog_tracing.rb +16 -20
- data/lib/graphql/tracing/platform_tracing.rb +4 -32
- data/lib/graphql/tracing.rb +0 -1
- data/lib/graphql/types/relay/connection_behaviors.rb +2 -6
- data/lib/graphql/types/relay/default_relay.rb +0 -10
- data/lib/graphql/types/relay/node_behaviors.rb +5 -1
- data/lib/graphql/types/relay.rb +0 -2
- data/lib/graphql/types/string.rb +1 -1
- data/lib/graphql/version.rb +1 -1
- data/lib/graphql.rb +1 -66
- metadata +28 -164
- data/lib/graphql/analysis/analyze_query.rb +0 -98
- data/lib/graphql/analysis/field_usage.rb +0 -45
- data/lib/graphql/analysis/max_query_complexity.rb +0 -26
- data/lib/graphql/analysis/max_query_depth.rb +0 -26
- data/lib/graphql/analysis/query_complexity.rb +0 -88
- data/lib/graphql/analysis/query_depth.rb +0 -43
- data/lib/graphql/analysis/reducer_state.rb +0 -48
- data/lib/graphql/argument.rb +0 -131
- data/lib/graphql/authorization.rb +0 -82
- data/lib/graphql/backtrace/legacy_tracer.rb +0 -56
- data/lib/graphql/backwards_compatibility.rb +0 -61
- data/lib/graphql/base_type.rb +0 -232
- data/lib/graphql/boolean_type.rb +0 -2
- data/lib/graphql/compatibility/execution_specification/counter_schema.rb +0 -53
- data/lib/graphql/compatibility/execution_specification/specification_schema.rb +0 -200
- data/lib/graphql/compatibility/execution_specification.rb +0 -436
- data/lib/graphql/compatibility/lazy_execution_specification/lazy_schema.rb +0 -111
- data/lib/graphql/compatibility/lazy_execution_specification.rb +0 -215
- data/lib/graphql/compatibility/query_parser_specification/parse_error_specification.rb +0 -87
- data/lib/graphql/compatibility/query_parser_specification/query_assertions.rb +0 -79
- data/lib/graphql/compatibility/query_parser_specification.rb +0 -266
- data/lib/graphql/compatibility/schema_parser_specification.rb +0 -682
- data/lib/graphql/compatibility.rb +0 -5
- data/lib/graphql/define/assign_argument.rb +0 -12
- data/lib/graphql/define/assign_connection.rb +0 -13
- data/lib/graphql/define/assign_enum_value.rb +0 -18
- data/lib/graphql/define/assign_global_id_field.rb +0 -11
- data/lib/graphql/define/assign_mutation_function.rb +0 -34
- data/lib/graphql/define/assign_object_field.rb +0 -42
- data/lib/graphql/define/defined_object_proxy.rb +0 -53
- data/lib/graphql/define/instance_definable.rb +0 -255
- data/lib/graphql/define/no_definition_error.rb +0 -7
- data/lib/graphql/define/non_null_with_bang.rb +0 -16
- data/lib/graphql/define/type_definer.rb +0 -31
- data/lib/graphql/define.rb +0 -31
- data/lib/graphql/deprecated_dsl.rb +0 -55
- data/lib/graphql/directive/deprecated_directive.rb +0 -2
- data/lib/graphql/directive/include_directive.rb +0 -2
- data/lib/graphql/directive/skip_directive.rb +0 -2
- data/lib/graphql/directive.rb +0 -107
- data/lib/graphql/enum_type.rb +0 -133
- data/lib/graphql/execution/execute.rb +0 -333
- data/lib/graphql/execution/flatten.rb +0 -40
- data/lib/graphql/execution/typecast.rb +0 -50
- data/lib/graphql/field/resolve.rb +0 -59
- data/lib/graphql/field.rb +0 -226
- data/lib/graphql/float_type.rb +0 -2
- data/lib/graphql/function.rb +0 -128
- data/lib/graphql/id_type.rb +0 -2
- data/lib/graphql/input_object_type.rb +0 -138
- data/lib/graphql/int_type.rb +0 -2
- data/lib/graphql/interface_type.rb +0 -72
- data/lib/graphql/internal_representation/document.rb +0 -27
- data/lib/graphql/internal_representation/node.rb +0 -206
- data/lib/graphql/internal_representation/print.rb +0 -51
- data/lib/graphql/internal_representation/rewrite.rb +0 -184
- data/lib/graphql/internal_representation/scope.rb +0 -88
- data/lib/graphql/internal_representation/visit.rb +0 -36
- data/lib/graphql/internal_representation.rb +0 -7
- data/lib/graphql/list_type.rb +0 -80
- data/lib/graphql/non_null_type.rb +0 -71
- data/lib/graphql/object_type.rb +0 -130
- data/lib/graphql/query/arguments.rb +0 -189
- data/lib/graphql/query/arguments_cache.rb +0 -24
- data/lib/graphql/query/executor.rb +0 -52
- data/lib/graphql/query/serial_execution/field_resolution.rb +0 -92
- data/lib/graphql/query/serial_execution/operation_resolution.rb +0 -19
- data/lib/graphql/query/serial_execution/selection_resolution.rb +0 -23
- data/lib/graphql/query/serial_execution/value_resolution.rb +0 -87
- data/lib/graphql/query/serial_execution.rb +0 -40
- data/lib/graphql/relay/array_connection.rb +0 -83
- data/lib/graphql/relay/base_connection.rb +0 -189
- data/lib/graphql/relay/connection_instrumentation.rb +0 -54
- data/lib/graphql/relay/connection_resolve.rb +0 -43
- data/lib/graphql/relay/connection_type.rb +0 -54
- data/lib/graphql/relay/edge.rb +0 -27
- data/lib/graphql/relay/edge_type.rb +0 -19
- data/lib/graphql/relay/edges_instrumentation.rb +0 -39
- data/lib/graphql/relay/global_id_resolve.rb +0 -17
- data/lib/graphql/relay/mongo_relation_connection.rb +0 -50
- data/lib/graphql/relay/mutation/instrumentation.rb +0 -23
- data/lib/graphql/relay/mutation/resolve.rb +0 -56
- data/lib/graphql/relay/mutation/result.rb +0 -38
- data/lib/graphql/relay/mutation.rb +0 -106
- data/lib/graphql/relay/node.rb +0 -39
- data/lib/graphql/relay/page_info.rb +0 -7
- data/lib/graphql/relay/relation_connection.rb +0 -188
- data/lib/graphql/relay/type_extensions.rb +0 -32
- data/lib/graphql/scalar_type.rb +0 -91
- data/lib/graphql/schema/catchall_middleware.rb +0 -35
- data/lib/graphql/schema/default_parse_error.rb +0 -10
- data/lib/graphql/schema/default_type_error.rb +0 -17
- data/lib/graphql/schema/member/accepts_definition.rb +0 -164
- data/lib/graphql/schema/member/cached_graphql_definition.rb +0 -58
- data/lib/graphql/schema/member/instrumentation.rb +0 -131
- data/lib/graphql/schema/middleware_chain.rb +0 -82
- data/lib/graphql/schema/possible_types.rb +0 -44
- data/lib/graphql/schema/rescue_middleware.rb +0 -60
- data/lib/graphql/schema/timeout_middleware.rb +0 -88
- data/lib/graphql/schema/traversal.rb +0 -228
- data/lib/graphql/schema/validation.rb +0 -313
- data/lib/graphql/static_validation/default_visitor.rb +0 -15
- data/lib/graphql/static_validation/no_validate_visitor.rb +0 -10
- data/lib/graphql/string_type.rb +0 -2
- data/lib/graphql/subscriptions/subscription_root.rb +0 -76
- data/lib/graphql/tracing/skylight_tracing.rb +0 -70
- data/lib/graphql/types/relay/node_field.rb +0 -24
- data/lib/graphql/types/relay/nodes_field.rb +0 -43
- data/lib/graphql/union_type.rb +0 -115
- data/lib/graphql/upgrader/member.rb +0 -937
- 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
|