graphql 1.8.0.pre1 → 1.8.0.pre2

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 (82) hide show
  1. checksums.yaml +4 -4
  2. data/lib/generators/graphql/function_generator.rb +1 -1
  3. data/lib/generators/graphql/loader_generator.rb +1 -1
  4. data/lib/generators/graphql/mutation_generator.rb +6 -1
  5. data/lib/generators/graphql/templates/function.erb +2 -2
  6. data/lib/generators/graphql/templates/loader.erb +2 -2
  7. data/lib/graphql.rb +1 -0
  8. data/lib/graphql/execution.rb +1 -0
  9. data/lib/graphql/execution/instrumentation.rb +82 -0
  10. data/lib/graphql/execution/multiplex.rb +11 -28
  11. data/lib/graphql/field.rb +5 -0
  12. data/lib/graphql/internal_representation/node.rb +1 -1
  13. data/lib/graphql/language.rb +1 -0
  14. data/lib/graphql/language/document_from_schema_definition.rb +185 -0
  15. data/lib/graphql/language/lexer.rb +3 -3
  16. data/lib/graphql/language/lexer.rl +2 -2
  17. data/lib/graphql/language/token.rb +9 -2
  18. data/lib/graphql/query.rb +4 -0
  19. data/lib/graphql/railtie.rb +83 -0
  20. data/lib/graphql/relay/relation_connection.rb +13 -18
  21. data/lib/graphql/schema.rb +6 -0
  22. data/lib/graphql/schema/argument.rb +1 -1
  23. data/lib/graphql/schema/build_from_definition.rb +2 -0
  24. data/lib/graphql/schema/field.rb +5 -2
  25. data/lib/graphql/schema/input_object.rb +2 -2
  26. data/lib/graphql/schema/member.rb +10 -0
  27. data/lib/graphql/schema/member/build_type.rb +8 -0
  28. data/lib/graphql/schema/member/instrumentation.rb +3 -3
  29. data/lib/graphql/subscriptions/action_cable_subscriptions.rb +6 -4
  30. data/lib/graphql/tracing.rb +1 -0
  31. data/lib/graphql/tracing/data_dog_tracing.rb +45 -0
  32. data/lib/graphql/tracing/platform_tracing.rb +20 -7
  33. data/lib/graphql/upgrader/member.rb +111 -0
  34. data/lib/graphql/upgrader/schema.rb +37 -0
  35. data/lib/graphql/version.rb +1 -1
  36. data/readme.md +1 -1
  37. data/spec/dummy/app/channels/graphql_channel.rb +22 -1
  38. data/spec/dummy/log/development.log +239 -0
  39. data/spec/dummy/log/test.log +204 -0
  40. data/spec/dummy/test/system/action_cable_subscription_test.rb +4 -0
  41. data/spec/dummy/tmp/screenshots/failures_test_it_handles_subscriptions.png +0 -0
  42. data/spec/generators/graphql/function_generator_spec.rb +26 -0
  43. data/spec/generators/graphql/loader_generator_spec.rb +24 -0
  44. data/spec/graphql/analysis/max_query_complexity_spec.rb +3 -3
  45. data/spec/graphql/analysis/max_query_depth_spec.rb +3 -3
  46. data/spec/graphql/base_type_spec.rb +12 -0
  47. data/spec/graphql/boolean_type_spec.rb +3 -3
  48. data/spec/graphql/execution/execute_spec.rb +1 -1
  49. data/spec/graphql/execution/instrumentation_spec.rb +165 -0
  50. data/spec/graphql/execution/multiplex_spec.rb +1 -1
  51. data/spec/graphql/float_type_spec.rb +2 -2
  52. data/spec/graphql/id_type_spec.rb +1 -1
  53. data/spec/graphql/input_object_type_spec.rb +2 -2
  54. data/spec/graphql/int_type_spec.rb +2 -2
  55. data/spec/graphql/internal_representation/rewrite_spec.rb +2 -2
  56. data/spec/graphql/introspection/schema_type_spec.rb +1 -0
  57. data/spec/graphql/language/document_from_schema_definition_spec.rb +337 -0
  58. data/spec/graphql/language/lexer_spec.rb +12 -1
  59. data/spec/graphql/language/parser_spec.rb +1 -1
  60. data/spec/graphql/query/arguments_spec.rb +3 -3
  61. data/spec/graphql/query/variables_spec.rb +1 -1
  62. data/spec/graphql/query_spec.rb +4 -4
  63. data/spec/graphql/relay/base_connection_spec.rb +1 -1
  64. data/spec/graphql/relay/connection_resolve_spec.rb +1 -1
  65. data/spec/graphql/relay/connection_type_spec.rb +1 -1
  66. data/spec/graphql/relay/mutation_spec.rb +3 -3
  67. data/spec/graphql/relay/relation_connection_spec.rb +58 -0
  68. data/spec/graphql/schema/build_from_definition_spec.rb +14 -0
  69. data/spec/graphql/schema/field_spec.rb +5 -1
  70. data/spec/graphql/schema/instrumentation_spec.rb +39 -0
  71. data/spec/graphql/schema/validation_spec.rb +1 -1
  72. data/spec/graphql/schema/warden_spec.rb +11 -11
  73. data/spec/graphql/schema_spec.rb +8 -1
  74. data/spec/graphql/string_type_spec.rb +3 -3
  75. data/spec/graphql/subscriptions_spec.rb +1 -1
  76. data/spec/graphql/tracing/platform_tracing_spec.rb +59 -0
  77. data/spec/graphql/upgrader/member_spec.rb +222 -0
  78. data/spec/graphql/upgrader/schema_spec.rb +82 -0
  79. data/spec/support/dummy/schema.rb +19 -0
  80. data/spec/support/jazz.rb +14 -14
  81. data/spec/support/star_wars/data.rb +1 -2
  82. metadata +18 -2
@@ -808,3 +808,207 @@ Could not execute command from ({"command"=>"subscribe", "identifier"=>"{\"chann
808
808
  ^
809
809
  /Users/rmosolgo/code/graphql-ruby/spec/dummy/app/channels/graphql_channel.rb:103: syntax error, unexpected end-of-input, expecting keyword_end]: /Users/rmosolgo/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/activesupport-5.1.4/lib/active_support/dependencies.rb:292:in `require' | /Users/rmosolgo/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/activesupport-5.1.4/lib/active_support/dependencies.rb:292:in `block in require' | /Users/rmosolgo/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/activesupport-5.1.4/lib/active_support/dependencies.rb:258:in `load_dependency' | /Users/rmosolgo/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/activesupport-5.1.4/lib/active_support/dependencies.rb:292:in `require' | /Users/rmosolgo/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/activesupport-5.1.4/lib/active_support/dependencies.rb:379:in `block in require_or_load'
810
810
  Finished "/cable/" [WebSocket] for 127.0.0.1 at 2017-11-13 21:58:53 -0500
811
+ -----------------------------------------------------------
812
+ ActionCableSubscriptionsTest: test_it_handles_subscriptions
813
+ -----------------------------------------------------------
814
+ Started GET "/" for 127.0.0.1 at 2017-11-16 21:25:41 -0500
815
+ Processing by PagesController#show as HTML
816
+ Rendering pages/show.html within layouts/application
817
+ Rendered pages/show.html within layouts/application (1.1ms)
818
+ Completed 200 OK in 169ms (Views: 167.8ms)
819
+ Started GET "/assets/application-aca150c4b2db51d5326af18134f6281fbce7e823a372b0337cca65ff41b4a7ea.js" for 127.0.0.1 at 2017-11-16 21:25:41 -0500
820
+ Started GET "/cable" for 127.0.0.1 at 2017-11-16 21:25:42 -0500
821
+ Started GET "/cable/" [WebSocket] for 127.0.0.1 at 2017-11-16 21:25:42 -0500
822
+ Successfully upgraded to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: Upgrade, HTTP_UPGRADE: websocket)
823
+ GraphqlChannel is transmitting the subscription confirmation
824
+ GraphqlChannel is transmitting the subscription confirmation
825
+ GraphqlChannel#execute({"query"=>"subscription($id: ID!) { payload(id: $id) { value } }", "variables"=>{"id"=>"updates-1"}})
826
+ GraphqlChannel transmitting {:result=>{"data"=>nil}, :more=>true}
827
+ GraphqlChannel#execute({"query"=>"subscription($id: ID!) { payload(id: $id) { value } }", "variables"=>{"id"=>"updates-2"}})
828
+ GraphqlChannel transmitting {:result=>{"data"=>nil}, :more=>true}
829
+ GraphqlChannel is streaming from graphql-event::payload:id:updates-1
830
+ GraphqlChannel is streaming from graphql-event::payload:id:updates-2
831
+ GraphqlChannel is streaming from graphql-subscription:2d85fcfd-550d-45ce-9b98-71d4adc0dcc0
832
+ GraphqlChannel is streaming from graphql-subscription:a225c15d-b0a3-4bdf-b535-e6e5e937cc25
833
+ GraphqlChannel#make_trigger({"id"=>"updates-1", "value"=>1})
834
+ Could not execute command from ({"command"=>"message", "identifier"=>"{\"channel\":\"GraphqlChannel\",\"id\":\"15fc7cbd4ad\"}", "data"=>"{\"id\":\"updates-1\",\"value\":1,\"action\":\"make_trigger\"}"}) [NoMethodError - undefined method `dump_value' for GraphqlChannel::CustomSerializer:Module]: /Users/rmosolgo/code/graphql-ruby/lib/graphql/subscriptions/serialize.rb:21:in `dump' | /Users/rmosolgo/code/graphql-ruby/spec/dummy/app/channels/graphql_channel.rb:36:in `dump' | /Users/rmosolgo/code/graphql-ruby/lib/graphql/subscriptions/action_cable_subscriptions.rb:78:in `execute_all' | /Users/rmosolgo/code/graphql-ruby/lib/graphql/subscriptions.rb:52:in `trigger' | /Users/rmosolgo/code/graphql-ruby/spec/dummy/app/channels/graphql_channel.rb:83:in `make_trigger'
835
+ GraphqlChannel#make_trigger({"id"=>"updates-1", "value"=>2})
836
+ Could not execute command from ({"command"=>"message", "identifier"=>"{\"channel\":\"GraphqlChannel\",\"id\":\"15fc7cbd4ad\"}", "data"=>"{\"id\":\"updates-1\",\"value\":2,\"action\":\"make_trigger\"}"}) [NoMethodError - undefined method `dump_value' for GraphqlChannel::CustomSerializer:Module]: /Users/rmosolgo/code/graphql-ruby/lib/graphql/subscriptions/serialize.rb:21:in `dump' | /Users/rmosolgo/code/graphql-ruby/spec/dummy/app/channels/graphql_channel.rb:36:in `dump' | /Users/rmosolgo/code/graphql-ruby/lib/graphql/subscriptions/action_cable_subscriptions.rb:78:in `execute_all' | /Users/rmosolgo/code/graphql-ruby/lib/graphql/subscriptions.rb:52:in `trigger' | /Users/rmosolgo/code/graphql-ruby/spec/dummy/app/channels/graphql_channel.rb:83:in `make_trigger'
837
+ GraphqlChannel#make_trigger({"id"=>"updates-1", "value"=>3})
838
+ Could not execute command from ({"command"=>"message", "identifier"=>"{\"channel\":\"GraphqlChannel\",\"id\":\"15fc7cbd4ad\"}", "data"=>"{\"id\":\"updates-1\",\"value\":3,\"action\":\"make_trigger\"}"}) [NoMethodError - undefined method `dump_value' for GraphqlChannel::CustomSerializer:Module]: /Users/rmosolgo/code/graphql-ruby/lib/graphql/subscriptions/serialize.rb:21:in `dump' | /Users/rmosolgo/code/graphql-ruby/spec/dummy/app/channels/graphql_channel.rb:36:in `dump' | /Users/rmosolgo/code/graphql-ruby/lib/graphql/subscriptions/action_cable_subscriptions.rb:78:in `execute_all' | /Users/rmosolgo/code/graphql-ruby/lib/graphql/subscriptions.rb:52:in `trigger' | /Users/rmosolgo/code/graphql-ruby/spec/dummy/app/channels/graphql_channel.rb:83:in `make_trigger'
839
+ Finished "/cable/" [WebSocket] for 127.0.0.1 at 2017-11-16 21:25:45 -0500
840
+ GraphqlChannel stopped streaming from graphql-subscription:2d85fcfd-550d-45ce-9b98-71d4adc0dcc0
841
+ GraphqlChannel stopped streaming from graphql-event::payload:id:updates-1
842
+ GraphqlChannel stopped streaming from graphql-subscription:a225c15d-b0a3-4bdf-b535-e6e5e937cc25
843
+ GraphqlChannel stopped streaming from graphql-event::payload:id:updates-2
844
+ -----------------------------------------------------------
845
+ ActionCableSubscriptionsTest: test_it_handles_subscriptions
846
+ -----------------------------------------------------------
847
+ Started GET "/" for 127.0.0.1 at 2017-11-16 21:31:11 -0500
848
+ Processing by PagesController#show as HTML
849
+ Rendering pages/show.html within layouts/application
850
+ Rendered pages/show.html within layouts/application (0.7ms)
851
+ Completed 200 OK in 138ms (Views: 136.5ms)
852
+ Started GET "/assets/application-aca150c4b2db51d5326af18134f6281fbce7e823a372b0337cca65ff41b4a7ea.js" for 127.0.0.1 at 2017-11-16 21:31:11 -0500
853
+ Started GET "/cable" for 127.0.0.1 at 2017-11-16 21:31:11 -0500
854
+ Started GET "/cable/" [WebSocket] for 127.0.0.1 at 2017-11-16 21:31:11 -0500
855
+ Successfully upgraded to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: Upgrade, HTTP_UPGRADE: websocket)
856
+ GraphqlChannel is transmitting the subscription confirmation
857
+ GraphqlChannel is transmitting the subscription confirmation
858
+ GraphqlChannel#execute({"query"=>"subscription($id: ID!) { payload(id: $id) { value } }", "variables"=>{"id"=>"updates-1"}})
859
+ GraphqlChannel transmitting {:result=>{"data"=>nil}, :more=>true}
860
+ GraphqlChannel#execute({"query"=>"subscription($id: ID!) { payload(id: $id) { value } }", "variables"=>{"id"=>"updates-2"}})
861
+ GraphqlChannel transmitting {:result=>{"data"=>nil}, :more=>true}
862
+ GraphqlChannel is streaming from graphql-subscription:17acca37-2b4d-448c-b9bb-51ce54d11284
863
+ GraphqlChannel is streaming from graphql-event::payload:id:updates-1
864
+ GraphqlChannel is streaming from graphql-event::payload:id:updates-2
865
+ GraphqlChannel is streaming from graphql-subscription:606ac42b-b06b-4d48-9f1e-0a82a7c313b0
866
+ GraphqlChannel#make_trigger({"id"=>"updates-1", "value"=>1})
867
+ [ActionCable] Broadcasting to graphql-event::payload:id:updates-1: "{\"__gid__\":\"Z2lkOi8vZHVtbXkvR3JhcGhxbENoYW5uZWw6OkV4YW1wbGVQYXlsb2FkLzE\"}"
868
+ [ActionCable] Broadcasting to graphql-subscription:17acca37-2b4d-448c-b9bb-51ce54d11284: {:result=>{"data"=>{"payload"=>{"value"=>1}}}, :more=>true}
869
+ GraphqlChannel transmitting {"result"=>{"data"=>{"payload"=>{"value"=>1}}}, "more"=>true} (via streamed from graphql-subscription:17acca37-2b4d-448c-b9bb-51ce54d11284)
870
+ GraphqlChannel#make_trigger({"id"=>"updates-1", "value"=>2})
871
+ [ActionCable] Broadcasting to graphql-event::payload:id:updates-1: "{\"__gid__\":\"Z2lkOi8vZHVtbXkvR3JhcGhxbENoYW5uZWw6OkV4YW1wbGVQYXlsb2FkLzI\"}"
872
+ [ActionCable] Broadcasting to graphql-subscription:17acca37-2b4d-448c-b9bb-51ce54d11284: {:result=>{"data"=>{"payload"=>{"value"=>2}}}, :more=>true}
873
+ GraphqlChannel transmitting {"result"=>{"data"=>{"payload"=>{"value"=>2}}}, "more"=>true} (via streamed from graphql-subscription:17acca37-2b4d-448c-b9bb-51ce54d11284)
874
+ GraphqlChannel#make_trigger({"id"=>"updates-1", "value"=>3})
875
+ [ActionCable] Broadcasting to graphql-event::payload:id:updates-1: "{\"__gid__\":\"Z2lkOi8vZHVtbXkvR3JhcGhxbENoYW5uZWw6OkV4YW1wbGVQYXlsb2FkLzM\"}"
876
+ [ActionCable] Broadcasting to graphql-subscription:17acca37-2b4d-448c-b9bb-51ce54d11284: {:result=>{"data"=>{"payload"=>{"value"=>3}}}, :more=>true}
877
+ GraphqlChannel transmitting {"result"=>{"data"=>{"payload"=>{"value"=>3}}}, "more"=>true} (via streamed from graphql-subscription:17acca37-2b4d-448c-b9bb-51ce54d11284)
878
+ GraphqlChannel#make_trigger({"id"=>"updates-2", "value"=>1})
879
+ [ActionCable] Broadcasting to graphql-event::payload:id:updates-2: "{\"__gid__\":\"Z2lkOi8vZHVtbXkvR3JhcGhxbENoYW5uZWw6OkV4YW1wbGVQYXlsb2FkLzE\"}"
880
+ [ActionCable] Broadcasting to graphql-subscription:606ac42b-b06b-4d48-9f1e-0a82a7c313b0: {:result=>{"data"=>{"payload"=>{"value"=>1}}}, :more=>true}
881
+ GraphqlChannel transmitting {"result"=>{"data"=>{"payload"=>{"value"=>1}}}, "more"=>true} (via streamed from graphql-subscription:606ac42b-b06b-4d48-9f1e-0a82a7c313b0)
882
+ GraphqlChannel#make_trigger({"id"=>"updates-2", "value"=>2})
883
+ [ActionCable] Broadcasting to graphql-event::payload:id:updates-2: "{\"__gid__\":\"Z2lkOi8vZHVtbXkvR3JhcGhxbENoYW5uZWw6OkV4YW1wbGVQYXlsb2FkLzI\"}"
884
+ [ActionCable] Broadcasting to graphql-subscription:606ac42b-b06b-4d48-9f1e-0a82a7c313b0: {:result=>{"data"=>{"payload"=>{"value"=>2}}}, :more=>true}
885
+ GraphqlChannel transmitting {"result"=>{"data"=>{"payload"=>{"value"=>2}}}, "more"=>true} (via streamed from graphql-subscription:606ac42b-b06b-4d48-9f1e-0a82a7c313b0)
886
+ Unsubscribing from channel: {"channel":"GraphqlChannel","id":"15fc7d184bc"}
887
+ GraphqlChannel stopped streaming from graphql-subscription:17acca37-2b4d-448c-b9bb-51ce54d11284
888
+ GraphqlChannel stopped streaming from graphql-event::payload:id:updates-1
889
+ Could not execute command from ({"command"=>"message", "identifier"=>"{\"channel\":\"GraphqlChannel\",\"id\":\"15fc7d184bc\"}", "data"=>"{\"id\":\"updates-1\",\"value\":4,\"action\":\"make_trigger\"}"}) [RuntimeError - Unable to find subscription with identifier: {"channel":"GraphqlChannel","id":"15fc7d184bc"}]: /Users/rmosolgo/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/actioncable-5.1.4/lib/action_cable/connection/subscriptions.rb:76:in `find' | /Users/rmosolgo/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/actioncable-5.1.4/lib/action_cable/connection/subscriptions.rb:53:in `perform_action' | /Users/rmosolgo/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/actioncable-5.1.4/lib/action_cable/connection/subscriptions.rb:17:in `execute_command' | /Users/rmosolgo/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/actioncable-5.1.4/lib/action_cable/connection/base.rb:85:in `dispatch_websocket_message' | /Users/rmosolgo/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/actioncable-5.1.4/lib/action_cable/server/worker.rb:58:in `block in invoke'
890
+ GraphqlChannel#make_trigger({"id"=>"updates-2", "value"=>3})
891
+ [ActionCable] Broadcasting to graphql-event::payload:id:updates-2: "{\"__gid__\":\"Z2lkOi8vZHVtbXkvR3JhcGhxbENoYW5uZWw6OkV4YW1wbGVQYXlsb2FkLzM\"}"
892
+ [ActionCable] Broadcasting to graphql-subscription:606ac42b-b06b-4d48-9f1e-0a82a7c313b0: {:result=>{"data"=>{"payload"=>{"value"=>3}}}, :more=>true}
893
+ GraphqlChannel transmitting {"result"=>{"data"=>{"payload"=>{"value"=>3}}}, "more"=>true} (via streamed from graphql-subscription:606ac42b-b06b-4d48-9f1e-0a82a7c313b0)
894
+ GraphqlChannel#make_trigger({"id"=>"updates-2", "value"=>4})
895
+ [ActionCable] Broadcasting to graphql-event::payload:id:updates-2: "4x"
896
+ [ActionCable] Broadcasting to graphql-subscription:606ac42b-b06b-4d48-9f1e-0a82a7c313b0: {:result=>{"data"=>{"payload"=>{"value"=>400}}}, :more=>true}
897
+ GraphqlChannel transmitting {"result"=>{"data"=>{"payload"=>{"value"=>400}}}, "more"=>true} (via streamed from graphql-subscription:606ac42b-b06b-4d48-9f1e-0a82a7c313b0)
898
+ Finished "/cable/" [WebSocket] for 127.0.0.1 at 2017-11-16 21:31:15 -0500
899
+ GraphqlChannel stopped streaming from graphql-subscription:606ac42b-b06b-4d48-9f1e-0a82a7c313b0
900
+ GraphqlChannel stopped streaming from graphql-event::payload:id:updates-2
901
+ -----------------------------------------------------------
902
+ ActionCableSubscriptionsTest: test_it_handles_subscriptions
903
+ -----------------------------------------------------------
904
+ Started GET "/" for 127.0.0.1 at 2017-11-16 21:31:35 -0500
905
+ Processing by PagesController#show as HTML
906
+ Rendering pages/show.html within layouts/application
907
+ Rendered pages/show.html within layouts/application (2.2ms)
908
+ Completed 200 OK in 195ms (Views: 194.0ms)
909
+ Started GET "/assets/application-aca150c4b2db51d5326af18134f6281fbce7e823a372b0337cca65ff41b4a7ea.js" for 127.0.0.1 at 2017-11-16 21:31:35 -0500
910
+ Started GET "/cable" for 127.0.0.1 at 2017-11-16 21:31:35 -0500
911
+ Started GET "/cable/" [WebSocket] for 127.0.0.1 at 2017-11-16 21:31:35 -0500
912
+ Successfully upgraded to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: Upgrade, HTTP_UPGRADE: websocket)
913
+ GraphqlChannel is transmitting the subscription confirmation
914
+ GraphqlChannel is transmitting the subscription confirmation
915
+ GraphqlChannel#execute({"query"=>"subscription($id: ID!) { payload(id: $id) { value } }", "variables"=>{"id"=>"updates-2"}})
916
+ GraphqlChannel transmitting {:result=>{"data"=>nil}, :more=>true}
917
+ GraphqlChannel#execute({"query"=>"subscription($id: ID!) { payload(id: $id) { value } }", "variables"=>{"id"=>"updates-1"}})
918
+ GraphqlChannel transmitting {:result=>{"data"=>nil}, :more=>true}
919
+ GraphqlChannel is streaming from graphql-subscription:deb86012-88c0-4449-872c-f71c390a3c11
920
+ GraphqlChannel is streaming from graphql-event::payload:id:updates-2
921
+ GraphqlChannel is streaming from graphql-subscription:ded77eba-1a76-4246-83f2-bd4637b11de0
922
+ GraphqlChannel is streaming from graphql-event::payload:id:updates-1
923
+ GraphqlChannel#make_trigger({"id"=>"updates-1", "value"=>1})
924
+ [ActionCable] Broadcasting to graphql-event::payload:id:updates-1: "{\"__gid__\":\"Z2lkOi8vZHVtbXkvR3JhcGhxbENoYW5uZWw6OkV4YW1wbGVQYXlsb2FkLzE\"}"
925
+ [ActionCable] Broadcasting to graphql-subscription:ded77eba-1a76-4246-83f2-bd4637b11de0: {:result=>{"data"=>{"payload"=>{"value"=>1}}}, :more=>true}
926
+ GraphqlChannel transmitting {"result"=>{"data"=>{"payload"=>{"value"=>1}}}, "more"=>true} (via streamed from graphql-subscription:ded77eba-1a76-4246-83f2-bd4637b11de0)
927
+ GraphqlChannel#make_trigger({"id"=>"updates-1", "value"=>2})
928
+ [ActionCable] Broadcasting to graphql-event::payload:id:updates-1: "{\"__gid__\":\"Z2lkOi8vZHVtbXkvR3JhcGhxbENoYW5uZWw6OkV4YW1wbGVQYXlsb2FkLzI\"}"
929
+ [ActionCable] Broadcasting to graphql-subscription:ded77eba-1a76-4246-83f2-bd4637b11de0: {:result=>{"data"=>{"payload"=>{"value"=>2}}}, :more=>true}
930
+ GraphqlChannel transmitting {"result"=>{"data"=>{"payload"=>{"value"=>2}}}, "more"=>true} (via streamed from graphql-subscription:ded77eba-1a76-4246-83f2-bd4637b11de0)
931
+ GraphqlChannel#make_trigger({"id"=>"updates-1", "value"=>3})
932
+ [ActionCable] Broadcasting to graphql-event::payload:id:updates-1: "{\"__gid__\":\"Z2lkOi8vZHVtbXkvR3JhcGhxbENoYW5uZWw6OkV4YW1wbGVQYXlsb2FkLzM\"}"
933
+ [ActionCable] Broadcasting to graphql-subscription:ded77eba-1a76-4246-83f2-bd4637b11de0: {:result=>{"data"=>{"payload"=>{"value"=>3}}}, :more=>true}
934
+ GraphqlChannel transmitting {"result"=>{"data"=>{"payload"=>{"value"=>3}}}, "more"=>true} (via streamed from graphql-subscription:ded77eba-1a76-4246-83f2-bd4637b11de0)
935
+ GraphqlChannel#make_trigger({"id"=>"updates-2", "value"=>1})
936
+ [ActionCable] Broadcasting to graphql-event::payload:id:updates-2: "{\"__gid__\":\"Z2lkOi8vZHVtbXkvR3JhcGhxbENoYW5uZWw6OkV4YW1wbGVQYXlsb2FkLzE\"}"
937
+ [ActionCable] Broadcasting to graphql-subscription:deb86012-88c0-4449-872c-f71c390a3c11: {:result=>{"data"=>{"payload"=>{"value"=>1}}}, :more=>true}
938
+ GraphqlChannel transmitting {"result"=>{"data"=>{"payload"=>{"value"=>1}}}, "more"=>true} (via streamed from graphql-subscription:deb86012-88c0-4449-872c-f71c390a3c11)
939
+ GraphqlChannel#make_trigger({"id"=>"updates-2", "value"=>2})
940
+ [ActionCable] Broadcasting to graphql-event::payload:id:updates-2: "{\"__gid__\":\"Z2lkOi8vZHVtbXkvR3JhcGhxbENoYW5uZWw6OkV4YW1wbGVQYXlsb2FkLzI\"}"
941
+ [ActionCable] Broadcasting to graphql-subscription:deb86012-88c0-4449-872c-f71c390a3c11: {:result=>{"data"=>{"payload"=>{"value"=>2}}}, :more=>true}
942
+ GraphqlChannel transmitting {"result"=>{"data"=>{"payload"=>{"value"=>2}}}, "more"=>true} (via streamed from graphql-subscription:deb86012-88c0-4449-872c-f71c390a3c11)
943
+ Unsubscribing from channel: {"channel":"GraphqlChannel","id":"15fc7d19ae3"}
944
+ GraphqlChannel stopped streaming from graphql-subscription:ded77eba-1a76-4246-83f2-bd4637b11de0
945
+ GraphqlChannel stopped streaming from graphql-event::payload:id:updates-1
946
+ Could not execute command from ({"command"=>"message", "identifier"=>"{\"channel\":\"GraphqlChannel\",\"id\":\"15fc7d19ae3\"}", "data"=>"{\"id\":\"updates-1\",\"value\":4,\"action\":\"make_trigger\"}"}) [RuntimeError - Unable to find subscription with identifier: {"channel":"GraphqlChannel","id":"15fc7d19ae3"}]: /Users/rmosolgo/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/actioncable-5.1.4/lib/action_cable/connection/subscriptions.rb:76:in `find' | /Users/rmosolgo/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/actioncable-5.1.4/lib/action_cable/connection/subscriptions.rb:53:in `perform_action' | /Users/rmosolgo/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/actioncable-5.1.4/lib/action_cable/connection/subscriptions.rb:17:in `execute_command' | /Users/rmosolgo/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/actioncable-5.1.4/lib/action_cable/connection/base.rb:85:in `dispatch_websocket_message' | /Users/rmosolgo/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/actioncable-5.1.4/lib/action_cable/server/worker.rb:58:in `block in invoke'
947
+ GraphqlChannel#make_trigger({"id"=>"updates-2", "value"=>3})
948
+ [ActionCable] Broadcasting to graphql-event::payload:id:updates-2: "{\"__gid__\":\"Z2lkOi8vZHVtbXkvR3JhcGhxbENoYW5uZWw6OkV4YW1wbGVQYXlsb2FkLzM\"}"
949
+ [ActionCable] Broadcasting to graphql-subscription:deb86012-88c0-4449-872c-f71c390a3c11: {:result=>{"data"=>{"payload"=>{"value"=>3}}}, :more=>true}
950
+ GraphqlChannel transmitting {"result"=>{"data"=>{"payload"=>{"value"=>3}}}, "more"=>true} (via streamed from graphql-subscription:deb86012-88c0-4449-872c-f71c390a3c11)
951
+ GraphqlChannel#make_trigger({"id"=>"updates-2", "value"=>4})
952
+ [ActionCable] Broadcasting to graphql-event::payload:id:updates-2: "4x"
953
+ [ActionCable] Broadcasting to graphql-subscription:deb86012-88c0-4449-872c-f71c390a3c11: {:result=>{"data"=>{"payload"=>{"value"=>400}}}, :more=>true}
954
+ GraphqlChannel transmitting {"result"=>{"data"=>{"payload"=>{"value"=>400}}}, "more"=>true} (via streamed from graphql-subscription:deb86012-88c0-4449-872c-f71c390a3c11)
955
+ Finished "/cable/" [WebSocket] for 127.0.0.1 at 2017-11-16 21:31:41 -0500
956
+ GraphqlChannel stopped streaming from graphql-subscription:deb86012-88c0-4449-872c-f71c390a3c11
957
+ GraphqlChannel stopped streaming from graphql-event::payload:id:updates-2
958
+ -----------------------------------------------------------
959
+ ActionCableSubscriptionsTest: test_it_handles_subscriptions
960
+ -----------------------------------------------------------
961
+ Started GET "/" for 127.0.0.1 at 2017-11-16 21:31:55 -0500
962
+ Processing by PagesController#show as HTML
963
+ Rendering pages/show.html within layouts/application
964
+ Rendered pages/show.html within layouts/application (1.0ms)
965
+ Completed 200 OK in 111ms (Views: 110.0ms)
966
+ Started GET "/assets/application-aca150c4b2db51d5326af18134f6281fbce7e823a372b0337cca65ff41b4a7ea.js" for 127.0.0.1 at 2017-11-16 21:31:55 -0500
967
+ Started GET "/cable" for 127.0.0.1 at 2017-11-16 21:31:56 -0500
968
+ Started GET "/cable/" [WebSocket] for 127.0.0.1 at 2017-11-16 21:31:56 -0500
969
+ Successfully upgraded to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: Upgrade, HTTP_UPGRADE: websocket)
970
+ GraphqlChannel is transmitting the subscription confirmation
971
+ GraphqlChannel is transmitting the subscription confirmation
972
+ GraphqlChannel#execute({"query"=>"subscription($id: ID!) { payload(id: $id) { value } }", "variables"=>{"id"=>"updates-2"}})
973
+ GraphqlChannel transmitting {:result=>{"data"=>nil}, :more=>true}
974
+ GraphqlChannel is streaming from graphql-event::payload:id:updates-2
975
+ GraphqlChannel#execute({"query"=>"subscription($id: ID!) { payload(id: $id) { value } }", "variables"=>{"id"=>"updates-1"}})
976
+ GraphqlChannel is streaming from graphql-subscription:4aa99f83-32cb-4a2f-a337-ebfa958ad4f9
977
+ GraphqlChannel transmitting {:result=>{"data"=>nil}, :more=>true}
978
+ GraphqlChannel is streaming from graphql-subscription:359ce997-f8e7-4431-bd71-74af6276e37e
979
+ GraphqlChannel is streaming from graphql-event::payload:id:updates-1
980
+ GraphqlChannel#make_trigger({"id"=>"updates-1", "value"=>1})
981
+ [ActionCable] Broadcasting to graphql-event::payload:id:updates-1: "{\"__gid__\":\"Z2lkOi8vZHVtbXkvR3JhcGhxbENoYW5uZWw6OkV4YW1wbGVQYXlsb2FkLzE\"}"
982
+ [ActionCable] Broadcasting to graphql-subscription:359ce997-f8e7-4431-bd71-74af6276e37e: {:result=>{"data"=>{"payload"=>{"value"=>1}}}, :more=>true}
983
+ GraphqlChannel transmitting {"result"=>{"data"=>{"payload"=>{"value"=>1}}}, "more"=>true} (via streamed from graphql-subscription:359ce997-f8e7-4431-bd71-74af6276e37e)
984
+ GraphqlChannel#make_trigger({"id"=>"updates-1", "value"=>2})
985
+ [ActionCable] Broadcasting to graphql-event::payload:id:updates-1: "{\"__gid__\":\"Z2lkOi8vZHVtbXkvR3JhcGhxbENoYW5uZWw6OkV4YW1wbGVQYXlsb2FkLzI\"}"
986
+ [ActionCable] Broadcasting to graphql-subscription:359ce997-f8e7-4431-bd71-74af6276e37e: {:result=>{"data"=>{"payload"=>{"value"=>2}}}, :more=>true}
987
+ GraphqlChannel transmitting {"result"=>{"data"=>{"payload"=>{"value"=>2}}}, "more"=>true} (via streamed from graphql-subscription:359ce997-f8e7-4431-bd71-74af6276e37e)
988
+ GraphqlChannel#make_trigger({"id"=>"updates-1", "value"=>3})
989
+ [ActionCable] Broadcasting to graphql-event::payload:id:updates-1: "{\"__gid__\":\"Z2lkOi8vZHVtbXkvR3JhcGhxbENoYW5uZWw6OkV4YW1wbGVQYXlsb2FkLzM\"}"
990
+ [ActionCable] Broadcasting to graphql-subscription:359ce997-f8e7-4431-bd71-74af6276e37e: {:result=>{"data"=>{"payload"=>{"value"=>3}}}, :more=>true}
991
+ GraphqlChannel transmitting {"result"=>{"data"=>{"payload"=>{"value"=>3}}}, "more"=>true} (via streamed from graphql-subscription:359ce997-f8e7-4431-bd71-74af6276e37e)
992
+ GraphqlChannel#make_trigger({"id"=>"updates-2", "value"=>1})
993
+ [ActionCable] Broadcasting to graphql-event::payload:id:updates-2: "{\"__gid__\":\"Z2lkOi8vZHVtbXkvR3JhcGhxbENoYW5uZWw6OkV4YW1wbGVQYXlsb2FkLzE\"}"
994
+ [ActionCable] Broadcasting to graphql-subscription:4aa99f83-32cb-4a2f-a337-ebfa958ad4f9: {:result=>{"data"=>{"payload"=>{"value"=>1}}}, :more=>true}
995
+ GraphqlChannel transmitting {"result"=>{"data"=>{"payload"=>{"value"=>1}}}, "more"=>true} (via streamed from graphql-subscription:4aa99f83-32cb-4a2f-a337-ebfa958ad4f9)
996
+ GraphqlChannel#make_trigger({"id"=>"updates-2", "value"=>2})
997
+ [ActionCable] Broadcasting to graphql-event::payload:id:updates-2: "{\"__gid__\":\"Z2lkOi8vZHVtbXkvR3JhcGhxbENoYW5uZWw6OkV4YW1wbGVQYXlsb2FkLzI\"}"
998
+ [ActionCable] Broadcasting to graphql-subscription:4aa99f83-32cb-4a2f-a337-ebfa958ad4f9: {:result=>{"data"=>{"payload"=>{"value"=>2}}}, :more=>true}
999
+ GraphqlChannel transmitting {"result"=>{"data"=>{"payload"=>{"value"=>2}}}, "more"=>true} (via streamed from graphql-subscription:4aa99f83-32cb-4a2f-a337-ebfa958ad4f9)
1000
+ Unsubscribing from channel: {"channel":"GraphqlChannel","id":"15fc7d1abf4"}
1001
+ GraphqlChannel stopped streaming from graphql-subscription:359ce997-f8e7-4431-bd71-74af6276e37e
1002
+ GraphqlChannel stopped streaming from graphql-event::payload:id:updates-1
1003
+ Could not execute command from ({"command"=>"message", "identifier"=>"{\"channel\":\"GraphqlChannel\",\"id\":\"15fc7d1abf4\"}", "data"=>"{\"id\":\"updates-1\",\"value\":4,\"action\":\"make_trigger\"}"}) [RuntimeError - Unable to find subscription with identifier: {"channel":"GraphqlChannel","id":"15fc7d1abf4"}]: /Users/rmosolgo/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/actioncable-5.1.4/lib/action_cable/connection/subscriptions.rb:76:in `find' | /Users/rmosolgo/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/actioncable-5.1.4/lib/action_cable/connection/subscriptions.rb:53:in `perform_action' | /Users/rmosolgo/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/actioncable-5.1.4/lib/action_cable/connection/subscriptions.rb:17:in `execute_command' | /Users/rmosolgo/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/actioncable-5.1.4/lib/action_cable/connection/base.rb:85:in `dispatch_websocket_message' | /Users/rmosolgo/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/actioncable-5.1.4/lib/action_cable/server/worker.rb:58:in `block in invoke'
1004
+ GraphqlChannel#make_trigger({"id"=>"updates-2", "value"=>3})
1005
+ [ActionCable] Broadcasting to graphql-event::payload:id:updates-2: "{\"__gid__\":\"Z2lkOi8vZHVtbXkvR3JhcGhxbENoYW5uZWw6OkV4YW1wbGVQYXlsb2FkLzM\"}"
1006
+ [ActionCable] Broadcasting to graphql-subscription:4aa99f83-32cb-4a2f-a337-ebfa958ad4f9: {:result=>{"data"=>{"payload"=>{"value"=>3}}}, :more=>true}
1007
+ GraphqlChannel transmitting {"result"=>{"data"=>{"payload"=>{"value"=>3}}}, "more"=>true} (via streamed from graphql-subscription:4aa99f83-32cb-4a2f-a337-ebfa958ad4f9)
1008
+ GraphqlChannel#make_trigger({"id"=>"updates-2", "value"=>4})
1009
+ [ActionCable] Broadcasting to graphql-event::payload:id:updates-2: "4x"
1010
+ [ActionCable] Broadcasting to graphql-subscription:4aa99f83-32cb-4a2f-a337-ebfa958ad4f9: {:result=>{"data"=>{"payload"=>{"value"=>400}}}, :more=>true}
1011
+ GraphqlChannel transmitting {"result"=>{"data"=>{"payload"=>{"value"=>400}}}, "more"=>true} (via streamed from graphql-subscription:4aa99f83-32cb-4a2f-a337-ebfa958ad4f9)
1012
+ Finished "/cable/" [WebSocket] for 127.0.0.1 at 2017-11-16 21:31:59 -0500
1013
+ GraphqlChannel stopped streaming from graphql-subscription:4aa99f83-32cb-4a2f-a337-ebfa958ad4f9
1014
+ GraphqlChannel stopped streaming from graphql-event::payload:id:updates-2
@@ -37,5 +37,9 @@ class ActionCableSubscriptionsTest < ApplicationSystemTestCase
37
37
  click_on("Trigger 2")
38
38
  assert_selector "#updates-2-3", text: "3"
39
39
  refute_selector "#updates-1-4"
40
+
41
+ # wacky behavior to make sure the custom serializer is used:
42
+ click_on("Trigger 2")
43
+ assert_selector "#updates-2-400", text: "400"
40
44
  end
41
45
  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
@@ -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
 
@@ -28,6 +28,18 @@ describe GraphQL::BaseType do
28
28
  assert_equal ["Cheese"], Dummy::CheeseType.metadata[:class_names]
29
29
  end
30
30
 
31
+ describe "name" do
32
+ it "fails with a helpful message" do
33
+ error = assert_raises RuntimeError do
34
+ class BaseType < GraphQL::Schema::Object
35
+ name "KerkShine"
36
+ end
37
+ end
38
+
39
+ assert_equal error.message, "The new name override method is `graphql_name`, not `name`. Usage: graphql_name \"KerkShine\""
40
+ end
41
+ end
42
+
31
43
  describe "forwards-compat with new api" do
32
44
  let(:type_defn) { Dummy::CheeseType }
33
45
  it "responds to new methods" 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
@@ -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
 
@@ -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