rspec-guard检测spec文件夹中的更改,但不检测lib文件夹中的更改

时间:2017-01-11 09:13:07

标签: guard

与标题一样,它检测spec文件夹中的更改,而不是lib文件夹中的更改。

Guardfile

guard :rspec, cmd: "bundle exec rspec" do
  require "guard/rspec/dsl"
  dsl = Guard::RSpec::Dsl.new(self)

  # Feel free to open issues for suggestions and improvements

  # RSpec files
  rspec = dsl.rspec
  watch(rspec.spec_helper) { rspec.spec_dir }
  watch(rspec.spec_support) { rspec.spec_dir }
  watch(rspec.spec_files)

  # Ruby files
  ruby = dsl.ruby
  files = ruby.lib_files
  save_path = '/data/sites/scripts/sw_scripts/ruby/files.txt'
  File.write(save_path, ruby.lib_files.inspect)
  dsl.watch_spec_files_for(ruby.lib_files)
end

的Gemfile

source 'https://rubygems.org'

gem 'nokogiri'
gem 'thor'
gem 'rmagick'

group :development do
  gem 'guard-rspec', require: false
  gem 'simplecov', :require => false
end

group :development, :test do
  gem 'pry-byebug'
  gem 'rspec', ">=3.0"
end

我做了什么:

  • 阅读了很多Guard文档 - 它已经过时了,Guardfile改变了它的语法(它包含一些正则表达式,而我的自动生成的Guardfile中没有正则表达式,链接到3年以上的教程等)
  • 将put语句放入Guardfile以查看ruby.lib_files
  • 是什么
  • 它没有用,所以我使用了File.write(path, ruby.lib_files.inspect)
  • 文件包含regexp

所以我进入irb并确认regexp是正确的,它匹配来自Dir['**/*']的所有lib文件

r = /^(lib\/.+)\.rb$/

`pwd`
=> "correct_dir\n"

files = Dir['**/*']
=> ** 149 files **

puts files.select { |f| r =~ f }
=> ** 36 files (snippet) **
lib/gallery_util/gallery_source.rb
lib/gallery_util/legacy_gallery_updater.rb
lib/gallery/specs/specs.rb
lib/gallery/specs/report.rb
lib/gallery/specs/universal_property.rb
lib/gallery/front_page_creator.rb
...

因此所有文件都被识别,但是当我为任何lib文件运行后,它根本不起作用。当我在调试模式下运行guard时,我得到了这个输出:

09:55:44 - DEBUG - Interactor was stopped or killed
09:55:44 - DEBUG - Hook :run_on_modifications_begin executed for Guard::RSpec
09:55:44 - DEBUG - Hook :run_on_modifications_end executed for Guard::RSpec
09:55:44 - DEBUG - Start interactor

只有想到的是,由于某种原因,警卫不会递归地查看lib文件夹。我怀疑这可能,为什么有人会这样做呢?

其他依赖于.git位置的东西。 .git是这个上面的2个文件夹(因为这是一个独立脚本的集合,可以收集,我希望它们在1个repo中,而不是5个+)

如何解决?如何强制守卫递归观看lib文件夹?

2 个答案:

答案 0 :(得分:0)

似乎guard需要spec文件夹结构来匹配lib文件夹结构。如果你有文件,它无法找出匹配的规范

lib/gallery/front_page.rb
spec/front_page_spec.rb

不,你必须像这样创建它:

lib/gallery/front_page.rb
spec/lib/gallery/front_page_spec.rb

我认为这也会有效(但还没试过)

lib/gallery/front_page.rb
spec/gallery/front_page_spec.rb

要保护维护者:如果在某处记录下来,肯定会很好。

答案 1 :(得分:0)

我是Guard的新手,过去两天都在了解为什么在修改和保存'something_test.rb'文件时RSpec无法启动。 深入研究代码,我在Inspectors :: BaseInspector

中找到了一个方法
    def _select_only_spec_files(paths)
       spec_files = _collect_files("*[_.]spec.rb")

强制将测试文件命名为'..._spec.rb'。根据Guard / Dsl的文件:

  

watch方法告诉Guard哪些插件应该响应更改的文件。

在我看来,'_spec.rb'的硬编码与watch给你的自由相矛盾。

此外,我不喜欢由guard init rspec生成的Guardfile中的代码。作者的意图当然是好的,它允许新手快速启动自动化RSpec测试。但是有人不了解幕后发生的事情,而且似乎是你的情况。

这是我的Guardfile,带有一个补丁,用于重新定义SimpleInspector#paths:

directories %w[ lib spec ]

guard :rspec, cmd: 'rspec' do
    require 'guard/rspec'
    require "guard/rspec/inspectors/simple_inspector.rb"
    module ::Guard
        class RSpec < Plugin
            module Inspectors
                class SimpleInspector < BaseInspector
                    def paths(paths)
                        # please don't clear modified files correctly detected
                        # by watch but whose name doesn't end with '_spec.rb'
                        paths # return input without modification
                    end
                end
            end
        end
    end

        # test files
    watch(/^spec\/.*_test\.rb$/)

        # source files
#    watch(%r|^lib/(?<path>.+)\.rb$|) { | m | "spec/#{m[:path]}_test.rb" }
#       *** same as ***        
    watch(/^lib\/(.+)\.rb$/) { | m | "spec/#{m[1]}_test.rb" }
end

这是一个临时解决方法,我希望,至少它允许我按照我想要的方式定义watch语句,这与我现有的测试文件相对应。

第一个watch检测到'..._test.rb'目录中已更改的RSpec spec文件。第二个watch检测lib目录或其子目录中的已更改源文件,并在块中转换其名称,以便RSpec将显示'spec/..._test.rb'文件。

这样你就可以摆脱任何约束,并掌握自己的正则表达式。如果测试的层次结构与其中一个源不匹配,您甚至可以操作块中的路径:为什么不

watch(/^abd\/def\/(.+)\.rb$/) { | m | "anywhere\/you\/like\/#{m[1]}_test.rb" }

我可以向您保证:我的Mac上的guard-2.14.1可以完全检测到lib文件夹层次结构内部的更改文件。

HTH

PS:我没有捆绑,但你可以在guard命令中用cmd: 'rspec'替换cmd: "bundle exec rspec"

某些控制台输出使您确信它有效(测试文件为空):

21:08:29 - DEBUG - Start interactor
21:08:29 - DEBUG - Command execution: stty -g 2>/dev/null
[1] guard(main)> _[Guard] in guard.rb #async_queue_add ch={:modified=>["lib/antlr4/ruby_static/listeners/please_check_me.rb"], :added=>[], :removed=>[]}
21:08:36 - DEBUG - Interactor was stopped or killed
21:08:36 - DEBUG - Command execution: stty  2>/dev/null
_[Guard] //1 in Runner#run_on_changes mod=["lib/antlr4/ruby_static/listeners/please_check_me.rb"] add=[] rem=[]
    ...
_[Guard] //3 in Runner#run_on_changes ... plugin Guard::RSpec yielded, types={[:run_on_modifications, :run_on_changes, :run_on_change]=>["lib/antlr4/ruby_static/listeners/please_check_me.rb"], [:run_on_additions, :run_on_changes, :run_on_change]=>[], ...
_[Guard] //3+ plugin=#<Guard::RSpec @name=rspec @group=#<Guard::Group @name=default @options={}> @watchers=[#<Guard::Watcher:0x0..., @pattern=#<Guard::Watcher::Pattern::Matcher:0x007fbdca22d780 @matcher=/^spec\/.*_test\.rb$/>>, ..., @pattern=#<Guard::Watcher::Pattern::Matcher:0x007fbdca22d528 @matcher=/^lib\/(.+)\.rb$/>>]
...
_[Guard] //5 in Runner#run_on_changes ... match_result=["spec/antlr4/ruby_static/listeners/please_check_me_test.rb"]
...
task=run_on_modifications
_[Guard] /+-+ in Runner#_supervise pl=Guard::RSpec, t=run_on_modifications, args=[["spec/antlr4/ruby_static/listeners/please_check_me_test.rb"]]
...
21:08:36 - DEBUG - Hook :run_on_modifications_begin executed for Guard::RSpec
_[Guard] §§§ in Plugin self.notify gp=Guard::RSpec, ev=run_on_modifications_begin, args=[["spec/antlr4/ruby_static/listeners/please_check_me_test.rb"]]
_[Guard] /+-+ in Runner#_supervise about to plugin.send task=run_on_modifications, args=[["spec/antlr4/ruby_static/listeners/please_check_me_test.rb"]]
_[RSpec] &&&& in RSpec#run_on_modifications paths=["spec/antlr4/ruby_static/listeners/please_check_me_test.rb"]
_[RSpec] &&&& in RSpec#run_on_modifications about to runner.run
_[RSpec] ))) in RSpec::Runner#run paths=["spec/antlr4/ruby_static/listeners/please_check_me_test.rb"] inspector=#<Guard::RSpec::Inspectors::SimpleInspector:0x007fbdca2351b0>
_[RSpec] ))) in RSpec::Runner#run after inspector ["spec/antlr4/ruby_static/listeners/please_check_me_test.rb"]
21:08:36 - INFO - Running: spec/antlr4/ruby_static/listeners/please_check_me_test.rb
_[RSpec] ))) in RSpec::Runner#_run
_[RSpec] ))) in RSpec::Runner#_run command=rspec
...
_[RSpec] ))) in RSpec::Runner#_really_run cmd=rspec -f documentation -r /Users/b/.rvm/gems/ruby-2.3.3@rspec2/gems/guard-rspec-4.7.3/lib/guard/rspec_formatter.rb ...  spec/antlr4/ruby_static/listeners/please_check_me_test.rb
...
21:08:36 - DEBUG - Command execution: ...                
Finished in 0.00042 seconds (files took 0.10208 seconds to load)
0 examples, 0 failures
...
21:08:36 - DEBUG - Guard::RSpec: RSpec command spec ... exited with: 0

...
21:08:36 - DEBUG - Start interactor
21:08:36 - DEBUG - Command execution: stty -g 2>/dev/null