graphql 0.18.11 → 0.18.12
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/graphql/analysis.rb +1 -0
- data/lib/graphql/analysis/field_usage.rb +44 -0
- data/lib/graphql/internal_representation/rewrite.rb +1 -1
- data/lib/graphql/query/arguments.rb +6 -0
- data/lib/graphql/query/literal_input.rb +18 -7
- data/lib/graphql/static_validation/all_rules.rb +2 -0
- data/lib/graphql/static_validation/rules/mutation_root_exists.rb +20 -0
- data/lib/graphql/static_validation/rules/subscription_root_exists.rb +20 -0
- data/lib/graphql/version.rb +1 -1
- data/readme.md +13 -0
- data/spec/graphql/analysis/field_usage_spec.rb +61 -0
- data/spec/graphql/query/arguments_spec.rb +82 -0
- data/spec/graphql/static_validation/rules/mutation_root_exists_spec.rb +39 -0
- data/spec/graphql/static_validation/rules/subscription_root_exists_spec.rb +34 -0
- metadata +11 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fbb584f225769c48d6c7d9878ff6d237068f0c5b
|
4
|
+
data.tar.gz: cf2c4052c0b5facfcf788524bf6a9b3b1b89b167
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4d09502f2198d2e0cc265db03d49bc80061c999e23471615622793b8d7ef25cea10e7a9fbd4ff48302f01453ae36652cb8c9b6fcca1ceac8c8c17578d3f2beb7
|
7
|
+
data.tar.gz: 81eb4cd1c6d3f00f9770a6929da390caac133266b89bd3c1ad8737ce8fd53a4cd750942db35332c34ba856559c1bfa53f33e82777a8b88b08eec74fda9921e2e
|
data/lib/graphql/analysis.rb
CHANGED
@@ -0,0 +1,44 @@
|
|
1
|
+
module GraphQL
|
2
|
+
module Analysis
|
3
|
+
# A query reducer for tracking both field usage and deprecated field usage.
|
4
|
+
#
|
5
|
+
# @example Logging field usage and deprecated field usage
|
6
|
+
# Schema.query_analyzers << GraphQL::Analysis::FieldUsage.new { |query, used_fields, used_deprecated_fields|
|
7
|
+
# puts "Used GraphQL fields: #{used_fields.join(', ')}"
|
8
|
+
# puts "Used deprecated GraphQL fields: #{used_deprecated_fields.join(', ')}"
|
9
|
+
# }
|
10
|
+
# Schema.execute(query_str)
|
11
|
+
# # Used GraphQL fields: Cheese.id, Cheese.fatContent, Query.cheese
|
12
|
+
# # Used deprecated GraphQL fields: Cheese.fatContent
|
13
|
+
#
|
14
|
+
class FieldUsage
|
15
|
+
def initialize(&block)
|
16
|
+
@field_usage_handler = block
|
17
|
+
end
|
18
|
+
|
19
|
+
def initial_value(query)
|
20
|
+
{
|
21
|
+
query: query,
|
22
|
+
used_fields: Set.new,
|
23
|
+
used_deprecated_fields: Set.new
|
24
|
+
}
|
25
|
+
end
|
26
|
+
|
27
|
+
def call(memo, visit_type, irep_node)
|
28
|
+
if irep_node.ast_node.is_a?(GraphQL::Language::Nodes::Field) && visit_type == :leave
|
29
|
+
irep_node.definitions.each do |type_defn, field_defn|
|
30
|
+
field = "#{type_defn.name}.#{field_defn.name}"
|
31
|
+
memo[:used_fields] << field
|
32
|
+
memo[:used_deprecated_fields] << field if field_defn.deprecation_reason
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
memo
|
37
|
+
end
|
38
|
+
|
39
|
+
def final_value(memo)
|
40
|
+
@field_usage_handler.call(memo[:query], memo[:used_fields].to_a, memo[:used_deprecated_fields].to_a)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -33,7 +33,7 @@ module GraphQL
|
|
33
33
|
|
34
34
|
visitor[Nodes::OperationDefinition].enter << -> (ast_node, prev_ast_node) {
|
35
35
|
node = Node.new(
|
36
|
-
return_type: context.type_definition.unwrap,
|
36
|
+
return_type: context.type_definition && context.type_definition.unwrap,
|
37
37
|
ast_node: ast_node,
|
38
38
|
name: ast_node.name,
|
39
39
|
parent: nil,
|
@@ -20,6 +20,12 @@ module GraphQL
|
|
20
20
|
@argument_values[key.to_s]
|
21
21
|
end
|
22
22
|
|
23
|
+
# @param key [String, Symbol] name of value to access
|
24
|
+
# @return [Boolean] true if the argument was present in this field
|
25
|
+
def key?(key)
|
26
|
+
@argument_values.key?(key.to_s)
|
27
|
+
end
|
28
|
+
|
23
29
|
# Get the original Ruby hash
|
24
30
|
# @return [Hash] the original values hash
|
25
31
|
def to_h
|
@@ -16,14 +16,25 @@ module GraphQL
|
|
16
16
|
values_hash = {}
|
17
17
|
argument_defns.each do |arg_name, arg_defn|
|
18
18
|
ast_arg = ast_arguments.find { |ast_arg| ast_arg.name == arg_name }
|
19
|
-
|
20
|
-
if ast_arg
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
19
|
+
arg_default_value = arg_defn.type.coerce_input(arg_defn.default_value)
|
20
|
+
if ast_arg.nil? && arg_default_value.nil?
|
21
|
+
# If it wasn't in the document,
|
22
|
+
# and there's no provided default,
|
23
|
+
# then don't pass it to the resolve function
|
24
|
+
next
|
25
|
+
else
|
26
|
+
arg_value = nil
|
27
|
+
|
28
|
+
if ast_arg
|
29
|
+
arg_value = coerce(arg_defn.type, ast_arg.value, variables)
|
30
|
+
end
|
31
|
+
|
32
|
+
if arg_value.nil?
|
33
|
+
arg_value = arg_default_value
|
34
|
+
end
|
35
|
+
|
36
|
+
values_hash[arg_name] = arg_value
|
25
37
|
end
|
26
|
-
values_hash[arg_name] = arg_value
|
27
38
|
end
|
28
39
|
GraphQL::Query::Arguments.new(values_hash)
|
29
40
|
end
|
@@ -24,6 +24,8 @@ module GraphQL
|
|
24
24
|
GraphQL::StaticValidation::VariableDefaultValuesAreCorrectlyTyped,
|
25
25
|
GraphQL::StaticValidation::VariablesAreUsedAndDefined,
|
26
26
|
GraphQL::StaticValidation::VariableUsagesAreAllowed,
|
27
|
+
GraphQL::StaticValidation::MutationRootExists,
|
28
|
+
GraphQL::StaticValidation::SubscriptionRootExists,
|
27
29
|
]
|
28
30
|
end
|
29
31
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module GraphQL
|
2
|
+
module StaticValidation
|
3
|
+
class MutationRootExists
|
4
|
+
include GraphQL::StaticValidation::Message::MessageHelper
|
5
|
+
|
6
|
+
def validate(context)
|
7
|
+
return if context.schema.mutation
|
8
|
+
|
9
|
+
visitor = context.visitor
|
10
|
+
|
11
|
+
visitor[GraphQL::Language::Nodes::OperationDefinition].enter << -> (ast_node, prev_ast_node) {
|
12
|
+
if ast_node.operation_type == 'mutation'
|
13
|
+
context.errors << message('Schema is not configured for mutations', ast_node, context: context)
|
14
|
+
return GraphQL::Language::Visitor::SKIP
|
15
|
+
end
|
16
|
+
}
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module GraphQL
|
2
|
+
module StaticValidation
|
3
|
+
class SubscriptionRootExists
|
4
|
+
include GraphQL::StaticValidation::Message::MessageHelper
|
5
|
+
|
6
|
+
def validate(context)
|
7
|
+
return if context.schema.subscription
|
8
|
+
|
9
|
+
visitor = context.visitor
|
10
|
+
|
11
|
+
visitor[GraphQL::Language::Nodes::OperationDefinition].enter << -> (ast_node, prev_ast_node) {
|
12
|
+
if ast_node.operation_type == 'subscription'
|
13
|
+
context.errors << message('Schema is not configured for subscriptions', ast_node, context: context)
|
14
|
+
return GraphQL::Language::Visitor::SKIP
|
15
|
+
end
|
16
|
+
}
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/lib/graphql/version.rb
CHANGED
data/readme.md
CHANGED
@@ -137,3 +137,16 @@ If you're building a backend for [Relay](http://facebook.github.io/relay/), you'
|
|
137
137
|
- If the new edge isn't a member of the connection's objects, raise a nice error
|
138
138
|
- Missing Enum value should raise a descriptive error, not "key not found"
|
139
139
|
- `args` should whitelist keys -- if you request a key that isn't defined for the field, it should 💥
|
140
|
+
- Fix middleware
|
141
|
+
- Handle out-of-bounds lookup, eg `graphql-batch`
|
142
|
+
- Handle non-serial execution, eg `@defer`
|
143
|
+
- Support non-instance-eval `.define`, eg `.define { |defn| ... }`
|
144
|
+
- First-class promise support
|
145
|
+
- like `graphql-batch` but more local
|
146
|
+
- support promises in connection resolves
|
147
|
+
- Add immutable transformation API to AST
|
148
|
+
- Support working with AST as data
|
149
|
+
- Adding fields to selections (`__typename` can go anywhere, others are type-specific)
|
150
|
+
- Renaming fragments from local names to unique names
|
151
|
+
- Support AST subclasses? This would be hard, I think classes are used as hash keys in many places.
|
152
|
+
- Support object deep-copy (schema, type, field, argument)? To support multiple schemas based on the same types.
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe GraphQL::Analysis::FieldUsage do
|
4
|
+
let(:result) { [] }
|
5
|
+
let(:field_usage_analyzer) { GraphQL::Analysis::FieldUsage.new { |query, used_fields, used_deprecated_fields| result << query << used_fields << used_deprecated_fields } }
|
6
|
+
let(:reduce_result) { GraphQL::Analysis.analyze_query(query, [field_usage_analyzer]) }
|
7
|
+
let(:query) { GraphQL::Query.new(DummySchema, query_string, variables: variables) }
|
8
|
+
let(:variables) { {} }
|
9
|
+
|
10
|
+
describe "query with deprecated fields" do
|
11
|
+
let(:query_string) {%|
|
12
|
+
query {
|
13
|
+
cheese(id: 1) {
|
14
|
+
id
|
15
|
+
fatContent
|
16
|
+
}
|
17
|
+
}
|
18
|
+
|}
|
19
|
+
|
20
|
+
it "returns query in reduced result" do
|
21
|
+
reduce_result
|
22
|
+
assert_equal query, result[0]
|
23
|
+
end
|
24
|
+
|
25
|
+
it "keeps track of used fields" do
|
26
|
+
reduce_result
|
27
|
+
assert_equal ['Cheese.id', 'Cheese.fatContent', 'Query.cheese'], result[1]
|
28
|
+
end
|
29
|
+
|
30
|
+
it "keeps track of deprecated fields" do
|
31
|
+
reduce_result
|
32
|
+
assert_equal ['Cheese.fatContent'], result[2]
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe "query with deprecated fields used more than once" do
|
37
|
+
let(:query_string) {%|
|
38
|
+
query {
|
39
|
+
cheese1: cheese(id: 1) {
|
40
|
+
id
|
41
|
+
fatContent
|
42
|
+
}
|
43
|
+
|
44
|
+
cheese2: cheese(id: 2) {
|
45
|
+
id
|
46
|
+
fatContent
|
47
|
+
}
|
48
|
+
}
|
49
|
+
|}
|
50
|
+
|
51
|
+
it "omits duplicate usage of a field" do
|
52
|
+
reduce_result
|
53
|
+
assert_equal ['Cheese.id', 'Cheese.fatContent', 'Query.cheese'], result[1]
|
54
|
+
end
|
55
|
+
|
56
|
+
it "omits duplicate usage of a deprecated field" do
|
57
|
+
reduce_result
|
58
|
+
assert_equal ['Cheese.fatContent'], result[2]
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -22,4 +22,86 @@ describe GraphQL::Query::Arguments do
|
|
22
22
|
it "returns original Ruby hash values with to_h" do
|
23
23
|
assert_equal({ a: 1, b: 2, c: { d: 3, e: 4 } }, arguments.to_h)
|
24
24
|
end
|
25
|
+
|
26
|
+
describe "#key?" do
|
27
|
+
let(:arg_values) { [] }
|
28
|
+
let(:schema) {
|
29
|
+
arg_values_array = arg_values
|
30
|
+
|
31
|
+
test_input_type = GraphQL::InputObjectType.define do
|
32
|
+
name "TestInput"
|
33
|
+
argument :a, types.Int
|
34
|
+
argument :b, types.Int, default_value: 2
|
35
|
+
argument :c, types.Int
|
36
|
+
argument :d, types.Int
|
37
|
+
end
|
38
|
+
|
39
|
+
query = GraphQL::ObjectType.define do
|
40
|
+
name "Query"
|
41
|
+
field :argTest, types.Int do
|
42
|
+
argument :a, types.Int
|
43
|
+
argument :b, types.Int, default_value: 2
|
44
|
+
argument :c, types.Int
|
45
|
+
argument :d, test_input_type
|
46
|
+
resolve -> (obj, args, ctx) {
|
47
|
+
arg_values_array << args
|
48
|
+
1
|
49
|
+
}
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
GraphQL::Schema.define(query: query)
|
54
|
+
}
|
55
|
+
|
56
|
+
it "detects missing keys by string or symbol" do
|
57
|
+
assert_equal true, arguments.key?(:a)
|
58
|
+
assert_equal true, arguments.key?("a")
|
59
|
+
assert_equal false, arguments.key?(:f)
|
60
|
+
assert_equal false, arguments.key?("f")
|
61
|
+
end
|
62
|
+
|
63
|
+
it "works from query literals" do
|
64
|
+
schema.execute("{ argTest(a: 1) }")
|
65
|
+
|
66
|
+
last_args = arg_values.last
|
67
|
+
|
68
|
+
assert_equal true, last_args.key?(:a)
|
69
|
+
# This is present from default value:
|
70
|
+
assert_equal true, last_args.key?(:b)
|
71
|
+
assert_equal false, last_args.key?(:c)
|
72
|
+
assert_equal({"a" => 1, "b" => 2}, last_args.to_h)
|
73
|
+
end
|
74
|
+
|
75
|
+
it "works from variables" do
|
76
|
+
variables = { "arg" => { "a" => 1, "d" => nil } }
|
77
|
+
schema.execute("query ArgTest($arg: TestInput){ argTest(d: $arg) }", variables: variables)
|
78
|
+
|
79
|
+
test_inputs = arg_values.last["d"]
|
80
|
+
|
81
|
+
assert_equal true, test_inputs.key?(:a)
|
82
|
+
# This is present from default value:
|
83
|
+
assert_equal true, test_inputs.key?(:b)
|
84
|
+
|
85
|
+
assert_equal false, test_inputs.key?(:c)
|
86
|
+
# This _was_ present in the variables,
|
87
|
+
# but it was nil, which is not allowed in GraphQL
|
88
|
+
assert_equal false, test_inputs.key?(:d)
|
89
|
+
|
90
|
+
assert_equal({"a" => 1, "b" => 2}, test_inputs.to_h)
|
91
|
+
end
|
92
|
+
|
93
|
+
it "works with variable default values" do
|
94
|
+
schema.execute("query ArgTest($arg: TestInput = {a: 1}){ argTest(d: $arg) }")
|
95
|
+
|
96
|
+
test_defaults = arg_values.last["d"]
|
97
|
+
|
98
|
+
assert_equal true, test_defaults.key?(:a)
|
99
|
+
# This is present from default val
|
100
|
+
assert_equal true, test_defaults.key?(:b)
|
101
|
+
|
102
|
+
assert_equal false, test_defaults.key?(:c)
|
103
|
+
assert_equal false, test_defaults.key?(:d)
|
104
|
+
assert_equal({"a" => 1, "b" => 2}, test_defaults.to_h)
|
105
|
+
end
|
106
|
+
end
|
25
107
|
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe GraphQL::StaticValidation::MutationRootExists do
|
4
|
+
let(:query_string) {%|
|
5
|
+
mutation addBagel {
|
6
|
+
introduceShip(input: {shipName: "Bagel"}) {
|
7
|
+
clientMutationId
|
8
|
+
shipEdge {
|
9
|
+
node { name, id }
|
10
|
+
}
|
11
|
+
}
|
12
|
+
}
|
13
|
+
|}
|
14
|
+
|
15
|
+
let(:schema) {
|
16
|
+
query_root = GraphQL::Field.define do
|
17
|
+
name "Query"
|
18
|
+
description "Query root of the system"
|
19
|
+
end
|
20
|
+
|
21
|
+
GraphQL::Schema.define do
|
22
|
+
query query_root
|
23
|
+
end
|
24
|
+
}
|
25
|
+
|
26
|
+
let(:validator) { GraphQL::StaticValidation::Validator.new(schema: schema, rules: [GraphQL::StaticValidation::MutationRootExists]) }
|
27
|
+
let(:query) { GraphQL::Query.new(schema, query_string) }
|
28
|
+
let(:errors) { validator.validate(query)[:errors] }
|
29
|
+
|
30
|
+
it "errors when a mutation is performed on a schema without a mutation root" do
|
31
|
+
assert_equal(1, errors.length)
|
32
|
+
missing_mutation_root_error = {
|
33
|
+
"message"=>"Schema is not configured for mutations",
|
34
|
+
"locations"=>[{"line"=>2, "column"=>5}],
|
35
|
+
"path"=>["mutation addBagel"],
|
36
|
+
}
|
37
|
+
assert_includes(errors, missing_mutation_root_error)
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe GraphQL::StaticValidation::SubscriptionRootExists do
|
4
|
+
let(:query_string) {%|
|
5
|
+
subscription {
|
6
|
+
test
|
7
|
+
}
|
8
|
+
|}
|
9
|
+
|
10
|
+
let(:schema) {
|
11
|
+
query_root = GraphQL::Field.define do
|
12
|
+
name "Query"
|
13
|
+
description "Query root of the system"
|
14
|
+
end
|
15
|
+
|
16
|
+
GraphQL::Schema.define do
|
17
|
+
query query_root
|
18
|
+
end
|
19
|
+
}
|
20
|
+
|
21
|
+
let(:validator) { GraphQL::StaticValidation::Validator.new(schema: schema, rules: [GraphQL::StaticValidation::SubscriptionRootExists]) }
|
22
|
+
let(:query) { GraphQL::Query.new(schema, query_string) }
|
23
|
+
let(:errors) { validator.validate(query)[:errors] }
|
24
|
+
|
25
|
+
it "errors when a subscription is performed on a schema without a subscription root" do
|
26
|
+
assert_equal(1, errors.length)
|
27
|
+
missing_subscription_root_error = {
|
28
|
+
"message"=>"Schema is not configured for subscriptions",
|
29
|
+
"locations"=>[{"line"=>2, "column"=>5}],
|
30
|
+
"path"=>["subscription"],
|
31
|
+
}
|
32
|
+
assert_includes(errors, missing_subscription_root_error)
|
33
|
+
end
|
34
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: graphql
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.18.
|
4
|
+
version: 0.18.12
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Robert Mosolgo
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-09-
|
11
|
+
date: 2016-09-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: codeclimate-test-reporter
|
@@ -246,6 +246,7 @@ files:
|
|
246
246
|
- lib/graphql.rb
|
247
247
|
- lib/graphql/analysis.rb
|
248
248
|
- lib/graphql/analysis/analyze_query.rb
|
249
|
+
- lib/graphql/analysis/field_usage.rb
|
249
250
|
- lib/graphql/analysis/max_query_complexity.rb
|
250
251
|
- lib/graphql/analysis/max_query_depth.rb
|
251
252
|
- lib/graphql/analysis/query_complexity.rb
|
@@ -376,7 +377,9 @@ files:
|
|
376
377
|
- lib/graphql/static_validation/rules/fragments_are_named.rb
|
377
378
|
- lib/graphql/static_validation/rules/fragments_are_on_composite_types.rb
|
378
379
|
- lib/graphql/static_validation/rules/fragments_are_used.rb
|
380
|
+
- lib/graphql/static_validation/rules/mutation_root_exists.rb
|
379
381
|
- lib/graphql/static_validation/rules/required_arguments_are_present.rb
|
382
|
+
- lib/graphql/static_validation/rules/subscription_root_exists.rb
|
380
383
|
- lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb
|
381
384
|
- lib/graphql/static_validation/rules/variable_usages_are_allowed.rb
|
382
385
|
- lib/graphql/static_validation/rules/variables_are_input_types.rb
|
@@ -390,6 +393,7 @@ files:
|
|
390
393
|
- lib/graphql/version.rb
|
391
394
|
- readme.md
|
392
395
|
- spec/graphql/analysis/analyze_query_spec.rb
|
396
|
+
- spec/graphql/analysis/field_usage_spec.rb
|
393
397
|
- spec/graphql/analysis/max_query_complexity_spec.rb
|
394
398
|
- spec/graphql/analysis/max_query_depth_spec.rb
|
395
399
|
- spec/graphql/analysis/query_complexity_spec.rb
|
@@ -461,7 +465,9 @@ files:
|
|
461
465
|
- spec/graphql/static_validation/rules/fragments_are_named_spec.rb
|
462
466
|
- spec/graphql/static_validation/rules/fragments_are_on_composite_types_spec.rb
|
463
467
|
- spec/graphql/static_validation/rules/fragments_are_used_spec.rb
|
468
|
+
- spec/graphql/static_validation/rules/mutation_root_exists_spec.rb
|
464
469
|
- spec/graphql/static_validation/rules/required_arguments_are_present_spec.rb
|
470
|
+
- spec/graphql/static_validation/rules/subscription_root_exists_spec.rb
|
465
471
|
- spec/graphql/static_validation/rules/variable_default_values_are_correctly_typed_spec.rb
|
466
472
|
- spec/graphql/static_validation/rules/variable_usages_are_allowed_spec.rb
|
467
473
|
- spec/graphql/static_validation/rules/variables_are_input_types_spec.rb
|
@@ -502,6 +508,7 @@ specification_version: 4
|
|
502
508
|
summary: A GraphQL server implementation for Ruby
|
503
509
|
test_files:
|
504
510
|
- spec/graphql/analysis/analyze_query_spec.rb
|
511
|
+
- spec/graphql/analysis/field_usage_spec.rb
|
505
512
|
- spec/graphql/analysis/max_query_complexity_spec.rb
|
506
513
|
- spec/graphql/analysis/max_query_depth_spec.rb
|
507
514
|
- spec/graphql/analysis/query_complexity_spec.rb
|
@@ -573,7 +580,9 @@ test_files:
|
|
573
580
|
- spec/graphql/static_validation/rules/fragments_are_named_spec.rb
|
574
581
|
- spec/graphql/static_validation/rules/fragments_are_on_composite_types_spec.rb
|
575
582
|
- spec/graphql/static_validation/rules/fragments_are_used_spec.rb
|
583
|
+
- spec/graphql/static_validation/rules/mutation_root_exists_spec.rb
|
576
584
|
- spec/graphql/static_validation/rules/required_arguments_are_present_spec.rb
|
585
|
+
- spec/graphql/static_validation/rules/subscription_root_exists_spec.rb
|
577
586
|
- spec/graphql/static_validation/rules/variable_default_values_are_correctly_typed_spec.rb
|
578
587
|
- spec/graphql/static_validation/rules/variable_usages_are_allowed_spec.rb
|
579
588
|
- spec/graphql/static_validation/rules/variables_are_input_types_spec.rb
|