graphql 1.6.4 → 1.6.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/generators/graphql/core.rb +47 -0
- data/lib/generators/graphql/install_generator.rb +15 -20
- data/lib/generators/graphql/mutation_generator.rb +31 -1
- data/lib/generators/graphql/templates/mutation.erb +2 -2
- data/lib/generators/graphql/templates/mutation_type.erb +5 -0
- data/lib/generators/graphql/templates/schema.erb +0 -1
- data/lib/graphql/argument.rb +6 -5
- data/lib/graphql/backwards_compatibility.rb +18 -4
- data/lib/graphql/base_type.rb +1 -1
- data/lib/graphql/compatibility/execution_specification/counter_schema.rb +1 -1
- data/lib/graphql/compatibility/execution_specification/specification_schema.rb +1 -1
- data/lib/graphql/compatibility/lazy_execution_specification.rb +9 -2
- data/lib/graphql/define.rb +1 -0
- data/lib/graphql/define/defined_object_proxy.rb +1 -1
- data/lib/graphql/define/no_definition_error.rb +7 -0
- data/lib/graphql/enum_type.rb +4 -0
- data/lib/graphql/execution/execute.rb +3 -3
- data/lib/graphql/execution/field_result.rb +1 -1
- data/lib/graphql/execution/lazy/resolve.rb +10 -9
- data/lib/graphql/execution/multiplex.rb +6 -5
- data/lib/graphql/input_object_type.rb +5 -1
- data/lib/graphql/interface_type.rb +12 -3
- data/lib/graphql/query.rb +21 -5
- data/lib/graphql/query/context.rb +11 -0
- data/lib/graphql/schema.rb +48 -27
- data/lib/graphql/schema/build_from_definition.rb +1 -1
- data/lib/graphql/schema/build_from_definition/resolve_map.rb +2 -2
- data/lib/graphql/schema/loader.rb +1 -1
- data/lib/graphql/schema/traversal.rb +91 -0
- data/lib/graphql/schema/validation.rb +1 -1
- data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +41 -7
- data/lib/graphql/union_type.rb +13 -2
- data/lib/graphql/version.rb +1 -1
- data/readme.md +1 -3
- data/spec/generators/graphql/install_generator_spec.rb +3 -1
- data/spec/generators/graphql/mutation_generator_spec.rb +14 -0
- data/spec/graphql/analysis/max_query_complexity_spec.rb +12 -1
- data/spec/graphql/analysis/query_complexity_spec.rb +1 -1
- data/spec/graphql/argument_spec.rb +29 -0
- data/spec/graphql/define/assign_argument_spec.rb +4 -4
- data/spec/graphql/define/instance_definable_spec.rb +1 -1
- data/spec/graphql/enum_type_spec.rb +8 -0
- data/spec/graphql/execution/lazy_spec.rb +30 -3
- data/spec/graphql/interface_type_spec.rb +44 -0
- data/spec/graphql/introspection/schema_type_spec.rb +3 -0
- data/spec/graphql/introspection/type_type_spec.rb +1 -0
- data/spec/graphql/object_type_spec.rb +8 -3
- data/spec/graphql/query/context_spec.rb +18 -0
- data/spec/graphql/query/executor_spec.rb +1 -1
- data/spec/graphql/query/literal_input_spec.rb +31 -15
- data/spec/graphql/query/serial_execution/value_resolution_spec.rb +1 -1
- data/spec/graphql/query/variables_spec.rb +25 -1
- data/spec/graphql/query_spec.rb +24 -9
- data/spec/graphql/relay/mutation_spec.rb +1 -1
- data/spec/graphql/schema/build_from_definition_spec.rb +1 -1
- data/spec/graphql/schema/loader_spec.rb +1 -1
- data/spec/graphql/schema/printer_spec.rb +1 -1
- data/spec/graphql/schema/{reduce_types_spec.rb → traversal_spec.rb} +21 -4
- data/spec/graphql/schema/warden_spec.rb +1 -1
- data/spec/graphql/schema_spec.rb +23 -2
- data/spec/graphql/static_validation/rules/variable_usages_are_allowed_spec.rb +133 -0
- data/spec/graphql/union_type_spec.rb +53 -0
- data/spec/spec_helper.rb +9 -0
- data/spec/support/dummy/data.rb +14 -5
- data/spec/support/dummy/schema.rb +46 -5
- data/spec/support/star_wars/data.rb +10 -6
- data/spec/support/star_wars/schema.rb +5 -2
- metadata +8 -7
- data/lib/graphql/schema/instrumented_field_map.rb +0 -40
- data/lib/graphql/schema/reduce_types.rb +0 -69
- data/lib/graphql/schema/type_map.rb +0 -31
@@ -24,6 +24,13 @@ describe GraphQL::Query::Context do
|
|
24
24
|
field :pushContext, types.Int do
|
25
25
|
resolve ->(t,a,c) { CTX << c; 1 }
|
26
26
|
end
|
27
|
+
|
28
|
+
field :pushQueryError, types.Int do
|
29
|
+
resolve ->(t,a,c) {
|
30
|
+
c.query.context.add_error(GraphQL::ExecutionError.new("Query-level error"))
|
31
|
+
1
|
32
|
+
}
|
33
|
+
end
|
27
34
|
}}
|
28
35
|
let(:schema) { GraphQL::Schema.define(query: query_type, mutation: nil)}
|
29
36
|
let(:result) { schema.execute(query_string, context: {"some_key" => "some value"})}
|
@@ -118,4 +125,15 @@ describe GraphQL::Query::Context do
|
|
118
125
|
assert_equal [2, 9], [err.ast_node.line, err.ast_node.col]
|
119
126
|
end
|
120
127
|
end
|
128
|
+
|
129
|
+
describe "query-level errors" do
|
130
|
+
let(:query_string) { %|
|
131
|
+
{ pushQueryError }
|
132
|
+
|}
|
133
|
+
|
134
|
+
it "allows query-level errors" do
|
135
|
+
expected_err = { "message" => "Query-level error" }
|
136
|
+
assert_equal [expected_err], result["errors"]
|
137
|
+
end
|
138
|
+
end
|
121
139
|
end
|
@@ -119,7 +119,7 @@ describe GraphQL::Query::Executor do
|
|
119
119
|
end
|
120
120
|
end
|
121
121
|
|
122
|
-
GraphQL::Schema.define(query: DummyQueryType, mutation: Dummy::DairyAppMutationType, resolve_type: :pass, id_from_object: :pass)
|
122
|
+
GraphQL::Schema.define(query: DummyQueryType, mutation: Dummy::DairyAppMutationType, resolve_type: ->(a,b,c) { :pass }, id_from_object: :pass)
|
123
123
|
}
|
124
124
|
let(:variables) { nil }
|
125
125
|
let(:query_string) { %|
|
@@ -5,8 +5,8 @@ describe GraphQL::Query::LiteralInput do
|
|
5
5
|
describe ".from_arguments" do
|
6
6
|
describe "arguments are prepared" do
|
7
7
|
let(:schema) {
|
8
|
-
|
9
|
-
name "
|
8
|
+
type = GraphQL::ObjectType.define do
|
9
|
+
name "SomeType"
|
10
10
|
|
11
11
|
field :addToArgumentValue do
|
12
12
|
type !types.Int
|
@@ -35,40 +35,56 @@ describe GraphQL::Query::LiteralInput do
|
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
38
|
+
query = GraphQL::ObjectType.define do
|
39
|
+
name "Query"
|
40
|
+
|
41
|
+
field :top, type, resolve: ->(_, _, _) { true }
|
42
|
+
end
|
43
|
+
|
38
44
|
GraphQL::Schema.define(query: query)
|
39
45
|
}
|
40
46
|
|
41
47
|
it "prepares values from query literals" do
|
42
|
-
result = schema.execute("{ addToArgumentValue(value: 1) }", context: { val: 1 })
|
43
|
-
assert_equal(result["data"]["addToArgumentValue"], 2)
|
48
|
+
result = schema.execute("{ top { addToArgumentValue(value: 1) } }", context: { val: 1 })
|
49
|
+
assert_equal(result["data"]["top"]["addToArgumentValue"], 2)
|
44
50
|
end
|
45
51
|
|
46
52
|
it "prepares default values" do
|
47
|
-
result = schema.execute("{ addToArgumentValue }", context: { val: 4 })
|
48
|
-
assert_equal(7, result["data"]["addToArgumentValue"])
|
53
|
+
result = schema.execute("{ top { addToArgumentValue } }", context: { val: 4 })
|
54
|
+
assert_equal(7, result["data"]["top"]["addToArgumentValue"])
|
49
55
|
end
|
50
56
|
|
51
57
|
it "raises an execution error if the default value is bad" do
|
52
|
-
result = schema.execute("{ fieldWithArgumentThatIsBadByDefault }", context: { })
|
53
|
-
assert_equal(result["
|
58
|
+
result = schema.execute("{ top { fieldWithArgumentThatIsBadByDefault } }", context: { })
|
59
|
+
assert_equal(result["data"], {
|
60
|
+
"top"=>{
|
61
|
+
"fieldWithArgumentThatIsBadByDefault"=>nil}
|
62
|
+
})
|
63
|
+
assert_equal(result["errors"], [
|
64
|
+
{"message"=>"Always bad",
|
65
|
+
"locations"=>[{"line"=>1, "column"=>9}],
|
66
|
+
"path"=>["top", "fieldWithArgumentThatIsBadByDefault"]}
|
67
|
+
])
|
54
68
|
end
|
55
69
|
|
56
70
|
it "prepares values from variables" do
|
57
|
-
result = schema.execute("query ($value: Int!) { addToArgumentValue(value: $value) }", variables: { "value" => 1}, context: { val: 2 } )
|
58
|
-
assert_equal(result["data"]["addToArgumentValue"], 3)
|
71
|
+
result = schema.execute("query ($value: Int!) { top { addToArgumentValue(value: $value) } }", variables: { "value" => 1}, context: { val: 2 } )
|
72
|
+
assert_equal(result["data"]["top"]["addToArgumentValue"], 3)
|
59
73
|
end
|
60
74
|
|
61
75
|
it "prepares values correctly if called multiple times with different arguments" do
|
62
|
-
result = schema.execute("{ first: addToArgumentValue(value: 1) second: addToArgumentValue(value: 2) }", context: { val: 3 })
|
63
|
-
assert_equal(result["data"]["first"], 4)
|
64
|
-
assert_equal(result["data"]["second"], 5)
|
76
|
+
result = schema.execute("{ top { first: addToArgumentValue(value: 1) second: addToArgumentValue(value: 2) } }", context: { val: 3 })
|
77
|
+
assert_equal(result["data"]["top"]["first"], 4)
|
78
|
+
assert_equal(result["data"]["top"]["second"], 5)
|
65
79
|
end
|
66
80
|
|
67
81
|
it "adds message to errors key if an ExecutionError is returned from the prepare function" do
|
68
|
-
result = schema.execute("{ addToArgumentValue(value: 999) }")
|
82
|
+
result = schema.execute("{ top { addToArgumentValue(value: 999) } }")
|
83
|
+
assert_equal(result["data"]["top"], nil)
|
69
84
|
assert_equal(result["errors"][0]["message"], "Can't return more than 3 digits")
|
70
85
|
assert_equal(result["errors"][0]["locations"][0]["line"], 1)
|
71
|
-
assert_equal(result["errors"][0]["locations"][0]["column"],
|
86
|
+
assert_equal(result["errors"][0]["locations"][0]["column"], 28)
|
87
|
+
assert_equal(result["errors"][0]["path"], ["top", "addToArgumentValue"])
|
72
88
|
end
|
73
89
|
end
|
74
90
|
end
|
@@ -16,7 +16,8 @@ describe GraphQL::Query::Variables do
|
|
16
16
|
|}
|
17
17
|
let(:ast_variables) { GraphQL.parse(query_string).definitions.first.variables }
|
18
18
|
let(:schema) { Dummy::Schema }
|
19
|
-
let(:variables) {
|
19
|
+
let(:variables) {
|
20
|
+
GraphQL::Query::Variables.new(
|
20
21
|
OpenStruct.new({
|
21
22
|
schema: schema,
|
22
23
|
warden: GraphQL::Schema::Warden.new(schema.default_filter, schema: schema, context: nil),
|
@@ -34,6 +35,29 @@ describe GraphQL::Query::Variables do
|
|
34
35
|
end
|
35
36
|
end
|
36
37
|
|
38
|
+
describe "validating input objects" do
|
39
|
+
let(:query_string) {%|
|
40
|
+
query searchMyDairy (
|
41
|
+
$product: DairyProductInput
|
42
|
+
) {
|
43
|
+
searchDairy(product: $product) {
|
44
|
+
... on Cheese {
|
45
|
+
flavor
|
46
|
+
}
|
47
|
+
}
|
48
|
+
}
|
49
|
+
|}
|
50
|
+
|
51
|
+
describe "when provided input is an array" do
|
52
|
+
let(:provided_variables) { { "product" => [] } }
|
53
|
+
|
54
|
+
it "validates invalid input objects" do
|
55
|
+
expected = "Variable product of type DairyProductInput was provided invalid value"
|
56
|
+
assert_equal expected, variables.errors.first.message
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
37
61
|
describe "nullable variables" do
|
38
62
|
module ObjectWithThingsCount
|
39
63
|
def self.thingsCount(args, ctx) # rubocop:disable Style/MethodName
|
data/spec/graphql/query_spec.rb
CHANGED
@@ -45,15 +45,15 @@ describe GraphQL::Query do
|
|
45
45
|
let(:result) { query.result }
|
46
46
|
|
47
47
|
describe "when passed no query string or document" do
|
48
|
-
it '
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
48
|
+
it 'returns an error to the client' do
|
49
|
+
res = GraphQL::Query.new(
|
50
|
+
schema,
|
51
|
+
variables: query_variables,
|
52
|
+
operation_name: operation_name,
|
53
|
+
max_depth: max_depth,
|
54
|
+
).result
|
55
|
+
assert_equal 1, res["errors"].length
|
56
|
+
assert_equal "No query string was present", res["errors"][0]["message"]
|
57
57
|
end
|
58
58
|
|
59
59
|
it 'can be assigned later' do
|
@@ -94,6 +94,21 @@ describe GraphQL::Query do
|
|
94
94
|
assert_equal "q3", query.selected_operation_name
|
95
95
|
end
|
96
96
|
end
|
97
|
+
|
98
|
+
describe "assigning operation_name=" do
|
99
|
+
let(:query_string) { <<-GRAPHQL
|
100
|
+
query q3 { manchego: cheese(id: 3) { flavor } }
|
101
|
+
query q2 { gouda: cheese(id: 2) { flavor } }
|
102
|
+
GRAPHQL
|
103
|
+
}
|
104
|
+
|
105
|
+
it "runs the assigned name" do
|
106
|
+
query = GraphQL::Query.new(Dummy::Schema, query_string, operation_name: "q3")
|
107
|
+
query.operation_name = "q2"
|
108
|
+
res = query.result
|
109
|
+
assert_equal "Gouda", res["data"]["gouda"]["flavor"]
|
110
|
+
end
|
111
|
+
end
|
97
112
|
end
|
98
113
|
|
99
114
|
describe "when passed a document instance" do
|
@@ -1,9 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
require "spec_helper"
|
3
3
|
|
4
|
-
describe GraphQL::Schema::
|
4
|
+
describe GraphQL::Schema::Traversal do
|
5
5
|
def reduce_types(types)
|
6
|
-
GraphQL::Schema
|
6
|
+
schema = GraphQL::Schema.define(orphan_types: types, resolve_type: :dummy)
|
7
|
+
traversal = GraphQL::Schema::Traversal.new(schema, introspection: false)
|
8
|
+
traversal.type_map
|
7
9
|
end
|
8
10
|
|
9
11
|
it "finds types from a single type and its fields" do
|
@@ -12,13 +14,14 @@ describe GraphQL::Schema::ReduceTypes do
|
|
12
14
|
"Float" => GraphQL::FLOAT_TYPE,
|
13
15
|
"String" => GraphQL::STRING_TYPE,
|
14
16
|
"Edible" => Dummy::EdibleInterface,
|
17
|
+
"EdibleAsMilk" => Dummy::EdibleAsMilkInterface,
|
15
18
|
"DairyAnimal" => Dummy::DairyAnimalEnum,
|
16
19
|
"Int" => GraphQL::INT_TYPE,
|
17
20
|
"AnimalProduct" => Dummy::AnimalProductInterface,
|
18
21
|
"LocalProduct" => Dummy::LocalProductInterface,
|
19
22
|
}
|
20
23
|
result = reduce_types([Dummy::CheeseType])
|
21
|
-
assert_equal(expected.keys, result.keys)
|
24
|
+
assert_equal(expected.keys.sort, result.keys.sort)
|
22
25
|
assert_equal(expected, result.to_h)
|
23
26
|
end
|
24
27
|
|
@@ -27,6 +30,20 @@ describe GraphQL::Schema::ReduceTypes do
|
|
27
30
|
assert_equal(Dummy::DairyProductInputType, result["DairyProductInput"])
|
28
31
|
end
|
29
32
|
|
33
|
+
it "finds types from field instrumentation" do
|
34
|
+
type = GraphQL::ObjectType.define do
|
35
|
+
name "ArgTypeTest"
|
36
|
+
connection :t, type.connection_type
|
37
|
+
end
|
38
|
+
|
39
|
+
result = reduce_types([type])
|
40
|
+
expected_types = [
|
41
|
+
"ArgTypeTest", "ArgTypeTestConnection", "ArgTypeTestEdge",
|
42
|
+
"Boolean", "Int", "PageInfo", "String"
|
43
|
+
]
|
44
|
+
assert_equal expected_types, result.keys.sort
|
45
|
+
end
|
46
|
+
|
30
47
|
it "finds types from nested InputObjectTypes" do
|
31
48
|
type_child = GraphQL::InputObjectType.define do
|
32
49
|
name "InputTypeChild"
|
@@ -92,7 +109,7 @@ describe GraphQL::Schema::ReduceTypes do
|
|
92
109
|
describe "when getting a type which doesnt exist" do
|
93
110
|
it "raises an error" do
|
94
111
|
type_map = reduce_types([])
|
95
|
-
assert_raises(
|
112
|
+
assert_raises(KeyError) { type_map.fetch("SomeType") }
|
96
113
|
end
|
97
114
|
end
|
98
115
|
|
data/spec/graphql/schema_spec.rb
CHANGED
@@ -99,7 +99,7 @@ describe GraphQL::Schema do
|
|
99
99
|
assert_raises(NotImplementedError) {
|
100
100
|
GraphQL::Schema.define do
|
101
101
|
query(query_type)
|
102
|
-
resolve_type
|
102
|
+
resolve_type NO_OP_RESOLVE_TYPE
|
103
103
|
end
|
104
104
|
}
|
105
105
|
end
|
@@ -125,7 +125,7 @@ describe GraphQL::Schema do
|
|
125
125
|
assert_raises(NotImplementedError) {
|
126
126
|
GraphQL::Schema.define do
|
127
127
|
query(query_type)
|
128
|
-
resolve_type
|
128
|
+
resolve_type NO_OP_RESOLVE_TYPE
|
129
129
|
end
|
130
130
|
}
|
131
131
|
end
|
@@ -293,6 +293,27 @@ type Query {
|
|
293
293
|
res = schema.execute("query { int(value: 2) } ")
|
294
294
|
assert_equal 24, res["data"]["int"]
|
295
295
|
end
|
296
|
+
|
297
|
+
class CyclicalDependencyInstrumentation
|
298
|
+
def initialize(schema)
|
299
|
+
@schema = schema
|
300
|
+
end
|
301
|
+
|
302
|
+
def instrument(type, field)
|
303
|
+
@schema.types # infinite loop
|
304
|
+
field
|
305
|
+
end
|
306
|
+
end
|
307
|
+
|
308
|
+
describe "field instrumenters which cause loops" do
|
309
|
+
it "has a nice error message" do
|
310
|
+
assert_raises(GraphQL::Schema::CyclicalDefinitionError) do
|
311
|
+
schema.redefine {
|
312
|
+
instrument(:field, CyclicalDependencyInstrumentation.new(self.target))
|
313
|
+
}
|
314
|
+
end
|
315
|
+
end
|
316
|
+
end
|
296
317
|
end
|
297
318
|
|
298
319
|
describe "#lazy? / #lazy_method_name" do
|
@@ -80,4 +80,137 @@ describe GraphQL::StaticValidation::VariableUsagesAreAllowed do
|
|
80
80
|
assert_equal "Argument 'id' on Field 'cheese' has an invalid value. Expected type 'Int!'.", errors[0]["message"]
|
81
81
|
end
|
82
82
|
end
|
83
|
+
|
84
|
+
describe "list-type variables" do
|
85
|
+
let(:schema) {
|
86
|
+
GraphQL::Schema.from_definition <<-GRAPHQL
|
87
|
+
input ImageSize {
|
88
|
+
height: Int
|
89
|
+
width: Int
|
90
|
+
scale: Int
|
91
|
+
}
|
92
|
+
|
93
|
+
type Query {
|
94
|
+
imageUrl(height: Int, width: Int, size: ImageSize, sizes: [ImageSize!]): String!
|
95
|
+
}
|
96
|
+
GRAPHQL
|
97
|
+
}
|
98
|
+
|
99
|
+
describe "nullability mismatch" do
|
100
|
+
let(:query_string) {
|
101
|
+
<<-GRAPHQL
|
102
|
+
# This variable _should_ be [ImageSize!]
|
103
|
+
query ($sizes: [ImageSize]) {
|
104
|
+
imageUrl(sizes: $sizes)
|
105
|
+
}
|
106
|
+
GRAPHQL
|
107
|
+
}
|
108
|
+
|
109
|
+
it "finds invalid inner definitions" do
|
110
|
+
assert_equal 1, errors.size
|
111
|
+
expected_message = "Nullability mismatch on variable $sizes and argument sizes ([ImageSize] / [ImageSize!])"
|
112
|
+
assert_equal [expected_message], errors.map { |e| e["message"] }
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
describe "list dimension mismatch" do
|
117
|
+
let(:query_string) {
|
118
|
+
<<-GRAPHQL
|
119
|
+
query ($sizes: [ImageSize]) {
|
120
|
+
imageUrl(sizes: [$sizes])
|
121
|
+
}
|
122
|
+
GRAPHQL
|
123
|
+
}
|
124
|
+
|
125
|
+
it "finds invalid inner definitions" do
|
126
|
+
assert_equal 1, errors.size
|
127
|
+
expected_message = "List dimension mismatch on variable $sizes and argument sizes ([[ImageSize]] / [ImageSize!])"
|
128
|
+
assert_equal [expected_message], errors.map { |e| e["message"] }
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
describe 'list is in the argument' do
|
133
|
+
let(:query_string) {
|
134
|
+
<<-GRAPHQL
|
135
|
+
query ($size: ImageSize!) {
|
136
|
+
imageUrl(sizes: [$size])
|
137
|
+
}
|
138
|
+
GRAPHQL
|
139
|
+
}
|
140
|
+
|
141
|
+
it "is a valid query" do
|
142
|
+
assert_equal 0, errors.size
|
143
|
+
end
|
144
|
+
|
145
|
+
describe "mixed with invalid literals" do
|
146
|
+
let(:query_string) {
|
147
|
+
<<-GRAPHQL
|
148
|
+
query ($size: ImageSize!) {
|
149
|
+
imageUrl(sizes: [$size, 1, true])
|
150
|
+
}
|
151
|
+
GRAPHQL
|
152
|
+
}
|
153
|
+
|
154
|
+
it "is an invalid query" do
|
155
|
+
assert_equal 1, errors.size
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
describe "mixed with invalid variables" do
|
160
|
+
let(:query_string) {
|
161
|
+
<<-GRAPHQL
|
162
|
+
query ($size: ImageSize!, $wrongSize: Boolean!) {
|
163
|
+
imageUrl(sizes: [$size, $wrongSize])
|
164
|
+
}
|
165
|
+
GRAPHQL
|
166
|
+
}
|
167
|
+
|
168
|
+
it "is an invalid query" do
|
169
|
+
assert_equal 1, errors.size
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
describe "mixed with valid literals and invalid variables" do
|
174
|
+
let(:query_string) {
|
175
|
+
<<-GRAPHQL
|
176
|
+
query ($size: ImageSize!, $wrongSize: Boolean!) {
|
177
|
+
imageUrl(sizes: [$size, {height: 100} $wrongSize])
|
178
|
+
}
|
179
|
+
GRAPHQL
|
180
|
+
}
|
181
|
+
|
182
|
+
it "is an invalid query" do
|
183
|
+
assert_equal 1, errors.size
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
describe 'argument contains a list with literal values' do
|
189
|
+
let(:query_string) {
|
190
|
+
<<-GRAPHQL
|
191
|
+
query {
|
192
|
+
imageUrl(sizes: [{height: 100, width: 100, scale: 1}])
|
193
|
+
}
|
194
|
+
GRAPHQL
|
195
|
+
}
|
196
|
+
|
197
|
+
it "is a valid query" do
|
198
|
+
assert_equal 0, errors.size
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
describe 'argument contains a list with both literal and variable values' do
|
203
|
+
let(:query_string) {
|
204
|
+
<<-GRAPHQL
|
205
|
+
query($size1: ImageSize!, $size2: ImageSize!) {
|
206
|
+
imageUrl(sizes: [{height: 100, width: 100, scale: 1}, $size1, {height: 1920, width: 1080, scale: 2}, $size2])
|
207
|
+
}
|
208
|
+
GRAPHQL
|
209
|
+
}
|
210
|
+
|
211
|
+
it "is a valid query" do
|
212
|
+
assert_equal 0, errors.size
|
213
|
+
end
|
214
|
+
end
|
215
|
+
end
|
83
216
|
end
|