graphql 1.6.8 → 1.7.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.
- checksums.yaml +4 -4
- data/lib/graphql.rb +5 -0
- data/lib/graphql/analysis/analyze_query.rb +21 -17
- data/lib/graphql/argument.rb +6 -2
- data/lib/graphql/backtrace.rb +50 -0
- data/lib/graphql/backtrace/inspect_result.rb +51 -0
- data/lib/graphql/backtrace/table.rb +120 -0
- data/lib/graphql/backtrace/traced_error.rb +55 -0
- data/lib/graphql/backtrace/tracer.rb +50 -0
- data/lib/graphql/enum_type.rb +1 -10
- data/lib/graphql/execution.rb +1 -2
- data/lib/graphql/execution/execute.rb +98 -89
- data/lib/graphql/execution/flatten.rb +40 -0
- data/lib/graphql/execution/lazy/resolve.rb +7 -7
- data/lib/graphql/execution/multiplex.rb +29 -29
- data/lib/graphql/field.rb +5 -1
- data/lib/graphql/internal_representation/node.rb +16 -0
- data/lib/graphql/invalid_name_error.rb +11 -0
- data/lib/graphql/language/parser.rb +11 -5
- data/lib/graphql/language/parser.y +11 -5
- data/lib/graphql/name_validator.rb +16 -0
- data/lib/graphql/object_type.rb +5 -0
- data/lib/graphql/query.rb +28 -7
- data/lib/graphql/query/context.rb +155 -52
- data/lib/graphql/query/literal_input.rb +36 -9
- data/lib/graphql/query/null_context.rb +7 -1
- data/lib/graphql/query/result.rb +63 -0
- data/lib/graphql/query/serial_execution/field_resolution.rb +3 -4
- data/lib/graphql/query/serial_execution/value_resolution.rb +3 -4
- data/lib/graphql/query/variables.rb +1 -1
- data/lib/graphql/schema.rb +31 -0
- data/lib/graphql/schema/traversal.rb +16 -1
- data/lib/graphql/schema/warden.rb +40 -4
- data/lib/graphql/static_validation/validator.rb +20 -18
- data/lib/graphql/subscriptions.rb +129 -0
- data/lib/graphql/subscriptions/action_cable_subscriptions.rb +122 -0
- data/lib/graphql/subscriptions/event.rb +52 -0
- data/lib/graphql/subscriptions/instrumentation.rb +68 -0
- data/lib/graphql/tracing.rb +80 -0
- data/lib/graphql/tracing/active_support_notifications_tracing.rb +31 -0
- data/lib/graphql/version.rb +1 -1
- data/readme.md +1 -1
- data/spec/graphql/analysis/analyze_query_spec.rb +19 -0
- data/spec/graphql/argument_spec.rb +28 -0
- data/spec/graphql/backtrace_spec.rb +144 -0
- data/spec/graphql/define/assign_argument_spec.rb +12 -0
- data/spec/graphql/enum_type_spec.rb +1 -1
- data/spec/graphql/execution/execute_spec.rb +66 -0
- data/spec/graphql/execution/lazy_spec.rb +4 -3
- data/spec/graphql/language/parser_spec.rb +16 -0
- data/spec/graphql/object_type_spec.rb +14 -0
- data/spec/graphql/query/context_spec.rb +134 -27
- data/spec/graphql/query/result_spec.rb +29 -0
- data/spec/graphql/query/variables_spec.rb +13 -0
- data/spec/graphql/query_spec.rb +22 -0
- data/spec/graphql/schema/build_from_definition_spec.rb +2 -0
- data/spec/graphql/schema/traversal_spec.rb +70 -12
- data/spec/graphql/schema/warden_spec.rb +67 -1
- data/spec/graphql/schema_spec.rb +29 -0
- data/spec/graphql/static_validation/validator_spec.rb +16 -0
- data/spec/graphql/subscriptions_spec.rb +331 -0
- data/spec/graphql/tracing/active_support_notifications_tracing_spec.rb +57 -0
- data/spec/graphql/tracing_spec.rb +47 -0
- data/spec/spec_helper.rb +32 -0
- data/spec/support/star_wars/schema.rb +39 -0
- metadata +27 -4
- data/lib/graphql/execution/field_result.rb +0 -54
- data/lib/graphql/execution/selection_result.rb +0 -90
@@ -37,6 +37,18 @@ describe GraphQL::Define::AssignArgument do
|
|
37
37
|
assert_equal "GraphQL::Argument can't define 'blah'", err.message
|
38
38
|
end
|
39
39
|
|
40
|
+
it "accepts an existing argument" do
|
41
|
+
existing = GraphQL::Argument.define do
|
42
|
+
name "bar"
|
43
|
+
type GraphQL::STRING_TYPE
|
44
|
+
end
|
45
|
+
|
46
|
+
arg = define_argument(:foo, existing)
|
47
|
+
|
48
|
+
assert_equal "foo", arg.name
|
49
|
+
assert_equal GraphQL::STRING_TYPE, arg.type
|
50
|
+
end
|
51
|
+
|
40
52
|
def define_argument(*args)
|
41
53
|
type = GraphQL::ObjectType.define do
|
42
54
|
field :a, types.String do
|
@@ -39,7 +39,7 @@ describe GraphQL::EnumType do
|
|
39
39
|
|
40
40
|
describe "invalid names" do
|
41
41
|
it "rejects names with a space" do
|
42
|
-
assert_raises(GraphQL::
|
42
|
+
assert_raises(GraphQL::InvalidNameError) {
|
43
43
|
InvalidEnumTest = GraphQL::EnumType.define do
|
44
44
|
name "InvalidEnumTest"
|
45
45
|
|
@@ -137,4 +137,70 @@ describe GraphQL::Execution::Execute do
|
|
137
137
|
assert_equal "👻", res["errors"].first["message"]
|
138
138
|
end
|
139
139
|
end
|
140
|
+
|
141
|
+
describe "tracing" do
|
142
|
+
if rails_should_be_installed?
|
143
|
+
it "emits traces" do
|
144
|
+
query_string = <<-GRAPHQL
|
145
|
+
query Bases($id1: ID!, $id2: ID!){
|
146
|
+
b1: batchedBase(id: $id1) { name }
|
147
|
+
b2: batchedBase(id: $id2) { name }
|
148
|
+
}
|
149
|
+
GRAPHQL
|
150
|
+
first_id = StarWars::Base.first.id
|
151
|
+
last_id = StarWars::Base.last.id
|
152
|
+
|
153
|
+
traces = TestTracing.with_trace do
|
154
|
+
star_wars_query(query_string, {
|
155
|
+
"id1" => first_id,
|
156
|
+
"id2" => last_id,
|
157
|
+
})
|
158
|
+
end
|
159
|
+
|
160
|
+
exec_traces = traces[5..-1]
|
161
|
+
expected_traces = [
|
162
|
+
"execute_field",
|
163
|
+
"execute_field",
|
164
|
+
"execute_query",
|
165
|
+
"lazy_loader",
|
166
|
+
"execute_field",
|
167
|
+
"execute_field_lazy",
|
168
|
+
"execute_field",
|
169
|
+
"execute_field_lazy",
|
170
|
+
"execute_field_lazy",
|
171
|
+
"execute_field_lazy",
|
172
|
+
"execute_query_lazy",
|
173
|
+
"execute_multiplex",
|
174
|
+
]
|
175
|
+
assert_equal expected_traces, exec_traces.map { |t| t[:key] }
|
176
|
+
|
177
|
+
field_1_eager, field_2_eager,
|
178
|
+
query_eager, lazy_loader,
|
179
|
+
# field 3 is eager-resolved _during_ field 1's lazy resolve
|
180
|
+
field_3_eager, field_1_lazy,
|
181
|
+
field_4_eager, field_2_lazy,
|
182
|
+
# field 3 didn't finish above, it's resolved in the next round
|
183
|
+
field_3_lazy, field_4_lazy,
|
184
|
+
query_lazy, multiplex = exec_traces
|
185
|
+
|
186
|
+
assert_equal ["b1"], field_1_eager[:context].path
|
187
|
+
assert_equal ["b2"], field_2_eager[:context].path
|
188
|
+
assert_instance_of GraphQL::Query, query_eager[:query]
|
189
|
+
|
190
|
+
assert_equal [first_id.to_s, last_id.to_s], lazy_loader[:ids]
|
191
|
+
assert_equal StarWars::Base, lazy_loader[:model]
|
192
|
+
|
193
|
+
assert_equal ["b1", "name"], field_3_eager[:context].path
|
194
|
+
assert_equal ["b1"], field_1_lazy[:context].path
|
195
|
+
assert_equal ["b2", "name"], field_4_eager[:context].path
|
196
|
+
assert_equal ["b2"], field_2_lazy[:context].path
|
197
|
+
|
198
|
+
assert_equal ["b1", "name"], field_3_lazy[:context].path
|
199
|
+
assert_equal ["b2", "name"], field_4_lazy[:context].path
|
200
|
+
assert_instance_of GraphQL::Query, query_lazy[:query]
|
201
|
+
|
202
|
+
assert_instance_of GraphQL::Execution::Multiplex, multiplex[:multiplex]
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|
140
206
|
end
|
@@ -70,7 +70,7 @@ describe GraphQL::Execution::Lazy do
|
|
70
70
|
assert_equal expected_data, res["data"]
|
71
71
|
end
|
72
72
|
|
73
|
-
it "propagates nulls" do
|
73
|
+
it "propagates nulls to the root" do
|
74
74
|
res = run_query %|
|
75
75
|
{
|
76
76
|
nestedSum(value: 1) {
|
@@ -85,14 +85,15 @@ describe GraphQL::Execution::Lazy do
|
|
85
85
|
|
86
86
|
assert_equal(nil, res["data"])
|
87
87
|
assert_equal 1, res["errors"].length
|
88
|
+
end
|
88
89
|
|
89
|
-
|
90
|
+
it "propagates partial nulls" do
|
90
91
|
res = run_query %|
|
91
92
|
{
|
92
93
|
nullableNestedSum(value: 1) {
|
93
94
|
value
|
94
95
|
nullableNestedSum(value: 2) {
|
95
|
-
nestedSum(value: 13) {
|
96
|
+
ns: nestedSum(value: 13) {
|
96
97
|
value
|
97
98
|
}
|
98
99
|
}
|
@@ -71,4 +71,20 @@ describe GraphQL::Language::Parser do
|
|
71
71
|
|
72
72
|
end
|
73
73
|
end
|
74
|
+
|
75
|
+
it "serves traces" do
|
76
|
+
traces = TestTracing.with_trace do
|
77
|
+
GraphQL.parse("{ t: __typename }")
|
78
|
+
end
|
79
|
+
assert_equal 2, traces.length
|
80
|
+
lex_trace, parse_trace = traces
|
81
|
+
|
82
|
+
assert_equal "{ t: __typename }", lex_trace[:query_string]
|
83
|
+
assert_equal "lex", lex_trace[:key]
|
84
|
+
assert_instance_of Array, lex_trace[:result]
|
85
|
+
|
86
|
+
assert_equal "{ t: __typename }", parse_trace[:query_string]
|
87
|
+
assert_equal "parse", parse_trace[:key]
|
88
|
+
assert_instance_of GraphQL::Language::Nodes::Document, parse_trace[:result]
|
89
|
+
end
|
74
90
|
end
|
@@ -17,6 +17,20 @@ describe GraphQL::ObjectType do
|
|
17
17
|
}
|
18
18
|
end
|
19
19
|
|
20
|
+
it "doesn't allow invalid name" do
|
21
|
+
exception = assert_raises(GraphQL::InvalidNameError) {
|
22
|
+
InvalidNameObject = GraphQL::ObjectType.define do
|
23
|
+
name "Three Word Query"
|
24
|
+
|
25
|
+
field :id, !types.Int, "id field"
|
26
|
+
end
|
27
|
+
|
28
|
+
# Force evaluation
|
29
|
+
InvalidNameObject.name
|
30
|
+
}
|
31
|
+
assert_equal("Names must match /^[_a-zA-Z][_a-zA-Z0-9]*$/ but 'Three Word Query' does not", exception.message)
|
32
|
+
end
|
33
|
+
|
20
34
|
it "has a name" do
|
21
35
|
assert_equal("Cheese", type.name)
|
22
36
|
type.name = "Fromage"
|
@@ -5,35 +5,102 @@ describe GraphQL::Query::Context do
|
|
5
5
|
CTX = []
|
6
6
|
before { CTX.clear }
|
7
7
|
|
8
|
-
let(:
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
8
|
+
let(:parent_info_type) {
|
9
|
+
GraphQL::ObjectType.define {
|
10
|
+
name "ParentInfo"
|
11
|
+
field :object, types.String do
|
12
|
+
resolve ->(o, a, c) { c.parent.parent.object }
|
13
|
+
end
|
14
|
+
field :objectClassName, types.String do
|
15
|
+
resolve ->(o, a, c) { c.parent.parent.object.class.name }
|
16
|
+
end
|
17
|
+
field :valueClassName, types.String do
|
18
|
+
resolve ->(o, a, c) { c.parent.parent.value.class.name }
|
19
|
+
end
|
20
|
+
field :value, types.String do
|
21
|
+
resolve ->(o, a, c) { c.parent.parent.value.to_s }
|
22
|
+
end
|
23
|
+
}
|
24
|
+
}
|
25
|
+
let(:backtrace_type) {
|
26
|
+
GraphQL::ObjectType.define do
|
27
|
+
name "Backtrace"
|
28
|
+
field :backtraceEntry, types.String do
|
29
|
+
argument :idx, !types.Int
|
30
|
+
resolve ->(o, a, c) { c.backtrace[a[:idx]] }
|
31
|
+
end
|
32
|
+
field :backtraceArray, types[types.String] do
|
33
|
+
resolve ->(o, a, c) { c.backtrace.to_a }
|
34
|
+
end
|
35
|
+
field :backtraceTable, types.String do
|
36
|
+
resolve ->(o, a, c) { c.backtrace.inspect }
|
37
|
+
end
|
22
38
|
end
|
39
|
+
}
|
40
|
+
let(:query_type) {
|
41
|
+
parent_info = parent_info_type
|
42
|
+
backtrace = backtrace_type
|
43
|
+
GraphQL::ObjectType.define {
|
44
|
+
name "Query"
|
45
|
+
field :context, types.String do
|
46
|
+
argument :key, !types.String
|
47
|
+
resolve ->(target, args, ctx) { ctx[args[:key]] }
|
48
|
+
end
|
49
|
+
field :contextAstNodeName, types.String do
|
50
|
+
resolve ->(target, args, ctx) { ctx.ast_node.class.name }
|
51
|
+
end
|
52
|
+
field :contextIrepNodeName, types.String do
|
53
|
+
resolve ->(target, args, ctx) { ctx.irep_node.class.name }
|
54
|
+
end
|
55
|
+
field :queryName, types.String do
|
56
|
+
resolve ->(target, args, ctx) { ctx.query.class.name }
|
57
|
+
end
|
23
58
|
|
24
|
-
|
25
|
-
|
26
|
-
|
59
|
+
field :pushContext, types.Int do
|
60
|
+
resolve ->(t,a,c) { CTX << c; 1 }
|
61
|
+
end
|
62
|
+
|
63
|
+
field :pushQueryError, types.Int do
|
64
|
+
resolve ->(t,a,c) {
|
65
|
+
c.query.context.add_error(GraphQL::ExecutionError.new("Query-level error"))
|
66
|
+
1
|
67
|
+
}
|
68
|
+
end
|
27
69
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
70
|
+
field :parentInfo, parent_info, resolve: ->(o,a,c) { :noop }
|
71
|
+
field :backtrace, backtrace, resolve: Proc.new { :noop }
|
72
|
+
}
|
73
|
+
}
|
74
|
+
|
75
|
+
let(:schema) { GraphQL::Schema.define(query: query_type, mutation: nil)}
|
76
|
+
let(:result) { schema.execute(query_string, root_value: "rootval", context: {"some_key" => "some value"})}
|
77
|
+
|
78
|
+
describe "access to parent context" do
|
79
|
+
let(:query_string) { %|
|
80
|
+
{
|
81
|
+
parentInfo {
|
82
|
+
value
|
83
|
+
valueClassName
|
84
|
+
object
|
85
|
+
objectClassName
|
86
|
+
}
|
32
87
|
}
|
88
|
+
|}
|
89
|
+
|
90
|
+
it "exposes the parent object" do
|
91
|
+
expected = {
|
92
|
+
"data" => {
|
93
|
+
"parentInfo" => {
|
94
|
+
"objectClassName" => "String",
|
95
|
+
"object" => "rootval",
|
96
|
+
"value" => "{}",
|
97
|
+
"valueClassName" => "Hash",
|
98
|
+
}
|
99
|
+
}
|
100
|
+
}
|
101
|
+
assert_equal(expected, result)
|
33
102
|
end
|
34
|
-
|
35
|
-
let(:schema) { GraphQL::Schema.define(query: query_type, mutation: nil)}
|
36
|
-
let(:result) { schema.execute(query_string, context: {"some_key" => "some value"})}
|
103
|
+
end
|
37
104
|
|
38
105
|
describe "access to passed-in values" do
|
39
106
|
let(:query_string) { %|
|
@@ -57,6 +124,46 @@ describe GraphQL::Query::Context do
|
|
57
124
|
end
|
58
125
|
end
|
59
126
|
|
127
|
+
describe "#backtrace" do
|
128
|
+
let(:query_string) { %|
|
129
|
+
query {
|
130
|
+
backtrace {
|
131
|
+
b1: backtraceEntry(idx: 0)
|
132
|
+
b2: backtraceEntry(idx: 1)
|
133
|
+
b3: backtraceEntry(idx: 2)
|
134
|
+
backtraceArray
|
135
|
+
backtraceTable
|
136
|
+
}
|
137
|
+
pushContext
|
138
|
+
}
|
139
|
+
|}
|
140
|
+
|
141
|
+
it "exposes the GraphQL backtrace" do
|
142
|
+
backtrace_result = result.fetch("data").fetch("backtrace")
|
143
|
+
assert_equal "4:11: Backtrace.backtraceEntry as b1", backtrace_result.fetch("b1")
|
144
|
+
assert_equal "3:9: Query.backtrace", backtrace_result.fetch("b2")
|
145
|
+
assert_equal "2:7: query", backtrace_result.fetch("b3")
|
146
|
+
assert_equal ["7:11: Backtrace.backtraceArray", "3:9: Query.backtrace", "2:7: query"], backtrace_result.fetch("backtraceArray")
|
147
|
+
expected_table = [
|
148
|
+
'Loc | Field | Object | Arguments | Result',
|
149
|
+
'8:11 | Backtrace.backtraceTable | :noop | {} | nil',
|
150
|
+
'3:9 | Query.backtrace | "rootval" | {} | {b1: "4:11: Backtrace.backtraceEntry as b1", b2: "3:9: Query.backtrace", b3: "2:7: query", backtr...',
|
151
|
+
'2:7 | query | "rootval" | {} | {}',
|
152
|
+
'',
|
153
|
+
].join("\n")
|
154
|
+
assert_equal expected_table, backtrace_result.fetch("backtraceTable")
|
155
|
+
|
156
|
+
expected_table_2 = <<-TABLE
|
157
|
+
Loc | Field | Object | Arguments | Result
|
158
|
+
10:9 | Query.pushContext | "rootval" | {} | 1
|
159
|
+
2:7 | query | "rootval" | {} | {backtrace: {...}, pushContext: 1}
|
160
|
+
TABLE
|
161
|
+
|
162
|
+
ctx = CTX.last
|
163
|
+
assert_equal expected_table_2, ctx.backtrace.to_s
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
60
167
|
describe "access to the InternalRepresentation node" do
|
61
168
|
let(:query_string) { %|
|
62
169
|
query getCtx { contextIrepNodeName }
|
@@ -80,7 +187,7 @@ describe GraphQL::Query::Context do
|
|
80
187
|
end
|
81
188
|
|
82
189
|
describe "empty values" do
|
83
|
-
let(:context) { GraphQL::Query::Context.new(query: OpenStruct.new(schema: schema), values: nil) }
|
190
|
+
let(:context) { GraphQL::Query::Context.new(query: OpenStruct.new(schema: schema), values: nil, object: nil) }
|
84
191
|
|
85
192
|
it "returns returns nil and reports key? => false" do
|
86
193
|
assert_equal(nil, context[:some_key])
|
@@ -90,7 +197,7 @@ describe GraphQL::Query::Context do
|
|
90
197
|
end
|
91
198
|
|
92
199
|
describe "assigning values" do
|
93
|
-
let(:context) { GraphQL::Query::Context.new(query: OpenStruct.new(schema: schema), values: nil) }
|
200
|
+
let(:context) { GraphQL::Query::Context.new(query: OpenStruct.new(schema: schema), values: nil, object: nil) }
|
94
201
|
|
95
202
|
it "allows you to assign new contexts" do
|
96
203
|
assert_equal(nil, context[:some_key])
|
@@ -99,7 +206,7 @@ describe GraphQL::Query::Context do
|
|
99
206
|
end
|
100
207
|
|
101
208
|
describe "namespaces" do
|
102
|
-
let(:context) { GraphQL::Query::Context.new(query: OpenStruct.new(schema: schema), values: {a: 1}) }
|
209
|
+
let(:context) { GraphQL::Query::Context.new(query: OpenStruct.new(schema: schema), values: {a: 1}, object: nil) }
|
103
210
|
|
104
211
|
it "doesn't conflict with base values" do
|
105
212
|
ns = context.namespace(:stuff)
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require "spec_helper"
|
3
|
+
|
4
|
+
describe GraphQL::Query::Result do
|
5
|
+
let(:query_string) { '{ __type(name: "Cheese") { name } }' }
|
6
|
+
let(:schema) { Dummy::Schema }
|
7
|
+
let(:result) { schema.execute(query_string, context: { a: :b }) }
|
8
|
+
|
9
|
+
it "exposes hash-like methods" do
|
10
|
+
assert_equal "Cheese", result["data"]["__type"]["name"]
|
11
|
+
refute result.key?("errors")
|
12
|
+
assert_equal ["data"], result.keys
|
13
|
+
end
|
14
|
+
|
15
|
+
it "is equal with hashes" do
|
16
|
+
hash_result = {"data" => { "__type" => { "name" => "Cheese" } } }
|
17
|
+
assert_equal hash_result, result
|
18
|
+
end
|
19
|
+
|
20
|
+
it "tells the kind of operation" do
|
21
|
+
assert result.query?
|
22
|
+
refute result.mutation?
|
23
|
+
end
|
24
|
+
|
25
|
+
it "exposes the context" do
|
26
|
+
assert_instance_of GraphQL::Query::Context, result.context
|
27
|
+
assert_equal({a: :b}, result.context.to_h)
|
28
|
+
end
|
29
|
+
end
|
@@ -26,6 +26,19 @@ describe GraphQL::Query::Variables do
|
|
26
26
|
provided_variables)
|
27
27
|
}
|
28
28
|
|
29
|
+
describe "#to_h" do
|
30
|
+
let(:provided_variables) { { "animals" => "YAK" } }
|
31
|
+
|
32
|
+
it "returns a hash representation including default values" do
|
33
|
+
expected_hash = {
|
34
|
+
"animals" => ["YAK"],
|
35
|
+
"intDefaultNull" => nil,
|
36
|
+
"intWithDefault" => 10,
|
37
|
+
}
|
38
|
+
assert_equal expected_hash, variables.to_h
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
29
42
|
describe "#initialize" do
|
30
43
|
describe "coercing inputs" do
|
31
44
|
let(:provided_variables) { { "animals" => "YAK" } }
|
data/spec/graphql/query_spec.rb
CHANGED
@@ -44,6 +44,28 @@ describe GraphQL::Query do
|
|
44
44
|
)}
|
45
45
|
let(:result) { query.result }
|
46
46
|
|
47
|
+
describe "when passed both a query string and a document" do
|
48
|
+
it "returns an error to the client when query kwarg is used" do
|
49
|
+
assert_raises ArgumentError do
|
50
|
+
GraphQL::Query.new(
|
51
|
+
schema,
|
52
|
+
query: "{ fromSource(source: COW) { id } }",
|
53
|
+
document: document
|
54
|
+
)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
it "returns an error to the client" do
|
59
|
+
assert_raises ArgumentError do
|
60
|
+
GraphQL::Query.new(
|
61
|
+
schema,
|
62
|
+
"{ fromSource(source: COW) { id } }",
|
63
|
+
document: document
|
64
|
+
)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
47
69
|
describe "when passed no query string or document" do
|
48
70
|
it 'returns an error to the client' do
|
49
71
|
res = GraphQL::Query.new(
|