Class: DeepCover::Analyser::Ruby25LikeBranch::NodeCoverageExtrator
- Inherits:
-
SimpleDelegator
- Object
- SimpleDelegator
- DeepCover::Analyser::Ruby25LikeBranch::NodeCoverageExtrator
- Defined in:
- lib/deep_cover/analyser/ruby25_like_branch.rb
Overview
This is the class doing the work. Since everything is about the node, the class delegates missing methods to the node, simplifying the code.
Instance Method Summary collapse
- #branch_coverage(node) ⇒ Object
- #handle_case ⇒ Object
- #handle_csend ⇒ Object
- #handle_if ⇒ Object
- #handle_short_circuit ⇒ Object
- #handle_until_while ⇒ Object
-
#initialize(node = nil) ⇒ NodeCoverageExtrator
constructor
A new instance of NodeCoverageExtrator.
Constructor Details
#initialize(node = nil) ⇒ NodeCoverageExtrator
Returns a new instance of NodeCoverageExtrator.
30 31 32 33 |
# File 'lib/deep_cover/analyser/ruby25_like_branch.rb', line 30 def initialize(node = nil) self.node = node @loc_index = 0 end |
Instance Method Details
#branch_coverage(node) ⇒ Object
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
# File 'lib/deep_cover/analyser/ruby25_like_branch.rb', line 38 def branch_coverage(node) self.node = node case node when Node::Case handle_case when Node::Csend handle_csend when Node::If handle_if when Node::ShortCircuit handle_short_circuit when Node::Until, Node::While, Node::UntilPost, Node::WhilePost handle_until_while end end |
#handle_case ⇒ Object
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 |
# File 'lib/deep_cover/analyser/ruby25_like_branch.rb', line 54 def handle_case cond_info = [:case, *node_loc_infos] sub_keys = [:when] * (branches.size - 1) + [:else] empty_fallbacks = whens.map { |w| (w.loc_hash[:begin] || w.loc_hash[:expression]).wrap_rwhitespace_and_comments.end } empty_fallbacks.map!(&:begin) if loc_hash[:else] empty_fallbacks << loc_hash[:end].begin else # DeepCover manually inserts a `else` for Case when there isn't one for tracker purposes. # The normal behavior of ruby25's branch coverage when there is no else is to return the loc of the node # So we sent that fallback. empty_fallbacks << expression end branches_locs = whens.map do |when_node| next when_node.body if when_node.body.is_a?(Node::EmptyBody) start_at = when_node.loc_hash[:begin] start_at = start_at.wrap_rwhitespace_and_comments.end if start_at start_at ||= when_node.body.expression.begin end_at = when_node.body.expression.end start_at.with(end_pos: end_at.end_pos) end branches_locs << node.else clauses_infos = infos_for_branches(branches_locs, sub_keys, empty_fallbacks, execution_counts: branches.map(&:execution_count)) [cond_info, clauses_infos] end |
#handle_csend ⇒ Object
87 88 89 90 91 92 93 94 95 96 |
# File 'lib/deep_cover/analyser/ruby25_like_branch.rb', line 87 def handle_csend # csend wraps the comment but not the newlines node_range = node.expression.wrap_rwhitespace_and_comments(whitespaces: /\A[ \t\r\f]+/) cond_info = [:"&.", *node_loc_infos(node_range)] false_branch, true_branch = branches [cond_info, {[:then, *node_loc_infos(node_range)] => true_branch.execution_count, [:else, *node_loc_infos(node_range)] => false_branch.execution_count, }, ] end |
#handle_if ⇒ Object
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 128 129 130 131 132 133 134 135 136 137 138 |
# File 'lib/deep_cover/analyser/ruby25_like_branch.rb', line 98 def handle_if key = style == :unless ? :unless : :if node_range = extend_elsif_range cond_info = [key, *node_loc_infos(node_range)] sub_keys = [:then, :else] if style == :ternary empty_fallback_locs = [nil, nil] else else_loc = loc_hash[:else] first_clause_fallback = loc_hash[:begin] if first_clause_fallback first_clause_fallback = first_clause_fallback.wrap_rwhitespace_and_comments.end elsif else_loc first_clause_fallback = else_loc.begin end if else_loc second_clause_fallback = else_loc.wrap_rwhitespace_and_comments.end end end_loc = root_if_node.loc_hash[:end] end_loc = end_loc.begin if end_loc empty_fallback_locs = [first_clause_fallback || end_loc, second_clause_fallback || end_loc] end # loc can be nil if the clause can't be empty, such as ternary and modifer if/unless if key == :unless sub_keys.reverse! empty_fallback_locs.reverse! end branches_locs = branches execution_counts = branches_locs.map(&:execution_count) branches_locs[1] = extend_elsif_range(branches_locs[1]) clauses_infos = infos_for_branches(branches_locs, sub_keys, empty_fallback_locs, execution_counts: execution_counts, node_range: node_range) [cond_info, clauses_infos] end |
#handle_short_circuit ⇒ Object
140 141 142 143 144 145 146 |
# File 'lib/deep_cover/analyser/ruby25_like_branch.rb', line 140 def handle_short_circuit cond_info = [operator, *node_loc_infos] sub_keys = [:then, :else] sub_keys.reverse! if node.is_a?(Node::Or) [cond_info, infos_for_branches(branches, sub_keys, [nil, nil])] end |
#handle_until_while ⇒ Object
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 |
# File 'lib/deep_cover/analyser/ruby25_like_branch.rb', line 148 def handle_until_while key = loc_hash[:keyword].source.to_sym base_info = [key, *node_loc_infos] body_node = if node.is_a?(Node::WhilePost) || node.is_a?(Node::UntilPost) if !body.instructions.empty? end_pos = body.instructions.last.expression.end_pos body.instructions.first.expression.with(end_pos: end_pos) else body.loc_hash[:end].begin end elsif body.is_a?(Node::Begin) && !node.body.expressions.empty? end_pos = body.expressions.last.expression.end_pos body.expressions.first.expression.with(end_pos: end_pos) else body end [base_info, {[:body, *node_loc_infos(body_node)] => body.execution_count}] end |