graphql 1.8.2 → 1.8.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/generators/graphql/templates/interface.erb +2 -1
- data/lib/graphql.rb +7 -5
- data/lib/graphql/base_type.rb +1 -0
- data/lib/graphql/boolean_type.rb +2 -8
- data/lib/graphql/compatibility/schema_parser_specification.rb +13 -1
- data/lib/graphql/float_type.rb +2 -8
- data/lib/graphql/id_type.rb +2 -15
- data/lib/graphql/int_type.rb +2 -8
- data/lib/graphql/interface_type.rb +18 -0
- data/lib/graphql/language/document_from_schema_definition.rb +11 -1
- data/lib/graphql/language/nodes.rb +6 -1
- data/lib/graphql/language/parser.rb +2 -2
- data/lib/graphql/language/parser.y +2 -2
- data/lib/graphql/language/printer.rb +1 -1
- data/lib/graphql/list_type.rb +1 -0
- data/lib/graphql/non_null_type.rb +1 -0
- data/lib/graphql/relay/connection_instrumentation.rb +19 -15
- data/lib/graphql/relay/node.rb +3 -3
- data/lib/graphql/schema.rb +0 -1
- data/lib/graphql/schema/build_from_definition.rb +1 -1
- data/lib/graphql/schema/built_in_types.rb +12 -0
- data/lib/graphql/schema/field.rb +2 -2
- data/lib/graphql/schema/list.rb +8 -0
- data/lib/graphql/schema/member/build_type.rb +5 -5
- data/lib/graphql/schema/member/type_system_helpers.rb +4 -0
- data/lib/graphql/schema/non_null.rb +4 -0
- data/lib/graphql/schema/scalar.rb +8 -0
- data/lib/graphql/schema/timeout_middleware.rb +1 -1
- data/lib/graphql/string_type.rb +2 -17
- data/lib/graphql/types/boolean.rb +18 -0
- data/lib/graphql/types/float.rb +19 -0
- data/lib/graphql/types/id.rb +24 -0
- data/lib/graphql/types/int.rb +19 -0
- data/lib/graphql/types/iso_8601_date_time.rb +38 -0
- data/lib/graphql/types/string.rb +23 -0
- data/lib/graphql/union_type.rb +18 -0
- data/lib/graphql/version.rb +1 -1
- data/spec/generators/graphql/interface_generator_spec.rb +2 -1
- data/spec/graphql/interface_type_spec.rb +44 -0
- data/spec/graphql/language/visitor_spec.rb +44 -0
- data/spec/graphql/schema/argument_spec.rb +1 -1
- data/spec/graphql/schema/build_from_definition_spec.rb +2 -2
- data/spec/graphql/schema/input_object_spec.rb +1 -1
- data/spec/graphql/types/iso_8601_date_time_spec.rb +110 -0
- data/spec/graphql/union_type_spec.rb +50 -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: 9b0ed1ae533e9983c59332bf6ad38dd5db6e2c92
|
4
|
+
data.tar.gz: 928cd4a961b87fdc43ffe2b71bfd34cea0ae0349
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1f35a05c996558a3742b79e71e89bb83b5dbc41d432e42d6dd06a9a00c3a616c5d0cb1bd23d80b48b66dff52285866ce614d781fd6abe6c61f64df57f3fa41ce
|
7
|
+
data.tar.gz: 6d3fba06e769adf32bd38f450c5d0d7b21f462e8b93160663c1f1c5f9731e1bf27985b25b20b850e9335be114dc28298f9a6dafd323ffb4d2b5640ae33906f80
|
data/lib/graphql.rb
CHANGED
@@ -59,11 +59,7 @@ require "graphql/type_kinds"
|
|
59
59
|
|
60
60
|
require "graphql/backwards_compatibility"
|
61
61
|
require "graphql/scalar_type"
|
62
|
-
|
63
|
-
require "graphql/float_type"
|
64
|
-
require "graphql/id_type"
|
65
|
-
require "graphql/int_type"
|
66
|
-
require "graphql/string_type"
|
62
|
+
|
67
63
|
require "graphql/directive"
|
68
64
|
require "graphql/name_validator"
|
69
65
|
|
@@ -73,6 +69,12 @@ require "graphql/tracing"
|
|
73
69
|
require "graphql/execution"
|
74
70
|
require "graphql/relay"
|
75
71
|
require "graphql/schema"
|
72
|
+
require "graphql/boolean_type"
|
73
|
+
require "graphql/float_type"
|
74
|
+
require "graphql/id_type"
|
75
|
+
require "graphql/int_type"
|
76
|
+
require "graphql/string_type"
|
77
|
+
require "graphql/schema/built_in_types"
|
76
78
|
require "graphql/schema/loader"
|
77
79
|
require "graphql/schema/printer"
|
78
80
|
require "graphql/introspection"
|
data/lib/graphql/base_type.rb
CHANGED
data/lib/graphql/boolean_type.rb
CHANGED
@@ -1,9 +1,3 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
|
3
|
-
|
4
|
-
description "Represents `true` or `false` values."
|
5
|
-
|
6
|
-
coerce_input ->(value, _ctx) { (value == true || value == false) ? value : nil }
|
7
|
-
coerce_result ->(value, _ctx) { !!value }
|
8
|
-
default_scalar true
|
9
|
-
end
|
2
|
+
require "graphql/types/boolean"
|
3
|
+
GraphQL::BOOLEAN_TYPE = GraphQL::Types::Boolean.graphql_definition
|
@@ -137,7 +137,19 @@ module GraphQL
|
|
137
137
|
assert_equal 'if', type.arguments[0].name
|
138
138
|
assert_equal 'Boolean', type.arguments[0].type.of_type.name
|
139
139
|
|
140
|
-
assert_equal
|
140
|
+
assert_equal 3, type.locations.length
|
141
|
+
|
142
|
+
assert_instance_of GraphQL::Language::Nodes::DirectiveLocation, type.locations[0]
|
143
|
+
assert_equal 'FIELD', type.locations[0].name
|
144
|
+
assert_equal [3, 20], type.locations[0].position
|
145
|
+
|
146
|
+
assert_instance_of GraphQL::Language::Nodes::DirectiveLocation, type.locations[1]
|
147
|
+
assert_equal 'FRAGMENT_SPREAD', type.locations[1].name
|
148
|
+
assert_equal [4, 19], type.locations[1].position
|
149
|
+
|
150
|
+
assert_instance_of GraphQL::Language::Nodes::DirectiveLocation, type.locations[2]
|
151
|
+
assert_equal 'INLINE_FRAGMENT', type.locations[2].name
|
152
|
+
assert_equal [5, 19], type.locations[2].position
|
141
153
|
end
|
142
154
|
|
143
155
|
def test_it_parses_field_arguments
|
data/lib/graphql/float_type.rb
CHANGED
@@ -1,9 +1,3 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
|
3
|
-
|
4
|
-
description "Represents signed double-precision fractional values as specified by [IEEE 754](http://en.wikipedia.org/wiki/IEEE_floating_point)."
|
5
|
-
|
6
|
-
coerce_input ->(value, _ctx) { value.is_a?(Numeric) ? value.to_f : nil }
|
7
|
-
coerce_result ->(value, _ctx) { value.to_f }
|
8
|
-
default_scalar true
|
9
|
-
end
|
2
|
+
require "graphql/types/float"
|
3
|
+
GraphQL::FLOAT_TYPE = GraphQL::Types::Float.graphql_definition
|
data/lib/graphql/id_type.rb
CHANGED
@@ -1,16 +1,3 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
|
3
|
-
|
4
|
-
description "Represents a unique identifier that is Base64 obfuscated. It is often used to refetch an object or as key for a cache. The ID type appears in a JSON response as a String; however, it is not intended to be human-readable. When expected as an input type, any string (such as `\"VXNlci0xMA==\"`) or integer (such as `4`) input value will be accepted as an ID."
|
5
|
-
|
6
|
-
coerce_result ->(value, _ctx) { value.to_s }
|
7
|
-
coerce_input ->(value, _ctx) {
|
8
|
-
case value
|
9
|
-
when String, Integer
|
10
|
-
value.to_s
|
11
|
-
else
|
12
|
-
nil
|
13
|
-
end
|
14
|
-
}
|
15
|
-
default_scalar true
|
16
|
-
end
|
2
|
+
require "graphql/types/id"
|
3
|
+
GraphQL::ID_TYPE = GraphQL::Types::ID.graphql_definition
|
data/lib/graphql/int_type.rb
CHANGED
@@ -1,9 +1,3 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
|
3
|
-
|
4
|
-
description "Represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1."
|
5
|
-
|
6
|
-
coerce_input ->(value, _ctx) { value.is_a?(Numeric) ? value.to_i : nil }
|
7
|
-
coerce_result ->(value, _ctx) { value.to_i }
|
8
|
-
default_scalar true
|
9
|
-
end
|
2
|
+
require "graphql/types/int"
|
3
|
+
GraphQL::INT_TYPE = GraphQL::Types::Int.graphql_definition
|
@@ -64,5 +64,23 @@ module GraphQL
|
|
64
64
|
def all_fields
|
65
65
|
fields.values
|
66
66
|
end
|
67
|
+
|
68
|
+
# Get a possible type of this {InterfaceType} by type name
|
69
|
+
# @param type_name [String]
|
70
|
+
# @param ctx [GraphQL::Query::Context] The context for the current query
|
71
|
+
# @return [GraphQL::ObjectType, nil] The type named `type_name` if it exists and implements this {InterfaceType}, (else `nil`)
|
72
|
+
def get_possible_type(type_name, ctx)
|
73
|
+
type = ctx.query.get_type(type_name)
|
74
|
+
type if type && ctx.query.schema.possible_types(self).include?(type)
|
75
|
+
end
|
76
|
+
|
77
|
+
# Check if a type is a possible type of this {InterfaceType}
|
78
|
+
# @param type [String, GraphQL::BaseType] Name of the type or a type definition
|
79
|
+
# @param ctx [GraphQL::Query::Context] The context for the current query
|
80
|
+
# @return [Boolean] True if the `type` exists and is a member of this {InterfaceType}, (else `nil`)
|
81
|
+
def possible_type?(type, ctx)
|
82
|
+
type_name = type.is_a?(String) ? type : type.graphql_name
|
83
|
+
!get_possible_type(type_name, ctx).nil?
|
84
|
+
end
|
67
85
|
end
|
68
86
|
end
|
@@ -149,11 +149,21 @@ module GraphQL
|
|
149
149
|
GraphQL::Language::Nodes::DirectiveDefinition.new(
|
150
150
|
name: directive.name,
|
151
151
|
arguments: build_argument_nodes(warden.arguments(directive)),
|
152
|
-
locations: directive.locations
|
152
|
+
locations: build_directive_location_nodes(directive.locations),
|
153
153
|
description: directive.description,
|
154
154
|
)
|
155
155
|
end
|
156
156
|
|
157
|
+
def build_directive_location_nodes(locations)
|
158
|
+
locations.map { |location| build_directive_location_node(location) }
|
159
|
+
end
|
160
|
+
|
161
|
+
def build_directive_location_node(location)
|
162
|
+
GraphQL::Language::Nodes::DirectiveLocation.new(
|
163
|
+
name: location.to_s
|
164
|
+
)
|
165
|
+
end
|
166
|
+
|
157
167
|
def build_type_name_node(type)
|
158
168
|
case type
|
159
169
|
when GraphQL::ListType
|
@@ -144,6 +144,8 @@ module GraphQL
|
|
144
144
|
end
|
145
145
|
end
|
146
146
|
|
147
|
+
class DirectiveLocation < NameOnlyNode; end
|
148
|
+
|
147
149
|
# This is the AST root for normal queries
|
148
150
|
#
|
149
151
|
# @example Deriving a document by parsing a string
|
@@ -537,7 +539,6 @@ module GraphQL
|
|
537
539
|
include Scalars::Name
|
538
540
|
|
539
541
|
attr_accessor :name, :fields, :directives, :description
|
540
|
-
alias :children :fields
|
541
542
|
|
542
543
|
def initialize_node(name:, fields:, directives: [], description: nil)
|
543
544
|
@name = name
|
@@ -545,6 +546,10 @@ module GraphQL
|
|
545
546
|
@directives = directives
|
546
547
|
@description = description
|
547
548
|
end
|
549
|
+
|
550
|
+
def children
|
551
|
+
fields + directives
|
552
|
+
end
|
548
553
|
end
|
549
554
|
end
|
550
555
|
end
|
@@ -1697,14 +1697,14 @@ module_eval(<<'.,.,', 'parser.y', 365)
|
|
1697
1697
|
|
1698
1698
|
module_eval(<<'.,.,', 'parser.y', 369)
|
1699
1699
|
def _reduce_147(val, _values, result)
|
1700
|
-
return [val[0].to_s]
|
1700
|
+
return [make_node(:DirectiveLocation, name: val[0].to_s, position_source: val[0])]
|
1701
1701
|
result
|
1702
1702
|
end
|
1703
1703
|
.,.,
|
1704
1704
|
|
1705
1705
|
module_eval(<<'.,.,', 'parser.y', 370)
|
1706
1706
|
def _reduce_148(val, _values, result)
|
1707
|
-
val[0] << val[2].to_s
|
1707
|
+
val[0] << make_node(:DirectiveLocation, name: val[2].to_s, position_source: val[2])
|
1708
1708
|
result
|
1709
1709
|
end
|
1710
1710
|
.,.,
|
@@ -367,8 +367,8 @@ rule
|
|
367
367
|
}
|
368
368
|
|
369
369
|
directive_locations:
|
370
|
-
name { return [val[0].to_s] }
|
371
|
-
| directive_locations PIPE name { val[0] << val[2].to_s }
|
370
|
+
name { return [make_node(:DirectiveLocation, name: val[0].to_s, position_source: val[0])] }
|
371
|
+
| directive_locations PIPE name { val[0] << make_node(:DirectiveLocation, name: val[2].to_s, position_source: val[2]) }
|
372
372
|
end
|
373
373
|
|
374
374
|
---- header ----
|
@@ -247,7 +247,7 @@ module GraphQL
|
|
247
247
|
out << print_arguments(directive.arguments)
|
248
248
|
end
|
249
249
|
|
250
|
-
out << " on #{directive.locations.join(' | ')}"
|
250
|
+
out << " on #{directive.locations.map(&:name).join(' | ')}"
|
251
251
|
end
|
252
252
|
|
253
253
|
def print_description(node, indent: "", first_in_block: true)
|
data/lib/graphql/list_type.rb
CHANGED
@@ -7,21 +7,25 @@ module GraphQL
|
|
7
7
|
# The original resolve proc is used to fetch nodes,
|
8
8
|
# then a connection implementation is fetched with {BaseConnection.connection_for_nodes}.
|
9
9
|
module ConnectionInstrumentation
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
10
|
+
def self.default_arguments
|
11
|
+
@default_arguments ||= begin
|
12
|
+
argument_definitions = [
|
13
|
+
["first", GraphQL::INT_TYPE, "Returns the first _n_ elements from the list."],
|
14
|
+
["after", GraphQL::STRING_TYPE, "Returns the elements in the list that come after the specified cursor."],
|
15
|
+
["last", GraphQL::INT_TYPE, "Returns the last _n_ elements from the list."],
|
16
|
+
["before", GraphQL::STRING_TYPE, "Returns the elements in the list that come before the specified cursor."],
|
17
|
+
]
|
16
18
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
19
|
+
argument_definitions.reduce({}) do |memo, arg_defn|
|
20
|
+
argument = GraphQL::Argument.new
|
21
|
+
name, type, description = arg_defn
|
22
|
+
argument.name = name
|
23
|
+
argument.type = type
|
24
|
+
argument.description = description
|
25
|
+
memo[argument.name.to_s] = argument
|
26
|
+
memo
|
27
|
+
end
|
28
|
+
end
|
25
29
|
end
|
26
30
|
|
27
31
|
# Build a connection field from a {GraphQL::Field} by:
|
@@ -29,7 +33,7 @@ module GraphQL
|
|
29
33
|
# - Transforming its resolve function to return a connection object
|
30
34
|
def self.instrument(type, field)
|
31
35
|
if field.connection?
|
32
|
-
connection_arguments =
|
36
|
+
connection_arguments = default_arguments.merge(field.arguments)
|
33
37
|
original_resolve = field.resolve_proc
|
34
38
|
original_lazy_resolve = field.lazy_resolve_proc
|
35
39
|
connection_resolve = GraphQL::Relay::ConnectionResolve.new(field, original_resolve, lazy: false)
|
data/lib/graphql/relay/node.rb
CHANGED
@@ -11,7 +11,7 @@ module GraphQL
|
|
11
11
|
field = GraphQL::Field.define do
|
12
12
|
type(GraphQL::Relay::Node.interface)
|
13
13
|
description("Fetches an object given its ID.")
|
14
|
-
argument(:id,
|
14
|
+
argument(:id, types.ID.to_non_null_type, "ID of the object.")
|
15
15
|
resolve(GraphQL::Relay::Node::FindNode)
|
16
16
|
relay_node_field(true)
|
17
17
|
end
|
@@ -27,7 +27,7 @@ module GraphQL
|
|
27
27
|
field = GraphQL::Field.define do
|
28
28
|
type(!types[GraphQL::Relay::Node.interface])
|
29
29
|
description("Fetches a list of objects given a list of IDs.")
|
30
|
-
argument(:ids,
|
30
|
+
argument(:ids, types.ID.to_non_null_type.to_list_type.to_non_null_type, "IDs of the objects.")
|
31
31
|
resolve(GraphQL::Relay::Node::FindNodes)
|
32
32
|
relay_nodes_field(true)
|
33
33
|
end
|
@@ -44,7 +44,7 @@ module GraphQL
|
|
44
44
|
@interface ||= GraphQL::InterfaceType.define do
|
45
45
|
name("Node")
|
46
46
|
description("An object with an ID.")
|
47
|
-
field(:id,
|
47
|
+
field(:id, types.ID.to_non_null_type, "ID of the object.")
|
48
48
|
default_relay(true)
|
49
49
|
end
|
50
50
|
end
|
data/lib/graphql/schema.rb
CHANGED
@@ -134,7 +134,6 @@ module GraphQL
|
|
134
134
|
|
135
135
|
self.default_execution_strategy = GraphQL::Execution::Execute
|
136
136
|
|
137
|
-
BUILT_IN_TYPES = Hash[[INT_TYPE, STRING_TYPE, FLOAT_TYPE, BOOLEAN_TYPE, ID_TYPE].map{ |type| [type.name, type] }]
|
138
137
|
DIRECTIVES = [GraphQL::Directive::IncludeDirective, GraphQL::Directive::SkipDirective, GraphQL::Directive::DeprecatedDirective]
|
139
138
|
DYNAMIC_FIELDS = ["__type", "__typename", "__schema"]
|
140
139
|
|
@@ -251,7 +251,7 @@ module GraphQL
|
|
251
251
|
name: directive_definition.name,
|
252
252
|
description: directive_definition.description,
|
253
253
|
arguments: Hash[build_directive_arguments(directive_definition, type_resolver)],
|
254
|
-
locations: directive_definition.locations.map
|
254
|
+
locations: directive_definition.locations.map { |location| location.name.to_sym },
|
255
255
|
)
|
256
256
|
|
257
257
|
directive.ast_node = directive_definition
|
data/lib/graphql/schema/field.rb
CHANGED
@@ -242,8 +242,8 @@ module GraphQL
|
|
242
242
|
# TODO: this could be a bit weird, because these fields won't be present
|
243
243
|
# after initialization, only in the `to_graphql` response.
|
244
244
|
# This calculation _could_ be moved up if need be.
|
245
|
-
argument :after, "String", "Returns the elements in the list that come after the specified
|
246
|
-
argument :before, "String", "Returns the elements in the list that come before the specified
|
245
|
+
argument :after, "String", "Returns the elements in the list that come after the specified cursor.", required: false
|
246
|
+
argument :before, "String", "Returns the elements in the list that come before the specified cursor.", required: false
|
247
247
|
argument :first, "Int", "Returns the first _n_ elements from the list.", required: false
|
248
248
|
argument :last, "Int", "Returns the last _n_ elements from the list.", required: false
|
249
249
|
end
|
data/lib/graphql/schema/list.rb
CHANGED
@@ -16,15 +16,15 @@ module GraphQL
|
|
16
16
|
when String
|
17
17
|
case type_expr
|
18
18
|
when "String"
|
19
|
-
GraphQL::
|
19
|
+
GraphQL::Types::String
|
20
20
|
when "Int", "Integer"
|
21
|
-
GraphQL::
|
21
|
+
GraphQL::Types::Int
|
22
22
|
when "Float"
|
23
|
-
GraphQL::
|
23
|
+
GraphQL::Types::Float
|
24
24
|
when "Boolean"
|
25
|
-
GraphQL::
|
25
|
+
GraphQL::Types::Boolean
|
26
26
|
when "ID"
|
27
|
-
GraphQL::
|
27
|
+
GraphQL::Types::ID
|
28
28
|
when /\A\[.*\]\Z/
|
29
29
|
list_type = true
|
30
30
|
# List members are required by default
|
@@ -23,12 +23,20 @@ module GraphQL
|
|
23
23
|
type_defn.coerce_result = method(:coerce_result)
|
24
24
|
type_defn.coerce_input = method(:coerce_input)
|
25
25
|
type_defn.metadata[:type_class] = self
|
26
|
+
type_defn.default_scalar = default_scalar
|
26
27
|
type_defn
|
27
28
|
end
|
28
29
|
|
29
30
|
def kind
|
30
31
|
GraphQL::TypeKinds::SCALAR
|
31
32
|
end
|
33
|
+
|
34
|
+
def default_scalar(is_default = nil)
|
35
|
+
if !is_default.nil?
|
36
|
+
@default_scalar = is_default
|
37
|
+
end
|
38
|
+
@default_scalar
|
39
|
+
end
|
32
40
|
end
|
33
41
|
end
|
34
42
|
end
|
@@ -34,7 +34,7 @@ module GraphQL
|
|
34
34
|
end
|
35
35
|
|
36
36
|
def call(parent_type, parent_object, field_definition, field_args, query_context)
|
37
|
-
ns = query_context.namespace(
|
37
|
+
ns = query_context.namespace(self.class)
|
38
38
|
timeout_at = ns[:timeout_at] ||= Time.now + @max_seconds
|
39
39
|
|
40
40
|
if timeout_at < Time.now
|
data/lib/graphql/string_type.rb
CHANGED
@@ -1,18 +1,3 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
|
3
|
-
|
4
|
-
description "Represents textual data as UTF-8 character sequences. This type is most often used by GraphQL to represent free-form human-readable text."
|
5
|
-
|
6
|
-
coerce_result ->(value, ctx) {
|
7
|
-
begin
|
8
|
-
str = value.to_s
|
9
|
-
str.encoding == Encoding::UTF_8 ? str : str.encode(Encoding::UTF_8)
|
10
|
-
rescue EncodingError
|
11
|
-
err = GraphQL::StringEncodingError.new(str)
|
12
|
-
ctx.schema.type_error(err, ctx)
|
13
|
-
end
|
14
|
-
}
|
15
|
-
|
16
|
-
coerce_input ->(value, _ctx) { value.is_a?(String) ? value : nil }
|
17
|
-
default_scalar true
|
18
|
-
end
|
2
|
+
require "graphql/types/string"
|
3
|
+
GraphQL::STRING_TYPE = GraphQL::Types::String.graphql_definition
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module GraphQL
|
3
|
+
module Types
|
4
|
+
class Boolean < GraphQL::Schema::Scalar
|
5
|
+
description "Represents `true` or `false` values."
|
6
|
+
|
7
|
+
def self.coerce_input(value, _ctx)
|
8
|
+
(value == true || value == false) ? value : nil
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.coerce_result(value, _ctx)
|
12
|
+
!!value
|
13
|
+
end
|
14
|
+
|
15
|
+
default_scalar true
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GraphQL
|
4
|
+
module Types
|
5
|
+
class Float < GraphQL::Schema::Scalar
|
6
|
+
description "Represents signed double-precision fractional values as specified by [IEEE 754](http://en.wikipedia.org/wiki/IEEE_floating_point)."
|
7
|
+
|
8
|
+
def self.coerce_input(value, _ctx)
|
9
|
+
value.is_a?(Numeric) ? value.to_f : nil
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.coerce_result(value, _ctx)
|
13
|
+
value.to_f
|
14
|
+
end
|
15
|
+
|
16
|
+
default_scalar true
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module GraphQL
|
3
|
+
module Types
|
4
|
+
class ID < GraphQL::Schema::Scalar
|
5
|
+
graphql_name "ID"
|
6
|
+
description "Represents a unique identifier that is Base64 obfuscated. It is often used to refetch an object or as key for a cache. The ID type appears in a JSON response as a String; however, it is not intended to be human-readable. When expected as an input type, any string (such as `\"VXNlci0xMA==\"`) or integer (such as `4`) input value will be accepted as an ID."
|
7
|
+
default_scalar true
|
8
|
+
def self.coerce_result(value, _ctx)
|
9
|
+
value.is_a?(::String) ? value : value.to_s
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.coerce_input(value, _ctx)
|
13
|
+
case value
|
14
|
+
when ::String
|
15
|
+
value
|
16
|
+
when Integer
|
17
|
+
value.to_s
|
18
|
+
else
|
19
|
+
nil
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GraphQL
|
4
|
+
module Types
|
5
|
+
class Int < GraphQL::Schema::Scalar
|
6
|
+
description "Represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1."
|
7
|
+
|
8
|
+
def self.coerce_input(value, _ctx)
|
9
|
+
value.is_a?(Numeric) ? value.to_i : nil
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.coerce_result(value, _ctx)
|
13
|
+
value.to_i
|
14
|
+
end
|
15
|
+
|
16
|
+
default_scalar true
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module GraphQL
|
3
|
+
module Types
|
4
|
+
# This scalar takes `DateTime`s and transmits them as strings,
|
5
|
+
# using ISO 8601 format.
|
6
|
+
#
|
7
|
+
# To use it, require it in your project:
|
8
|
+
#
|
9
|
+
# require "graphql/types/iso_8601_date_time"
|
10
|
+
#
|
11
|
+
# Then use it for fields or arguments:
|
12
|
+
#
|
13
|
+
# field :created_at, GraphQL::Types::ISO8601DateTime, null: false
|
14
|
+
#
|
15
|
+
# argument :deliver_at, GraphQL::Types::ISO8601DateTime, null: false
|
16
|
+
#
|
17
|
+
# Alternatively, use this built-in scalar as inspiration for your
|
18
|
+
# own DateTime type.
|
19
|
+
class ISO8601DateTime < GraphQL::Schema::Scalar
|
20
|
+
description "An ISO 8601-encoded datetime"
|
21
|
+
|
22
|
+
# @param value [DateTime]
|
23
|
+
# @return [String]
|
24
|
+
def self.coerce_result(value, _ctx)
|
25
|
+
value.iso8601
|
26
|
+
end
|
27
|
+
|
28
|
+
# @param str_value [String]
|
29
|
+
# @return [DateTime]
|
30
|
+
def self.coerce_input(str_value, _ctx)
|
31
|
+
DateTime.iso8601(str_value)
|
32
|
+
rescue ArgumentError
|
33
|
+
# Invalid input
|
34
|
+
nil
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module GraphQL
|
4
|
+
module Types
|
5
|
+
class String < GraphQL::Schema::Scalar
|
6
|
+
description "Represents textual data as UTF-8 character sequences. This type is most often used by GraphQL to represent free-form human-readable text."
|
7
|
+
|
8
|
+
def self.coerce_result(value, ctx)
|
9
|
+
str = value.to_s
|
10
|
+
str.encoding == Encoding::UTF_8 ? str : str.encode(Encoding::UTF_8)
|
11
|
+
rescue EncodingError
|
12
|
+
err = GraphQL::StringEncodingError.new(str)
|
13
|
+
ctx.schema.type_error(err, ctx)
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.coerce_input(value, _ctx)
|
17
|
+
value.is_a?(::String) ? value : nil
|
18
|
+
end
|
19
|
+
|
20
|
+
default_scalar true
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/graphql/union_type.rb
CHANGED
@@ -67,6 +67,24 @@ module GraphQL
|
|
67
67
|
end
|
68
68
|
end
|
69
69
|
|
70
|
+
# Get a possible type of this {UnionType} by type name
|
71
|
+
# @param type_name [String]
|
72
|
+
# @param ctx [GraphQL::Query::Context] The context for the current query
|
73
|
+
# @return [GraphQL::ObjectType, nil] The type named `type_name` if it exists and is a member of this {UnionType}, (else `nil`)
|
74
|
+
def get_possible_type(type_name, ctx)
|
75
|
+
type = ctx.query.get_type(type_name)
|
76
|
+
type if type && ctx.query.schema.possible_types(self).include?(type)
|
77
|
+
end
|
78
|
+
|
79
|
+
# Check if a type is a possible type of this {UnionType}
|
80
|
+
# @param type [String, GraphQL::BaseType] Name of the type or a type definition
|
81
|
+
# @param ctx [GraphQL::Query::Context] The context for the current query
|
82
|
+
# @return [Boolean] True if the `type` exists and is a member of this {UnionType}, (else `nil`)
|
83
|
+
def possible_type?(type, ctx)
|
84
|
+
type_name = type.is_a?(String) ? type : type.graphql_name
|
85
|
+
!get_possible_type(type_name, ctx).nil?
|
86
|
+
end
|
87
|
+
|
70
88
|
def resolve_type(value, ctx)
|
71
89
|
ctx.query.resolve_type(self, value)
|
72
90
|
end
|
data/lib/graphql/version.rb
CHANGED
@@ -16,7 +16,8 @@ class GraphQLGeneratorsInterfaceGeneratorTest < BaseGeneratorTest
|
|
16
16
|
]
|
17
17
|
|
18
18
|
expected_content = <<-RUBY
|
19
|
-
|
19
|
+
module Types::BirdType
|
20
|
+
include Types::BaseInterface
|
20
21
|
field :wingspan, Integer, null: false
|
21
22
|
field :foliage, [Types::ColorType], null: true
|
22
23
|
end
|
@@ -149,4 +149,48 @@ describe GraphQL::InterfaceType do
|
|
149
149
|
assert_equal expected_result, result["data"]
|
150
150
|
end
|
151
151
|
end
|
152
|
+
|
153
|
+
describe "#get_possible_type" do
|
154
|
+
let(:query_string) {%|
|
155
|
+
query fav {
|
156
|
+
favoriteEdible { fatContent }
|
157
|
+
}
|
158
|
+
|}
|
159
|
+
|
160
|
+
let(:query) { GraphQL::Query.new(Dummy::Schema, query_string) }
|
161
|
+
|
162
|
+
it "returns the type definition if the type exists and is a possible type of the interface" do
|
163
|
+
assert interface.get_possible_type("Cheese", query.context)
|
164
|
+
end
|
165
|
+
|
166
|
+
it "returns nil if the type is not found in the schema" do
|
167
|
+
assert_nil interface.get_possible_type("Foo", query.context)
|
168
|
+
end
|
169
|
+
|
170
|
+
it "returns nil if the type is not a possible type of the interface" do
|
171
|
+
assert_nil interface.get_possible_type("Beverage", query.context)
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
describe "#possible_type?" do
|
176
|
+
let(:query_string) {%|
|
177
|
+
query fav {
|
178
|
+
favoriteEdible { fatContent }
|
179
|
+
}
|
180
|
+
|}
|
181
|
+
|
182
|
+
let(:query) { GraphQL::Query.new(Dummy::Schema, query_string) }
|
183
|
+
|
184
|
+
it "returns true if the type exists and is a possible type of the interface" do
|
185
|
+
assert interface.possible_type?("Cheese", query.context)
|
186
|
+
end
|
187
|
+
|
188
|
+
it "returns false if the type is not found in the schema" do
|
189
|
+
refute interface.possible_type?("Foo", query.context)
|
190
|
+
end
|
191
|
+
|
192
|
+
it "returns false if the type is not a possible type of the interface" do
|
193
|
+
refute interface.possible_type?("Beverage", query.context)
|
194
|
+
end
|
195
|
+
end
|
152
196
|
end
|
@@ -40,6 +40,31 @@ describe GraphQL::Language::Visitor do
|
|
40
40
|
assert(counts[:finished])
|
41
41
|
end
|
42
42
|
|
43
|
+
it "can visit a document with directive definitions" do
|
44
|
+
document = GraphQL.parse("
|
45
|
+
# Marks an element of a GraphQL schema as only available via a preview header
|
46
|
+
directive @preview(
|
47
|
+
# The identifier of the API preview that toggles this field.
|
48
|
+
toggledBy: String
|
49
|
+
) on SCALAR | OBJECT | FIELD_DEFINITION | ARGUMENT_DEFINITION | INTERFACE | UNION | ENUM | ENUM_VALUE | INPUT_OBJECT | INPUT_FIELD_DEFINITION
|
50
|
+
|
51
|
+
type Query {
|
52
|
+
hello: String
|
53
|
+
}
|
54
|
+
")
|
55
|
+
|
56
|
+
directive = nil
|
57
|
+
directive_locations = []
|
58
|
+
|
59
|
+
v = GraphQL::Language::Visitor.new(document)
|
60
|
+
v[GraphQL::Language::Nodes::DirectiveDefinition] << ->(node, parent) { directive = node }
|
61
|
+
v[GraphQL::Language::Nodes::DirectiveLocation] << ->(node, parent) { directive_locations << node }
|
62
|
+
v.visit
|
63
|
+
|
64
|
+
assert_equal "preview", directive.name
|
65
|
+
assert_equal 10, directive_locations.length
|
66
|
+
end
|
67
|
+
|
43
68
|
describe "Visitor::SKIP" do
|
44
69
|
it "skips the rest of the node" do
|
45
70
|
visitor[GraphQL::Language::Nodes::Document] << ->(node, parent) { GraphQL::Language::Visitor::SKIP }
|
@@ -47,4 +72,23 @@ describe GraphQL::Language::Visitor do
|
|
47
72
|
assert_equal(0, counts[:fields_entered])
|
48
73
|
end
|
49
74
|
end
|
75
|
+
|
76
|
+
it "can visit InputObjectTypeDefinition directives" do
|
77
|
+
schema_sdl = <<-GRAPHQL
|
78
|
+
input Test @directive {
|
79
|
+
id: ID!
|
80
|
+
}
|
81
|
+
GRAPHQL
|
82
|
+
|
83
|
+
document = GraphQL.parse(schema_sdl)
|
84
|
+
|
85
|
+
visitor = GraphQL::Language::Visitor.new(document)
|
86
|
+
|
87
|
+
visited_directive = false
|
88
|
+
visitor[GraphQL::Language::Nodes::Directive] << ->(node, parent) { visited_directive = true }
|
89
|
+
|
90
|
+
visitor.visit
|
91
|
+
|
92
|
+
assert visited_directive
|
93
|
+
end
|
50
94
|
end
|
@@ -40,7 +40,7 @@ describe GraphQL::Schema::Argument do
|
|
40
40
|
describe "#type" do
|
41
41
|
let(:argument) { SchemaArgumentTest::Query.fields["field"].arguments["arg"] }
|
42
42
|
it "returns the type" do
|
43
|
-
assert_equal GraphQL::
|
43
|
+
assert_equal GraphQL::Types::String, argument.type
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
@@ -281,10 +281,10 @@ type Type {
|
|
281
281
|
|
282
282
|
# A list of organizations the user belongs to.
|
283
283
|
organizations(
|
284
|
-
# Returns the elements in the list that come after the specified
|
284
|
+
# Returns the elements in the list that come after the specified cursor.
|
285
285
|
after: String
|
286
286
|
|
287
|
-
# Returns the elements in the list that come before the specified
|
287
|
+
# Returns the elements in the list that come before the specified cursor.
|
288
288
|
before: String
|
289
289
|
|
290
290
|
# Returns the first _n_ elements from the list.
|
@@ -28,7 +28,7 @@ describe GraphQL::Schema::InputObject do
|
|
28
28
|
|
29
29
|
assert_equal 3, subclass.arguments.size
|
30
30
|
assert_equal ["arg1", "arg2", "arg3"], subclass.arguments.keys
|
31
|
-
assert_equal ["String!", "Int!", "Int!"], subclass.arguments.values.map { |a| a.type.
|
31
|
+
assert_equal ["String!", "Int!", "Int!"], subclass.arguments.values.map { |a| a.type.to_type_signature }
|
32
32
|
end
|
33
33
|
end
|
34
34
|
|
@@ -0,0 +1,110 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require "spec_helper"
|
3
|
+
require "graphql/types/iso_8601_date_time"
|
4
|
+
describe GraphQL::Types::ISO8601DateTime do
|
5
|
+
module DateTimeTest
|
6
|
+
class DateTimeObject < GraphQL::Schema::Object
|
7
|
+
field :year, Integer, null: false
|
8
|
+
field :month, Integer, null: false
|
9
|
+
field :day, Integer, null: false
|
10
|
+
field :hour, Integer, null: false
|
11
|
+
field :minute, Integer, null: false
|
12
|
+
field :second, Integer, null: false
|
13
|
+
field :zone, String, null: false
|
14
|
+
# Use method: :object so that the DateTime instance is passed to the scalar
|
15
|
+
field :iso8601, GraphQL::Types::ISO8601DateTime, null: false, method: :object
|
16
|
+
end
|
17
|
+
|
18
|
+
class Query < GraphQL::Schema::Object
|
19
|
+
field :parse_date, DateTimeObject, null: true do
|
20
|
+
argument :date, GraphQL::Types::ISO8601DateTime, required: true
|
21
|
+
end
|
22
|
+
|
23
|
+
def parse_date(date:)
|
24
|
+
# Date is parsed by the scalar, so it's already a DateTime
|
25
|
+
date
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
class Schema < GraphQL::Schema
|
31
|
+
query(Query)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
describe "as an input" do
|
37
|
+
|
38
|
+
def parse_date(date_str)
|
39
|
+
query_str = <<-GRAPHQL
|
40
|
+
query($date: ISO8601DateTime!){
|
41
|
+
parseDate(date: $date) {
|
42
|
+
year
|
43
|
+
month
|
44
|
+
day
|
45
|
+
hour
|
46
|
+
minute
|
47
|
+
second
|
48
|
+
zone
|
49
|
+
}
|
50
|
+
}
|
51
|
+
GRAPHQL
|
52
|
+
full_res = DateTimeTest::Schema.execute(query_str, variables: { date: date_str })
|
53
|
+
full_res["errors"] || full_res["data"]["parseDate"]
|
54
|
+
end
|
55
|
+
|
56
|
+
it "parses valid dates" do
|
57
|
+
res = parse_date("2018-06-07T09:31:42-07:00")
|
58
|
+
expected_res = {
|
59
|
+
"year" => 2018,
|
60
|
+
"month" => 6,
|
61
|
+
"day" => 7,
|
62
|
+
"hour" => 9,
|
63
|
+
"minute" => 31,
|
64
|
+
"second" => 42,
|
65
|
+
"zone" => "-07:00",
|
66
|
+
}
|
67
|
+
assert_equal(expected_res, res)
|
68
|
+
end
|
69
|
+
|
70
|
+
it "adds an error for invalid dates" do
|
71
|
+
expected_errors = ["Variable date of type ISO8601DateTime! was provided invalid value"]
|
72
|
+
|
73
|
+
assert_equal expected_errors, parse_date("2018-06-07T99:31:42-07:00").map { |e| e["message"] }
|
74
|
+
assert_equal expected_errors, parse_date("xyz").map { |e| e["message"] }
|
75
|
+
assert_equal expected_errors, parse_date(nil).map { |e| e["message"] }
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
describe "as an output" do
|
80
|
+
it "returns a string" do
|
81
|
+
query_str = <<-GRAPHQL
|
82
|
+
query($date: ISO8601DateTime!){
|
83
|
+
parseDate(date: $date) {
|
84
|
+
iso8601
|
85
|
+
}
|
86
|
+
}
|
87
|
+
GRAPHQL
|
88
|
+
|
89
|
+
date_str = "2010-02-02T22:30:30-06:00"
|
90
|
+
full_res = DateTimeTest::Schema.execute(query_str, variables: { date: date_str })
|
91
|
+
assert_equal date_str, full_res["data"]["parseDate"]["iso8601"]
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
describe "structure" do
|
96
|
+
it "is in introspection" do
|
97
|
+
introspection_res = DateTimeTest::Schema.execute <<-GRAPHQL
|
98
|
+
{
|
99
|
+
__type(name: "ISO8601DateTime") {
|
100
|
+
name
|
101
|
+
kind
|
102
|
+
}
|
103
|
+
}
|
104
|
+
GRAPHQL
|
105
|
+
|
106
|
+
expected_res = { "name" => "ISO8601DateTime", "kind" => "SCALAR"}
|
107
|
+
assert_equal expected_res, introspection_res["data"]["__type"]
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
@@ -158,4 +158,54 @@ describe GraphQL::UnionType do
|
|
158
158
|
assert_equal 3, union_2.possible_types.size
|
159
159
|
end
|
160
160
|
end
|
161
|
+
|
162
|
+
describe "#get_possible_type" do
|
163
|
+
let(:query_string) {%|
|
164
|
+
{
|
165
|
+
__type(name: "Beverage") {
|
166
|
+
name
|
167
|
+
}
|
168
|
+
}
|
169
|
+
|}
|
170
|
+
|
171
|
+
let(:query) { GraphQL::Query.new(Dummy::Schema, query_string) }
|
172
|
+
let(:union) { Dummy::BeverageUnion }
|
173
|
+
|
174
|
+
it "returns the type definition if the type exists and is a possible type of the union" do
|
175
|
+
assert union.get_possible_type("Milk", query.context)
|
176
|
+
end
|
177
|
+
|
178
|
+
it "returns nil if the type is not found in the schema" do
|
179
|
+
assert_nil union.get_possible_type("Foo", query.context)
|
180
|
+
end
|
181
|
+
|
182
|
+
it "returns nil if the type is not a possible type of the union" do
|
183
|
+
assert_nil union.get_possible_type("Cheese", query.context)
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
describe "#possible_type?" do
|
188
|
+
let(:query_string) {%|
|
189
|
+
{
|
190
|
+
__type(name: "Beverage") {
|
191
|
+
name
|
192
|
+
}
|
193
|
+
}
|
194
|
+
|}
|
195
|
+
|
196
|
+
let(:query) { GraphQL::Query.new(Dummy::Schema, query_string) }
|
197
|
+
let(:union) { Dummy::BeverageUnion }
|
198
|
+
|
199
|
+
it "returns true if the type exists and is a possible type of the union" do
|
200
|
+
assert union.possible_type?("Milk", query.context)
|
201
|
+
end
|
202
|
+
|
203
|
+
it "returns false if the type is not found in the schema" do
|
204
|
+
refute union.possible_type?("Foo", query.context)
|
205
|
+
end
|
206
|
+
|
207
|
+
it "returns false if the type is not a possible type of the union" do
|
208
|
+
refute union.possible_type?("Cheese", query.context)
|
209
|
+
end
|
210
|
+
end
|
161
211
|
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: 1.8.
|
4
|
+
version: 1.8.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Robert Mosolgo
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-06-
|
11
|
+
date: 2018-06-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: benchmark-ips
|
@@ -494,6 +494,7 @@ files:
|
|
494
494
|
- lib/graphql/schema/build_from_definition.rb
|
495
495
|
- lib/graphql/schema/build_from_definition/resolve_map.rb
|
496
496
|
- lib/graphql/schema/build_from_definition/resolve_map/default_resolve.rb
|
497
|
+
- lib/graphql/schema/built_in_types.rb
|
497
498
|
- lib/graphql/schema/catchall_middleware.rb
|
498
499
|
- lib/graphql/schema/default_parse_error.rb
|
499
500
|
- lib/graphql/schema/default_type_error.rb
|
@@ -587,6 +588,12 @@ files:
|
|
587
588
|
- lib/graphql/tracing/scout_tracing.rb
|
588
589
|
- lib/graphql/tracing/skylight_tracing.rb
|
589
590
|
- lib/graphql/type_kinds.rb
|
591
|
+
- lib/graphql/types/boolean.rb
|
592
|
+
- lib/graphql/types/float.rb
|
593
|
+
- lib/graphql/types/id.rb
|
594
|
+
- lib/graphql/types/int.rb
|
595
|
+
- lib/graphql/types/iso_8601_date_time.rb
|
596
|
+
- lib/graphql/types/string.rb
|
590
597
|
- lib/graphql/union_type.rb
|
591
598
|
- lib/graphql/unresolved_type_error.rb
|
592
599
|
- lib/graphql/upgrader/member.rb
|
@@ -1094,6 +1101,7 @@ files:
|
|
1094
1101
|
- spec/graphql/tracing/platform_tracing_spec.rb
|
1095
1102
|
- spec/graphql/tracing/scout_tracing_spec.rb
|
1096
1103
|
- spec/graphql/tracing_spec.rb
|
1104
|
+
- spec/graphql/types/iso_8601_date_time_spec.rb
|
1097
1105
|
- spec/graphql/union_type_spec.rb
|
1098
1106
|
- spec/graphql/upgrader/member_spec.rb
|
1099
1107
|
- spec/graphql/upgrader/schema_spec.rb
|
@@ -1641,6 +1649,7 @@ test_files:
|
|
1641
1649
|
- spec/graphql/tracing/platform_tracing_spec.rb
|
1642
1650
|
- spec/graphql/tracing/scout_tracing_spec.rb
|
1643
1651
|
- spec/graphql/tracing_spec.rb
|
1652
|
+
- spec/graphql/types/iso_8601_date_time_spec.rb
|
1644
1653
|
- spec/graphql/union_type_spec.rb
|
1645
1654
|
- spec/graphql/upgrader/member_spec.rb
|
1646
1655
|
- spec/graphql/upgrader/schema_spec.rb
|