rspec / rspec-rails

RSpec for Rails 6+
https://rspec.info
MIT License
5.15k stars 1.03k forks source link

Allow for customizing Rake tasks. #1428

Open mtuchowski opened 9 years ago

mtuchowski commented 9 years ago

RSpec-Core has a RakeTask class we can use to generate Rake tasks and customize them while we at it. RSpec-Rails uses this feature to do just that in rspec.rake and adds tasks for each directory that lives under spec/ dir. While this is great, we loose the ability to customize the tasks, things like name of task or namespace it's defined in are hardcoded in the .rake file.

It would be great if there would be a class that does the same thing as RSpec::Code::RakeTask with the addition of things generated at .rake file. The .rake file would use the class to provide defaults.

This would enable one to wipe the spec task and all derived ones (spec:models, spec:controllers, etc.) from Rake and define them under, say what:ever namespace ;)

Personally, the thing I'm after here is the ability to customize the path to .rspec file without the need to copy-paste said rspec.rake file for its features.

cupakromer commented 9 years ago

I like this idea. :heart: thanks for suggesting it. Aside from adding a new namespace option were there other settings you would think this would need? Looking at the rspec-rails rake file it does not look like there is much.

One concern I have is the knowing which sub-directory to look at to create the dynamic tasks. Additionally, the default settings for each of the sub directory tasks. I guess the block can server as defaults and those things, such as pattern would need to be overwritten. Or are you suggesting that if someone customizes it, then those tasks are dropped?

mtuchowski commented 9 years ago

For starters it would be good to be able to set the same options as the ones from original RSpec::Core::RakeTask. I would imagine it as simple as:

require 'rspec/rails/rake_task'

Rake::Task["spec"].clear

namespace :whatever do
  RSpec::Rails::RakeTask.new('funky_specs_name') do |t|
    t.rspec_opts = '--options config/rspec'
    t.rspec_path = 'tests/spec'
    t.verbose = false
  end
end

I believe the default rspec.rake file should stay in RSpec Rails. The defaults it provides are great for most people. That is why there is that line clearing the spec task.

Also, with the code I proposed, the RSpec::Rails::RakeTask.new call could use rspec_path option that is already understood by RSpec::Core::RakeTask.

mtuchowski commented 9 years ago

The existing rspec.rake file could, in turn look like this:

require_relative '../rake_task'
if default = Rake.application.instance_variable_get('@tasks')['default']
  default.prerequisites.delete('test')
end

task :default => :spec

task :stats => "spec:statsetup"

desc "Run all specs in spec directory (excluding plugin specs)"
RSpec::Rails::RakeTask.new(:spec)

Test types setup can use the passed options from block.

cupakromer commented 9 years ago

I'm not sure I see how the types can be derived from the rspec_path; that is meant to be the path of the RSpec executable. It's not the base director that your specs are defined in. RSpec finds the specs based on the pattern set which can cover multiple directories.

mtuchowski commented 9 years ago

Sorry, my mistake, I totally misread the docs and thought it's the path to the specs. I was quite late yesterday ;)

Anyway, the only thing I can think of is to get the root directory parts from pattern. After root parts are known, they could be inserted in here. That would not be trivial and maybe not even possible for some patterns.

Or, more simpler, the RSpec::Rails::RakeTask class could introduce new options, named let's say rails_specs_dir and rails_specs_pattern, that would be /spec and *_spec.rb parts of dir matching pattern.

dmolesUC commented 7 years ago

I'd settle for being able to set verbose = false.