graphql 0.18.15 → 0.19.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/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
|
|