graphql 1.6.6 → 1.6.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/graphql.rb +17 -26
- data/lib/graphql/input_object_type.rb +2 -1
- data/lib/graphql/language/nodes.rb +3 -1
- data/lib/graphql/language/parser.rb +11 -8
- data/lib/graphql/language/parser.y +11 -8
- data/lib/graphql/parse_error.rb +25 -0
- data/lib/graphql/query/arguments_cache.rb +1 -0
- data/lib/graphql/query/executor.rb +1 -0
- data/lib/graphql/relay/relation_connection.rb +1 -2
- data/lib/graphql/schema.rb +11 -5
- data/lib/graphql/schema/build_from_definition.rb +6 -1
- data/lib/graphql/static_validation/rules/fields_will_merge.rb +2 -4
- data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +3 -1
- data/lib/graphql/version.rb +1 -1
- data/spec/graphql/language/nodes_spec.rb +20 -0
- data/spec/graphql/language/parser_spec.rb +28 -0
- data/spec/graphql/query/arguments_spec.rb +50 -0
- data/spec/graphql/schema_spec.rb +7 -0
- data/spec/graphql/static_validation/rules/fields_will_merge_spec.rb +31 -0
- data/spec/graphql/static_validation/rules/variable_usages_are_allowed_spec.rb +17 -1
- data/spec/support/magic_cards/schema.graphql +33 -0
- data/spec/support/parser/filename_example.graphql +5 -0
- data/spec/support/parser/filename_example_error_1.graphql +4 -0
- data/spec/support/parser/filename_example_error_2.graphql +5 -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: cf91ec48fafdc82dbda6deb667fab007e575f2a3
|
4
|
+
data.tar.gz: 32ae2960557c969bee15e14552727d22c782a858
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 60b47807f1b5c868f300f173b7191522b6361d9ebd4cf0ad3fc52842da586f500d223cf1df9f719e1902f191d918fd1f5f6fef14dab7d686a853e1a49b58a09a
|
7
|
+
data.tar.gz: 0c3bf0b9fdfd281603ce140af59e7b75542ad8b992ac247b676876b0ca14586b1ede1462490cc1ed33236ec6e6643b67cdd4e1e724b75321972a73cfcdd1f07e
|
data/lib/graphql.rb
CHANGED
@@ -26,42 +26,32 @@ module GraphQL
|
|
26
26
|
class Error < StandardError
|
27
27
|
end
|
28
28
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
@col = col
|
35
|
-
@query = query
|
36
|
-
end
|
37
|
-
|
38
|
-
def to_h
|
39
|
-
locations = line ? [{ "line" => line, "column" => col }] : []
|
40
|
-
{
|
41
|
-
"message" => message,
|
42
|
-
"locations" => locations,
|
43
|
-
}
|
44
|
-
end
|
29
|
+
# Turn a query string or schema definition into an AST
|
30
|
+
# @param graphql_string [String] a GraphQL query string or schema definition
|
31
|
+
# @return [GraphQL::Language::Nodes::Document]
|
32
|
+
def self.parse(graphql_string)
|
33
|
+
parse_with_racc(graphql_string)
|
45
34
|
end
|
46
35
|
|
47
|
-
#
|
48
|
-
# @param
|
36
|
+
# Read the contents of `filename` and parse them as GraphQL
|
37
|
+
# @param filename [String] Path to a `.graphql` file containing IDL or query
|
49
38
|
# @return [GraphQL::Language::Nodes::Document]
|
50
|
-
def self.
|
51
|
-
|
39
|
+
def self.parse_file(filename)
|
40
|
+
content = File.read(filename)
|
41
|
+
parse_with_racc(content, filename: filename)
|
52
42
|
end
|
53
43
|
|
54
|
-
def self.parse_with_racc(string)
|
55
|
-
GraphQL::Language::Parser.parse(string)
|
44
|
+
def self.parse_with_racc(string, filename: nil)
|
45
|
+
GraphQL::Language::Parser.parse(string, filename: filename)
|
56
46
|
end
|
57
47
|
|
58
48
|
# @return [Array<GraphQL::Language::Token>]
|
59
|
-
def self.scan(
|
60
|
-
scan_with_ragel(
|
49
|
+
def self.scan(graphql_string)
|
50
|
+
scan_with_ragel(graphql_string)
|
61
51
|
end
|
62
52
|
|
63
|
-
def self.scan_with_ragel(
|
64
|
-
GraphQL::Language::Lexer.tokenize(
|
53
|
+
def self.scan_with_ragel(graphql_string)
|
54
|
+
GraphQL::Language::Lexer.tokenize(graphql_string)
|
65
55
|
end
|
66
56
|
end
|
67
57
|
|
@@ -113,3 +103,4 @@ require "graphql/version"
|
|
113
103
|
require "graphql/compatibility"
|
114
104
|
require "graphql/function"
|
115
105
|
require "graphql/filter"
|
106
|
+
require "graphql/parse_error"
|
@@ -89,7 +89,8 @@ module GraphQL
|
|
89
89
|
field_value = value[input_key]
|
90
90
|
|
91
91
|
if value.key?(input_key)
|
92
|
-
|
92
|
+
coerced_value = input_field_defn.type.coerce_input(field_value, ctx)
|
93
|
+
input_values[input_key] = input_field_defn.prepare(coerced_value, ctx)
|
93
94
|
elsif input_field_defn.default_value?
|
94
95
|
input_values[input_key] = input_field_defn.default_value
|
95
96
|
end
|
@@ -9,7 +9,7 @@ module GraphQL
|
|
9
9
|
# - `scalars` returns all scalar (Ruby) values attached to this one. Used for comparing nodes.
|
10
10
|
# - `to_query_string` turns an AST node into a GraphQL string
|
11
11
|
class AbstractNode
|
12
|
-
attr_accessor :line, :col
|
12
|
+
attr_accessor :line, :col, :filename
|
13
13
|
|
14
14
|
# Initialize a node by extracting its position,
|
15
15
|
# then calling the class's `initialize_node` method.
|
@@ -20,6 +20,8 @@ module GraphQL
|
|
20
20
|
@line, @col = position_source.line_and_column
|
21
21
|
end
|
22
22
|
|
23
|
+
@filename = options.delete(:filename)
|
24
|
+
|
23
25
|
initialize_node(options)
|
24
26
|
end
|
25
27
|
|
@@ -14,23 +14,24 @@ module GraphQL
|
|
14
14
|
|
15
15
|
module_eval(<<'...end parser.y/module_eval...', 'parser.y', 356)
|
16
16
|
|
17
|
-
def initialize(query_string)
|
17
|
+
def initialize(query_string, filename:)
|
18
18
|
@query_string = query_string
|
19
|
+
@filename = filename
|
19
20
|
end
|
20
21
|
|
21
22
|
def parse_document
|
22
23
|
@document ||= begin
|
23
24
|
@tokens ||= GraphQL.scan(@query_string)
|
24
25
|
if @tokens.none?
|
25
|
-
make_node(:Document, definitions: [])
|
26
|
+
make_node(:Document, definitions: [], filename: @filename)
|
26
27
|
else
|
27
28
|
do_parse
|
28
29
|
end
|
29
30
|
end
|
30
31
|
end
|
31
32
|
|
32
|
-
def self.parse(query_string)
|
33
|
-
self.new(query_string).parse_document
|
33
|
+
def self.parse(query_string, filename: nil)
|
34
|
+
self.new(query_string, filename: filename).parse_document
|
34
35
|
end
|
35
36
|
|
36
37
|
private
|
@@ -65,17 +66,17 @@ end
|
|
65
66
|
|
66
67
|
def on_error(parser_token_id, lexer_token, vstack)
|
67
68
|
if lexer_token == "$"
|
68
|
-
raise GraphQL::ParseError.new("Unexpected end of document", nil, nil, @query_string)
|
69
|
+
raise GraphQL::ParseError.new("Unexpected end of document", nil, nil, @query_string, filename: @filename)
|
69
70
|
else
|
70
71
|
parser_token_name = token_to_str(parser_token_id)
|
71
72
|
if parser_token_name.nil?
|
72
|
-
raise GraphQL::ParseError.new("Parse Error on unknown token: {token_id: #{parser_token_id}, lexer_token: #{lexer_token}} from #{@query_string}", nil, nil, @query_string)
|
73
|
+
raise GraphQL::ParseError.new("Parse Error on unknown token: {token_id: #{parser_token_id}, lexer_token: #{lexer_token}} from #{@query_string}", nil, nil, @query_string, filename: @filename)
|
73
74
|
else
|
74
75
|
line, col = lexer_token.line_and_column
|
75
76
|
if lexer_token.name == :BAD_UNICODE_ESCAPE
|
76
|
-
raise GraphQL::ParseError.new("Parse error on bad Unicode escape sequence: #{lexer_token.to_s.inspect} (#{parser_token_name}) at [#{line}, #{col}]", line, col, @query_string)
|
77
|
+
raise GraphQL::ParseError.new("Parse error on bad Unicode escape sequence: #{lexer_token.to_s.inspect} (#{parser_token_name}) at [#{line}, #{col}]", line, col, @query_string, filename: @filename)
|
77
78
|
else
|
78
|
-
raise GraphQL::ParseError.new("Parse error on #{lexer_token.to_s.inspect} (#{parser_token_name}) at [#{line}, #{col}]", line, col, @query_string)
|
79
|
+
raise GraphQL::ParseError.new("Parse error on #{lexer_token.to_s.inspect} (#{parser_token_name}) at [#{line}, #{col}]", line, col, @query_string, filename: @filename)
|
79
80
|
end
|
80
81
|
end
|
81
82
|
end
|
@@ -88,6 +89,8 @@ def make_node(node_name, assigns)
|
|
88
89
|
end
|
89
90
|
end
|
90
91
|
|
92
|
+
assigns[:filename] = @filename
|
93
|
+
|
91
94
|
GraphQL::Language::Nodes.const_get(node_name).new(assigns)
|
92
95
|
end
|
93
96
|
...end parser.y/module_eval...
|
@@ -354,23 +354,24 @@ end
|
|
354
354
|
|
355
355
|
---- inner ----
|
356
356
|
|
357
|
-
def initialize(query_string)
|
357
|
+
def initialize(query_string, filename:)
|
358
358
|
@query_string = query_string
|
359
|
+
@filename = filename
|
359
360
|
end
|
360
361
|
|
361
362
|
def parse_document
|
362
363
|
@document ||= begin
|
363
364
|
@tokens ||= GraphQL.scan(@query_string)
|
364
365
|
if @tokens.none?
|
365
|
-
make_node(:Document, definitions: [])
|
366
|
+
make_node(:Document, definitions: [], filename: @filename)
|
366
367
|
else
|
367
368
|
do_parse
|
368
369
|
end
|
369
370
|
end
|
370
371
|
end
|
371
372
|
|
372
|
-
def self.parse(query_string)
|
373
|
-
self.new(query_string).parse_document
|
373
|
+
def self.parse(query_string, filename: nil)
|
374
|
+
self.new(query_string, filename: filename).parse_document
|
374
375
|
end
|
375
376
|
|
376
377
|
private
|
@@ -405,17 +406,17 @@ end
|
|
405
406
|
|
406
407
|
def on_error(parser_token_id, lexer_token, vstack)
|
407
408
|
if lexer_token == "$"
|
408
|
-
raise GraphQL::ParseError.new("Unexpected end of document", nil, nil, @query_string)
|
409
|
+
raise GraphQL::ParseError.new("Unexpected end of document", nil, nil, @query_string, filename: @filename)
|
409
410
|
else
|
410
411
|
parser_token_name = token_to_str(parser_token_id)
|
411
412
|
if parser_token_name.nil?
|
412
|
-
raise GraphQL::ParseError.new("Parse Error on unknown token: {token_id: #{parser_token_id}, lexer_token: #{lexer_token}} from #{@query_string}", nil, nil, @query_string)
|
413
|
+
raise GraphQL::ParseError.new("Parse Error on unknown token: {token_id: #{parser_token_id}, lexer_token: #{lexer_token}} from #{@query_string}", nil, nil, @query_string, filename: @filename)
|
413
414
|
else
|
414
415
|
line, col = lexer_token.line_and_column
|
415
416
|
if lexer_token.name == :BAD_UNICODE_ESCAPE
|
416
|
-
raise GraphQL::ParseError.new("Parse error on bad Unicode escape sequence: #{lexer_token.to_s.inspect} (#{parser_token_name}) at [#{line}, #{col}]", line, col, @query_string)
|
417
|
+
raise GraphQL::ParseError.new("Parse error on bad Unicode escape sequence: #{lexer_token.to_s.inspect} (#{parser_token_name}) at [#{line}, #{col}]", line, col, @query_string, filename: @filename)
|
417
418
|
else
|
418
|
-
raise GraphQL::ParseError.new("Parse error on #{lexer_token.to_s.inspect} (#{parser_token_name}) at [#{line}, #{col}]", line, col, @query_string)
|
419
|
+
raise GraphQL::ParseError.new("Parse error on #{lexer_token.to_s.inspect} (#{parser_token_name}) at [#{line}, #{col}]", line, col, @query_string, filename: @filename)
|
419
420
|
end
|
420
421
|
end
|
421
422
|
end
|
@@ -428,5 +429,7 @@ def make_node(node_name, assigns)
|
|
428
429
|
end
|
429
430
|
end
|
430
431
|
|
432
|
+
assigns[:filename] = @filename
|
433
|
+
|
431
434
|
GraphQL::Language::Nodes.const_get(node_name).new(assigns)
|
432
435
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# test_via: language/parser.rb
|
3
|
+
module GraphQL
|
4
|
+
class ParseError < GraphQL::Error
|
5
|
+
attr_reader :line, :col, :query
|
6
|
+
def initialize(message, line, col, query, filename: nil)
|
7
|
+
if filename
|
8
|
+
message += " (#{filename})"
|
9
|
+
end
|
10
|
+
|
11
|
+
super(message)
|
12
|
+
@line = line
|
13
|
+
@col = col
|
14
|
+
@query = query
|
15
|
+
end
|
16
|
+
|
17
|
+
def to_h
|
18
|
+
locations = line ? [{ "line" => line, "column" => col }] : []
|
19
|
+
{
|
20
|
+
"message" => message,
|
21
|
+
"locations" => locations,
|
22
|
+
}
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -100,8 +100,7 @@ module GraphQL
|
|
100
100
|
|
101
101
|
# If a relation contains a `.group` clause, a `.count` will return a Hash.
|
102
102
|
def relation_count(relation)
|
103
|
-
count_or_hash =
|
104
|
-
when ActiveRecord::Relation
|
103
|
+
count_or_hash = if(defined?(ActiveRecord::Relation) && relation.is_a?(ActiveRecord::Relation))
|
105
104
|
relation.count(:all)
|
106
105
|
else # eg, Sequel::Dataset, don't mess up others
|
107
106
|
relation.count
|
data/lib/graphql/schema.rb
CHANGED
@@ -356,7 +356,7 @@ module GraphQL
|
|
356
356
|
type_proc.call(object, ctx)
|
357
357
|
else
|
358
358
|
if @resolve_type_proc.nil?
|
359
|
-
raise(NotImplementedError, "Can't determine GraphQL type for: #{object.inspect}, define `resolve_type (obj, ctx) -> { ... }` inside `Schema.define`.")
|
359
|
+
raise(NotImplementedError, "Can't determine GraphQL type for: #{object.inspect}, define `resolve_type (type, obj, ctx) -> { ... }` inside `Schema.define`.")
|
360
360
|
end
|
361
361
|
@resolve_type_proc.call(type, object, ctx)
|
362
362
|
end
|
@@ -462,13 +462,19 @@ module GraphQL
|
|
462
462
|
GraphQL::Schema::Loader.load(introspection_result)
|
463
463
|
end
|
464
464
|
|
465
|
-
# Create schema from an IDL schema.
|
466
|
-
# @param
|
465
|
+
# Create schema from an IDL schema or file containing an IDL definition.
|
466
|
+
# @param definition_or_path [String] A schema definition string, or a path to a file containing the definition
|
467
467
|
# @param default_resolve [<#call(type, field, obj, args, ctx)>] A callable for handling field resolution
|
468
468
|
# @param parser [Object] An object for handling definition string parsing (must respond to `parse`)
|
469
469
|
# @return [GraphQL::Schema] the schema described by `document`
|
470
|
-
def self.from_definition(
|
471
|
-
|
470
|
+
def self.from_definition(definition_or_path, default_resolve: BuildFromDefinition::DefaultResolve, parser: BuildFromDefinition::DefaultParser)
|
471
|
+
# If the file ends in `.graphql`, treat it like a filepath
|
472
|
+
definition = if definition_or_path.end_with?(".graphql")
|
473
|
+
File.read(definition_or_path)
|
474
|
+
else
|
475
|
+
definition_or_path
|
476
|
+
end
|
477
|
+
GraphQL::Schema::BuildFromDefinition.from_definition(definition, default_resolve: default_resolve, parser: parser)
|
472
478
|
end
|
473
479
|
|
474
480
|
# Error that is raised when [#Schema#from_definition] is passed an invalid schema definition string.
|
@@ -286,7 +286,12 @@ module GraphQL
|
|
286
286
|
|
287
287
|
def resolve_type(types, ast_node)
|
288
288
|
type = GraphQL::Schema::TypeExpression.build_type(types, ast_node)
|
289
|
-
|
289
|
+
if type.nil?
|
290
|
+
while ast_node.respond_to?(:of_type)
|
291
|
+
ast_node = ast_node.of_type
|
292
|
+
end
|
293
|
+
raise InvalidDocumentError.new("Type \"#{ast_node.name}\" not found in document.")
|
294
|
+
end
|
290
295
|
type
|
291
296
|
end
|
292
297
|
end
|
@@ -19,10 +19,8 @@ module GraphQL
|
|
19
19
|
n.arguments.reduce({}) do |memo, a|
|
20
20
|
arg_value = a.value
|
21
21
|
memo[a.name] = case arg_value
|
22
|
-
when GraphQL::Language::Nodes::
|
23
|
-
|
24
|
-
when GraphQL::Language::Nodes::Enum
|
25
|
-
"#{arg_value.name}"
|
22
|
+
when GraphQL::Language::Nodes::AbstractNode
|
23
|
+
arg_value.to_query_string
|
26
24
|
else
|
27
25
|
GraphQL::Language.serialize(arg_value)
|
28
26
|
end
|
@@ -83,7 +83,9 @@ module GraphQL
|
|
83
83
|
new_var_type = var_type
|
84
84
|
|
85
85
|
depth_of_array(arg_node_value).times do
|
86
|
-
|
86
|
+
# Since the array _is_ present, treat it like a non-null type
|
87
|
+
# (It satisfies a non-null requirement AND a nullable requirement)
|
88
|
+
new_var_type = new_var_type.to_list_type.to_non_null_type
|
87
89
|
end
|
88
90
|
|
89
91
|
new_var_type
|
data/lib/graphql/version.rb
CHANGED
@@ -13,4 +13,24 @@ describe GraphQL::Language::Nodes::AbstractNode do
|
|
13
13
|
subclassed_directive.child_attributes
|
14
14
|
end
|
15
15
|
end
|
16
|
+
|
17
|
+
describe "#filename" do
|
18
|
+
it "is set after .parse_file" do
|
19
|
+
filename = "spec/support/parser/filename_example.graphql"
|
20
|
+
doc = GraphQL.parse_file(filename)
|
21
|
+
op = doc.definitions.first
|
22
|
+
field = op.selections.first
|
23
|
+
arg = field.arguments.first
|
24
|
+
|
25
|
+
assert_equal filename, doc.filename
|
26
|
+
assert_equal filename, op.filename
|
27
|
+
assert_equal filename, field.filename
|
28
|
+
assert_equal filename, arg.filename
|
29
|
+
end
|
30
|
+
|
31
|
+
it "is null when parse from string" do
|
32
|
+
doc = GraphQL.parse("{ thing }")
|
33
|
+
assert_nil doc.filename
|
34
|
+
end
|
35
|
+
end
|
16
36
|
end
|
@@ -43,4 +43,32 @@ describe GraphQL::Language::Parser do
|
|
43
43
|
document = subject.parse(schema_string)
|
44
44
|
assert_equal schema_string, document.to_query_string
|
45
45
|
end
|
46
|
+
|
47
|
+
describe ".parse_file" do
|
48
|
+
it "assigns filename to all nodes" do
|
49
|
+
example_filename = "spec/support/parser/filename_example.graphql"
|
50
|
+
doc = GraphQL.parse_file(example_filename)
|
51
|
+
assert_equal example_filename, doc.filename
|
52
|
+
field = doc.definitions[0].selections[0].selections[0]
|
53
|
+
assert_equal example_filename, field.filename
|
54
|
+
end
|
55
|
+
|
56
|
+
it "raises errors with filename" do
|
57
|
+
error_filename = "spec/support/parser/filename_example_error_1.graphql"
|
58
|
+
err = assert_raises(GraphQL::ParseError) {
|
59
|
+
GraphQL.parse_file(error_filename)
|
60
|
+
}
|
61
|
+
|
62
|
+
assert_includes err.message, error_filename
|
63
|
+
|
64
|
+
error_filename_2 = "spec/support/parser/filename_example_error_2.graphql"
|
65
|
+
err_2 = assert_raises(GraphQL::ParseError) {
|
66
|
+
GraphQL.parse_file(error_filename_2)
|
67
|
+
}
|
68
|
+
|
69
|
+
assert_includes err_2.message, error_filename_2
|
70
|
+
assert_includes err_2.message, "3, 11"
|
71
|
+
|
72
|
+
end
|
73
|
+
end
|
46
74
|
end
|
@@ -241,4 +241,54 @@ describe GraphQL::Query::Arguments do
|
|
241
241
|
assert_equal({"d" => nil, "b" => 2}, test_defaults.to_h)
|
242
242
|
end
|
243
243
|
end
|
244
|
+
|
245
|
+
describe "prepare" do
|
246
|
+
let(:arg_values) { [] }
|
247
|
+
let(:schema) {
|
248
|
+
arg_values_array = arg_values
|
249
|
+
test_input_1 = GraphQL::InputObjectType.define do
|
250
|
+
name "TestInput1"
|
251
|
+
argument :a, types.Int, prepare: ->(value, ctx) do
|
252
|
+
value * 10
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
test_input_2 = GraphQL::InputObjectType.define do
|
257
|
+
name "TestInput2"
|
258
|
+
argument :b, !test_input_1, as: :inputObject
|
259
|
+
end
|
260
|
+
|
261
|
+
query = GraphQL::ObjectType.define do
|
262
|
+
name "Query"
|
263
|
+
field :prepareTest, types.Int do
|
264
|
+
argument :a, test_input_2
|
265
|
+
resolve ->(obj, args, ctx) {
|
266
|
+
arg_values_array << args
|
267
|
+
1
|
268
|
+
}
|
269
|
+
end
|
270
|
+
end
|
271
|
+
|
272
|
+
GraphQL::Schema.define(query: query)
|
273
|
+
}
|
274
|
+
|
275
|
+
it "returns prepared argument value for nested input type" do
|
276
|
+
schema.execute("query prepareTest($arg: TestInput2 = {b: {a: 2}}){ prepareTest(a: $arg) }")
|
277
|
+
|
278
|
+
args = arg_values[0].values[0]
|
279
|
+
assert_equal 2 * 10, args['inputObject']['a']
|
280
|
+
end
|
281
|
+
|
282
|
+
it "returns prepared argument value for nested input type" do
|
283
|
+
query_str = "
|
284
|
+
query($arg: TestInput2){
|
285
|
+
prepareTest(a: $arg)
|
286
|
+
}"
|
287
|
+
|
288
|
+
schema.execute(query_str, variables: { "arg" => { "b" => { "a" => 3 } } } )
|
289
|
+
|
290
|
+
args = arg_values[0].values[0]
|
291
|
+
assert_equal 30, args['inputObject']['a']
|
292
|
+
end
|
293
|
+
end
|
244
294
|
end
|
data/spec/graphql/schema_spec.rb
CHANGED
@@ -168,6 +168,13 @@ type Query {
|
|
168
168
|
built_schema = GraphQL::Schema.from_definition(schema)
|
169
169
|
assert_equal schema.chop, GraphQL::Schema::Printer.print_schema(built_schema)
|
170
170
|
end
|
171
|
+
|
172
|
+
it "builds from a file" do
|
173
|
+
schema = GraphQL::Schema.from_definition("spec/support/magic_cards/schema.graphql")
|
174
|
+
assert_instance_of GraphQL::Schema, schema
|
175
|
+
expected_types = ["Card", "Color", "Expansion", "Printing"]
|
176
|
+
assert_equal expected_types, (expected_types & schema.types.keys)
|
177
|
+
end
|
171
178
|
end
|
172
179
|
|
173
180
|
describe ".from_introspection" do
|
@@ -13,6 +13,10 @@ describe GraphQL::StaticValidation::FieldsWillMerge do
|
|
13
13
|
toy: Toy
|
14
14
|
}
|
15
15
|
|
16
|
+
type Mutation {
|
17
|
+
registerPet(params: PetParams): Pet
|
18
|
+
}
|
19
|
+
|
16
20
|
enum PetCommand {
|
17
21
|
SIT
|
18
22
|
HEEL
|
@@ -25,6 +29,16 @@ describe GraphQL::StaticValidation::FieldsWillMerge do
|
|
25
29
|
LARGE
|
26
30
|
}
|
27
31
|
|
32
|
+
enum PetSpecies {
|
33
|
+
DOG
|
34
|
+
CAT
|
35
|
+
}
|
36
|
+
|
37
|
+
input PetParams {
|
38
|
+
name: String!
|
39
|
+
species: PetSpecies!
|
40
|
+
}
|
41
|
+
|
28
42
|
interface Pet {
|
29
43
|
name(surname: Boolean = false): String!
|
30
44
|
nickname: String
|
@@ -85,6 +99,23 @@ describe GraphQL::StaticValidation::FieldsWillMerge do
|
|
85
99
|
end
|
86
100
|
end
|
87
101
|
|
102
|
+
describe "identical fields with identical input objects" do
|
103
|
+
let(:query_string) {%|
|
104
|
+
mutation {
|
105
|
+
registerPet(params: { name: "Fido", species: DOG }) {
|
106
|
+
name
|
107
|
+
}
|
108
|
+
registerPet(params: { name: "Fido", species: DOG }) {
|
109
|
+
__typename
|
110
|
+
}
|
111
|
+
}
|
112
|
+
|}
|
113
|
+
|
114
|
+
it "passes rule" do
|
115
|
+
assert_equal [], errors
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
88
119
|
describe "identical fields with identical args" do
|
89
120
|
let(:query_string) {%|
|
90
121
|
{
|
@@ -92,6 +92,7 @@ describe GraphQL::StaticValidation::VariableUsagesAreAllowed do
|
|
92
92
|
|
93
93
|
type Query {
|
94
94
|
imageUrl(height: Int, width: Int, size: ImageSize, sizes: [ImageSize!]): String!
|
95
|
+
sizedImageUrl(sizes: [ImageSize!]!): String!
|
95
96
|
}
|
96
97
|
GRAPHQL
|
97
98
|
}
|
@@ -124,7 +125,7 @@ describe GraphQL::StaticValidation::VariableUsagesAreAllowed do
|
|
124
125
|
|
125
126
|
it "finds invalid inner definitions" do
|
126
127
|
assert_equal 1, errors.size
|
127
|
-
expected_message = "List dimension mismatch on variable $sizes and argument sizes ([[ImageSize]] / [ImageSize!])"
|
128
|
+
expected_message = "List dimension mismatch on variable $sizes and argument sizes ([[ImageSize]]! / [ImageSize!])"
|
128
129
|
assert_equal [expected_message], errors.map { |e| e["message"] }
|
129
130
|
end
|
130
131
|
end
|
@@ -212,5 +213,20 @@ describe GraphQL::StaticValidation::VariableUsagesAreAllowed do
|
|
212
213
|
assert_equal 0, errors.size
|
213
214
|
end
|
214
215
|
end
|
216
|
+
|
217
|
+
describe "variable in non-null list" do
|
218
|
+
let(:query_string) {
|
219
|
+
<<-GRAPHQL
|
220
|
+
# This should work
|
221
|
+
query ($size: ImageSize!) {
|
222
|
+
sizedImageUrl(sizes: [$size])
|
223
|
+
}
|
224
|
+
GRAPHQL
|
225
|
+
}
|
226
|
+
|
227
|
+
it "is allowed" do
|
228
|
+
assert_equal [], errors
|
229
|
+
end
|
230
|
+
end
|
215
231
|
end
|
216
232
|
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
type Card {
|
2
|
+
name: String!
|
3
|
+
printings: [Printing!]!
|
4
|
+
expansions: [Expansion!]!
|
5
|
+
colors: [Color!]!
|
6
|
+
convertedManaCost: Int!
|
7
|
+
}
|
8
|
+
|
9
|
+
type Expansion {
|
10
|
+
name: String!
|
11
|
+
symbol: String!
|
12
|
+
printings: [Printing!]!
|
13
|
+
cards: [Card!]!
|
14
|
+
}
|
15
|
+
|
16
|
+
type Printing {
|
17
|
+
card: Card!
|
18
|
+
expansion: Expansion!
|
19
|
+
}
|
20
|
+
|
21
|
+
enum Color {
|
22
|
+
RED
|
23
|
+
GREEN
|
24
|
+
BLACK
|
25
|
+
BLUE
|
26
|
+
WHITE
|
27
|
+
COLORLESS
|
28
|
+
}
|
29
|
+
|
30
|
+
type Query {
|
31
|
+
card(name: String!): Card
|
32
|
+
expansion(symbol: String!): Expansion
|
33
|
+
}
|
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.6.
|
4
|
+
version: 1.6.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Robert Mosolgo
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-08-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: benchmark-ips
|
@@ -423,6 +423,7 @@ files:
|
|
423
423
|
- lib/graphql/list_type.rb
|
424
424
|
- lib/graphql/non_null_type.rb
|
425
425
|
- lib/graphql/object_type.rb
|
426
|
+
- lib/graphql/parse_error.rb
|
426
427
|
- lib/graphql/query.rb
|
427
428
|
- lib/graphql/query/arguments.rb
|
428
429
|
- lib/graphql/query/arguments_cache.rb
|
@@ -643,7 +644,11 @@ files:
|
|
643
644
|
- spec/support/dummy/data.rb
|
644
645
|
- spec/support/dummy/schema.rb
|
645
646
|
- spec/support/lazy_helpers.rb
|
647
|
+
- spec/support/magic_cards/schema.graphql
|
646
648
|
- spec/support/minimum_input_object.rb
|
649
|
+
- spec/support/parser/filename_example.graphql
|
650
|
+
- spec/support/parser/filename_example_error_1.graphql
|
651
|
+
- spec/support/parser/filename_example_error_2.graphql
|
647
652
|
- spec/support/star_wars/data.rb
|
648
653
|
- spec/support/star_wars/schema.rb
|
649
654
|
- spec/support/static_validation_helpers.rb
|
@@ -793,7 +798,11 @@ test_files:
|
|
793
798
|
- spec/support/dummy/data.rb
|
794
799
|
- spec/support/dummy/schema.rb
|
795
800
|
- spec/support/lazy_helpers.rb
|
801
|
+
- spec/support/magic_cards/schema.graphql
|
796
802
|
- spec/support/minimum_input_object.rb
|
803
|
+
- spec/support/parser/filename_example.graphql
|
804
|
+
- spec/support/parser/filename_example_error_1.graphql
|
805
|
+
- spec/support/parser/filename_example_error_2.graphql
|
797
806
|
- spec/support/star_wars/data.rb
|
798
807
|
- spec/support/star_wars/schema.rb
|
799
808
|
- spec/support/static_validation_helpers.rb
|