コンテンツにスキップ

rigor-rspec

describe / contextスコープ内でのRSpecのlet / subject宣言を検証します。これは意図的に小さく作られています。同梱される2つのチェックは、提案されているRSpecサーフェス(surface)の中で偽陽性リスクが最も低く、純粋な構文ウォークモードで動作し、rspec / rubocop-rspecが必ずしも明確に表面化しない実際のバグを捕捉します。RSpecのランタイム依存はありません。

これはrigortypeにバンドルされて配布されます。plugins:の下で有効化してください。

plugins:
- rigor-rspec
RSpec.describe "User" do
let(:user) { :alice }
let(:user) { :bob } # ← warning: duplicate `let(:user)`
let(:tags) { tags.map(&:up) } # ← error: self-referencing let
context "when admin" do
let(:user) { :admin } # ← OK: different scope
end
end
spec/user_spec.rb:5:3: warning: duplicate `let(:user)` in this scope (first declared at line 4); the last declaration wins at runtime
spec/user_spec.rb:7:3: error: `let(:tags)` references its own name `tags` — this will infinite-loop at runtime
  1. 同一スコープ内でのlet / subject宣言の重複 ── warning。RSpecのランタイムは最後の宣言を優先するため、最初の宣言は黙ってシャドウされます。メッセージは最初の宣言の行を示します。
  2. 自己参照するlet / subject ── 宣言した名前を自身のブロック本体の内側から呼び出すこと ── error。ランタイムでは無限ループになります。

ウォーカーはRSpec.describe … do(ルート)、ネストされたdescribe / context … dolet(:name) / let!(:name)、そしてsubject(:name) / 素のsubject(暗黙の:subject)を認識します。

設定ノブはありません。プラグインはプロジェクトのpaths:上のすべてのファイルをRSpec.describe … doブロックを探して走査します。認識されるdescribeブロックを持たないファイルは黙ってスキップされるため、spec以外のファイルと並べてプロジェクト全体で有効化しても安全です。

  • it本体内でのletタイポ検出はなしitブロック内のスペルミスしたlet名をフラグするには、はるかに重いウォーカー(マッチャーDSL、ヘルパーメソッド、letスコープチェーン)が必要 ── 待機中です。
  • モックターゲット検証はなしxのメソッドに対するexpect(x).to receive(:nme)は別のスライス(slice)です。
  • 共有コンテキストの解決はなしinclude_contextshared_contextit_behaves_likeは無視されます。
  • 自己参照検出はブロック内のみ。間接的なループ(let(:user) { foo }foouserを呼び戻す場合)はフラグされません。
  • 定数検証(RSpec.describe SomeClass)はこのプラグインではなくエンジンの仕事です。

rspec-railsshoulda-matchersのマッチャーはほとんどが振る舞い的(静的な型ではなくランタイムの状態をアサートする)なので、ここでは対象外です。待機中のrigor-rspec-railsrigor-shoulda-matchersプラグインが、それらに対するドメイン固有のdiagnosticを発行することになります。READMEがその境界を詳しく扱っています。

スコープウォーカー / アナライザーのレイアウト、デモの実行方法、このプラグインが行使する契約(contract)サーフェス、今後の方向性のスライスはプラグインのREADMEにあります。プラグインの書き方はexamples/rigor-plugin-authorスキルを参照してください。

© 2026 TypedDuck. Licensed under CC BY-SA 4.0.