graphql 1.9.0.pre1 → 1.9.0.pre2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (235) hide show
  1. checksums.yaml +4 -4
  2. data/lib/graphql.rb +5 -1
  3. data/lib/graphql/analysis/ast/analyzer.rb +1 -1
  4. data/lib/graphql/analysis/ast/visitor.rb +6 -1
  5. data/lib/graphql/backwards_compatibility.rb +1 -1
  6. data/lib/graphql/dig.rb +19 -0
  7. data/lib/graphql/directive.rb +13 -1
  8. data/lib/graphql/directive/include_directive.rb +1 -7
  9. data/lib/graphql/directive/skip_directive.rb +1 -8
  10. data/lib/graphql/execution/interpreter.rb +23 -13
  11. data/lib/graphql/execution/interpreter/resolve.rb +56 -0
  12. data/lib/graphql/execution/interpreter/runtime.rb +174 -74
  13. data/lib/graphql/execution/lazy.rb +7 -1
  14. data/lib/graphql/execution/lookahead.rb +71 -6
  15. data/lib/graphql/execution_error.rb +1 -1
  16. data/lib/graphql/introspection/entry_points.rb +5 -1
  17. data/lib/graphql/introspection/type_type.rb +4 -4
  18. data/lib/graphql/language.rb +0 -1
  19. data/lib/graphql/language/block_string.rb +37 -0
  20. data/lib/graphql/language/document_from_schema_definition.rb +1 -1
  21. data/lib/graphql/language/lexer.rb +55 -36
  22. data/lib/graphql/language/lexer.rl +8 -3
  23. data/lib/graphql/language/nodes.rb +27 -4
  24. data/lib/graphql/language/parser.rb +55 -55
  25. data/lib/graphql/language/parser.y +11 -11
  26. data/lib/graphql/language/printer.rb +1 -1
  27. data/lib/graphql/language/visitor.rb +22 -13
  28. data/lib/graphql/literal_validation_error.rb +6 -0
  29. data/lib/graphql/query.rb +13 -0
  30. data/lib/graphql/query/arguments.rb +2 -1
  31. data/lib/graphql/query/context.rb +3 -10
  32. data/lib/graphql/query/executor.rb +1 -1
  33. data/lib/graphql/query/validation_pipeline.rb +1 -1
  34. data/lib/graphql/relay/connection_resolve.rb +1 -1
  35. data/lib/graphql/relay/relation_connection.rb +1 -1
  36. data/lib/graphql/schema.rb +81 -11
  37. data/lib/graphql/schema/argument.rb +1 -1
  38. data/lib/graphql/schema/build_from_definition.rb +2 -4
  39. data/lib/graphql/schema/directive.rb +103 -0
  40. data/lib/graphql/schema/directive/feature.rb +66 -0
  41. data/lib/graphql/schema/directive/include.rb +25 -0
  42. data/lib/graphql/schema/directive/skip.rb +25 -0
  43. data/lib/graphql/schema/directive/transform.rb +48 -0
  44. data/lib/graphql/schema/enum_value.rb +2 -2
  45. data/lib/graphql/schema/field.rb +63 -17
  46. data/lib/graphql/schema/input_object.rb +1 -0
  47. data/lib/graphql/schema/member/base_dsl_methods.rb +4 -2
  48. data/lib/graphql/schema/member/build_type.rb +33 -1
  49. data/lib/graphql/schema/member/has_fields.rb +8 -73
  50. data/lib/graphql/schema/relay_classic_mutation.rb +6 -1
  51. data/lib/graphql/schema/resolver.rb +1 -1
  52. data/lib/graphql/static_validation.rb +2 -1
  53. data/lib/graphql/static_validation/all_rules.rb +1 -0
  54. data/lib/graphql/static_validation/base_visitor.rb +25 -10
  55. data/lib/graphql/static_validation/definition_dependencies.rb +3 -3
  56. data/lib/graphql/static_validation/{message.rb → error.rb} +11 -11
  57. data/lib/graphql/static_validation/interpreter_visitor.rb +14 -0
  58. data/lib/graphql/static_validation/literal_validator.rb +54 -11
  59. data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +34 -5
  60. data/lib/graphql/static_validation/rules/argument_literals_are_compatible_error.rb +31 -0
  61. data/lib/graphql/static_validation/rules/argument_names_are_unique.rb +2 -2
  62. data/lib/graphql/static_validation/rules/argument_names_are_unique_error.rb +30 -0
  63. data/lib/graphql/static_validation/rules/arguments_are_defined.rb +7 -1
  64. data/lib/graphql/static_validation/rules/arguments_are_defined_error.rb +35 -0
  65. data/lib/graphql/static_validation/rules/directives_are_defined.rb +5 -1
  66. data/lib/graphql/static_validation/rules/directives_are_defined_error.rb +29 -0
  67. data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +11 -2
  68. data/lib/graphql/static_validation/rules/directives_are_in_valid_locations_error.rb +31 -0
  69. data/lib/graphql/static_validation/rules/fields_are_defined_on_type.rb +11 -2
  70. data/lib/graphql/static_validation/rules/fields_are_defined_on_type_error.rb +32 -0
  71. data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +14 -2
  72. data/lib/graphql/static_validation/rules/fields_have_appropriate_selections_error.rb +31 -0
  73. data/lib/graphql/static_validation/rules/fields_will_merge.rb +24 -6
  74. data/lib/graphql/static_validation/rules/fields_will_merge_error.rb +32 -0
  75. data/lib/graphql/static_validation/rules/fragment_names_are_unique.rb +5 -1
  76. data/lib/graphql/static_validation/rules/fragment_names_are_unique_error.rb +29 -0
  77. data/lib/graphql/static_validation/rules/fragment_spreads_are_possible.rb +8 -1
  78. data/lib/graphql/static_validation/rules/fragment_spreads_are_possible_error.rb +35 -0
  79. data/lib/graphql/static_validation/rules/fragment_types_exist.rb +5 -1
  80. data/lib/graphql/static_validation/rules/fragment_types_exist_error.rb +29 -0
  81. data/lib/graphql/static_validation/rules/fragments_are_finite.rb +6 -1
  82. data/lib/graphql/static_validation/rules/fragments_are_finite_error.rb +29 -0
  83. data/lib/graphql/static_validation/rules/fragments_are_named.rb +4 -1
  84. data/lib/graphql/static_validation/rules/fragments_are_named_error.rb +26 -0
  85. data/lib/graphql/static_validation/rules/fragments_are_on_composite_types.rb +5 -1
  86. data/lib/graphql/static_validation/rules/fragments_are_on_composite_types_error.rb +30 -0
  87. data/lib/graphql/static_validation/rules/fragments_are_used.rb +13 -3
  88. data/lib/graphql/static_validation/rules/fragments_are_used_error.rb +29 -0
  89. data/lib/graphql/static_validation/rules/mutation_root_exists.rb +4 -1
  90. data/lib/graphql/static_validation/rules/mutation_root_exists_error.rb +26 -0
  91. data/lib/graphql/static_validation/rules/no_definitions_are_present.rb +2 -2
  92. data/lib/graphql/static_validation/rules/no_definitions_are_present_error.rb +25 -0
  93. data/lib/graphql/static_validation/rules/operation_names_are_valid.rb +9 -2
  94. data/lib/graphql/static_validation/rules/operation_names_are_valid_error.rb +28 -0
  95. data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +7 -1
  96. data/lib/graphql/static_validation/rules/required_arguments_are_present_error.rb +35 -0
  97. data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +47 -0
  98. data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present_error.rb +35 -0
  99. data/lib/graphql/static_validation/rules/subscription_root_exists.rb +4 -1
  100. data/lib/graphql/static_validation/rules/subscription_root_exists_error.rb +26 -0
  101. data/lib/graphql/static_validation/rules/unique_directives_per_location.rb +4 -3
  102. data/lib/graphql/static_validation/rules/unique_directives_per_location_error.rb +29 -0
  103. data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +20 -6
  104. data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed_error.rb +39 -0
  105. data/lib/graphql/static_validation/rules/variable_names_are_unique.rb +5 -1
  106. data/lib/graphql/static_validation/rules/variable_names_are_unique_error.rb +29 -0
  107. data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +8 -1
  108. data/lib/graphql/static_validation/rules/variable_usages_are_allowed_error.rb +38 -0
  109. data/lib/graphql/static_validation/rules/variables_are_input_types.rb +12 -2
  110. data/lib/graphql/static_validation/rules/variables_are_input_types_error.rb +32 -0
  111. data/lib/graphql/static_validation/rules/variables_are_used_and_defined.rb +18 -2
  112. data/lib/graphql/static_validation/rules/variables_are_used_and_defined_error.rb +37 -0
  113. data/lib/graphql/static_validation/validator.rb +24 -14
  114. data/lib/graphql/tracing/new_relic_tracing.rb +2 -2
  115. data/lib/graphql/tracing/skylight_tracing.rb +2 -2
  116. data/lib/graphql/unauthorized_field_error.rb +23 -0
  117. data/lib/graphql/version.rb +1 -1
  118. data/spec/graphql/analysis/ast_spec.rb +40 -0
  119. data/spec/graphql/authorization_spec.rb +93 -20
  120. data/spec/graphql/base_type_spec.rb +3 -1
  121. data/spec/graphql/execution/interpreter_spec.rb +127 -4
  122. data/spec/graphql/execution/lazy_spec.rb +49 -0
  123. data/spec/graphql/execution/lookahead_spec.rb +113 -21
  124. data/spec/graphql/execution/multiplex_spec.rb +2 -1
  125. data/spec/graphql/introspection/type_type_spec.rb +1 -1
  126. data/spec/graphql/language/lexer_spec.rb +72 -3
  127. data/spec/graphql/language/printer_spec.rb +18 -6
  128. data/spec/graphql/query/arguments_spec.rb +21 -0
  129. data/spec/graphql/query/context_spec.rb +10 -0
  130. data/spec/graphql/schema/build_from_definition_spec.rb +144 -29
  131. data/spec/graphql/schema/directive/feature_spec.rb +81 -0
  132. data/spec/graphql/schema/directive/transform_spec.rb +39 -0
  133. data/spec/graphql/schema/enum_spec.rb +5 -3
  134. data/spec/graphql/schema/field_extension_spec.rb +3 -3
  135. data/spec/graphql/schema/field_spec.rb +19 -0
  136. data/spec/graphql/schema/input_object_spec.rb +81 -0
  137. data/spec/graphql/schema/member/build_type_spec.rb +46 -0
  138. data/spec/graphql/schema/member/scoped_spec.rb +3 -3
  139. data/spec/graphql/schema/printer_spec.rb +244 -96
  140. data/spec/graphql/schema/relay_classic_mutation_spec.rb +26 -0
  141. data/spec/graphql/schema/resolver_spec.rb +1 -1
  142. data/spec/graphql/schema/warden_spec.rb +35 -11
  143. data/spec/graphql/static_validation/rules/argument_literals_are_compatible_spec.rb +212 -72
  144. data/spec/graphql/static_validation/rules/argument_names_are_unique_spec.rb +2 -2
  145. data/spec/graphql/static_validation/rules/arguments_are_defined_spec.rb +72 -29
  146. data/spec/graphql/static_validation/rules/directives_are_defined_spec.rb +4 -2
  147. data/spec/graphql/static_validation/rules/directives_are_in_valid_locations_spec.rb +4 -2
  148. data/spec/graphql/static_validation/rules/fields_are_defined_on_type_spec.rb +10 -5
  149. data/spec/graphql/static_validation/rules/fields_have_appropriate_selections_spec.rb +10 -5
  150. data/spec/graphql/static_validation/rules/fields_will_merge_spec.rb +2 -1
  151. data/spec/graphql/static_validation/rules/fragment_names_are_unique_spec.rb +2 -1
  152. data/spec/graphql/static_validation/rules/fragment_spreads_are_possible_spec.rb +6 -3
  153. data/spec/graphql/static_validation/rules/fragment_types_exist_spec.rb +4 -2
  154. data/spec/graphql/static_validation/rules/fragments_are_finite_spec.rb +4 -2
  155. data/spec/graphql/static_validation/rules/fragments_are_named_spec.rb +2 -1
  156. data/spec/graphql/static_validation/rules/fragments_are_on_composite_types_spec.rb +6 -3
  157. data/spec/graphql/static_validation/rules/fragments_are_used_spec.rb +22 -2
  158. data/spec/graphql/static_validation/rules/mutation_root_exists_spec.rb +2 -1
  159. data/spec/graphql/static_validation/rules/operation_names_are_valid_spec.rb +6 -3
  160. data/spec/graphql/static_validation/rules/required_arguments_are_present_spec.rb +13 -4
  161. data/spec/graphql/static_validation/rules/required_input_object_attributes_are_present_spec.rb +58 -0
  162. data/spec/graphql/static_validation/rules/subscription_root_exists_spec.rb +2 -1
  163. data/spec/graphql/static_validation/rules/unique_directives_per_location_spec.rb +14 -7
  164. data/spec/graphql/static_validation/rules/variable_default_values_are_correctly_typed_spec.rb +14 -7
  165. data/spec/graphql/static_validation/rules/variable_usages_are_allowed_spec.rb +8 -4
  166. data/spec/graphql/static_validation/rules/variables_are_input_types_spec.rb +8 -4
  167. data/spec/graphql/static_validation/rules/variables_are_used_and_defined_spec.rb +6 -3
  168. data/spec/graphql/static_validation/validator_spec.rb +6 -4
  169. data/spec/graphql/tracing/new_relic_tracing_spec.rb +10 -0
  170. data/spec/graphql/tracing/skylight_tracing_spec.rb +10 -0
  171. data/spec/graphql/types/iso_8601_date_time_spec.rb +1 -2
  172. data/spec/integration/mongoid/star_trek/schema.rb +5 -5
  173. data/spec/integration/rails/graphql/relay/relation_connection_spec.rb +37 -8
  174. data/spec/integration/rails/graphql/schema_spec.rb +2 -2
  175. data/spec/integration/rails/spec_helper.rb +10 -0
  176. data/spec/integration/tmp/app/graphql/types/bird_type.rb +7 -0
  177. data/spec/integration/tmp/dummy/Gemfile +45 -0
  178. data/spec/integration/tmp/dummy/README.rdoc +28 -0
  179. data/spec/integration/tmp/dummy/Rakefile +6 -0
  180. data/spec/integration/tmp/dummy/app/assets/javascripts/application.js +16 -0
  181. data/spec/integration/tmp/dummy/app/assets/stylesheets/application.css +15 -0
  182. data/spec/integration/tmp/dummy/app/controllers/application_controller.rb +5 -0
  183. data/spec/integration/tmp/dummy/app/controllers/graphql_controller.rb +43 -0
  184. data/spec/integration/tmp/dummy/app/graphql/dummy_schema.rb +34 -0
  185. data/spec/integration/tmp/dummy/app/graphql/types/base_enum.rb +4 -0
  186. data/spec/integration/tmp/dummy/app/graphql/types/base_input_object.rb +4 -0
  187. data/spec/integration/tmp/dummy/app/graphql/types/base_interface.rb +5 -0
  188. data/spec/integration/tmp/dummy/app/graphql/types/base_object.rb +4 -0
  189. data/spec/integration/tmp/dummy/app/graphql/types/base_scalar.rb +4 -0
  190. data/spec/integration/tmp/dummy/app/graphql/types/base_union.rb +4 -0
  191. data/spec/integration/tmp/dummy/app/graphql/types/mutation_type.rb +10 -0
  192. data/spec/integration/tmp/dummy/app/graphql/types/query_type.rb +15 -0
  193. data/spec/integration/tmp/dummy/app/helpers/application_helper.rb +2 -0
  194. data/spec/integration/tmp/dummy/app/views/layouts/application.html.erb +14 -0
  195. data/spec/integration/tmp/dummy/bin/bundle +3 -0
  196. data/spec/integration/tmp/dummy/bin/rails +4 -0
  197. data/spec/integration/tmp/dummy/bin/rake +4 -0
  198. data/spec/integration/tmp/dummy/bin/setup +29 -0
  199. data/spec/integration/tmp/dummy/config.ru +4 -0
  200. data/spec/integration/tmp/dummy/config/application.rb +32 -0
  201. data/spec/integration/tmp/dummy/config/boot.rb +3 -0
  202. data/spec/integration/tmp/dummy/config/environment.rb +5 -0
  203. data/spec/integration/tmp/dummy/config/environments/development.rb +38 -0
  204. data/spec/integration/tmp/dummy/config/environments/production.rb +76 -0
  205. data/spec/integration/tmp/dummy/config/environments/test.rb +42 -0
  206. data/spec/integration/tmp/dummy/config/initializers/assets.rb +11 -0
  207. data/spec/integration/tmp/dummy/config/initializers/backtrace_silencers.rb +7 -0
  208. data/spec/integration/tmp/dummy/config/initializers/cookies_serializer.rb +3 -0
  209. data/spec/integration/tmp/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  210. data/spec/integration/tmp/dummy/config/initializers/inflections.rb +16 -0
  211. data/spec/integration/tmp/dummy/config/initializers/mime_types.rb +4 -0
  212. data/spec/integration/tmp/dummy/config/initializers/session_store.rb +3 -0
  213. data/spec/integration/tmp/dummy/config/initializers/to_time_preserves_timezone.rb +10 -0
  214. data/spec/integration/tmp/dummy/config/initializers/wrap_parameters.rb +9 -0
  215. data/spec/integration/tmp/dummy/config/locales/en.yml +23 -0
  216. data/spec/integration/tmp/dummy/config/routes.rb +61 -0
  217. data/spec/integration/tmp/dummy/config/secrets.yml +22 -0
  218. data/spec/integration/tmp/dummy/db/seeds.rb +7 -0
  219. data/spec/integration/tmp/dummy/public/404.html +67 -0
  220. data/spec/integration/tmp/dummy/public/422.html +67 -0
  221. data/spec/integration/tmp/dummy/public/500.html +66 -0
  222. data/spec/integration/tmp/dummy/public/favicon.ico +0 -0
  223. data/spec/integration/tmp/dummy/public/robots.txt +5 -0
  224. data/spec/support/dummy/schema.rb +2 -2
  225. data/spec/support/error_bubbling_helpers.rb +23 -0
  226. data/spec/support/jazz.rb +53 -6
  227. data/spec/support/lazy_helpers.rb +26 -8
  228. data/spec/support/new_relic.rb +3 -0
  229. data/spec/support/skylight.rb +3 -0
  230. data/spec/support/star_wars/schema.rb +13 -9
  231. data/spec/support/static_validation_helpers.rb +3 -1
  232. metadata +145 -22
  233. data/lib/graphql/language/comments.rb +0 -45
  234. data/spec/graphql/schema/member/has_fields_spec.rb +0 -132
  235. data/spec/integration/tmp/app/graphql/types/family_type.rb +0 -9
@@ -60,37 +60,114 @@ type Hello {
60
60
  build_schema_and_compare_output(schema.chop)
61
61
  end
62
62
 
63
- it 'supports descriptions' do
63
+ it 'supports descriptions and definition_line' do
64
64
  schema = <<-SCHEMA
65
65
  schema {
66
66
  query: Hello
67
67
  }
68
68
 
69
- # This is a directive
69
+ """
70
+ This is a directive
71
+ """
70
72
  directive @foo(
71
- # It has an argument
73
+ """
74
+ It has an argument
75
+ """
72
76
  arg: Int
73
77
  ) on FIELD
74
78
 
75
- # With an enum
79
+ """
80
+ With an enum
81
+ """
76
82
  enum Color {
77
83
  BLUE
78
84
 
79
- # Not a creative color
85
+ """
86
+ Not a creative color
87
+ """
80
88
  GREEN
81
89
  RED
82
90
  }
83
91
 
84
- # What a great type
85
- type Hello {
86
- anEnum: Color
92
+ """
93
+ What a great type
94
+ """
95
+ type Hello implements I {
96
+ anEnum(s: S): Color
87
97
 
88
- # And a field to boot
89
- str: String
98
+ """
99
+ And a field to boot
100
+ """
101
+ str(i: Input): String
102
+ }
103
+
104
+ """
105
+ An interface
106
+ """
107
+ interface I {
108
+ str(i: Input): String
90
109
  }
110
+
111
+ """
112
+ And an Input
113
+ """
114
+ input Input {
115
+ s: String
116
+ }
117
+
118
+ """
119
+ A scalar
120
+ """
121
+ scalar S
122
+
123
+ """
124
+ And a union
125
+ """
126
+ union U = Hello
91
127
  SCHEMA
92
128
 
93
129
  build_schema_and_compare_output(schema.chop)
130
+
131
+ built_schema = GraphQL::Schema.from_definition(schema)
132
+ # The schema's are the same since there's no description
133
+ assert_equal 1, built_schema.ast_node.line
134
+ assert_equal 1, built_schema.ast_node.definition_line
135
+
136
+ # These account for description:
137
+ assert_equal 5, built_schema.directives["foo"].ast_node.line, "The ast_node.line points to the description"
138
+ assert_equal 8, built_schema.directives["foo"].ast_node.definition_line, "The ast_node.definition_line points to the definition"
139
+
140
+ arg = built_schema.directives["foo"].arguments["arg"]
141
+ assert_equal 9, arg.ast_node.line
142
+ assert_equal 12, arg.ast_node.definition_line
143
+
144
+ enum_type = built_schema.types["Color"]
145
+ assert_equal 15, enum_type.ast_node.line, "The ast_node.line points to the description"
146
+ assert_equal 18, enum_type.ast_node.definition_line, "The ast_node.definition_line points to the definition"
147
+
148
+ enum_value = enum_type.values["GREEN"]
149
+ assert_equal 21, enum_value.ast_node.line
150
+ assert_equal 24, enum_value.ast_node.definition_line
151
+
152
+ obj_type = built_schema.types["Hello"]
153
+ assert_equal 28, obj_type.ast_node.line, "The ast_node.line points to the description"
154
+ assert_equal 31, obj_type.ast_node.definition_line, "The ast_node.definition_line points to the definition"
155
+
156
+ field = obj_type.fields["str"]
157
+ assert_equal 34, field.ast_node.line
158
+ assert_equal 37, field.ast_node.definition_line
159
+
160
+ assert_equal 40, built_schema.types["I"].ast_node.line
161
+ assert_equal 43, built_schema.types["I"].ast_node.definition_line
162
+
163
+ assert_equal 47, built_schema.types["Input"].ast_node.line
164
+ assert_equal 50, built_schema.types["Input"].ast_node.definition_line
165
+
166
+ assert_equal 54, built_schema.types["S"].ast_node.line
167
+ assert_equal 57, built_schema.types["S"].ast_node.definition_line
168
+
169
+ assert_equal 59, built_schema.types["U"].ast_node.line
170
+ assert_equal 62, built_schema.types["U"].ast_node.definition_line
94
171
  end
95
172
 
96
173
  it 'maintains built-in directives' do
@@ -233,64 +310,102 @@ type Organization {
233
310
  email: String
234
311
  }
235
312
 
236
- # The connection type for Organization.
313
+ """
314
+ The connection type for Organization.
315
+ """
237
316
  type OrganizationConnection {
238
- # A list of edges.
317
+ """
318
+ A list of edges.
319
+ """
239
320
  edges: [OrganizationEdge]
240
321
 
241
- # A list of nodes.
322
+ """
323
+ A list of nodes.
324
+ """
242
325
  nodes: [Organization]
243
326
 
244
- # Information to aid in pagination.
327
+ """
328
+ Information to aid in pagination.
329
+ """
245
330
  pageInfo: PageInfo!
246
331
 
247
- # Identifies the total count of items in the connection.
332
+ """
333
+ Identifies the total count of items in the connection.
334
+ """
248
335
  totalCount: Int!
249
336
  }
250
337
 
251
- # An edge in a connection.
338
+ """
339
+ An edge in a connection.
340
+ """
252
341
  type OrganizationEdge {
253
- # A cursor for use in pagination.
342
+ """
343
+ A cursor for use in pagination.
344
+ """
254
345
  cursor: String!
255
346
 
256
- # The item at the end of the edge.
347
+ """
348
+ The item at the end of the edge.
349
+ """
257
350
  node: Organization
258
351
  }
259
352
 
260
- # Information about pagination in a connection.
353
+ """
354
+ Information about pagination in a connection.
355
+ """
261
356
  type PageInfo {
262
- # When paginating forwards, the cursor to continue.
357
+ """
358
+ When paginating forwards, the cursor to continue.
359
+ """
263
360
  endCursor: String
264
361
 
265
- # When paginating forwards, are there more items?
362
+ """
363
+ When paginating forwards, are there more items?
364
+ """
266
365
  hasNextPage: Boolean!
267
366
 
268
- # When paginating backwards, are there more items?
367
+ """
368
+ When paginating backwards, are there more items?
369
+ """
269
370
  hasPreviousPage: Boolean!
270
371
 
271
- # When paginating backwards, the cursor to continue.
372
+ """
373
+ When paginating backwards, the cursor to continue.
374
+ """
272
375
  startCursor: String
273
376
  }
274
377
 
275
378
  type Type {
276
379
  name: String
277
380
  organization(
278
- # The login of the organization to find.
381
+ """
382
+ The login of the organization to find.
383
+ """
279
384
  login: String!
280
385
  ): Organization
281
386
 
282
- # A list of organizations the user belongs to.
387
+ """
388
+ A list of organizations the user belongs to.
389
+ """
283
390
  organizations(
284
- # Returns the elements in the list that come after the specified cursor.
391
+ """
392
+ Returns the elements in the list that come after the specified cursor.
393
+ """
285
394
  after: String
286
395
 
287
- # Returns the elements in the list that come before the specified cursor.
396
+ """
397
+ Returns the elements in the list that come before the specified cursor.
398
+ """
288
399
  before: String
289
400
 
290
- # Returns the first _n_ elements from the list.
401
+ """
402
+ Returns the first _n_ elements from the list.
403
+ """
291
404
  first: Int
292
405
 
293
- # Returns the last _n_ elements from the list.
406
+ """
407
+ Returns the last _n_ elements from the list.
408
+ """
294
409
  last: Int
295
410
  ): OrganizationConnection!
296
411
  }
@@ -0,0 +1,81 @@
1
+ # frozen_string_literal: true
2
+ require "spec_helper"
3
+
4
+ describe GraphQL::Schema::Directive::Feature do
5
+ class FeatureSchema < GraphQL::Schema
6
+ class Feature < GraphQL::Schema::Directive::Feature
7
+ def self.enabled?(flag_name, obj, ctx)
8
+ !!ctx[flag_name.to_sym]
9
+ end
10
+ end
11
+
12
+ class Query < GraphQL::Schema::Object
13
+ field :int, Integer, null: false
14
+
15
+ def int
16
+ context[:int] ||= 0
17
+ context[:int] += 1
18
+ end
19
+ end
20
+
21
+ directive(Feature)
22
+ query(Query)
23
+ # only supported by the interpreter
24
+ use GraphQL::Execution::Interpreter
25
+ use GraphQL::Analysis::AST
26
+ end
27
+
28
+
29
+ it "skips or runs fields" do
30
+ str = '{
31
+ int1: int
32
+ int2: int @feature(flag: "flag1")
33
+ int3: int @feature(flag: "flag2")
34
+ }'
35
+
36
+ res = FeatureSchema.execute(str, context: { flag2: true })
37
+ # Int2 was not called, so `int3` is actually 2
38
+ assert_equal({"int1" => 1, "int3" => 2}, res["data"])
39
+ end
40
+
41
+ it "skips or runs fragment spreads" do
42
+ str = '{
43
+ ...F1
44
+ ...F2 @feature(flag: "flag1")
45
+ ...F3 @feature(flag: "flag2")
46
+ int4: int
47
+ }
48
+
49
+ fragment F1 on Query { int1: int }
50
+ fragment F2 on Query { int2: int }
51
+ fragment F3 on Query { int3: int }
52
+ '
53
+
54
+ res = FeatureSchema.execute(str, context: { flag1: true })
55
+ # `int3` was skipped
56
+ assert_equal({"int1" => 1, "int2" => 2, "int4" => 3}, res["data"])
57
+ end
58
+ it "skips or runs inline fragments" do
59
+ str = '{
60
+ ... { int1: int }
61
+ ... @feature(flag: "flag1") { int2: int }
62
+ ... @feature(flag: "flag2") { int3: int }
63
+ int4: int
64
+ }
65
+ '
66
+
67
+ res = FeatureSchema.execute(str, context: { flag2: true })
68
+ # `int2` was skipped
69
+ assert_equal({"int1" => 1, "int3" => 2, "int4" => 3}, res["data"])
70
+ end
71
+
72
+ it "returns an error if it's in the wrong place" do
73
+ str = '
74
+ query @feature(flag: "x") {
75
+ int
76
+ }
77
+ '
78
+ res = FeatureSchema.execute(str)
79
+ assert_equal ["'@feature' can't be applied to queries (allowed: fields, fragment spreads, inline fragments)"], res["errors"].map { |e| e["message"] }
80
+ end
81
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+ require "spec_helper"
3
+
4
+ describe GraphQL::Schema::Directive::Transform do
5
+ class TransformSchema < GraphQL::Schema
6
+ class Query < GraphQL::Schema::Object
7
+ field :echo, String, null: false do
8
+ argument :input, String, required: true
9
+ end
10
+
11
+ def echo(input:)
12
+ input
13
+ end
14
+ end
15
+
16
+ directive(GraphQL::Schema::Directive::Transform)
17
+
18
+ query(Query)
19
+ # only supported by the interpreter
20
+ use GraphQL::Execution::Interpreter
21
+ use GraphQL::Analysis::AST
22
+ end
23
+
24
+ it "transforms when applicable" do
25
+ str = '{
26
+ normal: echo(input: "Hello")
27
+ upcased: echo(input: "Hello") @transform(by: "upcase")
28
+ downcased: echo(input: "Hello") @transform(by: "downcase")
29
+ nonsense: echo(input: "Hello") @transform(by: "nonsense")
30
+ }'
31
+
32
+ res = TransformSchema.execute(str)
33
+
34
+ assert_equal "Hello", res["data"]["normal"]
35
+ assert_equal "HELLO", res["data"]["upcased"]
36
+ assert_equal "hello", res["data"]["downcased"]
37
+ assert_equal "Hello", res["data"]["nonsense"]
38
+ end
39
+ end
@@ -14,7 +14,7 @@ describe GraphQL::Schema::Enum do
14
14
  it "tells about the definition" do
15
15
  assert_equal "Family", enum.graphql_name
16
16
  assert_equal 29, enum.description.length
17
- assert_equal 6, enum.values.size
17
+ assert_equal 7, enum.values.size
18
18
  end
19
19
 
20
20
  it "inherits values and description" do
@@ -26,8 +26,8 @@ describe GraphQL::Schema::Enum do
26
26
  # Description was inherited
27
27
  assert_equal 29, new_enum.description.length
28
28
  # values were inherited without modifying the parent
29
- assert_equal 6, enum.values.size
30
- assert_equal 7, new_enum.values.size
29
+ assert_equal 7, enum.values.size
30
+ assert_equal 8, new_enum.values.size
31
31
  perc_value = new_enum.values["PERCUSSION"]
32
32
  assert_equal "new description", perc_value.description
33
33
  end
@@ -56,8 +56,10 @@ describe GraphQL::Schema::Enum do
56
56
 
57
57
  string_val = enum_type.values["STRING"]
58
58
  didg_val = enum_type.values["DIDGERIDOO"]
59
+ silence_val = enum_type.values["SILENCE"]
59
60
  assert_equal "STRING", string_val.name
60
61
  assert_equal :str, string_val.value
62
+ assert_equal false, silence_val.value
61
63
  assert_equal "DIDGERIDOO", didg_val.name
62
64
  assert_equal "Merged into BRASS", didg_val.deprecation_reason
63
65
  end
@@ -34,7 +34,7 @@ describe GraphQL::Schema::FieldExtension do
34
34
  end
35
35
 
36
36
  class Query < BaseObject
37
- field :doubled, Integer, null: false, method: :pass_thru do
37
+ field :doubled, Integer, null: false, resolver_method: :pass_thru do
38
38
  extension(DoubleFilter)
39
39
  argument :input, Integer, required: true
40
40
  end
@@ -43,12 +43,12 @@ describe GraphQL::Schema::FieldExtension do
43
43
  input # return it as-is, it will be modified by extensions
44
44
  end
45
45
 
46
- field :trippled_by_option, Integer, null: false, method: :pass_thru do
46
+ field :trippled_by_option, Integer, null: false, resolver_method: :pass_thru do
47
47
  extension(MultiplyByOption, factor: 3)
48
48
  argument :input, Integer, required: true
49
49
  end
50
50
 
51
- field :multiply_input, Integer, null: false, method: :pass_thru, extensions: [MultiplyByArgument] do
51
+ field :multiply_input, Integer, null: false, resolver_method: :pass_thru, extensions: [MultiplyByArgument] do
52
52
  argument :input, Integer, required: true
53
53
  end
54
54
  end
@@ -45,6 +45,12 @@ describe GraphQL::Schema::Field do
45
45
  assert_equal 'underscored_arg', arg_defn.name
46
46
  end
47
47
 
48
+ it "works with arbitrary hash keys" do
49
+ result = Jazz::Schema.execute "{ complexHashKey }", root_value: { :'foo bar/fizz-buzz' => "OK!"}
50
+ hash_val = result["data"]["complexHashKey"]
51
+ assert_equal "OK!", hash_val, "It looked up the hash key"
52
+ end
53
+
48
54
  it "exposes the method override" do
49
55
  object = Class.new(Jazz::BaseObject) do
50
56
  field :t, String, method: :tt, null: true
@@ -279,4 +285,17 @@ describe GraphQL::Schema::Field do
279
285
  assert_equal "Broken!!", field.deprecation_reason
280
286
  end
281
287
  end
288
+
289
+ describe "#original_name" do
290
+ it "is exactly the same as the passed in name" do
291
+ field = GraphQL::Schema::Field.from_options(
292
+ :my_field,
293
+ String,
294
+ null: false,
295
+ camelize: true
296
+ )
297
+
298
+ assert_equal :my_field, field.original_name
299
+ end
300
+ end
282
301
  end