Suppress Ruby warnings when running specs - ruby-on-rails

I'm looking for a way to suppress Ruby warnings when I run my specs.
spec spec/models/account_spec.rb
I receive warnings such as:
DEPRECATION WARNING: ActiveSupport::Dependencies.load_paths is deprecated, ...
warning: already initialized constant SOME_CONSTANT_NAME
Removing the ActiveSupport warning is quite easy with ActiveSupport::Deprecation.silenced = true.
How do I prevent the already initialized constant warnings as part of my spec command? Or through creating another spec file that can suppress such warnings. Keep in mind that these warnings are from gem files, therefore I cannot go into those files and surround them with Kernel.silence_warnings.
Note:
I understand that suppressing warnings are bad. However, when I run a single spec from within vim it would be nice if the warnings didn't clutter my screen.

The syntax for RUBYOPT is
RUBYOPT="-W0" rspec
Tested in ruby 2.1.x and 2.14.x

If you run your specs directly with the ruby command instead of the spec wrapper, you can use the -W command line option to silence warnings:
$ ruby --help
[...]
-W[level] set warning level; 0=silence, 1=medium, 2=verbose (default)
So in your case:
$ ruby -W0 -Ispec spec/models/event_spec.rb
should not show you any warnings.
Alternatively, you could set $VERBOSE=nil before your gems are loaded, ie at the top of your environment.rb (or application.rb if you're on Rails 3). Note that this disables all warnings all the time.
Or, since you are using Rails, you should be able to use Kernel.silence_warnings around the Bundler.require block if you're using Bundler:
Kernel.silence_warnings do
Bundler.require(:default, Rails.env) if defined?(Bundler)
end
More selectively, set $VERBOSE only for loading specific gems:
config.gem 'wellbehaving_gem'
original_verbosity = $VERBOSE
$VERBOSE = nil
config.gem 'noisy_gem_a'
$VERBOSE = original_verbosity

Related with this post, you can manage deprecation warnings according to th environment in which you are working, as said in rails guides:
active_support.deprecation_behavior Sets up deprecation reporting for
environments, defaulting to :log for development, :notify for
production and :stderr for test. If a value isn't set for
config.active_support.deprecation then this initializer will prompt
the user to configure this line in the current environment's
config/environments file. Can be set to an array of values.
So just change in config/environments/test.rb the value :stderr for :log
Rails.application.configure do
...
# Print deprecation notices to the log file instead of console.
config.active_support.deprecation = :log
...
end
And with this change, the deprecation warnings will now be printed to the log/test.log instead of the console output.

You can also use the "RUBYOPT" environment variable to pass -W0 to rspec:
RUBYOPT=W0 rspec spec/models/event_spec.rb
This allows you to run multiple specs by passing in a directory
RUBYOPT=W0 rspec spec/models

The only solution that worked for me is to add $VERBOSE = nil on top of my config/environments/test.rb file
Rails.application.configure do
$VERBOSE = nil
I'm with faker warning problems faker-1.9.6/lib/faker/default/number.rb:34.
Use it local because it hides all other warnings.

Putting Warning[:deprecated] = false after require "rails/all" in config/application.rb works very well to suppress those warnings everywhere. You can do
Warning[:deprecated] = false if Rails.env.test?
for your particular case, or better yet - put it in config/environments/test.rb, but I'm not sure how well it is going to work since I belive some stuff is loaded before that.

If you have this in your .rspec file, remove
--warnings
from your .rspec file in your project root.

rspec has a tag option you can use -- I simply used /dev/null.
rspec spec --deprecation-out /dev/null

Actually, perhaps you shouldn't ignore your warnings, but test them, to make sure they are fired where they're supposed to be.
It's not the easiest to use, but it looks like this:
obj.should_receive(:warn).with("Some Message")
I found it here, and tested it for my use case, and it works (and the warnings disappear from the console, of course)

If you're using guard for tests and Rails 6 and you get warnings such as:
- "warning: FILE in eval may not return location in binding"
- "warning: Capturing the given block using Proc.new is deprecated; use &block instead"
- "warning: Using the last argument as keyword parameters is deprecated; maybe ** should be added to the call"
Then the only way so remove them all is to:
Add $VERBOSE = nil to config/environments/test.rb
Run guard with: RUBYOPT='-W0' bundle exec guard
I guess this is not good advice to remove all those warnings so later on, after a few gem updates, we should remove those lines again so that we get the right warnings on your own code usage for example.

Related

Rspec - where is the extra configuration for test environment?

I am using the default test for different purposes and I have decided to make a specific rspec environment configuration for running the test suite.
However, I discovered that upon changing to ENV["RAILS_ENV"] ||= rspec in my rails_helper.rb file, suddenly a LOT of things are going wrong, constants are not being loaded (FactoryGirl, DatabaseCleaner, etc. throw uninitialized constant errors)
My question is, where is the code that loads those guys in test environment ? Since I am planning to use this stage for other purposes than running automatic tests, I'm afraid this "out of nowhere" added configuration might not work well with what I am planning to do.
From the perspective of Rails, the test environment is configured and loaded like any other environment such as production or development. You can see this prefixing RAILS_ENV=test to many of the native Rails commands e.g. RAILS_ENV=test rails c will load the rails console for the test environment, and so on. Similarly, all test-specific configuration within Rails is defined in test.rb in your config/environments folder.
However, when you run your specs with rspec spec, you're actually starting the RSpec runner, which, for most intents and purposes, runs independently of Rails (even with the rspec-rails gem).
By convention, when RSpec starts the first thing it does is read command line args from the .rspec in the current directory, if it exists. Then it runs spec_helper.rb (and also rails_helper.rb for rspec-rails 3+). It's actually the spec_helper.rb which does all the heavy-lifting in loading the Rails environment for your tests, along with any of the modules you're using in tests, such as DatabaseCleaner, FactoryGirl, etc.
If you're wondering how RSpec hooks into Rails, the bulk of it is performed in this line, which bootstraps Rails.
require File.expand_path('../../config/environment', __FILE__)
Now, as to your question, without the ENV['RAILS_ENV'] ||= 'test' statement, the above line will load Rails in the default environment (development), which isn't what you want, since any gems not in the :test group will not be loaded, and environments/test.rb will not be loaded either.
TL;DR
Test configuration is handled by two files: spec/spec_helper.rb (sometimes named rails_helper.rb) and config/environments/test.rb. The former configures RSpec and any objects and modules which will be used specifically within the files used in spec, the latter configures your Rails app itself. Omitting ENV['RAILS_ENV'] ||= test loads the development environment and gemsets instead of the test environment and gemsets, which is why you're getting a ton of errors.
If you are getting uninitialized constant errors for FactoryGirl, DatabaseCleaner etc, you most likely included them to test group in your Gemfile.
You should move them to rspec group, eg:
# Gemfile
group :rspec do
gem 'factory_girl_rails', '~> 4.0'
gem 'faker'
end

Rails I18n deprecation warning on a gem

Related to this questions, I have a gem that uses rails 4.1.8 and rspec 2.99. When I run my rspec suite I get the deprecation notice:
[deprecated] I18n.enforce_available_locales will default to true in the future. If you really want to skip validation of your locale you can set I18n.enforce_available_locales = false to avoid this message.
In the linked post, the solution was to add config.i18n.enforce_available_locales = true to the application.rb; however, there is no such file for gem and I don't know where to set configuration settings for a gem.
Update
I tried adding this statement into my railtie.rb as that seemed to be implied in the Railtie documentation, but that doesn't seem to have any effect.

How to override RSpec's filter_run_excluding in RubyMine?

Is it possible to get RubyMine to ignore the spec_helper.rb filters?
I usually add config.filter_run_excluding :js => truein my spec_helper file so that when running just rspec it excludes all js tests by default (because the js tests are usually slow).
But when I edit a file in RubyMine I would like to be able to run that single test, and get RubyMine to ignore the config.filter_run_excluding :js => true.
The way I solve it now is to comment out the line in the spec_helper.rb and then run the single test in RubyMine, but it would be nice to get that behaviour by default in RubyMine..
Versions
RubyMine 6.3.3
rspec-rails (2.14.1)
rails 4.0.4
I know I can also just remove the exclude filters in spec_helper and stop using just RSpec for running all the tests, and use rspec -tag ~js, but I would really like to just override the spec_helper filters in RubyMine and not in the terminal.
The easiest way is probably by using an environment variable.
Surround that configuration line in spec_helper with a check for an environment variable
unless ENV['INCLUDE_JS']
config.filter_run_excluding :js => true
end
and add INCLUDE_JS=1 to the RSpec Run/Debug Configurations that you want to not exclude Javascript specs. If you want to do it for all Run/Debug Configurations, add the environment variable to the RSpec default and it will propagate to new configurations when they are created.

What is the correct way to load modules/classes from lib/ when using the config.threadsafe! option?

I've been working on getting our Rails 2.3.8 app running correctly under JRuby. Everything works great until I enable config.threadsafe! in order to achieve the concurrency that JRuby offers. This caused modules and classes in lib/ to no longer autoload.
with config.threadsafe! enabled:
$ ruby script/runner -e production 'p Sim::Sim200Provisioner'
/Users/amchale/.rvm/gems/jruby-1.5.1#web-services/gems/activesupport-2.3.8/lib/active_support/dependencies.rb:105:in `const_missing': uninitialized constant Sim::Sim200Provisioner (NameError)
from (eval):1
with config.threadsafe! disabled:
$ ruby script/runner -e production 'p Sim::Sim200Provisioner'
Sim::Sim200Provisioner
The file in question is lib/sim/sim200_provisioner.rb where Sim is app/models/sim.rb. Rails normally has no trouble finding and loading the file.
Do I need to manually require all of our libs, or is there a more Rails-like way to handle it that I'm missing?
The documentation of threadsafe! mentions that it disables automatic dependency loading. The reason is that there might be race conditions during the loading of files if two or more threads both decide they are still missing a certain class.
Instead, you should manually require all files you need in an initializer.
Change config.autoload_paths to config.eager_load_paths
(based on Rails issue #6850 and Force reload! from lib directory in rails 3.2 console, Adding lib to 'config.autoload_paths' in Rails 3 does not autoload my module)
The documentation link contains no info, thus here's some relevant doc for #threadsafe! :
Enable threaded mode. Allows
concurrent requests to controller
actions and multiple database
connections. Also disables automatic
dependency loading after boot, and
disables reloading code on every
request, as these are fundamentally
incompatible with thread safety.

When -exactly- does the Rails3 application get initialized?

I've been fighting left and right with rails 3 and bundler. There are a few gems out there that don't work properly if the rails application hasn't been loaded yet. factory_girl and shoulda are both examples, even on the rails3 branch.
Taking shoulda as an example, when trying to run rake test:units I get the following error:
DEPRECATION WARNING: RAILS_ROOT is deprecated! Use Rails.root instead. (called from autoload_macros at c:/code/test_harness/vendor/windows_gems/gems/shoulda-2.10.3/lib/shoulda/autoload_macros.rb:40)
c:/code/test_harness/vendor/windows_gems/gems/shoulda-2.10.3/lib/shoulda/autoload_macros.rb:44:in 'join': can't convert #<Class:0x232b7c0> into String (TypeError)
from c:/code/test_harness/vendor/windows_gems/gems/shoulda-2.10.3/lib/shoulda/autoload_macros.rb:44:in 'block in autoload_macros'
from c:/code/test_harness/vendor/windows_gems/gems/shoulda-2.10.3/lib/shoulda/autoload_macros.rb:44:in 'map'
from c:/code/test_harness/vendor/windows_gems/gems/shoulda-2.10.3/lib/shoulda/autoload_macros.rb:44:in 'autoload_macros'
from c:/code/test_harness/vendor/windows_gems/gems/shoulda-2.10.3/lib/shoulda/rails.rb:17:in '<top (required)>'
Digging a bit deeper into lib/shoulda/rails, I see this:
root = if defined?(Rails.root) && Rails.root
Rails.root
else
RAILS_ROOT
end
# load in the 3rd party macros from vendorized plugins and gems
Shoulda.autoload_macros root, File.join("vendor", "{plugins,gems}", "*")
So...what's happening here is while Rails.root is defined, Rails.root == nil, so RAILS_ROOT is used, and RAILS_ROOT==nil, which is then being passed on to Shoulda.autoload_macros. Obviously the rails app has yet to be initialized. With Rails3 using Bundler now, there's been some hubub over on the Bundler side about being able to specify an order in which the gems are required, but I'm not sure whether or not this would solve the problem at hand.
Ultimately my questions is this: When exactly does the environment.rb file (which actually initializes the application) get pulled in? Is there any harm to bumping up when the app is initialized and have it happen before the Bundler.require line in config/application.rb? I've tried to hack bundler to specify the order myself, and have the rails gem pulled in first, but it doesn't appear to me that requiring the rails gem actually initializes the application.
As this line (in config/application.rb) is being called before the app is initialized, any gem in the bundler Gemfile that requires rails to be initialized is going to tank.
# Auto-require default libraries and those for the current Rails environment.
Bundler.require :default, Rails.env
Well, it was actually fairly easy to trace this down. All the rails libraries are being pulled in in application.rb. The app itself is being initialized in environment.rb.

Resources