graphql 1.9.9 → 1.9.10
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/ast/query_depth.rb +12 -1
- data/lib/graphql/language/nodes.rb +11 -8
- data/lib/graphql/query.rb +4 -4
- data/lib/graphql/schema.rb +1 -1
- data/lib/graphql/schema/member/has_fields.rb +2 -2
- data/lib/graphql/schema/validation.rb +0 -4
- data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +1 -1
- data/lib/graphql/version.rb +1 -1
- data/spec/graphql/analysis/ast/max_query_complexity_spec.rb +14 -2
- data/spec/graphql/analysis/ast/max_query_depth_spec.rb +14 -15
- data/spec/graphql/analysis/max_query_complexity_spec.rb +16 -8
- data/spec/graphql/analysis/max_query_depth_spec.rb +12 -3
- data/spec/graphql/query_spec.rb +13 -10
- data/spec/graphql/schema/argument_spec.rb +42 -8
- data/spec/graphql/schema/object_spec.rb +19 -0
- data/spec/graphql/schema/printer_spec.rb +14 -0
- data/spec/graphql/schema/validation_spec.rb +4 -4
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 239691cd4bf2f9f93314691a4ae3206438e2c51d544b3ef03f6928f62d5930a2
|
4
|
+
data.tar.gz: bb8c26e8da805c1020692ac979a5717a521aa14a353e17c0eaddb30ce1ebc092
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 32e52e6bc896c1b2f62bdefd4ce905ecbead2c81b52e2dac53700fd6a5956ccc594d4ff8eff5c314f496e44b16ab91ad7a3c1ed3c4e784bee489433b19853faa
|
7
|
+
data.tar.gz: 386a90ecd152c2b450d5c2045814241a6660180aef8edca92eea062cdc2285aa2545045390fa53bd92f0a5423ae2622aa18f7815e73fef5d902649f77e44b80b
|
@@ -3,13 +3,24 @@ module GraphQL
|
|
3
3
|
module Analysis
|
4
4
|
# A query reducer for measuring the depth of a given query.
|
5
5
|
#
|
6
|
+
# See https://graphql-ruby.org/queries/ast_analysis.html for more examples.
|
7
|
+
#
|
6
8
|
# @example Logging the depth of a query
|
7
9
|
# class LogQueryDepth < GraphQL::Analysis::QueryDepth
|
8
|
-
# def
|
10
|
+
# def result
|
9
11
|
# log("GraphQL query depth: #{@max_depth}")
|
10
12
|
# end
|
11
13
|
# end
|
12
14
|
#
|
15
|
+
# # In your Schema file:
|
16
|
+
#
|
17
|
+
# class MySchema < GraphQL::Schema
|
18
|
+
# use GraphQL::Analysis::AST
|
19
|
+
# query_analyzer LogQueryDepth
|
20
|
+
# end
|
21
|
+
#
|
22
|
+
# # When you run the query, the depth will get logged:
|
23
|
+
#
|
13
24
|
# Schema.execute(query_str)
|
14
25
|
# # GraphQL query depth: 8
|
15
26
|
#
|
@@ -61,6 +61,7 @@ module GraphQL
|
|
61
61
|
def initialize_copy(other)
|
62
62
|
@children = nil
|
63
63
|
@scalars = nil
|
64
|
+
@query_string = nil
|
64
65
|
end
|
65
66
|
|
66
67
|
# @return [Symbol] the method to call on {Language::Visitor} for this node
|
@@ -84,14 +85,7 @@ module GraphQL
|
|
84
85
|
# @param new_options [Hash]
|
85
86
|
# @return [AbstractNode] a shallow copy of `self`
|
86
87
|
def merge(new_options)
|
87
|
-
|
88
|
-
new_options.each do |key, value|
|
89
|
-
copied_self.instance_variable_set(:"@#{key}", value)
|
90
|
-
if copied_self.instance_variable_defined?(:@query_string)
|
91
|
-
copied_self.instance_variable_set(:@query_string, nil)
|
92
|
-
end
|
93
|
-
end
|
94
|
-
copied_self
|
88
|
+
dup.merge!(new_options)
|
95
89
|
end
|
96
90
|
|
97
91
|
# Copy `self`, but modify the copy so that `previous_child` is replaced by `new_child`
|
@@ -129,6 +123,15 @@ module GraphQL
|
|
129
123
|
copy_of_self
|
130
124
|
end
|
131
125
|
|
126
|
+
protected
|
127
|
+
|
128
|
+
def merge!(new_options)
|
129
|
+
new_options.each do |key, value|
|
130
|
+
instance_variable_set(:"@#{key}", value)
|
131
|
+
end
|
132
|
+
self
|
133
|
+
end
|
134
|
+
|
132
135
|
class << self
|
133
136
|
# Add a default `#visit_method` and `#children_method_name` using the class name
|
134
137
|
def inherited(child_class)
|
data/lib/graphql/query.rb
CHANGED
@@ -78,7 +78,7 @@ module GraphQL
|
|
78
78
|
# @param max_complexity [Numeric] the maximum field complexity for this query (falls back to schema-level value)
|
79
79
|
# @param except [<#call(schema_member, context)>] If provided, objects will be hidden from the schema when `.call(schema_member, context)` returns truthy
|
80
80
|
# @param only [<#call(schema_member, context)>] If provided, objects will be hidden from the schema when `.call(schema_member, context)` returns false
|
81
|
-
def initialize(schema, query_string = nil, query: nil, document: nil, context: nil, variables: nil, validate: true, subscription_topic: nil, operation_name: nil, root_value: nil, max_depth:
|
81
|
+
def initialize(schema, query_string = nil, query: nil, document: nil, context: nil, variables: nil, validate: true, subscription_topic: nil, operation_name: nil, root_value: nil, max_depth: schema.max_depth, max_complexity: schema.max_complexity, except: nil, only: nil)
|
82
82
|
# Even if `variables: nil` is passed, use an empty hash for simpler logic
|
83
83
|
variables ||= {}
|
84
84
|
@schema = schema
|
@@ -127,8 +127,8 @@ module GraphQL
|
|
127
127
|
@operation_name = operation_name
|
128
128
|
@prepared_ast = false
|
129
129
|
@validation_pipeline = nil
|
130
|
-
@max_depth = max_depth
|
131
|
-
@max_complexity = max_complexity
|
130
|
+
@max_depth = max_depth
|
131
|
+
@max_complexity = max_complexity
|
132
132
|
|
133
133
|
@result_values = nil
|
134
134
|
@executed = false
|
@@ -368,7 +368,7 @@ module GraphQL
|
|
368
368
|
parse_error: parse_error,
|
369
369
|
operation_name_error: operation_name_error,
|
370
370
|
max_depth: @max_depth,
|
371
|
-
max_complexity: @max_complexity
|
371
|
+
max_complexity: @max_complexity
|
372
372
|
)
|
373
373
|
end
|
374
374
|
|
data/lib/graphql/schema.rb
CHANGED
@@ -705,7 +705,7 @@ module GraphQL
|
|
705
705
|
# Eventually, the methods will be moved into this class, removing the need for the singleton.
|
706
706
|
def_delegators :graphql_definition,
|
707
707
|
# Schema structure
|
708
|
-
:as_json, :to_json, :to_document, :to_definition,
|
708
|
+
:as_json, :to_json, :to_document, :to_definition, :ast_node,
|
709
709
|
# Execution
|
710
710
|
:execute, :multiplex,
|
711
711
|
:static_validator, :introspection_system,
|
@@ -53,8 +53,8 @@ module GraphQL
|
|
53
53
|
# @param field_defn [GraphQL::Schema::Field]
|
54
54
|
# @return [void]
|
55
55
|
def add_field(field_defn)
|
56
|
-
if CONFLICT_FIELD_NAMES.include?(field_defn.resolver_method
|
57
|
-
warn "#{self.graphql_name}'s `field :#{field_defn.
|
56
|
+
if CONFLICT_FIELD_NAMES.include?(field_defn.original_name) && field_defn.original_name == field_defn.resolver_method
|
57
|
+
warn "#{self.graphql_name}'s `field :#{field_defn.original_name}` conflicts with a built-in method, use `resolver_method:` to pick a different resolver method for this field (for example, `resolver_method: :resolve_#{field_defn.original_name}` and `def resolve_#{field_defn.original_name}`)"
|
58
58
|
end
|
59
59
|
own_fields[field_defn.name] = field_defn
|
60
60
|
nil
|
@@ -104,10 +104,6 @@ module GraphQL
|
|
104
104
|
ARGUMENTS_ARE_VALID = Rules.assert_named_items_are_valid("argument", ->(type) { type.arguments.values })
|
105
105
|
|
106
106
|
DEFAULT_VALUE_IS_VALID_FOR_TYPE = ->(type) {
|
107
|
-
if !type.default_value.nil? && type.type.is_a?(NonNullType)
|
108
|
-
return %Q(Variable #{type.name} of type "#{type.type}" is required and will not use the default value. Perhaps you meant to use type "#{type.type.of_type}".)
|
109
|
-
end
|
110
|
-
|
111
107
|
if !type.default_value.nil?
|
112
108
|
coerced_value = begin
|
113
109
|
type.type.coerce_isolated_result(type.default_value)
|
@@ -18,7 +18,7 @@ module GraphQL
|
|
18
18
|
def assert_required_args(ast_node, defn)
|
19
19
|
present_argument_names = ast_node.arguments.map(&:name)
|
20
20
|
required_argument_names = context.warden.arguments(defn)
|
21
|
-
.select { |a| a.type.kind.non_null? }
|
21
|
+
.select { |a| a.type.kind.non_null? && !a.default_value? }
|
22
22
|
.map(&:name)
|
23
23
|
|
24
24
|
missing_names = required_argument_names - present_argument_names
|
data/lib/graphql/version.rb
CHANGED
@@ -45,7 +45,7 @@ describe GraphQL::Analysis::AST::MaxQueryComplexity do
|
|
45
45
|
|
46
46
|
describe "when max_complexity is decreased at query-level" do
|
47
47
|
before do
|
48
|
-
schema.max_complexity
|
48
|
+
schema.max_complexity(100)
|
49
49
|
end
|
50
50
|
|
51
51
|
let(:max_complexity) { 7 }
|
@@ -58,7 +58,7 @@ describe GraphQL::Analysis::AST::MaxQueryComplexity do
|
|
58
58
|
|
59
59
|
describe "when max_complexity is increased at query-level" do
|
60
60
|
before do
|
61
|
-
schema.max_complexity
|
61
|
+
schema.max_complexity(1)
|
62
62
|
end
|
63
63
|
|
64
64
|
let(:max_complexity) { 10 }
|
@@ -68,6 +68,18 @@ describe GraphQL::Analysis::AST::MaxQueryComplexity do
|
|
68
68
|
end
|
69
69
|
end
|
70
70
|
|
71
|
+
describe "when max_complexity is nil at query-level" do
|
72
|
+
let(:max_complexity) { nil }
|
73
|
+
|
74
|
+
before do
|
75
|
+
schema.max_complexity(1)
|
76
|
+
end
|
77
|
+
|
78
|
+
it "is applied" do
|
79
|
+
assert_nil result
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
71
83
|
describe "across a multiplex" do
|
72
84
|
before do
|
73
85
|
schema.analysis_engine = GraphQL::Analysis::AST
|
@@ -20,29 +20,27 @@ describe GraphQL::Analysis::AST::MaxQueryDepth do
|
|
20
20
|
}
|
21
21
|
}
|
22
22
|
"}
|
23
|
-
let(:
|
24
|
-
let(:query) {
|
25
|
-
GraphQL::Query.new(
|
26
|
-
schema.graphql_definition,
|
27
|
-
query_string,
|
28
|
-
variables: {},
|
29
|
-
max_depth: max_depth
|
30
|
-
)
|
31
|
-
}
|
23
|
+
let(:query) { GraphQL::Query.new(schema, query_string) }
|
32
24
|
let(:result) {
|
33
25
|
GraphQL::Analysis::AST.analyze_query(query, [GraphQL::Analysis::AST::MaxQueryDepth]).first
|
34
26
|
}
|
35
27
|
|
36
28
|
describe "when the query is deeper than max depth" do
|
37
|
-
let(:max_depth) { 5 }
|
38
|
-
|
39
29
|
it "adds an error message for a too-deep query" do
|
40
30
|
assert_equal "Query has depth of 7, which exceeds max depth of 5", result.message
|
41
31
|
end
|
42
32
|
end
|
43
33
|
|
44
34
|
describe "when the query specifies a different max_depth" do
|
45
|
-
let(:
|
35
|
+
let(:query) { GraphQL::Query.new(schema, query_string, max_depth: 100) }
|
36
|
+
|
37
|
+
it "obeys that max_depth" do
|
38
|
+
assert_nil result
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe "when the query disables max_depth" do
|
43
|
+
let(:query) { GraphQL::Query.new(schema, query_string, max_depth: nil) }
|
46
44
|
|
47
45
|
it "obeys that max_depth" do
|
48
46
|
assert_nil result
|
@@ -51,7 +49,7 @@ describe GraphQL::Analysis::AST::MaxQueryDepth do
|
|
51
49
|
|
52
50
|
describe "When the query is not deeper than max_depth" do
|
53
51
|
before do
|
54
|
-
schema.max_depth
|
52
|
+
schema.max_depth(100)
|
55
53
|
end
|
56
54
|
|
57
55
|
it "doesn't add an error" do
|
@@ -61,7 +59,8 @@ describe GraphQL::Analysis::AST::MaxQueryDepth do
|
|
61
59
|
|
62
60
|
describe "when the max depth isn't set" do
|
63
61
|
before do
|
64
|
-
|
62
|
+
# Yuck - Can't override GraphQL::Schema.max_depth to return nil if it has already been set
|
63
|
+
schema.define_singleton_method(:max_depth) { |*| nil }
|
65
64
|
end
|
66
65
|
|
67
66
|
it "doesn't add an error message" do
|
@@ -71,7 +70,7 @@ describe GraphQL::Analysis::AST::MaxQueryDepth do
|
|
71
70
|
|
72
71
|
describe "when a fragment exceeds max depth" do
|
73
72
|
before do
|
74
|
-
schema.max_depth
|
73
|
+
schema.max_depth(4)
|
75
74
|
end
|
76
75
|
|
77
76
|
let(:query_string) { "
|
@@ -16,7 +16,7 @@ describe GraphQL::Analysis::MaxQueryComplexity do
|
|
16
16
|
|
17
17
|
describe "when a query goes over max complexity" do
|
18
18
|
before do
|
19
|
-
schema.max_complexity
|
19
|
+
schema.max_complexity(9)
|
20
20
|
end
|
21
21
|
|
22
22
|
it "returns an error" do
|
@@ -25,9 +25,6 @@ describe GraphQL::Analysis::MaxQueryComplexity do
|
|
25
25
|
end
|
26
26
|
|
27
27
|
describe "when there is no max complexity" do
|
28
|
-
before do
|
29
|
-
schema.max_complexity = nil
|
30
|
-
end
|
31
28
|
it "doesn't error" do
|
32
29
|
assert_nil result["errors"]
|
33
30
|
end
|
@@ -35,7 +32,7 @@ describe GraphQL::Analysis::MaxQueryComplexity do
|
|
35
32
|
|
36
33
|
describe "when the query is less than the max complexity" do
|
37
34
|
before do
|
38
|
-
schema.max_complexity
|
35
|
+
schema.max_complexity(99)
|
39
36
|
end
|
40
37
|
it "doesn't error" do
|
41
38
|
assert_nil result["errors"]
|
@@ -44,7 +41,7 @@ describe GraphQL::Analysis::MaxQueryComplexity do
|
|
44
41
|
|
45
42
|
describe "when max_complexity is decreased at query-level" do
|
46
43
|
before do
|
47
|
-
schema.max_complexity
|
44
|
+
schema.max_complexity(100)
|
48
45
|
end
|
49
46
|
let(:result) {schema.execute(query_string, max_complexity: 7) }
|
50
47
|
|
@@ -55,7 +52,7 @@ describe GraphQL::Analysis::MaxQueryComplexity do
|
|
55
52
|
|
56
53
|
describe "when max_complexity is increased at query-level" do
|
57
54
|
before do
|
58
|
-
schema.max_complexity
|
55
|
+
schema.max_complexity(1)
|
59
56
|
end
|
60
57
|
let(:result) {schema.execute(query_string, max_complexity: 10) }
|
61
58
|
|
@@ -64,9 +61,20 @@ describe GraphQL::Analysis::MaxQueryComplexity do
|
|
64
61
|
end
|
65
62
|
end
|
66
63
|
|
64
|
+
describe "when max_complexity is nil query-level" do
|
65
|
+
before do
|
66
|
+
schema.max_complexity(1)
|
67
|
+
end
|
68
|
+
let(:result) {schema.execute(query_string, max_complexity: nil) }
|
69
|
+
|
70
|
+
it "is applied" do
|
71
|
+
assert_nil result["errors"]
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
67
75
|
describe "across a multiplex" do
|
68
76
|
before do
|
69
|
-
schema.max_complexity
|
77
|
+
schema.max_complexity(9)
|
70
78
|
end
|
71
79
|
|
72
80
|
let(:queries) { 5.times.map { |n| { query: "{ cheese(id: #{n}) { id } }" } } }
|
@@ -36,9 +36,17 @@ describe GraphQL::Analysis::MaxQueryDepth do
|
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
39
|
+
describe "when the query specifies a nil max_depth" do
|
40
|
+
let(:result) { schema.execute(query_string, max_depth: nil) }
|
41
|
+
|
42
|
+
it "obeys that max_depth" do
|
43
|
+
assert_nil result["errors"]
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
39
47
|
describe "When the query is not deeper than max_depth" do
|
40
48
|
before do
|
41
|
-
schema.max_depth
|
49
|
+
schema.max_depth(100)
|
42
50
|
end
|
43
51
|
|
44
52
|
it "doesn't add an error" do
|
@@ -48,7 +56,8 @@ describe GraphQL::Analysis::MaxQueryDepth do
|
|
48
56
|
|
49
57
|
describe "when the max depth isn't set" do
|
50
58
|
before do
|
51
|
-
|
59
|
+
# Yuck - Can't override GraphQL::Schema.max_depth to return nil if it has already been set
|
60
|
+
schema.define_singleton_method(:max_depth) { |*| nil }
|
52
61
|
end
|
53
62
|
|
54
63
|
it "doesn't add an error message" do
|
@@ -58,7 +67,7 @@ describe GraphQL::Analysis::MaxQueryDepth do
|
|
58
67
|
|
59
68
|
describe "when a fragment exceeds max depth" do
|
60
69
|
before do
|
61
|
-
schema.max_depth
|
70
|
+
schema.max_depth(4)
|
62
71
|
end
|
63
72
|
|
64
73
|
let(:query_string) { "
|
data/spec/graphql/query_spec.rb
CHANGED
@@ -30,7 +30,6 @@ describe GraphQL::Query do
|
|
30
30
|
}
|
31
31
|
|}
|
32
32
|
let(:operation_name) { nil }
|
33
|
-
let(:max_depth) { nil }
|
34
33
|
let(:query_variables) { {"cheeseId" => 2} }
|
35
34
|
let(:schema) { Dummy::Schema }
|
36
35
|
let(:document) { GraphQL.parse(query_string) }
|
@@ -39,8 +38,7 @@ describe GraphQL::Query do
|
|
39
38
|
schema,
|
40
39
|
query_string,
|
41
40
|
variables: query_variables,
|
42
|
-
operation_name: operation_name
|
43
|
-
max_depth: max_depth,
|
41
|
+
operation_name: operation_name
|
44
42
|
)}
|
45
43
|
let(:result) { query.result }
|
46
44
|
|
@@ -71,8 +69,7 @@ describe GraphQL::Query do
|
|
71
69
|
res = GraphQL::Query.new(
|
72
70
|
schema,
|
73
71
|
variables: query_variables,
|
74
|
-
operation_name: operation_name
|
75
|
-
max_depth: max_depth,
|
72
|
+
operation_name: operation_name
|
76
73
|
).result
|
77
74
|
assert_equal 1, res["errors"].length
|
78
75
|
assert_equal "No query string was present", res["errors"][0]["message"]
|
@@ -82,8 +79,7 @@ describe GraphQL::Query do
|
|
82
79
|
query = GraphQL::Query.new(
|
83
80
|
schema,
|
84
81
|
variables: query_variables,
|
85
|
-
operation_name: operation_name
|
86
|
-
max_depth: max_depth,
|
82
|
+
operation_name: operation_name
|
87
83
|
)
|
88
84
|
query.query_string = '{ __type(name: """Cheese""") { name } }'
|
89
85
|
assert_equal "Cheese", query.result["data"] ["__type"]["name"]
|
@@ -174,8 +170,7 @@ describe GraphQL::Query do
|
|
174
170
|
schema,
|
175
171
|
document: document,
|
176
172
|
variables: query_variables,
|
177
|
-
operation_name: operation_name
|
178
|
-
max_depth: max_depth,
|
173
|
+
operation_name: operation_name
|
179
174
|
)}
|
180
175
|
|
181
176
|
it "runs the query using the already parsed document" do
|
@@ -560,7 +555,15 @@ describe GraphQL::Query do
|
|
560
555
|
end
|
561
556
|
|
562
557
|
describe "overriding max_depth" do
|
563
|
-
let(:
|
558
|
+
let(:query) {
|
559
|
+
GraphQL::Query.new(
|
560
|
+
schema,
|
561
|
+
query_string,
|
562
|
+
variables: query_variables,
|
563
|
+
operation_name: operation_name,
|
564
|
+
max_depth: 12
|
565
|
+
)
|
566
|
+
}
|
564
567
|
|
565
568
|
it "overrides the schema's max_depth" do
|
566
569
|
assert result["data"].key?("cheese")
|
@@ -10,7 +10,7 @@ describe GraphQL::Schema::Argument do
|
|
10
10
|
argument :arg_with_block, String, required: false do
|
11
11
|
description "test"
|
12
12
|
end
|
13
|
-
|
13
|
+
argument :required_with_default_arg, Int, required: true, default_value: 1
|
14
14
|
argument :aliased_arg, String, required: false, as: :renamed
|
15
15
|
argument :prepared_arg, Int, required: false, prepare: :multiply
|
16
16
|
argument :prepared_by_proc_arg, Int, required: false, prepare: ->(val, context) { context[:multiply_by] * val }
|
@@ -30,7 +30,11 @@ describe GraphQL::Schema::Argument do
|
|
30
30
|
end
|
31
31
|
|
32
32
|
def field(**args)
|
33
|
-
|
33
|
+
# sort the fields so that they match the output of the new interpreter
|
34
|
+
sorted_keys = args.keys.sort
|
35
|
+
sorted_args = {}
|
36
|
+
sorted_keys.each {|k| sorted_args[k] = args[k] }
|
37
|
+
sorted_args.inspect
|
34
38
|
end
|
35
39
|
|
36
40
|
def multiply(val)
|
@@ -48,7 +52,7 @@ describe GraphQL::Schema::Argument do
|
|
48
52
|
|
49
53
|
describe "#keys" do
|
50
54
|
it "is not overwritten by the 'keys' argument" do
|
51
|
-
expected_keys = ["aliasedArg", "arg", "argWithBlock", "explodingPreparedArg", "keys", "preparedArg", "preparedByCallableArg", "preparedByProcArg"]
|
55
|
+
expected_keys = ["aliasedArg", "arg", "argWithBlock", "explodingPreparedArg", "keys", "preparedArg", "preparedByCallableArg", "preparedByProcArg", "requiredWithDefaultArg"]
|
52
56
|
assert_equal expected_keys, SchemaArgumentTest::Query.fields["field"].arguments.keys.sort
|
53
57
|
end
|
54
58
|
end
|
@@ -103,7 +107,7 @@ describe GraphQL::Schema::Argument do
|
|
103
107
|
|
104
108
|
res = SchemaArgumentTest::Schema.execute(query_str)
|
105
109
|
# Make sure it's getting the renamed symbol:
|
106
|
-
assert_equal '{:renamed=>"x"}', res["data"]["field"]
|
110
|
+
assert_equal '{:renamed=>"x", :required_with_default_arg=>1}', res["data"]["field"]
|
107
111
|
end
|
108
112
|
end
|
109
113
|
|
@@ -115,7 +119,7 @@ describe GraphQL::Schema::Argument do
|
|
115
119
|
|
116
120
|
res = SchemaArgumentTest::Schema.execute(query_str, context: {multiply_by: 3})
|
117
121
|
# Make sure it's getting the renamed symbol:
|
118
|
-
assert_equal '{:prepared_arg=>15}', res["data"]["field"]
|
122
|
+
assert_equal '{:prepared_arg=>15, :required_with_default_arg=>1}', res["data"]["field"]
|
119
123
|
end
|
120
124
|
|
121
125
|
it "calls the method on the provided Proc" do
|
@@ -125,7 +129,7 @@ describe GraphQL::Schema::Argument do
|
|
125
129
|
|
126
130
|
res = SchemaArgumentTest::Schema.execute(query_str, context: {multiply_by: 3})
|
127
131
|
# Make sure it's getting the renamed symbol:
|
128
|
-
assert_equal '{:prepared_by_proc_arg=>15}', res["data"]["field"]
|
132
|
+
assert_equal '{:prepared_by_proc_arg=>15, :required_with_default_arg=>1}', res["data"]["field"]
|
129
133
|
end
|
130
134
|
|
131
135
|
it "calls the method on the provided callable object" do
|
@@ -135,7 +139,7 @@ describe GraphQL::Schema::Argument do
|
|
135
139
|
|
136
140
|
res = SchemaArgumentTest::Schema.execute(query_str, context: {multiply_by: 3})
|
137
141
|
# Make sure it's getting the renamed symbol:
|
138
|
-
assert_equal '{:prepared_by_callable_arg=>15}', res["data"]["field"]
|
142
|
+
assert_equal '{:prepared_by_callable_arg=>15, :required_with_default_arg=>1}', res["data"]["field"]
|
139
143
|
end
|
140
144
|
|
141
145
|
it "handles exceptions raised by prepare" do
|
@@ -144,9 +148,39 @@ describe GraphQL::Schema::Argument do
|
|
144
148
|
GRAPHQL
|
145
149
|
|
146
150
|
res = SchemaArgumentTest::Schema.execute(query_str, context: {multiply_by: 3})
|
147
|
-
assert_equal({ 'f1' => '{:arg=>"echo"}', 'f2' => nil }, res['data'])
|
151
|
+
assert_equal({ 'f1' => '{:arg=>"echo", :required_with_default_arg=>1}', 'f2' => nil }, res['data'])
|
148
152
|
assert_equal(res['errors'][0]['message'], 'boom!')
|
149
153
|
assert_equal(res['errors'][0]['path'], ['f2'])
|
150
154
|
end
|
151
155
|
end
|
156
|
+
|
157
|
+
describe "default_value:" do
|
158
|
+
it 'uses default_value: with no input' do
|
159
|
+
query_str = <<-GRAPHQL
|
160
|
+
{ field() }
|
161
|
+
GRAPHQL
|
162
|
+
|
163
|
+
res = SchemaArgumentTest::Schema.execute(query_str)
|
164
|
+
assert_equal '{:required_with_default_arg=>1}', res["data"]["field"]
|
165
|
+
end
|
166
|
+
|
167
|
+
it 'uses provided input value' do
|
168
|
+
query_str = <<-GRAPHQL
|
169
|
+
{ field(requiredWithDefaultArg: 2) }
|
170
|
+
GRAPHQL
|
171
|
+
|
172
|
+
res = SchemaArgumentTest::Schema.execute(query_str)
|
173
|
+
assert_equal '{:required_with_default_arg=>2}', res["data"]["field"]
|
174
|
+
end
|
175
|
+
|
176
|
+
it 'respects non-null type' do
|
177
|
+
query_str = <<-GRAPHQL
|
178
|
+
{ field(requiredWithDefaultArg: null) }
|
179
|
+
GRAPHQL
|
180
|
+
|
181
|
+
res = SchemaArgumentTest::Schema.execute(query_str)
|
182
|
+
assert_equal "Argument 'requiredWithDefaultArg' on Field 'field' has an invalid value. Expected type 'Int!'.", res['errors'][0]['message']
|
183
|
+
end
|
184
|
+
|
185
|
+
end
|
152
186
|
end
|
@@ -324,6 +324,16 @@ describe GraphQL::Schema::Object do
|
|
324
324
|
end
|
325
325
|
end
|
326
326
|
|
327
|
+
it "warns when override matches field name" do
|
328
|
+
expected_warning = "X's `field :object` conflicts with a built-in method, use `resolver_method:` to pick a different resolver method for this field (for example, `resolver_method: :resolve_object` and `def resolve_object`)\n"
|
329
|
+
assert_output "", expected_warning do
|
330
|
+
Class.new(GraphQL::Schema::Object) do
|
331
|
+
graphql_name "X"
|
332
|
+
field :object, String, null: true, resolver_method: :object
|
333
|
+
end
|
334
|
+
end
|
335
|
+
end
|
336
|
+
|
327
337
|
it "doesn't warn with an override" do
|
328
338
|
assert_output "", "" do
|
329
339
|
Class.new(GraphQL::Schema::Object) do
|
@@ -332,5 +342,14 @@ describe GraphQL::Schema::Object do
|
|
332
342
|
end
|
333
343
|
end
|
334
344
|
end
|
345
|
+
|
346
|
+
it "doesn't warn when passing object through using resolver_method" do
|
347
|
+
assert_output "", "" do
|
348
|
+
Class.new(GraphQL::Schema::Object) do
|
349
|
+
graphql_name "X"
|
350
|
+
field :thing, String, null: true, resolver_method: :object
|
351
|
+
end
|
352
|
+
end
|
353
|
+
end
|
335
354
|
end
|
336
355
|
end
|
@@ -866,4 +866,18 @@ SCHEMA
|
|
866
866
|
assert_equal expected.chomp, GraphQL::Schema::Printer.new(schema, context: context, only: only_filter).print_schema
|
867
867
|
end
|
868
868
|
end
|
869
|
+
|
870
|
+
it "prints schemas from class" do
|
871
|
+
class TestPrintSchema < GraphQL::Schema
|
872
|
+
class OddlyNamedQuery < GraphQL::Schema::Object
|
873
|
+
field :int, Int, null: false
|
874
|
+
end
|
875
|
+
|
876
|
+
query(OddlyNamedQuery)
|
877
|
+
end
|
878
|
+
|
879
|
+
|
880
|
+
str = GraphQL::Schema::Printer.print_schema TestPrintSchema
|
881
|
+
assert_equal "schema {\n query: OddlyNamedQuery\n}\n\ntype OddlyNamedQuery {\n int: Int!\n}", str
|
882
|
+
end
|
869
883
|
end
|
@@ -297,9 +297,9 @@ describe GraphQL::Schema::Validation do
|
|
297
297
|
end
|
298
298
|
}
|
299
299
|
|
300
|
-
let(:
|
300
|
+
let(:default_argument_for_non_null_argument) {
|
301
301
|
GraphQL::Argument.define do
|
302
|
-
name "
|
302
|
+
name "ValidDefault"
|
303
303
|
type !GraphQL::INT_TYPE
|
304
304
|
default_value 1
|
305
305
|
end
|
@@ -324,8 +324,8 @@ describe GraphQL::Schema::Validation do
|
|
324
324
|
assert_error_includes untyped_argument, "must be a valid input type (Scalar or InputObject), not Symbol"
|
325
325
|
end
|
326
326
|
|
327
|
-
it "
|
328
|
-
|
327
|
+
it "allows default values for non-null argument" do
|
328
|
+
assert_nil GraphQL::Schema::Validation.validate(default_argument_for_non_null_argument)
|
329
329
|
end
|
330
330
|
|
331
331
|
it "cannot use reserved name" do
|
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: 1.9.
|
4
|
+
version: 1.9.10
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Robert Mosolgo
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-08-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: benchmark-ips
|