graphql 1.2.6 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
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