📘 hkob-astro-notion-blog

これまではてなブログにて情報発信をしていましたが、令和5年3月22日より、こちらでの情報発信を始めました。2019年以前の古い記事は過去の Middleman 時代のものなので、情報が古いです。記録のためだけに残しています。

Guard の設定 - 不定期刊 Rails App を作る(7)

💡
この記事は Middleman 時代に書いた古いものです。記録のため、astro-notion-blog に移行していますが、あまり参考にしないでください。

前回は RSpec でのテストを作成した. しかし,spec や実装を記述するたびにテストを実行するのは面倒である. そこで,ファイル保存時に自動的にテストを実行してくれる guard を設定する.

Guard のインストール
  1. Gemfile の development グループの中に guard-rspec とを追加する
    group :development do
      gem 'guard-rspec', require: false
      (中略)
    end
  2. bundle する(2行目以降は結果: 更新分のみ).
    bundle
    Fetching lumberjack 1.0.13
    Fetching coderay 1.1.2
    Fetching formatador 0.2.5
    Installing formatador 0.2.5
    Installing lumberjack 1.0.13
    Installing coderay 1.1.2
    Fetching nenv 0.3.0
    Installing nenv 0.3.0
    Fetching shellany 0.0.1
    Installing shellany 0.0.1
    Fetching guard-compat 1.2.1
    Installing guard-compat 1.2.1
    Fetching notiffany 0.1.1
    Installing notiffany 0.1.1
    Fetching rspec 3.8.0
    Installing rspec 3.8.0
    Fetching pry 0.12.0
    Installing pry 0.12.0
    Fetching guard 2.14.2
    Installing guard 2.14.2
    Fetching guard-rspec 4.7.3
    Installing guard-rspec 4.7.3
  3. guard の初期化をすると,Guardfile が生成される.なお,bundle exec と毎回書くのは面倒なので,be というエイリアスを設定している.
    $ be guard init rspec
    11:19:26 - INFO - Writing new Guardfile to /Users/hkob/rails/attendance/Guardfile
    11:19:26 - INFO - rspec guard added to Guardfile, feel free to edit it
  4. Guardfile の最初にどのコマンドを呼ぶかが書いてある.今回の場合は,以下のように書いてある.
    guard :rspec, cmd: "bundle exec rspec" do
  5. せっかくなのでこの部分は spring で高速化された rspec を呼びたい.早速 binstub を作ろうと思ったが,rspec は知らないと言われてしまった.
    $ bin/spring binstub rspec
    The 'rspec' command is not known to spring.
  6. spring-commands-rspec が必要とのことなので,Gemfile に追加する.
    group :development do
      gem 'spring-commands-rspec'
      (中略)
    end
  7. 再度 bundle する(2行目以降は結果: 更新分のみ).
    Fetching spring-commands-rspec 1.0.4
    Installing spring-commands-rspec 1.0.4
  8. 再度 binstub を作成する.今度は成功した.
    $ bin/spring binstub rspec
    * bin/rspec: generated with spring
  9. 念のため,bin/rspec で spring 経由でコマンドが実行されていることを確認する.
    $ bin/rspec
    Running via Spring preloader in process 52269
    
    ApplicationHelper
      generate date strings
        wareki, ewareki wareki_num, wareki_ymd and md should have correct values
    
    Finished in 0.00842 seconds (files took 2.63 seconds to load)
    1 example, 0 failures
  10. Guardfile を開き,guard で実行するコマンドを以下のように変更する
    guard :rspec, cmd: "bin/rspec" do
Guard の実行
  1. 設定が終わったので,以下のようにして guard を実行する.deprecated の警告が出ているが,gem の内部の話なので無視する.
    $ be guard
    12:46:26 - INFO - Guard::RSpec is running
    12:46:26 - INFO - Guard is now watching at '/Users/hkob/rails/attendance'
    /Users/hkob/rails/attendance/vendor/bundle/ruby/2.5.0/gems/guard-2.14.2/lib/guard/jobs/pry_wrapper.rb:279: warning: method Pry#input_array is deprecated. Use Pry#input_ring instead
    [1] guard(main)>
  2. guard がちゃんとファイル更新を見張ってくれるかを確認するために,昨日の spec/helpers/application_helper_spec.rb にテストを追加してみる.昨日のものは,引数を3つ渡すメソッドだったので,Date オブジェクトを一つだけ渡すメソッドのテストを作ってみる.
    RSpec.describe ApplicationHelper, type: :helper do
      context 'generate date strings' do
        # (ここには前回の spec が書かれている.以下の it を追加)
    
        it 'wareki_by_date, ewareki_by_date wareki_num_by_date, wareki_ymd_by_date and md_by_date should have correct values' do
          subject.each do |ymd, jy, ey, y, jm, jd|
            date = Date.new(*ymd)
            expect(wareki_by_date(date)).to eq jy
            expect(ewareki_by_date(date)).to eq ey
            expect(wareki_num_by_date(date)).to eq y
            jymd = "#{jy}#{jm}#{jd}"
            expect(wareki_ymd_by_date(date)).to eq jymd
            expect(md_by_date(date)).to eq "#{jm}#{jd}"
          end
        end
      end
    end
  3. ファイルを保存した瞬間に guard を開いていたターミナルでテストが自動実行される.結果はこんな感じ.
    12:51:42 - INFO - Running: spec/helpers/application_helper_spec.rb
    Running via Spring preloader in process 52389
    
    ApplicationHelper
      generate date strings
        wareki, ewareki wareki_num, wareki_ymd and md should have correct values
        wareki_by_date, ewareki_by_date wareki_num_by_date, wareki_ymd_by_date and md_by_date should have correct values (FAILED - 1)
    
    Failures:
    
      1) ApplicationHelper generate date strings wareki_by_date, ewareki_by_date wareki_num_by_date, wareki_ymd_by_date and md_by_date should have correct values
        Failure/Error: expect(wareki_by_date(date)).to eq jy
    
        NoMethodError:
          undefined method `wareki_by_date' for #<RSpec::ExampleGroups::ApplicationHelper::GenerateDateStrings:0x00007fa225dd1020>
          Did you mean?  wareki_ymd
         # ./spec/helpers/application_helper_spec.rb:27:in `block (4 levels) in <main>'
         # ./spec/helpers/application_helper_spec.rb:25:in `each'
         # ./spec/helpers/application_helper_spec.rb:25:in `block (3 levels) in <main>'
         # -e:1:in `<main>'
    
    Finished in 0.02964 seconds (files took 2.94 seconds to load)
    2 examples, 1 failure
    
    Failed examples:
    
    rspec ./spec/helpers/application_helper_spec.rb:24 # ApplicationHelper generate date strings wareki_by_date, ewareki_by_date wareki_num_by_date, wareki_ymd_by_date and md_by_date should have correct values
    
    
    /Users/hkob/rails/attendance/vendor/bundle/ruby/2.5.0/gems/guard-2.14.2/lib/guard/jobs/pry_wrapper.rb:279: warning: method Pry#input_array is deprecated. Use Pry#input_ring instead
  4. この spec が通過するように app/helpers/application_helper.rb にメソッドを追加した.
    # @param [Date] d 日付
    # @return [String] 和暦年度文字列 (例: 平成21, 平成元, 昭和43).
    def wareki_by_date(d)
      wareki d.year, d.month, d.day
    end
    
    # @param [Date] d 日付
    # @return [String] 英文和暦記号年度文字列 (例: H21, H1, S43) .
    def ewareki_by_date(d)
      ewareki d.year, d.month, d.day
    end
    
    # @param [Date] d 日付
    # @return [Fixnum] 和暦年度 (21, 1, 43)
    def wareki_num_by_date(d)
      wareki_num d.year, d.month, d.day
    end
    
    # @param [Date] d 日付
    # @return [String] 和暦年度月日 (例: 平成21年12月7日, 平成元年1月7日, 昭和43年4月25日)
    def wareki_ymd_by_date(d)
      wareki_ymd d.year, d.month, d.day
    end
    
    # @param [Date] d 日付
    # @return [String] 月日 (例: 12月7日, 1月7日, 4月25日)
    def md_by_date(d)
      md d.month, d.day
    end
  5. 修正すると guard 画面は以下のように全て成功となる.
    13:03:42 - INFO - Running: spec/helpers/application_helper_spec.rb
    Running via Spring preloader in process 52597
    
    ApplicationHelper
      generate date strings
        wareki, ewareki wareki_num, wareki_ymd and md should have correct values
        wareki_by_date, ewareki_by_date wareki_num_by_date, wareki_ymd_by_date and md_by_date should have correct values
    
    Finished in 0.00708 seconds (files took 1.69 seconds to load)
    2 examples, 0 failures
    
    
    /Users/hkob/rails/attendance/vendor/bundle/ruby/2.5.0/gems/guard-2.14.2/lib/guard/jobs/pry_wrapper.rb:279: warning: method Pry#input_array is deprecated. Use Pry#input_ring instead

長くなったので今日はここまで