graphql 1.8.0.pre1 → 1.8.0.pre2

Sign up to get free protection for your applications and to get access to all the features.
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