graphql 1.7.6 → 1.8.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 (289) hide show
  1. checksums.yaml +4 -4
  2. data/lib/generators/graphql/function_generator.rb +1 -1
  3. data/lib/generators/graphql/install_generator.rb +14 -8
  4. data/lib/generators/graphql/loader_generator.rb +1 -1
  5. data/lib/generators/graphql/mutation_generator.rb +6 -1
  6. data/lib/generators/graphql/templates/function.erb +2 -2
  7. data/lib/generators/graphql/templates/loader.erb +2 -2
  8. data/lib/generators/graphql/templates/schema.erb +1 -1
  9. data/lib/graphql/argument.rb +25 -19
  10. data/lib/graphql/backtrace/tracer.rb +16 -22
  11. data/lib/graphql/backtrace.rb +1 -1
  12. data/lib/graphql/backwards_compatibility.rb +2 -3
  13. data/lib/graphql/base_type.rb +31 -31
  14. data/lib/graphql/compatibility/query_parser_specification/parse_error_specification.rb +14 -0
  15. data/lib/graphql/compatibility/query_parser_specification.rb +117 -0
  16. data/lib/graphql/define/assign_object_field.rb +5 -12
  17. data/lib/graphql/deprecated_dsl.rb +42 -0
  18. data/lib/graphql/directive.rb +1 -0
  19. data/lib/graphql/enum_type.rb +3 -1
  20. data/lib/graphql/execution/execute.rb +21 -13
  21. data/lib/graphql/execution/instrumentation.rb +82 -0
  22. data/lib/graphql/execution/lazy/lazy_method_map.rb +1 -1
  23. data/lib/graphql/execution/lazy/resolve.rb +1 -3
  24. data/lib/graphql/execution/multiplex.rb +12 -29
  25. data/lib/graphql/execution.rb +1 -0
  26. data/lib/graphql/field.rb +21 -4
  27. data/lib/graphql/function.rb +14 -0
  28. data/lib/graphql/input_object_type.rb +3 -1
  29. data/lib/graphql/interface_type.rb +5 -3
  30. data/lib/graphql/internal_representation/node.rb +26 -14
  31. data/lib/graphql/internal_representation/visit.rb +3 -6
  32. data/lib/graphql/introspection/base_object.rb +16 -0
  33. data/lib/graphql/introspection/directive_location_enum.rb +11 -7
  34. data/lib/graphql/introspection/directive_type.rb +23 -16
  35. data/lib/graphql/introspection/dynamic_fields.rb +11 -0
  36. data/lib/graphql/introspection/entry_points.rb +29 -0
  37. data/lib/graphql/introspection/enum_value_type.rb +16 -11
  38. data/lib/graphql/introspection/field_type.rb +21 -12
  39. data/lib/graphql/introspection/input_value_type.rb +26 -23
  40. data/lib/graphql/introspection/schema_field.rb +7 -2
  41. data/lib/graphql/introspection/schema_type.rb +36 -22
  42. data/lib/graphql/introspection/type_by_name_field.rb +10 -2
  43. data/lib/graphql/introspection/type_kind_enum.rb +10 -6
  44. data/lib/graphql/introspection/type_type.rb +85 -23
  45. data/lib/graphql/introspection/typename_field.rb +1 -0
  46. data/lib/graphql/introspection.rb +3 -10
  47. data/lib/graphql/language/block_string.rb +47 -0
  48. data/lib/graphql/language/document_from_schema_definition.rb +280 -0
  49. data/lib/graphql/language/generation.rb +3 -182
  50. data/lib/graphql/language/lexer.rb +144 -69
  51. data/lib/graphql/language/lexer.rl +15 -4
  52. data/lib/graphql/language/nodes.rb +141 -78
  53. data/lib/graphql/language/parser.rb +677 -630
  54. data/lib/graphql/language/parser.y +18 -12
  55. data/lib/graphql/language/printer.rb +361 -0
  56. data/lib/graphql/language/token.rb +10 -3
  57. data/lib/graphql/language.rb +3 -0
  58. data/lib/graphql/non_null_type.rb +1 -1
  59. data/lib/graphql/object_type.rb +1 -6
  60. data/lib/graphql/query/arguments.rb +63 -32
  61. data/lib/graphql/query/context.rb +32 -2
  62. data/lib/graphql/query/literal_input.rb +4 -1
  63. data/lib/graphql/query/null_context.rb +1 -1
  64. data/lib/graphql/query/result.rb +1 -1
  65. data/lib/graphql/query/variables.rb +21 -3
  66. data/lib/graphql/query.rb +19 -6
  67. data/lib/graphql/railtie.rb +109 -0
  68. data/lib/graphql/relay/connection_resolve.rb +3 -0
  69. data/lib/graphql/relay/connection_type.rb +5 -3
  70. data/lib/graphql/relay/edge_type.rb +2 -1
  71. data/lib/graphql/relay/global_id_resolve.rb +5 -1
  72. data/lib/graphql/relay/mongo_relation_connection.rb +40 -0
  73. data/lib/graphql/relay/mutation/instrumentation.rb +1 -1
  74. data/lib/graphql/relay/mutation/resolve.rb +5 -1
  75. data/lib/graphql/relay/relation_connection.rb +14 -19
  76. data/lib/graphql/relay/type_extensions.rb +30 -0
  77. data/lib/graphql/relay.rb +2 -0
  78. data/lib/graphql/scalar_type.rb +14 -2
  79. data/lib/graphql/schema/argument.rb +92 -0
  80. data/lib/graphql/schema/build_from_definition.rb +64 -18
  81. data/lib/graphql/schema/enum.rb +85 -0
  82. data/lib/graphql/schema/enum_value.rb +74 -0
  83. data/lib/graphql/schema/field.rb +372 -0
  84. data/lib/graphql/schema/finder.rb +153 -0
  85. data/lib/graphql/schema/input_object.rb +87 -0
  86. data/lib/graphql/schema/interface.rb +105 -0
  87. data/lib/graphql/schema/introspection_system.rb +93 -0
  88. data/lib/graphql/schema/late_bound_type.rb +32 -0
  89. data/lib/graphql/schema/list.rb +32 -0
  90. data/lib/graphql/schema/loader.rb +2 -2
  91. data/lib/graphql/schema/member/accepts_definition.rb +152 -0
  92. data/lib/graphql/schema/member/base_dsl_methods.rb +100 -0
  93. data/lib/graphql/schema/member/build_type.rb +137 -0
  94. data/lib/graphql/schema/member/cached_graphql_definition.rb +26 -0
  95. data/lib/graphql/schema/member/graphql_type_names.rb +21 -0
  96. data/lib/graphql/schema/member/has_arguments.rb +50 -0
  97. data/lib/graphql/schema/member/has_fields.rb +130 -0
  98. data/lib/graphql/schema/member/instrumentation.rb +115 -0
  99. data/lib/graphql/schema/member/type_system_helpers.rb +34 -0
  100. data/lib/graphql/schema/member.rb +28 -0
  101. data/lib/graphql/schema/middleware_chain.rb +5 -1
  102. data/lib/graphql/schema/mutation.rb +138 -0
  103. data/lib/graphql/schema/non_null.rb +38 -0
  104. data/lib/graphql/schema/object.rb +81 -0
  105. data/lib/graphql/schema/printer.rb +33 -266
  106. data/lib/graphql/schema/relay_classic_mutation.rb +87 -0
  107. data/lib/graphql/schema/rescue_middleware.rb +8 -7
  108. data/lib/graphql/schema/resolver.rb +122 -0
  109. data/lib/graphql/schema/scalar.rb +35 -0
  110. data/lib/graphql/schema/traversal.rb +102 -22
  111. data/lib/graphql/schema/union.rb +36 -0
  112. data/lib/graphql/schema/validation.rb +3 -2
  113. data/lib/graphql/schema.rb +381 -12
  114. data/lib/graphql/static_validation/definition_dependencies.rb +1 -1
  115. data/lib/graphql/static_validation/literal_validator.rb +16 -4
  116. data/lib/graphql/static_validation/rules/fields_are_defined_on_type.rb +6 -6
  117. data/lib/graphql/static_validation/rules/fields_have_appropriate_selections.rb +5 -1
  118. data/lib/graphql/static_validation/rules/fields_will_merge.rb +15 -8
  119. data/lib/graphql/static_validation/rules/variables_are_used_and_defined.rb +11 -1
  120. data/lib/graphql/static_validation/validation_context.rb +1 -1
  121. data/lib/graphql/subscriptions/action_cable_subscriptions.rb +7 -5
  122. data/lib/graphql/subscriptions/instrumentation.rb +5 -1
  123. data/lib/graphql/subscriptions/serialize.rb +2 -0
  124. data/lib/graphql/subscriptions.rb +90 -16
  125. data/lib/graphql/tracing/data_dog_tracing.rb +49 -0
  126. data/lib/graphql/tracing/new_relic_tracing.rb +26 -0
  127. data/lib/graphql/tracing/platform_tracing.rb +20 -7
  128. data/lib/graphql/tracing/scout_tracing.rb +2 -2
  129. data/lib/graphql/tracing.rb +1 -0
  130. data/lib/graphql/unresolved_type_error.rb +3 -2
  131. data/lib/graphql/upgrader/member.rb +894 -0
  132. data/lib/graphql/upgrader/schema.rb +37 -0
  133. data/lib/graphql/version.rb +1 -1
  134. data/lib/graphql.rb +5 -25
  135. data/readme.md +2 -2
  136. data/spec/dummy/app/channels/graphql_channel.rb +23 -2
  137. data/spec/dummy/log/development.log +239 -0
  138. data/spec/dummy/log/test.log +410 -0
  139. data/spec/dummy/test/system/action_cable_subscription_test.rb +4 -0
  140. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/-x/-xYZjAnuuzgR79fcznLTQtSdh6AARxu8FcQ_J6p7L3U.cache +0 -0
  141. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/13/13HiV12xyoQvT-1L39ZzLwMZxjyaGMiENmfw7f-QTIc.cache +0 -0
  142. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/3W/3Wtf5pCWdqq0AB-iB0Y9uUNrTkruRxIEf1XFn_BETU0.cache +1 -0
  143. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/5i/5iguGafb4hOn8262Kn8Q37ogNN9MxxQKGKNzHAzUcvI.cache +1 -0
  144. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/8m/8mj2T6yy847Mc2Z7k3Xzh8O91hhVJt3NrPe8ASNDlIA.cache +1 -0
  145. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/DT/DTQyMpr4ABZYQetsdRJ5A7S4jf1r3ie4FGOR7GZBNSs.cache +3 -0
  146. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Dq/DqJ5_yJPrP5iLlOQyTQsjAVI5FE5LCVDkED0f7GgsSo.cache +3 -0
  147. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/F8/F8MUNRzORGFgr329fNM0xLaoWCXdv3BIalT7dsvLfjs.cache +0 -0
  148. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/KB/KB07ZaKNC5uXJ7TjLi-WqnY6g7dq8wWp_8N3HNjBNxg.cache +0 -0
  149. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Rw/RwDuCV-XpnCtjNkvhpJfBuxXMk0b5AD3L9eR6M-wcy0.cache +3 -0
  150. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/UL/ULdjhhb0bRuqmaG7XSZlFYzGYCXTDnqZuJBTWRlzqgw.cache +0 -0
  151. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Up/UpPNgh0yYoUsyMDh5zWqe_U6qJIyTC6-dxMMAs1vvlM.cache +1 -0
  152. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/Wg/Wguh-szFGTI1gaL6npYwPekMXflugRei7F_mOyRucXg.cache +0 -0
  153. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/X-/X-khLYMA9mqFRPg3zAi86mREDxpKl4bdKYp3uF6WHos.cache +0 -0
  154. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/bi/BIkdhfxsezxM4q-HZ4oCNTq97WEJTigcq0tpX2cDvbY.cache +0 -0
  155. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/ff/FfxmA4CMHQZT7exx0G7NS1Wpcnny0vzp-Jhc2H36bp8.cache +1 -0
  156. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/gE/gEiiG4GZNy_djEjK2pHm_NgA-gyhLZhdQvo0Yt96GqE.cache +0 -0
  157. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/gn/gnA9ZSqpjccNL2m8pe_jBvY6SinXlCzXDWyop83Od8s.cache +1 -0
  158. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/lO/lOAan3cMwCE_Hli6gsDML88xFNfn0nxPmvrSkW7eEOw.cache +1 -0
  159. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/m1/M1pv8MJEPLXGLvS8QxVh3DSO9cI4mRt5FHFWdrvUj6o.cache +2 -0
  160. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/m7/m77qH7ZqH0_0SmwJbiKGDd-aLau1Dav847DC6ge46zY.cache +1 -0
  161. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/sj/sjRjnjRB37lH2vrgtkdJ8Cz84__IJ978IuKTM7HcztI.cache +0 -0
  162. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/um/um1JrirR4hJhK-1rE-HywlyCi5ibgxHVrReiujZBWJM.cache +1 -0
  163. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/v4/v4fwVytD7ITcE0_GDbslZEYud8a5Okm85fV1o7SDl6g.cache +0 -0
  164. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/v_/v_0PAQt0iipQjFP5zjgkkk9Stnpf4VzvnMv67d1Keuw.cache +1 -0
  165. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/wd/wdT9U4MKxe1PyqNjVuCKMpCl3dxGCIRJIlwUTfh2DQU.cache +1 -0
  166. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/xI/xIaxut_fEIhKBDqljTNwYaADK9kj3gG0ESrfHs-5_og.cache +3 -0
  167. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/y0/y0SJOqIx2fn1SKqOkAihsQow0trRJrSIyAswufVuoA8.cache +0 -0
  168. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/zg/zgpzeaX-KZErHyGJ1aBH3ZusweNXMneVZule88XsIJI.cache +1 -0
  169. data/spec/dummy/tmp/cache/assets/sprockets/v3.0/zy/zYFltDy-8VC-uKq2BVEiJJyYXNFvVzAKuMlR3ZIYZsk.cache +0 -0
  170. data/spec/dummy/tmp/screenshots/failures_test_it_handles_subscriptions.png +0 -0
  171. data/spec/fixtures/upgrader/account.original.rb +19 -0
  172. data/spec/fixtures/upgrader/account.transformed.rb +20 -0
  173. data/spec/fixtures/upgrader/blame_range.original.rb +43 -0
  174. data/spec/fixtures/upgrader/blame_range.transformed.rb +30 -0
  175. data/spec/fixtures/upgrader/date_time.original.rb +24 -0
  176. data/spec/fixtures/upgrader/date_time.transformed.rb +23 -0
  177. data/spec/fixtures/upgrader/delete_project.original.rb +28 -0
  178. data/spec/fixtures/upgrader/delete_project.transformed.rb +27 -0
  179. data/spec/fixtures/upgrader/gist_order_field.original.rb +14 -0
  180. data/spec/fixtures/upgrader/gist_order_field.transformed.rb +13 -0
  181. data/spec/fixtures/upgrader/increment_count.original.rb +59 -0
  182. data/spec/fixtures/upgrader/increment_count.transformed.rb +50 -0
  183. data/spec/fixtures/upgrader/photo.original.rb +10 -0
  184. data/spec/fixtures/upgrader/photo.transformed.rb +12 -0
  185. data/spec/fixtures/upgrader/release_order.original.rb +15 -0
  186. data/spec/fixtures/upgrader/release_order.transformed.rb +14 -0
  187. data/spec/fixtures/upgrader/starrable.original.rb +49 -0
  188. data/spec/fixtures/upgrader/starrable.transformed.rb +46 -0
  189. data/spec/fixtures/upgrader/subscribable.original.rb +55 -0
  190. data/spec/fixtures/upgrader/subscribable.transformed.rb +51 -0
  191. data/spec/fixtures/upgrader/type_x.original.rb +65 -0
  192. data/spec/fixtures/upgrader/type_x.transformed.rb +56 -0
  193. data/spec/generators/graphql/function_generator_spec.rb +26 -0
  194. data/spec/generators/graphql/install_generator_spec.rb +1 -1
  195. data/spec/generators/graphql/loader_generator_spec.rb +24 -0
  196. data/spec/graphql/analysis/max_query_complexity_spec.rb +3 -3
  197. data/spec/graphql/analysis/max_query_depth_spec.rb +3 -3
  198. data/spec/graphql/argument_spec.rb +21 -0
  199. data/spec/graphql/backtrace_spec.rb +10 -0
  200. data/spec/graphql/base_type_spec.rb +42 -0
  201. data/spec/graphql/boolean_type_spec.rb +3 -3
  202. data/spec/graphql/directive_spec.rb +3 -1
  203. data/spec/graphql/enum_type_spec.rb +18 -5
  204. data/spec/graphql/execution/execute_spec.rb +4 -4
  205. data/spec/graphql/execution/instrumentation_spec.rb +165 -0
  206. data/spec/graphql/execution/multiplex_spec.rb +2 -2
  207. data/spec/graphql/execution_error_spec.rb +18 -0
  208. data/spec/graphql/float_type_spec.rb +2 -2
  209. data/spec/graphql/id_type_spec.rb +1 -1
  210. data/spec/graphql/input_object_type_spec.rb +15 -2
  211. data/spec/graphql/int_type_spec.rb +2 -2
  212. data/spec/graphql/interface_type_spec.rb +12 -0
  213. data/spec/graphql/internal_representation/rewrite_spec.rb +2 -2
  214. data/spec/graphql/introspection/schema_type_spec.rb +2 -0
  215. data/spec/graphql/language/block_string_spec.rb +70 -0
  216. data/spec/graphql/language/document_from_schema_definition_spec.rb +770 -0
  217. data/spec/graphql/language/generation_spec.rb +21 -186
  218. data/spec/graphql/language/lexer_spec.rb +21 -1
  219. data/spec/graphql/language/nodes_spec.rb +21 -12
  220. data/spec/graphql/language/parser_spec.rb +1 -1
  221. data/spec/graphql/language/printer_spec.rb +203 -0
  222. data/spec/graphql/object_type_spec.rb +22 -0
  223. data/spec/graphql/query/arguments_spec.rb +25 -15
  224. data/spec/graphql/query/context_spec.rb +18 -0
  225. data/spec/graphql/query/executor_spec.rb +2 -1
  226. data/spec/graphql/query/serial_execution/value_resolution_spec.rb +2 -8
  227. data/spec/graphql/query/variables_spec.rb +42 -1
  228. data/spec/graphql/query_spec.rb +31 -5
  229. data/spec/graphql/rake_task_spec.rb +3 -1
  230. data/spec/graphql/relay/base_connection_spec.rb +1 -1
  231. data/spec/graphql/relay/connection_instrumentation_spec.rb +2 -2
  232. data/spec/graphql/relay/connection_resolve_spec.rb +1 -1
  233. data/spec/graphql/relay/connection_type_spec.rb +1 -1
  234. data/spec/graphql/relay/mongo_relation_connection_spec.rb +474 -0
  235. data/spec/graphql/relay/mutation_spec.rb +9 -7
  236. data/spec/graphql/relay/range_add_spec.rb +5 -1
  237. data/spec/graphql/relay/relation_connection_spec.rb +65 -1
  238. data/spec/graphql/schema/argument_spec.rb +87 -0
  239. data/spec/graphql/schema/build_from_definition_spec.rb +89 -5
  240. data/spec/graphql/schema/enum_spec.rb +74 -0
  241. data/spec/graphql/schema/field_spec.rb +225 -0
  242. data/spec/graphql/schema/finder_spec.rb +135 -0
  243. data/spec/graphql/schema/input_object_spec.rb +111 -0
  244. data/spec/graphql/schema/instrumentation_spec.rb +40 -0
  245. data/spec/graphql/schema/interface_spec.rb +185 -0
  246. data/spec/graphql/schema/introspection_system_spec.rb +39 -0
  247. data/spec/graphql/schema/member/accepts_definition_spec.rb +111 -0
  248. data/spec/graphql/schema/member/build_type_spec.rb +17 -0
  249. data/spec/graphql/schema/member/has_fields_spec.rb +129 -0
  250. data/spec/graphql/schema/member/type_system_helpers_spec.rb +63 -0
  251. data/spec/graphql/schema/mutation_spec.rb +148 -0
  252. data/spec/graphql/schema/object_spec.rb +175 -0
  253. data/spec/graphql/schema/printer_spec.rb +111 -15
  254. data/spec/graphql/schema/relay_classic_mutation_spec.rb +38 -0
  255. data/spec/graphql/schema/rescue_middleware_spec.rb +11 -0
  256. data/spec/graphql/schema/resolver_spec.rb +131 -0
  257. data/spec/graphql/schema/scalar_spec.rb +95 -0
  258. data/spec/graphql/schema/traversal_spec.rb +31 -0
  259. data/spec/graphql/schema/union_spec.rb +65 -0
  260. data/spec/graphql/schema/validation_spec.rb +1 -1
  261. data/spec/graphql/schema/warden_spec.rb +11 -11
  262. data/spec/graphql/schema_spec.rb +55 -12
  263. data/spec/graphql/static_validation/rules/fields_have_appropriate_selections_spec.rb +10 -2
  264. data/spec/graphql/static_validation/rules/fields_will_merge_spec.rb +2 -2
  265. data/spec/graphql/string_type_spec.rb +3 -3
  266. data/spec/graphql/subscriptions_spec.rb +273 -184
  267. data/spec/graphql/tracing/active_support_notifications_tracing_spec.rb +1 -1
  268. data/spec/graphql/tracing/new_relic_tracing_spec.rb +47 -0
  269. data/spec/graphql/tracing/platform_tracing_spec.rb +60 -1
  270. data/spec/graphql/union_type_spec.rb +1 -1
  271. data/spec/graphql/upgrader/member_spec.rb +516 -0
  272. data/spec/graphql/upgrader/schema_spec.rb +82 -0
  273. data/spec/spec_helper.rb +8 -0
  274. data/spec/support/dummy/schema.rb +53 -24
  275. data/spec/support/jazz.rb +544 -0
  276. data/spec/support/lazy_helpers.rb +21 -23
  277. data/spec/support/new_relic.rb +24 -0
  278. data/spec/support/star_trek/data.rb +109 -0
  279. data/spec/support/star_trek/schema.rb +388 -0
  280. data/spec/support/star_wars/data.rb +6 -7
  281. data/spec/support/star_wars/schema.rb +127 -171
  282. metadata +233 -11
  283. data/lib/graphql/introspection/arguments_field.rb +0 -7
  284. data/lib/graphql/introspection/enum_values_field.rb +0 -18
  285. data/lib/graphql/introspection/fields_field.rb +0 -13
  286. data/lib/graphql/introspection/input_fields_field.rb +0 -12
  287. data/lib/graphql/introspection/interfaces_field.rb +0 -11
  288. data/lib/graphql/introspection/of_type_field.rb +0 -6
  289. data/lib/graphql/introspection/possible_types_field.rb +0 -11
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Platform
4
+ module Objects
5
+ X = define_active_record_type(-> { ::X }) do
6
+ name "X"
7
+ description "An x on a y."
8
+ visibility :internal
9
+ minimum_accepted_scopes ["z"]
10
+
11
+ global_id_field :id
12
+ interfaces [GraphQL::Relay::Node.interface]
13
+
14
+ field :f1, !Objects::O1, "The x being y."
15
+ field :f2, !Enums::E1, "x for the y.",
16
+ property: :field_2
17
+ field :f3, Enums::E2, "x for y."
18
+ field :details, types.String, "Details."
19
+
20
+ field :f4, !Objects::O2, "x as a y inside the z." do
21
+ argument :a1, !Inputs::I1
22
+
23
+ resolve ->(obj_x, arguments, context) do
24
+ Class1.new(
25
+ a: Class2.new(
26
+ b: obj_x.b_1,
27
+ c: obj_x.c_1
28
+ ),
29
+ d: Class3.new(
30
+ b: obj_x.b_2,
31
+ c: obj_x.c_3,
32
+ )
33
+ )
34
+ end
35
+ end
36
+
37
+ field :f5, -> { !types.String } do
38
+ description "The thing"
39
+ property :custom_property
40
+ visibility :custom_value
41
+ end
42
+
43
+ field :f6, -> { !types.String } do
44
+ description "The thing"
45
+ property :custom_property
46
+ visibility :custom_value
47
+ end
48
+
49
+ field :f7, field: SomeField
50
+ field :f8, function: SomeFunction
51
+ field :f9, types[Objects::O2]
52
+ field :fieldField, types.String, hash_key: "fieldField"
53
+ field :fieldField2, types.String, property: :field_field2
54
+
55
+ field :f10, types.String do
56
+ resolve ->(obj, _, _) do
57
+ obj.something do |_|
58
+ xyz_obj.obj
59
+ obj.f10
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Platform
4
+ module Objects
5
+ class X < Platform::Objects::Base
6
+ model_name "X"
7
+ description "An x on a y."
8
+ visibility :internal
9
+ minimum_accepted_scopes ["z"]
10
+
11
+ global_id_field :id
12
+ implements GraphQL::Relay::Node.interface
13
+
14
+ field :f1, Objects::O1, "The x being y.", null: false
15
+ field :f2, Enums::E1, "x for the y.", method: :field_2, null: false
16
+ field :f3, Enums::E2, "x for y.", null: true
17
+ field :details, String, "Details.", null: true
18
+
19
+ field :f4, Objects::O2, "x as a y inside the z.", null: false do
20
+ argument :a1, Inputs::I1, required: true
21
+ end
22
+
23
+ def f4(**arguments)
24
+ Class1.new(
25
+ a: Class2.new(
26
+ b: @object.b_1,
27
+ c: @object.c_1
28
+ ),
29
+ d: Class3.new(
30
+ b: @object.b_2,
31
+ c: @object.c_3,
32
+ )
33
+ )
34
+ end
35
+
36
+ field :f5, String, visibility: :custom_value, method: :custom_property, description: "The thing", null: false
37
+
38
+ field :f6, String, visibility: :custom_value, method: :custom_property, description: "The thing", null: false
39
+
40
+ field :f7, field: SomeField
41
+ field :f8, function: SomeFunction
42
+ field :f9, [Objects::O2, null: true], null: true
43
+ field :field_field, String, hash_key: "fieldField", null: true
44
+ field :field_field2, String, null: true
45
+
46
+ field :f10, String, null: true
47
+
48
+ def f10
49
+ @object.something do |_|
50
+ xyz_obj.obj
51
+ @object.f10
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -30,4 +30,30 @@ RUBY
30
30
 
31
31
  assert_file "app/graphql/functions/find_record.rb", expected_content
32
32
  end
33
+
34
+ test "it generates a namespaced function by name" do
35
+ run_generator(["finders::find_record"])
36
+
37
+ expected_content = <<-RUBY
38
+ class Functions::Finders::FindRecord < GraphQL::Function
39
+ # Define `initialize` to store field-level options, eg
40
+ #
41
+ # field :myField, function: Functions::Finders::FindRecord.new(type: MyType)
42
+ #
43
+ # attr_reader :type
44
+ # def initialize(type:)
45
+ # @type = type
46
+ # end
47
+
48
+ # add arguments by type:
49
+ # argument :id, !types.ID
50
+
51
+ # Resolve function:
52
+ def call(obj, args, ctx)
53
+ end
54
+ end
55
+ RUBY
56
+
57
+ assert_file "app/graphql/functions/finders/find_record.rb", expected_content
58
+ end
33
59
  end
@@ -192,7 +192,7 @@ DummySchema = GraphQL::Schema.define do
192
192
  }
193
193
 
194
194
  # Object Resolution
195
- resolve_type -> (obj, ctx) {
195
+ resolve_type -> (type, obj, ctx) {
196
196
  # TODO: Implement this function
197
197
  # to return the correct type for `obj`
198
198
  raise(NotImplementedError)
@@ -28,4 +28,28 @@ RUBY
28
28
 
29
29
  assert_file "app/graphql/loaders/record_loader.rb", expected_content
30
30
  end
31
+
32
+ test "it generates a namespaced loader by name" do
33
+ run_generator(["active_record::record_loader"])
34
+
35
+ expected_content = <<-RUBY
36
+ class Loaders::ActiveRecord::RecordLoader < GraphQL::Batch::Loader
37
+ # Define `initialize` to store grouping arguments, eg
38
+ #
39
+ # Loaders::ActiveRecord::RecordLoader.for(group).load(value)
40
+ #
41
+ # def initialize()
42
+ # end
43
+
44
+ # `keys` contains each key from `.load(key)`.
45
+ # Find the corresponding values, then
46
+ # call `fulfill(key, value)` or `fulfill(key, nil)`
47
+ # for each key.
48
+ def perform(keys)
49
+ end
50
+ end
51
+ RUBY
52
+
53
+ assert_file "app/graphql/loaders/active_record/record_loader.rb", expected_content
54
+ end
31
55
  end
@@ -37,7 +37,7 @@ describe GraphQL::Analysis::MaxQueryComplexity do
37
37
  Dummy::Schema.max_complexity = nil
38
38
  end
39
39
  it "doesn't error" do
40
- assert_equal nil, result["errors"]
40
+ assert_nil result["errors"]
41
41
  end
42
42
  end
43
43
 
@@ -46,7 +46,7 @@ describe GraphQL::Analysis::MaxQueryComplexity do
46
46
  Dummy::Schema.max_complexity = 99
47
47
  end
48
48
  it "doesn't error" do
49
- assert_equal nil, result["errors"]
49
+ assert_nil result["errors"]
50
50
  end
51
51
  end
52
52
 
@@ -68,7 +68,7 @@ describe GraphQL::Analysis::MaxQueryComplexity do
68
68
  let(:result) { Dummy::Schema.execute(query_string, max_complexity: 10) }
69
69
 
70
70
  it "doesn't error" do
71
- assert_equal nil, result["errors"]
71
+ assert_nil result["errors"]
72
72
  end
73
73
  end
74
74
 
@@ -39,7 +39,7 @@ describe GraphQL::Analysis::MaxQueryDepth do
39
39
  let(:result) { Dummy::Schema.execute(query_string, max_depth: 100) }
40
40
 
41
41
  it "obeys that max_depth" do
42
- assert_equal nil, result["errors"]
42
+ assert_nil result["errors"]
43
43
  end
44
44
  end
45
45
 
@@ -49,7 +49,7 @@ describe GraphQL::Analysis::MaxQueryDepth do
49
49
  end
50
50
 
51
51
  it "doesn't add an error" do
52
- assert_equal nil, result["errors"]
52
+ assert_nil result["errors"]
53
53
  end
54
54
  end
55
55
 
@@ -59,7 +59,7 @@ describe GraphQL::Analysis::MaxQueryDepth do
59
59
  end
60
60
 
61
61
  it "doesn't add an error message" do
62
- assert_equal nil, result["errors"]
62
+ assert_nil result["errors"]
63
63
  end
64
64
  end
65
65
 
@@ -32,6 +32,27 @@ describe GraphQL::Argument do
32
32
  assert_equal GraphQL::STRING_TYPE, arg.type
33
33
  end
34
34
 
35
+ it "accepts a definition block after defining kwargs" do
36
+ arg = GraphQL::Argument.from_dsl(:foo, GraphQL::STRING_TYPE) do
37
+ description "my type is #{target.type}"
38
+ end
39
+
40
+ assert_equal "my type is String", arg.description
41
+ end
42
+
43
+ it "accepts a definition block with existing arg" do
44
+ existing = GraphQL::Argument.define do
45
+ name "bar"
46
+ type GraphQL::STRING_TYPE
47
+ end
48
+
49
+ arg = GraphQL::Argument.from_dsl(:foo, existing) do
50
+ description "Description for an existing field."
51
+ end
52
+
53
+ assert_equal "Description for an existing field.", arg.description
54
+ end
55
+
35
56
  it "creates an argument from dsl arguments" do
36
57
  arg = GraphQL::Argument.from_dsl(
37
58
  :foo,
@@ -126,6 +126,16 @@ describe GraphQL::Backtrace do
126
126
  assert_includes err.message, "more lines"
127
127
  end
128
128
 
129
+ it "annotates errors from Query#result" do
130
+ query_str = "query StrField { field2 { strField } __typename }"
131
+ context = { backtrace: true }
132
+ query = GraphQL::Query.new(schema, query_str, context: context)
133
+ err = assert_raises(GraphQL::Backtrace::TracedError) {
134
+ query.result
135
+ }
136
+ assert_instance_of RuntimeError, err.cause
137
+ end
138
+
129
139
  it "annotates errors inside lazy resolution" do
130
140
  # Test context-based flag
131
141
  err = assert_raises(GraphQL::Backtrace::TracedError) {
@@ -28,6 +28,48 @@ describe GraphQL::BaseType do
28
28
  assert_equal ["Cheese"], Dummy::CheeseType.metadata[:class_names]
29
29
  end
30
30
 
31
+ describe "#name" do
32
+ describe "when containing spaces" do
33
+ BaseNameSpaceTest = GraphQL::BaseType.define do
34
+ name "Some Invalid Name"
35
+ end
36
+
37
+ it "is invalid" do
38
+ assert_raises(GraphQL::InvalidNameError) { BaseNameSpaceTest.name }
39
+ end
40
+ end
41
+
42
+ describe "when containing colons" do
43
+ BaseNameColonsTest = GraphQL::BaseType.define do
44
+ name "Some::Invalid::Name"
45
+ end
46
+
47
+ it 'is invalid' do
48
+ assert_raises(GraphQL::InvalidNameError) { BaseNameColonsTest.name }
49
+ end
50
+ end
51
+ end
52
+
53
+ describe "name" do
54
+ it "fails with a helpful message" do
55
+ error = assert_raises RuntimeError do
56
+ class BaseType < GraphQL::Schema::Object
57
+ name "KerkShine"
58
+ end
59
+ end
60
+
61
+ assert_equal error.message, "The new name override method is `graphql_name`, not `name`. Usage: graphql_name \"KerkShine\""
62
+ end
63
+ end
64
+
65
+ describe "forwards-compat with new api" do
66
+ let(:type_defn) { Dummy::CheeseType }
67
+ it "responds to new methods" do
68
+ assert_equal "Cheese", type_defn.graphql_name
69
+ assert_equal type_defn, type_defn.graphql_definition
70
+ end
71
+ end
72
+
31
73
  describe "#dup" do
32
74
  let(:obj_type) {
33
75
  GraphQL::ObjectType.define do
@@ -13,9 +13,9 @@ describe GraphQL::BOOLEAN_TYPE do
13
13
  end
14
14
 
15
15
  it "rejects other types" do
16
- assert_equal nil, coerce_input("true")
17
- assert_equal nil, coerce_input(5.5)
18
- assert_equal nil, coerce_input(nil)
16
+ assert_nil coerce_input("true")
17
+ assert_nil coerce_input(5.5)
18
+ assert_nil coerce_input(nil)
19
19
  end
20
20
  end
21
21
  end
@@ -31,7 +31,9 @@ describe GraphQL::Directive do
31
31
  describe "child fields" do
32
32
  let(:query_string) { <<-GRAPHQL
33
33
  {
34
- __type(name: "Cheese") {
34
+ __type(name: """
35
+ Cheese
36
+ """) {
35
37
  fields { name }
36
38
  fields @skip(if: true) { isDeprecated }
37
39
  }
@@ -37,21 +37,34 @@ describe GraphQL::EnumType do
37
37
  end
38
38
  end
39
39
 
40
- describe "invalid names" do
41
- it "rejects names with a space" do
40
+ describe "invalid values" do
41
+ it "rejects value names with a space" do
42
42
  assert_raises(GraphQL::InvalidNameError) {
43
- InvalidEnumTest = GraphQL::EnumType.define do
44
- name "InvalidEnumTest"
43
+ InvalidEnumValueTest = GraphQL::EnumType.define do
44
+ name "InvalidEnumValueTest"
45
45
 
46
46
  value("SPACE IN VALUE", "Invalid enum because it contains spaces", value: 1)
47
47
  end
48
48
 
49
49
  # Force evaluation
50
- InvalidEnumTest.name
50
+ InvalidEnumValueTest.name
51
51
  }
52
52
  end
53
53
  end
54
54
 
55
+ describe "invalid name" do
56
+ it "reject names with invalid format" do
57
+ assert_raises(GraphQL::InvalidNameError) do
58
+ InvalidEnumNameTest = GraphQL::EnumType.define do
59
+ name "Some::Invalid::Name"
60
+ end
61
+
62
+ # Force evaluation
63
+ InvalidEnumNameTest.name
64
+ end
65
+ end
66
+ end
67
+
55
68
  describe "values that are Arrays" do
56
69
  let(:schema) {
57
70
  enum = GraphQL::EnumType.define do
@@ -120,7 +120,7 @@ describe GraphQL::Execution::Execute do
120
120
  }
121
121
  GRAPHQL
122
122
 
123
- assert_equal nil, res["data"]
123
+ assert_nil res["data"]
124
124
  assert_equal "👻", res["errors"].first["message"]
125
125
  end
126
126
 
@@ -163,10 +163,10 @@ describe GraphQL::Execution::Execute do
163
163
  "execute_field",
164
164
  "execute_query",
165
165
  "lazy_loader",
166
- "execute_field",
167
166
  "execute_field_lazy",
168
167
  "execute_field",
169
168
  "execute_field_lazy",
169
+ "execute_field",
170
170
  "execute_field_lazy",
171
171
  "execute_field_lazy",
172
172
  "execute_query_lazy",
@@ -177,8 +177,8 @@ describe GraphQL::Execution::Execute do
177
177
  field_1_eager, field_2_eager,
178
178
  query_eager, lazy_loader,
179
179
  # field 3 is eager-resolved _during_ field 1's lazy resolve
180
- field_3_eager, field_1_lazy,
181
- field_4_eager, field_2_lazy,
180
+ field_1_lazy, field_3_eager,
181
+ field_2_lazy, field_4_eager,
182
182
  # field 3 didn't finish above, it's resolved in the next round
183
183
  field_3_lazy, field_4_lazy,
184
184
  query_lazy, multiplex = exec_traces
@@ -0,0 +1,165 @@
1
+ # frozen_string_literal: true
2
+ require "spec_helper"
3
+
4
+ describe GraphQL::Schema do
5
+ describe "instrumentation teardown bug" do
6
+ # This instrumenter records that it ran,
7
+ # or raises an error if instructed to do so
8
+ class InstrumenterError < StandardError
9
+ attr_reader :key
10
+ def initialize(key)
11
+ @key = key
12
+ super()
13
+ end
14
+ end
15
+
16
+ class LogInstrumenter
17
+ def before_query(unit_of_work)
18
+ run_hook(unit_of_work, "begin")
19
+ end
20
+
21
+ def after_query(unit_of_work)
22
+ run_hook(unit_of_work, "end")
23
+ end
24
+
25
+ alias :before_multiplex :before_query
26
+ alias :after_multiplex :after_query
27
+
28
+ private
29
+
30
+ def run_hook(unit_of_work, event_name)
31
+ unit_of_work.context[log_key(event_name)] = true
32
+ if unit_of_work.context[raise_key(event_name)]
33
+ raise InstrumenterError.new(log_key(event_name))
34
+ end
35
+ end
36
+
37
+ def log_key(event_name)
38
+ context_key("did_#{event_name}")
39
+ end
40
+
41
+ def raise_key(event_name)
42
+ context_key("should_raise_#{event_name}")
43
+ end
44
+
45
+ def context_key(suffix)
46
+ prefix = self.class.name.sub("Instrumenter", "").downcase
47
+ :"#{prefix}_instrumenter_#{suffix}"
48
+ end
49
+ end
50
+
51
+ class FirstInstrumenter < LogInstrumenter; end
52
+ class SecondInstrumenter < LogInstrumenter; end
53
+
54
+ let(:query_type) {
55
+ GraphQL::ObjectType.define do
56
+ name "Query"
57
+ field :int, types.Int do
58
+ argument :value, types.Int
59
+ resolve ->(obj, args, ctx) { args.value }
60
+ end
61
+ end
62
+ }
63
+
64
+ let(:schema) {
65
+ spec = self
66
+ GraphQL::Schema.define do
67
+ query(spec.query_type)
68
+ instrument(:query, FirstInstrumenter.new)
69
+ instrument(:query, SecondInstrumenter.new)
70
+ end
71
+ }
72
+
73
+ describe "query instrumenters" do
74
+ it "before_query of the 2nd instrumenter does not run but after_query does" do
75
+ context = {second_instrumenter_should_raise_begin: true}
76
+ assert_raises InstrumenterError do
77
+ schema.execute(" { int(value: 2) } ", context: context)
78
+ end
79
+ assert context[:first_instrumenter_did_begin]
80
+ assert context[:first_instrumenter_did_end]
81
+ assert context[:second_instrumenter_did_begin]
82
+ refute context[:second_instrumenter_did_end]
83
+ end
84
+
85
+ it "runs after_query even if a previous after_query raised an error" do
86
+ context = {second_instrumenter_should_raise_end: true}
87
+ err = assert_raises InstrumenterError do
88
+ schema.execute(" { int(value: 2) } ", context: context)
89
+ end
90
+ # The error came from the second instrumenter:
91
+ assert_equal :second_instrumenter_did_end, err.key
92
+ # But the first instrumenter still got a chance to teardown
93
+ assert context[:first_instrumenter_did_begin]
94
+ assert context[:first_instrumenter_did_end]
95
+ assert context[:second_instrumenter_did_begin]
96
+ assert context[:second_instrumenter_did_end]
97
+ end
98
+ end
99
+
100
+ describe "within a multiplex" do
101
+ let(:multiplex_schema) {
102
+ schema.redefine {
103
+ instrument(:multiplex, FirstInstrumenter.new)
104
+ instrument(:multiplex, SecondInstrumenter.new)
105
+ }
106
+ }
107
+
108
+ it "only runs after_multiplex if before_multiplex finished" do
109
+ multiplex_ctx = {second_instrumenter_should_raise_begin: true}
110
+ query_1_ctx = {}
111
+ query_2_ctx = {}
112
+ assert_raises InstrumenterError do
113
+ multiplex_schema.multiplex(
114
+ [
115
+ {query: "{int(value: 1)}", context: query_1_ctx},
116
+ {query: "{int(value: 2)}", context: query_2_ctx},
117
+ ],
118
+ context: multiplex_ctx
119
+ )
120
+ end
121
+
122
+ assert multiplex_ctx[:first_instrumenter_did_begin]
123
+ assert multiplex_ctx[:first_instrumenter_did_end]
124
+ assert multiplex_ctx[:second_instrumenter_did_begin]
125
+ refute multiplex_ctx[:second_instrumenter_did_end]
126
+ # No query instrumentation was run at all
127
+ assert_equal 0, query_1_ctx.size
128
+ assert_equal 0, query_2_ctx.size
129
+ end
130
+
131
+ it "does full and partial query runs" do
132
+ multiplex_ctx = {}
133
+ query_1_ctx = {}
134
+ query_2_ctx = {second_instrumenter_should_raise_begin: true}
135
+ assert_raises InstrumenterError do
136
+ multiplex_schema.multiplex(
137
+ [
138
+ { query: " { int(value: 2) } ", context: query_1_ctx },
139
+ { query: " { int(value: 2) } ", context: query_2_ctx },
140
+ ],
141
+ context: multiplex_ctx
142
+ )
143
+ end
144
+
145
+ # multiplex got a full run
146
+ assert multiplex_ctx[:first_instrumenter_did_begin]
147
+ assert multiplex_ctx[:first_instrumenter_did_end]
148
+ assert multiplex_ctx[:second_instrumenter_did_begin]
149
+ assert multiplex_ctx[:second_instrumenter_did_end]
150
+
151
+ # query 1 got a full run
152
+ assert query_1_ctx[:first_instrumenter_did_begin]
153
+ assert query_1_ctx[:first_instrumenter_did_end]
154
+ assert query_1_ctx[:second_instrumenter_did_begin]
155
+ assert query_1_ctx[:second_instrumenter_did_end]
156
+
157
+ # query 2 got a partial run
158
+ assert query_2_ctx[:first_instrumenter_did_begin]
159
+ assert query_2_ctx[:first_instrumenter_did_end]
160
+ assert query_2_ctx[:second_instrumenter_did_begin]
161
+ refute query_2_ctx[:second_instrumenter_did_end]
162
+ end
163
+ end
164
+ end
165
+ end
@@ -126,7 +126,7 @@ describe GraphQL::Execution::Multiplex do
126
126
  "before multiplex 1",
127
127
  "before multiplex 2",
128
128
  "before Q1", "before Q2", "before Q3",
129
- "after Q1", "after Q2", "after Q3",
129
+ "after Q3", "after Q2", "after Q1",
130
130
  "after multiplex 2",
131
131
  "after multiplex 1",
132
132
  ], checks
@@ -176,7 +176,7 @@ describe GraphQL::Execution::Multiplex do
176
176
  assert_raises(GraphQL::Error) do
177
177
  InspectSchema.execute("{ raiseError }")
178
178
  end
179
- unhandled_err_json = 'null'
179
+ unhandled_err_json = '{}'
180
180
  assert_equal unhandled_err_json, InspectQueryInstrumentation.last_json
181
181
  end
182
182
  end
@@ -271,4 +271,22 @@ describe GraphQL::ExecutionError do
271
271
  assert_equal(expected_result, result)
272
272
  end
273
273
  end
274
+
275
+ describe "more than one ExecutionError" do
276
+ let(:query_string) { %|{ multipleErrorsOnNonNullableField} |}
277
+ it "the errors are inserted into the errors key and the data is nil even for a NonNullable field " do
278
+ expected_result = {
279
+ "data"=>nil,
280
+ "errors"=>
281
+ [{"message"=>"This is an error message for some error.",
282
+ "locations"=>[{"line"=>1, "column"=>3}],
283
+ "path"=>["multipleErrorsOnNonNullableField", 0]},
284
+ {"message"=>"This is another error message for a different error.",
285
+ "locations"=>[{"line"=>1, "column"=>3}],
286
+ "path"=>["multipleErrorsOnNonNullableField", 1]}]
287
+ }
288
+ assert_equal(expected_result, result)
289
+ end
290
+ end
291
+
274
292
  end
@@ -9,8 +9,8 @@ describe GraphQL::FLOAT_TYPE do
9
9
  end
10
10
 
11
11
  it "rejects other types" do
12
- assert_equal nil, GraphQL::FLOAT_TYPE.coerce_isolated_input("55")
13
- assert_equal nil, GraphQL::FLOAT_TYPE.coerce_isolated_input(true)
12
+ assert_nil GraphQL::FLOAT_TYPE.coerce_isolated_input("55")
13
+ assert_nil GraphQL::FLOAT_TYPE.coerce_isolated_input(true)
14
14
  end
15
15
  end
16
16
  end
@@ -26,7 +26,7 @@ describe GraphQL::ID_TYPE do
26
26
  let(:query_string) { %|query getMilk { cow: milk(id: 1.0) { id } }| }
27
27
 
28
28
  it "doesn't allow other types" do
29
- assert_equal nil, result["data"]
29
+ assert_nil result["data"]
30
30
  assert_equal 1, result["errors"].length
31
31
  end
32
32
  end