appsignal 3.2.1-java → 3.3.0-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.
data/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # AppSignal for Ruby gem Changelog
2
2
 
3
+ ## 3.3.0
4
+
5
+ ### Added
6
+
7
+ - [e4314b5b](https://github.com/appsignal/appsignal-ruby/commit/e4314b5b2d3fdf7865555535b2324094ec620349) minor - Hanami 2 is now supported. Requests will now appear as performance measurements.
8
+
9
+ ## 3.2.2
10
+
11
+ ### Changed
12
+
13
+ - [2b1964d9](https://github.com/appsignal/appsignal-ruby/commit/2b1964d94eee0b20c12f5c602c427643057e787b) patch - Track new Ruby 3.2 VM cache metrics. In Ruby 3.2 the `class_serial` and `global_constant_state` metrics are no longer reported for the "Ruby (VM) metrics" magic dashboard, because Ruby 3.2 removed these metrics. Instead we will now report the new `constant_cache_invalidations` and `constant_cache_misses` metrics reported by Ruby 3.2.
14
+ - [6804e898](https://github.com/appsignal/appsignal-ruby/commit/6804e89817234c88105d2376687b5574bfc8e8c9) patch - Use log formatter if set in logger
15
+
3
16
  ## 3.2.1
4
17
 
5
18
  ### Fixed
data/README.md CHANGED
@@ -232,6 +232,7 @@ configurations you need to run the spec suite with a specific Gemfile.
232
232
  BUNDLE_GEMFILE=gemfiles/capistrano2.gemfile bundle exec rspec
233
233
  BUNDLE_GEMFILE=gemfiles/capistrano3.gemfile bundle exec rspec
234
234
  BUNDLE_GEMFILE=gemfiles/grape.gemfile bundle exec rspec
235
+ BUNDLE_GEMFILE=gemfiles/hanami.gemfile bundle exec rspec
235
236
  BUNDLE_GEMFILE=gemfiles/http5.gemfile bundle exec rspec
236
237
  BUNDLE_GEMFILE=gemfiles/no_dependencies.gemfile bundle exec rspec
237
238
  BUNDLE_GEMFILE=gemfiles/padrino.gemfile bundle exec rspec
data/build_matrix.yml CHANGED
@@ -25,6 +25,12 @@ semaphore: # Default `.semaphore/semaphore.yml` contents
25
25
  commands:
26
26
  - checkout
27
27
  - rm -f $HOME/.rbenv/plugins/rbenv-gem-rehash/etc/rbenv.d/exec/~gem-rehash.bash
28
+ - |
29
+ if [ -n "$_LIBYAML" ]; then
30
+ install-package --update libyaml-dev
31
+ else
32
+ echo Skipping libyaml-dev install
33
+ fi
28
34
  - |
29
35
  if [ -n "$_C_VERSION" ]; then
30
36
  sem-version c $_C_VERSION
@@ -54,8 +60,8 @@ semaphore: # Default `.semaphore/semaphore.yml` contents
54
60
  task:
55
61
  prologue:
56
62
  commands:
57
- - cache restore $_BUNDLER_CACHE-bundler-$RUBY_VERSION-$GEMSET-$(checksum $BUNDLE_GEMFILE)
58
- - cache restore $_GEMS_CACHE-gems-$RUBY_VERSION-$GEMSET-$(checksum $BUNDLE_GEMFILE)
63
+ - cache restore $_BUNDLER_CACHE-bundler-$RUBY_VERSION-$GEMSET-$(checksum $BUNDLE_GEMFILE)-$(checksum appsignal.gemspec)
64
+ - cache restore $_GEMS_CACHE-gems-$RUBY_VERSION-$GEMSET-$(checksum $BUNDLE_GEMFILE)-$(checksum appsignal.gemspec)
59
65
  - ./support/bundler_wrapper install --jobs=3 --retry=3
60
66
  jobs:
61
67
  - name: Validate CI setup
@@ -71,15 +77,15 @@ semaphore: # Default `.semaphore/semaphore.yml` contents
71
77
  epilogue:
72
78
  on_pass:
73
79
  commands:
74
- - cache store $_BUNDLER_CACHE-bundler-$RUBY_VERSION-$GEMSET-$(checksum $BUNDLE_GEMFILE) .bundle
75
- - cache store $_GEMS_CACHE-gems-$RUBY_VERSION-$GEMSET-$(checksum $BUNDLE_GEMFILE) $HOME/.gem
80
+ - cache store $_BUNDLER_CACHE-bundler-$RUBY_VERSION-$GEMSET-$(checksum $BUNDLE_GEMFILE)-$(checksum appsignal.gemspec) .bundle
81
+ - cache store $_GEMS_CACHE-gems-$RUBY_VERSION-$GEMSET-$(checksum $BUNDLE_GEMFILE)-$(checksum appsignal.gemspec) $HOME/.gem
76
82
  - name: Ruby linters
77
83
  dependencies: []
78
84
  task:
79
85
  prologue:
80
86
  commands:
81
- - cache restore $_BUNDLER_CACHE-bundler-$RUBY_VERSION-$GEMSET-$(checksum $BUNDLE_GEMFILE)
82
- - cache restore $_GEMS_CACHE-gems-$RUBY_VERSION-$GEMSET-$(checksum $BUNDLE_GEMFILE)
87
+ - cache restore $_BUNDLER_CACHE-bundler-$RUBY_VERSION-$GEMSET-$(checksum $BUNDLE_GEMFILE)-$(checksum appsignal.gemspec)
88
+ - cache restore $_GEMS_CACHE-gems-$RUBY_VERSION-$GEMSET-$(checksum $BUNDLE_GEMFILE)-$(checksum appsignal.gemspec)
83
89
  - ./support/bundler_wrapper install --jobs=3 --retry=3
84
90
  jobs:
85
91
  - name: RuboCop
@@ -95,8 +101,8 @@ semaphore: # Default `.semaphore/semaphore.yml` contents
95
101
  epilogue:
96
102
  on_pass:
97
103
  commands:
98
- - cache store $_BUNDLER_CACHE-bundler-$RUBY_VERSION-$GEMSET-$(checksum $BUNDLE_GEMFILE) .bundle
99
- - cache store $_GEMS_CACHE-gems-$RUBY_VERSION-$GEMSET-$(checksum $BUNDLE_GEMFILE) $HOME/.gem
104
+ - cache store $_BUNDLER_CACHE-bundler-$RUBY_VERSION-$GEMSET-$(checksum $BUNDLE_GEMFILE)-$(checksum appsignal.gemspec) .bundle
105
+ - cache store $_GEMS_CACHE-gems-$RUBY_VERSION-$GEMSET-$(checksum $BUNDLE_GEMFILE)-$(checksum appsignal.gemspec) $HOME/.gem
100
106
  - name: Other linters
101
107
  dependencies: []
102
108
  task:
@@ -143,16 +149,16 @@ matrix:
143
149
  value: "1"
144
150
  prologue: # Shared for all jobs in the build matrix
145
151
  commands:
146
- - cache restore $_BUNDLER_CACHE-bundler-$RUBY_VERSION-$GEMSET-$(checksum $BUNDLE_GEMFILE)
147
- - cache restore $_GEMS_CACHE-gems-$RUBY_VERSION-$(checksum $BUNDLE_GEMFILE)
152
+ - cache restore $_BUNDLER_CACHE-bundler-$RUBY_VERSION-$GEMSET-$(checksum $BUNDLE_GEMFILE)-$(checksum appsignal.gemspec)
153
+ - cache restore $_GEMS_CACHE-gems-$RUBY_VERSION-$(checksum $BUNDLE_GEMFILE)-$(checksum appsignal.gemspec)
148
154
  - ./support/install_deps
149
155
  - bundle config set clean 'true'
150
156
  - ./support/bundler_wrapper install --jobs=3 --retry=3
151
157
  epilogue: # Shared for all jobs in the build matrix
152
158
  on_pass:
153
159
  commands:
154
- - cache store $_BUNDLER_CACHE-bundler-$RUBY_VERSION-$GEMSET-$(checksum $BUNDLE_GEMFILE) .bundle
155
- - cache store $_GEMS_CACHE-gems-$RUBY_VERSION-$(checksum $BUNDLE_GEMFILE) $HOME/.gem
160
+ - cache store $_BUNDLER_CACHE-bundler-$RUBY_VERSION-$GEMSET-$(checksum $BUNDLE_GEMFILE)-$(checksum appsignal.gemspec) .bundle
161
+ - cache store $_GEMS_CACHE-gems-$RUBY_VERSION-$(checksum $BUNDLE_GEMFILE)-$(checksum appsignal.gemspec) $HOME/.gem
156
162
  on_fail:
157
163
  commands:
158
164
  - "[ -e ext/install.report ] && cat ext/install.report || echo 'No ext/install.report file found'"
@@ -196,36 +202,44 @@ matrix:
196
202
  - ruby: "2.5.8"
197
203
  gems: "minimal"
198
204
  - ruby: "2.6.9"
199
- - ruby: "2.7.5"
200
- - ruby: "3.0.3"
201
- - ruby: "3.1.1"
202
- - ruby: "3.2.0-preview1"
203
- - ruby: "jruby-9.2.19.0"
204
- gems: "minimal"
205
+ - ruby: "2.7.7"
206
+ - ruby: "3.0.4"
207
+ - ruby: "3.1.2"
208
+ - ruby: "3.2.0-rc1"
205
209
  env_vars:
206
- - name: "_C_VERSION"
207
- value: "8"
208
- - ruby: "jruby-9.3.6.0"
210
+ - name: "_LIBYAML"
211
+ value: "1"
212
+ - name: "RUBY_CFLAGS"
213
+ value: "-std=gnu99"
214
+ - ruby: "jruby-9.3.9.0"
215
+ gems: "minimal"
216
+ - ruby: "jruby-9.4.0.0"
209
217
  gems: "minimal"
210
218
  gems:
211
219
  - gem: "no_dependencies"
212
220
  - gem: "capistrano2"
213
221
  - gem: "capistrano3"
214
222
  - gem: "grape"
223
+ - gem: "hanami"
224
+ only:
225
+ ruby:
226
+ - "3.0.4"
227
+ - "3.1.2"
228
+ - "3.2.0-rc1"
215
229
  - gem: "http5"
216
230
  - gem: "padrino"
217
231
  - gem: "psych-3"
218
232
  only:
219
233
  ruby:
220
- - "3.0.3"
221
- - "3.1.1"
222
- - "3.2.0-preview1"
234
+ - "3.0.4"
235
+ - "3.1.2"
236
+ - "3.2.0-rc1"
223
237
  - gem: "psych-4"
224
238
  only:
225
239
  ruby:
226
- - "3.0.3"
227
- - "3.1.1"
228
- - "3.2.0-preview1"
240
+ - "3.0.4"
241
+ - "3.1.2"
242
+ - "3.2.0-rc1"
229
243
  - gem: "que"
230
244
  - gem: "que_beta"
231
245
  - gem: "rails-3.2"
@@ -258,7 +272,7 @@ matrix:
258
272
  - "2.4.10"
259
273
  - "2.5.8"
260
274
  - "2.6.9"
261
- - "2.7.5"
275
+ - "2.7.7"
262
276
  - gem: "rails-5.1"
263
277
  only:
264
278
  ruby:
@@ -269,7 +283,7 @@ matrix:
269
283
  - "2.4.10"
270
284
  - "2.5.8"
271
285
  - "2.6.9"
272
- - "2.7.5"
286
+ - "2.7.7"
273
287
  - gem: "rails-5.2"
274
288
  only:
275
289
  ruby:
@@ -280,34 +294,34 @@ matrix:
280
294
  - "2.4.10"
281
295
  - "2.5.8"
282
296
  - "2.6.9"
283
- - "2.7.5"
284
- - "jruby-9.2.19.0"
297
+ - "2.7.7"
298
+ - "jruby-9.3.9.0"
285
299
  - gem: "rails-6.0"
286
300
  only:
287
301
  ruby:
288
302
  - "2.5.8"
289
303
  - "2.6.9"
290
- - "2.7.5"
291
- - "3.0.3"
292
- - "jruby-9.2.19.0"
304
+ - "2.7.7"
305
+ - "3.0.4"
306
+ - "jruby-9.4.0.0"
293
307
  - gem: "rails-6.1"
294
308
  only:
295
309
  ruby:
296
310
  - "2.5.8"
297
311
  - "2.6.9"
298
- - "2.7.5"
299
- - "3.0.3"
300
- - "3.1.1"
301
- - "3.2.0-preview1"
302
- - "jruby-9.2.19.0"
303
- - "jruby-9.3.6.0"
312
+ - "2.7.7"
313
+ - "3.0.4"
314
+ - "3.1.2"
315
+ - "3.2.0-rc1"
316
+ - "jruby-9.4.0.0"
304
317
  - gem: "rails-7.0"
305
318
  only:
306
319
  ruby:
307
- - "2.7.5"
308
- - "3.0.3"
309
- - "3.1.1"
310
- - "3.2.0-preview1"
320
+ - "2.7.7"
321
+ - "3.0.4"
322
+ - "3.1.2"
323
+ - "3.2.0-rc1"
324
+ - "jruby-9.4.0.0"
311
325
  - gem: "resque-1"
312
326
  bundler: "1.17.3"
313
327
  only:
@@ -319,7 +333,7 @@ matrix:
319
333
  - "2.4.10"
320
334
  - "2.5.8"
321
335
  - "2.6.9"
322
- - "2.7.5"
336
+ - "2.7.7"
323
337
  - gem: "resque-2"
324
338
  - gem: "sequel"
325
339
  - gem: "sequel-435"
@@ -332,6 +346,6 @@ matrix:
332
346
  - "2.4.10"
333
347
  - "2.5.8"
334
348
  - "2.6.9"
335
- - "2.7.5"
349
+ - "2.7.7"
336
350
  - gem: "sinatra"
337
351
  - gem: "webmachine"
@@ -0,0 +1,7 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem "hanami", "~> 2.0.0"
4
+ gem "hanami-router", "~> 2.0.0"
5
+ gem "hanami-controller", "~> 2.0.0"
6
+
7
+ gemspec :path => '../'
@@ -61,6 +61,8 @@ module Appsignal
61
61
  install_for_padrino(config)
62
62
  elsif installed_frameworks.include?(:grape)
63
63
  install_for_grape(config)
64
+ elsif installed_frameworks.include?(:hanami)
65
+ install_for_hanami(config)
64
66
  elsif installed_frameworks.include?(:sinatra)
65
67
  install_for_sinatra(config)
66
68
  else
@@ -162,6 +164,24 @@ module Appsignal
162
164
  done_notice
163
165
  end
164
166
 
167
+ def install_for_hanami(config)
168
+ puts "Installing for Hanami"
169
+ config[:name] = required_input(" Enter application name: ")
170
+ puts
171
+ configure(config, %w[development production staging], true)
172
+
173
+ puts "Finish Hanami installation"
174
+ puts " Hanami requires some manual configuration."
175
+ puts " After installing the gem, add the following line to config.ru:"
176
+ puts
177
+ puts " require 'appsignal/integrations/hanami'"
178
+ puts
179
+ puts " You can find more information in the documentation:"
180
+ puts " http://docs.appsignal.com/ruby/integrations/hanami.html"
181
+ press_any_key
182
+ done_notice
183
+ end
184
+
165
185
  def install_for_capistrano
166
186
  capfile = File.join(Dir.pwd, "Capfile")
167
187
  return unless File.exist?(capfile)
@@ -256,6 +276,7 @@ module Appsignal
256
276
  out << :sinatra if framework_available? "sinatra"
257
277
  out << :padrino if framework_available? "padrino"
258
278
  out << :grape if framework_available? "grape"
279
+ out << :hanami if framework_available? "hanami"
259
280
  end
260
281
  end
261
282
 
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "appsignal"
4
+
5
+ module Appsignal
6
+ module Integrations
7
+ module HanamiPlugin
8
+ def self.init
9
+ Appsignal.logger.debug("Loading Hanami integration")
10
+
11
+ hanami_app_config = ::Hanami.app.config
12
+ Appsignal.config = Appsignal::Config.new(
13
+ hanami_app_config.root || Dir.pwd,
14
+ hanami_app_config.env
15
+ )
16
+
17
+ Appsignal.start_logger
18
+ Appsignal.start
19
+
20
+ ::Hanami::Action.send(:prepend, Appsignal::Integrations::HanamiIntegration) if Appsignal.active?
21
+ end
22
+ end
23
+ end
24
+ end
25
+
26
+ module Appsignal::Integrations::HanamiIntegration
27
+ def call(env)
28
+ params = ::Hanami::Action::BaseParams.new(env)
29
+ request = ::Hanami::Action::Request.new(
30
+ :env => env,
31
+ :params => params,
32
+ :sessions_enabled => true
33
+ )
34
+
35
+ transaction = Appsignal::Transaction.create(
36
+ SecureRandom.uuid,
37
+ Appsignal::Transaction::HTTP_REQUEST,
38
+ request
39
+ )
40
+
41
+ begin
42
+ Appsignal.instrument("process_action.hanami") do
43
+ super.tap do |response|
44
+ transaction.set_metadata("status", response.status.to_s)
45
+ end
46
+ end
47
+ rescue Exception => error # rubocop:disable Lint/RescueException
48
+ transaction.set_error(error)
49
+ transaction.set_metadata("status", "500")
50
+ raise error
51
+ ensure
52
+ transaction.params = request.params.to_h
53
+ transaction.set_action_if_nil(self.class.name)
54
+ transaction.set_metadata("path", request.path)
55
+ transaction.set_metadata("method", request.request_method)
56
+ transaction.set_http_or_background_queue_start
57
+ Appsignal::Transaction.complete_current!
58
+ end
59
+ end
60
+ end
61
+
62
+ Appsignal::Integrations::HanamiPlugin.init
@@ -5,7 +5,7 @@ require "set"
5
5
 
6
6
  module Appsignal
7
7
  # Logger that flushes logs to the AppSignal logging service
8
- class Logger < ::Logger
8
+ class Logger < ::Logger # rubocop:disable Metrics/ClassLength
9
9
  # Create a new logger instance
10
10
  #
11
11
  # @param group Name of the group for this logger.
@@ -20,7 +20,7 @@ module Appsignal
20
20
  # We support the various methods in the Ruby
21
21
  # logger class by supplying this method.
22
22
  # @api private
23
- def add(severity, message = nil, group = nil)
23
+ def add(severity, message = nil, group = nil) # rubocop:disable Metrics/CyclomaticComplexity
24
24
  severity ||= UNKNOWN
25
25
  return true if severity < level
26
26
  group = @group if group.nil?
@@ -33,6 +33,7 @@ module Appsignal
33
33
  end
34
34
  end
35
35
  return if message.nil?
36
+ message = formatter.call(severity, 0, group, message) if formatter
36
37
  severity_number = case severity
37
38
  when DEBUG
38
39
  2
@@ -64,6 +65,7 @@ module Appsignal
64
65
  return if DEBUG < level
65
66
  message = yield if message.nil? && block_given?
66
67
  return if message.nil?
68
+ message = formatter.call(DEBUG, 0, @group, message) if formatter
67
69
  Appsignal::Extension.log(
68
70
  @group,
69
71
  2,
@@ -80,6 +82,7 @@ module Appsignal
80
82
  return if INFO < level
81
83
  message = yield if message.nil? && block_given?
82
84
  return if message.nil?
85
+ message = formatter.call(INFO, 0, @group, message) if formatter
83
86
  Appsignal::Extension.log(
84
87
  @group,
85
88
  3,
@@ -96,6 +99,7 @@ module Appsignal
96
99
  return if WARN < level
97
100
  message = yield if message.nil? && block_given?
98
101
  return if message.nil?
102
+ message = formatter.call(WARN, 0, @group, message) if formatter
99
103
  Appsignal::Extension.log(
100
104
  @group,
101
105
  5,
@@ -112,6 +116,7 @@ module Appsignal
112
116
  return if ERROR < level
113
117
  message = yield if message.nil? && block_given?
114
118
  return if message.nil?
119
+ message = formatter.call(ERROR, 0, @group, message) if formatter
115
120
  Appsignal::Extension.log(
116
121
  @group,
117
122
  6,
@@ -128,6 +133,7 @@ module Appsignal
128
133
  return if FATAL < level
129
134
  message = yield if message.nil? && block_given?
130
135
  return if message.nil?
136
+ message = formatter.call(FATAL, 0, @group, message) if formatter
131
137
  Appsignal::Extension.log(
132
138
  @group,
133
139
  7,
@@ -18,17 +18,38 @@ module Appsignal
18
18
  def call
19
19
  stat = RubyVM.stat
20
20
 
21
- set_gauge(
22
- "ruby_vm",
23
- stat[:class_serial],
24
- :metric => :class_serial
25
- )
26
-
27
- set_gauge(
28
- "ruby_vm",
29
- stat[:constant_cache] ? stat[:constant_cache].values.sum : stat[:global_constant_state],
30
- :metric => :global_constant_state
31
- )
21
+ constant_cache_invalidations = stat[:constant_cache_invalidations]
22
+ if constant_cache_invalidations
23
+ set_gauge(
24
+ "ruby_vm",
25
+ constant_cache_invalidations,
26
+ :metric => :constant_cache_invalidations
27
+ )
28
+ end
29
+
30
+ constant_cache_misses = stat[:constant_cache_misses]
31
+ if constant_cache_misses
32
+ set_gauge(
33
+ "ruby_vm",
34
+ constant_cache_misses,
35
+ :metric => :constant_cache_misses
36
+ )
37
+ end
38
+
39
+ class_serial = stat[:class_serial]
40
+ if class_serial
41
+ set_gauge("ruby_vm", class_serial, :metric => :class_serial)
42
+ end
43
+
44
+ global_constant_state =
45
+ stat[:constant_cache] ? stat[:constant_cache].values.sum : stat[:global_constant_state]
46
+ if global_constant_state
47
+ set_gauge(
48
+ "ruby_vm",
49
+ global_constant_state,
50
+ :metric => :global_constant_state
51
+ )
52
+ end
32
53
 
33
54
  set_gauge("thread_count", Thread.list.size)
34
55
  if Appsignal::GarbageCollection.enabled?
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Appsignal
4
- VERSION = "3.2.1".freeze
4
+ VERSION = "3.3.0".freeze
5
5
  end
@@ -20,12 +20,7 @@ describe Appsignal::AuthCheck do
20
20
  end
21
21
 
22
22
  def build_uri_query_string(hash)
23
- hash.map do |k, v|
24
- k.to_s.tap do |s|
25
- next unless v
26
- s << "=#{v}"
27
- end
28
- end.join("&")
23
+ URI.encode_www_form(hash)
29
24
  end
30
25
 
31
26
  describe "#perform" do
@@ -660,7 +660,73 @@ describe Appsignal::CLI::Install do
660
660
  end
661
661
  end
662
662
 
663
- if !rails_present? && !sinatra_present? && !padrino_present? && !grape_present?
663
+ if hanami2_present?
664
+ context "with hanami" do
665
+ it_behaves_like "push_api_key validation"
666
+ it_behaves_like "requires an application name"
667
+
668
+ describe "hanami specific tests" do
669
+ let(:installation_instructions) do
670
+ [
671
+ "Installing for Hanami",
672
+ "Hanami requires some manual configuration.",
673
+ "http://docs.appsignal.com/ruby/integrations/hanami.html"
674
+ ]
675
+ end
676
+ let(:app_name) { "Test app" }
677
+ before { enter_app_name app_name }
678
+
679
+ describe "configuration with environment variables" do
680
+ before { choose_environment_config }
681
+
682
+ it_behaves_like "windows installation"
683
+ it_behaves_like "capistrano install"
684
+ it_behaves_like "demo data"
685
+
686
+ it "prints environment variables" do
687
+ run
688
+
689
+ expect(output).to include_env_push_api_key(push_api_key)
690
+ expect(output).to include_env_app_name(app_name)
691
+ end
692
+
693
+ it "completes the installation" do
694
+ run
695
+
696
+ expect(output).to include(*installation_instructions)
697
+ expect(output).to include_complete_install
698
+ end
699
+ end
700
+
701
+ describe "configure with a configuration file" do
702
+ before { choose_config_file }
703
+
704
+ it_behaves_like "windows installation"
705
+ it_behaves_like "capistrano install"
706
+ it_behaves_like "demo data"
707
+
708
+ it "writes configuration to file" do
709
+ run
710
+ expect(output).to include_file_config
711
+ expect(config_file).to configure_app_name(app_name)
712
+ expect(config_file).to configure_push_api_key(push_api_key)
713
+ expect(config_file).to configure_environment("development")
714
+ expect(config_file).to configure_environment("staging")
715
+ expect(config_file).to configure_environment("production")
716
+ end
717
+
718
+ it "completes the installation" do
719
+ run
720
+
721
+ expect(output).to include(*installation_instructions)
722
+ expect(output).to include_complete_install
723
+ end
724
+ end
725
+ end
726
+ end
727
+ end
728
+
729
+ if !rails_present? && !sinatra_present? && !padrino_present? && !grape_present? && !hanami2_present?
664
730
  context "with unknown framework" do
665
731
  let(:push_api_key) { "my_key" }
666
732