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,770 @@
1
+ # frozen_string_literal: true
2
+ require "spec_helper"
3
+
4
+ describe GraphQL::Language::DocumentFromSchemaDefinition do
5
+ let(:subject) { GraphQL::Language::DocumentFromSchemaDefinition }
6
+
7
+ describe "#document" do
8
+ let(:schema_idl) { <<-GRAPHQL
9
+ type QueryType {
10
+ foo: Foo
11
+ }
12
+
13
+ type Foo implements Bar {
14
+ one: Type
15
+ two(argument: InputType!): Site
16
+ three(argument: InputType, other: String): CustomScalar
17
+ four(argument: String = "string"): String
18
+ five(argument: [String] = ["string", "string"]): String
19
+ six(argument: String): Type
20
+ }
21
+
22
+ interface Bar {
23
+ one: Type
24
+ four(argument: String = "string"): String
25
+ }
26
+
27
+ type Type {
28
+ a: String
29
+ }
30
+
31
+ input InputType {
32
+ key: String!
33
+ answer: Int = 42
34
+ }
35
+
36
+ type MutationType {
37
+ a(input: InputType): String
38
+ }
39
+
40
+ # Scalar description
41
+ scalar CustomScalar
42
+
43
+ enum Site {
44
+ DESKTOP
45
+ MOBILE
46
+ }
47
+
48
+ union Union = Type | QueryType
49
+
50
+ schema {
51
+ query: QueryType
52
+ mutation: MutationType
53
+ }
54
+ GRAPHQL
55
+ }
56
+
57
+ let(:schema) { GraphQL::Schema.from_definition(schema_idl) }
58
+
59
+ let(:expected_document) { GraphQL.parse(expected_idl) }
60
+
61
+ describe "when printing and schema respects root name conventions" do
62
+ let(:schema_idl) { <<-GRAPHQL
63
+ type Query {
64
+ foo: Foo
65
+ }
66
+
67
+ type Foo implements Bar {
68
+ one: Type
69
+ two(argument: InputType!): Site
70
+ three(argument: InputType, other: String): CustomScalar
71
+ four(argument: String = "string"): String
72
+ five(argument: [String] = ["string", "string"]): String
73
+ six(argument: String): Type
74
+ }
75
+
76
+ interface Bar {
77
+ one: Type
78
+ four(argument: String = "string"): String
79
+ }
80
+
81
+ type Type {
82
+ a: String
83
+ }
84
+
85
+ input InputType {
86
+ key: String!
87
+ answer: Int = 42
88
+ }
89
+
90
+ type Mutation {
91
+ a(input: InputType): String
92
+ }
93
+
94
+ # Scalar description
95
+ scalar CustomScalar
96
+
97
+ enum Site {
98
+ DESKTOP
99
+ MOBILE
100
+ }
101
+
102
+ union Union = Type | Query
103
+
104
+ schema {
105
+ query: Query
106
+ mutation: Mutation
107
+ }
108
+ GRAPHQL
109
+ }
110
+
111
+ let(:expected_idl) { <<-GRAPHQL
112
+ type QueryType {
113
+ foo: Foo
114
+ }
115
+
116
+ type Foo implements Bar {
117
+ one: Type
118
+ two(argument: InputType!): Site
119
+ three(argument: InputType, other: String): CustomScalar
120
+ four(argument: String = "string"): String
121
+ five(argument: [String] = ["string", "string"]): String
122
+ six(argument: String): Type
123
+ }
124
+
125
+ interface Bar {
126
+ one: Type
127
+ four(argument: String = "string"): String
128
+ }
129
+
130
+ type Type {
131
+ a: String
132
+ }
133
+
134
+ input InputType {
135
+ key: String!
136
+ answer: Int = 42
137
+ }
138
+
139
+ type MutationType {
140
+ a(input: InputType): String
141
+ }
142
+
143
+ # Scalar description
144
+ scalar CustomScalar
145
+
146
+ enum Site {
147
+ DESKTOP
148
+ MOBILE
149
+ }
150
+
151
+ union Union = Type | QueryType
152
+ GRAPHQL
153
+ }
154
+
155
+ let(:document) {
156
+ subject.new(
157
+ schema
158
+ ).document
159
+ }
160
+
161
+ it "returns the IDL without introspection, built ins and schema root" do
162
+ assert equivalent_node?(expected_document, document)
163
+ end
164
+ end
165
+
166
+ describe "with defaults" do
167
+ let(:expected_idl) { <<-GRAPHQL
168
+ type QueryType {
169
+ foo: Foo
170
+ }
171
+
172
+ type Foo implements Bar {
173
+ one: Type
174
+ two(argument: InputType!): Site
175
+ three(argument: InputType, other: String): CustomScalar
176
+ four(argument: String = "string"): String
177
+ five(argument: [String] = ["string", "string"]): String
178
+ six(argument: String): Type
179
+ }
180
+
181
+ interface Bar {
182
+ one: Type
183
+ four(argument: String = "string"): String
184
+ }
185
+
186
+ type Type {
187
+ a: String
188
+ }
189
+
190
+ input InputType {
191
+ key: String!
192
+ answer: Int = 42
193
+ }
194
+
195
+ type MutationType {
196
+ a(input: InputType): String
197
+ }
198
+
199
+ # Scalar description
200
+ scalar CustomScalar
201
+
202
+ enum Site {
203
+ DESKTOP
204
+ MOBILE
205
+ }
206
+
207
+ union Union = Type | QueryType
208
+
209
+ schema {
210
+ query: QueryType
211
+ mutation: MutationType
212
+ }
213
+ GRAPHQL
214
+ }
215
+
216
+ let(:document) {
217
+ subject.new(
218
+ schema
219
+ ).document
220
+ }
221
+
222
+ it "returns the IDL without introspection, built ins and schema if it doesnt respect name conventions" do
223
+ assert equivalent_node?(expected_document, document)
224
+ end
225
+ end
226
+
227
+ describe "with an except filter" do
228
+ let(:expected_idl) { <<-GRAPHQL
229
+ type QueryType {
230
+ foo: Foo
231
+ }
232
+
233
+ type Foo implements Bar {
234
+ three(argument: InputType, other: String): CustomScalar
235
+ four(argument: String = "string"): String
236
+ five(argument: [String] = ["string", "string"]): Site
237
+ }
238
+
239
+ interface Bar {
240
+ one: Type
241
+ four(argument: String = "string"): String
242
+ }
243
+
244
+ input InputType {
245
+ key: String!
246
+ answer: Int = 42
247
+ }
248
+
249
+ type MutationType {
250
+ a(input: InputType): String
251
+ }
252
+
253
+ # Scalar description
254
+ scalar CustomScalar
255
+
256
+ enum Site {
257
+ DESKTOP
258
+ MOBILE
259
+ }
260
+
261
+ schema {
262
+ query: QueryType
263
+ mutation: MutationType
264
+ }
265
+ GRAPHQL
266
+ }
267
+
268
+ let(:document) {
269
+ subject.new(
270
+ schema,
271
+ except: ->(m, _ctx) { m.is_a?(GraphQL::BaseType) && m.name == "Type" }
272
+ ).document
273
+ }
274
+
275
+ it "returns the IDL minus the filtered members" do
276
+ assert equivalent_node?(expected_document, document)
277
+ end
278
+ end
279
+
280
+ describe "with an only filter" do
281
+ let(:expected_idl) { <<-GRAPHQL
282
+ type QueryType {
283
+ foo: Foo
284
+ }
285
+
286
+ type Foo implements Bar {
287
+ three(argument: InputType, other: String): CustomScalar
288
+ four(argument: String = "string"): String
289
+ five(argument: [String] = ["string", "string"]): Site
290
+ }
291
+
292
+ interface Bar {
293
+ one: Type
294
+ four(argument: String = "string"): String
295
+ }
296
+
297
+ input InputType {
298
+ key: String!
299
+ answer: Int = 42
300
+ }
301
+
302
+ type MutationType {
303
+ a(input: InputType): String
304
+ }
305
+
306
+ enum Site {
307
+ DESKTOP
308
+ MOBILE
309
+ }
310
+
311
+ schema {
312
+ query: QueryType
313
+ mutation: MutationType
314
+ }
315
+ GRAPHQL
316
+ }
317
+
318
+ let(:document) {
319
+ subject.new(
320
+ schema,
321
+ only: ->(m, _ctx) { !(m.is_a?(GraphQL::ScalarType) && m.name == "CustomScalar") }
322
+ ).document
323
+ }
324
+
325
+ it "returns the IDL minus the filtered members" do
326
+ assert equivalent_node?(expected_document, document)
327
+ end
328
+ end
329
+
330
+ describe "when excluding built ins and introspection types" do
331
+ let(:expected_idl) { <<-GRAPHQL
332
+ type QueryType {
333
+ foo: Foo
334
+ }
335
+
336
+ type Foo implements Bar {
337
+ one: Type
338
+ two(argument: InputType!): Site
339
+ three(argument: InputType, other: String): CustomScalar
340
+ four(argument: String = "string"): String
341
+ five(argument: [String] = ["string", "string"]): String
342
+ six(argument: String): Type
343
+ }
344
+
345
+ interface Bar {
346
+ one: Type
347
+ four(argument: String = "string"): String
348
+ }
349
+
350
+ type Type {
351
+ a: String
352
+ }
353
+
354
+ input InputType {
355
+ key: String!
356
+ answer: Int = 42
357
+ }
358
+
359
+ type MutationType {
360
+ a(input: InputType): String
361
+ }
362
+
363
+ # Scalar description
364
+ scalar CustomScalar
365
+
366
+ enum Site {
367
+ DESKTOP
368
+ MOBILE
369
+ }
370
+
371
+ union Union = Type | QueryType
372
+
373
+ schema {
374
+ query: QueryType
375
+ mutation: MutationType
376
+ }
377
+ GRAPHQL
378
+ }
379
+
380
+ let(:document) {
381
+ subject.new(
382
+ schema,
383
+ always_include_schema: true
384
+ ).document
385
+ }
386
+
387
+ it "returns the schema idl besides introspection types and built ins" do
388
+ assert equivalent_node?(expected_document, document)
389
+ end
390
+ end
391
+
392
+ describe "when printing excluding only introspection types" do
393
+ let(:expected_idl) { <<-GRAPHQL
394
+ # Represents `true` or `false` values.
395
+ scalar Boolean
396
+
397
+ # Represents textual data as UTF-8 character sequences. This type is most often
398
+ # used by GraphQL to represent free-form human-readable text.
399
+ scalar String
400
+
401
+ type QueryType {
402
+ foo: Foo
403
+ }
404
+
405
+ type Foo implements Bar {
406
+ one: Type
407
+ two(argument: InputType!): Type
408
+ three(argument: InputType, other: String): CustomScalar
409
+ four(argument: String = "string"): String
410
+ five(argument: [String] = ["string", "string"]): String
411
+ six(argument: String): Type
412
+ }
413
+
414
+ interface Bar {
415
+ one: Type
416
+ four(argument: String = "string"): String
417
+ }
418
+
419
+ type Type {
420
+ a: String
421
+ }
422
+
423
+ input InputType {
424
+ key: String!
425
+ answer: Int = 42
426
+ }
427
+
428
+ # Represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1.
429
+ scalar Int
430
+
431
+ type MutationType {
432
+ a(input: InputType): String
433
+ }
434
+
435
+ # Represents signed double-precision fractional values as specified by [IEEE
436
+ # 754](http://en.wikipedia.org/wiki/IEEE_floating_point).
437
+ scalar Float
438
+
439
+ # Represents a unique identifier that is Base64 obfuscated. It is often used to
440
+ # refetch an object or as key for a cache. The ID type appears in a JSON response
441
+ # as a String; however, it is not intended to be human-readable. When expected as
442
+ # an input type, any string (such as `"VXNlci0xMA=="`) or integer (such as `4`)
443
+ # input value will be accepted as an ID.
444
+ scalar ID
445
+
446
+ # Scalar description
447
+ scalar CustomScalar
448
+
449
+ enum Site {
450
+ DESKTOP
451
+ MOBILE
452
+ }
453
+
454
+ union Union = Type | QueryType
455
+
456
+ directive @skip(if: Boolean!) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT
457
+
458
+ directive @include(if: Boolean!) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT
459
+
460
+ # Marks an element of a GraphQL schema as no longer supported.
461
+ directive @deprecated(reason: String = "No longer supported") on FIELD_DEFINITION | ENUM_VALUE
462
+
463
+ schema {
464
+ query: QueryType
465
+ mutation: MutationType
466
+ }
467
+ GRAPHQL
468
+ }
469
+
470
+ let(:document) {
471
+ subject.new(
472
+ schema,
473
+ include_built_in_scalars: true,
474
+ include_built_in_directives: true,
475
+ ).document
476
+ }
477
+
478
+ it "returns the the schema IDL including only the built ins and not introspection types" do
479
+ assert equivalent_node?(expected_document, document)
480
+ end
481
+ end
482
+
483
+ describe "when printing the full schema" do
484
+ let(:expected_idl) { <<-GRAPHQL
485
+ # Represents `true` or `false` values.
486
+ scalar Boolean
487
+
488
+ # Represents textual data as UTF-8 character sequences. This type is most often
489
+ # used by GraphQL to represent free-form human-readable text.
490
+ scalar String
491
+
492
+ # The fundamental unit of any GraphQL Schema is the type. There are many kinds of
493
+ # types in GraphQL as represented by the `__TypeKind` enum.
494
+ #
495
+ # Depending on the kind of a type, certain fields describe information about that
496
+ # type. Scalar types provide no information beyond a name and description, while
497
+ # Enum types provide their values. Object and Interface types provide the fields
498
+ # they describe. Abstract types, Union and Interface, provide the Object types
499
+ # possible at runtime. List and NonNull types compose other types.
500
+ type __Type {
501
+ kind: __TypeKind!
502
+ name: String
503
+ description: String
504
+ fields(includeDeprecated: Boolean = false): [__Field!]
505
+ interfaces: [__Type!]
506
+ possibleTypes: [__Type!]
507
+ enumValues(includeDeprecated: Boolean = false): [__EnumValue!]
508
+ inputFields: [__InputValue!]
509
+ ofType: __Type
510
+ }
511
+
512
+ # An enum describing what kind of type a given `__Type` is.
513
+ enum __TypeKind {
514
+ # Indicates this type is a scalar.
515
+ SCALAR
516
+
517
+ # Indicates this type is an object. `fields` and `interfaces` are valid fields.
518
+ OBJECT
519
+
520
+ # Indicates this type is an interface. `fields` and `possibleTypes` are valid fields.
521
+ INTERFACE
522
+
523
+ # Indicates this type is a union. `possibleTypes` is a valid field.
524
+ UNION
525
+
526
+ # Indicates this type is an enum. `enumValues` is a valid field.
527
+ ENUM
528
+
529
+ # Indicates this type is an input object. `inputFields` is a valid field.
530
+ INPUT_OBJECT
531
+
532
+ # Indicates this type is a list. `ofType` is a valid field.
533
+ LIST
534
+
535
+ # Indicates this type is a non-null. `ofType` is a valid field.
536
+ NON_NULL
537
+ }
538
+
539
+ # Object and Interface types are described by a list of Fields, each of which has
540
+ # a name, potentially a list of arguments, and a return type.
541
+ type __Field {
542
+ name: String!
543
+ description: String
544
+ args: [__InputValue!]!
545
+ type: __Type!
546
+ isDeprecated: Boolean!
547
+ deprecationReason: String
548
+ }
549
+
550
+ # Arguments provided to Fields or Directives and the input fields of an
551
+ # InputObject are represented as Input Values which describe their type and
552
+ # optionally a default value.
553
+ type __InputValue {
554
+ name: String!
555
+ description: String
556
+ type: __Type!
557
+
558
+ # A GraphQL-formatted string representing the default value for this input value.
559
+ defaultValue: String
560
+ }
561
+
562
+ # One possible value for a given Enum. Enum values are unique values, not a
563
+ # placeholder for a string or numeric value. However an Enum value is returned in
564
+ # a JSON response as a string.
565
+ type __EnumValue {
566
+ name: String!
567
+ description: String
568
+ isDeprecated: Boolean!
569
+ deprecationReason: String
570
+ }
571
+
572
+ type QueryType {
573
+ foo: Foo
574
+ }
575
+
576
+ type Foo implements Bar {
577
+ one: Type
578
+ two(argument: InputType!): Type
579
+ three(argument: InputType, other: String): Int
580
+ four(argument: String = "string"): String
581
+ five(argument: [String] = ["string", "string"]): String
582
+ six(argument: String): Type
583
+ }
584
+
585
+ interface Bar {
586
+ one: Type
587
+ four(argument: String = "string"): String
588
+ }
589
+
590
+ type Type {
591
+ a: String
592
+ }
593
+
594
+ input InputType {
595
+ key: String!
596
+ answer: Int = 42
597
+ }
598
+
599
+ # Represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1.
600
+ scalar Int
601
+
602
+ type MutationType {
603
+ a(input: InputType): String
604
+ }
605
+
606
+ # A GraphQL Schema defines the capabilities of a GraphQL server. It exposes all
607
+ # available types and directives on the server, as well as the entry points for
608
+ # query, mutation, and subscription operations.
609
+ type __Schema {
610
+ # A list of all types supported by this server.
611
+ types: [__Type!]!
612
+
613
+ # The type that query operations will be rooted at.
614
+ queryType: __Type!
615
+
616
+ # If this server supports mutation, the type that mutation operations will be rooted at.
617
+ mutationType: __Type
618
+
619
+ # If this server support subscription, the type that subscription operations will be rooted at.
620
+ subscriptionType: __Type
621
+
622
+ # A list of all directives supported by this server.
623
+ directives: [__Directive!]!
624
+ }
625
+
626
+ # A Directive provides a way to describe alternate runtime execution and type validation behavior in a GraphQL document.
627
+ #
628
+ # In some cases, you need to provide options to alter GraphQL's execution behavior
629
+ # in ways field arguments will not suffice, such as conditionally including or
630
+ # skipping a field. Directives provide this by describing additional information
631
+ # to the executor.
632
+ type __Directive {
633
+ name: String!
634
+ description: String
635
+ locations: [__DirectiveLocation!]!
636
+ args: [__InputValue!]!
637
+ onOperation: Boolean!
638
+ onFragment: Boolean!
639
+ onField: Boolean!
640
+ }
641
+
642
+ # A Directive can be adjacent to many parts of the GraphQL language, a
643
+ # __DirectiveLocation describes one such possible adjacencies.
644
+ enum __DirectiveLocation {
645
+ # Location adjacent to a query operation.
646
+ QUERY
647
+
648
+ # Location adjacent to a mutation operation.
649
+ MUTATION
650
+
651
+ # Location adjacent to a subscription operation.
652
+ SUBSCRIPTION
653
+
654
+ # Location adjacent to a field.
655
+ FIELD
656
+
657
+ # Location adjacent to a fragment definition.
658
+ FRAGMENT_DEFINITION
659
+
660
+ # Location adjacent to a fragment spread.
661
+ FRAGMENT_SPREAD
662
+
663
+ # Location adjacent to an inline fragment.
664
+ INLINE_FRAGMENT
665
+
666
+ # Location adjacent to a schema definition.
667
+ SCHEMA
668
+
669
+ # Location adjacent to a scalar definition.
670
+ SCALAR
671
+
672
+ # Location adjacent to an object type definition.
673
+ OBJECT
674
+
675
+ # Location adjacent to a field definition.
676
+ FIELD_DEFINITION
677
+
678
+ # Location adjacent to an argument definition.
679
+ ARGUMENT_DEFINITION
680
+
681
+ # Location adjacent to an interface definition.
682
+ INTERFACE
683
+
684
+ # Location adjacent to a union definition.
685
+ UNION
686
+
687
+ # Location adjacent to an enum definition.
688
+ ENUM
689
+
690
+ # Location adjacent to an enum value definition.
691
+ ENUM_VALUE
692
+
693
+ # Location adjacent to an input object type definition.
694
+ INPUT_OBJECT
695
+
696
+ # Location adjacent to an input object field definition.
697
+ INPUT_FIELD_DEFINITION
698
+ }
699
+
700
+ # Represents signed double-precision fractional values as specified by [IEEE
701
+ # 754](http://en.wikipedia.org/wiki/IEEE_floating_point).
702
+ scalar Float
703
+
704
+ # Represents a unique identifier that is Base64 obfuscated. It is often used to
705
+ # refetch an object or as key for a cache. The ID type appears in a JSON response
706
+ # as a String; however, it is not intended to be human-readable. When expected as
707
+ # an input type, any string (such as `"VXNlci0xMA=="`) or integer (such as `4`)
708
+ # input value will be accepted as an ID.
709
+ scalar ID
710
+
711
+ # Scalar description
712
+ scalar CustomScalar
713
+
714
+ enum Site {
715
+ DESKTOP
716
+ MOBILE
717
+ }
718
+
719
+ union Union = Type | QueryType
720
+
721
+ directive @skip(if: Boolean!) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT
722
+
723
+ directive @include(if: Boolean!) on FIELD | FRAGMENT_SPREAD | INLINE_FRAGMENT
724
+
725
+ # Marks an element of a GraphQL schema as no longer supported.
726
+ directive @deprecated(reason: String = "No longer supported") on FIELD_DEFINITION | ENUM_VALUE
727
+
728
+ schema {
729
+ query: QueryType
730
+ mutation: MutationType
731
+ }
732
+ GRAPHQL
733
+ }
734
+
735
+ let(:document) {
736
+ subject.new(
737
+ schema,
738
+ include_introspection_types: true,
739
+ include_built_in_directives: true,
740
+ include_built_in_scalars: true,
741
+ always_include_schema: true,
742
+ ).document
743
+ }
744
+
745
+ it "returns the full document AST from the given schema including built ins and introspection" do
746
+ assert equivalent_node?(expected_document, document)
747
+ end
748
+ end
749
+ end
750
+
751
+ private
752
+
753
+ def equivalent_node?(expected, node)
754
+ return false unless expected.is_a?(node.class)
755
+
756
+ if expected.respond_to?(:children) && expected.respond_to?(:scalars)
757
+ children_equal = expected.children.all? do |expected_child|
758
+ node.children.find { |child| equivalent_node?(expected_child, child) }
759
+ end
760
+
761
+ scalars_equal = expected.children.all? do |expected_child|
762
+ node.children.find { |child| equivalent_node?(expected_child, child) }
763
+ end
764
+
765
+ children_equal && scalars_equal
766
+ else
767
+ expected == node
768
+ end
769
+ end
770
+ end