2024-03-09

Neovim 上で factory_bot の呼び出し箇所から定義ファイルにジャンプする

Ruby、特に Rails アプリケーションのテストを書くときに、factory_bot をよく使います。

factory_bot を使うと

create(:user, :admin, name: 'Bob')

のように書くだけで User オブジェクトを作ることができますが、テスト書いているときにしばしばこの定義ファイルである spec/factories/users.rb を確認したくなります。

なぜ確認したくなるか

  • factory_bot には Traits という仕組みがあり、先の例で言うと :admin がそれにあたります。管理者ユーザを作っていることを想像できると思いますが、具体的にどういった属性が指定されているかは定義を見ないとわかりません
  • オブジェクトを作るとき、未指定の属性はデフォルト値が使われます。先の例では name: 'Bob' という属性のみ渡していますが、name 以外の属性が存在する場合、そのデフォルト値を確認するためには定義ファイルを確認しないとわかりません
  • テストを書くときに、その状況に適したデータを作りたくなります。マッチした Traits, transient, Hook の設定がすでにあれば流用したいですし、なければ新たに定義したくなるはずです。そのためにもやはり定義ファイルを開きたくなります

go-to-factory-bot.nvim というプラグインを作った

このような理由から、factory_bot の定義ファイルにジャンプする Neovim プラグイン go-to-factory-bot.nvim を作りました。

以下はデモ動画です。 go-to-factory-bot-nvim-demo

テストコード上の create(:user)create(:project, :with_namespace_settings) というコード行にカーソルを合わせ、:FactoryBotJump というコマンドを実行することで定義ファイルにジャンプできています。gitlabhq/gitlabhq のコードで試しています。

仕組み

仕組みとしては、コマンドが実行された行を対象に createbuild といった factory_bot のメソッド呼び出しが見つかったら、その引数をパースして定義ファイルを開くという単純なものです。

現状では特定のメソッドしかサポートできていません。例えば create_list では動かないです。現状自分があまり使わないのでサポートしませんでしたが、必要になるか気が向いたときにゆくゆく対応すると思います。

Rails で factory_bot を使う場合、基本的にモデル名を複数形にしたファイルを spec/factories に置くのが一般的かなと思いますが、場合によっては定義ファイルに suffix がついていたり、配置先のファイルパスが特殊な場合もあることを考慮し、プラグインの設定 である程度カスタマイズできるようにしています。

おわりに

1日に使えるエネルギー(MP的なもの)は有限であって、この MP は結構些細なことでも減っているように感じます。キーボードをタイプする操作やマウスを動かす操作でもわずかながら消耗しているような気がします。
ファイルを開くという単純操作ではありますが、頻繁に発生するアクションにおいてミスなく正確に簡略化できるのは意味があると思い、このプラグインを作るに至りました。

まだちょっと荒い作りにはなっていますが、徐々に改善していきたいと思います。