graphql 0.18.15 → 0.19.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/graphql/define/assign_global_id_field.rb +1 -2
- data/lib/graphql/directive.rb +41 -7
- data/lib/graphql/directive/deprecated_directive.rb +11 -0
- data/lib/graphql/directive/include_directive.rb +2 -2
- data/lib/graphql/directive/skip_directive.rb +2 -2
- data/lib/graphql/input_object_type.rb +14 -0
- data/lib/graphql/internal_representation/node.rb +8 -4
- data/lib/graphql/introspection/arguments_field.rb +0 -1
- data/lib/graphql/introspection/directive_location_enum.rb +3 -2
- data/lib/graphql/introspection/directive_type.rb +12 -7
- data/lib/graphql/introspection/enum_value_type.rb +4 -2
- data/lib/graphql/introspection/enum_values_field.rb +0 -1
- data/lib/graphql/introspection/field_type.rb +8 -7
- data/lib/graphql/introspection/fields_field.rb +0 -1
- data/lib/graphql/introspection/input_fields_field.rb +0 -1
- data/lib/graphql/introspection/input_value_type.rb +8 -10
- data/lib/graphql/introspection/interfaces_field.rb +0 -1
- data/lib/graphql/introspection/of_type_field.rb +0 -1
- data/lib/graphql/introspection/possible_types_field.rb +0 -1
- data/lib/graphql/introspection/schema_type.rb +11 -9
- data/lib/graphql/introspection/type_kind_enum.rb +3 -3
- data/lib/graphql/introspection/type_type.rb +9 -6
- data/lib/graphql/language/generation.rb +4 -1
- data/lib/graphql/language/lexer.rb +353 -316
- data/lib/graphql/language/lexer.rl +8 -6
- data/lib/graphql/language/nodes.rb +12 -0
- data/lib/graphql/language/parser.rb +553 -501
- data/lib/graphql/language/parser.y +26 -16
- data/lib/graphql/language/parser_tests.rb +20 -1
- data/lib/graphql/list_type.rb +5 -1
- data/lib/graphql/non_null_type.rb +4 -0
- data/lib/graphql/object_type.rb +1 -1
- data/lib/graphql/query/literal_input.rb +1 -1
- data/lib/graphql/relay.rb +1 -1
- data/lib/graphql/relay/global_id_resolve.rb +3 -5
- data/lib/graphql/relay/node.rb +34 -0
- data/lib/graphql/scalar_type.rb +1 -1
- data/lib/graphql/schema.rb +43 -15
- data/lib/graphql/schema/loader.rb +2 -2
- data/lib/graphql/schema/printer.rb +50 -8
- data/lib/graphql/schema/unique_within_type.rb +28 -0
- data/lib/graphql/schema/validation.rb +10 -3
- data/lib/graphql/static_validation/rules/fields_will_merge.rb +9 -1
- data/lib/graphql/static_validation/rules/fragment_spreads_are_possible.rb +8 -2
- data/lib/graphql/type_kinds.rb +12 -12
- data/lib/graphql/version.rb +1 -1
- data/readme.md +6 -5
- data/spec/graphql/argument_spec.rb +1 -1
- data/spec/graphql/execution_error_spec.rb +53 -0
- data/spec/graphql/introspection/directive_type_spec.rb +10 -0
- data/spec/graphql/introspection/input_value_type_spec.rb +23 -0
- data/spec/graphql/language/generation_spec.rb +4 -0
- data/spec/graphql/query/executor_spec.rb +2 -2
- data/spec/graphql/relay/mutation_spec.rb +1 -1
- data/spec/graphql/relay/node_spec.rb +87 -0
- data/spec/graphql/schema/catchall_middleware_spec.rb +1 -1
- data/spec/graphql/schema/loader_spec.rb +37 -4
- data/spec/graphql/schema/printer_spec.rb +30 -7
- data/spec/graphql/schema/unique_within_type_spec.rb +27 -0
- data/spec/graphql/schema/validation_spec.rb +7 -11
- data/spec/graphql/schema_spec.rb +32 -2
- data/spec/graphql/static_validation/rules/argument_literals_are_compatible_spec.rb +14 -15
- data/spec/graphql/static_validation/rules/arguments_are_defined_spec.rb +10 -10
- data/spec/graphql/static_validation/rules/directives_are_defined_spec.rb +1 -5
- data/spec/graphql/static_validation/rules/directives_are_in_valid_locations_spec.rb +3 -5
- data/spec/graphql/static_validation/rules/fields_are_defined_on_type_spec.rb +7 -11
- data/spec/graphql/static_validation/rules/fields_have_appropriate_selections_spec.rb +1 -4
- data/spec/graphql/static_validation/rules/fields_will_merge_spec.rb +10 -13
- data/spec/graphql/static_validation/rules/fragment_spreads_are_possible_spec.rb +3 -5
- data/spec/graphql/static_validation/rules/fragment_types_exist_spec.rb +2 -4
- data/spec/graphql/static_validation/rules/fragments_are_finite_spec.rb +4 -6
- data/spec/graphql/static_validation/rules/fragments_are_named_spec.rb +2 -4
- data/spec/graphql/static_validation/rules/fragments_are_on_composite_types_spec.rb +7 -7
- data/spec/graphql/static_validation/rules/fragments_are_used_spec.rb +1 -4
- data/spec/graphql/static_validation/rules/mutation_root_exists_spec.rb +2 -4
- data/spec/graphql/static_validation/rules/required_arguments_are_present_spec.rb +3 -6
- data/spec/graphql/static_validation/rules/subscription_root_exists_spec.rb +2 -4
- data/spec/graphql/static_validation/rules/variable_default_values_are_correctly_typed_spec.rb +12 -14
- data/spec/graphql/static_validation/rules/variable_usages_are_allowed_spec.rb +7 -9
- data/spec/graphql/static_validation/rules/variables_are_input_types_spec.rb +20 -22
- data/spec/graphql/static_validation/rules/variables_are_used_and_defined_spec.rb +27 -23
- data/spec/spec_helper.rb +1 -0
- data/spec/support/dairy_app.rb +2 -2
- data/spec/support/star_wars_schema.rb +15 -18
- data/spec/support/static_validation_helpers.rb +27 -0
- metadata +25 -5
- data/lib/graphql/relay/global_node_identification.rb +0 -138
- data/spec/graphql/relay/global_node_identification_spec.rb +0 -153
@@ -13,6 +13,8 @@ describe GraphQL::Schema::Printer do
|
|
13
13
|
|
14
14
|
value "FOO"
|
15
15
|
value "BAR"
|
16
|
+
value "BAZ", deprecation_reason: 'Use "BAR".'
|
17
|
+
value "WOZ", deprecation_reason: GraphQL::Directive::DEFAULT_DEPRECATION_REASON
|
16
18
|
end
|
17
19
|
|
18
20
|
sub_input_type = GraphQL::InputObjectType.define do
|
@@ -46,6 +48,7 @@ describe GraphQL::Schema::Printer do
|
|
46
48
|
field :title, !types.String
|
47
49
|
field :body, !types.String
|
48
50
|
field :comments, types[!comment_type]
|
51
|
+
field :comments_count, !types.Int, deprecation_reason: 'Use "comments".'
|
49
52
|
end
|
50
53
|
|
51
54
|
query_root = GraphQL::ObjectType.define do
|
@@ -70,14 +73,20 @@ schema {
|
|
70
73
|
query: Query
|
71
74
|
}
|
72
75
|
|
76
|
+
directive @skip(if: Boolean!) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT
|
77
|
+
|
78
|
+
directive @include(if: Boolean!) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT
|
79
|
+
|
80
|
+
directive @deprecated(reason: String = \"No longer supported\") on FIELD_DEFINITION | ENUM_VALUE
|
81
|
+
|
73
82
|
type __Directive {
|
74
83
|
name: String!
|
75
84
|
description: String
|
76
|
-
args: [__InputValue!]!
|
77
85
|
locations: [__DirectiveLocation!]!
|
78
|
-
|
79
|
-
|
80
|
-
|
86
|
+
args: [__InputValue!]!
|
87
|
+
onOperation: Boolean! @deprecated(reason: \"Use `locations`.\")
|
88
|
+
onFragment: Boolean! @deprecated(reason: \"Use `locations`.\")
|
89
|
+
onField: Boolean! @deprecated(reason: \"Use `locations`.\")
|
81
90
|
}
|
82
91
|
|
83
92
|
enum __DirectiveLocation {
|
@@ -88,21 +97,32 @@ enum __DirectiveLocation {
|
|
88
97
|
FRAGMENT_DEFINITION
|
89
98
|
FRAGMENT_SPREAD
|
90
99
|
INLINE_FRAGMENT
|
100
|
+
SCHEMA
|
101
|
+
SCALAR
|
102
|
+
OBJECT
|
103
|
+
FIELD_DEFINITION
|
104
|
+
ARGUMENT_DEFINITION
|
105
|
+
INTERFACE
|
106
|
+
UNION
|
107
|
+
ENUM
|
108
|
+
ENUM_VALUE
|
109
|
+
INPUT_OBJECT
|
110
|
+
INPUT_FIELD_DEFINITION
|
91
111
|
}
|
92
112
|
|
93
113
|
type __EnumValue {
|
94
114
|
name: String!
|
95
115
|
description: String
|
96
|
-
deprecationReason: String
|
97
116
|
isDeprecated: Boolean!
|
117
|
+
deprecationReason: String
|
98
118
|
}
|
99
119
|
|
100
120
|
type __Field {
|
101
121
|
name: String!
|
102
122
|
description: String
|
123
|
+
args: [__InputValue!]!
|
103
124
|
type: __Type!
|
104
125
|
isDeprecated: Boolean!
|
105
|
-
args: [__InputValue!]!
|
106
126
|
deprecationReason: String
|
107
127
|
}
|
108
128
|
|
@@ -115,10 +135,10 @@ type __InputValue {
|
|
115
135
|
|
116
136
|
type __Schema {
|
117
137
|
types: [__Type!]!
|
118
|
-
directives: [__Directive!]!
|
119
138
|
queryType: __Type!
|
120
139
|
mutationType: __Type
|
121
140
|
subscriptionType: __Type
|
141
|
+
directives: [__Directive!]!
|
122
142
|
}
|
123
143
|
|
124
144
|
type __Type {
|
@@ -158,6 +178,8 @@ schema {
|
|
158
178
|
enum Choice {
|
159
179
|
FOO
|
160
180
|
BAR
|
181
|
+
BAZ @deprecated(reason: "Use \\\"BAR\\\".")
|
182
|
+
WOZ @deprecated
|
161
183
|
}
|
162
184
|
|
163
185
|
type Comment implements Node {
|
@@ -173,6 +195,7 @@ type Post {
|
|
173
195
|
title: String!
|
174
196
|
body: String!
|
175
197
|
comments: [Comment!]
|
198
|
+
comments_count: Int! @deprecated(reason: \"Use \\\"comments\\\".\")
|
176
199
|
}
|
177
200
|
|
178
201
|
type Query {
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe GraphQL::Schema::UniqueWithinType do
|
4
|
+
describe 'encode / decode' do
|
5
|
+
it 'Converts typename and ID to and from ID' do
|
6
|
+
global_id = GraphQL::Schema::UniqueWithinType.encode("SomeType", 123)
|
7
|
+
type_name, id = GraphQL::Schema::UniqueWithinType.decode(global_id)
|
8
|
+
assert_equal("SomeType", type_name)
|
9
|
+
assert_equal("123", id)
|
10
|
+
end
|
11
|
+
|
12
|
+
it "allows you to specify the separator" do
|
13
|
+
custom_separator = "---"
|
14
|
+
global_id = GraphQL::Schema::UniqueWithinType.encode("Type-With-UUID", "250cda0e-a89d-41cf-99e1-2872d89f1100", separator: custom_separator)
|
15
|
+
type_name, id = GraphQL::Schema::UniqueWithinType.decode(global_id, separator: custom_separator)
|
16
|
+
assert_equal("Type-With-UUID", type_name)
|
17
|
+
assert_equal("250cda0e-a89d-41cf-99e1-2872d89f1100", id)
|
18
|
+
end
|
19
|
+
|
20
|
+
it "raises an error if you try and use a reserved character in the ID" do
|
21
|
+
err = assert_raises(RuntimeError) {
|
22
|
+
GraphQL::Schema::UniqueWithinType.encode("Best-Thing", "234")
|
23
|
+
}
|
24
|
+
assert_includes err.message, "encode(Best-Thing, 234) contains reserved characters `-`"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -34,7 +34,7 @@ describe GraphQL::Schema::Validation do
|
|
34
34
|
name "InvalidArgument"
|
35
35
|
type !types[!GraphQL::INT_TYPE]
|
36
36
|
argument :invalid do
|
37
|
-
type GraphQL::
|
37
|
+
type GraphQL::FLOAT_TYPE
|
38
38
|
default_value [1,2,3]
|
39
39
|
end
|
40
40
|
end
|
@@ -53,7 +53,7 @@ describe GraphQL::Schema::Validation do
|
|
53
53
|
end
|
54
54
|
|
55
55
|
it "applies validation to its member Arguments" do
|
56
|
-
assert_error_includes invalid_argument_member_field, "default value [1, 2, 3] is not valid for type
|
56
|
+
assert_error_includes invalid_argument_member_field, "default value [1, 2, 3] is not valid for type Float"
|
57
57
|
end
|
58
58
|
end
|
59
59
|
|
@@ -159,7 +159,7 @@ describe GraphQL::Schema::Validation do
|
|
159
159
|
name "InvalidArgumentMember"
|
160
160
|
argument :nonsense do
|
161
161
|
type GraphQL::FLOAT_TYPE
|
162
|
-
default_value "xyz"
|
162
|
+
default_value ["xyz"]
|
163
163
|
end
|
164
164
|
end
|
165
165
|
}
|
@@ -169,7 +169,7 @@ describe GraphQL::Schema::Validation do
|
|
169
169
|
end
|
170
170
|
|
171
171
|
it "applies validation to its member Arguments" do
|
172
|
-
assert_error_includes invalid_argument_member_input, "default value \"xyz\" is not valid for type Float"
|
172
|
+
assert_error_includes invalid_argument_member_input, "default value [\"xyz\"] is not valid for type Float"
|
173
173
|
end
|
174
174
|
end
|
175
175
|
|
@@ -180,15 +180,15 @@ describe GraphQL::Schema::Validation do
|
|
180
180
|
field :invalid do
|
181
181
|
type GraphQL::BOOLEAN_TYPE
|
182
182
|
argument :invalid do
|
183
|
-
type GraphQL::
|
184
|
-
default_value
|
183
|
+
type GraphQL::FLOAT_TYPE
|
184
|
+
default_value ["123"]
|
185
185
|
end
|
186
186
|
end
|
187
187
|
end
|
188
188
|
}
|
189
189
|
|
190
190
|
it "validates fields" do
|
191
|
-
assert_error_includes invalid_field_interface, "default value
|
191
|
+
assert_error_includes invalid_field_interface, "default value [\"123\"] is not valid for type Float"
|
192
192
|
end
|
193
193
|
end
|
194
194
|
|
@@ -211,9 +211,5 @@ describe GraphQL::Schema::Validation do
|
|
211
211
|
it "requires the type is a Base type" do
|
212
212
|
assert_error_includes untyped_argument, "must be a valid input type (Scalar or InputObject), not Symbol"
|
213
213
|
end
|
214
|
-
|
215
|
-
it "requires the default value is compatible" do
|
216
|
-
assert_error_includes invalid_default_argument, 'default value "abc" is not valid for type Int'
|
217
|
-
end
|
218
214
|
end
|
219
215
|
end
|
data/spec/graphql/schema_spec.rb
CHANGED
@@ -2,6 +2,8 @@ require "spec_helper"
|
|
2
2
|
|
3
3
|
describe GraphQL::Schema do
|
4
4
|
let(:schema) { DummySchema }
|
5
|
+
let(:relay_schema) { StarWarsSchema }
|
6
|
+
let(:empty_schema) { GraphQL::Schema.define }
|
5
7
|
|
6
8
|
describe "#rescue_from" do
|
7
9
|
let(:rescue_middleware) { schema.middleware.first }
|
@@ -24,7 +26,7 @@ describe GraphQL::Schema do
|
|
24
26
|
describe "#resolve_type" do
|
25
27
|
describe "when the return value is nil" do
|
26
28
|
it "returns nil" do
|
27
|
-
result =
|
29
|
+
result = relay_schema.resolve_type(123, nil)
|
28
30
|
assert_equal(nil, result)
|
29
31
|
end
|
30
32
|
end
|
@@ -32,10 +34,38 @@ describe GraphQL::Schema do
|
|
32
34
|
describe "when the return value is not a BaseType" do
|
33
35
|
it "raises an error " do
|
34
36
|
err = assert_raises(RuntimeError) {
|
35
|
-
|
37
|
+
relay_schema.resolve_type(:test_error, nil)
|
36
38
|
}
|
37
39
|
assert_includes err.message, "not_a_type (Symbol)"
|
38
40
|
end
|
39
41
|
end
|
42
|
+
|
43
|
+
describe "when the hook wasn't implemented" do
|
44
|
+
it "raises not implemented" do
|
45
|
+
assert_raises(NotImplementedError) {
|
46
|
+
empty_schema.resolve_type(nil, nil)
|
47
|
+
}
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe "object_from_id" do
|
53
|
+
describe "when the hook wasn't implemented" do
|
54
|
+
it "raises not implemented" do
|
55
|
+
assert_raises(NotImplementedError) {
|
56
|
+
empty_schema.object_from_id(nil, nil)
|
57
|
+
}
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
describe "id_from_object" do
|
63
|
+
describe "when the hook wasn't implemented" do
|
64
|
+
it "raises not implemented" do
|
65
|
+
assert_raises(NotImplementedError) {
|
66
|
+
empty_schema.id_from_object(nil, nil, nil)
|
67
|
+
}
|
68
|
+
end
|
69
|
+
end
|
40
70
|
end
|
41
71
|
end
|
@@ -1,33 +1,32 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
3
|
describe GraphQL::StaticValidation::ArgumentLiteralsAreCompatible do
|
4
|
+
include StaticValidationHelpers
|
5
|
+
|
4
6
|
let(:query_string) {%|
|
5
7
|
query getCheese {
|
6
|
-
cheese(id: "aasdlkfj") {
|
7
|
-
cheese(id: 1) { source @skip(if:
|
8
|
-
yakSource: searchDairy(product: [{source: COW, fatContent: 1.1}]) {
|
9
|
-
badSource: searchDairy(product: [{source: 1.1}]) {
|
10
|
-
missingSource: searchDairy(product: [{fatContent: 1.1}]) {
|
11
|
-
listCoerce: cheese(id: 1) { similarCheese(source: YAK) }
|
12
|
-
missingInputField: searchDairy(product: [{source: YAK, wacky: 1}])
|
8
|
+
stringCheese: cheese(id: "aasdlkfj") { ...cheeseFields }
|
9
|
+
cheese(id: 1) { source @skip(if: "whatever") }
|
10
|
+
yakSource: searchDairy(product: [{source: COW, fatContent: 1.1}]) { __typename }
|
11
|
+
badSource: searchDairy(product: [{source: 1.1}]) { __typename }
|
12
|
+
missingSource: searchDairy(product: [{fatContent: 1.1}]) { __typename }
|
13
|
+
listCoerce: cheese(id: 1) { similarCheese(source: YAK) { __typename } }
|
14
|
+
missingInputField: searchDairy(product: [{source: YAK, wacky: 1}]) { __typename }
|
13
15
|
}
|
14
16
|
|
15
17
|
fragment cheeseFields on Cheese {
|
16
|
-
similarCheese(source: 4.5)
|
18
|
+
similarCheese(source: 4.5) { __typename }
|
17
19
|
}
|
18
20
|
|}
|
19
21
|
|
20
|
-
let(:validator) { GraphQL::StaticValidation::Validator.new(schema: DummySchema, rules: [GraphQL::StaticValidation::ArgumentLiteralsAreCompatible]) }
|
21
|
-
let(:query) { GraphQL::Query.new(DummySchema, query_string) }
|
22
|
-
let(:errors) { validator.validate(query)[:errors] }
|
23
|
-
|
24
22
|
it "finds undefined or missing-required arguments to fields and directives" do
|
25
|
-
|
23
|
+
# `wacky` above is handled by ArgumentsAreDefined, so only 6 are tested below
|
24
|
+
assert_equal(7, errors.length)
|
26
25
|
|
27
26
|
query_root_error = {
|
28
|
-
"message"=>"Argument 'id' on Field '
|
27
|
+
"message"=>"Argument 'id' on Field 'stringCheese' has an invalid value. Expected type 'Int!'.",
|
29
28
|
"locations"=>[{"line"=>3, "column"=>7}],
|
30
|
-
"fields"=>["query getCheese", "
|
29
|
+
"fields"=>["query getCheese", "stringCheese", "id"],
|
31
30
|
}
|
32
31
|
assert_includes(errors, query_root_error)
|
33
32
|
|
@@ -1,25 +1,25 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
3
|
describe GraphQL::StaticValidation::ArgumentsAreDefined do
|
4
|
+
include StaticValidationHelpers
|
5
|
+
|
4
6
|
let(:query_string) {"
|
5
7
|
query getCheese {
|
6
|
-
cheese(id: 1) { source }
|
7
|
-
cheese(silly: false) { source }
|
8
|
-
searchDairy(product: [{wacky: 1}])
|
8
|
+
okCheese: cheese(id: 1) { source }
|
9
|
+
cheese(silly: false, id: 2) { source }
|
10
|
+
searchDairy(product: [{wacky: 1}]) { ...cheeseFields }
|
9
11
|
}
|
10
12
|
|
11
13
|
fragment cheeseFields on Cheese {
|
12
|
-
similarCheese(source: SHEEP, nonsense: 1)
|
13
|
-
id @skip(something: 3.4)
|
14
|
+
similarCheese(source: SHEEP, nonsense: 1) { __typename }
|
15
|
+
id @skip(something: 3.4, if: false)
|
14
16
|
}
|
15
17
|
"}
|
16
18
|
|
17
|
-
let(:validator) { GraphQL::StaticValidation::Validator.new(schema: DummySchema, rules: [GraphQL::StaticValidation::ArgumentsAreDefined]) }
|
18
|
-
let(:query) { GraphQL::Query.new(DummySchema, query_string) }
|
19
|
-
let(:errors) { validator.validate(query)[:errors] }
|
20
|
-
|
21
19
|
it "finds undefined arguments to fields and directives" do
|
22
|
-
|
20
|
+
# There's an extra error here, the unexpected argument on "DairyProductInput"
|
21
|
+
# triggers _another_ error that the field expected a different type
|
22
|
+
assert_equal(5, errors.length)
|
23
23
|
|
24
24
|
query_root_error = {
|
25
25
|
"message"=>"Field 'cheese' doesn't accept argument 'silly'",
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
3
|
describe GraphQL::StaticValidation::DirectivesAreDefined do
|
4
|
+
include StaticValidationHelpers
|
4
5
|
let(:query_string) {"
|
5
6
|
query getCheese {
|
6
7
|
okCheese: cheese(id: 1) {
|
@@ -12,11 +13,6 @@ describe GraphQL::StaticValidation::DirectivesAreDefined do
|
|
12
13
|
}
|
13
14
|
}
|
14
15
|
"}
|
15
|
-
|
16
|
-
let(:validator) { GraphQL::StaticValidation::Validator.new(schema: DummySchema, rules: [GraphQL::StaticValidation::DirectivesAreDefined]) }
|
17
|
-
let(:query) { GraphQL::Query.new(DummySchema, query_string) }
|
18
|
-
let(:errors) { validator.validate(query)[:errors] }
|
19
|
-
|
20
16
|
describe "non-existent directives" do
|
21
17
|
it "makes errors for them" do
|
22
18
|
expected = [
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
3
|
describe GraphQL::StaticValidation::DirectivesAreInValidLocations do
|
4
|
+
include StaticValidationHelpers
|
4
5
|
let(:query_string) {"
|
5
6
|
query getCheese @skip(if: true) {
|
6
7
|
okCheese: cheese(id: 1) {
|
@@ -8,6 +9,7 @@ describe GraphQL::StaticValidation::DirectivesAreInValidLocations do
|
|
8
9
|
source
|
9
10
|
... on Cheese @skip(if: true) {
|
10
11
|
flavor
|
12
|
+
... whatever
|
11
13
|
}
|
12
14
|
}
|
13
15
|
}
|
@@ -17,10 +19,6 @@ describe GraphQL::StaticValidation::DirectivesAreInValidLocations do
|
|
17
19
|
}
|
18
20
|
"}
|
19
21
|
|
20
|
-
let(:validator) { GraphQL::StaticValidation::Validator.new(schema: DummySchema, rules: [GraphQL::StaticValidation::DirectivesAreInValidLocations]) }
|
21
|
-
let(:query) { GraphQL::Query.new(DummySchema, query_string) }
|
22
|
-
let(:errors) { validator.validate(query)[:errors] }
|
23
|
-
|
24
22
|
describe "invalid directive locations" do
|
25
23
|
it "makes errors for them" do
|
26
24
|
expected = [
|
@@ -31,7 +29,7 @@ describe GraphQL::StaticValidation::DirectivesAreInValidLocations do
|
|
31
29
|
},
|
32
30
|
{
|
33
31
|
"message"=>"'@skip' can't be applied to fragment definitions (allowed: fields, fragment spreads, inline fragments)",
|
34
|
-
"locations"=>[{"line"=>
|
32
|
+
"locations"=>[{"line"=>13, "column"=>33}],
|
35
33
|
"fields"=>["fragment whatever"],
|
36
34
|
},
|
37
35
|
]
|
@@ -1,21 +1,17 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
3
|
describe GraphQL::StaticValidation::FieldsAreDefinedOnType do
|
4
|
+
include StaticValidationHelpers
|
4
5
|
let(:query_string) { "
|
5
|
-
query getCheese
|
6
|
+
query getCheese {
|
6
7
|
notDefinedField { name }
|
7
|
-
cheese(id: 1) { nonsenseField, flavor }
|
8
|
+
cheese(id: 1) { nonsenseField, flavor ...cheeseFields }
|
8
9
|
fromSource(source: COW) { bogusField }
|
9
10
|
}
|
10
11
|
|
11
12
|
fragment cheeseFields on Cheese { fatContent, hogwashField }
|
12
13
|
"}
|
13
14
|
|
14
|
-
let(:validator) { GraphQL::StaticValidation::Validator.new(schema: DummySchema, rules: [GraphQL::StaticValidation::FieldsAreDefinedOnType]) }
|
15
|
-
let(:query) { GraphQL::Query.new(DummySchema, query_string) }
|
16
|
-
let(:errors) { validator.validate(query)[:errors] }
|
17
|
-
let(:error_messages) { errors.map { |e| e["message"] } }
|
18
|
-
|
19
15
|
it "finds fields that are requested on types that don't have that field" do
|
20
16
|
expected_errors = [
|
21
17
|
"Field 'notDefinedField' doesn't exist on type 'Query'", # from query root
|
@@ -58,9 +54,9 @@ describe GraphQL::StaticValidation::FieldsAreDefinedOnType do
|
|
58
54
|
|
59
55
|
describe "on unions" do
|
60
56
|
let(:query_string) { "
|
61
|
-
query notOnUnion { favoriteEdible { ...dpFields } }
|
62
|
-
fragment
|
63
|
-
fragment
|
57
|
+
query notOnUnion { favoriteEdible { ...dpFields ...dpIndirectFields } }
|
58
|
+
fragment dpFields on DairyProduct { source }
|
59
|
+
fragment dpIndirectFields on DairyProduct { ... on Cheese { source } }
|
64
60
|
"}
|
65
61
|
|
66
62
|
|
@@ -71,7 +67,7 @@ describe GraphQL::StaticValidation::FieldsAreDefinedOnType do
|
|
71
67
|
"locations"=>[
|
72
68
|
{"line"=>3, "column"=>7}
|
73
69
|
],
|
74
|
-
"fields"=>["fragment
|
70
|
+
"fields"=>["fragment dpFields", "source"],
|
75
71
|
}
|
76
72
|
]
|
77
73
|
assert_equal(expected_errors, errors)
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
3
|
describe GraphQL::StaticValidation::FieldsHaveAppropriateSelections do
|
4
|
+
include StaticValidationHelpers
|
4
5
|
let(:query_string) {"
|
5
6
|
query getCheese {
|
6
7
|
okCheese: cheese(id: 1) { fatContent, similarCheese(source: YAK) { source } }
|
@@ -9,10 +10,6 @@ describe GraphQL::StaticValidation::FieldsHaveAppropriateSelections do
|
|
9
10
|
}
|
10
11
|
"}
|
11
12
|
|
12
|
-
let(:validator) { GraphQL::StaticValidation::Validator.new(schema: DummySchema, rules: [GraphQL::StaticValidation::FieldsHaveAppropriateSelections]) }
|
13
|
-
let(:query) { GraphQL::Query.new(DummySchema, query_string) }
|
14
|
-
let(:errors) { validator.validate(query)[:errors] }
|
15
|
-
|
16
13
|
it "adds errors for selections on scalars" do
|
17
14
|
assert_equal(2, errors.length)
|
18
15
|
|