RSpec infrastructure
RSpec, Guard, FactoryBot, Shoulda, VCR, Webmock - standard rspec environment
Used 158 times
d
dpaluy
Usage
This template installs:
It creates
spec/support
folder and includes those files while loading RSpecIt also adds the following:
ActiveSupport::Testing::TimeHelpers
.rspec
Add HOSTS to be ignored: `c.ignore_hosts 'codeclimate.com', 'example.com'`
If you want to disable saving cassettes, add the following
vcr: { record: :skip }
For example:
context 'amazing spec', vcr: { record: :skip } do ... end
Run this command in your Rails app directory in the terminal:
rails app:template LOCATION="https://railsbytes.com/script/X8Bsyo"
Template Source
Review the code before running this template on your machine.
gem_group :development, :test do
gem "factory_bot_rails"
gem "rspec-rails"
end
gem_group :development do
gem 'guard-bundler'
gem 'guard-rspec'
gem 'terminal-notifier', require: false
gem 'terminal-notifier-guard', require: false
end
gem_group :test do
gem 'capybara'
gem 'shoulda-matchers'
gem 'vcr'
gem 'webmock', require: 'webmock/rspec'
end
run "bundle install"
rails_command "generate rspec:install"
File.open(Rails.root.join("spec/rails_helper.rb"), "r+") do |file|
lines = file.each_line.to_a
config_index = lines.find_index("RSpec.configure do |config|\n")
lines.insert(config_index, "\nDir[Rails.root.join('spec', 'support', '**', '*.rb')].sort.each { |f| require f }\n\n")
file.rewind
file.write(lines.join)
end
factory_bot_rb = %Q[require 'factory_bot_rails'
RSpec.configure do |config|
config.include FactoryBot::Syntax::Methods
end
FactoryBot.use_parent_strategy = true
]
shoulda_rb = %Q[require 'shoulda/matchers'
Shoulda::Matchers.configure do |config|
config.integrate do |with|
with.test_framework :rspec
with.library :rails
end
end
]
vcr_rb = <<~EOS
require 'vcr'
require 'webmock/rspec'
WebMock.disable_net_connect!(allow_localhost: true)
VCR.configure do |c|
c.cassette_library_dir = Rails.root.join('spec', 'cassettes')
c.ignore_localhost = true
c.hook_into :webmock
c.configure_rspec_metadata!
c.allow_http_connections_when_no_cassette = true
c.ignore_hosts 'codeclimate.com'
c.before_record do |interaction|
interaction.request.headers['Authorization'] = '[FILTERED]'
end
end
RSpec.configure do |config|
# Add VCR to all tests
config.around(:each) do |example|
options = example.metadata[:vcr] || {}
options[:allow_playback_repeats] = true
options[:match_requests_on] = %i[path]
if options[:record] == :skip
WebMock.allow_net_connect!
VCR.turned_off(ignore_cassettes: true, &example)
WebMock.disable_net_connect!(allow_localhost: false)
else
custom_name = example.metadata.dig(:vcr, :cassette_name)
generated_name = example.metadata[:full_description].split(/\\s+/, 2).join('/').underscore.tr('.', '/').gsub(/[^\\w\\/]+/, '_').gsub(/\\/$/, '')
name = custom_name || generated_name
VCR.use_cassette(name, options, &example)
end
end
end
EOS
time_helper_rb = %{RSpec.configure do |config|
config.include ActiveSupport::Testing::TimeHelpers
end
}
capybara_rb = %{require 'capybara/rspec'}
run "mkdir spec/support"
File.open(Rails.root.join("spec/support/time_helper.rb"), "w") do |file|
file.write(time_helper_rb)
end
File.open(Rails.root.join("spec/support/factory_bot.rb"), "w") do |file|
file.write(factory_bot_rb)
end
File.open(Rails.root.join("spec/support/shoulda.rb"), "w") do |file|
file.write(shoulda_rb)
end
File.open(Rails.root.join("spec/support/vcr.rb"), "w") do |file|
file.write(vcr_rb)
end
File.open(Rails.root.join("spec/support/capybara.rb"), "w") do |file|
file.write(capybara_rb)
end
dot_rspec = %{--require rails_helper
--color
--format documentation
--tag ~slow
}
File.open(Rails.root.join(".rspec"), "w") do |file|
file.write(dot_rspec)
end
run "bundle exec guard init"
run "bundle binstub guard"
run "rm -rf test" if yes?("Do you want to remove the /test directory?")
if yes?("Would you like to generate factories for your existing models?")
Dir.glob(Rails.root.join("app/models/*.rb")).each { |file| require file }
models = ApplicationRecord.send(:subclasses).map(&:name)
models.each do |model|
run("rails generate factory_bot:model #{model} #{model.constantize.columns.map { |column| "#{column.name}:#{column.type}" }.join(" ")}")
end
end
Comments
BB
Thanks for this!
There's an issue though, the `vcr.rb` file is outputting the regex incorrectly because of the escaping.
There's an issue though, the `vcr.rb` file is outputting the regex incorrectly because of the escaping.
# actual: example.metadata[:full_description].split(/ +/, 2).join('/').underscore.tr('.', '/').gsub(/[^w/]+/, '_').gsub(//$/, '')
# expected: example.metadata[:full_description].split(/\s+/, 2).join('/').underscore.tr('.', '/').gsub(/[^\w\/]+/, '_').gsub(/\/$/, '')
The template needs to escape the slashes:
# fix: example.metadata[:full_description].split(/\\s+/, 2).join('/').underscore.tr('.', '/').gsub(/[^\\w\\/]+/, '_').gsub(/\\/$/, '')
dpaluy
Fixed. Thanks!
I also updated the `VCR` skip option
I also updated the `VCR` skip option
dpaluy
Note: `options[:match_requests_on] = %i[path]` ignores HOST
dpaluy
Note: https://github.com/sds/mock_redis/issues/253
Should be removed:
```
config.before(:each) do
mock_redis = MockRedis.new
allow(RedisClient).to receive(:current).and_return(mock_redis)
end
```
Should be removed:
```
config.before(:each) do
mock_redis = MockRedis.new
allow(RedisClient).to receive(:current).and_return(mock_redis)
end
```