RuboCop 実装者向けの小ネタ。
例えば Ruby 2.2 以上のみをターゲットとする Cop を作る場合のプロダクションコードの方は、以下のように TargetRubyVersion
を extend
して minimum_target_ruby_version
で Ruby のバージョンを指定する。
class UnneededRequireStatement < Cop extend TargetRubyVersion minimum_target_ruby_version 2.2
テストコードの方は、以下のようになる。結果だけ見ると context
の引数で Ruby の実行バージョンを指定するという見たままのものだと思うけれど、ジェネレーションで生成したコードをベースのままにすると上手く行かないので、そのあたりを最後に記す。
describe RuboCop::Cop::Lint::UnneededRequireStatement, :config do subject(:cop) { described_class.new(config) } context 'target ruby version < 2.2', :ruby21 do ... end context 'target ruby version >= 2.2', :ruby22 do ... end
RuboCop 0.52.0 現在のrake new_cop
でジェネレーションしたテストコードは以下のようになっている。
describe RuboCop::Cop::Lint::UnneededRequireStatement do subject(:cop) { described_class.new(config) } let(:config) { RuboCop::Config.new }
複数の Ruby バージョンに対しての振る舞いを確認するテストを書く時はlet(:config) { RuboCop::Config.new }
を消して describe
の引数に :config
を付けると良い。
-describe RuboCop::Cop::Lint::UnneededRequireStatement do +describe RuboCop::Cop::Lint::UnneededRequireStatement, :config do subject(:cop) { described_class.new(config) } - let(:config) { RuboCop::Config.new }
このあたりを忘れるとバージョンごとの期待した結果を得ることができなくて、そのあたりも今年の RubyKaigi のときに pocke さんに相談していたりした内容だったりした。
そのとき相談していたベースは以下の PR で、このエントリの元にもなっている。