graphql 1.2.6 → 1.3.0

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 (278) hide show
  1. checksums.yaml +4 -4
  2. data/lib/graphql.rb +3 -1
  3. data/lib/graphql/analysis.rb +1 -0
  4. data/lib/graphql/analysis/analyze_query.rb +1 -0
  5. data/lib/graphql/analysis/field_usage.rb +1 -0
  6. data/lib/graphql/analysis/max_query_complexity.rb +1 -0
  7. data/lib/graphql/analysis/max_query_depth.rb +1 -0
  8. data/lib/graphql/analysis/query_complexity.rb +1 -0
  9. data/lib/graphql/analysis/query_depth.rb +1 -0
  10. data/lib/graphql/analysis/reducer_state.rb +1 -0
  11. data/lib/graphql/analysis_error.rb +1 -0
  12. data/lib/graphql/argument.rb +1 -0
  13. data/lib/graphql/base_type.rb +16 -7
  14. data/lib/graphql/boolean_type.rb +1 -0
  15. data/lib/graphql/compatibility.rb +2 -0
  16. data/lib/graphql/compatibility/execution_specification.rb +113 -192
  17. data/lib/graphql/compatibility/execution_specification/counter_schema.rb +53 -0
  18. data/lib/graphql/compatibility/execution_specification/specification_schema.rb +195 -0
  19. data/lib/graphql/compatibility/lazy_execution_specification.rb +186 -0
  20. data/lib/graphql/compatibility/lazy_execution_specification/lazy_schema.rb +97 -0
  21. data/lib/graphql/compatibility/query_parser_specification.rb +1 -0
  22. data/lib/graphql/compatibility/query_parser_specification/parse_error_specification.rb +1 -0
  23. data/lib/graphql/compatibility/query_parser_specification/query_assertions.rb +1 -0
  24. data/lib/graphql/compatibility/schema_parser_specification.rb +1 -0
  25. data/lib/graphql/define.rb +1 -0
  26. data/lib/graphql/define/assign_argument.rb +1 -0
  27. data/lib/graphql/define/assign_connection.rb +1 -0
  28. data/lib/graphql/define/assign_enum_value.rb +1 -0
  29. data/lib/graphql/define/assign_global_id_field.rb +1 -0
  30. data/lib/graphql/define/assign_object_field.rb +1 -0
  31. data/lib/graphql/define/defined_object_proxy.rb +1 -0
  32. data/lib/graphql/define/instance_definable.rb +11 -12
  33. data/lib/graphql/define/non_null_with_bang.rb +1 -0
  34. data/lib/graphql/define/type_definer.rb +1 -0
  35. data/lib/graphql/directive.rb +1 -0
  36. data/lib/graphql/directive/deprecated_directive.rb +1 -0
  37. data/lib/graphql/directive/include_directive.rb +1 -0
  38. data/lib/graphql/directive/skip_directive.rb +1 -0
  39. data/lib/graphql/enum_type.rb +8 -1
  40. data/lib/graphql/execution.rb +5 -0
  41. data/lib/graphql/execution/directive_checks.rb +1 -0
  42. data/lib/graphql/execution/execute.rb +222 -0
  43. data/lib/graphql/execution/field_result.rb +52 -0
  44. data/lib/graphql/execution/lazy.rb +59 -0
  45. data/lib/graphql/execution/lazy/lazy_method_map.rb +38 -0
  46. data/lib/graphql/execution/lazy/resolve.rb +68 -0
  47. data/lib/graphql/execution/selection_result.rb +84 -0
  48. data/lib/graphql/execution/typecast.rb +4 -4
  49. data/lib/graphql/execution_error.rb +1 -0
  50. data/lib/graphql/field.rb +68 -18
  51. data/lib/graphql/field/resolve.rb +1 -0
  52. data/lib/graphql/float_type.rb +1 -0
  53. data/lib/graphql/id_type.rb +1 -0
  54. data/lib/graphql/input_object_type.rb +6 -0
  55. data/lib/graphql/int_type.rb +1 -0
  56. data/lib/graphql/interface_type.rb +6 -0
  57. data/lib/graphql/internal_representation.rb +2 -1
  58. data/lib/graphql/internal_representation/node.rb +2 -1
  59. data/lib/graphql/internal_representation/rewrite.rb +1 -0
  60. data/lib/graphql/internal_representation/selection.rb +85 -0
  61. data/lib/graphql/introspection.rb +1 -0
  62. data/lib/graphql/introspection/arguments_field.rb +1 -0
  63. data/lib/graphql/introspection/directive_location_enum.rb +1 -0
  64. data/lib/graphql/introspection/directive_type.rb +1 -0
  65. data/lib/graphql/introspection/enum_value_type.rb +1 -0
  66. data/lib/graphql/introspection/enum_values_field.rb +1 -0
  67. data/lib/graphql/introspection/field_type.rb +1 -0
  68. data/lib/graphql/introspection/fields_field.rb +1 -0
  69. data/lib/graphql/introspection/input_fields_field.rb +1 -0
  70. data/lib/graphql/introspection/input_value_type.rb +2 -1
  71. data/lib/graphql/introspection/interfaces_field.rb +1 -0
  72. data/lib/graphql/introspection/introspection_query.rb +1 -0
  73. data/lib/graphql/introspection/of_type_field.rb +1 -0
  74. data/lib/graphql/introspection/possible_types_field.rb +1 -0
  75. data/lib/graphql/introspection/schema_field.rb +1 -0
  76. data/lib/graphql/introspection/schema_type.rb +1 -0
  77. data/lib/graphql/introspection/type_by_name_field.rb +1 -0
  78. data/lib/graphql/introspection/type_kind_enum.rb +1 -0
  79. data/lib/graphql/introspection/type_type.rb +1 -0
  80. data/lib/graphql/introspection/typename_field.rb +1 -0
  81. data/lib/graphql/invalid_null_error.rb +17 -7
  82. data/lib/graphql/language.rb +10 -0
  83. data/lib/graphql/language/comments.rb +2 -1
  84. data/lib/graphql/language/definition_slice.rb +1 -0
  85. data/lib/graphql/language/generation.rb +25 -24
  86. data/lib/graphql/language/nodes.rb +1 -0
  87. data/lib/graphql/language/token.rb +1 -0
  88. data/lib/graphql/language/visitor.rb +1 -0
  89. data/lib/graphql/list_type.rb +1 -0
  90. data/lib/graphql/non_null_type.rb +2 -1
  91. data/lib/graphql/object_type.rb +12 -0
  92. data/lib/graphql/query.rb +40 -43
  93. data/lib/graphql/query/arguments.rb +1 -0
  94. data/lib/graphql/query/context.rb +31 -7
  95. data/lib/graphql/query/executor.rb +8 -1
  96. data/lib/graphql/query/input_validation_result.rb +1 -0
  97. data/lib/graphql/query/literal_input.rb +1 -0
  98. data/lib/graphql/query/serial_execution.rb +3 -4
  99. data/lib/graphql/query/serial_execution/field_resolution.rb +15 -10
  100. data/lib/graphql/query/serial_execution/operation_resolution.rb +3 -5
  101. data/lib/graphql/query/serial_execution/selection_resolution.rb +4 -5
  102. data/lib/graphql/query/serial_execution/value_resolution.rb +26 -11
  103. data/lib/graphql/query/variable_validation_error.rb +1 -0
  104. data/lib/graphql/query/variables.rb +1 -0
  105. data/lib/graphql/relay.rb +1 -0
  106. data/lib/graphql/relay/array_connection.rb +3 -2
  107. data/lib/graphql/relay/base_connection.rb +20 -8
  108. data/lib/graphql/relay/connection_field.rb +1 -0
  109. data/lib/graphql/relay/connection_resolve.rb +14 -1
  110. data/lib/graphql/relay/connection_type.rb +1 -0
  111. data/lib/graphql/relay/edge.rb +1 -0
  112. data/lib/graphql/relay/edge_type.rb +1 -0
  113. data/lib/graphql/relay/global_id_resolve.rb +1 -0
  114. data/lib/graphql/relay/mutation.rb +13 -0
  115. data/lib/graphql/relay/node.rb +1 -0
  116. data/lib/graphql/relay/page_info.rb +1 -0
  117. data/lib/graphql/relay/relation_connection.rb +3 -2
  118. data/lib/graphql/runtime_type_error.rb +4 -0
  119. data/lib/graphql/scalar_type.rb +2 -1
  120. data/lib/graphql/schema.rb +116 -26
  121. data/lib/graphql/schema/base_64_encoder.rb +14 -0
  122. data/lib/graphql/schema/build_from_definition.rb +4 -0
  123. data/lib/graphql/schema/catchall_middleware.rb +1 -0
  124. data/lib/graphql/schema/default_type_error.rb +15 -0
  125. data/lib/graphql/schema/instrumented_field_map.rb +1 -0
  126. data/lib/graphql/schema/invalid_type_error.rb +1 -0
  127. data/lib/graphql/schema/loader.rb +5 -1
  128. data/lib/graphql/schema/middleware_chain.rb +1 -0
  129. data/lib/graphql/schema/possible_types.rb +1 -0
  130. data/lib/graphql/schema/printer.rb +3 -2
  131. data/lib/graphql/schema/reduce_types.rb +1 -0
  132. data/lib/graphql/schema/rescue_middleware.rb +3 -2
  133. data/lib/graphql/schema/timeout_middleware.rb +1 -0
  134. data/lib/graphql/schema/type_expression.rb +1 -0
  135. data/lib/graphql/schema/type_map.rb +1 -0
  136. data/lib/graphql/schema/unique_within_type.rb +1 -0
  137. data/lib/graphql/schema/validation.rb +57 -1
  138. data/lib/graphql/schema/warden.rb +1 -0
  139. data/lib/graphql/static_validation.rb +1 -0
  140. data/lib/graphql/static_validation/all_rules.rb +1 -0
  141. data/lib/graphql/static_validation/arguments_validator.rb +1 -0
  142. data/lib/graphql/static_validation/literal_validator.rb +1 -0
  143. data/lib/graphql/static_validation/message.rb +1 -0
  144. data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +1 -0
  145. data/lib/graphql/static_validation/rules/arguments_are_defined.rb +1 -0
  146. data/lib/graphql/static_validation/rules/directives_are_defined.rb +1 -0
  147. data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +1 -0
  148. data/lib/graphql/static_validation/rules/fields_are_defined_on_type.rb +1 -0
  149. data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +1 -0
  150. data/lib/graphql/static_validation/rules/fields_will_merge.rb +6 -3
  151. data/lib/graphql/static_validation/rules/fragment_spreads_are_possible.rb +1 -0
  152. data/lib/graphql/static_validation/rules/fragment_types_exist.rb +1 -0
  153. data/lib/graphql/static_validation/rules/fragments_are_finite.rb +1 -0
  154. data/lib/graphql/static_validation/rules/fragments_are_named.rb +1 -0
  155. data/lib/graphql/static_validation/rules/fragments_are_on_composite_types.rb +1 -0
  156. data/lib/graphql/static_validation/rules/fragments_are_used.rb +1 -0
  157. data/lib/graphql/static_validation/rules/mutation_root_exists.rb +1 -0
  158. data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +1 -0
  159. data/lib/graphql/static_validation/rules/subscription_root_exists.rb +1 -0
  160. data/lib/graphql/static_validation/rules/unique_directives_per_location.rb +1 -0
  161. data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +1 -0
  162. data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +1 -0
  163. data/lib/graphql/static_validation/rules/variables_are_input_types.rb +1 -0
  164. data/lib/graphql/static_validation/rules/variables_are_used_and_defined.rb +1 -0
  165. data/lib/graphql/static_validation/type_stack.rb +1 -0
  166. data/lib/graphql/static_validation/validation_context.rb +2 -1
  167. data/lib/graphql/static_validation/validator.rb +2 -1
  168. data/lib/graphql/string_type.rb +1 -0
  169. data/lib/graphql/type_kinds.rb +1 -0
  170. data/lib/graphql/union_type.rb +13 -0
  171. data/lib/graphql/unresolved_type_error.rb +26 -5
  172. data/lib/graphql/version.rb +2 -1
  173. data/readme.md +1 -5
  174. data/spec/graphql/analysis/analyze_query_spec.rb +1 -0
  175. data/spec/graphql/analysis/field_usage_spec.rb +1 -0
  176. data/spec/graphql/analysis/max_query_complexity_spec.rb +1 -0
  177. data/spec/graphql/analysis/max_query_depth_spec.rb +1 -0
  178. data/spec/graphql/analysis/query_complexity_spec.rb +1 -0
  179. data/spec/graphql/analysis/query_depth_spec.rb +1 -0
  180. data/spec/graphql/argument_spec.rb +1 -0
  181. data/spec/graphql/base_type_spec.rb +13 -0
  182. data/spec/graphql/boolean_type_spec.rb +1 -0
  183. data/spec/graphql/compatibility/execution_specification_spec.rb +1 -0
  184. data/spec/graphql/compatibility/lazy_execution_specification_spec.rb +4 -0
  185. data/spec/graphql/compatibility/query_parser_specification_spec.rb +1 -0
  186. data/spec/graphql/compatibility/schema_parser_specification_spec.rb +1 -0
  187. data/spec/graphql/define/assign_argument_spec.rb +1 -0
  188. data/spec/graphql/define/instance_definable_spec.rb +1 -0
  189. data/spec/graphql/directive_spec.rb +1 -0
  190. data/spec/graphql/enum_type_spec.rb +10 -0
  191. data/spec/graphql/execution/execute_spec.rb +5 -0
  192. data/spec/graphql/execution/lazy_spec.rb +252 -0
  193. data/spec/graphql/execution/typecast_spec.rb +1 -0
  194. data/spec/graphql/execution_error_spec.rb +1 -0
  195. data/spec/graphql/field_spec.rb +17 -0
  196. data/spec/graphql/float_type_spec.rb +1 -0
  197. data/spec/graphql/id_type_spec.rb +1 -0
  198. data/spec/graphql/input_object_type_spec.rb +10 -0
  199. data/spec/graphql/int_type_spec.rb +1 -0
  200. data/spec/graphql/interface_type_spec.rb +10 -0
  201. data/spec/graphql/internal_representation/rewrite_spec.rb +1 -0
  202. data/spec/graphql/introspection/directive_type_spec.rb +1 -0
  203. data/spec/graphql/introspection/input_value_type_spec.rb +1 -0
  204. data/spec/graphql/introspection/introspection_query_spec.rb +1 -0
  205. data/spec/graphql/introspection/schema_type_spec.rb +1 -0
  206. data/spec/graphql/introspection/type_type_spec.rb +1 -0
  207. data/spec/graphql/language/definition_slice_spec.rb +1 -0
  208. data/spec/graphql/language/equality_spec.rb +1 -0
  209. data/spec/graphql/language/generation_spec.rb +1 -0
  210. data/spec/graphql/language/lexer_spec.rb +1 -0
  211. data/spec/graphql/language/nodes_spec.rb +1 -0
  212. data/spec/graphql/language/parser_spec.rb +1 -0
  213. data/spec/graphql/language/visitor_spec.rb +1 -0
  214. data/spec/graphql/list_type_spec.rb +1 -0
  215. data/spec/graphql/non_null_type_spec.rb +17 -0
  216. data/spec/graphql/object_type_spec.rb +19 -0
  217. data/spec/graphql/query/arguments_spec.rb +1 -0
  218. data/spec/graphql/query/context_spec.rb +1 -0
  219. data/spec/graphql/query/executor_spec.rb +1 -0
  220. data/spec/graphql/query/serial_execution/value_resolution_spec.rb +1 -0
  221. data/spec/graphql/query/variables_spec.rb +1 -0
  222. data/spec/graphql/query_spec.rb +25 -0
  223. data/spec/graphql/relay/array_connection_spec.rb +1 -0
  224. data/spec/graphql/relay/base_connection_spec.rb +33 -4
  225. data/spec/graphql/relay/connection_field_spec.rb +1 -0
  226. data/spec/graphql/relay/connection_type_spec.rb +1 -0
  227. data/spec/graphql/relay/mutation_spec.rb +6 -0
  228. data/spec/graphql/relay/node_spec.rb +1 -0
  229. data/spec/graphql/relay/page_info_spec.rb +1 -0
  230. data/spec/graphql/relay/relation_connection_spec.rb +1 -0
  231. data/spec/graphql/scalar_type_spec.rb +1 -0
  232. data/spec/graphql/schema/build_from_definition_spec.rb +9 -1
  233. data/spec/graphql/schema/catchall_middleware_spec.rb +1 -0
  234. data/spec/graphql/schema/loader_spec.rb +7 -0
  235. data/spec/graphql/schema/middleware_chain_spec.rb +1 -0
  236. data/spec/graphql/schema/printer_spec.rb +1 -0
  237. data/spec/graphql/schema/reduce_types_spec.rb +1 -0
  238. data/spec/graphql/schema/rescue_middleware_spec.rb +1 -0
  239. data/spec/graphql/schema/timeout_middleware_spec.rb +1 -0
  240. data/spec/graphql/schema/type_expression_spec.rb +1 -0
  241. data/spec/graphql/schema/unique_within_type_spec.rb +1 -0
  242. data/spec/graphql/schema/validation_spec.rb +55 -0
  243. data/spec/graphql/schema/warden_spec.rb +1 -0
  244. data/spec/graphql/schema_spec.rb +39 -0
  245. data/spec/graphql/static_validation/rules/argument_literals_are_compatible_spec.rb +1 -0
  246. data/spec/graphql/static_validation/rules/arguments_are_defined_spec.rb +1 -0
  247. data/spec/graphql/static_validation/rules/directives_are_defined_spec.rb +1 -0
  248. data/spec/graphql/static_validation/rules/directives_are_in_valid_locations_spec.rb +1 -0
  249. data/spec/graphql/static_validation/rules/fields_are_defined_on_type_spec.rb +1 -0
  250. data/spec/graphql/static_validation/rules/fields_have_appropriate_selections_spec.rb +1 -0
  251. data/spec/graphql/static_validation/rules/fields_will_merge_spec.rb +515 -31
  252. data/spec/graphql/static_validation/rules/fragment_spreads_are_possible_spec.rb +1 -0
  253. data/spec/graphql/static_validation/rules/fragment_types_exist_spec.rb +1 -0
  254. data/spec/graphql/static_validation/rules/fragments_are_finite_spec.rb +1 -0
  255. data/spec/graphql/static_validation/rules/fragments_are_named_spec.rb +1 -0
  256. data/spec/graphql/static_validation/rules/fragments_are_on_composite_types_spec.rb +1 -0
  257. data/spec/graphql/static_validation/rules/fragments_are_used_spec.rb +1 -0
  258. data/spec/graphql/static_validation/rules/mutation_root_exists_spec.rb +1 -0
  259. data/spec/graphql/static_validation/rules/required_arguments_are_present_spec.rb +1 -0
  260. data/spec/graphql/static_validation/rules/subscription_root_exists_spec.rb +1 -0
  261. data/spec/graphql/static_validation/rules/unique_directives_per_location_spec.rb +1 -0
  262. data/spec/graphql/static_validation/rules/variable_default_values_are_correctly_typed_spec.rb +1 -0
  263. data/spec/graphql/static_validation/rules/variable_usages_are_allowed_spec.rb +1 -0
  264. data/spec/graphql/static_validation/rules/variables_are_input_types_spec.rb +1 -0
  265. data/spec/graphql/static_validation/rules/variables_are_used_and_defined_spec.rb +1 -0
  266. data/spec/graphql/static_validation/type_stack_spec.rb +1 -0
  267. data/spec/graphql/static_validation/validator_spec.rb +1 -0
  268. data/spec/graphql/string_type_spec.rb +1 -0
  269. data/spec/graphql/union_type_spec.rb +11 -0
  270. data/spec/spec_helper.rb +1 -0
  271. data/spec/support/dairy_app.rb +1 -0
  272. data/spec/support/dairy_data.rb +1 -0
  273. data/spec/support/minimum_input_object.rb +1 -0
  274. data/spec/support/star_wars_data.rb +1 -0
  275. data/spec/support/star_wars_schema.rb +30 -7
  276. data/spec/support/static_validation_helpers.rb +1 -0
  277. metadata +24 -5
  278. data/lib/graphql/internal_representation/selections.rb +0 -41
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module GraphQL
2
3
  module StaticValidation
3
4
  class RequiredArgumentsArePresent
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module GraphQL
2
3
  module StaticValidation
3
4
  class SubscriptionRootExists
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module GraphQL
2
3
  module StaticValidation
3
4
  class UniqueDirectivesPerLocation
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module GraphQL
2
3
  module StaticValidation
3
4
  class VariableDefaultValuesAreCorrectlyTyped
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module GraphQL
2
3
  module StaticValidation
3
4
  class VariableUsagesAreAllowed
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module GraphQL
2
3
  module StaticValidation
3
4
  class VariablesAreInputTypes
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module GraphQL
2
3
  module StaticValidation
3
4
  # The problem is
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module GraphQL
2
3
  module StaticValidation
3
4
  # - Ride along with `GraphQL::Language::Visitor`
@@ -1,8 +1,9 @@
1
+ # frozen_string_literal: true
1
2
  module GraphQL
2
3
  module StaticValidation
3
4
  # The validation context gets passed to each validator.
4
5
  #
5
- # It exposes a {GraphQL::Language::Visitor} where validators may add hooks. ({Visitor#visit} is called in {Validator#validate})
6
+ # It exposes a {GraphQL::Language::Visitor} where validators may add hooks. ({Language::Visitor#visit} is called in {Validator#validate})
6
7
  #
7
8
  # It provides access to the schema & fragments which validators may read from.
8
9
  #
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module GraphQL
2
3
  module StaticValidation
3
4
  # Initialized with a {GraphQL::Schema}, then it can validate {GraphQL::Language::Nodes::Documents}s based on that schema.
@@ -11,7 +12,7 @@ module GraphQL
11
12
  #
12
13
  class Validator
13
14
  # @param schema [GraphQL::Schema]
14
- # @param rule [Array<#validate(context)>] a list of rules to use when validating
15
+ # @param rules [Array<#validate(context)>] a list of rules to use when validating
15
16
  def initialize(schema:, rules: GraphQL::StaticValidation::ALL_RULES)
16
17
  @schema = schema
17
18
  @rules = rules
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  GraphQL::STRING_TYPE = GraphQL::ScalarType.define do
2
3
  name "String"
3
4
  description "Represents textual data as UTF-8 character sequences. This type is most often used by GraphQL to represent free-form human-readable text."
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module GraphQL
2
3
  # Type kinds are the basic categories which a type may belong to (`Object`, `Scalar`, `Union`...)
3
4
  module TypeKinds
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module GraphQL
2
3
  # A Union is is a collection of object types which may appear in the same place.
3
4
  #
@@ -26,10 +27,17 @@ module GraphQL
26
27
  accepts_definitions :possible_types, :resolve_type
27
28
  ensure_defined :possible_types
28
29
 
30
+ def initialize_copy(other)
31
+ super
32
+ @clean_possible_types = nil
33
+ @dirty_possible_types = other.dirty_possible_types.dup
34
+ end
35
+
29
36
  def kind
30
37
  GraphQL::TypeKinds::UNION
31
38
  end
32
39
 
40
+ # @return [Boolean] True if `child_type_defn` is a member of this {UnionType}
33
41
  def include?(child_type_defn)
34
42
  possible_types.include?(child_type_defn)
35
43
  end
@@ -39,6 +47,7 @@ module GraphQL
39
47
  @dirty_possible_types = new_possible_types
40
48
  end
41
49
 
50
+ # @return [Array<GraphQL::ObjectType>] Types which may be found in this union
42
51
  def possible_types
43
52
  @clean_possible_types ||= begin
44
53
  if @dirty_possible_types.respond_to?(:map)
@@ -48,5 +57,9 @@ module GraphQL
48
57
  end
49
58
  end
50
59
  end
60
+
61
+ protected
62
+
63
+ attr_reader :dirty_possible_types
51
64
  end
52
65
  end
@@ -1,9 +1,30 @@
1
+ # frozen_string_literal: true
1
2
  module GraphQL
2
- # Error raised when the value provided for a field can't be resolved to one of the possible types
3
- # for the field.
4
- class UnresolvedTypeError < GraphQL::Error
5
- def initialize(field_name, field_type, parent_type, received_type, possible_types)
6
- message = %|The value from "#{field_name}" on "#{parent_type}" could not be resolved to "#{field_type}". (Received: #{received_type.inspect}, Expected: [#{possible_types.map(&:inspect).join(", ")}])|
3
+ # Error raised when the value provided for a field
4
+ # can't be resolved to one of the possible types for the field.
5
+ class UnresolvedTypeError < GraphQL::RuntimeTypeError
6
+ # @return [Object] The runtime value which couldn't be successfully resolved with `resolve_type`
7
+ attr_reader :value
8
+
9
+ # @return [GraphQL::Field] The field whose value couldn't be resolved (`field.type` is type which couldn't be resolved)
10
+ attr_reader :field
11
+
12
+ # @return [GraphQL::BaseType] The owner of `field`
13
+ attr_reader :parent_type
14
+
15
+ # @return [Object] The return of {Schema#resolve_type} for `value`
16
+ attr_reader :resolved_type
17
+
18
+ # @return [Array<GraphQL::BaseType>] The allowed options for resolving `value` to `field.type`
19
+ attr_reader :possible_types
20
+
21
+ def initialize(value, field, parent_type, resolved_type, possible_types)
22
+ @value = value
23
+ @field = field
24
+ @parent_type = parent_type
25
+ @resolved_type = resolved_type
26
+ @possible_types = possible_types
27
+ message = %|The value from "#{field.name}" on "#{parent_type}" could not be resolved to "#{field.type}". (Received: #{resolved_type.inspect}, Expected: [#{possible_types.map(&:inspect).join(", ")}])|
7
28
  super(message)
8
29
  end
9
30
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module GraphQL
2
- VERSION = "1.2.6"
3
+ VERSION = "1.3.0"
3
4
  end
data/readme.md CHANGED
@@ -44,7 +44,7 @@ See "Getting Started" on the [website](https://rmosolgo.github.io/graphql-ruby/)
44
44
 
45
45
  ## To Do
46
46
 
47
- - StaticValidation improvements ([in progress](https://github.com/rmosolgo/graphql-ruby/pull/268))
47
+ - StaticValidation improvements ([in progress ??](https://github.com/rmosolgo/graphql-ruby/pull/268))
48
48
  - Use catch-all type/field/argument definitions instead of terminating traversal
49
49
  - Reduce ad-hoc traversals?
50
50
  - Validators are order-dependent, is this a smell?
@@ -56,11 +56,7 @@ See "Getting Started" on the [website](https://rmosolgo.github.io/graphql-ruby/)
56
56
  - If the new edge isn't a member of the connection's objects, raise a nice error
57
57
  - `args` should whitelist keys -- if you request a key that isn't defined for the field, it should 💥
58
58
  - Support non-instance-eval `.define`, eg `.define { |defn| ... }`
59
- - First-class promise support ([discussion](https://github.com/rmosolgo/graphql-ruby/issues/274))
60
- - like `graphql-batch` but more local
61
- - support promises in connection resolves
62
59
  - Add immutable transformation API to AST
63
60
  - Support working with AST as data
64
61
  - Adding fields to selections (`__typename` can go anywhere, others are type-specific)
65
62
  - Renaming fragments from local names to unique names
66
- - Document encrypted & versioned cursors
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require "spec_helper"
2
3
 
3
4
  describe GraphQL::Analysis do
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require "spec_helper"
2
3
 
3
4
  describe GraphQL::Analysis::FieldUsage do
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require "spec_helper"
2
3
 
3
4
  describe GraphQL::Analysis::MaxQueryComplexity do
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require "spec_helper"
2
3
 
3
4
  describe GraphQL::Analysis::MaxQueryDepth do
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require "spec_helper"
2
3
 
3
4
  describe GraphQL::Analysis::QueryComplexity do
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require "spec_helper"
2
3
 
3
4
  describe GraphQL::Analysis::QueryDepth do
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require "spec_helper"
2
3
 
3
4
  describe GraphQL::Argument do
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require "spec_helper"
2
3
 
3
4
  describe GraphQL::BaseType do
@@ -25,4 +26,16 @@ describe GraphQL::BaseType do
25
26
  it "Accepts arbitrary metadata" do
26
27
  assert_equal ["Cheese"], CheeseType.metadata[:class_names]
27
28
  end
29
+
30
+ describe "#dup" do
31
+ it "resets connection types" do
32
+ # Make sure the defaults have been calculated
33
+ cheese_edge = CheeseType.edge_type
34
+ cheese_conn = CheeseType.connection_type
35
+ cheese_2 = CheeseType.dup
36
+ cheese_2.name = "Cheese2"
37
+ refute_equal cheese_edge, cheese_2.edge_type
38
+ refute_equal cheese_conn, cheese_2.connection_type
39
+ end
40
+ end
28
41
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require "spec_helper"
2
3
 
3
4
  describe GraphQL::BOOLEAN_TYPE do
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require "spec_helper"
2
3
 
3
4
  SerialExecutionSuite = GraphQL::Compatibility::ExecutionSpecification.build_suite(GraphQL::Query::SerialExecution)
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+ require "spec_helper"
3
+
4
+ LazySpecSuite = GraphQL::Compatibility::LazyExecutionSpecification.build_suite(GraphQL::Execution::Execute)
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require "spec_helper"
2
3
 
3
4
  BuiltInQueryParserSuite = GraphQL::Compatibility::QueryParserSpecification.build_suite do |query_string|
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require "spec_helper"
2
3
 
3
4
  BuiltInSchemaParserSuite = GraphQL::Compatibility::SchemaParserSpecification.build_suite do |query_string|
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require "spec_helper"
2
3
 
3
4
  describe GraphQL::Define::AssignArgument do
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require "date"
2
3
  require "spec_helper"
3
4
 
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require "spec_helper"
2
3
 
3
4
  describe GraphQL::Directive do
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  require "spec_helper"
2
3
 
3
4
  describe GraphQL::EnumType do
@@ -88,4 +89,13 @@ describe GraphQL::EnumType do
88
89
  enum = GraphQL::EnumType.define(name: "DairyAnimal", values: [cow, goat])
89
90
  assert_equal({ "COW" => cow, "GOAT" => goat }, enum.values)
90
91
  end
92
+
93
+ describe "#dup" do
94
+ it "copies the values map without altering the original" do
95
+ enum_2 = enum.dup
96
+ enum_2.add_value(GraphQL::EnumType::EnumValue.define(name: "MUSKRAT"))
97
+ assert_equal(6, enum.values.size)
98
+ assert_equal(7, enum_2.values.size)
99
+ end
100
+ end
91
101
  end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+ require "spec_helper"
3
+
4
+ ExecuteSuite = GraphQL::Compatibility::ExecutionSpecification.build_suite(GraphQL::Execution::Execute)
5
+ LazyExecuteSuite = GraphQL::Compatibility::LazyExecutionSpecification.build_suite(GraphQL::Execution::Execute)
@@ -0,0 +1,252 @@
1
+ # frozen_string_literal: true
2
+ require "spec_helper"
3
+
4
+ describe GraphQL::Execution::Lazy do
5
+ class Wrapper
6
+ def initialize(item = nil, &block)
7
+ if block
8
+ @block = block
9
+ else
10
+ @item = item
11
+ end
12
+ end
13
+
14
+ def item
15
+ if @block
16
+ @item = @block.call()
17
+ @block = nil
18
+ end
19
+ @item
20
+ end
21
+ end
22
+
23
+ class SumAll
24
+ attr_reader :own_value
25
+ attr_accessor :value
26
+
27
+ def initialize(ctx, own_value)
28
+ @own_value = own_value
29
+ @all = ctx[:__sum_all__] ||= []
30
+ @all << self
31
+ end
32
+
33
+ def value
34
+ @value ||= begin
35
+ total_value = @all.map(&:own_value).reduce(&:+)
36
+ @all.each { |v| v.value = total_value}
37
+ @all.clear
38
+ total_value
39
+ end
40
+ @value
41
+ end
42
+ end
43
+
44
+ LazySum = GraphQL::ObjectType.define do
45
+ name "LazySum"
46
+ field :value, types.Int do
47
+ resolve ->(o, a, c) { o == 13 ? nil : o }
48
+ end
49
+ field :nestedSum, !LazySum do
50
+ argument :value, !types.Int
51
+ resolve ->(o, args, c) {
52
+ if args[:value] == 13
53
+ Wrapper.new(nil)
54
+ else
55
+ SumAll.new(c, o + args[:value])
56
+ end
57
+ }
58
+ end
59
+
60
+ field :nullableNestedSum, LazySum do
61
+ argument :value, types.Int
62
+ resolve ->(o, args, c) {
63
+ if args[:value] == 13
64
+ Wrapper.new(nil)
65
+ else
66
+ SumAll.new(c, o + args[:value])
67
+ end
68
+ }
69
+ end
70
+ end
71
+
72
+ LazyQuery = GraphQL::ObjectType.define do
73
+ name "Query"
74
+ field :int, !types.Int do
75
+ argument :value, !types.Int
76
+ argument :plus, types.Int, default_value: 0
77
+ resolve ->(o, a, c) { Wrapper.new(a[:value] + a[:plus])}
78
+ end
79
+
80
+ field :nestedSum, !LazySum do
81
+ argument :value, !types.Int
82
+ resolve ->(o, args, c) { SumAll.new(c, args[:value]) }
83
+ end
84
+
85
+ field :nullableNestedSum, LazySum do
86
+ argument :value, types.Int
87
+ resolve ->(o, args, c) {
88
+ if args[:value] == 13
89
+ Wrapper.new { raise GraphQL::ExecutionError.new("13 is unlucky") }
90
+ else
91
+ SumAll.new(c, args[:value])
92
+ end
93
+ }
94
+ end
95
+
96
+ field :listSum, types[LazySum] do
97
+ argument :values, types[types.Int]
98
+ resolve ->(o, args, c) { args[:values] }
99
+ end
100
+ end
101
+
102
+ LazySchema = GraphQL::Schema.define do
103
+ query(LazyQuery)
104
+ mutation(LazyQuery)
105
+ lazy_resolve(Wrapper, :item)
106
+ lazy_resolve(SumAll, :value)
107
+ end
108
+
109
+ def run_query(query_str)
110
+ LazySchema.execute(query_str)
111
+ end
112
+
113
+ describe "resolving" do
114
+ it "calls value handlers" do
115
+ res = run_query('{ int(value: 2, plus: 1)}')
116
+ assert_equal 3, res["data"]["int"]
117
+ end
118
+
119
+ it "can do nested lazy values" do
120
+ res = run_query %|
121
+ {
122
+ a: nestedSum(value: 3) {
123
+ value
124
+ nestedSum(value: 7) {
125
+ value
126
+ }
127
+ }
128
+ b: nestedSum(value: 2) {
129
+ value
130
+ nestedSum(value: 11) {
131
+ value
132
+ }
133
+ }
134
+
135
+ c: listSum(values: [1,2]) {
136
+ nestedSum(value: 3) {
137
+ value
138
+ }
139
+ }
140
+ }
141
+ |
142
+
143
+ expected_data = {
144
+ "a"=>{"value"=>14, "nestedSum"=>{"value"=>46}},
145
+ "b"=>{"value"=>14, "nestedSum"=>{"value"=>46}},
146
+ "c"=>[{"nestedSum"=>{"value"=>14}}, {"nestedSum"=>{"value"=>14}}],
147
+ }
148
+
149
+ assert_equal expected_data, res["data"]
150
+ end
151
+
152
+ it "propagates nulls" do
153
+ res = run_query %|
154
+ {
155
+ nestedSum(value: 1) {
156
+ value
157
+ nestedSum(value: 2) {
158
+ nestedSum(value: 13) {
159
+ value
160
+ }
161
+ }
162
+ }
163
+ }|
164
+
165
+ assert_equal(nil, res["data"])
166
+ assert_equal 1, res["errors"].length
167
+
168
+
169
+ res = run_query %|
170
+ {
171
+ nullableNestedSum(value: 1) {
172
+ value
173
+ nullableNestedSum(value: 2) {
174
+ nestedSum(value: 13) {
175
+ value
176
+ }
177
+ }
178
+ }
179
+ }|
180
+
181
+ expected_data = {
182
+ "nullableNestedSum" => {
183
+ "value" => 1,
184
+ "nullableNestedSum" => nil,
185
+ }
186
+ }
187
+ assert_equal(expected_data, res["data"])
188
+ assert_equal 1, res["errors"].length
189
+ end
190
+
191
+ it "handles raised errors" do
192
+ res = run_query %|
193
+ {
194
+ a: nullableNestedSum(value: 1) { value }
195
+ b: nullableNestedSum(value: 13) { value }
196
+ c: nullableNestedSum(value: 2) { value }
197
+ }|
198
+
199
+ expected_data = {
200
+ "a" => { "value" => 3 },
201
+ "b" => nil,
202
+ "c" => { "value" => 3 },
203
+ }
204
+ assert_equal expected_data, res["data"]
205
+
206
+ expected_errors = [{
207
+ "message"=>"13 is unlucky",
208
+ "locations"=>[{"line"=>4, "column"=>9}],
209
+ "path"=>["b"],
210
+ }]
211
+ assert_equal expected_errors, res["errors"]
212
+ end
213
+
214
+ it "resolves mutation fields right away" do
215
+ res = run_query %|
216
+ {
217
+ a: nestedSum(value: 2) { value }
218
+ b: nestedSum(value: 4) { value }
219
+ c: nestedSum(value: 6) { value }
220
+ }|
221
+
222
+ assert_equal [12, 12, 12], res["data"].values.map { |d| d["value"] }
223
+
224
+ res = run_query %|
225
+ mutation {
226
+ a: nestedSum(value: 2) { value }
227
+ b: nestedSum(value: 4) { value }
228
+ c: nestedSum(value: 6) { value }
229
+ }
230
+ |
231
+
232
+ assert_equal [2, 4, 6], res["data"].values.map { |d| d["value"] }
233
+ end
234
+ end
235
+
236
+ describe "LazyMethodMap" do
237
+ class SubWrapper < Wrapper; end
238
+
239
+ let(:map) { GraphQL::Execution::Lazy::LazyMethodMap.new }
240
+
241
+ it "finds methods for classes and subclasses" do
242
+ map.set(Wrapper, :item)
243
+ map.set(SumAll, :value)
244
+ b = Wrapper.new(1)
245
+ sub_b = Wrapper.new(2)
246
+ s = SumAll.new({}, 3)
247
+ assert_equal(:item, map.get(b))
248
+ assert_equal(:item, map.get(sub_b))
249
+ assert_equal(:value, map.get(s))
250
+ end
251
+ end
252
+ end