graphql 0.19.3 → 0.19.4
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/analysis/max_query_complexity.rb +1 -1
- data/lib/graphql/analysis/max_query_depth.rb +1 -1
- data/lib/graphql/boolean_type.rb +2 -2
- data/lib/graphql/define/instance_definable.rb +2 -2
- data/lib/graphql/enum_type.rb +3 -3
- data/lib/graphql/field.rb +6 -6
- data/lib/graphql/float_type.rb +2 -2
- data/lib/graphql/id_type.rb +2 -2
- data/lib/graphql/input_object_type.rb +1 -1
- data/lib/graphql/int_type.rb +2 -2
- data/lib/graphql/internal_representation/rewrite.rb +12 -12
- data/lib/graphql/introspection/arguments_field.rb +1 -1
- data/lib/graphql/introspection/enum_value_type.rb +1 -1
- data/lib/graphql/introspection/enum_values_field.rb +1 -1
- data/lib/graphql/introspection/field_type.rb +1 -1
- data/lib/graphql/introspection/fields_field.rb +1 -1
- data/lib/graphql/introspection/input_fields_field.rb +1 -1
- data/lib/graphql/introspection/input_value_type.rb +2 -2
- data/lib/graphql/introspection/interfaces_field.rb +1 -1
- data/lib/graphql/introspection/of_type_field.rb +1 -1
- data/lib/graphql/introspection/possible_types_field.rb +1 -1
- data/lib/graphql/introspection/schema_field.rb +1 -1
- data/lib/graphql/introspection/schema_type.rb +5 -5
- data/lib/graphql/introspection/type_by_name_field.rb +1 -1
- data/lib/graphql/introspection/type_type.rb +6 -6
- data/lib/graphql/introspection/typename_field.rb +1 -1
- data/lib/graphql/language.rb +1 -0
- data/lib/graphql/language/comments.rb +44 -0
- data/lib/graphql/language/definition_slice.rb +1 -1
- data/lib/graphql/language/generation.rb +35 -12
- data/lib/graphql/language/lexer.rb +29 -10
- data/lib/graphql/language/lexer.rl +25 -6
- data/lib/graphql/language/nodes.rb +30 -23
- data/lib/graphql/language/parser.rb +33 -14
- data/lib/graphql/language/parser.y +33 -14
- data/lib/graphql/language/parser_tests.rb +86 -2
- data/lib/graphql/language/token.rb +3 -2
- data/lib/graphql/language/visitor.rb +3 -3
- data/lib/graphql/object_type.rb +1 -1
- data/lib/graphql/query/arguments.rb +23 -2
- data/lib/graphql/query/serial_execution/field_resolution.rb +31 -14
- data/lib/graphql/relay/base_connection.rb +1 -3
- data/lib/graphql/relay/connection_type.rb +1 -1
- data/lib/graphql/relay/mutation.rb +1 -1
- data/lib/graphql/relay/relation_connection.rb +7 -3
- data/lib/graphql/scalar_type.rb +1 -1
- data/lib/graphql/schema.rb +19 -8
- data/lib/graphql/schema/loader.rb +2 -2
- data/lib/graphql/schema/printer.rb +63 -8
- data/lib/graphql/schema/timeout_middleware.rb +11 -11
- data/lib/graphql/schema/validation.rb +12 -12
- data/lib/graphql/static_validation/arguments_validator.rb +1 -1
- data/lib/graphql/static_validation/rules/directives_are_defined.rb +1 -1
- data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +1 -1
- data/lib/graphql/static_validation/rules/fields_are_defined_on_type.rb +1 -1
- data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +1 -1
- data/lib/graphql/static_validation/rules/fields_will_merge.rb +3 -2
- data/lib/graphql/static_validation/rules/fragment_spreads_are_possible.rb +3 -3
- data/lib/graphql/static_validation/rules/fragment_types_exist.rb +1 -1
- data/lib/graphql/static_validation/rules/fragments_are_finite.rb +9 -4
- data/lib/graphql/static_validation/rules/fragments_are_named.rb +1 -1
- data/lib/graphql/static_validation/rules/fragments_are_on_composite_types.rb +1 -1
- data/lib/graphql/static_validation/rules/fragments_are_used.rb +3 -3
- data/lib/graphql/static_validation/rules/mutation_root_exists.rb +1 -1
- data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +2 -2
- data/lib/graphql/static_validation/rules/subscription_root_exists.rb +1 -1
- data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +1 -1
- data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +2 -2
- data/lib/graphql/static_validation/rules/variables_are_input_types.rb +1 -1
- data/lib/graphql/static_validation/rules/variables_are_used_and_defined.rb +6 -6
- data/lib/graphql/static_validation/type_stack.rb +2 -2
- data/lib/graphql/string_type.rb +2 -2
- data/lib/graphql/version.rb +1 -1
- data/readme.md +1 -1
- data/spec/graphql/analysis/analyze_query_spec.rb +3 -3
- data/spec/graphql/analysis/query_complexity_spec.rb +7 -7
- data/spec/graphql/introspection/directive_type_spec.rb +2 -2
- data/spec/graphql/introspection/introspection_query_spec.rb +26 -26
- data/spec/graphql/language/generation_spec.rb +137 -53
- data/spec/graphql/language/lexer_spec.rb +22 -0
- data/spec/graphql/language/visitor_spec.rb +6 -6
- data/spec/graphql/query/arguments_spec.rb +45 -1
- data/spec/graphql/query/context_spec.rb +4 -4
- data/spec/graphql/query/executor_spec.rb +1 -1
- data/spec/graphql/query/serial_execution/value_resolution_spec.rb +1 -1
- data/spec/graphql/relay/mutation_spec.rb +2 -2
- data/spec/graphql/relay/node_spec.rb +2 -2
- data/spec/graphql/relay/relation_connection_spec.rb +16 -0
- data/spec/graphql/schema/loader_spec.rb +2 -2
- data/spec/graphql/schema/middleware_chain_spec.rb +6 -6
- data/spec/graphql/schema/printer_spec.rb +268 -18
- data/spec/graphql/schema/rescue_middleware_spec.rb +1 -1
- data/spec/graphql/schema/timeout_middleware_spec.rb +2 -2
- data/spec/graphql/schema_spec.rb +2 -2
- data/spec/graphql/static_validation/rules/fragments_are_finite_spec.rb +13 -0
- data/spec/graphql/static_validation/rules/fragments_are_used_spec.rb +1 -1
- data/spec/graphql/static_validation/type_stack_spec.rb +1 -1
- data/spec/support/dairy_app.rb +25 -25
- data/spec/support/dairy_data.rb +2 -0
- data/spec/support/star_wars_data.rb +2 -1
- data/spec/support/star_wars_schema.rb +18 -18
- metadata +19 -2
@@ -44,6 +44,25 @@ def next_token
|
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
47
|
+
def get_description(token)
|
48
|
+
comments = []
|
49
|
+
|
50
|
+
loop do
|
51
|
+
prev_token = token
|
52
|
+
token = token.prev_token
|
53
|
+
|
54
|
+
break if token.nil?
|
55
|
+
break if token.name != :COMMENT
|
56
|
+
break if prev_token.line != token.line + 1
|
57
|
+
|
58
|
+
comments.unshift(token.to_s.sub(/^#\s*/, ""))
|
59
|
+
end
|
60
|
+
|
61
|
+
return nil if comments.empty?
|
62
|
+
|
63
|
+
comments.join("\n")
|
64
|
+
end
|
65
|
+
|
47
66
|
def on_error(parser_token_id, lexer_token, vstack)
|
48
67
|
if lexer_token == "$"
|
49
68
|
raise GraphQL::ParseError.new("Unexpected end of document", nil, nil, @query_string)
|
@@ -1046,21 +1065,21 @@ module_eval(<<'.,.,', 'parser.y', 103)
|
|
1046
1065
|
|
1047
1066
|
module_eval(<<'.,.,', 'parser.y', 146)
|
1048
1067
|
def _reduce_58(val, _values, result)
|
1049
|
-
return [val[0]
|
1068
|
+
return [make_node(:TypeName, name: val[0])]
|
1050
1069
|
result
|
1051
1070
|
end
|
1052
1071
|
.,.,
|
1053
1072
|
|
1054
1073
|
module_eval(<<'.,.,', 'parser.y', 147)
|
1055
1074
|
def _reduce_59(val, _values, result)
|
1056
|
-
val[0] << val[1]
|
1075
|
+
val[0] << make_node(:TypeName, name: val[1])
|
1057
1076
|
result
|
1058
1077
|
end
|
1059
1078
|
.,.,
|
1060
1079
|
|
1061
1080
|
module_eval(<<'.,.,', 'parser.y', 150)
|
1062
1081
|
def _reduce_60(val, _values, result)
|
1063
|
-
return make_node(:EnumValueDefinition, name: val[0], directives: val[1])
|
1082
|
+
return make_node(:EnumValueDefinition, name: val[0], directives: val[1], description: get_description(val[0]))
|
1064
1083
|
result
|
1065
1084
|
end
|
1066
1085
|
.,.,
|
@@ -1371,14 +1390,14 @@ module_eval(<<'.,.,', 'parser.y', 262)
|
|
1371
1390
|
|
1372
1391
|
module_eval(<<'.,.,', 'parser.y', 272)
|
1373
1392
|
def _reduce_113(val, _values, result)
|
1374
|
-
return make_node(:ScalarTypeDefinition, name: val[1], directives: val[2])
|
1393
|
+
return make_node(:ScalarTypeDefinition, name: val[1], directives: val[2], description: get_description(val[0]))
|
1375
1394
|
result
|
1376
1395
|
end
|
1377
1396
|
.,.,
|
1378
1397
|
|
1379
1398
|
module_eval(<<'.,.,', 'parser.y', 276)
|
1380
1399
|
def _reduce_114(val, _values, result)
|
1381
|
-
return make_node(:ObjectTypeDefinition, name: val[1], interfaces: val[2], directives: val[3], fields: val[5])
|
1400
|
+
return make_node(:ObjectTypeDefinition, name: val[1], interfaces: val[2], directives: val[3], fields: val[5], description: get_description(val[0]))
|
1382
1401
|
|
1383
1402
|
result
|
1384
1403
|
end
|
@@ -1400,7 +1419,7 @@ module_eval(<<'.,.,', 'parser.y', 281)
|
|
1400
1419
|
|
1401
1420
|
module_eval(<<'.,.,', 'parser.y', 285)
|
1402
1421
|
def _reduce_117(val, _values, result)
|
1403
|
-
return make_node(:InputValueDefinition, name: val[0], type: val[2], default_value: val[3], directives: val[4])
|
1422
|
+
return make_node(:InputValueDefinition, name: val[0], type: val[2], default_value: val[3], directives: val[4], description: get_description(val[0]))
|
1404
1423
|
|
1405
1424
|
result
|
1406
1425
|
end
|
@@ -1436,7 +1455,7 @@ module_eval(<<'.,.,', 'parser.y', 294)
|
|
1436
1455
|
|
1437
1456
|
module_eval(<<'.,.,', 'parser.y', 298)
|
1438
1457
|
def _reduce_122(val, _values, result)
|
1439
|
-
return make_node(:FieldDefinition, name: val[0], arguments: val[1], type: val[3], directives: val[4])
|
1458
|
+
return make_node(:FieldDefinition, name: val[0], arguments: val[1], type: val[3], directives: val[4], description: get_description(val[0]))
|
1440
1459
|
|
1441
1460
|
result
|
1442
1461
|
end
|
@@ -1458,7 +1477,7 @@ module_eval(<<'.,.,', 'parser.y', 303)
|
|
1458
1477
|
|
1459
1478
|
module_eval(<<'.,.,', 'parser.y', 307)
|
1460
1479
|
def _reduce_125(val, _values, result)
|
1461
|
-
return make_node(:InterfaceTypeDefinition, name: val[1], directives: val[2], fields: val[4])
|
1480
|
+
return make_node(:InterfaceTypeDefinition, name: val[1], directives: val[2], fields: val[4], description: get_description(val[0]))
|
1462
1481
|
|
1463
1482
|
result
|
1464
1483
|
end
|
@@ -1466,21 +1485,21 @@ module_eval(<<'.,.,', 'parser.y', 307)
|
|
1466
1485
|
|
1467
1486
|
module_eval(<<'.,.,', 'parser.y', 311)
|
1468
1487
|
def _reduce_126(val, _values, result)
|
1469
|
-
return [val[0]
|
1488
|
+
return [make_node(:TypeName, name: val[0])]
|
1470
1489
|
result
|
1471
1490
|
end
|
1472
1491
|
.,.,
|
1473
1492
|
|
1474
1493
|
module_eval(<<'.,.,', 'parser.y', 312)
|
1475
1494
|
def _reduce_127(val, _values, result)
|
1476
|
-
val[0] << val[2]
|
1495
|
+
val[0] << make_node(:TypeName, name: val[2])
|
1477
1496
|
result
|
1478
1497
|
end
|
1479
1498
|
.,.,
|
1480
1499
|
|
1481
1500
|
module_eval(<<'.,.,', 'parser.y', 316)
|
1482
1501
|
def _reduce_128(val, _values, result)
|
1483
|
-
return make_node(:UnionTypeDefinition, name: val[1], directives: val[2], types: val[4])
|
1502
|
+
return make_node(:UnionTypeDefinition, name: val[1], directives: val[2], types: val[4], description: get_description(val[0]))
|
1484
1503
|
|
1485
1504
|
result
|
1486
1505
|
end
|
@@ -1488,7 +1507,7 @@ module_eval(<<'.,.,', 'parser.y', 316)
|
|
1488
1507
|
|
1489
1508
|
module_eval(<<'.,.,', 'parser.y', 321)
|
1490
1509
|
def _reduce_129(val, _values, result)
|
1491
|
-
return make_node(:EnumTypeDefinition, name: val[1], directives: val[2], values: val[4])
|
1510
|
+
return make_node(:EnumTypeDefinition, name: val[1], directives: val[2], values: val[4], description: get_description(val[0]))
|
1492
1511
|
|
1493
1512
|
result
|
1494
1513
|
end
|
@@ -1496,7 +1515,7 @@ module_eval(<<'.,.,', 'parser.y', 321)
|
|
1496
1515
|
|
1497
1516
|
module_eval(<<'.,.,', 'parser.y', 326)
|
1498
1517
|
def _reduce_130(val, _values, result)
|
1499
|
-
return make_node(:InputObjectTypeDefinition, name: val[1], directives: val[2], fields: val[4])
|
1518
|
+
return make_node(:InputObjectTypeDefinition, name: val[1], directives: val[2], fields: val[4], description: get_description(val[0]))
|
1500
1519
|
|
1501
1520
|
result
|
1502
1521
|
end
|
@@ -1504,7 +1523,7 @@ module_eval(<<'.,.,', 'parser.y', 326)
|
|
1504
1523
|
|
1505
1524
|
module_eval(<<'.,.,', 'parser.y', 331)
|
1506
1525
|
def _reduce_131(val, _values, result)
|
1507
|
-
return make_node(:DirectiveDefinition, name: val[2], arguments: val[3], locations: val[5])
|
1526
|
+
return make_node(:DirectiveDefinition, name: val[2], arguments: val[3], locations: val[5], description: get_description(val[0]))
|
1508
1527
|
|
1509
1528
|
result
|
1510
1529
|
end
|
@@ -144,11 +144,11 @@ rule
|
|
144
144
|
| schema_keyword
|
145
145
|
|
146
146
|
name_list:
|
147
|
-
name { return [val[0]
|
148
|
-
| name_list name { val[0] << val[1]
|
147
|
+
name { return [make_node(:TypeName, name: val[0])] }
|
148
|
+
| name_list name { val[0] << make_node(:TypeName, name: val[1]) }
|
149
149
|
|
150
150
|
enum_value_definition:
|
151
|
-
enum_name directives_list_opt { return make_node(:EnumValueDefinition, name: val[0], directives: val[1]) }
|
151
|
+
enum_name directives_list_opt { return make_node(:EnumValueDefinition, name: val[0], directives: val[1], description: get_description(val[0])) }
|
152
152
|
|
153
153
|
enum_value_definitions:
|
154
154
|
enum_value_definition { return [val[0]] }
|
@@ -270,11 +270,11 @@ rule
|
|
270
270
|
| enum_type_definition
|
271
271
|
| input_object_type_definition
|
272
272
|
|
273
|
-
scalar_type_definition: SCALAR name directives_list_opt { return make_node(:ScalarTypeDefinition, name: val[1], directives: val[2]) }
|
273
|
+
scalar_type_definition: SCALAR name directives_list_opt { return make_node(:ScalarTypeDefinition, name: val[1], directives: val[2], description: get_description(val[0])) }
|
274
274
|
|
275
275
|
object_type_definition:
|
276
276
|
TYPE name implements_opt directives_list_opt LCURLY field_definition_list RCURLY {
|
277
|
-
return make_node(:ObjectTypeDefinition, name: val[1], interfaces: val[2], directives: val[3], fields: val[5])
|
277
|
+
return make_node(:ObjectTypeDefinition, name: val[1], interfaces: val[2], directives: val[3], fields: val[5], description: get_description(val[0]))
|
278
278
|
}
|
279
279
|
|
280
280
|
implements_opt:
|
@@ -283,7 +283,7 @@ rule
|
|
283
283
|
|
284
284
|
input_value_definition:
|
285
285
|
name COLON type default_value_opt directives_list_opt {
|
286
|
-
return make_node(:InputValueDefinition, name: val[0], type: val[2], default_value: val[3], directives: val[4])
|
286
|
+
return make_node(:InputValueDefinition, name: val[0], type: val[2], default_value: val[3], directives: val[4], description: get_description(val[0]))
|
287
287
|
}
|
288
288
|
|
289
289
|
input_value_definition_list:
|
@@ -296,7 +296,7 @@ rule
|
|
296
296
|
|
297
297
|
field_definition:
|
298
298
|
name arguments_definitions_opt COLON type directives_list_opt {
|
299
|
-
return make_node(:FieldDefinition, name: val[0], arguments: val[1], type: val[3], directives: val[4])
|
299
|
+
return make_node(:FieldDefinition, name: val[0], arguments: val[1], type: val[3], directives: val[4], description: get_description(val[0]))
|
300
300
|
}
|
301
301
|
|
302
302
|
field_definition_list:
|
@@ -305,31 +305,31 @@ rule
|
|
305
305
|
|
306
306
|
interface_type_definition:
|
307
307
|
INTERFACE name directives_list_opt LCURLY field_definition_list RCURLY {
|
308
|
-
return make_node(:InterfaceTypeDefinition, name: val[1], directives: val[2], fields: val[4])
|
308
|
+
return make_node(:InterfaceTypeDefinition, name: val[1], directives: val[2], fields: val[4], description: get_description(val[0]))
|
309
309
|
}
|
310
310
|
|
311
311
|
union_members:
|
312
|
-
name { return [val[0]
|
313
|
-
| union_members PIPE name { val[0] << val[2]
|
312
|
+
name { return [make_node(:TypeName, name: val[0])]}
|
313
|
+
| union_members PIPE name { val[0] << make_node(:TypeName, name: val[2]) }
|
314
314
|
|
315
315
|
union_type_definition:
|
316
316
|
UNION name directives_list_opt EQUALS union_members {
|
317
|
-
return make_node(:UnionTypeDefinition, name: val[1], directives: val[2], types: val[4])
|
317
|
+
return make_node(:UnionTypeDefinition, name: val[1], directives: val[2], types: val[4], description: get_description(val[0]))
|
318
318
|
}
|
319
319
|
|
320
320
|
enum_type_definition:
|
321
321
|
ENUM name directives_list_opt LCURLY enum_value_definitions RCURLY {
|
322
|
-
return make_node(:EnumTypeDefinition, name: val[1], directives: val[2], values: val[4])
|
322
|
+
return make_node(:EnumTypeDefinition, name: val[1], directives: val[2], values: val[4], description: get_description(val[0]))
|
323
323
|
}
|
324
324
|
|
325
325
|
input_object_type_definition:
|
326
326
|
INPUT name directives_list_opt LCURLY input_value_definition_list RCURLY {
|
327
|
-
return make_node(:InputObjectTypeDefinition, name: val[1], directives: val[2], fields: val[4])
|
327
|
+
return make_node(:InputObjectTypeDefinition, name: val[1], directives: val[2], fields: val[4], description: get_description(val[0]))
|
328
328
|
}
|
329
329
|
|
330
330
|
directive_definition:
|
331
331
|
DIRECTIVE DIR_SIGN name arguments_definitions_opt ON directive_locations {
|
332
|
-
return make_node(:DirectiveDefinition, name: val[2], arguments: val[3], locations: val[5])
|
332
|
+
return make_node(:DirectiveDefinition, name: val[2], arguments: val[3], locations: val[5], description: get_description(val[0]))
|
333
333
|
}
|
334
334
|
|
335
335
|
directive_locations:
|
@@ -372,6 +372,25 @@ def next_token
|
|
372
372
|
end
|
373
373
|
end
|
374
374
|
|
375
|
+
def get_description(token)
|
376
|
+
comments = []
|
377
|
+
|
378
|
+
loop do
|
379
|
+
prev_token = token
|
380
|
+
token = token.prev_token
|
381
|
+
|
382
|
+
break if token.nil?
|
383
|
+
break if token.name != :COMMENT
|
384
|
+
break if prev_token.line != token.line + 1
|
385
|
+
|
386
|
+
comments.unshift(token.to_s.sub(/^#\s*/, ""))
|
387
|
+
end
|
388
|
+
|
389
|
+
return nil if comments.empty?
|
390
|
+
|
391
|
+
comments.join("\n")
|
392
|
+
end
|
393
|
+
|
375
394
|
def on_error(parser_token_id, lexer_token, vstack)
|
376
395
|
if lexer_token == "$"
|
377
396
|
raise GraphQL::ParseError.new("Unexpected end of document", nil, nil, @query_string)
|
@@ -275,6 +275,90 @@ module GraphQL
|
|
275
275
|
end
|
276
276
|
end
|
277
277
|
|
278
|
+
describe "schema with comments" do
|
279
|
+
let(:query_string) {%|
|
280
|
+
# Schema at beginning of file
|
281
|
+
|
282
|
+
schema {
|
283
|
+
query: Hello
|
284
|
+
}
|
285
|
+
|
286
|
+
# Comment between two definitions are omitted
|
287
|
+
|
288
|
+
# This is a directive
|
289
|
+
directive @foo(
|
290
|
+
# It has an argument
|
291
|
+
arg: Int
|
292
|
+
) on FIELD
|
293
|
+
|
294
|
+
# Multiline comment
|
295
|
+
#
|
296
|
+
# With an enum
|
297
|
+
enum Color {
|
298
|
+
RED
|
299
|
+
|
300
|
+
# Not a creative color
|
301
|
+
GREEN
|
302
|
+
BLUE
|
303
|
+
}
|
304
|
+
|
305
|
+
#Comment without preceding space
|
306
|
+
type Hello {
|
307
|
+
# And a field to boot
|
308
|
+
str: String
|
309
|
+
}
|
310
|
+
|
311
|
+
# Comment for input object types
|
312
|
+
input Car {
|
313
|
+
# Color of the car
|
314
|
+
color: String!
|
315
|
+
}
|
316
|
+
|
317
|
+
# Comment for interface definitions
|
318
|
+
interface Vehicle {
|
319
|
+
# Amount of wheels
|
320
|
+
wheels: Int!
|
321
|
+
}
|
322
|
+
|
323
|
+
# Comment at the end of schema
|
324
|
+
|}
|
325
|
+
|
326
|
+
it "parses successfully" do
|
327
|
+
document = subject.parse(query_string)
|
328
|
+
|
329
|
+
assert_equal 6, document.definitions.size
|
330
|
+
|
331
|
+
schema_definition = document.definitions.shift
|
332
|
+
assert_equal GraphQL::Language::Nodes::SchemaDefinition, schema_definition.class
|
333
|
+
|
334
|
+
directive_definition = document.definitions.shift
|
335
|
+
assert_equal GraphQL::Language::Nodes::DirectiveDefinition, directive_definition.class
|
336
|
+
assert_equal 'This is a directive', directive_definition.description
|
337
|
+
|
338
|
+
enum_type_definition = document.definitions.shift
|
339
|
+
assert_equal GraphQL::Language::Nodes::EnumTypeDefinition, enum_type_definition.class
|
340
|
+
assert_equal "Multiline comment\n\nWith an enum", enum_type_definition.description
|
341
|
+
|
342
|
+
assert_nil enum_type_definition.values[0].description
|
343
|
+
assert_equal 'Not a creative color', enum_type_definition.values[1].description
|
344
|
+
|
345
|
+
object_type_definition = document.definitions.shift
|
346
|
+
assert_equal GraphQL::Language::Nodes::ObjectTypeDefinition, object_type_definition.class
|
347
|
+
assert_equal 'Comment without preceding space', object_type_definition.description
|
348
|
+
assert_equal 'And a field to boot', object_type_definition.fields[0].description
|
349
|
+
|
350
|
+
input_object_type_definition = document.definitions.shift
|
351
|
+
assert_equal GraphQL::Language::Nodes::InputObjectTypeDefinition, input_object_type_definition.class
|
352
|
+
assert_equal 'Comment for input object types', input_object_type_definition.description
|
353
|
+
assert_equal 'Color of the car', input_object_type_definition.fields[0].description
|
354
|
+
|
355
|
+
interface_type_definition = document.definitions.shift
|
356
|
+
assert_equal GraphQL::Language::Nodes::InterfaceTypeDefinition, interface_type_definition.class
|
357
|
+
assert_equal 'Comment for interface definitions', interface_type_definition.description
|
358
|
+
assert_equal 'Amount of wheels', interface_type_definition.fields[0].description
|
359
|
+
end
|
360
|
+
end
|
361
|
+
|
278
362
|
describe "schema" do
|
279
363
|
it "parses the test schema" do
|
280
364
|
schema = DummySchema
|
@@ -319,7 +403,7 @@ module GraphQL
|
|
319
403
|
type = document.definitions.first
|
320
404
|
assert_equal GraphQL::Language::Nodes::ObjectTypeDefinition, type.class
|
321
405
|
assert_equal 'Comment', type.name
|
322
|
-
assert_equal ['Node'], type.interfaces
|
406
|
+
assert_equal ['Node'], type.interfaces.map(&:name)
|
323
407
|
assert_equal ['id'], type.fields.map(&:name)
|
324
408
|
assert_equal [], type.fields[0].arguments
|
325
409
|
assert_equal 'ID', type.fields[0].type.of_type.name
|
@@ -335,7 +419,7 @@ module GraphQL
|
|
335
419
|
type = document.definitions.first
|
336
420
|
assert_equal GraphQL::Language::Nodes::ObjectTypeDefinition, type.class
|
337
421
|
assert_equal 'Comment', type.name
|
338
|
-
assert_equal ['Node'], type.interfaces
|
422
|
+
assert_equal ['Node'], type.interfaces.map(&:name)
|
339
423
|
assert_equal ['id'], type.fields.map(&:name)
|
340
424
|
assert_equal [], type.fields[0].arguments
|
341
425
|
assert_equal 'ID', type.fields[0].type.of_type.name
|
@@ -4,13 +4,14 @@ module GraphQL
|
|
4
4
|
# Contains type, value and position data.
|
5
5
|
class Token
|
6
6
|
# @return [Symbol] The kind of token this is
|
7
|
-
attr_reader :name
|
7
|
+
attr_reader :name, :prev_token, :line
|
8
8
|
|
9
|
-
def initialize(value:, name:, line:, col:)
|
9
|
+
def initialize(value:, name:, line:, col:, prev_token:)
|
10
10
|
@name = name
|
11
11
|
@value = value
|
12
12
|
@line = line
|
13
13
|
@col = col
|
14
|
+
@prev_token = prev_token
|
14
15
|
end
|
15
16
|
|
16
17
|
def to_s; @value; end
|
@@ -6,9 +6,9 @@ module GraphQL
|
|
6
6
|
# total_field_count = 0
|
7
7
|
# visitor = GraphQL::Language::Visitor.new(document)
|
8
8
|
# # Whenever you find a field, increment the field count:
|
9
|
-
# visitor[GraphQL::Language::Nodes::Field] << ->
|
9
|
+
# visitor[GraphQL::Language::Nodes::Field] << ->(node) { total_field_count += 1 }
|
10
10
|
# # When we finish, print the field count:
|
11
|
-
# visitor[GraphQL::Language::Nodes::Document].leave << ->
|
11
|
+
# visitor[GraphQL::Language::Nodes::Document].leave << ->(node) { p total_field_count }
|
12
12
|
# visitor.visit
|
13
13
|
# # => 6
|
14
14
|
#
|
@@ -34,7 +34,7 @@ module GraphQL
|
|
34
34
|
# @return [NodeVisitor]
|
35
35
|
#
|
36
36
|
# @example Run a hook whenever you enter a new Field
|
37
|
-
# visitor[GraphQL::Language::Nodes::Field] << ->
|
37
|
+
# visitor[GraphQL::Language::Nodes::Field] << ->(node, parent) { p "Here's a field" }
|
38
38
|
def [](node_class)
|
39
39
|
@visitors[node_class] ||= NodeVisitor.new
|
40
40
|
end
|
data/lib/graphql/object_type.rb
CHANGED
@@ -12,7 +12,7 @@ module GraphQL
|
|
12
12
|
# field :cast, CastType
|
13
13
|
# field :starring, types[PersonType] do
|
14
14
|
# argument :limit, types.Int
|
15
|
-
# resolve ->
|
15
|
+
# resolve ->(object, args, ctx) {
|
16
16
|
# stars = object.cast.stars
|
17
17
|
# args[:limit] && stars = stars.limit(args[:limit])
|
18
18
|
# stars
|
@@ -11,7 +11,8 @@ module GraphQL
|
|
11
11
|
@argument_values = values.inject({}) do |memo, (inner_key, inner_value)|
|
12
12
|
string_key = inner_key.to_s
|
13
13
|
arg_defn = argument_definitions[string_key]
|
14
|
-
|
14
|
+
arg_value = wrap_value(inner_value, arg_defn.type)
|
15
|
+
memo[string_key] = ArgumentValue.new(string_key, arg_value, arg_defn)
|
15
16
|
memo
|
16
17
|
end
|
17
18
|
end
|
@@ -19,7 +20,7 @@ module GraphQL
|
|
19
20
|
# @param key [String, Symbol] name or index of value to access
|
20
21
|
# @return [Object] the argument at that key
|
21
22
|
def [](key)
|
22
|
-
@argument_values
|
23
|
+
@argument_values.fetch(key.to_s, NULL_ARGUMENT_VALUE).value
|
23
24
|
end
|
24
25
|
|
25
26
|
# @param key [String, Symbol] name of value to access
|
@@ -36,8 +37,28 @@ module GraphQL
|
|
36
37
|
|
37
38
|
def_delegators :string_key_values, :keys, :values, :each
|
38
39
|
|
40
|
+
# Access each key, value and type for the arguments in this set.
|
41
|
+
# @yield [argument_value] The {ArgumentValue} for each argument
|
42
|
+
# @yieldparam argument_value [ArgumentValue]
|
43
|
+
def each_value
|
44
|
+
@argument_values.each_value do |argument_value|
|
45
|
+
yield(argument_value)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
39
49
|
private
|
40
50
|
|
51
|
+
class ArgumentValue
|
52
|
+
attr_reader :key, :value, :definition
|
53
|
+
def initialize(key, value, definition)
|
54
|
+
@key = key
|
55
|
+
@value = value
|
56
|
+
@definition = definition
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
NULL_ARGUMENT_VALUE = ArgumentValue.new(nil, nil, nil)
|
61
|
+
|
41
62
|
def wrap_value(value, arg_defn_type)
|
42
63
|
case value
|
43
64
|
when Array
|