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.
Files changed (103) hide show
  1. checksums.yaml +4 -4
  2. data/lib/graphql/analysis/max_query_complexity.rb +1 -1
  3. data/lib/graphql/analysis/max_query_depth.rb +1 -1
  4. data/lib/graphql/boolean_type.rb +2 -2
  5. data/lib/graphql/define/instance_definable.rb +2 -2
  6. data/lib/graphql/enum_type.rb +3 -3
  7. data/lib/graphql/field.rb +6 -6
  8. data/lib/graphql/float_type.rb +2 -2
  9. data/lib/graphql/id_type.rb +2 -2
  10. data/lib/graphql/input_object_type.rb +1 -1
  11. data/lib/graphql/int_type.rb +2 -2
  12. data/lib/graphql/internal_representation/rewrite.rb +12 -12
  13. data/lib/graphql/introspection/arguments_field.rb +1 -1
  14. data/lib/graphql/introspection/enum_value_type.rb +1 -1
  15. data/lib/graphql/introspection/enum_values_field.rb +1 -1
  16. data/lib/graphql/introspection/field_type.rb +1 -1
  17. data/lib/graphql/introspection/fields_field.rb +1 -1
  18. data/lib/graphql/introspection/input_fields_field.rb +1 -1
  19. data/lib/graphql/introspection/input_value_type.rb +2 -2
  20. data/lib/graphql/introspection/interfaces_field.rb +1 -1
  21. data/lib/graphql/introspection/of_type_field.rb +1 -1
  22. data/lib/graphql/introspection/possible_types_field.rb +1 -1
  23. data/lib/graphql/introspection/schema_field.rb +1 -1
  24. data/lib/graphql/introspection/schema_type.rb +5 -5
  25. data/lib/graphql/introspection/type_by_name_field.rb +1 -1
  26. data/lib/graphql/introspection/type_type.rb +6 -6
  27. data/lib/graphql/introspection/typename_field.rb +1 -1
  28. data/lib/graphql/language.rb +1 -0
  29. data/lib/graphql/language/comments.rb +44 -0
  30. data/lib/graphql/language/definition_slice.rb +1 -1
  31. data/lib/graphql/language/generation.rb +35 -12
  32. data/lib/graphql/language/lexer.rb +29 -10
  33. data/lib/graphql/language/lexer.rl +25 -6
  34. data/lib/graphql/language/nodes.rb +30 -23
  35. data/lib/graphql/language/parser.rb +33 -14
  36. data/lib/graphql/language/parser.y +33 -14
  37. data/lib/graphql/language/parser_tests.rb +86 -2
  38. data/lib/graphql/language/token.rb +3 -2
  39. data/lib/graphql/language/visitor.rb +3 -3
  40. data/lib/graphql/object_type.rb +1 -1
  41. data/lib/graphql/query/arguments.rb +23 -2
  42. data/lib/graphql/query/serial_execution/field_resolution.rb +31 -14
  43. data/lib/graphql/relay/base_connection.rb +1 -3
  44. data/lib/graphql/relay/connection_type.rb +1 -1
  45. data/lib/graphql/relay/mutation.rb +1 -1
  46. data/lib/graphql/relay/relation_connection.rb +7 -3
  47. data/lib/graphql/scalar_type.rb +1 -1
  48. data/lib/graphql/schema.rb +19 -8
  49. data/lib/graphql/schema/loader.rb +2 -2
  50. data/lib/graphql/schema/printer.rb +63 -8
  51. data/lib/graphql/schema/timeout_middleware.rb +11 -11
  52. data/lib/graphql/schema/validation.rb +12 -12
  53. data/lib/graphql/static_validation/arguments_validator.rb +1 -1
  54. data/lib/graphql/static_validation/rules/directives_are_defined.rb +1 -1
  55. data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +1 -1
  56. data/lib/graphql/static_validation/rules/fields_are_defined_on_type.rb +1 -1
  57. data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +1 -1
  58. data/lib/graphql/static_validation/rules/fields_will_merge.rb +3 -2
  59. data/lib/graphql/static_validation/rules/fragment_spreads_are_possible.rb +3 -3
  60. data/lib/graphql/static_validation/rules/fragment_types_exist.rb +1 -1
  61. data/lib/graphql/static_validation/rules/fragments_are_finite.rb +9 -4
  62. data/lib/graphql/static_validation/rules/fragments_are_named.rb +1 -1
  63. data/lib/graphql/static_validation/rules/fragments_are_on_composite_types.rb +1 -1
  64. data/lib/graphql/static_validation/rules/fragments_are_used.rb +3 -3
  65. data/lib/graphql/static_validation/rules/mutation_root_exists.rb +1 -1
  66. data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +2 -2
  67. data/lib/graphql/static_validation/rules/subscription_root_exists.rb +1 -1
  68. data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +1 -1
  69. data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +2 -2
  70. data/lib/graphql/static_validation/rules/variables_are_input_types.rb +1 -1
  71. data/lib/graphql/static_validation/rules/variables_are_used_and_defined.rb +6 -6
  72. data/lib/graphql/static_validation/type_stack.rb +2 -2
  73. data/lib/graphql/string_type.rb +2 -2
  74. data/lib/graphql/version.rb +1 -1
  75. data/readme.md +1 -1
  76. data/spec/graphql/analysis/analyze_query_spec.rb +3 -3
  77. data/spec/graphql/analysis/query_complexity_spec.rb +7 -7
  78. data/spec/graphql/introspection/directive_type_spec.rb +2 -2
  79. data/spec/graphql/introspection/introspection_query_spec.rb +26 -26
  80. data/spec/graphql/language/generation_spec.rb +137 -53
  81. data/spec/graphql/language/lexer_spec.rb +22 -0
  82. data/spec/graphql/language/visitor_spec.rb +6 -6
  83. data/spec/graphql/query/arguments_spec.rb +45 -1
  84. data/spec/graphql/query/context_spec.rb +4 -4
  85. data/spec/graphql/query/executor_spec.rb +1 -1
  86. data/spec/graphql/query/serial_execution/value_resolution_spec.rb +1 -1
  87. data/spec/graphql/relay/mutation_spec.rb +2 -2
  88. data/spec/graphql/relay/node_spec.rb +2 -2
  89. data/spec/graphql/relay/relation_connection_spec.rb +16 -0
  90. data/spec/graphql/schema/loader_spec.rb +2 -2
  91. data/spec/graphql/schema/middleware_chain_spec.rb +6 -6
  92. data/spec/graphql/schema/printer_spec.rb +268 -18
  93. data/spec/graphql/schema/rescue_middleware_spec.rb +1 -1
  94. data/spec/graphql/schema/timeout_middleware_spec.rb +2 -2
  95. data/spec/graphql/schema_spec.rb +2 -2
  96. data/spec/graphql/static_validation/rules/fragments_are_finite_spec.rb +13 -0
  97. data/spec/graphql/static_validation/rules/fragments_are_used_spec.rb +1 -1
  98. data/spec/graphql/static_validation/type_stack_spec.rb +1 -1
  99. data/spec/support/dairy_app.rb +25 -25
  100. data/spec/support/dairy_data.rb +2 -0
  101. data/spec/support/star_wars_data.rb +2 -1
  102. data/spec/support/star_wars_schema.rb +18 -18
  103. 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].to_s]
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].to_s
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].to_s]
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].to_s
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].to_s]}
148
- | name_list name { val[0] << val[1].to_s }
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].to_s]}
313
- | union_members PIPE name { val[0] << val[2].to_s }
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] << -> (node) { total_field_count += 1 }
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 << -> (node) { p total_field_count }
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] << -> (node, parent) { p "Here's a 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
@@ -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 -> (object, args, ctx) {
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
- memo[string_key] = wrap_value(inner_value, arg_defn.type)
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[key.to_s]
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