graphql 1.8.0.pre11 → 1.8.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/generators/graphql/templates/schema.erb +1 -1
- data/lib/graphql/function.rb +2 -0
- data/lib/graphql/railtie.rb +1 -1
- data/lib/graphql/schema.rb +1 -0
- data/lib/graphql/schema/argument.rb +3 -2
- data/lib/graphql/schema/build_from_definition.rb +1 -1
- data/lib/graphql/schema/field.rb +96 -49
- data/lib/graphql/schema/interface.rb +21 -3
- data/lib/graphql/schema/list.rb +4 -0
- data/lib/graphql/schema/member/accepts_definition.rb +2 -2
- data/lib/graphql/schema/member/base_dsl_methods.rb +4 -0
- data/lib/graphql/schema/member/build_type.rb +4 -2
- data/lib/graphql/schema/member/has_fields.rb +1 -8
- data/lib/graphql/schema/mutation.rb +19 -88
- data/lib/graphql/schema/non_null.rb +4 -0
- data/lib/graphql/schema/object.rb +1 -1
- data/lib/graphql/schema/relay_classic_mutation.rb +14 -15
- data/lib/graphql/schema/resolver.rb +122 -0
- data/lib/graphql/subscriptions/instrumentation.rb +5 -1
- data/lib/graphql/subscriptions/serialize.rb +2 -0
- data/lib/graphql/tracing/new_relic_tracing.rb +26 -0
- data/lib/graphql/version.rb +1 -1
- data/readme.md +1 -1
- data/spec/generators/graphql/install_generator_spec.rb +1 -1
- data/spec/graphql/relay/mutation_spec.rb +5 -3
- data/spec/graphql/schema/build_from_definition_spec.rb +1 -1
- data/spec/graphql/schema/field_spec.rb +7 -24
- data/spec/graphql/schema/interface_spec.rb +25 -0
- data/spec/graphql/schema/member/accepts_definition_spec.rb +22 -0
- data/spec/graphql/schema/member/build_type_spec.rb +17 -0
- data/spec/graphql/schema/mutation_spec.rb +15 -14
- data/spec/graphql/schema/resolver_spec.rb +131 -0
- data/spec/graphql/subscriptions_spec.rb +267 -205
- data/spec/graphql/tracing/new_relic_tracing_spec.rb +47 -0
- data/spec/support/jazz.rb +6 -1
- data/spec/support/new_relic.rb +24 -0
- data/spec/support/star_trek/schema.rb +2 -2
- data/spec/support/star_wars/schema.rb +1 -2
- metadata +13 -4
@@ -45,7 +45,7 @@ module GraphQL
|
|
45
45
|
if int.is_a?(GraphQL::InterfaceType)
|
46
46
|
int_f = {}
|
47
47
|
int.fields.each do |name, legacy_field|
|
48
|
-
int_f[name] =
|
48
|
+
int_f[name] = field_class.from_options(name, field: legacy_field)
|
49
49
|
end
|
50
50
|
all_fields = int_f.merge(all_fields)
|
51
51
|
end
|
@@ -22,22 +22,20 @@ module GraphQL
|
|
22
22
|
class RelayClassicMutation < GraphQL::Schema::Mutation
|
23
23
|
# The payload should always include this field
|
24
24
|
field(:client_mutation_id, String, "A unique identifier for the client performing the mutation.", null: true)
|
25
|
-
|
25
|
+
# Relay classic default:
|
26
|
+
null(true)
|
26
27
|
|
27
28
|
# Override {GraphQL::Schema::Mutation#resolve_mutation} to
|
28
29
|
# delete `client_mutation_id` from the kwargs.
|
29
30
|
def resolve_mutation(kwargs)
|
30
31
|
# This is handled by Relay::Mutation::Resolve, a bit hacky, but here we are.
|
31
32
|
kwargs.delete(:client_mutation_id)
|
32
|
-
|
33
|
+
resolve(**kwargs)
|
33
34
|
end
|
34
35
|
|
35
|
-
|
36
|
-
def inherited(base)
|
37
|
-
base.null(true)
|
38
|
-
super
|
39
|
-
end
|
36
|
+
resolve_method(:resolve_mutation)
|
40
37
|
|
38
|
+
class << self
|
41
39
|
# The base class for generated input object types
|
42
40
|
# @param new_class [Class] The base class to use for generating input object definitions
|
43
41
|
# @return [Class] The base class for this mutation's generated input object (default is {GraphQL::Schema::InputObject})
|
@@ -57,16 +55,17 @@ module GraphQL
|
|
57
55
|
@input_type ||= generate_input_type
|
58
56
|
end
|
59
57
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
field_instance
|
58
|
+
# Extend {Schema::Mutation.field_options} to add the `input` argument
|
59
|
+
def field_options
|
60
|
+
sig = super
|
61
|
+
# Arguments were added at the root, but they should be nested
|
62
|
+
sig[:arguments].clear
|
63
|
+
sig[:arguments][:input] = { type: input_type, required: true }
|
64
|
+
sig
|
68
65
|
end
|
69
66
|
|
67
|
+
private
|
68
|
+
|
70
69
|
# Generate the input type for the `input:` argument
|
71
70
|
# To customize how input objects are generated, override this method
|
72
71
|
# @return [Class] a subclass of {.input_object_class}
|
@@ -0,0 +1,122 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GraphQL
|
4
|
+
class Schema
|
5
|
+
# A class-based container for field configuration and resolution logic. It supports:
|
6
|
+
#
|
7
|
+
# - Arguments, via `.argument(...)` helper, which will be applied to the field.
|
8
|
+
# - Return type, via `.type(..., null: ...)`, which will be applied to the field.
|
9
|
+
# - Description, via `.description(...)`, which will be applied to the field
|
10
|
+
# - Resolution, via `#resolve(**args)` method, which will be called to resolve the field.
|
11
|
+
# - `#object` and `#context` accessors for use during `#resolve`.
|
12
|
+
#
|
13
|
+
# Resolvers can be attached with the `resolver:` option in a `field(...)` call.
|
14
|
+
#
|
15
|
+
# A resolver's configuration may be overridden with other keywords in the `field(...)` call.
|
16
|
+
#
|
17
|
+
# See the {.field_options} to see how a Resolver becomes a set of field configuration options.
|
18
|
+
#
|
19
|
+
# @see {GraphQL::Schema::Mutation} for a concrete subclass of `Resolver`.
|
20
|
+
# @see {GraphQL::Function} `Resolver` is a replacement for `GraphQL::Function`
|
21
|
+
class Resolver
|
22
|
+
include Schema::Member::GraphQLTypeNames
|
23
|
+
# Really we only need description from here, but:
|
24
|
+
extend Schema::Member::BaseDSLMethods
|
25
|
+
extend GraphQL::Schema::Member::HasArguments
|
26
|
+
|
27
|
+
# @param object [Object] the initialize object, pass to {Query.initialize} as `root_value`
|
28
|
+
# @param context [GraphQL::Query::Context]
|
29
|
+
def initialize(object:, context:)
|
30
|
+
@object = object
|
31
|
+
@context = context
|
32
|
+
end
|
33
|
+
|
34
|
+
# @return [Object] The application object this field is being resolved on
|
35
|
+
attr_reader :object
|
36
|
+
|
37
|
+
# @return [GraphQL::Query::Context]
|
38
|
+
attr_reader :context
|
39
|
+
|
40
|
+
# Do the work. Everything happens here.
|
41
|
+
# @return [Object] An object corresponding to the return type
|
42
|
+
def resolve(**args)
|
43
|
+
raise NotImplementedError, "#{self.class.name}#resolve should execute the field's logic"
|
44
|
+
end
|
45
|
+
|
46
|
+
class << self
|
47
|
+
# Default `:resolve` set below.
|
48
|
+
# @return [Symbol] The method to call on instances of this object to resolve the field
|
49
|
+
def resolve_method(new_method = nil)
|
50
|
+
if new_method
|
51
|
+
@resolve_method = new_method
|
52
|
+
end
|
53
|
+
@resolve_method || (superclass.respond_to?(:resolve_method) ? superclass.resolve_method : :resolve)
|
54
|
+
end
|
55
|
+
|
56
|
+
# Additional info injected into {#resolve}
|
57
|
+
# @see {GraphQL::Schema::Field#extras}
|
58
|
+
def extras(new_extras = nil)
|
59
|
+
if new_extras
|
60
|
+
@own_extras = new_extras
|
61
|
+
end
|
62
|
+
own_extras = @own_extras || []
|
63
|
+
own_extras + (superclass.respond_to?(:extras) ? superclass.extras : [])
|
64
|
+
end
|
65
|
+
|
66
|
+
# Specifies whether or not the field is nullable. Defaults to `true`
|
67
|
+
# TODO unify with {#type}
|
68
|
+
# @param allow_null [Boolean] Whether or not the response can be null
|
69
|
+
def null(allow_null = nil)
|
70
|
+
if !allow_null.nil?
|
71
|
+
@null = allow_null
|
72
|
+
end
|
73
|
+
|
74
|
+
@null.nil? ? (superclass.respond_to?(:null) ? superclass.null : true) : @null
|
75
|
+
end
|
76
|
+
|
77
|
+
# Call this method to get the return type of the field,
|
78
|
+
# or use it as a configuration method to assign a return type
|
79
|
+
# instead of generating one.
|
80
|
+
# TODO unify with {#null}
|
81
|
+
# @param new_type [Class, nil] If a type definition class is provided, it will be used as the return type of the field
|
82
|
+
# @param null [true, false] Whether or not the field may return `nil`
|
83
|
+
# @return [Class] The type which this field returns.
|
84
|
+
def type(new_type = nil, null: nil)
|
85
|
+
if new_type
|
86
|
+
if null.nil?
|
87
|
+
raise ArgumentError, "required argument `null:` is missing"
|
88
|
+
end
|
89
|
+
@type_expr = new_type
|
90
|
+
@null = null
|
91
|
+
else
|
92
|
+
if @type_expr
|
93
|
+
GraphQL::Schema::Member::BuildType.parse_type(@type_expr, null: @null)
|
94
|
+
elsif superclass.respond_to?(:type)
|
95
|
+
superclass.type
|
96
|
+
else
|
97
|
+
nil
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def field_options
|
103
|
+
{
|
104
|
+
type: type_expr,
|
105
|
+
description: description,
|
106
|
+
extras: extras,
|
107
|
+
method: resolve_method,
|
108
|
+
resolver_class: self,
|
109
|
+
arguments: arguments,
|
110
|
+
null: null,
|
111
|
+
}
|
112
|
+
end
|
113
|
+
|
114
|
+
# A non-normalized type configuration, without `null` applied
|
115
|
+
# @api private
|
116
|
+
def type_expr
|
117
|
+
@type_expr || (superclass.respond_to?(:type_expr) ? superclass.type_expr : nil)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
@@ -56,7 +56,11 @@ module GraphQL
|
|
56
56
|
ctx.skip
|
57
57
|
elsif ctx.irep_node.subscription_topic == ctx.query.subscription_topic
|
58
58
|
# The root object is _already_ the subscription update:
|
59
|
-
obj
|
59
|
+
if obj.is_a?(GraphQL::Schema::Object)
|
60
|
+
obj.object
|
61
|
+
else
|
62
|
+
obj
|
63
|
+
end
|
60
64
|
else
|
61
65
|
# This is a subscription update, but this event wasn't triggered.
|
62
66
|
ctx.skip
|
@@ -35,6 +35,8 @@ module GraphQL
|
|
35
35
|
obj.map { |i| dump_recursive(i) }.join(':')
|
36
36
|
when obj.is_a?(Hash)
|
37
37
|
obj.map { |k, v| "#{dump_recursive(k)}:#{dump_recursive(v)}" }.join(":")
|
38
|
+
when obj.is_a?(GraphQL::Schema::InputObject)
|
39
|
+
dump_recursive(obj.to_h)
|
38
40
|
when obj.respond_to?(:to_gid_param)
|
39
41
|
obj.to_gid_param
|
40
42
|
when obj.respond_to?(:to_param)
|
@@ -14,7 +14,33 @@ module GraphQL
|
|
14
14
|
"execute_query_lazy" => "GraphQL/execute",
|
15
15
|
}
|
16
16
|
|
17
|
+
# @param set_transaction_name [Boolean] If true, the GraphQL operation name will be used as the transaction name.
|
18
|
+
# This is not advised if you run more than one query per HTTP request, for example, with `graphql-client` or multiplexing.
|
19
|
+
# It can also be specified per-query with `context[:set_new_relic_transaction_name]`.
|
20
|
+
def initialize(set_transaction_name: false)
|
21
|
+
@set_transaction_name = set_transaction_name
|
22
|
+
super
|
23
|
+
end
|
24
|
+
|
17
25
|
def platform_trace(platform_key, key, data)
|
26
|
+
if key == "execute_query"
|
27
|
+
set_this_txn_name = data[:query].context[:set_new_relic_transaction_name]
|
28
|
+
if set_this_txn_name == true || (set_this_txn_name.nil? && @set_transaction_name)
|
29
|
+
query = data[:query]
|
30
|
+
# Set the transaction name based on the operation type and name
|
31
|
+
selected_op = query.selected_operation
|
32
|
+
if selected_op
|
33
|
+
op_type = selected_op.operation_type
|
34
|
+
op_name = selected_op.name || "anonymous"
|
35
|
+
else
|
36
|
+
op_type = "query"
|
37
|
+
op_name = "anonymous"
|
38
|
+
end
|
39
|
+
|
40
|
+
NewRelic::Agent.set_transaction_name("GraphQL/#{op_type}.#{op_name}")
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
18
44
|
NewRelic::Agent::MethodTracerHelpers.trace_execution_scoped(platform_key) do
|
19
45
|
yield
|
20
46
|
end
|
data/lib/graphql/version.rb
CHANGED
data/readme.md
CHANGED
@@ -37,7 +37,7 @@ Or, see ["Getting Started"](https://rmosolgo.github.io/graphql-ruby/).
|
|
37
37
|
|
38
38
|
## Upgrade
|
39
39
|
|
40
|
-
I also sell [GraphQL::Pro](http://graphql.pro) which provides several features on top of the GraphQL runtime, including [authorization](http://rmosolgo.github.io/graphql-ruby/pro/authorization), [
|
40
|
+
I also sell [GraphQL::Pro](http://graphql.pro) which provides several features on top of the GraphQL runtime, including [authorization](http://rmosolgo.github.io/graphql-ruby/pro/authorization), [Pusher-based subscriptions](http://graphql-ruby.org/subscriptions/pusher_implementation) and [persisted queries](http://rmosolgo.github.io/graphql-ruby/operation_store/overview). Besides that, Pro customers get email support and an opportunity to support graphql-ruby's development!
|
41
41
|
|
42
42
|
## Goals
|
43
43
|
|
@@ -192,7 +192,7 @@ DummySchema = GraphQL::Schema.define do
|
|
192
192
|
}
|
193
193
|
|
194
194
|
# Object Resolution
|
195
|
-
resolve_type -> (obj, ctx) {
|
195
|
+
resolve_type -> (type, obj, ctx) {
|
196
196
|
# TODO: Implement this function
|
197
197
|
# to return the correct type for `obj`
|
198
198
|
raise(NotImplementedError)
|
@@ -103,12 +103,14 @@ describe GraphQL::Relay::Mutation do
|
|
103
103
|
end
|
104
104
|
|
105
105
|
it "applies the description to the derived field" do
|
106
|
-
|
106
|
+
field = GraphQL::Schema::Field.from_options(name: "x", **StarWars::IntroduceShipMutation.field_options)
|
107
|
+
assert_equal "Add a ship to this faction", field.description
|
107
108
|
end
|
108
109
|
|
109
110
|
it "inserts itself into the derived objects' metadata" do
|
110
|
-
|
111
|
-
assert_equal StarWars::IntroduceShipMutation,
|
111
|
+
field = GraphQL::Schema::Field.from_options(name: "x", **StarWars::IntroduceShipMutation.field_options)
|
112
|
+
assert_equal StarWars::IntroduceShipMutation, field.mutation
|
113
|
+
assert_equal StarWars::IntroduceShipMutation, field.to_graphql.mutation
|
112
114
|
assert_equal StarWars::IntroduceShipMutation, StarWars::IntroduceShipMutation.payload_type.mutation
|
113
115
|
assert_equal StarWars::IntroduceShipMutation, StarWars::IntroduceShipMutation.input_type.mutation
|
114
116
|
end
|
@@ -668,7 +668,7 @@ type Type implements Interface {
|
|
668
668
|
assert_equal [18, 1], schema.types["Union"].ast_node.position
|
669
669
|
assert_equal [20, 1], schema.types["Scalar"].ast_node.position
|
670
670
|
assert_equal [22, 1], schema.types["Input"].ast_node.position
|
671
|
-
assert_equal [
|
671
|
+
assert_equal [23, 3], schema.types["Input"].arguments["argument"].ast_node.position
|
672
672
|
assert_equal [26, 1], schema.directives["Directive"].ast_node.position
|
673
673
|
assert_equal [28, 3], schema.directives["Directive"].arguments["argument"].ast_node.position
|
674
674
|
assert_equal [31, 22], schema.types["Type"].ast_node.interfaces[0].position
|
@@ -19,7 +19,7 @@ describe GraphQL::Schema::Field do
|
|
19
19
|
assert_equal 'inspectInput', field.graphql_definition.name
|
20
20
|
assert_equal 'inspectInput', field.name
|
21
21
|
|
22
|
-
underscored_field = GraphQL::Schema::Field.
|
22
|
+
underscored_field = GraphQL::Schema::Field.from_options(:underscored_field, String, null: false, camelize: false, owner: nil) do
|
23
23
|
argument :underscored_arg, String, required: true, camelize: false
|
24
24
|
end
|
25
25
|
|
@@ -55,7 +55,7 @@ describe GraphQL::Schema::Field do
|
|
55
55
|
type = Class.new(GraphQL::Schema::Object) do
|
56
56
|
graphql_name 'MyType'
|
57
57
|
end
|
58
|
-
field = GraphQL::Schema::Field.
|
58
|
+
field = GraphQL::Schema::Field.from_options(:my_field, type, owner: nil, null: true)
|
59
59
|
assert_equal type.to_graphql, field.to_graphql.type
|
60
60
|
end
|
61
61
|
|
@@ -210,33 +210,16 @@ describe GraphQL::Schema::Field do
|
|
210
210
|
end
|
211
211
|
|
212
212
|
describe "mutation" do
|
213
|
-
|
214
|
-
Class.new(GraphQL::Schema::Mutation) do
|
213
|
+
it "passes when not including extra arguments" do
|
214
|
+
mutation_class = Class.new(GraphQL::Schema::Mutation) do
|
215
215
|
graphql_name "Thing"
|
216
|
-
|
217
216
|
field :stuff, String, null: false
|
218
217
|
end
|
219
|
-
end
|
220
|
-
let(:error_message) { "when keyword `mutation:` is present, all arguments are ignored, please remove them" }
|
221
218
|
|
222
|
-
|
223
|
-
|
224
|
-
GraphQL::Schema::Field.new(:my_field, mutation: mutation, null: true)
|
219
|
+
obj = Class.new(GraphQL::Schema::Object) do
|
220
|
+
field(:my_field, mutation: mutation_class, null: true)
|
225
221
|
end
|
226
|
-
|
227
|
-
assert_equal error.message, error_message
|
228
|
-
end
|
229
|
-
|
230
|
-
it "fails when including null option as false" do
|
231
|
-
error = assert_raises(ArgumentError) do
|
232
|
-
GraphQL::Schema::Field.new(:my_field, mutation: mutation, null: false)
|
233
|
-
end
|
234
|
-
|
235
|
-
assert_equal error.message, error_message
|
236
|
-
end
|
237
|
-
|
238
|
-
it "passes when not including extra arguments" do
|
239
|
-
assert_equal GraphQL::Schema::Field.new(:my_field, mutation: mutation).mutation, mutation
|
222
|
+
assert_equal obj.fields["myField"].mutation, mutation_class
|
240
223
|
end
|
241
224
|
end
|
242
225
|
end
|
@@ -157,4 +157,29 @@ describe GraphQL::Schema::Interface do
|
|
157
157
|
assert_equal(expected_data, res["data"]["find"])
|
158
158
|
end
|
159
159
|
end
|
160
|
+
|
161
|
+
describe ':DefinitionMethods' do
|
162
|
+
module InterfaceA
|
163
|
+
include GraphQL::Schema::Interface
|
164
|
+
end
|
165
|
+
|
166
|
+
module InterfaceB
|
167
|
+
include GraphQL::Schema::Interface
|
168
|
+
end
|
169
|
+
|
170
|
+
module InterfaceC
|
171
|
+
include GraphQL::Schema::Interface
|
172
|
+
end
|
173
|
+
|
174
|
+
it "doesn't overwrite them when including multiple interfaces" do
|
175
|
+
def_methods = InterfaceC::DefinitionMethods
|
176
|
+
|
177
|
+
InterfaceC.module_eval do
|
178
|
+
include InterfaceA
|
179
|
+
include InterfaceB
|
180
|
+
end
|
181
|
+
|
182
|
+
assert_equal(InterfaceC::DefinitionMethods, def_methods)
|
183
|
+
end
|
184
|
+
end
|
160
185
|
end
|
@@ -46,6 +46,17 @@ describe GraphQL::Schema::Member::AcceptsDefinition do
|
|
46
46
|
metadata2 :a, :bc
|
47
47
|
end
|
48
48
|
|
49
|
+
module Thing2
|
50
|
+
include Thing
|
51
|
+
end
|
52
|
+
|
53
|
+
class SomeObject < BaseObject
|
54
|
+
metadata :a, :aaa
|
55
|
+
end
|
56
|
+
|
57
|
+
class SomeObject2 < SomeObject
|
58
|
+
end
|
59
|
+
|
49
60
|
class Query < BaseObject
|
50
61
|
metadata :a, :abc
|
51
62
|
metadata2 :xyz, :zyx
|
@@ -56,6 +67,9 @@ describe GraphQL::Schema::Member::AcceptsDefinition do
|
|
56
67
|
end
|
57
68
|
|
58
69
|
field :thing, Thing, null: false
|
70
|
+
field :thing2, Thing2, null: false
|
71
|
+
field :some_object, SomeObject, null: false
|
72
|
+
field :some_object2, SomeObject2, null: false
|
59
73
|
end
|
60
74
|
|
61
75
|
query(Query)
|
@@ -71,6 +85,14 @@ describe GraphQL::Schema::Member::AcceptsDefinition do
|
|
71
85
|
assert_equal [:z, 888], AcceptsDefinitionSchema::Thing.metadata
|
72
86
|
assert_equal 888, AcceptsDefinitionSchema::Thing.graphql_definition.metadata[:z]
|
73
87
|
assert_equal :bc, AcceptsDefinitionSchema::Thing.graphql_definition.metadata[:a]
|
88
|
+
# Interface inheritance
|
89
|
+
assert_equal [:z, 888], AcceptsDefinitionSchema::Thing2.metadata
|
90
|
+
assert_equal 888, AcceptsDefinitionSchema::Thing2.graphql_definition.metadata[:z]
|
91
|
+
assert_equal :bc, AcceptsDefinitionSchema::Thing2.graphql_definition.metadata[:a]
|
92
|
+
|
93
|
+
# Object inheritance
|
94
|
+
assert_equal :aaa, AcceptsDefinitionSchema::SomeObject.graphql_definition.metadata[:a]
|
95
|
+
assert_equal :aaa, AcceptsDefinitionSchema::SomeObject2.graphql_definition.metadata[:a]
|
74
96
|
end
|
75
97
|
|
76
98
|
it "passes along configs for fields and arguments" do
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require "spec_helper"
|
3
|
+
|
4
|
+
describe GraphQL::Schema::Member::BuildType do
|
5
|
+
describe ".to_type_name" do
|
6
|
+
it "works with lists and non-nulls" do
|
7
|
+
t = Class.new(GraphQL::Schema::Object) do
|
8
|
+
graphql_name "T"
|
9
|
+
end
|
10
|
+
|
11
|
+
req_t = GraphQL::Schema::NonNull.new(t)
|
12
|
+
list_req_t = GraphQL::Schema::List.new(req_t)
|
13
|
+
|
14
|
+
assert_equal "T", GraphQL::Schema::Member::BuildType.to_type_name(list_req_t)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|