Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

undercover reports <100% method coverage even though it appears by eye to be 100% #167

Open
gc-tim opened this issue Feb 21, 2022 · 2 comments

Comments

@gc-tim
Copy link

gc-tim commented Feb 21, 2022

Undercover does not show any red in the output, other than the initial "loc" line, and there are no "hits: 0/" or "branches: 0/" lines. Every line that is not "hits: n/a" is green.

Output from undercover:

undercover: 👮‍♂️ some methods have no test coverage! Please add specs for methods listed below
🚨 1) node `fun` type: instance method,
      loc: foo/applications/bar/services/baz.rb:92:168, coverage: 94.12%
 92:     def fun( hits: n/a
 93:       arg_a:, hits: n/a
 94:       arg_b:, hits: n/a
 95:       arg_c:, hits: n/a
 96:       arg_d:, hits: n/a
 97:       arg_e:, hits: n/a
 98:       arg_f:, hits: n/a
 99:       arg_g:, hits: n/a
100:       arg_h:, hits: n/a
101:       arg_i:, hits: n/a
102:       arg_j:, hits: n/a
103:       arg_k:, hits: n/a
104:       arg_l: hits: n/a
105:     ) hits: n/a
106:       var_a = fun_a(arg_b, arg_h, arg_l) hits: 181
107:       var_b = arg_e || arg_c hits: 181
108:       var_c = arg_g || arg_d hits: 181
109:       var_d = { hits: n/a
110:         key_a: arg_b.key_a, hits: 181
111:         key_b: var_b, hits: n/a
112:         key_c: var_c, hits: n/a
113:       }.merge(arg_i) hits: n/a
114: 
115:       if arg_k == :sym_a && (var_b.nil? || var_c.nil?) hits: 181 branches: 2/2
116:         return Result.new(var_a.fun_b, true, var_d) hits: 2
117:       end hits: n/a
118: 
119:       var_e = ModuleA::ClassA.new( hits: 179
120:         arg_f, hits: n/a
121:         var_b, hits: n/a
122:         var_c, hits: n/a
123:         nil, hits: n/a
124:         arg_k, hits: n/a
125:       ) hits: n/a
126: 
127:       var_f = var_a.find_unit( hits: 179
128:         var_e, hits: n/a
129:         key_d: arg_a, hits: n/a
130:         key_e: false, hits: n/a
131:         key_f: arg_j, hits: n/a
132:       ) hits: n/a
133: 
134:       if var_f hits: 179 branches: 1/1
135:         Result.new(var_f, false, var_d) hits: 125
136:       else hits: n/a
137:         var_f = var_a.find_unit( hits: 54
138:           var_e, hits: n/a
139:           key_d: arg_a, hits: n/a
140:           key_e: true, hits: n/a
141:           key_f: arg_j, hits: n/a
142:         ) hits: n/a
143:         if var_f hits: 54 branches: 1/1
144:           Result.new(var_f, true, var_d) hits: 32
145:         else hits: n/a
146:           raise( hits: 22
147:             RuntimeError.new( hits: n/a
148:               { hits: n/a
149:                 reason: 'Something sensible', hits: n/a
150: 
151:                 arg_k: arg_k, hits: n/a
152:                 arg_i: arg_i, hits: n/a
153:                 arg_d: arg_d, hits: n/a
154:                 arg_g: arg_g, hits: n/a
155:                 arg_f: arg_f, hits: n/a
156:                 key_a: arg_b&.key_a, hits: n/a
157:                 arg_a: arg_a, hits: n/a
158:                 arg_e: arg_e, hits: n/a
159:                 arg_c: arg_c, hits: n/a
160:                 arg_l: arg_l, hits: n/a
161:                 arg_h: arg_h, hits: n/a
162:                 arg_j: arg_j, hits: n/a
163:               }, hits: n/a
164:             ), hits: n/a
165:           ) hits: n/a
166:         end hits: n/a
167:       end hits: n/a
168:     end hits: n/a
Undercover finished in 0.953s

Relevant lines from lcov file:

…
SF:./foo/applications/bar/services/baz.rb
…
DA:92,1
DA:106,181
DA:107,181
DA:108,181
DA:110,181
DA:115,181
DA:116,2
DA:119,179
DA:127,179
DA:134,179
DA:135,125
DA:137,54
DA:143,54
DA:144,32
DA:146,22
…
@gc-tim gc-tim changed the title undercover reports <100% method coverage even though it appears to be 100% undercover reports <100% method coverage even though it appears by eye to be 100% Feb 21, 2022
@grodowski
Copy link
Owner

Thank you for reporting this and sharing both the method snippet and related lcov. I suspect there could be an issue with how line coverage is interpreted in one or more of the multi-line statements...

Above bug could potentially live in Undercover::Result#uncovered? and Undercover::Result#coverage_f

@gc-tim
Copy link
Author

gc-tim commented Mar 15, 2022

That sounds very likely. A few days ago I encountered a similar issue where undercover was saying that coverage was below 100%, but its output showed all branches visited.

I eventually put a multi-line function call onto one line, and then it started to show branches: 3/4 on that line. One of the arguments was foo&.fun (with a safe navigation operator). It looks like that was the issue here as well, as I can now see key_a: arg_b&.key_a on line 156.

As for the specifics of how Undercover deals (or does not) with this case, I am afraid that I have no idea. 😂

Let me know if you need any more information.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants