There wasn't much information how to do this online but in my Guardfile I am setting up the watch
for the various directories/files that I want Guard to be watching for changes on. How do you specify a watch for changed spec/test
files that have been updated and only run that specific file when that happens? Thanks!
guard 'rspec' do
watch(%r|^spec/.+_spec\.rb$|) { "spec" }
end
Currently the above runs all of the spec/tests when a file is changed under the spec
directory. But I only want that changed test file's tests to be run.
Current spec
directory tree:
spec
-models
-user_spec.rb
-classroom_spec.rb
-controllers
-classroom_spec.rb
-lib
-support_spec.rb
Thanks!
The Guard RSpec plugin has a demo Guardfile that you can create with
$ bundle exec guard init rspec
and the content is as follows:
# A sample Guardfile
# More info at https://github.com/guard/guard#readme
guard 'rspec' do
watch(%r{^spec/.+_spec\.rb$})
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
watch('spec/spec_helper.rb') { "spec" }
# Rails example
watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
watch(%r{^app/(.*)(\.erb|\.haml)$}) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" }
watch(%r{^app/controllers/(.+)_(controller)\.rb$}) { |m| ["spec/routing/#{m[1]}_routing_spec.rb", "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb", "spec/acceptance/#{m[1]}_spec.rb"] }
watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
watch('config/routes.rb') { "spec/routing" }
watch('app/controllers/application_controller.rb') { "spec/controllers" }
# Capybara features specs
watch(%r{^app/views/(.+)/.*\.(erb|haml)$}) { |m| "spec/features/#{m[1]}_spec.rb" }
# Turnip features and steps
watch(%r{^spec/acceptance/(.+)\.feature$})
watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) { |m| Dir[File.join("**/#{m[1]}.feature")][0] || 'spec/acceptance' }
end
I recommend to stick with this, because it contains many best practices for file/folder naming and triggering associated specs.
To answer your question, if you omit the block of the watch expression, Guard uses the exact file that had a change:
guard 'rspec' do
watch(%r|^spec/.+_spec\.rb$|)
end
That would trigger the RSpec plugin for each modified file in the spec folder that ends with _spec.rb
.
The block to the watch expression is there to transform the filename to something else and the parameter to the black is the match of the regexp, so you can add some special logic to it. Short example demonstrating this:
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
A file change in lib/file.rb
will trigger the plugin and the block converts that file name to spec/lib/file_spec.rb
, because m[1]
contains the match group from the RegExp, which is file
.