coverband 6.0.3.rc.3 → 6.0.3.rc.4

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7076b5973080adc6d9fc4ddeadf8baa92d19e04f0d8f2e1ef961ac3075737448
4
- data.tar.gz: aca8e906625af383fbae32139836e8c93113d89e9b17ca323708aed3b5b46ee7
3
+ metadata.gz: cf0b6bab823d8155a5e15d361c3acbbef271f84e79947b9818a650e640a61fc7
4
+ data.tar.gz: 25cd0843b3c1e852794bcc008be165bfcbf7e476f373ab681cbff7861f050904
5
5
  SHA512:
6
- metadata.gz: 302bf319119b5c1c3911da3591db34170717a53b9d9af32aee1f04b87171115daa6f97502c1e2d2d06180c7ba9c24ca675e5b09c6f19473bffb98838c5765f6f
7
- data.tar.gz: 0a65eb875a43605f1ef355b6bc268728763e8c6a64e1a5566388fbbd685714e8db6ef48e38849a4d1de5b5b34e984782512b9ffe9a37446b3549f82fa586701a
6
+ metadata.gz: d2ae2023667369ac1e7be83ec41898c6e77662545f6226c02417ef9a43e75a4e2950ad0d775e18c96d800270d81da104162d4414b13768ac98c14bcff431acd1
7
+ data.tar.gz: 64ddff4e59042a6ee22cd4839e6e7ac57dff4cf289b02a8f6801c144aafea7edd417ed918c38309b61173176cb177ce548dbf6302963d4b53464d8901cb05d30
data/coverband.gemspec CHANGED
@@ -34,12 +34,13 @@ Gem::Specification.new do |spec|
34
34
  spec.add_development_dependency "capybara"
35
35
  spec.add_development_dependency "m"
36
36
  spec.add_development_dependency "memory_profiler"
37
- # breaking change in minitest and mocha
37
+ # breaking change in minitest and mocha...
38
+ # note: we are also adding 'spy' as mocha doesn't want us to spy on redis calls...
39
+ # ^^^ probably need a large test cleanup refactor
38
40
  spec.add_development_dependency "minitest", "= 5.18.1"
39
41
  spec.add_development_dependency "minitest-fork_executor"
40
42
  spec.add_development_dependency "minitest-stub-const"
41
43
  spec.add_development_dependency "mocha", "~> 1.7.0"
42
- # spec.add_development_dependency "spy"
43
44
  spec.add_development_dependency "rack"
44
45
  spec.add_development_dependency "rack-test"
45
46
  spec.add_development_dependency "rake"
@@ -89,7 +89,7 @@ module Coverband
89
89
  # used to store data to redis. It is changed only when breaking changes to our
90
90
  # redis format are required.
91
91
  ###
92
- REDIS_STORAGE_FORMAT_VERSION = "coverband_hash_3_3"
92
+ REDIS_STORAGE_FORMAT_VERSION = "coverband_hash_4_0"
93
93
 
94
94
  JSON_PAYLOAD_EXPIRATION = 5 * 60
95
95
 
@@ -107,7 +107,7 @@ module Coverband
107
107
  @relative_file_converter = opts[:relative_file_converter] || Utils::RelativeFileConverter
108
108
 
109
109
  @get_coverage_cache = if opts[:get_coverage_cache]
110
- key_prefix = [REDIS_STORAGE_FORMAT_VERSION, @redis_namespace, "v2"].compact.join(".")
110
+ key_prefix = [REDIS_STORAGE_FORMAT_VERSION, @redis_namespace].compact.join(".")
111
111
  GetCoverageRedisCacheStore.new(redis, key_prefix)
112
112
  else
113
113
  GetCoverageNullCacheStore
@@ -172,19 +172,21 @@ module Coverband
172
172
  @redis.sadd(files_key, keys) if keys.any?
173
173
  end
174
174
 
175
- # TODO: refactor this and the method below and consider removing all the cached results stuff
175
+ # NOTE: This method should be used for full coverage or filename coverage look ups
176
+ # When paging code should use coverage_for_types and pull eager and runtime together as matched pairs
176
177
  def coverage(local_type = nil, opts = {})
177
178
  page_size = opts[:page_size] || 250
178
179
  cached_results = @get_coverage_cache.fetch(local_type || type) do |sleep_time|
179
180
  files_set = if opts[:page]
180
- files_set(local_type).each_slice(page_size).to_a[opts[:page] - 1] || {}
181
+ raise "call coverage_for_types with paging"
181
182
  elsif opts[:filename]
182
- # TODO: this probably needs to be an exact match of the parsed cache key section
183
- files_set(local_type).select{ |cache_key| cache_key.match(short_name(opts[:filename])) } || {}
183
+ type_key_prefix = key_prefix(local_type)
184
+ # NOTE: a better way to extract filename from key would be better
185
+ files_set(local_type).select { |cache_key| cache_key.sub(type_key_prefix, "").match(short_name(opts[:filename])) } || {}
184
186
  else
185
187
  files_set(local_type)
186
188
  end
187
- # use batches with a sleep in between to avoid overloading redis
189
+ # below uses batches with a sleep in between to avoid overloading redis
188
190
  files_set.each_slice(page_size).flat_map do |key_batch|
189
191
  sleep sleep_time
190
192
  @redis.pipelined do |pipeline|
@@ -200,33 +202,25 @@ module Coverband
200
202
  end
201
203
  end
202
204
 
203
- # TODO: fix this before shipping main line release
204
- # def split_coverage(types, coverage_cache, options = {})
205
- # if types.is_a?(Array)
206
- # coverage_for_types(types, options)
207
- # else
208
- # super
209
- # end
210
- # end
211
-
212
- # NOTE: when using paging we need to ensure we have the same set of files per page in runtime and eager
213
- # TODO: This merge of eager and runtime isn't working fix later...
205
+ def split_coverage(types, coverage_cache, options = {})
206
+ if types.is_a?(Array) && !options[:filename] && options[:page]
207
+ data = coverage_for_types(types, options)
208
+ coverage_cache[Coverband::RUNTIME_TYPE] = data[Coverband::RUNTIME_TYPE]
209
+ coverage_cache[Coverband::EAGER_TYPE] = data[Coverband::EAGER_TYPE]
210
+ data
211
+ else
212
+ super
213
+ end
214
+ end
215
+
214
216
  def coverage_for_types(types, opts = {})
215
217
  page_size = opts[:page_size] || 250
216
218
 
217
219
  local_type = Coverband::RUNTIME_TYPE
218
220
  hash_data = {}
219
221
 
220
- runtime_file_set = if opts[:page]
221
- files_set(local_type).each_slice(page_size).to_a[opts[:page] - 1] || {}
222
- elsif opts[:filename]
223
- # TODO: this probably needs to be an exact match of the parsed cache key section
224
- # match is a hack that will only kind of work
225
- files_set(local_type).select{ |cache_key| cache_key.match(short_name(opts[:filename])) } || {}
226
- else
227
- files_set(local_type)
228
- end
229
-
222
+ runtime_file_set = files_set(local_type).each_slice(page_size).to_a[opts[:page] - 1] || []
223
+
230
224
  hash_data[Coverband::RUNTIME_TYPE] = runtime_file_set.each_slice(page_size).flat_map do |key_batch|
231
225
  @redis.pipelined do |pipeline|
232
226
  key_batch.each do |key|
@@ -235,12 +229,14 @@ module Coverband
235
229
  end
236
230
  end
237
231
 
238
- # TODO: debug the set isn't just paths it has other key details including coverage type so below probalby fails
239
- # match is a hack that will work a sometimes... fix this but it will prove out if this solves the perf issue
232
+ eager_key_pre = key_prefix(Coverband::EAGER_TYPE)
233
+ runtime_key_pre = key_prefix(Coverband::RUNTIME_TYPE)
240
234
  matched_file_set = files_set(Coverband::EAGER_TYPE)
241
- .select { |eager_key, val| runtime_file_set.any?{ |runtime_key|
242
- (eager_key.match(/\.\.(.*).rb/) && eager_key.match(/\.\.(.*).rb/)[0]==runtime_key.match(/\.\.(.*).rb/)[0]) }
243
- } || {}
235
+ .select { |eager_key, val|
236
+ runtime_file_set.any? { |runtime_key|
237
+ (eager_key.sub(eager_key_pre, "") == runtime_key.sub(runtime_key_pre, ""))
238
+ }
239
+ } || []
244
240
  hash_data[Coverband::EAGER_TYPE] = matched_file_set.each_slice(page_size).flat_map do |key_batch|
245
241
  @redis.pipelined do |pipeline|
246
242
  key_batch.each do |key|
@@ -17,7 +17,7 @@ module Coverband
17
17
  :s3_secret_access_key, :password, :api_key, :service_url, :coverband_timeout, :service_dev_mode,
18
18
  :service_test_mode, :process_type, :track_views, :redis_url,
19
19
  :background_reporting_sleep_seconds, :reporting_wiggle,
20
- :send_deferred_eager_loading_data
20
+ :send_deferred_eager_loading_data, :paged_reporting
21
21
 
22
22
  attr_reader :track_gems, :ignore, :use_oneshot_lines_coverage
23
23
 
@@ -293,6 +293,10 @@ module Coverband
293
293
  @send_deferred_eager_loading_data
294
294
  end
295
295
 
296
+ def paged_reporting
297
+ !!@paged_reporting
298
+ end
299
+
296
300
  def service_disabled_dev_test_env?
297
301
  return false unless service?
298
302
 
@@ -30,6 +30,18 @@ module Coverband
30
30
 
31
31
  private
32
32
 
33
+ def coverage_css_class(covered_percent)
34
+ if covered_percent.nil?
35
+ ""
36
+ elsif covered_percent > 90
37
+ "green"
38
+ elsif covered_percent > 80
39
+ "yellow"
40
+ else
41
+ "red"
42
+ end
43
+ end
44
+
33
45
  def report_as_json
34
46
  result = Coverband::Utils::Results.new(filtered_report_files)
35
47
  source_files = result.source_files
@@ -42,16 +54,16 @@ module Coverband
42
54
  if as_report
43
55
  row_data = []
44
56
  data[:files].each_pair do |key, data|
45
- source_class = data[:never_loaded] ? 'strong red' : 'strong'
46
- data_loader_url="#{base_path}load_file_details?filename=#{data[:filename]}"
47
- # class=\"src_link cboxElement\
48
- link = "<a href=\"##{data[:hash]}\" class=\"cboxElement\" title=\"#{key}\" data-loader-url=\"#{data_loader_url}\" onclick=\"src_link_click(this)\">#{key}</a>"
49
- # Started GET "/config/coverage/load_file_details?filename=/home/danmayer/projects/coverband_rails_example/app/jobs/application_job.rb" for ::1 at 2024-03-05 16:02:33 -0700
50
- # class="<%= coverage_css_class(source_file.covered_percent) %> strong"
57
+ source_class = data[:never_loaded] ? "strong red" : "strong"
58
+ data_loader_url = "#{base_path}load_file_details?filename=#{data[:filename]}"
59
+ link = "<a href=\"##{data[:hash]}\" class=\"src_link #{source_class} cboxElement\" title=\"#{key}\" data-loader-url=\"#{data_loader_url}\" onclick=\"src_link_click(this)\">#{key}</a>"
60
+ # Hack to ensure the sorting works on percentage columns, the span is hidden but colors the cell and the text is used for sorting
61
+ covered_percent = "#{data[:covered_percent]} <span class=\"#{coverage_css_class(data[:covered_percent])}\">&nbsp;</span>"
62
+ runtime_percentage = "#{data[:runtime_percentage]}<span class=\"#{coverage_css_class(data[:runtime_percentage])}\">&nbsp;</span>"
51
63
  row_data << [
52
64
  link,
53
- data[:covered_percent].to_s,
54
- data[:runtime_percentage].to_s,
65
+ covered_percent,
66
+ runtime_percentage,
55
67
  data[:lines_of_code].to_s,
56
68
  (data[:lines_covered] + data[:lines_missed]).to_s,
57
69
  data[:lines_covered].to_s,
@@ -112,11 +112,16 @@ module Coverband
112
112
  def index
113
113
  notice = "<strong>Notice:</strong> #{Rack::Utils.escape_html(request.params["notice"])}<br/>"
114
114
  notice = request.params["notice"] ? notice : ""
115
- Coverband::Reporters::HTMLReport.new(Coverband.configuration.store,
115
+ page = (request.params["page"] || 1).to_i
116
+ options = {
116
117
  static: false,
117
118
  base_path: base_path,
118
119
  notice: notice,
119
- open_report: false).report
120
+ open_report: false
121
+ }
122
+ options[:page] = page if Coverband.configuration.paged_reporting
123
+ Coverband::Reporters::HTMLReport.new(Coverband.configuration.store,
124
+ options).report
120
125
  end
121
126
 
122
127
  def json
@@ -142,10 +147,12 @@ module Coverband
142
147
  def display_abstract_tracker(tracker)
143
148
  notice = "<strong>Notice:</strong> #{Rack::Utils.escape_html(request.params["notice"])}<br/>"
144
149
  notice = request.params["notice"] ? notice : ""
145
- Coverband::Utils::HTMLFormatter.new(nil,
150
+ options = {
146
151
  tracker: tracker,
147
152
  notice: notice,
148
- base_path: base_path).format_abstract_tracker!
153
+ base_path: base_path
154
+ }
155
+ Coverband::Utils::HTMLFormatter.new(nil, options).format_abstract_tracker!
149
156
  end
150
157
 
151
158
  def view_tracker_data
@@ -117,13 +117,6 @@ module Coverband
117
117
  puts "Encoding error file:#{source_file.filename} Coverband/ERB error #{e.message}."
118
118
  end
119
119
 
120
- # Returns the html to ajax load a given source_file
121
- def formatted_source_file_loader(result, source_file)
122
- template("source_file_loader").result(binding)
123
- rescue Encoding::CompatibilityError => e
124
- puts "Encoding error file:#{source_file.filename} Coverband/ERB error #{e.message}."
125
- end
126
-
127
120
  # Returns a table containing the given source files
128
121
  def formatted_file_list(title, result, source_files, options = {})
129
122
  title_id = title.gsub(/^[^a-zA-Z]+/, "").gsub(/[^a-zA-Z0-9\-\_]/, "")
@@ -175,7 +168,8 @@ module Coverband
175
168
  end
176
169
 
177
170
  def link_to_source_file(source_file)
178
- %(<a href="##{id source_file}" class="src_link" title="#{shortened_filename source_file}">#{shortened_filename source_file}</a>)
171
+ data_loader_url = "#{base_path}load_file_details?filename=#{source_file.filename}"
172
+ %(<a href="##{id source_file}" class="src_link" title="#{shortened_filename source_file}" data-loader-url="#{data_loader_url}" onclick="src_link_click(this)">#{shortened_filename source_file}</a>)
179
173
  end
180
174
  end
181
175
  end
@@ -44,6 +44,8 @@ module Coverband
44
44
  eager_file = get_eager_file(source_file)
45
45
  runtime_file = get_runtime_file(source_file)
46
46
 
47
+ return 0 unless runtime_file
48
+
47
49
  return runtime_file.covered_lines_count unless eager_file
48
50
 
49
51
  eager_file.relevant_lines - eager_file.covered_lines_count
@@ -5,5 +5,5 @@
5
5
  # use format "4.2.1.rc.1" ~> 4.2.1.rc to prerelease versions like v4.2.1.rc.2 and v4.2.1.rc.3
6
6
  ###
7
7
  module Coverband
8
- VERSION = "6.0.3.rc.3"
8
+ VERSION = "6.0.3.rc.4"
9
9
  end
data/lib/coverband.rb CHANGED
@@ -91,8 +91,8 @@ module Coverband
91
91
  coverage_instance.eager_loading!
92
92
  end
93
93
 
94
- def self.eager_loading_coverage(&block)
95
- coverage_instance.eager_loading(&block)
94
+ def self.eager_loading_coverage(...)
95
+ coverage_instance.eager_loading(...)
96
96
  end
97
97
 
98
98
  def self.runtime_coverage!
@@ -130,7 +130,6 @@ module Coverband
130
130
  ###
131
131
  def initialize
132
132
  require "coverband/reporters/web"
133
- require "coverband/reporters/web_pager"
134
133
  require "coverband/utils/html_formatter"
135
134
  require "coverband/utils/result"
136
135
  require "coverband/utils/file_list"
@@ -148,19 +147,4 @@ module Coverband
148
147
  end
149
148
  end
150
149
  end
151
-
152
- module Reporters
153
- class WebPager < Web
154
- def initialize
155
- require "coverband/reporters/web"
156
- require "coverband/reporters/web_pager"
157
- super
158
- end
159
-
160
- def self.call(env)
161
- @app ||= new
162
- @app.call(env)
163
- end
164
- end
165
- end
166
150
  end
@@ -687,9 +687,17 @@ a.src_link {
687
687
  background: url("./magnify.png") no-repeat left 50%;
688
688
  padding-left: 18px; }
689
689
 
690
+ a.src_link.strong {
691
+ font-weight: bold;
692
+ }
693
+
690
694
  .red a.src_link {
691
695
  color: #990000;
692
- }
696
+ }
697
+
698
+ a.src_link.red {
699
+ color: #990000;
700
+ }
693
701
 
694
702
  tr, td {
695
703
  margin: 0;
@@ -817,6 +825,21 @@ td {
817
825
  .red {
818
826
  color: #990000; }
819
827
 
828
+ span.red {
829
+ color: #990000; }
830
+
831
+ td:has(> span.red) {
832
+ color: #990000;
833
+ }
834
+
835
+ td:has(> span.yellow) {
836
+ color: #ddaa00;
837
+ }
838
+
839
+ td:has(> span.green) {
840
+ color: #009900;
841
+ }
842
+
820
843
  .yellow {
821
844
  color: #ddaa00; }
822
845
 
@@ -16,7 +16,7 @@ $(document).ready(function() {
16
16
  });
17
17
 
18
18
  // Configuration for fancy sortable tables for source file groups
19
- $(".file_list").dataTable({
19
+ var tableOptions = {
20
20
  aaSorting: [[1, "asc"]],
21
21
  bPaginate: false,
22
22
  bJQueryUI: true,
@@ -30,19 +30,25 @@ $(document).ready(function() {
30
30
  null,
31
31
  null,
32
32
  null
33
- ]
34
- });
33
+ ],
34
+ }
35
+
36
+ $(".file_list").dataTable(tableOptions);
35
37
 
36
- // TODO: add support for searching...
37
- // hmm should I just use manual paging? or load more...
38
+ // TODO: add support for searching on server side
38
39
  // best docs on our version of datatables 1.7 https://datatables.net/beta/1.7/examples/server_side/server_side.html
39
- // TODO: fix bug where we hardcoded /coverage we need to pull it from the path it is mounted on
40
40
  if ($(".file_list.unsorted").length == 1) {
41
+ $(".dataTables_empty").html("loading...");
41
42
  var current_rows = 0;
42
43
  var total_rows = 0;
43
44
  var page = 1;
45
+
46
+ // load and render page content before we start the loop
47
+ // perhaps move this into a datatable ready event
48
+ setTimeout(() => {
49
+ get_page(page);
50
+ }, 1250);
44
51
 
45
- // write a function to get a page of data and add it to the table
46
52
  function get_page(page) {
47
53
  $.ajax({
48
54
  url: `${$(".file_list").data("coverageurl")}/report_json?page=${page}`,
@@ -54,92 +60,52 @@ $(document).ready(function() {
54
60
  // so we don't get back 250 per page... to ensure we we need to account for filtered out and empty files
55
61
  // this 250 at the moment is synced to the 250 in the hash redis store
56
62
  current_rows += 250; //data["aaData"].length;
57
- console.log(current_rows);
58
- console.log(total_rows);
59
63
  $(".file_list.unsorted").dataTable().fnAddData(data["aaData"]);
60
64
  page += 1;
65
+ // allow rendering to complete before we click the anchor
66
+ setTimeout(() => {
67
+ if (window.auto_click_anchor && $(window.auto_click_anchor).length > 0) {
68
+ $(window.auto_click_anchor).click();
69
+ }
70
+ }, 50);
61
71
  // the page less than 100 is to stop infinite loop in case of folks never clearing out old coverage reports
62
72
  if (page < 100 && current_rows < total_rows) {
63
- get_page(page);
73
+ setTimeout(() => {
74
+ get_page(page);
75
+ }, 200);
64
76
  }
65
77
  }
66
78
  });
67
79
  }
68
- get_page(page);
69
80
  }
70
81
 
71
-
72
- // Syntax highlight all files up front - deactivated
73
- // $('.source_table pre code').each(function(i, e) {hljs.highlightBlock(e, ' ')});
74
82
  src_link_click = (trigger_element) => {
75
- // Get the source file element that corresponds to the clicked element
76
- var source_table = $(".shared_source_table");
77
83
  var loader_url = $(trigger_element).attr("data-loader-url");
84
+ auto_click_anchor = null;
78
85
  $(trigger_element).colorbox(jQuery.extend(colorbox_options, { href: loader_url}));
79
-
80
- // If not highlighted yet, do it!
81
- if (!source_table.hasClass("highlighted")) {
82
- source_table.find("pre code").each(function(i, e) {
83
- hljs.highlightBlock(e, " ");
84
- });
85
- source_table.addClass("highlighted");
86
- }
87
86
  };
88
- window.src_link_click = src_link_click;
89
87
 
90
- // Syntax highlight source files on first toggle of the file view popup
91
- $("a.src_link").click(src_link_click(this));
92
-
93
- var prev_anchor;
94
- var curr_anchor;
95
88
  var colorbox_options = {
96
- open: true,
97
89
  transition: "none",
98
- // inline: true,
99
90
  opacity: 1,
100
91
  width: "95%",
101
92
  height: "95%",
102
93
  onLoad: function() {
103
- // TODO: move source highlighting here
104
- prev_anchor = curr_anchor ? curr_anchor : jQuery.url.attr("anchor");
105
- curr_anchor = this.href.split("#")[1];
106
- window.location.hash = curr_anchor;
94
+ // If not highlighted yet, do it!
95
+ var source_table = $(".shared_source_table");
96
+ if (!source_table.hasClass("highlighted")) {
97
+ source_table.find("pre code").each(function(i, e) {
98
+ hljs.highlightBlock(e, " ");
99
+ });
100
+ source_table.addClass("highlighted");
101
+ }
102
+ window.location.hash = this.href.split("#")[1];
107
103
  },
108
104
  onCleanup: function() {
109
- if (prev_anchor && prev_anchor != curr_anchor) {
110
- $('a[href="#' + prev_anchor + '"]').click();
111
- curr_anchor = prev_anchor;
112
- } else {
113
- $(".group_tabs a:first").click();
114
- prev_anchor = curr_anchor;
115
- curr_anchor = $(".group_tabs a:first").attr("href");
116
- }
117
- window.location.hash = curr_anchor;
105
+ window.location.hash = $(".group_tabs a:first").attr("href");
118
106
  }
119
107
  }
120
108
 
121
- src_link_colorbox = (trigger_element) => {
122
- $(trigger_element).colorbox(colorbox_options);
123
- };
124
- window.src_link_colorbox = src_link_colorbox;
125
-
126
- // Set-up of popup for source file views
127
- // TODO: drop the static source view even for not paged coverband, then delete all this
128
- $("a.src_link").colorbox(colorbox_options);
129
-
130
- window.onpopstate = function(event) {
131
- if (location.hash.substring(0, 2) == "#_") {
132
- $.colorbox.close();
133
- curr_anchor = jQuery.url.attr("anchor");
134
- } else {
135
- if ($("#colorbox").is(":hidden")) {
136
- console.log("pop");
137
- // $('a.src_link[href="' + location.hash + '"]').colorbox({ open: true });
138
- $('.shared_source_table').colorbox({ open: true });
139
- }
140
- }
141
- };
142
-
143
109
  // Hide src files and file list container after load
144
110
  $(".source_files").hide();
145
111
  $(".file_list_container").hide();
@@ -157,15 +123,20 @@ $(document).ready(function() {
157
123
  .find(".covered_percent")
158
124
  .first()
159
125
  .html();
126
+ if (covered_percent) {
127
+ covered_percent = "(" + covered_percent + ")";
128
+ } else {
129
+ covered_percent = "";
130
+ }
160
131
 
161
132
  $(".group_tabs").append(
162
133
  '<li><a href="#' +
163
134
  container_id +
164
135
  '">' +
165
136
  group_name +
166
- " (" +
137
+ " " +
167
138
  covered_percent +
168
- ")</a></li>"
139
+ "</a></li>"
169
140
  );
170
141
  });
171
142
 
@@ -197,15 +168,26 @@ $(document).ready(function() {
197
168
  .addClass("active");
198
169
  }
199
170
  $(".file_list_container").hide();
200
- $(".file_list_container" + $(this).attr("href")).show();
201
- window.location.href =
202
- window.location.href.split("#")[0] +
203
- $(this)
204
- .attr("href")
205
- .replace("#", "#_");
206
-
171
+ $(".file_list_container" + $(this).attr("href")).show(function() {
172
+ // If we have an anchor to click, click it
173
+ // allow rendering to complete before we click the anchor
174
+ setTimeout(() => {
175
+ if (window.auto_click_anchor && $(window.auto_click_anchor).length > 0) {
176
+ $(window.auto_click_anchor).click();
177
+ }
178
+ }, 30);
179
+ });
180
+ // Below the #_ is a hack to show we have processed the hash change
181
+ if (!window.auto_click_anchor) {
182
+ window.location.href =
183
+ window.location.href.split("#")[0] +
184
+ $(this)
185
+ .attr("href")
186
+ .replace("#", "#_");
187
+ }
188
+
207
189
  // Force favicon reload - otherwise the location change containing anchor would drop the favicon...
208
- // Works only on firefox, but still... - Anyone know a better solution to force favicon on local file?
190
+ // Works only on firefox, but still... - Anyone know a better solution to force favicon on local relative file path?
209
191
  $('link[rel="shortcut icon"]').remove();
210
192
  $("head").append(
211
193
  '<link rel="shortcut icon" type="image/png" href="' +
@@ -215,18 +197,21 @@ $(document).ready(function() {
215
197
  return false;
216
198
  });
217
199
 
200
+ // The below function handles turning initial anchors in links to navigate to correct tab
218
201
  if (jQuery.url.attr("anchor")) {
219
202
  var anchor = jQuery.url.attr("anchor");
220
- // source file hash
221
203
  if (anchor.length == 40) {
222
- console.log("I need to fix deep links to source, the click call wont work anymore");
223
- // $("a.src_link[href=#" + anchor + "]").click();
204
+ // handles deep links to source files
205
+ window.auto_click_anchor = "a.src_link[href=#" + anchor + "]";
206
+ $(".group_tabs a:first").click();
224
207
  } else {
208
+ // handles a # anchor that needs to be processed into a #_ completed action
225
209
  if ($(".group_tabs a." + anchor.replace("_", "")).length > 0) {
226
210
  $(".group_tabs a." + anchor.replace("_", "")).click();
227
211
  }
228
212
  }
229
213
  } else {
214
+ // No anchor, so click the first navigation tab
230
215
  $(".group_tabs a:first").click();
231
216
  }
232
217
 
@@ -38,7 +38,7 @@ class ReportJSONTest < Minitest::Test
38
38
  json = Coverband::Reporters::JSONReport.new(@store).report
39
39
  parsed = JSON.parse(json)
40
40
 
41
- expected_keys = ["never_loaded", "runtime_percentage", "lines_of_code", "lines_covered", "lines_runtime", "lines_missed", "covered_percent", "covered_strength"]
41
+ expected_keys = ["filename", "hash", "never_loaded", "runtime_percentage", "lines_of_code", "lines_covered", "lines_runtime", "lines_missed", "covered_percent", "covered_strength"]
42
42
 
43
43
  assert_equal parsed["files"].length, 2
44
44
  parsed["files"].keys.each do |file|
@@ -7,12 +7,14 @@ describe "results" do
7
7
  let(:source_file) { Coverband::Utils::SourceFile.new(source_fixture("app/models/user.rb"), run_lines) }
8
8
  let(:eager_lines) { [nil, 1, 1, 0, nil, nil, 1, 0, nil, nil] }
9
9
  let(:run_lines) { [nil, nil, nil, 1, nil, nil, nil, nil, nil, nil] }
10
+ let(:missing_run_coverage_file) { false }
10
11
  let(:original_result) do
11
12
  orig = {
12
13
  Coverband::MERGED_TYPE => {source_fixture("app/models/user.rb") => eager_lines}
13
14
  }
14
15
  orig[Coverband::EAGER_TYPE] = {source_fixture("app/models/user.rb") => eager_lines} if eager_lines
15
16
  orig[Coverband::RUNTIME_TYPE] = {source_fixture("app/models/user.rb") => run_lines} if run_lines
17
+ orig[Coverband::RUNTIME_TYPE] = {"random.rb" => [nil, 1, nil]} if missing_run_coverage_file
16
18
  orig
17
19
  end
18
20
  subject { Coverband::Utils::Results.new(original_result) }
@@ -27,15 +29,28 @@ describe "results" do
27
29
  end
28
30
  end
29
31
 
30
- describe "runtime relevant lines when no runtime coverage exists" do
32
+ describe "runtime relevant lines when no runtime coverage file matches" do
31
33
  let(:run_lines) { nil }
32
34
 
35
+ it "has correct runtime relevant coverage" do
36
+ assert_equal 0, subject.runtime_relevant_coverage(source_file)
37
+ end
38
+
33
39
  it "has correct runtime relevant lines" do
40
+ assert_equal 0, subject.runtime_relavent_lines(source_file)
41
+ end
42
+ end
43
+
44
+ describe "runtime relevant lines when no runtime coverage exists" do
45
+ let(:run_lines) { nil }
46
+ let(:missing_run_coverage_file) { true }
47
+
48
+ it "has correct runtime relevant coverage" do
34
49
  assert_equal 0.0, subject.runtime_relevant_coverage(source_file)
35
50
  end
36
51
 
37
52
  it "has correct runtime relevant lines" do
38
- assert_equal 2, subject.runtime_relavent_lines(source_file)
53
+ assert_equal 0, subject.runtime_relavent_lines(source_file)
39
54
  end
40
55
  end
41
56
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: coverband
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.0.3.rc.3
4
+ version: 6.0.3.rc.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dan Mayer
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2024-03-13 00:00:00.000000000 Z
12
+ date: 2024-04-09 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: benchmark-ips
@@ -307,7 +307,6 @@ files:
307
307
  - lib/coverband/reporters/html_report.rb
308
308
  - lib/coverband/reporters/json_report.rb
309
309
  - lib/coverband/reporters/web.rb
310
- - lib/coverband/reporters/web_pager.rb
311
310
  - lib/coverband/utils/absolute_file_converter.rb
312
311
  - lib/coverband/utils/configuration_template.rb
313
312
  - lib/coverband/utils/dead_methods.rb
@@ -490,7 +489,6 @@ files:
490
489
  - views/nav.erb
491
490
  - views/settings.erb
492
491
  - views/source_file.erb
493
- - views/source_file_loader.erb
494
492
  homepage: https://github.com/danmayer/coverband
495
493
  licenses:
496
494
  - MIT
@@ -1,28 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "base64"
4
- require "coverband"
5
-
6
- begin
7
- require "rack"
8
- rescue LoadError
9
- puts "error loading Coverband web reporter as Rack is not available"
10
- end
11
-
12
- module Coverband
13
- module Reporters
14
- class WebPager < Web
15
- def index
16
- notice = "<strong>Notice:</strong> #{Rack::Utils.escape_html(request.params["notice"])}<br/>"
17
- notice = request.params["notice"] ? notice : ""
18
- # TODO: remove the call to the store render empty table
19
- Coverband::Reporters::HTMLReport.new(Coverband.configuration.store,
20
- page: (request.params["page"] || 1).to_i,
21
- static: false,
22
- base_path: base_path,
23
- notice: notice,
24
- open_report: false).report
25
- end
26
- end
27
- end
28
- end
@@ -1,7 +0,0 @@
1
- <div class="source_table" id="<%= id source_file %>" data-loader-url="<%= base_path %>load_file_details?filename=<%= source_file.filename %>">
2
- <div class='loader'>
3
- loading source data...
4
- <br/>
5
- <img src="<%= assets_path('loading.gif') %>" alt="loading"/>
6
- </div>
7
- </div>