How configure Rspec deprecation_stream so it logs deprecation warnings to a file?

Viewed 131

In a Rails 5.0.7 app that is about to being upgraded to 5.1, we'd like to capture all the (many) deprecation warnings to a file.

Rspec 3.9 provides a pretty clear example of how to send deprecations to a text file: https://relishapp.com/rspec/rspec-core/v/3-9/docs/configuration/custom-deprecation-stream

But it doesn't work:

# spec/spec_helper.rb
RSpec.configure do |config|
   config.deprecation_stream = File.open('deprecations.txt', 'w')
end

When I run a spec that has warnings without the code above, stdout displays a bunch of instances of: DEPRECATION WARNING: uniq is deprecated and will be removed from Rails 5.1 (use distinct instead) (called from...

If I add the config.deprecation_stream code above, and re-run the same spec:

  1. the deprecation warnings no longer are shown on stdout as the specs run
  2. the file deprecations.txt IS created, but
  3. the file is blank.

How do I configure Rspec's deprecation_stream so it works as expected, eg, sends all deprecation warnings to a file?

1 Answers

To catch the Rails deprecation messages you can use active_support.deprecation option:

# config/environments/test.rb
  config.active_support.deprecation = ->(message, callstack, deprecation_horizon, gem_name) {
    # Do anything you want with the deprecation (append to a file, send to an external service, etc.)
    puts "!!! [#{gem_name}] #{message}", callstack[0..2]
  }

This will produce an output like:

!!! [Rails] DEPRECATION WARNING: ActiveRecord::Base.allow_unsafe_raw_sql= is deprecated and will be removed in Rails 6.2 (called from old_method at /my_project/app/models/post.rb:36)
/my_project/app/models/post.rb:36:in `old_method'
/my_project/spec/models/post_spec.rb:36:in `block (3 levels) in <main>'
/my_gems/rspec-core-3.10.1/lib/rspec/core/memoized_helpers.rb:317:in `block (2 levels) in let'

RSpec deprecation_stream is useful with RSpec's deprecations. From the docs, an example can be:

class Foo
  def bar
    RSpec.deprecate "Foo#bar"
  end
end
Related