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.
- 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/pagination/relation_connection.rb +0 -2
- 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,215 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
require "graphql/compatibility/lazy_execution_specification/lazy_schema"
|
3
|
-
|
4
|
-
module GraphQL
|
5
|
-
module Compatibility
|
6
|
-
module LazyExecutionSpecification
|
7
|
-
# @param execution_strategy [<#new, #execute>] An execution strategy class
|
8
|
-
# @return [Class<Minitest::Test>] A test suite for this execution strategy
|
9
|
-
def self.build_suite(execution_strategy)
|
10
|
-
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."
|
11
|
-
|
12
|
-
Class.new(Minitest::Test) do
|
13
|
-
class << self
|
14
|
-
attr_accessor :lazy_schema
|
15
|
-
end
|
16
|
-
|
17
|
-
self.lazy_schema = LazySchema.build(execution_strategy)
|
18
|
-
|
19
|
-
def test_it_resolves_lazy_values
|
20
|
-
pushes = []
|
21
|
-
query_str = %|
|
22
|
-
{
|
23
|
-
p1: push(value: 1) {
|
24
|
-
value
|
25
|
-
}
|
26
|
-
p2: push(value: 2) {
|
27
|
-
push(value: 3) {
|
28
|
-
value
|
29
|
-
push(value: 21) {
|
30
|
-
value
|
31
|
-
}
|
32
|
-
}
|
33
|
-
}
|
34
|
-
p3: push(value: 4) {
|
35
|
-
push(value: 5) {
|
36
|
-
value
|
37
|
-
push(value: 22) {
|
38
|
-
value
|
39
|
-
}
|
40
|
-
}
|
41
|
-
}
|
42
|
-
}
|
43
|
-
|
|
44
|
-
res = self.class.lazy_schema.execute(query_str, context: {pushes: pushes})
|
45
|
-
|
46
|
-
expected_data = {
|
47
|
-
"p1"=>{"value"=>1},
|
48
|
-
"p2"=>{"push"=>{"value"=>3, "push"=>{"value"=>21}}},
|
49
|
-
"p3"=>{"push"=>{"value"=>5, "push"=>{"value"=>22}}},
|
50
|
-
}
|
51
|
-
assert_equal expected_data, res["data"]
|
52
|
-
|
53
|
-
expected_pushes = [
|
54
|
-
[1,2,4], # first level
|
55
|
-
[3,5], # second level
|
56
|
-
[21, 22],
|
57
|
-
]
|
58
|
-
assert_equal expected_pushes, pushes
|
59
|
-
end
|
60
|
-
|
61
|
-
def test_it_maintains_path
|
62
|
-
query_str = %|
|
63
|
-
{
|
64
|
-
push(value: 2) {
|
65
|
-
push(value: 3) {
|
66
|
-
fail1: push(value: 14) {
|
67
|
-
value
|
68
|
-
}
|
69
|
-
fail2: push(value: 14) {
|
70
|
-
value
|
71
|
-
}
|
72
|
-
}
|
73
|
-
}
|
74
|
-
}
|
75
|
-
|
|
76
|
-
res = self.class.lazy_schema.execute(query_str, context: {pushes: []})
|
77
|
-
assert_equal nil, res["data"]
|
78
|
-
# The first fail causes the second field to never resolve
|
79
|
-
assert_equal 1, res["errors"].length
|
80
|
-
assert_equal ["push", "push", "fail1", "value"], res["errors"][0]["path"]
|
81
|
-
end
|
82
|
-
|
83
|
-
def test_it_resolves_mutation_values_eagerly
|
84
|
-
pushes = []
|
85
|
-
query_str = %|
|
86
|
-
mutation {
|
87
|
-
p1: push(value: 1) {
|
88
|
-
value
|
89
|
-
}
|
90
|
-
p2: push(value: 2) {
|
91
|
-
push(value: 3) {
|
92
|
-
value
|
93
|
-
}
|
94
|
-
}
|
95
|
-
p3: push(value: 4) {
|
96
|
-
p5: push(value: 5) {
|
97
|
-
value
|
98
|
-
}
|
99
|
-
p6: push(value: 6) {
|
100
|
-
value
|
101
|
-
}
|
102
|
-
}
|
103
|
-
}
|
104
|
-
|
|
105
|
-
res = self.class.lazy_schema.execute(query_str, context: {pushes: pushes})
|
106
|
-
|
107
|
-
expected_data = {
|
108
|
-
"p1"=>{"value"=>1},
|
109
|
-
"p2"=>{"push"=>{"value"=>3}},
|
110
|
-
"p3"=>{"p5"=>{"value"=>5},"p6"=>{"value"=>6}},
|
111
|
-
}
|
112
|
-
assert_equal expected_data, res["data"]
|
113
|
-
|
114
|
-
expected_pushes = [
|
115
|
-
[1], # first operation
|
116
|
-
[2], [3], # second operation
|
117
|
-
[4], [5, 6], # third operation
|
118
|
-
]
|
119
|
-
assert_equal expected_pushes, pushes
|
120
|
-
end
|
121
|
-
|
122
|
-
def test_it_resolves_lazy_connections
|
123
|
-
pushes = []
|
124
|
-
query_str = %|
|
125
|
-
{
|
126
|
-
pushes(values: [1,2,3]) {
|
127
|
-
edges {
|
128
|
-
node {
|
129
|
-
value
|
130
|
-
push(value: 4) {
|
131
|
-
value
|
132
|
-
}
|
133
|
-
}
|
134
|
-
}
|
135
|
-
}
|
136
|
-
}
|
137
|
-
|
|
138
|
-
res = self.class.lazy_schema.execute(query_str, context: {pushes: pushes})
|
139
|
-
|
140
|
-
expected_edges = [
|
141
|
-
{"node"=>{"value"=>1, "push"=>{"value"=>4}}},
|
142
|
-
{"node"=>{"value"=>2, "push"=>{"value"=>4}}},
|
143
|
-
{"node"=>{"value"=>3, "push"=>{"value"=>4}}},
|
144
|
-
]
|
145
|
-
assert_equal expected_edges, res["data"]["pushes"]["edges"]
|
146
|
-
assert_equal [[1, 2, 3], [4, 4, 4]], pushes
|
147
|
-
end
|
148
|
-
|
149
|
-
def test_it_calls_lazy_resolve_instrumentation
|
150
|
-
query_str = %|
|
151
|
-
{
|
152
|
-
p1: push(value: 1) {
|
153
|
-
value
|
154
|
-
}
|
155
|
-
p2: push(value: 2) {
|
156
|
-
push(value: 3) {
|
157
|
-
value
|
158
|
-
}
|
159
|
-
}
|
160
|
-
pushes(values: [1,2,3]) {
|
161
|
-
edges {
|
162
|
-
node {
|
163
|
-
value
|
164
|
-
push(value: 4) {
|
165
|
-
value
|
166
|
-
}
|
167
|
-
}
|
168
|
-
}
|
169
|
-
}
|
170
|
-
}
|
171
|
-
|
|
172
|
-
|
173
|
-
log = []
|
174
|
-
self.class.lazy_schema.execute(query_str, context: {lazy_instrumentation: log, pushes: []})
|
175
|
-
expected_log = [
|
176
|
-
"PUSH",
|
177
|
-
"Query.push: 1",
|
178
|
-
"Query.push: 2",
|
179
|
-
"Query.pushes: [1, 2, 3]",
|
180
|
-
"PUSH",
|
181
|
-
"LazyPush.push: 3",
|
182
|
-
"LazyPushEdge.node: 1",
|
183
|
-
"LazyPushEdge.node: 2",
|
184
|
-
"LazyPushEdge.node: 3",
|
185
|
-
"PUSH",
|
186
|
-
"LazyPush.push: 4",
|
187
|
-
"LazyPush.push: 4",
|
188
|
-
"LazyPush.push: 4",
|
189
|
-
]
|
190
|
-
assert_equal expected_log, log
|
191
|
-
end
|
192
|
-
|
193
|
-
def test_it_skips_ctx_skip
|
194
|
-
query_string = <<-GRAPHQL
|
195
|
-
{
|
196
|
-
p0: push(value: 15) { value }
|
197
|
-
p1: push(value: 1) { value }
|
198
|
-
p2: push(value: 2) {
|
199
|
-
value
|
200
|
-
p3: push(value: 15) {
|
201
|
-
value
|
202
|
-
}
|
203
|
-
}
|
204
|
-
}
|
205
|
-
GRAPHQL
|
206
|
-
pushes = []
|
207
|
-
res = self.class.lazy_schema.execute(query_string, context: {pushes: pushes})
|
208
|
-
assert_equal [[1,2]], pushes
|
209
|
-
assert_equal({"data"=>{"p1"=>{"value"=>1}, "p2"=>{"value"=>2}}}, res)
|
210
|
-
end
|
211
|
-
end
|
212
|
-
end
|
213
|
-
end
|
214
|
-
end
|
215
|
-
end
|
@@ -1,87 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
module GraphQL
|
3
|
-
module Compatibility
|
4
|
-
module QueryParserSpecification
|
5
|
-
module ParseErrorSpecification
|
6
|
-
def assert_raises_parse_error(query_string)
|
7
|
-
assert_raises(GraphQL::ParseError) {
|
8
|
-
parse(query_string)
|
9
|
-
}
|
10
|
-
end
|
11
|
-
|
12
|
-
def test_it_includes_line_and_column
|
13
|
-
err = assert_raises_parse_error("
|
14
|
-
query getCoupons {
|
15
|
-
allCoupons: {data{id}}
|
16
|
-
}
|
17
|
-
")
|
18
|
-
|
19
|
-
assert_includes(err.message, '{')
|
20
|
-
assert_equal(3, err.line)
|
21
|
-
assert_equal(27, err.col)
|
22
|
-
end
|
23
|
-
|
24
|
-
def test_it_rejects_unterminated_strings
|
25
|
-
assert_raises_parse_error('{ " }')
|
26
|
-
assert_raises_parse_error(%|{ "\n" }|)
|
27
|
-
end
|
28
|
-
|
29
|
-
def test_it_rejects_unexpected_ends
|
30
|
-
assert_raises_parse_error("query { stuff { thing }")
|
31
|
-
end
|
32
|
-
|
33
|
-
def assert_rejects_character(char)
|
34
|
-
err = assert_raises_parse_error("{ field#{char} }")
|
35
|
-
expected_char = char.inspect.gsub('"', '').downcase
|
36
|
-
msg_downcase = err.message.downcase
|
37
|
-
# Case-insensitive for UTF-8 printing
|
38
|
-
assert_includes(msg_downcase, expected_char, "The message includes the invalid character")
|
39
|
-
end
|
40
|
-
|
41
|
-
def test_it_rejects_invalid_characters
|
42
|
-
assert_rejects_character(";")
|
43
|
-
assert_rejects_character("\a")
|
44
|
-
assert_rejects_character("\xef")
|
45
|
-
assert_rejects_character("\v")
|
46
|
-
assert_rejects_character("\f")
|
47
|
-
assert_rejects_character("\xa0")
|
48
|
-
end
|
49
|
-
|
50
|
-
def test_it_rejects_bad_unicode
|
51
|
-
assert_raises_parse_error(%|{ field(arg:"\\x") }|)
|
52
|
-
assert_raises_parse_error(%|{ field(arg:"\\u1") }|)
|
53
|
-
assert_raises_parse_error(%|{ field(arg:"\\u0XX1") }|)
|
54
|
-
assert_raises_parse_error(%|{ field(arg:"\\uXXXX") }|)
|
55
|
-
assert_raises_parse_error(%|{ field(arg:"\\uFXXX") }|)
|
56
|
-
assert_raises_parse_error(%|{ field(arg:"\\uXXXF") }|)
|
57
|
-
end
|
58
|
-
|
59
|
-
def test_it_rejects_empty_inline_fragments
|
60
|
-
assert_raises_parse_error("
|
61
|
-
query {
|
62
|
-
viewer {
|
63
|
-
login {
|
64
|
-
... on String {
|
65
|
-
|
66
|
-
}
|
67
|
-
}
|
68
|
-
}
|
69
|
-
}
|
70
|
-
")
|
71
|
-
end
|
72
|
-
|
73
|
-
def test_it_rejects_blank_queries
|
74
|
-
assert_raises_parse_error("")
|
75
|
-
assert_raises_parse_error(" ")
|
76
|
-
assert_raises_parse_error("\t \t")
|
77
|
-
assert_raises_parse_error(" # comment ")
|
78
|
-
end
|
79
|
-
|
80
|
-
def test_it_restricts_on
|
81
|
-
assert_raises_parse_error("{ ...on }")
|
82
|
-
assert_raises_parse_error("fragment on on Type { field }")
|
83
|
-
end
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|
@@ -1,79 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
module GraphQL
|
3
|
-
module Compatibility
|
4
|
-
module QueryParserSpecification
|
5
|
-
module QueryAssertions
|
6
|
-
def assert_valid_query(query)
|
7
|
-
assert query.is_a?(GraphQL::Language::Nodes::OperationDefinition)
|
8
|
-
assert_equal "getStuff", query.name
|
9
|
-
assert_equal "query", query.operation_type
|
10
|
-
assert_equal 2, query.variables.length
|
11
|
-
assert_equal 4, query.selections.length
|
12
|
-
assert_equal 1, query.directives.length
|
13
|
-
assert_equal [2, 13], [query.line, query.col]
|
14
|
-
end
|
15
|
-
|
16
|
-
def assert_valid_fragment(fragment_def)
|
17
|
-
assert fragment_def.is_a?(GraphQL::Language::Nodes::FragmentDefinition)
|
18
|
-
assert_equal "moreNestedFields", fragment_def.name
|
19
|
-
assert_equal 1, fragment_def.selections.length
|
20
|
-
assert_equal "NestedType", fragment_def.type.name
|
21
|
-
assert_equal 1, fragment_def.directives.length
|
22
|
-
assert_equal [20, 13], fragment_def.position
|
23
|
-
end
|
24
|
-
|
25
|
-
def assert_valid_variable(variable)
|
26
|
-
assert_equal "someVar", variable.name
|
27
|
-
assert_equal "Int", variable.type.name
|
28
|
-
assert_equal 1, variable.default_value
|
29
|
-
assert_equal [2, 28], variable.position
|
30
|
-
end
|
31
|
-
|
32
|
-
def assert_valid_field(field)
|
33
|
-
assert_equal "someField", field.name
|
34
|
-
assert_equal "myField", field.alias
|
35
|
-
assert_equal 2, field.directives.length
|
36
|
-
assert_equal 2, field.arguments.length
|
37
|
-
assert_equal 0, field.selections.length
|
38
|
-
assert_equal [3, 15], field.position
|
39
|
-
end
|
40
|
-
|
41
|
-
def assert_valid_literal_argument(argument)
|
42
|
-
assert_equal "ok", argument.name
|
43
|
-
assert_equal 1.4, argument.value
|
44
|
-
end
|
45
|
-
|
46
|
-
def assert_valid_variable_argument(argument)
|
47
|
-
assert_equal "someArg", argument.name
|
48
|
-
assert_equal "someVar", argument.value.name
|
49
|
-
end
|
50
|
-
|
51
|
-
def assert_valid_fragment_spread(fragment_spread)
|
52
|
-
assert_equal "moreNestedFields", fragment_spread.name
|
53
|
-
assert_equal 1, fragment_spread.directives.length
|
54
|
-
assert_equal [7, 17], fragment_spread.position
|
55
|
-
end
|
56
|
-
|
57
|
-
def assert_valid_directive(directive)
|
58
|
-
assert_equal "skip", directive.name
|
59
|
-
assert_equal "if", directive.arguments.first.name
|
60
|
-
assert_equal 1, directive.arguments.length
|
61
|
-
assert_equal [3, 62], directive.position
|
62
|
-
end
|
63
|
-
|
64
|
-
def assert_valid_typed_inline_fragment(inline_fragment)
|
65
|
-
assert_equal "OtherType", inline_fragment.type.name
|
66
|
-
assert_equal 2, inline_fragment.selections.length
|
67
|
-
assert_equal 1, inline_fragment.directives.length
|
68
|
-
assert_equal [10, 15], inline_fragment.position
|
69
|
-
end
|
70
|
-
|
71
|
-
def assert_valid_typeless_inline_fragment(inline_fragment)
|
72
|
-
assert_equal nil, inline_fragment.type
|
73
|
-
assert_equal 1, inline_fragment.selections.length
|
74
|
-
assert_equal 0, inline_fragment.directives.length
|
75
|
-
end
|
76
|
-
end
|
77
|
-
end
|
78
|
-
end
|
79
|
-
end
|
@@ -1,266 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
require "graphql/compatibility/query_parser_specification/query_assertions"
|
3
|
-
require "graphql/compatibility/query_parser_specification/parse_error_specification"
|
4
|
-
|
5
|
-
module GraphQL
|
6
|
-
module Compatibility
|
7
|
-
# This asserts that a given parse function turns a string into
|
8
|
-
# the proper tree of {{GraphQL::Language::Nodes}}.
|
9
|
-
module QueryParserSpecification
|
10
|
-
# @yieldparam query_string [String] A query string to parse
|
11
|
-
# @yieldreturn [GraphQL::Language::Nodes::Document]
|
12
|
-
# @return [Class<Minitest::Test>] A test suite for this parse function
|
13
|
-
def self.build_suite(&block)
|
14
|
-
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."
|
15
|
-
|
16
|
-
Class.new(Minitest::Test) do
|
17
|
-
include QueryAssertions
|
18
|
-
include ParseErrorSpecification
|
19
|
-
|
20
|
-
@@parse_fn = block
|
21
|
-
|
22
|
-
def parse(query_string)
|
23
|
-
@@parse_fn.call(query_string)
|
24
|
-
end
|
25
|
-
|
26
|
-
def test_it_parses_queries
|
27
|
-
document = parse(QUERY_STRING)
|
28
|
-
query = document.definitions.first
|
29
|
-
assert_valid_query(query)
|
30
|
-
assert_valid_fragment(document.definitions.last)
|
31
|
-
assert_valid_variable(query.variables.first)
|
32
|
-
field = query.selections.first
|
33
|
-
assert_valid_field(field)
|
34
|
-
assert_valid_variable_argument(field.arguments.first)
|
35
|
-
assert_valid_literal_argument(field.arguments.last)
|
36
|
-
assert_valid_directive(field.directives.first)
|
37
|
-
fragment_spread = query.selections[1].selections.last
|
38
|
-
assert_valid_fragment_spread(fragment_spread)
|
39
|
-
assert_valid_typed_inline_fragment(query.selections[2])
|
40
|
-
assert_valid_typeless_inline_fragment(query.selections[3])
|
41
|
-
end
|
42
|
-
|
43
|
-
def test_it_parses_unnamed_queries
|
44
|
-
document = parse("{ name, age, height }")
|
45
|
-
operation = document.definitions.first
|
46
|
-
assert_equal 1, document.definitions.length
|
47
|
-
assert_equal "query", operation.operation_type
|
48
|
-
assert_equal nil, operation.name
|
49
|
-
assert_equal 3, operation.selections.length
|
50
|
-
end
|
51
|
-
|
52
|
-
def test_it_parses_the_introspection_query
|
53
|
-
parse(GraphQL::Introspection::INTROSPECTION_QUERY)
|
54
|
-
end
|
55
|
-
|
56
|
-
def test_it_parses_inputs
|
57
|
-
query_string = %|
|
58
|
-
{
|
59
|
-
field(
|
60
|
-
int: 3,
|
61
|
-
float: 4.7e-24,
|
62
|
-
bool: false,
|
63
|
-
string: "☀︎🏆 \\b \\f \\n \\r \\t \\" \u00b6 \\u00b6 / \\/",
|
64
|
-
enum: ENUM_NAME,
|
65
|
-
array: [7, 8, 9]
|
66
|
-
object: {a: [1,2,3], b: {c: "4"}}
|
67
|
-
unicode_bom: "\xef\xbb\xbfquery"
|
68
|
-
keywordEnum: on
|
69
|
-
nullValue: null
|
70
|
-
nullValueInObject: {a: null, b: "b"}
|
71
|
-
nullValueInArray: ["a", null, "b"]
|
72
|
-
blockString: """
|
73
|
-
Hello,
|
74
|
-
World
|
75
|
-
"""
|
76
|
-
)
|
77
|
-
}
|
78
|
-
|
|
79
|
-
document = parse(query_string)
|
80
|
-
inputs = document.definitions.first.selections.first.arguments
|
81
|
-
assert_equal 3, inputs[0].value, "Integers"
|
82
|
-
assert_equal 0.47e-23, inputs[1].value, "Floats"
|
83
|
-
assert_equal false, inputs[2].value, "Booleans"
|
84
|
-
assert_equal %|☀︎🏆 \b \f \n \r \t " ¶ ¶ / /|, inputs[3].value, "Strings"
|
85
|
-
assert_instance_of GraphQL::Language::Nodes::Enum, inputs[4].value
|
86
|
-
assert_equal "ENUM_NAME", inputs[4].value.name, "Enums"
|
87
|
-
assert_equal [7,8,9], inputs[5].value, "Lists"
|
88
|
-
|
89
|
-
obj = inputs[6].value
|
90
|
-
assert_equal "a", obj.arguments[0].name
|
91
|
-
assert_equal [1,2,3], obj.arguments[0].value
|
92
|
-
assert_equal "b", obj.arguments[1].name
|
93
|
-
assert_equal "c", obj.arguments[1].value.arguments[0].name
|
94
|
-
assert_equal "4", obj.arguments[1].value.arguments[0].value
|
95
|
-
|
96
|
-
assert_equal %|\xef\xbb\xbfquery|, inputs[7].value, "Unicode BOM"
|
97
|
-
assert_equal "on", inputs[8].value.name, "Enum value 'on'"
|
98
|
-
|
99
|
-
assert_instance_of GraphQL::Language::Nodes::NullValue, inputs[9].value
|
100
|
-
|
101
|
-
args = inputs[10].value.arguments
|
102
|
-
assert_instance_of GraphQL::Language::Nodes::NullValue, args.find{ |arg| arg.name == 'a' }.value
|
103
|
-
assert_equal 'b', args.find{ |arg| arg.name == 'b' }.value
|
104
|
-
|
105
|
-
values = inputs[11].value
|
106
|
-
assert_equal 'a', values[0]
|
107
|
-
assert_instance_of GraphQL::Language::Nodes::NullValue, values[1]
|
108
|
-
assert_equal 'b', values[2]
|
109
|
-
|
110
|
-
block_str_value = inputs[12].value
|
111
|
-
assert_equal "Hello,\n World", block_str_value
|
112
|
-
end
|
113
|
-
|
114
|
-
def test_it_doesnt_parse_nonsense_variables
|
115
|
-
query_string_1 = "query Vars($var1) { cheese(id: $var1) { flavor } }"
|
116
|
-
query_string_2 = "query Vars2($var1: Int = $var1) { cheese(id: $var1) { flavor } }"
|
117
|
-
|
118
|
-
err_1 = assert_raises(GraphQL::ParseError) do
|
119
|
-
parse(query_string_1)
|
120
|
-
end
|
121
|
-
assert_equal [1,17], [err_1.line, err_1.col]
|
122
|
-
|
123
|
-
err_2 = assert_raises(GraphQL::ParseError) do
|
124
|
-
parse(query_string_2)
|
125
|
-
end
|
126
|
-
assert_equal [1,26], [err_2.line, err_2.col]
|
127
|
-
end
|
128
|
-
|
129
|
-
def test_enum_value_definitions_have_a_position
|
130
|
-
document = parse("""
|
131
|
-
enum Enum {
|
132
|
-
VALUE
|
133
|
-
}
|
134
|
-
""")
|
135
|
-
|
136
|
-
assert_equal [3, 17], document.definitions[0].values[0].position
|
137
|
-
end
|
138
|
-
|
139
|
-
def test_field_definitions_have_a_position
|
140
|
-
document = parse("""
|
141
|
-
type A {
|
142
|
-
field: String
|
143
|
-
}
|
144
|
-
""")
|
145
|
-
|
146
|
-
assert_equal [3, 17], document.definitions[0].fields[0].position
|
147
|
-
end
|
148
|
-
|
149
|
-
def test_input_value_definitions_have_a_position
|
150
|
-
document = parse("""
|
151
|
-
input A {
|
152
|
-
field: String
|
153
|
-
}
|
154
|
-
""")
|
155
|
-
|
156
|
-
assert_equal [3, 17], document.definitions[0].fields[0].position
|
157
|
-
end
|
158
|
-
|
159
|
-
def test_parses_when_there_are_no_interfaces
|
160
|
-
schema = "
|
161
|
-
type A {
|
162
|
-
a: String
|
163
|
-
}
|
164
|
-
"
|
165
|
-
|
166
|
-
document = parse(schema)
|
167
|
-
|
168
|
-
assert_equal [], document.definitions[0].interfaces.map(&:name)
|
169
|
-
end
|
170
|
-
|
171
|
-
def test_parses_implements_with_leading_ampersand
|
172
|
-
schema = "
|
173
|
-
type A implements & B {
|
174
|
-
a: String
|
175
|
-
}
|
176
|
-
"
|
177
|
-
|
178
|
-
document = parse(schema)
|
179
|
-
|
180
|
-
assert_equal ["B"], document.definitions[0].interfaces.map(&:name)
|
181
|
-
assert_equal [2, 35], document.definitions[0].interfaces[0].position
|
182
|
-
end
|
183
|
-
|
184
|
-
def test_parses_implements_with_leading_ampersand_and_multiple_interfaces
|
185
|
-
schema = "
|
186
|
-
type A implements & B & C {
|
187
|
-
a: String
|
188
|
-
}
|
189
|
-
"
|
190
|
-
|
191
|
-
document = parse(schema)
|
192
|
-
|
193
|
-
assert_equal ["B", "C"], document.definitions[0].interfaces.map(&:name)
|
194
|
-
assert_equal [2, 35], document.definitions[0].interfaces[0].position
|
195
|
-
assert_equal [2, 39], document.definitions[0].interfaces[1].position
|
196
|
-
end
|
197
|
-
|
198
|
-
def test_parses_implements_without_leading_ampersand
|
199
|
-
schema = "
|
200
|
-
type A implements B {
|
201
|
-
a: String
|
202
|
-
}
|
203
|
-
"
|
204
|
-
|
205
|
-
document = parse(schema)
|
206
|
-
|
207
|
-
assert_equal ["B"], document.definitions[0].interfaces.map(&:name)
|
208
|
-
assert_equal [2, 33], document.definitions[0].interfaces[0].position
|
209
|
-
end
|
210
|
-
|
211
|
-
def test_parses_implements_without_leading_ampersand_and_multiple_interfaces
|
212
|
-
schema = "
|
213
|
-
type A implements B & C {
|
214
|
-
a: String
|
215
|
-
}
|
216
|
-
"
|
217
|
-
|
218
|
-
document = parse(schema)
|
219
|
-
|
220
|
-
assert_equal ["B", "C"], document.definitions[0].interfaces.map(&:name)
|
221
|
-
assert_equal [2, 33], document.definitions[0].interfaces[0].position
|
222
|
-
assert_equal [2, 37], document.definitions[0].interfaces[1].position
|
223
|
-
end
|
224
|
-
|
225
|
-
def test_supports_old_syntax_for_parsing_multiple_interfaces
|
226
|
-
schema = "
|
227
|
-
type A implements B, C {
|
228
|
-
a: String
|
229
|
-
}
|
230
|
-
"
|
231
|
-
|
232
|
-
document = parse(schema)
|
233
|
-
|
234
|
-
assert_equal ["B", "C"], document.definitions[0].interfaces.map(&:name)
|
235
|
-
assert_equal [2, 33], document.definitions[0].interfaces[0].position
|
236
|
-
assert_equal [2, 36], document.definitions[0].interfaces[1].position
|
237
|
-
end
|
238
|
-
end
|
239
|
-
end
|
240
|
-
|
241
|
-
QUERY_STRING = %|
|
242
|
-
query getStuff($someVar: Int = 1, $anotherVar: [String!] ) @skip(if: false) {
|
243
|
-
myField: someField(someArg: $someVar, ok: 1.4) @skip(if: $anotherVar) @thing(or: "Whatever")
|
244
|
-
|
245
|
-
anotherField(someArg: [1,2,3]) {
|
246
|
-
nestedField
|
247
|
-
... moreNestedFields @skip(if: true)
|
248
|
-
}
|
249
|
-
|
250
|
-
... on OtherType @include(unless: false){
|
251
|
-
field(arg: [{key: "value", anotherKey: 0.9, anotherAnotherKey: WHATEVER}])
|
252
|
-
anotherField
|
253
|
-
}
|
254
|
-
|
255
|
-
... {
|
256
|
-
id
|
257
|
-
}
|
258
|
-
}
|
259
|
-
|
260
|
-
fragment moreNestedFields on NestedType @or(something: "ok") {
|
261
|
-
anotherNestedField @enum(directive: true)
|
262
|
-
}
|
263
|
-
|
|
264
|
-
end
|
265
|
-
end
|
266
|
-
end
|