graphql 0.12.1 → 0.13.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (146) hide show
  1. checksums.yaml +4 -4
  2. data/lib/graphql.rb +31 -41
  3. data/lib/graphql/argument.rb +23 -21
  4. data/lib/graphql/base_type.rb +5 -8
  5. data/lib/graphql/define/assign_argument.rb +5 -2
  6. data/lib/graphql/define/type_definer.rb +2 -1
  7. data/lib/graphql/directive.rb +34 -36
  8. data/lib/graphql/directive/include_directive.rb +3 -7
  9. data/lib/graphql/directive/skip_directive.rb +3 -7
  10. data/lib/graphql/enum_type.rb +78 -76
  11. data/lib/graphql/execution_error.rb +1 -3
  12. data/lib/graphql/field.rb +99 -95
  13. data/lib/graphql/input_object_type.rb +49 -47
  14. data/lib/graphql/interface_type.rb +31 -34
  15. data/lib/graphql/introspection.rb +19 -18
  16. data/lib/graphql/introspection/directive_location_enum.rb +8 -0
  17. data/lib/graphql/introspection/directive_type.rb +1 -3
  18. data/lib/graphql/introspection/field_type.rb +1 -1
  19. data/lib/graphql/introspection/fields_field.rb +1 -1
  20. data/lib/graphql/introspection/introspection_query.rb +1 -3
  21. data/lib/graphql/introspection/possible_types_field.rb +7 -1
  22. data/lib/graphql/introspection/schema_field.rb +13 -9
  23. data/lib/graphql/introspection/type_by_name_field.rb +13 -17
  24. data/lib/graphql/introspection/typename_field.rb +12 -8
  25. data/lib/graphql/language.rb +5 -9
  26. data/lib/graphql/language/lexer.rb +668 -0
  27. data/lib/graphql/language/lexer.rl +149 -0
  28. data/lib/graphql/language/parser.rb +842 -116
  29. data/lib/graphql/language/parser.y +264 -0
  30. data/lib/graphql/language/token.rb +21 -0
  31. data/lib/graphql/list_type.rb +33 -31
  32. data/lib/graphql/non_null_type.rb +33 -31
  33. data/lib/graphql/object_type.rb +52 -55
  34. data/lib/graphql/query.rb +83 -80
  35. data/lib/graphql/query/context.rb +5 -1
  36. data/lib/graphql/query/directive_resolution.rb +16 -0
  37. data/lib/graphql/query/executor.rb +3 -3
  38. data/lib/graphql/query/input_validation_result.rb +17 -15
  39. data/lib/graphql/query/serial_execution.rb +5 -5
  40. data/lib/graphql/query/serial_execution/execution_context.rb +4 -3
  41. data/lib/graphql/query/serial_execution/selection_resolution.rb +19 -21
  42. data/lib/graphql/query/serial_execution/value_resolution.rb +1 -1
  43. data/lib/graphql/query/type_resolver.rb +22 -18
  44. data/lib/graphql/query/variable_validation_error.rb +14 -12
  45. data/lib/graphql/schema.rb +87 -77
  46. data/lib/graphql/schema/each_item_validator.rb +16 -12
  47. data/lib/graphql/schema/field_validator.rb +14 -10
  48. data/lib/graphql/schema/implementation_validator.rb +26 -22
  49. data/lib/graphql/schema/middleware_chain.rb +2 -1
  50. data/lib/graphql/schema/possible_types.rb +34 -0
  51. data/lib/graphql/schema/printer.rb +122 -120
  52. data/lib/graphql/schema/type_expression.rb +1 -0
  53. data/lib/graphql/schema/type_map.rb +3 -10
  54. data/lib/graphql/schema/type_reducer.rb +65 -81
  55. data/lib/graphql/schema/type_validator.rb +45 -41
  56. data/lib/graphql/static_validation.rb +7 -9
  57. data/lib/graphql/static_validation/all_rules.rb +29 -24
  58. data/lib/graphql/static_validation/arguments_validator.rb +39 -35
  59. data/lib/graphql/static_validation/literal_validator.rb +44 -40
  60. data/lib/graphql/static_validation/message.rb +30 -26
  61. data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +15 -11
  62. data/lib/graphql/static_validation/rules/arguments_are_defined.rb +14 -10
  63. data/lib/graphql/static_validation/rules/directives_are_defined.rb +16 -12
  64. data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +59 -0
  65. data/lib/graphql/static_validation/rules/fields_are_defined_on_type.rb +25 -21
  66. data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +28 -24
  67. data/lib/graphql/static_validation/rules/fields_will_merge.rb +84 -80
  68. data/lib/graphql/static_validation/rules/fragment_spreads_are_possible.rb +49 -43
  69. data/lib/graphql/static_validation/rules/fragment_types_exist.rb +22 -17
  70. data/lib/graphql/static_validation/rules/fragments_are_finite.rb +19 -15
  71. data/lib/graphql/static_validation/rules/fragments_are_on_composite_types.rb +25 -20
  72. data/lib/graphql/static_validation/rules/fragments_are_used.rb +36 -23
  73. data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +29 -25
  74. data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +21 -17
  75. data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +79 -70
  76. data/lib/graphql/static_validation/rules/variables_are_input_types.rb +24 -20
  77. data/lib/graphql/static_validation/rules/variables_are_used_and_defined.rb +122 -119
  78. data/lib/graphql/static_validation/type_stack.rb +138 -129
  79. data/lib/graphql/static_validation/validator.rb +29 -25
  80. data/lib/graphql/type_kinds.rb +42 -40
  81. data/lib/graphql/union_type.rb +22 -16
  82. data/lib/graphql/version.rb +1 -1
  83. data/readme.md +12 -27
  84. data/spec/graphql/base_type_spec.rb +3 -3
  85. data/spec/graphql/directive_spec.rb +10 -18
  86. data/spec/graphql/enum_type_spec.rb +7 -7
  87. data/spec/graphql/execution_error_spec.rb +1 -1
  88. data/spec/graphql/field_spec.rb +14 -13
  89. data/spec/graphql/id_type_spec.rb +6 -6
  90. data/spec/graphql/input_object_type_spec.rb +39 -39
  91. data/spec/graphql/interface_type_spec.rb +16 -32
  92. data/spec/graphql/introspection/directive_type_spec.rb +5 -9
  93. data/spec/graphql/introspection/input_value_type_spec.rb +10 -4
  94. data/spec/graphql/introspection/introspection_query_spec.rb +2 -2
  95. data/spec/graphql/introspection/schema_type_spec.rb +2 -2
  96. data/spec/graphql/introspection/type_type_spec.rb +34 -6
  97. data/spec/graphql/language/parser_spec.rb +299 -105
  98. data/spec/graphql/language/visitor_spec.rb +4 -4
  99. data/spec/graphql/list_type_spec.rb +11 -11
  100. data/spec/graphql/object_type_spec.rb +10 -10
  101. data/spec/graphql/query/arguments_spec.rb +7 -7
  102. data/spec/graphql/query/context_spec.rb +11 -3
  103. data/spec/graphql/query/executor_spec.rb +26 -19
  104. data/spec/graphql/query/serial_execution/execution_context_spec.rb +6 -6
  105. data/spec/graphql/query/serial_execution/value_resolution_spec.rb +2 -2
  106. data/spec/graphql/query/type_resolver_spec.rb +3 -3
  107. data/spec/graphql/query_spec.rb +6 -38
  108. data/spec/graphql/scalar_type_spec.rb +28 -19
  109. data/spec/graphql/schema/field_validator_spec.rb +1 -1
  110. data/spec/graphql/schema/middleware_chain_spec.rb +12 -1
  111. data/spec/graphql/schema/printer_spec.rb +12 -4
  112. data/spec/graphql/schema/rescue_middleware_spec.rb +1 -1
  113. data/spec/graphql/schema/type_expression_spec.rb +2 -2
  114. data/spec/graphql/schema/type_reducer_spec.rb +21 -36
  115. data/spec/graphql/schema/type_validator_spec.rb +9 -9
  116. data/spec/graphql/schema_spec.rb +1 -1
  117. data/spec/graphql/static_validation/rules/argument_literals_are_compatible_spec.rb +4 -4
  118. data/spec/graphql/static_validation/rules/arguments_are_defined_spec.rb +4 -4
  119. data/spec/graphql/static_validation/rules/directives_are_defined_spec.rb +5 -5
  120. data/spec/graphql/static_validation/rules/directives_are_in_valid_locations_spec.rb +39 -0
  121. data/spec/graphql/static_validation/rules/fields_are_defined_on_type_spec.rb +5 -5
  122. data/spec/graphql/static_validation/rules/fields_have_appropriate_selections_spec.rb +4 -4
  123. data/spec/graphql/static_validation/rules/fields_will_merge_spec.rb +2 -2
  124. data/spec/graphql/static_validation/rules/fragment_spreads_are_possible_spec.rb +1 -1
  125. data/spec/graphql/static_validation/rules/fragment_types_exist_spec.rb +2 -2
  126. data/spec/graphql/static_validation/rules/fragments_are_finite_spec.rb +2 -2
  127. data/spec/graphql/static_validation/rules/fragments_are_on_composite_types_spec.rb +2 -2
  128. data/spec/graphql/static_validation/rules/fragments_are_used_spec.rb +3 -3
  129. data/spec/graphql/static_validation/rules/required_arguments_are_present_spec.rb +3 -3
  130. data/spec/graphql/static_validation/rules/variable_default_values_are_correctly_typed_spec.rb +5 -5
  131. data/spec/graphql/static_validation/rules/variable_usages_are_allowed_spec.rb +3 -1
  132. data/spec/graphql/static_validation/rules/variables_are_input_types_spec.rb +4 -4
  133. data/spec/graphql/static_validation/rules/variables_are_used_and_defined_spec.rb +3 -3
  134. data/spec/graphql/static_validation/type_stack_spec.rb +3 -2
  135. data/spec/graphql/static_validation/validator_spec.rb +26 -6
  136. data/spec/graphql/union_type_spec.rb +5 -4
  137. data/spec/spec_helper.rb +2 -5
  138. data/spec/support/dairy_app.rb +30 -9
  139. data/spec/support/dairy_data.rb +1 -1
  140. data/spec/support/star_wars_data.rb +26 -26
  141. data/spec/support/star_wars_schema.rb +1 -1
  142. metadata +40 -21
  143. data/lib/graphql/language/transform.rb +0 -113
  144. data/lib/graphql/query/directive_chain.rb +0 -44
  145. data/lib/graphql/repl.rb +0 -27
  146. data/spec/graphql/language/transform_spec.rb +0 -156
@@ -1,6 +1,6 @@
1
1
  # Based on the graphql-js example
2
2
  # https://github.com/graphql/graphql-js/blob/master/src/__tests__/starWarsSchema.js
3
- require_relative './star_wars_data'
3
+ require_relative "./star_wars_data"
4
4
 
5
5
  EpisodeEnum = GraphQL::EnumType.define do
6
6
  name("Episode")
metadata CHANGED
@@ -1,29 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: graphql
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.12.1
4
+ version: 0.13.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robert Mosolgo
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-04-26 00:00:00.000000000 Z
11
+ date: 2016-04-29 00:00:00.000000000 Z
12
12
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: parslet
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - "~>"
18
- - !ruby/object:Gem::Version
19
- version: '1.6'
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - "~>"
25
- - !ruby/object:Gem::Version
26
- version: '1.6'
27
13
  - !ruby/object:Gem::Dependency
28
14
  name: codeclimate-test-reporter
29
15
  requirement: !ruby/object:Gem::Requirement
@@ -94,6 +80,20 @@ dependencies:
94
80
  - - "~>"
95
81
  - !ruby/object:Gem::Version
96
82
  version: '2.4'
83
+ - !ruby/object:Gem::Dependency
84
+ name: guard-rake
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: listen
99
99
  requirement: !ruby/object:Gem::Requirement
@@ -150,6 +150,20 @@ dependencies:
150
150
  - - "~>"
151
151
  - !ruby/object:Gem::Version
152
152
  version: '1.0'
153
+ - !ruby/object:Gem::Dependency
154
+ name: racc
155
+ requirement: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - "~>"
158
+ - !ruby/object:Gem::Version
159
+ version: '1.4'
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - "~>"
165
+ - !ruby/object:Gem::Version
166
+ version: '1.4'
153
167
  - !ruby/object:Gem::Dependency
154
168
  name: rake
155
169
  requirement: !ruby/object:Gem::Requirement
@@ -199,6 +213,7 @@ files:
199
213
  - lib/graphql/interface_type.rb
200
214
  - lib/graphql/introspection.rb
201
215
  - lib/graphql/introspection/arguments_field.rb
216
+ - lib/graphql/introspection/directive_location_enum.rb
202
217
  - lib/graphql/introspection/directive_type.rb
203
218
  - lib/graphql/introspection/enum_value_type.rb
204
219
  - lib/graphql/introspection/enum_values_field.rb
@@ -218,9 +233,12 @@ files:
218
233
  - lib/graphql/introspection/typename_field.rb
219
234
  - lib/graphql/invalid_null_error.rb
220
235
  - lib/graphql/language.rb
236
+ - lib/graphql/language/lexer.rb
237
+ - lib/graphql/language/lexer.rl
221
238
  - lib/graphql/language/nodes.rb
222
239
  - lib/graphql/language/parser.rb
223
- - lib/graphql/language/transform.rb
240
+ - lib/graphql/language/parser.y
241
+ - lib/graphql/language/token.rb
224
242
  - lib/graphql/language/visitor.rb
225
243
  - lib/graphql/list_type.rb
226
244
  - lib/graphql/non_null_type.rb
@@ -228,7 +246,7 @@ files:
228
246
  - lib/graphql/query.rb
229
247
  - lib/graphql/query/arguments.rb
230
248
  - lib/graphql/query/context.rb
231
- - lib/graphql/query/directive_chain.rb
249
+ - lib/graphql/query/directive_resolution.rb
232
250
  - lib/graphql/query/executor.rb
233
251
  - lib/graphql/query/input_validation_result.rb
234
252
  - lib/graphql/query/literal_input.rb
@@ -241,13 +259,13 @@ files:
241
259
  - lib/graphql/query/type_resolver.rb
242
260
  - lib/graphql/query/variable_validation_error.rb
243
261
  - lib/graphql/query/variables.rb
244
- - lib/graphql/repl.rb
245
262
  - lib/graphql/scalar_type.rb
246
263
  - lib/graphql/schema.rb
247
264
  - lib/graphql/schema/each_item_validator.rb
248
265
  - lib/graphql/schema/field_validator.rb
249
266
  - lib/graphql/schema/implementation_validator.rb
250
267
  - lib/graphql/schema/middleware_chain.rb
268
+ - lib/graphql/schema/possible_types.rb
251
269
  - lib/graphql/schema/printer.rb
252
270
  - lib/graphql/schema/rescue_middleware.rb
253
271
  - lib/graphql/schema/type_expression.rb
@@ -262,6 +280,7 @@ files:
262
280
  - lib/graphql/static_validation/rules/argument_literals_are_compatible.rb
263
281
  - lib/graphql/static_validation/rules/arguments_are_defined.rb
264
282
  - lib/graphql/static_validation/rules/directives_are_defined.rb
283
+ - lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb
265
284
  - lib/graphql/static_validation/rules/document_does_not_exceed_max_depth.rb
266
285
  - lib/graphql/static_validation/rules/fields_are_defined_on_type.rb
267
286
  - lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb
@@ -302,7 +321,6 @@ files:
302
321
  - spec/graphql/introspection/schema_type_spec.rb
303
322
  - spec/graphql/introspection/type_type_spec.rb
304
323
  - spec/graphql/language/parser_spec.rb
305
- - spec/graphql/language/transform_spec.rb
306
324
  - spec/graphql/language/visitor_spec.rb
307
325
  - spec/graphql/list_type_spec.rb
308
326
  - spec/graphql/object_type_spec.rb
@@ -326,6 +344,7 @@ files:
326
344
  - spec/graphql/static_validation/rules/argument_literals_are_compatible_spec.rb
327
345
  - spec/graphql/static_validation/rules/arguments_are_defined_spec.rb
328
346
  - spec/graphql/static_validation/rules/directives_are_defined_spec.rb
347
+ - spec/graphql/static_validation/rules/directives_are_in_valid_locations_spec.rb
329
348
  - spec/graphql/static_validation/rules/document_does_not_exceed_max_depth_spec.rb
330
349
  - spec/graphql/static_validation/rules/fields_are_defined_on_type_spec.rb
331
350
  - spec/graphql/static_validation/rules/fields_have_appropriate_selections_spec.rb
@@ -393,7 +412,6 @@ test_files:
393
412
  - spec/graphql/introspection/schema_type_spec.rb
394
413
  - spec/graphql/introspection/type_type_spec.rb
395
414
  - spec/graphql/language/parser_spec.rb
396
- - spec/graphql/language/transform_spec.rb
397
415
  - spec/graphql/language/visitor_spec.rb
398
416
  - spec/graphql/list_type_spec.rb
399
417
  - spec/graphql/object_type_spec.rb
@@ -417,6 +435,7 @@ test_files:
417
435
  - spec/graphql/static_validation/rules/argument_literals_are_compatible_spec.rb
418
436
  - spec/graphql/static_validation/rules/arguments_are_defined_spec.rb
419
437
  - spec/graphql/static_validation/rules/directives_are_defined_spec.rb
438
+ - spec/graphql/static_validation/rules/directives_are_in_valid_locations_spec.rb
420
439
  - spec/graphql/static_validation/rules/document_does_not_exceed_max_depth_spec.rb
421
440
  - spec/graphql/static_validation/rules/fields_are_defined_on_type_spec.rb
422
441
  - spec/graphql/static_validation/rules/fields_have_appropriate_selections_spec.rb
@@ -1,113 +0,0 @@
1
- module GraphQL
2
- module Language
3
- # {Transform} is a [parslet](http://kschiess.github.io/parslet/) transform for for turning the AST into objects in {GraphQL::Language::Nodes} objects.
4
- class Transform < Parslet::Transform
5
-
6
- # @param [Symbol] name of a node constant
7
- # @param [Hash] attributes to initialize the {Node} with
8
- # @return [GraphQL::Language::Node] a node of type `name` with attributes `attributes`
9
- CREATE_NODE = Proc.new do |name, attributes|
10
- node_class = GraphQL::Language::Nodes.const_get(name)
11
- node_class.new(attributes)
12
- end
13
-
14
- def self.optional_sequence(name)
15
- rule(name => simple(:val)) { [] }
16
- rule(name => sequence(:val)) { val }
17
- end
18
-
19
- # Document
20
- rule(document_parts: sequence(:p)) { CREATE_NODE[:Document, definitions: p, line: (p.first ? p.first.line : 1), col: (p.first ? p.first.col : 1)]}
21
- rule(document_parts: simple(:p)) { CREATE_NODE[:Document, definitions: [], line: 1, col: 1]}
22
-
23
- # Fragment Definition
24
- rule(
25
- fragment_keyword: simple(:kw),
26
- fragment_name: simple(:name),
27
- type_condition: simple(:type),
28
- directives: sequence(:directives),
29
- selections: sequence(:selections)
30
- ) { CREATE_NODE[:FragmentDefinition, name: name.to_s, type: type.to_s, directives: directives, selections: selections, position_source: kw]}
31
-
32
- rule(
33
- fragment_spread_keyword: simple(:kw),
34
- fragment_spread_name: simple(:n),
35
- directives: sequence(:d)
36
- ) { CREATE_NODE[:FragmentSpread, name: n.to_s, directives: d, position_source: kw]}
37
-
38
- rule(
39
- fragment_spread_keyword: simple(:kw),
40
- inline_fragment_type: simple(:n),
41
- directives: sequence(:d),
42
- selections: sequence(:s),
43
- ) { CREATE_NODE[:InlineFragment, type: n.to_s, directives: d, selections: s, position_source: kw]}
44
-
45
- # Operation Definition
46
- rule(
47
- operation_type: simple(:ot),
48
- name: simple(:n),
49
- variables: sequence(:v),
50
- directives: sequence(:d),
51
- selections: sequence(:s),
52
- ) { CREATE_NODE[:OperationDefinition, operation_type: ot.to_s, name: n.to_s, variables: v, directives: d, selections: s, position_source: ot] }
53
- optional_sequence(:optional_variables)
54
- rule(variable_name: simple(:n), variable_type: simple(:t), variable_optional_default_value: simple(:v)) { CREATE_NODE.(:VariableDefinition, name: n.name, type: t, default_value: v, line: n.line, col: n.col)}
55
- rule(variable_name: simple(:n), variable_type: simple(:t), variable_optional_default_value: sequence(:v)) { CREATE_NODE.(:VariableDefinition, name: n.name, type: t, default_value: v, line: n.line, col: n.col)}
56
- rule(variable_default_value: simple(:v) ) { v }
57
- rule(variable_default_value: sequence(:v) ) { v }
58
- # Query short-hand
59
- rule(unnamed_selections: sequence(:s)) { CREATE_NODE[:OperationDefinition, selections: s, operation_type: "query", name: nil, variables: [], directives: [], line: s.first.line, col: s.first.col]}
60
-
61
- # Field
62
- rule(
63
- alias: simple(:a),
64
- field_name: simple(:name),
65
- field_arguments: sequence(:args),
66
- directives: sequence(:dir),
67
- selections: sequence(:sel)
68
- ) { CREATE_NODE[:Field, alias: a && a.to_s, name: name.to_s, arguments: args, directives: dir, selections: sel, position_source: [a, name].find { |part| !part.nil? }] }
69
-
70
- rule(alias_name: simple(:a)) { a }
71
- optional_sequence(:optional_field_arguments)
72
- rule(field_argument_name: simple(:n), field_argument_value: simple(:v)) { CREATE_NODE[:Argument, name: n.to_s, value: v, position_source: n]}
73
- rule(field_argument_name: simple(:n), field_argument_value: subtree(:v)) { CREATE_NODE[:Argument, name: n.to_s, value: v, position_source: n]}
74
- optional_sequence(:optional_selections)
75
- optional_sequence(:optional_directives)
76
-
77
- # Directive
78
- rule(directive_name: simple(:name), directive_arguments: sequence(:args)) { CREATE_NODE[:Directive, name: name.to_s, arguments: args, position_source: name ] }
79
- rule(directive_argument_name: simple(:n), directive_argument_value: simple(:v)) { CREATE_NODE[:Argument, name: n.to_s, value: v, position_source: n]}
80
- optional_sequence(:optional_directive_arguments)
81
-
82
- # Type Defs
83
- rule(type_name: simple(:n)) { CREATE_NODE[:TypeName, name: n.to_s, position_source: n] }
84
- rule(list_type: simple(:t)) { CREATE_NODE[:ListType, of_type: t, line: t.line, col: t.col] }
85
- rule(non_null_type: simple(:t)) { CREATE_NODE[:NonNullType, of_type: t, line: t.line, col: t.col] }
86
-
87
- # Values
88
- rule(array: subtree(:v)) { v }
89
- rule(array: simple(:v)) { [] } # just `nil`
90
- rule(boolean: simple(:v)) { v == "true" ? true : false }
91
- rule(input_object: sequence(:v)) { CREATE_NODE[:InputObject, arguments: v, line: (v.first ? v.first.line : 1), col: (v.first ? v.first.col : 1)] }
92
- rule(input_object_name: simple(:n), input_object_value: simple(:v)) { CREATE_NODE[:Argument, name: n.to_s, value: v, position_source: n]}
93
- rule(input_object_name: simple(:n), input_object_value: sequence(:v)) { CREATE_NODE[:Argument, name: n.to_s, value: v, position_source: n]}
94
- rule(int: simple(:v)) { v.to_i }
95
- rule(float: simple(:v)) { v.to_f }
96
-
97
- ESCAPES = /\\["\\\/bfnrt]/
98
- ESCAPES_REPLACE = { '\\"' => '"', "\\\\" => "\\", "\\/" => '/', "\\b" => "\b", "\\f" => "\f", "\\n" => "\n", "\\r" => "\r", "\\t" => "\t" }
99
- UTF_8 = /\\u[\da-f]{4}/i
100
- UTF_8_REPLACE = -> (m) { [m[-4..-1].to_i(16)].pack('U') }
101
-
102
- rule(string: simple(:v)) {
103
- string = v.to_s
104
- string.gsub!(ESCAPES, ESCAPES_REPLACE)
105
- string.gsub!(UTF_8, &UTF_8_REPLACE)
106
- string
107
- }
108
- rule(optional_string_content: simple(:v)) { v.to_s }
109
- rule(variable: simple(:v)) { CREATE_NODE[:VariableIdentifier, name: v.to_s, position_source: v] }
110
- rule(enum: simple(:v)) { CREATE_NODE[:Enum, name: v.to_s, position_source: v] }
111
- end
112
- end
113
- end
@@ -1,44 +0,0 @@
1
- # TODO: directives on fragments: http://facebook.github.io/graphql/#sec-Fragment-Directives
2
- class GraphQL::Query::DirectiveChain
3
- DIRECTIVE_ON = {
4
- GraphQL::Language::Nodes::Field => GraphQL::Directive::ON_FIELD,
5
- GraphQL::Language::Nodes::InlineFragment => GraphQL::Directive::ON_FRAGMENT,
6
- GraphQL::Language::Nodes::FragmentSpread => GraphQL::Directive::ON_FRAGMENT,
7
- }
8
-
9
- GET_DIRECTIVES = {
10
- GraphQL::Language::Nodes::Field => Proc.new { |n, f| n.directives },
11
- GraphQL::Language::Nodes::InlineFragment => Proc.new { |n, f| n.directives },
12
- GraphQL::Language::Nodes::FragmentSpread => Proc.new { |n, f| n.directives + f[n.name].directives }, # get directives from definition too
13
- }
14
-
15
- attr_reader :result
16
- def initialize(ast_node, query, &block)
17
- directives = query.schema.directives
18
- on_what = DIRECTIVE_ON[ast_node.class]
19
- ast_directives = GET_DIRECTIVES[ast_node.class].call(ast_node, query.fragments)
20
-
21
- if contains_skip?(ast_directives)
22
- ast_directives = ast_directives.reject { |ast_directive| ast_directive.name == 'include' }
23
- end
24
-
25
- applicable_directives = ast_directives
26
- .map { |ast_directive| [ast_directive, directives[ast_directive.name]] }
27
- .select { |directive_pair| directive_pair.last.on.include?(on_what) }
28
-
29
- if applicable_directives.none?
30
- @result = block.call
31
- else
32
- applicable_directives.map do |(ast_directive, directive)|
33
- args = GraphQL::Query::LiteralInput.from_arguments(ast_directive.arguments, directive.arguments, query.variables)
34
- @result = directive.resolve(args, block)
35
- end
36
- @result ||= {}
37
- end
38
- end
39
-
40
- private
41
- def contains_skip?(directives)
42
- directives.any? { |directive| directive.name == 'skip' }
43
- end
44
- end
@@ -1,27 +0,0 @@
1
- require 'pp'
2
- class GraphQL::Repl
3
- def initialize(schema)
4
- @schema = schema
5
- end
6
-
7
- def run
8
- puts "Starting a repl for schema (type 'quit' to exit)"
9
- while line = gets do
10
- if line == "quit\n"
11
- exit
12
- end
13
- execute_query(line)
14
- end
15
- end
16
-
17
- private
18
-
19
- def execute_query(query_string)
20
- begin
21
- query = GraphQL::Query.new(@schema, query_string)
22
- puts JSON.pretty_generate(query.result)
23
- rescue StandardError => err
24
- puts "Couldn't parse: #{err}\n\n" # #{err.backtrace.join("\n")}"
25
- end
26
- end
27
- end
@@ -1,156 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe GraphQL::Language::Transform do
4
- def get_result(query_string, parse: nil, debug: false)
5
- # send parse: :value to do something less than a document
6
- parser = parse ? GraphQL::PARSER.send(parse) : GraphQL::PARSER
7
- raw_tree = parser.parse_with_debug(query_string)
8
- transformed_result = GraphQL::TRANSFORM.apply(raw_tree)
9
- # send debug: true to see parsing & transforming output
10
- if debug
11
- p raw_tree.inspect
12
- p transformed_result.inspect
13
- end
14
- transformed_result
15
- end
16
-
17
- it 'transforms documents' do
18
- query = %|
19
- # you can retrieve data:
20
- query someInfo($var: [Int!] = [1,2,3]) {
21
- me {
22
- name, favorite_food,
23
- ...personInfo
24
- someStuff(vars: [1,2,3])
25
- someOtherStuff(input: {ints: [1,2,3]})
26
- someEmptyStuff(emptyObj: {}, emptySpaceObj: { })
27
- evenMoreStuff(arg: [[1]])
28
- }
29
- }
30
-
31
- # assign fragments:
32
- fragment personInfo on Person {
33
- birthdate, name # with fields
34
- hobbies(names: [])
35
- }
36
-
37
- fragment petInfo on Pet { isHousebroken, species } # all on one line
38
-
39
- # and also mutations
40
- mutation changePetInfo($id: Int = 5, $info: [Dog]) {
41
- changePetName(id: $id, info: $info) {
42
- name,
43
- ... petInfo,
44
- }
45
- }
46
- |
47
- res = get_result(query, debug: false)
48
- assert_equal(4, res.definitions.length)
49
-
50
- res = get_result("{ me {id, birthdate} } # query shorthand")
51
- assert_equal(1, res.definitions.length)
52
- assert_equal("me", res.definitions.first.selections.first.name)
53
- end
54
-
55
- it 'transforms operation definitions' do
56
- res = get_result("query someInfo { a, b, c }", parse: :operation_definition)
57
- assert_equal("query", res.operation_type)
58
- assert_equal("someInfo", res.name)
59
- assert_equal(3, res.selections.length)
60
-
61
- res = get_result(
62
- "mutation changeThings(
63
- $var: Float = 4.5E+6,
64
- $arr: [Int]!
65
- ) @flag, @skip(if: 1) {
66
- changeThings(var: $var) { a,b,c }
67
- }", parse: :operation_definition)
68
- assert_equal("mutation", res.operation_type)
69
- assert_equal("var", res.variables.first.name)
70
- assert_equal("Float", res.variables.first.type.name)
71
- assert_equal(4_500_000.0, res.variables.first.default_value)
72
- assert_equal("arr", res.variables.last.name)
73
- assert_equal(3, res.variables.last.line)
74
- assert_equal(10, res.variables.last.col)
75
- assert_equal("Int", res.variables.last.type.of_type.of_type.name)
76
- assert_equal(2, res.directives.length)
77
- end
78
-
79
- it 'transforms fragment definitions' do
80
- res = get_result("fragment someFields on SomeType @flag1, @flag2 { id, name }", parse: :fragment_definition)
81
- assert_equal("someFields", res.name)
82
- assert_equal("SomeType", res.type)
83
- assert_equal(2, res.directives.length)
84
- assert_equal(2, res.selections.length)
85
- end
86
-
87
- it 'transforms selections' do
88
- res = get_result("{ id, ...petStuff @flag, ... on Pet { isHousebroken }, name }", parse: :selections)
89
- expected_classes = [GraphQL::Language::Nodes::Field, GraphQL::Language::Nodes::FragmentSpread, GraphQL::Language::Nodes::InlineFragment, GraphQL::Language::Nodes::Field]
90
- assert_equal(expected_classes, res.map(&:class))
91
- end
92
-
93
- it 'transforms fields' do
94
- res = get_result(%|best_pals: friends(first: 3, coolnessLevel: SO_COOL, query: {nice: {very: true}}, emptyStr: "")|, parse: :field)
95
- assert_equal(GraphQL::Language::Nodes::Field, res.class)
96
- assert_equal(1, res.line)
97
- assert_equal(1, res.col)
98
- assert_equal("friends", res.name)
99
- assert_equal("best_pals", res.alias)
100
- assert_equal("first", res.arguments[0].name)
101
- assert_equal(3, res.arguments[0].value)
102
- assert_equal("SO_COOL", res.arguments[1].value.name)
103
- assert_equal({"nice" => {"very" => true}}, res.arguments[2].value.to_h)
104
-
105
- res = get_result('me @flag, @include(if: "\"something\"") {name, id}', parse: :field)
106
- assert_equal("me", res.name)
107
- assert_equal(nil, res.alias)
108
- assert_equal(2, res.directives.length)
109
- assert_equal("flag", res.directives.first.name)
110
- assert_equal('"something"', res.directives.last.arguments.first.value)
111
- assert_equal(2, res.selections.length)
112
- end
113
-
114
- it 'transforms input objects' do
115
- res_one_pair = get_result(%q|{one: 1}|, parse: :value_input_object)
116
- res_many_pair = get_result(%q|{first: "Apple", second: "Banana", third: ORANGE}|, parse: :value_input_object)
117
- res_empty = get_result(%q|{}|, parse: :value_input_object)
118
- res_empty_space = get_result(%q|{ }|, parse: :value_input_object)
119
-
120
- assert_equal('one', res_one_pair.arguments[0].name)
121
- assert_equal(1 , res_one_pair.arguments[0].value)
122
-
123
- assert_equal("first" , res_many_pair.arguments[0].name)
124
- assert_equal("Apple" , res_many_pair.arguments[0].value)
125
- assert_equal("second", res_many_pair.arguments[1].name)
126
- assert_equal("Banana", res_many_pair.arguments[1].value)
127
-
128
- assert(res_many_pair.arguments[2].value.is_a?(GraphQL::Language::Nodes::Enum))
129
- assert_equal("third", res_many_pair.arguments[2].name)
130
- assert_equal("ORANGE", res_many_pair.arguments[2].value.name)
131
-
132
- assert_equal([], res_empty.arguments)
133
- assert_equal([], res_empty_space.arguments)
134
- end
135
-
136
- it 'transforms directives' do
137
- res = get_result('@doSomething(vigorously: "\"true\u0025\"")', parse: :directive)
138
- assert_equal("doSomething", res.name, 'gets the name without @')
139
- assert_equal("vigorously", res.arguments.first.name)
140
- assert_equal('"true%"', res.arguments.first.value)
141
-
142
- res = get_result("@someFlag", parse: :directive)
143
- assert_equal("someFlag", res.name)
144
- assert_equal([], res.arguments, 'gets [] if no args')
145
- end
146
-
147
- it 'transforms unnamed operations' do
148
- assert_equal(1, get_result("query { me }").definitions.length)
149
- assert_equal(1, get_result("mutation { touch }").definitions.length)
150
- end
151
-
152
- it 'transforms escaped characters' do
153
- res = get_result("{quoted: \"\\\" \\\\ \\/ \\b \\f \\n \\r \\t\"}", parse: :value_input_object)
154
- assert_equal("\" \\ / \b \f \n \r \t", res.arguments[0].value)
155
- end
156
- end