graphql 0.19.3 → 0.19.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/graphql/analysis/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
|