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
@@ -13,22 +13,23 @@ describe GraphQL::Schema::CatchallMiddleware do
13
13
  Dummy::Schema.middleware.delete(GraphQL::Schema::CatchallMiddleware)
14
14
  end
15
15
 
16
- describe "rescuing errors" do
17
- let(:errors) { query.context.errors }
16
+ if TESTING_RESCUE_FROM
17
+ describe "rescuing errors" do
18
+ let(:errors) { query.context.errors }
18
19
 
19
- it "turns into error messages" do
20
- expected = {
21
- "data" => { "error" => nil },
22
- "errors"=> [
23
- {
24
- "message"=>"Internal error",
25
- "locations"=>[{"line"=>1, "column"=>17}],
26
- "path"=>["error"]
27
- },
28
- ]
29
- }
30
- assert_equal(expected, result)
20
+ it "turns into error messages" do
21
+ expected = {
22
+ "data" => { "error" => nil },
23
+ "errors"=> [
24
+ {
25
+ "message"=>"Internal error",
26
+ "locations"=>[{"line"=>1, "column"=>17}],
27
+ "path"=>["error"]
28
+ },
29
+ ]
30
+ }
31
+ assert_equal(expected, result)
32
+ end
31
33
  end
32
34
  end
33
-
34
35
  end
@@ -0,0 +1,81 @@
1
+ # frozen_string_literal: true
2
+ require "spec_helper"
3
+
4
+ describe GraphQL::Schema::Directive::Feature do
5
+ class FeatureSchema < GraphQL::Schema
6
+ class Feature < GraphQL::Schema::Directive::Feature
7
+ def self.enabled?(flag_name, obj, ctx)
8
+ !!ctx[flag_name.to_sym]
9
+ end
10
+ end
11
+
12
+ class Query < GraphQL::Schema::Object
13
+ field :int, Integer, null: false
14
+
15
+ def int
16
+ context[:int] ||= 0
17
+ context[:int] += 1
18
+ end
19
+ end
20
+
21
+ directive(Feature)
22
+ query(Query)
23
+ # only supported by the interpreter
24
+ use GraphQL::Execution::Interpreter
25
+ use GraphQL::Analysis::AST
26
+ end
27
+
28
+
29
+ it "skips or runs fields" do
30
+ str = '{
31
+ int1: int
32
+ int2: int @feature(flag: "flag1")
33
+ int3: int @feature(flag: "flag2")
34
+ }'
35
+
36
+ res = FeatureSchema.execute(str, context: { flag2: true })
37
+ # Int2 was not called, so `int3` is actually 2
38
+ assert_equal({"int1" => 1, "int3" => 2}, res["data"])
39
+ end
40
+
41
+ it "skips or runs fragment spreads" do
42
+ str = '{
43
+ ...F1
44
+ ...F2 @feature(flag: "flag1")
45
+ ...F3 @feature(flag: "flag2")
46
+ int4: int
47
+ }
48
+
49
+ fragment F1 on Query { int1: int }
50
+ fragment F2 on Query { int2: int }
51
+ fragment F3 on Query { int3: int }
52
+ '
53
+
54
+ res = FeatureSchema.execute(str, context: { flag1: true })
55
+ # `int3` was skipped
56
+ assert_equal({"int1" => 1, "int2" => 2, "int4" => 3}, res["data"])
57
+ end
58
+ it "skips or runs inline fragments" do
59
+ str = '{
60
+ ... { int1: int }
61
+ ... @feature(flag: "flag1") { int2: int }
62
+ ... @feature(flag: "flag2") { int3: int }
63
+ int4: int
64
+ }
65
+ '
66
+
67
+ res = FeatureSchema.execute(str, context: { flag2: true })
68
+ # `int2` was skipped
69
+ assert_equal({"int1" => 1, "int3" => 2, "int4" => 3}, res["data"])
70
+ end
71
+
72
+ it "returns an error if it's in the wrong place" do
73
+ str = '
74
+ query @feature(flag: "x") {
75
+ int
76
+ }
77
+ '
78
+ res = FeatureSchema.execute(str)
79
+ assert_equal ["'@feature' can't be applied to queries (allowed: fields, fragment spreads, inline fragments)"], res["errors"].map { |e| e["message"] }
80
+ end
81
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+ require "spec_helper"
3
+
4
+ describe GraphQL::Schema::Directive::Transform do
5
+ class TransformSchema < GraphQL::Schema
6
+ class Query < GraphQL::Schema::Object
7
+ field :echo, String, null: false do
8
+ argument :input, String, required: true
9
+ end
10
+
11
+ def echo(input:)
12
+ input
13
+ end
14
+ end
15
+
16
+ directive(GraphQL::Schema::Directive::Transform)
17
+
18
+ query(Query)
19
+ # only supported by the interpreter
20
+ use GraphQL::Execution::Interpreter
21
+ use GraphQL::Analysis::AST
22
+ end
23
+
24
+ it "transforms when applicable" do
25
+ str = '{
26
+ normal: echo(input: "Hello")
27
+ upcased: echo(input: "Hello") @transform(by: "upcase")
28
+ downcased: echo(input: "Hello") @transform(by: "downcase")
29
+ nonsense: echo(input: "Hello") @transform(by: "nonsense")
30
+ }'
31
+
32
+ res = TransformSchema.execute(str)
33
+
34
+ assert_equal "Hello", res["data"]["normal"]
35
+ assert_equal "HELLO", res["data"]["upcased"]
36
+ assert_equal "hello", res["data"]["downcased"]
37
+ assert_equal "Hello", res["data"]["nonsense"]
38
+ end
39
+ end
@@ -3,11 +3,18 @@ require "spec_helper"
3
3
 
4
4
  describe GraphQL::Schema::Enum do
5
5
  let(:enum) { Jazz::Family }
6
+
7
+ describe ".path" do
8
+ it "is the name" do
9
+ assert_equal "Family", enum.path
10
+ end
11
+ end
12
+
6
13
  describe "type info" do
7
14
  it "tells about the definition" do
8
15
  assert_equal "Family", enum.graphql_name
9
16
  assert_equal 29, enum.description.length
10
- assert_equal 6, enum.values.size
17
+ assert_equal 7, enum.values.size
11
18
  end
12
19
 
13
20
  it "inherits values and description" do
@@ -19,8 +26,8 @@ describe GraphQL::Schema::Enum do
19
26
  # Description was inherited
20
27
  assert_equal 29, new_enum.description.length
21
28
  # values were inherited without modifying the parent
22
- assert_equal 6, enum.values.size
23
- assert_equal 7, new_enum.values.size
29
+ assert_equal 7, enum.values.size
30
+ assert_equal 8, new_enum.values.size
24
31
  perc_value = new_enum.values["PERCUSSION"]
25
32
  assert_equal "new description", perc_value.description
26
33
  end
@@ -49,8 +56,10 @@ describe GraphQL::Schema::Enum do
49
56
 
50
57
  string_val = enum_type.values["STRING"]
51
58
  didg_val = enum_type.values["DIDGERIDOO"]
59
+ silence_val = enum_type.values["SILENCE"]
52
60
  assert_equal "STRING", string_val.name
53
61
  assert_equal :str, string_val.value
62
+ assert_equal false, silence_val.value
54
63
  assert_equal "DIDGERIDOO", didg_val.name
55
64
  assert_equal "Merged into BRASS", didg_val.deprecation_reason
56
65
  end
@@ -2,6 +2,17 @@
2
2
  require "spec_helper"
3
3
 
4
4
  describe GraphQL::Schema::EnumValue do
5
+ describe "#path" do
6
+ it "Has the owner name too" do
7
+ enum = Class.new(GraphQL::Schema::Enum) do
8
+ graphql_name "Abc"
9
+ value(:XYZ)
10
+ end
11
+
12
+ assert_equal "Abc.XYZ", enum.values["XYZ"].path
13
+ end
14
+ end
15
+
5
16
  describe "#deprecation_reason" do
6
17
  it "can be written and read" do
7
18
  enum_value = GraphQL::Schema::EnumValue.new(:x, owner: nil)
@@ -0,0 +1,115 @@
1
+ # frozen_string_literal: true
2
+ require "spec_helper"
3
+
4
+ describe GraphQL::Schema::FieldExtension do
5
+ module FilterTestSchema
6
+ class DoubleFilter < GraphQL::Schema::FieldExtension
7
+ def after_resolve(object:, value:, arguments:, context:, memo:)
8
+ value * 2
9
+ end
10
+ end
11
+
12
+ class MultiplyByOption < GraphQL::Schema::FieldExtension
13
+ def after_resolve(object:, value:, arguments:, context:, memo:)
14
+ value * options[:factor]
15
+ end
16
+ end
17
+
18
+ class MultiplyByArgument < GraphQL::Schema::FieldExtension
19
+ def apply
20
+ field.argument(:factor, Integer, required: true)
21
+ end
22
+
23
+ def resolve(object:, arguments:, context:)
24
+ factor = arguments.delete(:factor)
25
+ yield(object, arguments, factor)
26
+ end
27
+
28
+ def after_resolve(object:, value:, arguments:, context:, memo:)
29
+ value * memo
30
+ end
31
+ end
32
+
33
+ class MultiplyByArgumentUsingResolve < GraphQL::Schema::FieldExtension
34
+ def apply
35
+ field.argument(:factor, Integer, required: true)
36
+ end
37
+
38
+ # `yield` returns the user-returned value
39
+ # This method's return value is passed along
40
+ def resolve(object:, arguments:, context:)
41
+ factor = arguments.delete(:factor)
42
+ yield(object, arguments) * factor
43
+ end
44
+ end
45
+
46
+ class BaseObject < GraphQL::Schema::Object
47
+ end
48
+
49
+ class Query < BaseObject
50
+ field :doubled, Integer, null: false, resolver_method: :pass_thru do
51
+ extension(DoubleFilter)
52
+ argument :input, Integer, required: true
53
+ end
54
+
55
+ def pass_thru(input:)
56
+ input # return it as-is, it will be modified by extensions
57
+ end
58
+
59
+ field :tripled_by_option, Integer, null: false, resolver_method: :pass_thru do
60
+ extension(MultiplyByOption, factor: 3)
61
+ argument :input, Integer, required: true
62
+ end
63
+
64
+ field :multiply_input, Integer, null: false, resolver_method: :pass_thru, extensions: [MultiplyByArgument] do
65
+ argument :input, Integer, required: true
66
+ end
67
+
68
+ field :multiply_input2, Integer, null: false, resolver_method: :pass_thru, extensions: [MultiplyByArgumentUsingResolve] do
69
+ argument :input, Integer, required: true
70
+ end
71
+ end
72
+
73
+ class Schema < GraphQL::Schema
74
+ query(Query)
75
+ if TESTING_INTERPRETER
76
+ use GraphQL::Execution::Interpreter
77
+ end
78
+ end
79
+ end
80
+
81
+ def exec_query(query_str, **kwargs)
82
+ FilterTestSchema::Schema.execute(query_str, **kwargs)
83
+ end
84
+
85
+ describe "reading" do
86
+ it "has a reader method" do
87
+ field = FilterTestSchema::Query.fields["multiplyInput"]
88
+ assert_equal 1, field.extensions.size
89
+ assert_instance_of FilterTestSchema::MultiplyByArgument, field.extensions.first
90
+ end
91
+ end
92
+
93
+ describe "modifying return values" do
94
+ it "returns the modified value" do
95
+ res = exec_query("{ doubled(input: 5) }")
96
+ assert_equal 10, res["data"]["doubled"]
97
+ end
98
+
99
+ it "returns the modified value from `yield`" do
100
+ res = exec_query("{ multiplyInput2(input: 5, factor: 5) }")
101
+ assert_equal 25, res["data"]["multiplyInput2"]
102
+ end
103
+
104
+ it "has access to config options" do
105
+ # The factor of three came from an option
106
+ res = exec_query("{ tripledByOption(input: 4) }")
107
+ assert_equal 12, res["data"]["tripledByOption"]
108
+ end
109
+
110
+ it "can hide arguments from resolve methods" do
111
+ res = exec_query("{ multiplyInput(input: 3, factor: 5) }")
112
+ assert_equal 15, res["data"]["multiplyInput"]
113
+ end
114
+ end
115
+ end
@@ -6,6 +6,13 @@ describe GraphQL::Schema::Field do
6
6
  let(:object_class) { Jazz::Query }
7
7
  let(:field) { object_class.fields["inspectInput"] }
8
8
 
9
+ describe "path" do
10
+ it "is the object/interface and field name" do
11
+ assert_equal "Query.inspectInput", field.path
12
+ assert_equal "GloballyIdentifiable.id", Jazz::GloballyIdentifiableType.fields["id"].path
13
+ end
14
+ end
15
+
9
16
  it "uses the argument class" do
10
17
  arg_defn = field.graphql_definition.arguments.values.first
11
18
  assert_equal :ok, arg_defn.metadata[:custom]
@@ -38,6 +45,12 @@ describe GraphQL::Schema::Field do
38
45
  assert_equal 'underscored_arg', arg_defn.name
39
46
  end
40
47
 
48
+ it "works with arbitrary hash keys" do
49
+ result = Jazz::Schema.execute "{ complexHashKey }", root_value: { :'foo bar/fizz-buzz' => "OK!"}
50
+ hash_val = result["data"]["complexHashKey"]
51
+ assert_equal "OK!", hash_val, "It looked up the hash key"
52
+ end
53
+
41
54
  it "exposes the method override" do
42
55
  object = Class.new(Jazz::BaseObject) do
43
56
  field :t, String, method: :tt, null: true
@@ -100,6 +113,22 @@ describe GraphQL::Schema::Field do
100
113
  assert_equal ["find", "addError"], err["path"]
101
114
  assert_equal [{"line"=>4, "column"=>15}], err["locations"]
102
115
  end
116
+
117
+ it "can get methods from the field instance" do
118
+ query_str = <<-GRAPHQL
119
+ {
120
+ upcaseCheck1
121
+ upcaseCheck2
122
+ upcaseCheck3
123
+ upcaseCheck4
124
+ }
125
+ GRAPHQL
126
+ res = Jazz::Schema.execute(query_str)
127
+ assert_equal "nil", res["data"].fetch("upcaseCheck1")
128
+ assert_equal "false", res["data"]["upcaseCheck2"]
129
+ assert_equal "TRUE", res["data"]["upcaseCheck3"]
130
+ assert_equal "\"WHY NOT?\"", res["data"]["upcaseCheck4"]
131
+ end
103
132
  end
104
133
 
105
134
  it "is the #owner of its arguments" do
@@ -205,14 +234,12 @@ describe GraphQL::Schema::Field do
205
234
  end
206
235
 
207
236
  it "makes a suggestion when the type is false" do
208
- thing = Class.new(GraphQL::Schema::Object) do
209
- graphql_name "Thing"
210
- # False might come from an invalid `!`
211
- field :stuff, false, null: false
212
- end
213
-
214
237
  err = assert_raises ArgumentError do
215
- thing.fields["stuff"].type
238
+ Class.new(GraphQL::Schema::Object) do
239
+ graphql_name "Thing"
240
+ # False might come from an invalid `!`
241
+ field :stuff, false, null: false
242
+ end
216
243
  end
217
244
 
218
245
  assert_includes err.message, "Thing.stuff"
@@ -258,4 +285,17 @@ describe GraphQL::Schema::Field do
258
285
  assert_equal "Broken!!", field.deprecation_reason
259
286
  end
260
287
  end
288
+
289
+ describe "#original_name" do
290
+ it "is exactly the same as the passed in name" do
291
+ field = GraphQL::Schema::Field.from_options(
292
+ :my_field,
293
+ String,
294
+ null: false,
295
+ camelize: true
296
+ )
297
+
298
+ assert_equal :my_field, field.original_name
299
+ end
300
+ end
261
301
  end
@@ -3,6 +3,17 @@ require "spec_helper"
3
3
 
4
4
  describe GraphQL::Schema::InputObject do
5
5
  let(:input_object) { Jazz::EnsembleInput }
6
+
7
+ describe ".path" do
8
+ it "is the name" do
9
+ assert_equal "EnsembleInput", input_object.path
10
+ end
11
+
12
+ it "is used in argument paths" do
13
+ assert_equal "EnsembleInput.name", input_object.arguments["name"].path
14
+ end
15
+ end
16
+
6
17
  describe "type info" do
7
18
  it "has it" do
8
19
  assert_equal "EnsembleInput", input_object.graphql_name
@@ -70,6 +81,9 @@ describe GraphQL::Schema::InputObject do
70
81
 
71
82
  class Schema < GraphQL::Schema
72
83
  query(Query)
84
+ if TESTING_INTERPRETER
85
+ use GraphQL::Execution::Interpreter
86
+ end
73
87
  end
74
88
  end
75
89
 
@@ -109,6 +123,13 @@ describe GraphQL::Schema::InputObject do
109
123
  end
110
124
  end
111
125
 
126
+ describe "when used with default_value" do
127
+ it "comes as an instance" do
128
+ res = Jazz::Schema.execute("{ defaultValueTest }")
129
+ assert_equal "Jazz::InspectableInput -> {:string_value=>\"S\"}", res["data"]["defaultValueTest"]
130
+ end
131
+ end
132
+
112
133
  describe "#to_h" do
113
134
  module InputObjectToHTest
114
135
  class TestInput1 < GraphQL::Schema::InputObject
@@ -140,4 +161,78 @@ describe GraphQL::Schema::InputObject do
140
161
  assert_equal({ a: 1, b: 2, input_object: { d: 3, e: 4 } }, input_object.to_h)
141
162
  end
142
163
  end
164
+
165
+ describe "#dig" do
166
+ module InputObjectDigTest
167
+ class TestInput1 < GraphQL::Schema::InputObject
168
+ graphql_name "TestInput1"
169
+ argument :d, Int, required: true
170
+ argument :e, Int, required: true
171
+ end
172
+
173
+ class TestInput2 < GraphQL::Schema::InputObject
174
+ graphql_name "TestInput2"
175
+ argument :a, Int, required: true
176
+ argument :b, Int, required: true
177
+ argument :c, TestInput1, as: :inputObject, required: true
178
+ end
179
+
180
+ TestInput1.to_graphql
181
+ TestInput2.to_graphql
182
+ end
183
+ arg_values = {a: 1, b: 2, c: { d: 3, e: 4 }}
184
+
185
+ input_object = InputObjectDigTest::TestInput2.new(
186
+ arg_values,
187
+ context: nil,
188
+ defaults_used: Set.new
189
+ )
190
+ it "returns the value at that key" do
191
+ assert_equal 1, input_object.dig("a")
192
+ assert_equal 1, input_object.dig(:a)
193
+ assert input_object.dig("inputObject").is_a?(GraphQL::Schema::InputObject)
194
+ end
195
+
196
+ it "works with nested keys" do
197
+ assert_equal 3, input_object.dig("inputObject", "d")
198
+ assert_equal 3, input_object.dig(:inputObject, :d)
199
+ assert_equal 3, input_object.dig("inputObject", :d)
200
+ assert_equal 3, input_object.dig(:inputObject, "d")
201
+ end
202
+
203
+ it "returns nil for missing keys" do
204
+ assert_nil input_object.dig("z")
205
+ assert_nil input_object.dig(7)
206
+ end
207
+
208
+ it "handles underscored keys" do
209
+ # TODO - shouldn't this work too?
210
+ # assert_equal 3, input_object.dig('input_object', 'd')
211
+ assert_equal 3, input_object.dig(:input_object, :d)
212
+ end
213
+ end
214
+
215
+ describe "introspection" do
216
+ it "returns input fields" do
217
+ res = Jazz::Schema.execute('
218
+ {
219
+ __type(name: "InspectableInput") {
220
+ name
221
+ inputFields { name }
222
+ }
223
+ __schema {
224
+ types {
225
+ name
226
+ inputFields { name }
227
+ }
228
+ }
229
+ }')
230
+ # Test __type
231
+ assert_equal ["stringValue", "nestedInput", "legacyInput"], res["data"]["__type"]["inputFields"].map { |f| f["name"] }
232
+ # Test __schema { types }
233
+ # It's upcased to test custom introspection
234
+ input_type = res["data"]["__schema"]["types"].find { |t| t["name"] == "INSPECTABLEINPUT" }
235
+ assert_equal ["stringValue", "nestedInput", "legacyInput"], input_type["inputFields"].map { |f| f["name"] }
236
+ end
237
+ end
143
238
  end
@@ -26,6 +26,9 @@ module InstrumentationSpec
26
26
  class Schema < GraphQL::Schema
27
27
  query Query
28
28
  orphan_types [SomeType]
29
+ if TESTING_INTERPRETER
30
+ use GraphQL::Execution::Interpreter
31
+ end
29
32
  end
30
33
  end
31
34
 
@@ -4,6 +4,12 @@ require "spec_helper"
4
4
  describe GraphQL::Schema::Interface do
5
5
  let(:interface) { Jazz::GloballyIdentifiableType }
6
6
 
7
+ describe ".path" do
8
+ it "is the name" do
9
+ assert_equal "GloballyIdentifiable", interface.path
10
+ end
11
+ end
12
+
7
13
  describe "type info" do
8
14
  it "tells its type info" do
9
15
  assert_equal "GloballyIdentifiable", interface.graphql_name
@@ -77,11 +83,11 @@ describe GraphQL::Schema::Interface do
77
83
  interface = Module.new do
78
84
  include GraphQL::Schema::Interface
79
85
  graphql_name "MyInterface"
80
- orphan_types Dummy::CheeseType, Dummy::HoneyType
86
+ orphan_types Dummy::Cheese, Dummy::Honey
81
87
  end
82
88
 
83
89
  interface_type = interface.to_graphql
84
- assert_equal [Dummy::CheeseType, Dummy::HoneyType], interface_type.orphan_types
90
+ assert_equal [Dummy::Cheese, Dummy::Honey], interface_type.orphan_types
85
91
  end
86
92
  end
87
93
 
@@ -13,7 +13,7 @@ describe GraphQL::Schema::IntrospectionSystem do
13
13
  assert_equal "ENSEMBLE", res["data"]["__type"]["name"]
14
14
  end
15
15
 
16
- it "serves custom entry points" do
16
+ it "serves custom entry points" do
17
17
  res = Jazz::Schema.execute("{ __classname }", root_value: Set.new)
18
18
  assert_equal "Set", res["data"]["__classname"]
19
19
  end
@@ -35,5 +35,13 @@ describe GraphQL::Schema::IntrospectionSystem do
35
35
  res = Dummy::Schema.execute("{ ensembles { __typenameLength } }")
36
36
  assert_equal 1, res["errors"].length
37
37
  end
38
+
39
+ it "runs the introspection query" do
40
+ res = Jazz::Schema.execute(GraphQL::Introspection::INTROSPECTION_QUERY)
41
+ assert res
42
+ query_type = res["data"]["__schema"]["types"].find { |t| t["name"] == "QUERY" }
43
+ ensembles_field = query_type["fields"].find { |f| f["name"] == "ensembles" }
44
+ assert_equal [], ensembles_field["args"]
45
+ end
38
46
  end
39
47
  end
@@ -103,6 +103,7 @@ describe GraphQL::Schema::Loader do
103
103
  argument :id, !types.ID
104
104
  argument :varied, variant_input_type, default_value: { id: "123", int: 234, float: 2.3, enum: :foo, sub: [{ string: "str" }] }
105
105
  argument :variedWithNull, variant_input_type_with_nulls, default_value: { id: nil, int: nil, float: nil, enum: nil, sub: nil, bigint: nil, bool: nil }
106
+ argument :variedArray, types[variant_input_type], default_value: [{ id: "123", int: 234, float: 2.3, enum: :foo, sub: [{ string: "str" }] }]
106
107
  argument :enum, choice_type, default_value: :foo
107
108
  argument :array, types[!types.String], default_value: ["foo", "bar"]
108
109
  end
@@ -229,6 +230,10 @@ describe GraphQL::Schema::Loader do
229
230
  assert_equal varied.default_value, { 'id' => "123", 'int' => 234, 'float' => 2.3, 'enum' => "FOO", 'sub' => [{ 'string' => "str" }] }
230
231
  assert !varied.default_value.key?('bool'), 'Omits default value for unspecified arguments'
231
232
 
233
+ variedArray = field.arguments['variedArray']
234
+ assert_equal variedArray.default_value, [{ 'id' => "123", 'int' => 234, 'float' => 2.3, 'enum' => "FOO", 'sub' => [{ 'string' => "str" }] }]
235
+ assert !variedArray.default_value.first.key?('bool'), 'Omits default value for unspecified arguments'
236
+
232
237
  array = field.arguments['array']
233
238
  assert_equal array.default_value, ["foo", "bar"]
234
239
  end
@@ -6,6 +6,10 @@ describe GraphQL::Schema::Member::AcceptsDefinition do
6
6
  accepts_definition :set_metadata
7
7
  set_metadata :a, 999
8
8
 
9
+ if TESTING_INTERPRETER
10
+ use GraphQL::Execution::Interpreter
11
+ end
12
+
9
13
  class BaseField < GraphQL::Schema::Field
10
14
  class BaseField < GraphQL::Schema::Argument
11
15
  accepts_definition :metadata