graphql 1.8.7 → 1.9.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 (368) hide show
  1. checksums.yaml +4 -4
  2. data/lib/generators/graphql/install_generator.rb +2 -1
  3. data/lib/generators/graphql/scalar_generator.rb +20 -0
  4. data/lib/generators/graphql/templates/base_scalar.erb +4 -0
  5. data/lib/generators/graphql/templates/scalar.erb +13 -0
  6. data/lib/graphql/analysis/ast/analyzer.rb +62 -0
  7. data/lib/graphql/analysis/ast/field_usage.rb +28 -0
  8. data/lib/graphql/analysis/ast/max_query_complexity.rb +23 -0
  9. data/lib/graphql/analysis/ast/max_query_depth.rb +18 -0
  10. data/lib/graphql/analysis/ast/query_complexity.rb +114 -0
  11. data/lib/graphql/analysis/ast/query_depth.rb +66 -0
  12. data/lib/graphql/analysis/ast/visitor.rb +255 -0
  13. data/lib/graphql/analysis/ast.rb +82 -0
  14. data/lib/graphql/analysis.rb +1 -0
  15. data/lib/graphql/argument.rb +5 -0
  16. data/lib/graphql/authorization.rb +1 -0
  17. data/lib/graphql/backwards_compatibility.rb +1 -1
  18. data/lib/graphql/base_type.rb +1 -1
  19. data/lib/graphql/compatibility/execution_specification/specification_schema.rb +1 -2
  20. data/lib/graphql/compatibility/schema_parser_specification.rb +2 -6
  21. data/lib/graphql/dig.rb +19 -0
  22. data/lib/graphql/directive/include_directive.rb +1 -7
  23. data/lib/graphql/directive/skip_directive.rb +1 -8
  24. data/lib/graphql/directive.rb +13 -1
  25. data/lib/graphql/enum_type.rb +8 -0
  26. data/lib/graphql/execution/execute.rb +36 -17
  27. data/lib/graphql/execution/instrumentation.rb +2 -0
  28. data/lib/graphql/execution/interpreter/execution_errors.rb +29 -0
  29. data/lib/graphql/execution/interpreter/hash_response.rb +46 -0
  30. data/lib/graphql/execution/interpreter/resolve.rb +58 -0
  31. data/lib/graphql/execution/interpreter/runtime.rb +597 -0
  32. data/lib/graphql/execution/interpreter.rb +99 -0
  33. data/lib/graphql/execution/lazy.rb +8 -1
  34. data/lib/graphql/execution/lookahead.rb +351 -0
  35. data/lib/graphql/execution/multiplex.rb +37 -29
  36. data/lib/graphql/execution.rb +2 -0
  37. data/lib/graphql/execution_error.rb +1 -1
  38. data/lib/graphql/field.rb +1 -7
  39. data/lib/graphql/integer_encoding_error.rb +12 -0
  40. data/lib/graphql/internal_representation/rewrite.rb +127 -142
  41. data/lib/graphql/introspection/dynamic_fields.rb +8 -2
  42. data/lib/graphql/introspection/entry_points.rb +11 -6
  43. data/lib/graphql/introspection/enum_value_type.rb +4 -0
  44. data/lib/graphql/introspection/schema_type.rb +7 -2
  45. data/lib/graphql/introspection/type_type.rb +9 -5
  46. data/lib/graphql/invalid_null_error.rb +1 -1
  47. data/lib/graphql/language/block_string.rb +37 -0
  48. data/lib/graphql/language/document_from_schema_definition.rb +10 -7
  49. data/lib/graphql/language/lexer.rb +55 -36
  50. data/lib/graphql/language/lexer.rl +8 -3
  51. data/lib/graphql/language/nodes.rb +440 -362
  52. data/lib/graphql/language/parser.rb +56 -56
  53. data/lib/graphql/language/parser.y +12 -12
  54. data/lib/graphql/language/printer.rb +2 -2
  55. data/lib/graphql/language/visitor.rb +158 -15
  56. data/lib/graphql/language.rb +0 -1
  57. data/lib/graphql/literal_validation_error.rb +6 -0
  58. data/lib/graphql/query/arguments.rb +3 -2
  59. data/lib/graphql/query/arguments_cache.rb +1 -1
  60. data/lib/graphql/query/context.rb +14 -5
  61. data/lib/graphql/query/executor.rb +1 -1
  62. data/lib/graphql/query/result.rb +1 -1
  63. data/lib/graphql/query/validation_pipeline.rb +35 -11
  64. data/lib/graphql/query/variable_validation_error.rb +10 -1
  65. data/lib/graphql/query.rb +16 -2
  66. data/lib/graphql/relay/base_connection.rb +2 -0
  67. data/lib/graphql/relay/connection_instrumentation.rb +3 -1
  68. data/lib/graphql/relay/connection_resolve.rb +1 -1
  69. data/lib/graphql/relay/node.rb +2 -28
  70. data/lib/graphql/relay/relation_connection.rb +1 -1
  71. data/lib/graphql/schema/argument.rb +13 -5
  72. data/lib/graphql/schema/base_64_encoder.rb +4 -4
  73. data/lib/graphql/schema/build_from_definition.rb +2 -4
  74. data/lib/graphql/schema/default_type_error.rb +1 -1
  75. data/lib/graphql/schema/directive/feature.rb +66 -0
  76. data/lib/graphql/schema/directive/include.rb +25 -0
  77. data/lib/graphql/schema/directive/skip.rb +25 -0
  78. data/lib/graphql/schema/directive/transform.rb +48 -0
  79. data/lib/graphql/schema/directive.rb +103 -0
  80. data/lib/graphql/schema/enum_value.rb +3 -2
  81. data/lib/graphql/schema/field/connection_extension.rb +50 -0
  82. data/lib/graphql/schema/field/scope_extension.rb +18 -0
  83. data/lib/graphql/schema/field.rb +273 -64
  84. data/lib/graphql/schema/field_extension.rb +69 -0
  85. data/lib/graphql/schema/input_object.rb +16 -8
  86. data/lib/graphql/schema/interface.rb +1 -0
  87. data/lib/graphql/schema/loader.rb +22 -16
  88. data/lib/graphql/schema/member/base_dsl_methods.rb +8 -2
  89. data/lib/graphql/schema/member/build_type.rb +33 -1
  90. data/lib/graphql/schema/member/has_arguments.rb +6 -2
  91. data/lib/graphql/schema/member/has_fields.rb +18 -70
  92. data/lib/graphql/schema/member/has_path.rb +25 -0
  93. data/lib/graphql/schema/member/instrumentation.rb +10 -7
  94. data/lib/graphql/schema/member.rb +2 -0
  95. data/lib/graphql/schema/mutation.rb +6 -48
  96. data/lib/graphql/schema/non_null.rb +5 -1
  97. data/lib/graphql/schema/object.rb +18 -4
  98. data/lib/graphql/schema/printer.rb +1 -1
  99. data/lib/graphql/schema/relay_classic_mutation.rb +42 -9
  100. data/lib/graphql/schema/resolver/has_payload_type.rb +65 -0
  101. data/lib/graphql/schema/resolver.rb +45 -20
  102. data/lib/graphql/schema/subscription.rb +97 -0
  103. data/lib/graphql/schema/traversal.rb +11 -7
  104. data/lib/graphql/schema.rb +186 -38
  105. data/lib/graphql/static_validation/all_rules.rb +3 -2
  106. data/lib/graphql/static_validation/base_visitor.rb +199 -0
  107. data/lib/graphql/static_validation/default_visitor.rb +15 -0
  108. data/lib/graphql/static_validation/definition_dependencies.rb +62 -68
  109. data/lib/graphql/static_validation/{message.rb → error.rb} +11 -11
  110. data/lib/graphql/static_validation/interpreter_visitor.rb +14 -0
  111. data/lib/graphql/static_validation/literal_validator.rb +54 -11
  112. data/lib/graphql/static_validation/no_validate_visitor.rb +10 -0
  113. data/lib/graphql/static_validation/rules/argument_literals_are_compatible.rb +87 -16
  114. data/lib/graphql/static_validation/rules/argument_literals_are_compatible_error.rb +31 -0
  115. data/lib/graphql/static_validation/rules/argument_names_are_unique.rb +11 -11
  116. data/lib/graphql/static_validation/rules/argument_names_are_unique_error.rb +30 -0
  117. data/lib/graphql/static_validation/rules/arguments_are_defined.rb +52 -8
  118. data/lib/graphql/static_validation/rules/arguments_are_defined_error.rb +35 -0
  119. data/lib/graphql/static_validation/rules/directives_are_defined.rb +12 -15
  120. data/lib/graphql/static_validation/rules/directives_are_defined_error.rb +29 -0
  121. data/lib/graphql/static_validation/rules/directives_are_in_valid_locations.rb +19 -14
  122. data/lib/graphql/static_validation/rules/directives_are_in_valid_locations_error.rb +31 -0
  123. data/lib/graphql/static_validation/rules/fields_are_defined_on_type.rb +17 -19
  124. data/lib/graphql/static_validation/rules/fields_are_defined_on_type_error.rb +32 -0
  125. data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +30 -14
  126. data/lib/graphql/static_validation/rules/fields_have_appropriate_selections_error.rb +31 -0
  127. data/lib/graphql/static_validation/rules/fields_will_merge.rb +356 -29
  128. data/lib/graphql/static_validation/rules/fields_will_merge_error.rb +32 -0
  129. data/lib/graphql/static_validation/rules/fragment_names_are_unique.rb +20 -13
  130. data/lib/graphql/static_validation/rules/fragment_names_are_unique_error.rb +29 -0
  131. data/lib/graphql/static_validation/rules/fragment_spreads_are_possible.rb +37 -29
  132. data/lib/graphql/static_validation/rules/fragment_spreads_are_possible_error.rb +35 -0
  133. data/lib/graphql/static_validation/rules/fragment_types_exist.rb +25 -17
  134. data/lib/graphql/static_validation/rules/fragment_types_exist_error.rb +29 -0
  135. data/lib/graphql/static_validation/rules/fragments_are_finite.rb +12 -10
  136. data/lib/graphql/static_validation/rules/fragments_are_finite_error.rb +29 -0
  137. data/lib/graphql/static_validation/rules/fragments_are_named.rb +7 -11
  138. data/lib/graphql/static_validation/rules/fragments_are_named_error.rb +26 -0
  139. data/lib/graphql/static_validation/rules/fragments_are_on_composite_types.rb +16 -16
  140. data/lib/graphql/static_validation/rules/fragments_are_on_composite_types_error.rb +30 -0
  141. data/lib/graphql/static_validation/rules/fragments_are_used.rb +21 -14
  142. data/lib/graphql/static_validation/rules/fragments_are_used_error.rb +29 -0
  143. data/lib/graphql/static_validation/rules/mutation_root_exists.rb +10 -14
  144. data/lib/graphql/static_validation/rules/mutation_root_exists_error.rb +26 -0
  145. data/lib/graphql/static_validation/rules/no_definitions_are_present.rb +30 -30
  146. data/lib/graphql/static_validation/rules/no_definitions_are_present_error.rb +25 -0
  147. data/lib/graphql/static_validation/rules/operation_names_are_valid.rb +25 -17
  148. data/lib/graphql/static_validation/rules/operation_names_are_valid_error.rb +28 -0
  149. data/lib/graphql/static_validation/rules/required_arguments_are_present.rb +17 -18
  150. data/lib/graphql/static_validation/rules/required_arguments_are_present_error.rb +35 -0
  151. data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present.rb +47 -0
  152. data/lib/graphql/static_validation/rules/required_input_object_attributes_are_present_error.rb +35 -0
  153. data/lib/graphql/static_validation/rules/subscription_root_exists.rb +10 -14
  154. data/lib/graphql/static_validation/rules/subscription_root_exists_error.rb +26 -0
  155. data/lib/graphql/static_validation/rules/unique_directives_per_location.rb +28 -17
  156. data/lib/graphql/static_validation/rules/unique_directives_per_location_error.rb +29 -0
  157. data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed.rb +35 -27
  158. data/lib/graphql/static_validation/rules/variable_default_values_are_correctly_typed_error.rb +39 -0
  159. data/lib/graphql/static_validation/rules/variable_names_are_unique.rb +15 -14
  160. data/lib/graphql/static_validation/rules/variable_names_are_unique_error.rb +29 -0
  161. data/lib/graphql/static_validation/rules/variable_usages_are_allowed.rb +41 -30
  162. data/lib/graphql/static_validation/rules/variable_usages_are_allowed_error.rb +38 -0
  163. data/lib/graphql/static_validation/rules/variables_are_input_types.rb +18 -14
  164. data/lib/graphql/static_validation/rules/variables_are_input_types_error.rb +32 -0
  165. data/lib/graphql/static_validation/rules/variables_are_used_and_defined.rb +73 -65
  166. data/lib/graphql/static_validation/rules/variables_are_used_and_defined_error.rb +37 -0
  167. data/lib/graphql/static_validation/validation_context.rb +8 -51
  168. data/lib/graphql/static_validation/validator.rb +23 -15
  169. data/lib/graphql/static_validation.rb +5 -3
  170. data/lib/graphql/subscriptions/action_cable_subscriptions.rb +21 -2
  171. data/lib/graphql/subscriptions/event.rb +28 -5
  172. data/lib/graphql/subscriptions/subscription_root.rb +66 -0
  173. data/lib/graphql/subscriptions.rb +16 -2
  174. data/lib/graphql/tracing/active_support_notifications_tracing.rb +0 -1
  175. data/lib/graphql/tracing/appsignal_tracing.rb +1 -1
  176. data/lib/graphql/tracing/data_dog_tracing.rb +1 -1
  177. data/lib/graphql/tracing/new_relic_tracing.rb +3 -3
  178. data/lib/graphql/tracing/platform_tracing.rb +17 -1
  179. data/lib/graphql/tracing/prometheus_tracing.rb +1 -1
  180. data/lib/graphql/tracing/scout_tracing.rb +1 -1
  181. data/lib/graphql/tracing/skylight_tracing.rb +3 -3
  182. data/lib/graphql/tracing.rb +8 -8
  183. data/lib/graphql/types/float.rb +1 -1
  184. data/lib/graphql/types/int.rb +11 -2
  185. data/lib/graphql/types/iso_8601_date_time.rb +15 -1
  186. data/lib/graphql/types/relay/base_connection.rb +15 -1
  187. data/lib/graphql/types/relay/node.rb +0 -1
  188. data/lib/graphql/types/relay/node_field.rb +43 -0
  189. data/lib/graphql/types/relay/nodes_field.rb +45 -0
  190. data/lib/graphql/types/relay.rb +2 -0
  191. data/lib/graphql/unauthorized_error.rb +4 -0
  192. data/lib/graphql/unauthorized_field_error.rb +23 -0
  193. data/lib/graphql/upgrader/member.rb +5 -0
  194. data/lib/graphql/version.rb +1 -1
  195. data/lib/graphql.rb +6 -1
  196. data/readme.md +7 -7
  197. data/spec/dummy/Gemfile +1 -1
  198. data/spec/dummy/Gemfile.lock +157 -0
  199. data/spec/dummy/app/channels/graphql_channel.rb +22 -11
  200. data/spec/dummy/config/locales/en.yml +1 -1
  201. data/spec/dummy/log/test.log +199 -0
  202. data/spec/dummy/test/test_helper.rb +1 -0
  203. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/4w/4wzXRZrAkwKdgYaSE0pid5eB-fer8vSfSku_NPg4rMA.cache +0 -0
  204. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/7I/7IHVBiJT06QSpgLpLoJIxboQ0B-D_tMTxsvoezBTV3Q.cache +1 -0
  205. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/8w/8wY_SKagj8wHuwGNAAf6JnQ8joMbC6cEYpHrTAI8Urc.cache +1 -0
  206. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/AK/AKzz1u6bGb4auXcrObA_g5LL-oV0ejNGa448AgAi_WQ.cache +1 -0
  207. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/ET/ETW4uxvaYpruL8y6_ZptUH82ZowMaHIqvg5WexBFdEM.cache +3 -0
  208. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/F1/F1TWpjjyA56k9Z90n5B3xRn7DUdGjX73QCkYC6k07JQ.cache +0 -0
  209. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/F8/F8MUNRzORGFgr329fNM0xLaoWCXdv3BIalT7dsvLfjs.cache +2 -0
  210. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/KB/KB07ZaKNC5uXJ7TjLi-WqnY6g7dq8wWp_8N3HNjBNxg.cache +2 -0
  211. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Ms/MsKSimH_UCB-H1tLvDABDHuvGciuoW6kVqQWDrXU5FQ.cache +0 -0
  212. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Mt/Mtci-Kim50aPOmeClD4AIicKn1d1WJ0n454IjSd94sk.cache +0 -0
  213. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/QH/QHt3Tc1Y6M66Oo_pDuMyWrQNs4Pp3SMeZR5K1wJj2Ts.cache +1 -0
  214. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/XU/XU4k1OXnfMils5SrirorPvDSyDSqiOWLZNtmAH1HH8k.cache +0 -0
  215. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/ZI/ZIof7mZxWWCnraIFOCuV6a8QRWzKJXJnx2Xd7C0ZyX0.cache +1 -0
  216. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/cG/cGc_puuPS5pZKgUcy1Y_i1L6jl5UtsiIrMH59rTzR6c.cache +3 -0
  217. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/df/dfro_B6bx3KP1Go-7jEOqqZ2j4hVRseXIc3es9PKQno.cache +1 -0
  218. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/jO/jO1DfbqnG0mTULsjJJANc3fefrG2zt7DIMmcptMT628.cache +1 -0
  219. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/pE/pE7gO6pQ-z187Swb4hT554wmqsq-cNzgPWLrCz-LQQQ.cache +0 -0
  220. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/r9/r9iU1l58a6rxkZSW5RSC52_tD-_UQuHxoMVnkfJ7Mhs.cache +1 -0
  221. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/xi/xitPPFfPIyDMpaznV0sBBcw8eSCV8PJcLLWin78sCgE.cache +0 -0
  222. data/spec/dummy/tmp/screenshots/failures_test_it_handles_subscriptions.png +0 -0
  223. data/spec/graphql/analysis/analyze_query_spec.rb +1 -1
  224. data/spec/graphql/analysis/ast/field_usage_spec.rb +51 -0
  225. data/spec/graphql/analysis/ast/max_query_complexity_spec.rb +120 -0
  226. data/spec/graphql/analysis/ast/max_query_depth_spec.rb +114 -0
  227. data/spec/graphql/analysis/ast/query_complexity_spec.rb +299 -0
  228. data/spec/graphql/analysis/ast/query_depth_spec.rb +108 -0
  229. data/spec/graphql/analysis/ast_spec.rb +269 -0
  230. data/spec/graphql/authorization_spec.rb +120 -23
  231. data/spec/graphql/base_type_spec.rb +6 -4
  232. data/spec/graphql/enum_type_spec.rb +6 -1
  233. data/spec/graphql/execution/execute_spec.rb +9 -9
  234. data/spec/graphql/execution/instrumentation_spec.rb +19 -0
  235. data/spec/graphql/execution/interpreter_spec.rb +485 -0
  236. data/spec/graphql/execution/lazy_spec.rb +67 -1
  237. data/spec/graphql/execution/lookahead_spec.rb +363 -0
  238. data/spec/graphql/execution/multiplex_spec.rb +31 -3
  239. data/spec/graphql/execution/typecast_spec.rb +20 -20
  240. data/spec/graphql/execution_error_spec.rb +110 -96
  241. data/spec/graphql/field_spec.rb +1 -1
  242. data/spec/graphql/input_object_type_spec.rb +13 -352
  243. data/spec/graphql/int_type_spec.rb +19 -0
  244. data/spec/graphql/interface_type_spec.rb +4 -4
  245. data/spec/graphql/internal_representation/rewrite_spec.rb +2 -0
  246. data/spec/graphql/introspection/input_value_type_spec.rb +1 -1
  247. data/spec/graphql/introspection/type_type_spec.rb +1 -2
  248. data/spec/graphql/language/document_from_schema_definition_spec.rb +2 -2
  249. data/spec/graphql/language/lexer_spec.rb +72 -3
  250. data/spec/graphql/language/nodes_spec.rb +20 -0
  251. data/spec/graphql/language/printer_spec.rb +18 -6
  252. data/spec/graphql/language/visitor_spec.rb +320 -14
  253. data/spec/graphql/non_null_type_spec.rb +1 -1
  254. data/spec/graphql/object_type_spec.rb +32 -27
  255. data/spec/graphql/query/arguments_spec.rb +21 -0
  256. data/spec/graphql/query/context_spec.rb +28 -0
  257. data/spec/graphql/query/executor_spec.rb +40 -36
  258. data/spec/graphql/query_spec.rb +12 -6
  259. data/spec/graphql/schema/argument_spec.rb +35 -1
  260. data/spec/graphql/schema/build_from_definition_spec.rb +144 -29
  261. data/spec/graphql/schema/catchall_middleware_spec.rb +16 -15
  262. data/spec/graphql/schema/directive/feature_spec.rb +81 -0
  263. data/spec/graphql/schema/directive/transform_spec.rb +39 -0
  264. data/spec/graphql/schema/enum_spec.rb +12 -3
  265. data/spec/graphql/schema/enum_value_spec.rb +11 -0
  266. data/spec/graphql/schema/field_extension_spec.rb +115 -0
  267. data/spec/graphql/schema/field_spec.rb +47 -7
  268. data/spec/graphql/schema/input_object_spec.rb +95 -0
  269. data/spec/graphql/schema/instrumentation_spec.rb +3 -0
  270. data/spec/graphql/schema/interface_spec.rb +8 -2
  271. data/spec/graphql/schema/introspection_system_spec.rb +9 -1
  272. data/spec/graphql/schema/loader_spec.rb +5 -0
  273. data/spec/graphql/schema/member/accepts_definition_spec.rb +4 -0
  274. data/spec/graphql/schema/member/build_type_spec.rb +46 -0
  275. data/spec/graphql/schema/member/scoped_spec.rb +19 -3
  276. data/spec/graphql/schema/mutation_spec.rb +5 -3
  277. data/spec/graphql/schema/object_spec.rb +9 -1
  278. data/spec/graphql/schema/printer_spec.rb +255 -93
  279. data/spec/graphql/schema/relay_classic_mutation_spec.rb +133 -0
  280. data/spec/graphql/schema/resolver_spec.rb +173 -9
  281. data/spec/graphql/schema/scalar_spec.rb +6 -0
  282. data/spec/graphql/schema/subscription_spec.rb +416 -0
  283. data/spec/graphql/schema/traversal_spec.rb +10 -10
  284. data/spec/graphql/schema/type_expression_spec.rb +2 -2
  285. data/spec/graphql/schema/union_spec.rb +7 -0
  286. data/spec/graphql/schema/validation_spec.rb +1 -1
  287. data/spec/graphql/schema/warden_spec.rb +145 -88
  288. data/spec/graphql/static_validation/rules/argument_literals_are_compatible_spec.rb +213 -73
  289. data/spec/graphql/static_validation/rules/argument_names_are_unique_spec.rb +2 -2
  290. data/spec/graphql/static_validation/rules/arguments_are_defined_spec.rb +72 -29
  291. data/spec/graphql/static_validation/rules/directives_are_defined_spec.rb +4 -2
  292. data/spec/graphql/static_validation/rules/directives_are_in_valid_locations_spec.rb +4 -2
  293. data/spec/graphql/static_validation/rules/fields_are_defined_on_type_spec.rb +10 -5
  294. data/spec/graphql/static_validation/rules/fields_have_appropriate_selections_spec.rb +10 -5
  295. data/spec/graphql/static_validation/rules/fields_will_merge_spec.rb +131 -5
  296. data/spec/graphql/static_validation/rules/fragment_names_are_unique_spec.rb +2 -1
  297. data/spec/graphql/static_validation/rules/fragment_spreads_are_possible_spec.rb +6 -3
  298. data/spec/graphql/static_validation/rules/fragment_types_exist_spec.rb +4 -2
  299. data/spec/graphql/static_validation/rules/fragments_are_finite_spec.rb +4 -2
  300. data/spec/graphql/static_validation/rules/fragments_are_named_spec.rb +2 -1
  301. data/spec/graphql/static_validation/rules/fragments_are_on_composite_types_spec.rb +6 -3
  302. data/spec/graphql/static_validation/rules/fragments_are_used_spec.rb +22 -2
  303. data/spec/graphql/static_validation/rules/mutation_root_exists_spec.rb +2 -1
  304. data/spec/graphql/static_validation/rules/operation_names_are_valid_spec.rb +6 -3
  305. data/spec/graphql/static_validation/rules/required_arguments_are_present_spec.rb +13 -4
  306. data/spec/graphql/static_validation/rules/required_input_object_attributes_are_present_spec.rb +58 -0
  307. data/spec/graphql/static_validation/rules/subscription_root_exists_spec.rb +2 -1
  308. data/spec/graphql/static_validation/rules/unique_directives_per_location_spec.rb +14 -7
  309. data/spec/graphql/static_validation/rules/variable_default_values_are_correctly_typed_spec.rb +14 -7
  310. data/spec/graphql/static_validation/rules/variable_usages_are_allowed_spec.rb +8 -4
  311. data/spec/graphql/static_validation/rules/variables_are_input_types_spec.rb +8 -4
  312. data/spec/graphql/static_validation/rules/variables_are_used_and_defined_spec.rb +23 -3
  313. data/spec/graphql/static_validation/type_stack_spec.rb +10 -19
  314. data/spec/graphql/static_validation/validator_spec.rb +50 -2
  315. data/spec/graphql/subscriptions_spec.rb +27 -16
  316. data/spec/graphql/tracing/new_relic_tracing_spec.rb +16 -0
  317. data/spec/graphql/tracing/platform_tracing_spec.rb +59 -37
  318. data/spec/graphql/tracing/prometheus_tracing_spec.rb +3 -0
  319. data/spec/graphql/tracing/skylight_tracing_spec.rb +16 -0
  320. data/spec/graphql/types/iso_8601_date_time_spec.rb +29 -2
  321. data/spec/graphql/union_type_spec.rb +2 -2
  322. data/spec/graphql/upgrader/member_spec.rb +67 -0
  323. data/spec/{graphql → integration/mongoid/graphql}/relay/mongo_relation_connection_spec.rb +11 -22
  324. data/spec/integration/mongoid/spec_helper.rb +2 -0
  325. data/spec/{support → integration/mongoid}/star_trek/data.rb +0 -0
  326. data/spec/{support → integration/mongoid}/star_trek/schema.rb +56 -34
  327. data/spec/{support/star_wars → integration/rails}/data.rb +1 -0
  328. data/spec/{support → integration/rails/generators}/base_generator_test.rb +0 -0
  329. data/spec/{generators → integration/rails/generators}/graphql/enum_generator_spec.rb +0 -0
  330. data/spec/{generators → integration/rails/generators}/graphql/install_generator_spec.rb +1 -1
  331. data/spec/{generators → integration/rails/generators}/graphql/interface_generator_spec.rb +0 -0
  332. data/spec/{generators → integration/rails/generators}/graphql/loader_generator_spec.rb +0 -0
  333. data/spec/{generators → integration/rails/generators}/graphql/mutation_generator_spec.rb +0 -0
  334. data/spec/{generators → integration/rails/generators}/graphql/object_generator_spec.rb +0 -0
  335. data/spec/integration/rails/generators/graphql/scalar_generator_spec.rb +28 -0
  336. data/spec/{generators → integration/rails/generators}/graphql/union_generator_spec.rb +0 -0
  337. data/spec/integration/rails/graphql/input_object_type_spec.rb +364 -0
  338. data/spec/{graphql → integration/rails/graphql}/query/variables_spec.rb +7 -7
  339. data/spec/{graphql → integration/rails/graphql}/relay/array_connection_spec.rb +9 -9
  340. data/spec/{graphql → integration/rails/graphql}/relay/base_connection_spec.rb +11 -3
  341. data/spec/{graphql → integration/rails/graphql}/relay/connection_instrumentation_spec.rb +19 -22
  342. data/spec/{graphql → integration/rails/graphql}/relay/connection_resolve_spec.rb +16 -0
  343. data/spec/{graphql → integration/rails/graphql}/relay/connection_type_spec.rb +0 -0
  344. data/spec/{graphql → integration/rails/graphql}/relay/edge_spec.rb +0 -0
  345. data/spec/{graphql → integration/rails/graphql}/relay/mutation_spec.rb +48 -0
  346. data/spec/{graphql → integration/rails/graphql}/relay/node_spec.rb +0 -0
  347. data/spec/{graphql → integration/rails/graphql}/relay/page_info_spec.rb +22 -22
  348. data/spec/{graphql → integration/rails/graphql}/relay/range_add_spec.rb +4 -4
  349. data/spec/{graphql → integration/rails/graphql}/relay/relation_connection_spec.rb +56 -27
  350. data/spec/{graphql → integration/rails/graphql}/schema_spec.rb +15 -11
  351. data/spec/{graphql → integration/rails/graphql}/tracing/active_support_notifications_tracing_spec.rb +16 -9
  352. data/spec/integration/rails/spec_helper.rb +25 -0
  353. data/spec/integration/tmp/app/graphql/types/family_type.rb +9 -0
  354. data/spec/spec_helper.rb +23 -39
  355. data/spec/support/dummy/data.rb +20 -17
  356. data/spec/support/dummy/schema.rb +315 -305
  357. data/spec/support/error_bubbling_helpers.rb +23 -0
  358. data/spec/support/jazz.rb +213 -46
  359. data/spec/support/lazy_helpers.rb +69 -27
  360. data/spec/support/new_relic.rb +3 -0
  361. data/spec/support/skylight.rb +3 -0
  362. data/spec/support/star_wars/schema.rb +131 -81
  363. data/spec/support/static_validation_helpers.rb +9 -5
  364. metadata +418 -261
  365. data/lib/graphql/language/comments.rb +0 -45
  366. data/lib/graphql/static_validation/arguments_validator.rb +0 -50
  367. data/spec/graphql/schema/member/has_fields_spec.rb +0 -129
  368. data/spec/rails_dependency_sanity_spec.rb +0 -14
@@ -50,6 +50,97 @@ describe GraphQL::Schema::RelayClassicMutation do
50
50
 
51
51
  assert_equal "Sitar", res["data"]["addSitar"]["instrument"]["name"]
52
52
  end
53
+
54
+ it "supports extras" do
55
+ res = Jazz::Schema.execute <<-GRAPHQL
56
+ mutation {
57
+ hasExtras(input: {}) {
58
+ nodeClass
59
+ int
60
+ }
61
+ }
62
+ GRAPHQL
63
+
64
+ assert_equal "GraphQL::Language::Nodes::Field", res["data"]["hasExtras"]["nodeClass"]
65
+ assert_nil res["data"]["hasExtras"]["int"]
66
+
67
+ # Also test with given args
68
+ res = Jazz::Schema.execute <<-GRAPHQL
69
+ mutation {
70
+ hasExtras(input: {int: 5}) {
71
+ nodeClass
72
+ int
73
+ }
74
+ }
75
+ GRAPHQL
76
+ assert_equal "GraphQL::Language::Nodes::Field", res["data"]["hasExtras"]["nodeClass"]
77
+ assert_equal 5, res["data"]["hasExtras"]["int"]
78
+ end
79
+ end
80
+
81
+ describe "loading multiple application objects" do
82
+ let(:query_str) {
83
+ <<-GRAPHQL
84
+ mutation($ids: [ID!]!) {
85
+ upvoteEnsembles(input: {ensembleIds: $ids}) {
86
+ ensembles {
87
+ id
88
+ }
89
+ }
90
+ }
91
+ GRAPHQL
92
+ }
93
+
94
+ it "loads arguments as objects of the given type and strips `_ids` suffix off argument name and appends `s`" do
95
+ res = Jazz::Schema.execute(query_str, variables: { ids: ["Ensemble/Robert Glasper Experiment", "Ensemble/Bela Fleck and the Flecktones"]})
96
+ assert_equal ["Ensemble/Robert Glasper Experiment", "Ensemble/Bela Fleck and the Flecktones"], res["data"]["upvoteEnsembles"]["ensembles"].map { |e| e["id"] }
97
+ end
98
+
99
+ it "uses the `as:` name when loading" do
100
+ as_bands_query_str = query_str.sub("upvoteEnsembles", "upvoteEnsemblesAsBands")
101
+ res = Jazz::Schema.execute(as_bands_query_str, variables: { ids: ["Ensemble/Robert Glasper Experiment", "Ensemble/Bela Fleck and the Flecktones"]})
102
+ assert_equal ["Ensemble/Robert Glasper Experiment", "Ensemble/Bela Fleck and the Flecktones"], res["data"]["upvoteEnsemblesAsBands"]["ensembles"].map { |e| e["id"] }
103
+ end
104
+
105
+ it "doesn't append `s` to argument names that already end in `s`" do
106
+ query = <<-GRAPHQL
107
+ mutation($ids: [ID!]!) {
108
+ upvoteEnsemblesIds(input: {ensemblesIds: $ids}) {
109
+ ensembles {
110
+ id
111
+ }
112
+ }
113
+ }
114
+ GRAPHQL
115
+
116
+ res = Jazz::Schema.execute(query, variables: { ids: ["Ensemble/Robert Glasper Experiment", "Ensemble/Bela Fleck and the Flecktones"]})
117
+ assert_equal ["Ensemble/Robert Glasper Experiment", "Ensemble/Bela Fleck and the Flecktones"], res["data"]["upvoteEnsemblesIds"]["ensembles"].map { |e| e["id"] }
118
+ end
119
+
120
+ it "returns an error instead when the ID resolves to nil" do
121
+ res = Jazz::Schema.execute(query_str, variables: {
122
+ ids: ["Ensemble/Nonexistant Name"],
123
+ })
124
+ assert_nil res["data"].fetch("upvoteEnsembles")
125
+ assert_equal ['No object found for `ensembleIds: "Ensemble/Nonexistant Name"`'], res["errors"].map { |e| e["message"] }
126
+ end
127
+
128
+ it "returns an error instead when the ID resolves to an object of the wrong type" do
129
+ res = Jazz::Schema.execute(query_str, variables: {
130
+ ids: ["Instrument/Organ"],
131
+ })
132
+ assert_nil res["data"].fetch("upvoteEnsembles")
133
+ assert_equal ["No object found for `ensembleIds: \"Instrument/Organ\"`"], res["errors"].map { |e| e["message"] }
134
+ end
135
+
136
+ it "raises an authorization error when the type's auth fails" do
137
+ res = Jazz::Schema.execute(query_str, variables: {
138
+ ids: ["Ensemble/Spinal Tap"],
139
+ })
140
+ assert_nil res["data"].fetch("upvoteEnsembles")
141
+ # Failed silently
142
+ refute res.key?("errors")
143
+ end
53
144
  end
54
145
 
55
146
  describe "loading application objects" do
@@ -70,6 +161,48 @@ describe GraphQL::Schema::RelayClassicMutation do
70
161
  assert_equal "August Greene", res["data"]["renameEnsemble"]["ensemble"]["name"]
71
162
  end
72
163
 
164
+ it "loads arguments as objects when provided an interface type" do
165
+ query = <<-GRAPHQL
166
+ mutation($id: ID!, $newName: String!) {
167
+ renameNamedEntity(input: {namedEntityId: $id, newName: $newName}) {
168
+ namedEntity {
169
+ __typename
170
+ name
171
+ }
172
+ }
173
+ }
174
+ GRAPHQL
175
+
176
+ res = Jazz::Schema.execute(query, variables: { id: "Ensemble/Robert Glasper Experiment", newName: "August Greene"})
177
+ assert_equal "August Greene", res["data"]["renameNamedEntity"]["namedEntity"]["name"]
178
+ assert_equal "Ensemble", res["data"]["renameNamedEntity"]["namedEntity"]["__typename"]
179
+ end
180
+
181
+ it "loads arguments as objects when provided an union type" do
182
+ query = <<-GRAPHQL
183
+ mutation($id: ID!, $newName: String!) {
184
+ renamePerformingAct(input: {performingActId: $id, newName: $newName}) {
185
+ performingAct {
186
+ __typename
187
+ ... on Ensemble {
188
+ name
189
+ }
190
+ }
191
+ }
192
+ }
193
+ GRAPHQL
194
+
195
+ res = Jazz::Schema.execute(query, variables: { id: "Ensemble/Robert Glasper Experiment", newName: "August Greene"})
196
+ assert_equal "August Greene", res["data"]["renamePerformingAct"]["performingAct"]["name"]
197
+ assert_equal "Ensemble", res["data"]["renamePerformingAct"]["performingAct"]["__typename"]
198
+ end
199
+
200
+ it "uses the `as:` name when loading" do
201
+ band_query_str = query_str.sub("renameEnsemble", "renameEnsembleAsBand")
202
+ res = Jazz::Schema.execute(band_query_str, variables: { id: "Ensemble/Robert Glasper Experiment", newName: "August Greene"})
203
+ assert_equal "August Greene", res["data"]["renameEnsembleAsBand"]["ensemble"]["name"]
204
+ end
205
+
73
206
  it "returns an error instead when the ID resolves to nil" do
74
207
  res = Jazz::Schema.execute(query_str, variables: {
75
208
  id: "Ensemble/Nonexistant Name",
@@ -56,6 +56,15 @@ describe GraphQL::Schema::Resolver do
56
56
  end
57
57
  end
58
58
 
59
+ class ResolverWithPath < BaseResolver
60
+ type String, null: false
61
+
62
+ extras [:path]
63
+ def resolve(path:)
64
+ path.inspect
65
+ end
66
+ end
67
+
59
68
  class Resolver5 < Resolver4
60
69
  end
61
70
 
@@ -172,7 +181,7 @@ describe GraphQL::Schema::Resolver do
172
181
 
173
182
  class IntegerWrapper < GraphQL::Schema::Object
174
183
  implements HasValue
175
- field :value, Integer, null: false, method: :object
184
+ field :value, Integer, null: false, method: :itself
176
185
  end
177
186
 
178
187
  class PrepResolver9 < BaseResolver
@@ -192,28 +201,45 @@ describe GraphQL::Schema::Resolver do
192
201
  end
193
202
  end
194
203
 
204
+ class PrepResolver9Array < BaseResolver
205
+ argument :int_ids, [ID], required: true, loads: HasValue, as: :ints
206
+ # Make sure the lazy object is resolved properly:
207
+ type [HasValue], null: false
208
+ def object_from_id(type, id, ctx)
209
+ # Make sure a lazy object is handled appropriately
210
+ LazyBlock.new {
211
+ # Make sure that the right type ends up here
212
+ id.to_i + type.graphql_name.length
213
+ }
214
+ end
215
+
216
+ def resolve(ints:)
217
+ ints.map { |int| int * 3}
218
+ end
219
+ end
220
+
195
221
  class PrepResolver10 < BaseResolver
196
222
  argument :int1, Integer, required: true
197
- argument :int2, Integer, required: true
223
+ argument :int2, Integer, required: true, as: :integer_2
198
224
  type Integer, null: true
199
- def authorized?(int1:, int2:)
200
- if int1 + int2 > context[:max_int]
225
+ def authorized?(int1:, integer_2:)
226
+ if int1 + integer_2 > context[:max_int]
201
227
  raise GraphQL::ExecutionError, "Inputs too big"
202
- elsif context[:min_int] && (int1 + int2 < context[:min_int])
228
+ elsif context[:min_int] && (int1 + integer_2 < context[:min_int])
203
229
  false
204
230
  else
205
231
  true
206
232
  end
207
233
  end
208
234
 
209
- def resolve(int1:, int2:)
210
- int1 + int2
235
+ def resolve(int1:, integer_2:)
236
+ int1 + integer_2
211
237
  end
212
238
  end
213
239
 
214
240
  class PrepResolver11 < PrepResolver10
215
- def authorized?(int1:, int2:)
216
- LazyBlock.new { super(int1: int1 * 2, int2: int2) }
241
+ def authorized?(int1:, integer_2:)
242
+ LazyBlock.new { super(int1: int1 * 2, integer_2: integer_2) }
217
243
  end
218
244
  end
219
245
 
@@ -242,6 +268,47 @@ describe GraphQL::Schema::Resolver do
242
268
  end
243
269
  end
244
270
 
271
+ class PrepResolver14 < GraphQL::Schema::RelayClassicMutation
272
+ field :number, Integer, null: false
273
+
274
+ def authorized?
275
+ true
276
+ end
277
+
278
+ def resolve
279
+ { number: 1 }
280
+ end
281
+ end
282
+
283
+ class MutationWithNullableLoadsArgument < GraphQL::Schema::Mutation
284
+ argument :label_id, ID, required: false, loads: HasValue
285
+ argument :label_ids, [ID], required: false, loads: HasValue
286
+
287
+ field :inputs, String, null: false
288
+
289
+ def resolve(**inputs)
290
+ {
291
+ inputs: JSON.dump(inputs)
292
+ }
293
+ end
294
+ end
295
+
296
+ class MutationWithRequiredLoadsArgument < GraphQL::Schema::Mutation
297
+ argument :label_id, ID, required: true, loads: HasValue
298
+
299
+ field :inputs, String, null: false
300
+
301
+ def resolve(**inputs)
302
+ {
303
+ inputs: JSON.dump(inputs)
304
+ }
305
+ end
306
+ end
307
+
308
+ class Mutation < GraphQL::Schema::Object
309
+ field :mutation_with_nullable_loads_argument, mutation: MutationWithNullableLoadsArgument
310
+ field :mutation_with_required_loads_argument, mutation: MutationWithRequiredLoadsArgument
311
+ end
245
312
 
246
313
  class Query < GraphQL::Schema::Object
247
314
  class CustomField < GraphQL::Schema::Field
@@ -252,6 +319,14 @@ describe GraphQL::Schema::Resolver do
252
319
  end
253
320
  value
254
321
  end
322
+
323
+ def resolve(*)
324
+ value = super
325
+ if @name == "resolver3"
326
+ value << -1
327
+ end
328
+ value
329
+ end
255
330
  end
256
331
 
257
332
  field_class(CustomField)
@@ -265,6 +340,7 @@ describe GraphQL::Schema::Resolver do
265
340
  field :resolver_6, resolver: Resolver6
266
341
  field :resolver_7, resolver: Resolver7
267
342
  field :resolver_8, resolver: Resolver8
343
+ field :resolver_with_path, resolver: ResolverWithPath
268
344
 
269
345
  field :prep_resolver_1, resolver: PrepResolver1
270
346
  field :prep_resolver_2, resolver: PrepResolver2
@@ -274,16 +350,30 @@ describe GraphQL::Schema::Resolver do
274
350
  field :prep_resolver_6, resolver: PrepResolver6
275
351
  field :prep_resolver_7, resolver: PrepResolver7
276
352
  field :prep_resolver_9, resolver: PrepResolver9
353
+ field :prep_resolver_9_array, resolver: PrepResolver9Array
277
354
  field :prep_resolver_10, resolver: PrepResolver10
278
355
  field :prep_resolver_11, resolver: PrepResolver11
279
356
  field :prep_resolver_12, resolver: PrepResolver12
280
357
  field :prep_resolver_13, resolver: PrepResolver13
358
+ field :prep_resolver_14, resolver: PrepResolver14
281
359
  end
282
360
 
283
361
  class Schema < GraphQL::Schema
284
362
  query(Query)
363
+ mutation(Mutation)
285
364
  lazy_resolve LazyBlock, :value
286
365
  orphan_types IntegerWrapper
366
+ if TESTING_INTERPRETER
367
+ use GraphQL::Execution::Interpreter
368
+ end
369
+
370
+ def object_from_id(id, ctx)
371
+ if id == "invalid"
372
+ nil
373
+ else
374
+ 1
375
+ end
376
+ end
287
377
  end
288
378
  end
289
379
 
@@ -291,6 +381,22 @@ describe GraphQL::Schema::Resolver do
291
381
  ResolverTest::Schema.execute(*args)
292
382
  end
293
383
 
384
+ describe ".path" do
385
+ it "is the name" do
386
+ assert_equal "Resolver1", ResolverTest::Resolver1.path
387
+ end
388
+
389
+ it "is used for arguments and fields" do
390
+ assert_equal "Resolver1.value", ResolverTest::Resolver1.arguments["value"].path
391
+ assert_equal "PrepResolver7.int", ResolverTest::PrepResolver7.fields["int"].path
392
+ end
393
+
394
+ it "works on instances" do
395
+ r = ResolverTest::Resolver1.new(object: nil, context: nil)
396
+ assert_equal "Resolver1", r.path
397
+ end
398
+ end
399
+
294
400
  it "gets initialized for each resolution" do
295
401
  # State isn't shared between calls:
296
402
  res = exec_query " { r1: resolver1(value: 1) r2: resolver1 }"
@@ -320,6 +426,11 @@ describe GraphQL::Schema::Resolver do
320
426
  res = exec_query " { resolver4 } ", root_value: OpenStruct.new(value: 0)
321
427
  assert_equal 9, res["data"]["resolver4"]
322
428
  end
429
+
430
+ it "gets path from extras" do
431
+ res = exec_query " { resolverWithPath } ", root_value: OpenStruct.new(value: 0)
432
+ assert_equal '["resolverWithPath"]', res["data"]["resolverWithPath"]
433
+ end
323
434
  end
324
435
 
325
436
  describe "extras" do
@@ -426,6 +537,11 @@ describe GraphQL::Schema::Resolver do
426
537
  assert_equal 11, res["data"]["prepResolver10"]
427
538
  end
428
539
 
540
+ it "uses the argument name provided in `as:`" do
541
+ res = exec_query("{ prepResolver10(int1: 5, int2: 6) }", context: { max_int: 90 })
542
+ assert_equal 11, res["data"]["prepResolver10"]
543
+ end
544
+
429
545
  it "can return a lazy object" do
430
546
  # This is too big because it's modified in the overridden authorized? hook:
431
547
  res = exec_query("{ prepResolver11(int1: 3, int2: 5) }", context: { max_int: 9 })
@@ -462,6 +578,11 @@ describe GraphQL::Schema::Resolver do
462
578
  res = exec_query(str, context: { max_int: 100, min_int: 20 })
463
579
  assert_equal({ "prepResolver10" => nil, "prepResolver11" => nil }, res["data"])
464
580
  end
581
+
582
+ it "works with no arguments for RelayClassicMutation" do
583
+ res = exec_query("{ prepResolver14(input: {}) { number } }")
584
+ assert_equal 1, res["data"]["prepResolver14"]["number"]
585
+ end
465
586
  end
466
587
  end
467
588
 
@@ -471,6 +592,49 @@ describe GraphQL::Schema::Resolver do
471
592
  # (5 + 8) * 3
472
593
  assert_equal 39, res["data"]["prepResolver9"]["value"]
473
594
  end
595
+
596
+ it "supports loading array of ids" do
597
+ res = exec_query('{ prepResolver9Array(intIds: ["1", "10", "100"]) { value } }')
598
+ # (1 + 8) * 3
599
+ # (10 + 8) * 3
600
+ # (100 + 8) * 3
601
+ assert_equal [27, 54, 324], res["data"]["prepResolver9Array"].map { |v| v["value"] }
602
+ end
603
+
604
+ it "preserves `nil` when nullable argument is provided `null`" do
605
+ res = exec_query("mutation { mutationWithNullableLoadsArgument(labelId: null) { inputs } }")
606
+
607
+ assert_equal nil, res["errors"]
608
+ assert_equal '{"label":null}', res["data"]["mutationWithNullableLoadsArgument"]["inputs"]
609
+ end
610
+
611
+ it "preserves `nil` when nullable list argument is provided `null`" do
612
+ res = exec_query("mutation { mutationWithNullableLoadsArgument(labelIds: null) { inputs } }")
613
+
614
+ assert_equal nil, res["errors"]
615
+ assert_equal '{"labels":null}', res["data"]["mutationWithNullableLoadsArgument"]["inputs"]
616
+ end
617
+
618
+ it "omits omitted nullable argument" do
619
+ res = exec_query("mutation { mutationWithNullableLoadsArgument { inputs } }")
620
+
621
+ assert_equal nil, res["errors"]
622
+ assert_equal "{}", res["data"]["mutationWithNullableLoadsArgument"]["inputs"]
623
+ end
624
+
625
+ it "returns an error when nullable argument is provided an invalid value" do
626
+ res = exec_query('mutation { mutationWithNullableLoadsArgument(labelId: "invalid") { inputs } }')
627
+
628
+ assert res["errors"]
629
+ assert_equal 'No object found for `labelId: "invalid"`', res["errors"][0]["message"]
630
+ end
631
+
632
+ it "returns an error when a non-nullable argument is provided an invalid value" do
633
+ res = exec_query('mutation { mutationWithRequiredLoadsArgument(labelId: "invalid") { inputs } }')
634
+
635
+ assert res["errors"]
636
+ assert_equal 'No object found for `labelId: "invalid"`', res["errors"][0]["message"]
637
+ end
474
638
  end
475
639
  end
476
640
  end
@@ -2,6 +2,12 @@
2
2
  require "spec_helper"
3
3
 
4
4
  describe GraphQL::Schema::Scalar do
5
+ describe ".path" do
6
+ it "is the name" do
7
+ assert_equal "String", GraphQL::Types::String.path
8
+ end
9
+ end
10
+
5
11
  describe "in queries" do
6
12
  it "becomes output" do
7
13
  query_str = <<-GRAPHQL