appsignal 2.11.10-java → 3.0.0.beta.1-java

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 (91) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +4 -1
  3. data/.semaphore/semaphore.yml +161 -70
  4. data/CHANGELOG.md +5 -18
  5. data/Rakefile +3 -13
  6. data/appsignal.gemspec +2 -24
  7. data/build_matrix.yml +20 -22
  8. data/gemfiles/capistrano2.gemfile +1 -0
  9. data/gemfiles/capistrano3.gemfile +1 -0
  10. data/gemfiles/grape.gemfile +1 -0
  11. data/gemfiles/no_dependencies.gemfile +1 -4
  12. data/gemfiles/rails-3.2.gemfile +0 -2
  13. data/gemfiles/rails-4.2.gemfile +0 -6
  14. data/gemfiles/resque-2.gemfile +4 -0
  15. data/gemfiles/sequel-435.gemfile +1 -0
  16. data/gemfiles/sequel.gemfile +1 -0
  17. data/gemfiles/sinatra.gemfile +1 -0
  18. data/lib/appsignal/auth_check.rb +2 -8
  19. data/lib/appsignal/cli.rb +1 -23
  20. data/lib/appsignal/config.rb +0 -24
  21. data/lib/appsignal/event_formatter.rb +0 -25
  22. data/lib/appsignal/extension.rb +0 -50
  23. data/lib/appsignal/hooks/action_cable.rb +5 -44
  24. data/lib/appsignal/hooks/active_support_notifications.rb +7 -86
  25. data/lib/appsignal/hooks/celluloid.rb +5 -9
  26. data/lib/appsignal/hooks/net_http.rb +2 -12
  27. data/lib/appsignal/hooks/puma.rb +3 -5
  28. data/lib/appsignal/hooks/que.rb +1 -1
  29. data/lib/appsignal/hooks/rake.rb +2 -24
  30. data/lib/appsignal/hooks/redis.rb +2 -13
  31. data/lib/appsignal/hooks/resque.rb +2 -43
  32. data/lib/appsignal/hooks/sidekiq.rb +1 -5
  33. data/lib/appsignal/hooks/unicorn.rb +3 -24
  34. data/lib/appsignal/hooks/webmachine.rb +1 -7
  35. data/lib/appsignal/hooks.rb +0 -23
  36. data/lib/appsignal/integrations/action_cable.rb +34 -0
  37. data/lib/appsignal/integrations/active_support_notifications.rb +77 -0
  38. data/lib/appsignal/integrations/net_http.rb +16 -0
  39. data/lib/appsignal/integrations/object.rb +61 -4
  40. data/lib/appsignal/integrations/padrino.rb +5 -7
  41. data/lib/appsignal/integrations/que.rb +26 -33
  42. data/lib/appsignal/integrations/railtie.rb +1 -4
  43. data/lib/appsignal/integrations/rake.rb +26 -2
  44. data/lib/appsignal/integrations/redis.rb +17 -0
  45. data/lib/appsignal/integrations/resque.rb +39 -10
  46. data/lib/appsignal/integrations/unicorn.rb +28 -0
  47. data/lib/appsignal/integrations/webmachine.rb +22 -24
  48. data/lib/appsignal/minutely.rb +0 -18
  49. data/lib/appsignal/transaction.rb +1 -1
  50. data/lib/appsignal/version.rb +1 -1
  51. data/lib/appsignal.rb +1 -27
  52. data/spec/lib/appsignal/auth_check_spec.rb +1 -24
  53. data/spec/lib/appsignal/cli_spec.rb +1 -1
  54. data/spec/lib/appsignal/config_spec.rb +0 -66
  55. data/spec/lib/appsignal/event_formatter_spec.rb +0 -37
  56. data/spec/lib/appsignal/extension_install_failure_spec.rb +7 -0
  57. data/spec/lib/appsignal/extension_spec.rb +9 -43
  58. data/spec/lib/appsignal/hooks/action_cable_spec.rb +0 -88
  59. data/spec/lib/appsignal/hooks/celluloid_spec.rb +6 -1
  60. data/spec/lib/appsignal/hooks/rake_spec.rb +1 -2
  61. data/spec/lib/appsignal/hooks/redis_spec.rb +50 -15
  62. data/spec/lib/appsignal/hooks/sidekiq_spec.rb +7 -61
  63. data/spec/lib/appsignal/hooks/unicorn_spec.rb +14 -3
  64. data/spec/lib/appsignal/hooks/webmachine_spec.rb +2 -13
  65. data/spec/lib/appsignal/hooks_spec.rb +0 -57
  66. data/spec/lib/appsignal/integrations/object_spec.rb +4 -95
  67. data/spec/lib/appsignal/integrations/padrino_spec.rb +2 -3
  68. data/spec/lib/appsignal/integrations/railtie_spec.rb +0 -45
  69. data/spec/lib/appsignal/integrations/webmachine_spec.rb +26 -8
  70. data/spec/lib/appsignal/minutely_spec.rb +0 -19
  71. data/spec/lib/appsignal/transaction_spec.rb +1 -31
  72. data/spec/lib/appsignal/transmitter_spec.rb +1 -1
  73. data/spec/lib/appsignal/utils/data_spec.rb +87 -133
  74. data/spec/lib/appsignal_spec.rb +0 -69
  75. data/spec/lib/puma/appsignal_spec.rb +0 -28
  76. data/spec/spec_helper.rb +1 -37
  77. data/spec/support/testing.rb +1 -11
  78. data/support/install_deps +0 -4
  79. metadata +10 -23
  80. data/lib/appsignal/cli/notify_of_deploy.rb +0 -131
  81. data/lib/appsignal/integrations/object_ruby_19.rb +0 -37
  82. data/lib/appsignal/integrations/object_ruby_modern.rb +0 -41
  83. data/lib/appsignal/integrations/resque_active_job.rb +0 -19
  84. data/lib/appsignal/js_exception_transaction.rb +0 -56
  85. data/lib/appsignal/rack/js_exception_catcher.rb +0 -80
  86. data/spec/lib/appsignal/cli/notify_of_deploy_spec.rb +0 -180
  87. data/spec/lib/appsignal/integrations/object_19_spec.rb +0 -266
  88. data/spec/lib/appsignal/integrations/resque_active_job_spec.rb +0 -28
  89. data/spec/lib/appsignal/integrations/resque_spec.rb +0 -28
  90. data/spec/lib/appsignal/js_exception_transaction_spec.rb +0 -128
  91. data/spec/lib/appsignal/rack/js_exception_catcher_spec.rb +0 -170
@@ -1,131 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Appsignal
4
- class CLI
5
- # Command line tool to send a "Deploy Marker" for an application to
6
- # AppSignal.
7
- #
8
- # Deploy markers are used on AppSignal.com to indicate changes in an
9
- # application, "Deploy markers" indicate a deploy of an application.
10
- #
11
- # Incidents for exceptions and performance issues will be closed and
12
- # reopened if they occur again in the new deploy.
13
- #
14
- # @note The same logic is used in the Capistrano integration. A deploy
15
- # marker is created on each deploy.
16
- #
17
- # ## Options
18
- #
19
- # - `--environment` required. The environment of the application being
20
- # deployed.
21
- # - `--user` required. User that triggered the deploy.
22
- # - `--revision` required. Git commit SHA or other identifiable revision id.
23
- # - `--name` If no "name" config can be found in a `config/appsignal.yml`
24
- # file or based on the `APPSIGNAL_APP_NAME` environment variable, this
25
- # option is required.
26
- #
27
- # ## Exit codes
28
- #
29
- # - Exits with status code `0` if the deploy marker is sent.
30
- # - Exits with status code `1` if the configuration is not valid and active.
31
- # - Exits with status code `1` if the required options aren't present.
32
- #
33
- # @example basic example
34
- # appsignal notify_of_deploy \
35
- # --user=tom \
36
- # --environment=production \
37
- # --revision=abc1234
38
- #
39
- # @example using a custom app name
40
- # appsignal notify_of_deploy \
41
- # --user=tom \
42
- # --environment=production \
43
- # --revision=abc1234 \
44
- # --name="My app"
45
- #
46
- # @example help command
47
- # appsignal notify_of_deploy --help
48
- #
49
- # @deprecated This method of sending AppSignal deploy markers is
50
- # deprecated. Use the [`revision` config option]
51
- # (https://docs.appsignal.com/ruby/configuration/options.html#app_revision-revision)
52
- # instead. For more information, please read the [deploy markers]
53
- # (https://docs.appsignal.com/application/markers/deploy-markers.html)
54
- # documentation.
55
- # @since 0.2.5
56
- # @see Appsignal::Marker Appsignal::Marker
57
- # @see http://docs.appsignal.com/ruby/command-line/notify_of_deploy.html
58
- # AppSignal notify_of_deploy documentation
59
- # @see http://docs.appsignal.com/appsignal/terminology.html#markers
60
- # Terminology: Deploy marker
61
- class NotifyOfDeploy
62
- class << self
63
- include Appsignal::Utils::DeprecationMessage
64
-
65
- # @param options [Hash]
66
- # @option options :environment [String] environment to load
67
- # configuration for.
68
- # @option options :name [String] custom name of the application.
69
- # @option options :user [String] user who triggered the deploy.
70
- # @option options :revision [String] the revision that has been
71
- # deployed. E.g. a git commit SHA.
72
- # @return [void]
73
- def run(options)
74
- config = config_for(options[:environment])
75
- config[:name] = options[:name] if options[:name]
76
-
77
- validate_active_config(config)
78
- required_config = [:revision, :user]
79
- required_config << :environment if config.env.empty?
80
- required_config << :name if !config[:name] || config[:name].empty?
81
- validate_required_options(options, required_config)
82
-
83
- Appsignal::Marker.new(
84
- {
85
- :revision => options[:revision],
86
- :user => options[:user]
87
- },
88
- config
89
- ).transmit
90
-
91
- puts
92
- message = "This command (appsignal notify_of_deploy) has been " \
93
- "deprecated in favor of the `revision` config option. Please " \
94
- "see our documentation for more information on the recommended " \
95
- "method: " \
96
- "https://docs.appsignal.com/application/markers/deploy-markers.html"
97
- deprecation_message message
98
- end
99
-
100
- private
101
-
102
- def validate_required_options(options, required_options)
103
- missing = required_options.select do |required_option|
104
- val = options[required_option]
105
- val.nil? || (val.respond_to?(:empty?) && val.empty?)
106
- end
107
- return unless missing.any?
108
-
109
- puts "Error: Missing options: #{missing.join(", ")}"
110
- exit 1
111
- end
112
-
113
- def validate_active_config(config)
114
- return if config.active?
115
-
116
- puts "Error: No valid config found."
117
- exit 1
118
- end
119
-
120
- def config_for(environment)
121
- Appsignal::Config.new(
122
- Dir.pwd,
123
- environment,
124
- {},
125
- Logger.new(StringIO.new)
126
- )
127
- end
128
- end
129
- end
130
- end
131
- end
@@ -1,37 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Object
4
- def self.appsignal_instrument_class_method(method_name, options = {})
5
- singleton_class.send \
6
- :alias_method, "appsignal_uninstrumented_#{method_name}", method_name
7
- singleton_class.send(:define_method, method_name) do |*args, &block|
8
- name = options.fetch(:name) do
9
- "#{method_name}.class_method.#{appsignal_reverse_class_name}.other"
10
- end
11
- Appsignal.instrument name do
12
- send "appsignal_uninstrumented_#{method_name}", *args, &block
13
- end
14
- end
15
- end
16
-
17
- def self.appsignal_instrument_method(method_name, options = {})
18
- alias_method "appsignal_uninstrumented_#{method_name}", method_name
19
- define_method method_name do |*args, &block|
20
- name = options.fetch(:name) do
21
- "#{method_name}.#{appsignal_reverse_class_name}.other"
22
- end
23
- Appsignal.instrument name do
24
- send "appsignal_uninstrumented_#{method_name}", *args, &block
25
- end
26
- end
27
- end
28
-
29
- def self.appsignal_reverse_class_name
30
- return "AnonymousClass" unless name
31
- name.split("::").reverse.join(".")
32
- end
33
-
34
- def appsignal_reverse_class_name
35
- self.class.appsignal_reverse_class_name
36
- end
37
- end
@@ -1,41 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Object
4
- def self.appsignal_instrument_class_method(method_name, options = {})
5
- singleton_class.send \
6
- :alias_method, "appsignal_uninstrumented_#{method_name}", method_name
7
- singleton_class.send(:define_method, method_name) do |*args, &block|
8
- name = options.fetch(:name) do
9
- "#{method_name}.class_method.#{appsignal_reverse_class_name}.other"
10
- end
11
- Appsignal.instrument name do
12
- send "appsignal_uninstrumented_#{method_name}", *args, &block
13
- end
14
- end
15
- if singleton_class.respond_to?(:ruby2_keywords, true)
16
- singleton_class.send(:ruby2_keywords, method_name)
17
- end
18
- end
19
-
20
- def self.appsignal_instrument_method(method_name, options = {})
21
- alias_method "appsignal_uninstrumented_#{method_name}", method_name
22
- define_method method_name do |*args, &block|
23
- name = options.fetch(:name) do
24
- "#{method_name}.#{appsignal_reverse_class_name}.other"
25
- end
26
- Appsignal.instrument name do
27
- send "appsignal_uninstrumented_#{method_name}", *args, &block
28
- end
29
- end
30
- ruby2_keywords method_name if respond_to?(:ruby2_keywords, true)
31
- end
32
-
33
- def self.appsignal_reverse_class_name
34
- return "AnonymousClass" unless name
35
- name.split("::").reverse.join(".")
36
- end
37
-
38
- def appsignal_reverse_class_name
39
- self.class.appsignal_reverse_class_name
40
- end
41
- end
@@ -1,19 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Appsignal
4
- module Integrations
5
- # @api private
6
- module ResqueActiveJobPlugin
7
- def self.included(_)
8
- callers = caller
9
- Appsignal::Utils::DeprecationMessage.message \
10
- "The AppSignal ResqueActiveJobPlugin is deprecated and does " \
11
- "nothing on extend. In this version of the AppSignal Ruby gem " \
12
- "the integration with Resque is automatic on all Resque workers. " \
13
- "Please remove the following line from this file to remove this " \
14
- "message: include Appsignal::Integrations::ResqueActiveJobPlugin\n" \
15
- "#{callers.first}"
16
- end
17
- end
18
- end
19
- end
@@ -1,56 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Appsignal
4
- class JSExceptionTransaction
5
- attr_reader :uuid, :ext
6
-
7
- def initialize(data)
8
- @data = data
9
- @uuid = SecureRandom.uuid
10
- @ext = Appsignal::Extension.start_transaction(@uuid, Appsignal::Transaction::FRONTEND, 0)
11
-
12
- set_action
13
- set_metadata
14
- set_error
15
- set_sample_data
16
- end
17
-
18
- def set_action
19
- return unless @data["action"]
20
- ext.set_action(@data["action"])
21
- end
22
-
23
- def set_metadata
24
- return unless @data["path"]
25
- ext.set_metadata("path", @data["path"])
26
- end
27
-
28
- def set_error
29
- ext.set_error(
30
- @data["name"],
31
- @data["message"] || "",
32
- Appsignal::Utils::Data.generate(@data["backtrace"] || [])
33
- )
34
- end
35
-
36
- def set_sample_data
37
- {
38
- :params => @data["params"],
39
- :session_data => @data["session_data"],
40
- :environment => @data["environment"],
41
- :tags => @data["tags"]
42
- }.each do |key, data|
43
- next unless data.is_a?(Array) || data.is_a?(Hash)
44
- ext.set_sample_data(
45
- key.to_s,
46
- Appsignal::Utils::Data.generate(data)
47
- )
48
- end
49
- end
50
-
51
- def complete!
52
- ext.finish(0)
53
- ext.complete
54
- end
55
- end
56
- end
@@ -1,80 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Appsignal
4
- # @api private
5
- module Rack
6
- # JavaScript error catching middleware.
7
- #
8
- # Listens to the endpoint specified in the `frontend_error_catching_path`
9
- # configuration option.
10
- #
11
- # This is automatically included middleware in Rails apps if the
12
- # `frontend_error_catching_path` configuration option is active.
13
- #
14
- # If AppSignal is not active in the current environment, but does have
15
- # JavaScript error catching turned on, we assume that a JavaScript script
16
- # still sends errors to this endpoint. When AppSignal is not active in this
17
- # scenario this middleware still listens to the endpoint, but won't record
18
- # the error. It will return HTTP status code 202.
19
- #
20
- # @example with a Sinatra app
21
- # Sinatra::Application.use(Appsignal::Rack::JSExceptionCatcher)
22
- #
23
- # @see http://docs.appsignal.com/front-end/error-handling.html
24
- # @api private
25
- class JSExceptionCatcher
26
- include Appsignal::Utils::DeprecationMessage
27
-
28
- def initialize(app, _options = nil)
29
- Appsignal.logger.debug \
30
- "Initializing Appsignal::Rack::JSExceptionCatcher"
31
- deprecation_message "The Appsignal::Rack::JSExceptionCatcher is " \
32
- "deprecated and will be removed in a future version. Please use " \
33
- "the official AppSignal JavaScript integration by disabling " \
34
- "`enable_frontend_error_catching` in your configuration and " \
35
- "installing AppSignal for JavaScript instead. " \
36
- "(https://docs.appsignal.com/front-end/)"
37
- @app = app
38
- end
39
-
40
- def call(env)
41
- # Ignore other paths than the error catching path.
42
- return @app.call(env) unless error_cathing_endpoint?(env)
43
-
44
- # Prevent raising a 404 not found when a non-active environment posts
45
- # to this endpoint.
46
- unless Appsignal.active?
47
- return [
48
- 202,
49
- {},
50
- ["AppSignal JavaScript error catching endpoint is not active."]
51
- ]
52
- end
53
-
54
- begin
55
- body = JSON.parse(env["rack.input"].read)
56
- rescue JSON::ParserError
57
- return [400, {}, ["Request payload is not valid JSON."]]
58
- end
59
-
60
- if body["name"].is_a?(String) && !body["name"].empty?
61
- transaction = JSExceptionTransaction.new(body)
62
- transaction.complete!
63
- code = 200
64
- else
65
- Appsignal.logger.debug \
66
- "JSExceptionCatcher: Could not send exception, 'name' is empty."
67
- code = 422
68
- end
69
-
70
- [code, {}, []]
71
- end
72
-
73
- private
74
-
75
- def error_cathing_endpoint?(env)
76
- env["PATH_INFO"] == Appsignal.config[:frontend_error_catching_path]
77
- end
78
- end
79
- end
80
- end
@@ -1,180 +0,0 @@
1
- require "appsignal/cli"
2
-
3
- describe Appsignal::CLI::NotifyOfDeploy do
4
- include CLIHelpers
5
-
6
- let(:out_stream) { std_stream }
7
- let(:output) { out_stream.read }
8
- let(:err_stream) { std_stream }
9
- let(:stderr) { err_stream.read }
10
-
11
- define :include_deploy_notification do
12
- match do |log|
13
- log.include?("Notifying AppSignal of deploy with: ") &&
14
- log.include?("AppSignal has been notified of this deploy!")
15
- end
16
- end
17
- define :include_deploy_notification_with do |options|
18
- match do |log|
19
- return false unless options
20
- values = "revision: #{options[:revision]}, user: #{options[:user]}"
21
- log.include?("Notifying AppSignal of deploy with: #{values}") &&
22
- log.include?("AppSignal has been notified of this deploy!")
23
- end
24
- end
25
- define :include_config_error do
26
- match do |log|
27
- log.include? "Error: No valid config found."
28
- end
29
- end
30
- define :include_missing_options do |options|
31
- match do |log|
32
- log.include? "Error: Missing options: #{options.join(", ")}"
33
- end
34
- end
35
-
36
- def run
37
- capture_std_streams(out_stream, err_stream) do
38
- run_cli("notify_of_deploy", options)
39
- end
40
- end
41
-
42
- context "without config" do
43
- let(:config) { Appsignal::Config.new(tmp_dir, "production") }
44
- let(:options) { {} }
45
- around do |example|
46
- Dir.chdir tmp_dir do
47
- example.run
48
- end
49
- end
50
-
51
- it "prints a config error" do
52
- expect { run }.to raise_error(SystemExit)
53
- expect(output).to include_config_error
54
- expect(output).to_not include_deploy_notification
55
- end
56
- end
57
-
58
- context "with config" do
59
- let(:config) { project_fixture_config }
60
- before do
61
- config[:name] = options[:name] if options[:name]
62
- stub_api_request config, "markers", :revision => options[:revision],
63
- :user => options[:user]
64
- end
65
- around do |example|
66
- Dir.chdir project_fixture_path do
67
- example.run
68
- end
69
- end
70
-
71
- context "without environment" do
72
- let(:options) { { :environment => "", :revision => "foo", :user => "thijs" } }
73
- before do
74
- # Makes the config "active"
75
- ENV["APPSIGNAL_PUSH_API_KEY"] = "foo"
76
- end
77
-
78
- it "requires environment option" do
79
- expect { run }.to raise_error(SystemExit)
80
- expect(output).to include_missing_options(%w[environment])
81
- expect(output).to_not include_deploy_notification
82
- end
83
- end
84
-
85
- context "without known environment" do
86
- let(:options) { { :environment => "foo" } }
87
-
88
- it "prints a config error" do
89
- expect { run }.to raise_error(SystemExit)
90
- expect(output).to include_config_error
91
- expect(output).to_not include_missing_options([])
92
- expect(output).to_not include_deploy_notification
93
- end
94
- end
95
-
96
- context "with known environment" do
97
- context "without required options" do
98
- let(:options) { { :environment => "production" } }
99
-
100
- it "prints a missing required options error" do
101
- expect { run }.to raise_error(SystemExit)
102
- expect(output).to_not include_config_error
103
- expect(output).to include_missing_options(%w[revision user])
104
- expect(output).to_not include_deploy_notification
105
- end
106
-
107
- context "with empty required option" do
108
- let(:options) { { :environment => "production", :revision => "foo", :user => "" } }
109
-
110
- it "prints a missing required option error" do
111
- expect { run }.to raise_error(SystemExit)
112
- expect(output).to_not include_config_error
113
- expect(output).to include_missing_options(%w[user])
114
- expect(output).to_not include_deploy_notification
115
- end
116
- end
117
- end
118
-
119
- context "with required options" do
120
- let(:options) { { :environment => "production", :revision => "aaaaa", :user => "thijs" } }
121
- let(:log_stream) { std_stream }
122
- let(:log) { log_contents(log_stream) }
123
- before { Appsignal.logger = test_logger(log_stream) }
124
-
125
- it "notifies of a deploy" do
126
- run
127
- expect(output).to_not include_config_error
128
- expect(output).to_not include_missing_options([])
129
- expect(output).to include_deploy_notification_with(options)
130
- end
131
-
132
- it "prints a deprecation message" do
133
- run
134
- deprecation_message = "This command (appsignal notify_of_deploy) has been deprecated"
135
- expect(stderr).to include("appsignal WARNING: #{deprecation_message}")
136
- expect(log).to contains_log :warn, deprecation_message
137
- end
138
-
139
- context "with no app name configured" do
140
- before { ENV["APPSIGNAL_APP_NAME"] = "" }
141
-
142
- context "without name option" do
143
- let(:options) { { :environment => "production", :revision => "aaaaa", :user => "thijs" } }
144
-
145
- it "requires name option" do
146
- expect { run }.to raise_error(SystemExit)
147
- expect(output).to_not include_config_error
148
- expect(output).to include_missing_options(%w[name])
149
- expect(output).to_not include_deploy_notification
150
- end
151
- end
152
-
153
- context "with name option" do
154
- let(:options) { { :environment => "production", :revision => "aaaaa", :user => "thijs", :name => "foo" } }
155
-
156
- it "notifies of a deploy with a custom name" do
157
- run
158
- expect(output).to_not include_config_error
159
- expect(output).to_not include_missing_options([])
160
- expect(output).to include_deploy_notification_with(options)
161
- end
162
- end
163
- end
164
-
165
- context "with name option" do
166
- let(:options) do
167
- { :environment => "production", :revision => "aaaaa", :user => "thijs", :name => "foo" }
168
- end
169
-
170
- it "notifies of a deploy with a custom name" do
171
- run
172
- expect(output).to_not include_config_error
173
- expect(output).to_not include_missing_options([])
174
- expect(output).to include_deploy_notification_with(options)
175
- end
176
- end
177
- end
178
- end
179
- end
180
- end