Class: RSpecLetAnalyzer::Visitors::ParserVisitor
- Inherits:
-
Parser::AST::Processor
- Object
- Parser::AST::Processor
- RSpecLetAnalyzer::Visitors::ParserVisitor
- Defined in:
- lib/rspec_let_analyzer/visitors/parser_visitor.rb
Overview
Visitor for the parser gem (uses AST::Processor)
Instance Attribute Summary collapse
-
#before_creates ⇒ Object
readonly
Returns the value of attribute before_creates.
-
#factory_usage ⇒ Object
readonly
Returns the value of attribute factory_usage.
-
#nesting_counts ⇒ Object
readonly
Returns the value of attribute nesting_counts.
-
#redefinitions ⇒ Object
readonly
Returns the value of attribute redefinitions.
-
#root_lets ⇒ Object
readonly
Returns the value of attribute root_lets.
-
#total_its ⇒ Object
readonly
Returns the value of attribute total_its.
Instance Method Summary collapse
- #handler_missing(node) ⇒ Object
-
#initialize(max_nesting_depth, track_factories) ⇒ ParserVisitor
constructor
A new instance of ParserVisitor.
-
#on_block(node) ⇒ Object
For block nodes, we need to handle them specially Blocks in parser gem represent describe/context/let blocks.
- #on_send(node) ⇒ Object
Constructor Details
#initialize(max_nesting_depth, track_factories) ⇒ ParserVisitor
Returns a new instance of ParserVisitor.
16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
# File 'lib/rspec_let_analyzer/visitors/parser_visitor.rb', line 16 def initialize(max_nesting_depth, track_factories) super() @root_lets = 0 @total_its = 0 @redefinitions = 0 @depth = 0 @let_names_by_depth = {} @max_nesting_depth = max_nesting_depth @nesting_counts = Array.new(max_nesting_depth, 0) if max_nesting_depth @track_factories = track_factories @factory_usage = Hash.new(0) if track_factories @before_creates = 0 @in_before_block = false end |
Instance Attribute Details
#before_creates ⇒ Object (readonly)
Returns the value of attribute before_creates.
14 15 16 |
# File 'lib/rspec_let_analyzer/visitors/parser_visitor.rb', line 14 def before_creates @before_creates end |
#factory_usage ⇒ Object (readonly)
Returns the value of attribute factory_usage.
14 15 16 |
# File 'lib/rspec_let_analyzer/visitors/parser_visitor.rb', line 14 def factory_usage @factory_usage end |
#nesting_counts ⇒ Object (readonly)
Returns the value of attribute nesting_counts.
14 15 16 |
# File 'lib/rspec_let_analyzer/visitors/parser_visitor.rb', line 14 def nesting_counts @nesting_counts end |
#redefinitions ⇒ Object (readonly)
Returns the value of attribute redefinitions.
14 15 16 |
# File 'lib/rspec_let_analyzer/visitors/parser_visitor.rb', line 14 def redefinitions @redefinitions end |
#root_lets ⇒ Object (readonly)
Returns the value of attribute root_lets.
14 15 16 |
# File 'lib/rspec_let_analyzer/visitors/parser_visitor.rb', line 14 def root_lets @root_lets end |
#total_its ⇒ Object (readonly)
Returns the value of attribute total_its.
14 15 16 |
# File 'lib/rspec_let_analyzer/visitors/parser_visitor.rb', line 14 def total_its @total_its end |
Instance Method Details
#handler_missing(node) ⇒ Object
129 130 131 |
# File 'lib/rspec_let_analyzer/visitors/parser_visitor.rb', line 129 def handler_missing(node) node.children.each { |child| process(child) if child.is_a?(::Parser::AST::Node) } end |
#on_block(node) ⇒ Object
For block nodes, we need to handle them specially Blocks in parser gem represent describe/context/let blocks
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
# File 'lib/rspec_let_analyzer/visitors/parser_visitor.rb', line 53 def on_block(node) send_node = node.children[0] return unless send_node.is_a?(::Parser::AST::Node) return unless send_node.type == :send method_name = send_node.children[1] case method_name when :describe, :context, :shared_examples, :shared_context @depth += 1 # Process args send_node.children.each { |child| process(child) if child.is_a?(::Parser::AST::Node) } # Process block body body = node.children[2] process(body) if body.is_a?(::Parser::AST::Node) @depth -= 1 @let_names_by_depth.delete(@depth + 1) when :before # Check if this is before or before(:each) arg = send_node.children[2] is_before_each = arg.nil? || (arg.type == :sym && arg.children[0] == :each) if is_before_each @in_before_block = true # Process args send_node.children.each { |child| process(child) if child.is_a?(::Parser::AST::Node) } # Process block body body = node.children[2] process(body) if body.is_a?(::Parser::AST::Node) @in_before_block = false else # Process args send_node.children.each { |child| process(child) if child.is_a?(::Parser::AST::Node) } # Process block body body = node.children[2] process(body) if body.is_a?(::Parser::AST::Node) end when :it, :specify @total_its += 1 # Process args send_node.children.each { |child| process(child) if child.is_a?(::Parser::AST::Node) } # Process block body body = node.children[2] process(body) if body.is_a?(::Parser::AST::Node) when :let, :let! let_name = extract_let_name_from_block(node) if let_name @redefinitions += 1 if redefinition?(let_name) @let_names_by_depth[@depth] ||= [] @let_names_by_depth[@depth] << let_name end if @depth == 1 @root_lets += 1 elsif @max_nesting_depth nesting_index = @depth - 2 if nesting_index < @max_nesting_depth - 1 @nesting_counts[nesting_index] += 1 else @nesting_counts[@max_nesting_depth - 1] += 1 end end # Process args and body send_node.children.each { |child| process(child) if child.is_a?(::Parser::AST::Node) } body = node.children[2] process(body) if body.is_a?(::Parser::AST::Node) else # Process all children send_node.children.each { |child| process(child) if child.is_a?(::Parser::AST::Node) } body = node.children[2] process(body) if body.is_a?(::Parser::AST::Node) end end |
#on_send(node) ⇒ Object
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
# File 'lib/rspec_let_analyzer/visitors/parser_visitor.rb', line 31 def on_send(node) method_name = node.children[1] case method_name when :create, :build, :build_stubbed # Track if create is inside a before block if @in_before_block && method_name == :create @before_creates += 1 end if @track_factories factory_name = extract_factory_name(node) @factory_usage[factory_name] += 1 if factory_name end node.children.each { |child| process(child) if child.is_a?(::Parser::AST::Node) } else node.children.each { |child| process(child) if child.is_a?(::Parser::AST::Node) } end end |