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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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>