Class: RspecSprint::Fixers::LetItBe::Detector
- Inherits:
-
Object
- Object
- RspecSprint::Fixers::LetItBe::Detector
- Defined in:
- lib/rspec_sprint/fixers/let_it_be/detector.rb
Overview
spec ソースを AST で走査し、本体が「単一の create(:factory) 呼び出し」だけの‘let(:x) { … }` を候補として返す純粋関数。挙動を変える変換なので、安全性は後段(verify/revert, 本プラン対象外)に委ね、ここでは確定パターンだけ拾う。
Constant Summary collapse
- PATTERN =
block:
レシーバ無し let に sym 引数 1 つ($ で let 名を捕捉) 引数なしブロック (args) 本体は レシーバが無 or FactoryBot の create、第1引数は sym($ で factory 名を捕捉) ::RuboCop::AST::NodePattern.new(<<~PAT) (block (send nil? :let (sym $_)) (args) (send {nil? (const nil? :FactoryBot)} :create (sym $_) ...)) PAT
- LET_BANG_PATTERN =
同形だが ‘let!`。eager → once でセマンティクスが変わるため安全変換の対象外。「対象外だが隣接する let{create} がどれだけあるか」を提示するために数えるだけ。
::RuboCop::AST::NodePattern.new(<<~PAT) (block (send nil? :let! (sym $_)) (args) (send {nil? (const nil? :FactoryBot)} :create (sym $_) ...)) PAT
Class Method Summary collapse
-
.count_let_bang_create(source) ⇒ Object
安全変換できない let{single create} の件数(lazy/let! 比を示すため)。.
- .scan(source, file_path: nil) ⇒ Object
-
.scan_all(source, file_path: nil) ⇒ Object
let と let! の両方を候補として返す(apply モード用)。line 昇順。.
Class Method Details
.count_let_bang_create(source) ⇒ Object
安全変換できない let{single create} の件数(lazy/let! 比を示すため)。
66 67 68 |
# File 'lib/rspec_sprint/fixers/let_it_be/detector.rb', line 66 def self.count_let_bang_create(source) each_match(source, LET_BANG_PATTERN).size end |
.scan(source, file_path: nil) ⇒ Object
40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/rspec_sprint/fixers/let_it_be/detector.rb', line 40 def self.scan(source, file_path: nil) each_match(source, PATTERN).map do |let_name, factory_name, node| Candidate.new( let_name: let_name, factory_name: factory_name, line: node.loc.line, file_path: file_path, kind: :let ) end end |
.scan_all(source, file_path: nil) ⇒ Object
let と let! の両方を候補として返す(apply モード用)。line 昇順。
53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/rspec_sprint/fixers/let_it_be/detector.rb', line 53 def self.scan_all(source, file_path: nil) let_cands = each_match(source, PATTERN).map do |let_name, factory_name, node| Candidate.new(let_name: let_name, factory_name: factory_name, line: node.loc.line, file_path: file_path, kind: :let) end let_bang_cands = each_match(source, LET_BANG_PATTERN).map do |let_name, factory_name, node| Candidate.new(let_name: let_name, factory_name: factory_name, line: node.loc.line, file_path: file_path, kind: :let_bang) end (let_cands + let_bang_cands).sort_by(&:line) end |