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| wrap_rwhitespace_and_comments_if_ruby25(w.loc_hash[:begin] || w.loc_hash[:expression]).end } empty_fallbacks.map!(&:begin) if loc_hash[:else] empty_fallbacks << wrap_rwhitespace_and_comments_if_ruby25(loc_hash[:else]).end 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 = wrap_rwhitespace_and_comments_if_ruby25(node.expression, 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 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 |
# 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 first_clause_fallback = wrap_rwhitespace_and_comments_if_ruby25(loc_hash[:begin]) if loc_hash[:begin] first_clause_fallback ||= wrap_rwhitespace_and_comments_if_ruby25(condition.expression) # Ruby26 wraps the comments but only on the same line # No need for condition since Ruby25 wraps all of them first_clause_fallback = first_clause_fallback.wrap_final_comment.end else_loc = loc_hash[:else] if else_loc second_clause_fallback = wrap_rwhitespace_and_comments_if_ruby25(else_loc).end elsif !modifier? second_clause_fallback = root_if_node.loc_hash[:end].begin end empty_fallback_locs = [first_clause_fallback, second_clause_fallback] 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) if modifier? branches_locs = branches_locs.map do |branch| if branch.is_a?(Node::Kwbegin) if branch.instructions.empty? wrap_rwhitespace_and_comments_if_ruby25(branch.loc_hash[:begin]).end elsif branch.instructions.first.is_a?(Node::Ensure) # Kernel.binding.pry end_pos = wrap_rwhitespace_and_comments_if_ruby25(branch.instructions.last.expression).end_pos wrap_rwhitespace_and_comments_if_ruby25(branch.loc_hash[:begin]).end.with(end_pos: end_pos) else end_pos = branch.instructions.last.expression.end_pos branch.loc_hash[:begin].wrap_rwhitespace_and_comments.end.with(end_pos: end_pos) end else branch end end end 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
156 157 158 159 160 161 162 |
# File 'lib/deep_cover/analyser/ruby25_like_branch.rb', line 156 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
164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 |
# File 'lib/deep_cover/analyser/ruby25_like_branch.rb', line 164 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 wrap_rwhitespace_and_comments_if_ruby25(body.loc_hash[:begin]).end end elsif body.is_a?(Node::Begin) && !body.expressions.empty? end_pos = body.expressions.last.expression.end_pos body.expressions.first.expression.with(end_pos: end_pos) elsif body.is_a?(Node::EmptyBody) wrap_rwhitespace_and_comments_if_ruby25(condition.loc_hash[:expression]).end else body end [base_info, {[:body, *node_loc_infos(body_node)] => body.execution_count}] end |