Skip to content

Commit 6097c92

Browse files
authored
Merge pull request #530 from danmayer/add_last_touched
resolve #494 pull in the work that @FeLvi-zzz committed to support last accessed time
2 parents def88a7 + 55350e0 commit 6097c92

File tree

6 files changed

+51
-21
lines changed

6 files changed

+51
-21
lines changed

lib/coverband/adapters/hash_redis_store.rb

+11-2
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ def save_report(report)
167167

168168
arguments_key = [@redis_namespace, SecureRandom.uuid].compact.join(".")
169169
@redis.set(arguments_key, {ttl: @ttl, files_data: files_data}.to_json, ex: JSON_PAYLOAD_EXPIRATION)
170-
@redis.evalsha(hash_incr_script, [arguments_key])
170+
@redis.evalsha(hash_incr_script, [arguments_key], [report_time])
171171
end
172172
@redis.sadd(files_key, keys) if keys.any?
173173
end
@@ -289,9 +289,10 @@ def add_coverage_for_file(data_from_redis, hash)
289289
return unless file_hash(file) == data_from_redis[FILE_HASH]
290290

291291
data = coverage_data_from_redis(data_from_redis)
292+
timedata = coverage_time_data_from_redis(data_from_redis)
292293
hash[file] = data_from_redis.select do |meta_data_key, _value|
293294
META_DATA_KEYS.include?(meta_data_key)
294-
end.merge!("data" => data)
295+
end.merge!("data" => data, "timedata" => timedata)
295296
hash[file][LAST_UPDATED_KEY] =
296297
(hash[file][LAST_UPDATED_KEY].nil? || hash[file][LAST_UPDATED_KEY] == "") ? nil : hash[file][LAST_UPDATED_KEY].to_i
297298
hash[file].merge!(LAST_UPDATED_KEY => hash[file][LAST_UPDATED_KEY],
@@ -306,6 +307,14 @@ def coverage_data_from_redis(data_from_redis)
306307
end
307308
end
308309

310+
def coverage_time_data_from_redis(data_from_redis)
311+
max = data_from_redis[FILE_LENGTH_KEY].to_i - 1
312+
Array.new(max + 1) do |index|
313+
unixtime = data_from_redis["#{index}_last_posted"]
314+
unixtime.nil? ? nil : Time.at(unixtime.to_i)
315+
end
316+
end
317+
309318
def script_input(key:, file:, file_hash:, data:, report_time:, updated_time:)
310319
coverage_data = data.each_with_index.each_with_object({}) do |(coverage, index), hash|
311320
hash[index] = coverage if coverage

lib/coverband/utils/html_formatter.rb

+3-3
Original file line numberDiff line numberDiff line change
@@ -155,11 +155,11 @@ def id(source_file)
155155
Digest::SHA1.hexdigest(source_file.filename)
156156
end
157157

158-
def timeago(time)
159-
if time
158+
def timeago(time, err_msg = "Not Available")
159+
if time.respond_to?(:iso8601)
160160
"<abbr class=\"timeago\" title=\"#{time.iso8601}\">#{time.iso8601}</abbr>"
161161
else
162-
"Not Available"
162+
err_msg
163163
end
164164
end
165165

lib/coverband/utils/source_file.rb

+17-2
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,15 @@ class Line
2525
attr_reader :coverage
2626
# Whether this line was skipped
2727
attr_reader :skipped
28+
# The coverage data posted time for this line: either nil (never), nil (missed) or Time instance (last posted)
29+
attr_reader :coverage_posted
2830

2931
# Lets grab some fancy aliases, shall we?
3032
alias source src
3133
alias line line_number
3234
alias number line_number
3335

34-
def initialize(src, line_number, coverage)
36+
def initialize(src, line_number, coverage, coverage_posted = nil)
3537
raise ArgumentError, "Only String accepted for source" unless src.is_a?(String)
3638
raise ArgumentError, "Only Integer accepted for line_number" unless line_number.is_a?(Integer)
3739
raise ArgumentError, "Only Integer and nil accepted for coverage" unless coverage.is_a?(Integer) || coverage.nil?
@@ -40,6 +42,7 @@ def initialize(src, line_number, coverage)
4042
@line_number = line_number
4143
@coverage = coverage
4244
@skipped = false
45+
@coverage_posted = coverage_posted
4346
end
4447

4548
# Returns true if this is a line that should have been covered, but was not
@@ -82,6 +85,8 @@ def status
8285
attr_reader :filename
8386
# The array of coverage data received from the Coverage.result
8487
attr_reader :coverage
88+
# The array of coverage timedata received from the Coverage.result
89+
attr_reader :coverage_posted
8590

8691
# the date this version of the file first started to record coverage
8792
attr_reader :first_updated_at
@@ -96,6 +101,7 @@ def initialize(filename, file_data)
96101
@runtime_relavant_lines = nil
97102
if file_data.is_a?(Hash)
98103
@coverage = file_data["data"]
104+
@coverage_posted = file_data["timedata"] || [] # NOTE: only implement timedata for HashRedisStore
99105
@first_updated_at = @last_updated_at = NOT_AVAILABLE
100106
@first_updated_at = Time.at(file_data["first_updated_at"]) if file_data["first_updated_at"]
101107
@last_updated_at = Time.at(file_data["last_updated_at"]) if file_data["last_updated_at"]
@@ -139,7 +145,12 @@ def build_lines
139145
coverage_exceeding_source_warn if coverage.size > src.size
140146

141147
lines = src.map.with_index(1) { |src, i|
142-
Coverband::Utils::SourceFile::Line.new(src, i, never_loaded ? 0 : coverage[i - 1])
148+
Coverband::Utils::SourceFile::Line.new(
149+
src,
150+
i,
151+
never_loaded ? 0 : coverage[i - 1],
152+
(never_loaded || !coverage_posted.is_a?(Array)) ? nil : coverage_posted[i - 1]
153+
)
143154
}
144155

145156
process_skipped_lines(lines)
@@ -200,6 +211,10 @@ def line_coverage(index)
200211
lines[index]&.coverage
201212
end
202213

214+
def line_coverage_posted(index)
215+
lines[index]&.coverage_posted
216+
end
217+
203218
# Returns all lines that should have been, but were not covered
204219
# as instances of SimpleCov::SourceFile::Line
205220
def missed_lines

lua/lib/persist-coverage.lua

+3
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ for _, file_data in ipairs(files_data) do
2121
redis.call('HSETNX', hash_key, 'first_updated_at', first_updated_at)
2222
for line, coverage in pairs(file_data.coverage) do
2323
redis.call("HINCRBY", hash_key, line, coverage)
24+
if coverage > 0 then
25+
redis.call("HSET", hash_key, line .. "_last_posted", ARGV[1])
26+
end
2427
end
2528
if ttl and ttl ~= cjson.null then
2629
redis.call("EXPIRE", hash_key, ttl)

test/coverband/adapters/hash_redis_store_test.rb

+16-14
Original file line numberDiff line numberDiff line change
@@ -57,23 +57,21 @@ def test_coverage_for_file
5757
"first_updated_at" => yesterday.to_i,
5858
"last_updated_at" => yesterday.to_i,
5959
"file_hash" => "abcd",
60-
"data" => [0, 1, 2]
60+
"data" => [0, 1, 2],
61+
"timedata" => [nil, Time.at(yesterday.to_i), Time.at(yesterday.to_i)]
6162
},
6263
@store.coverage["./dog.rb"]
6364
)
6465
mock_time(today)
6566
@store.save_report(
6667
"app_path/dog.rb" => [1, 1, 0]
6768
)
68-
assert_equal(
69-
{
70-
"first_updated_at" => yesterday.to_i,
71-
"last_updated_at" => today.to_i,
72-
"file_hash" => "abcd",
73-
"data" => [1, 2, 2]
74-
},
75-
@store.coverage["./dog.rb"]
76-
)
69+
70+
assert_equal("abcd", @store.coverage["./dog.rb"]["file_hash"])
71+
assert_equal(today.to_i, @store.coverage["./dog.rb"]["last_updated_at"])
72+
assert_equal(yesterday.to_i, @store.coverage["./dog.rb"]["first_updated_at"])
73+
assert_equal([1, 2, 2], @store.coverage["./dog.rb"]["data"])
74+
assert_equal([Time.at(today.to_i), Time.at(today.to_i), Time.at(yesterday.to_i)], @store.coverage["./dog.rb"]["timedata"])
7775
end
7876

7977
def test_ttl_set
@@ -109,7 +107,8 @@ def test_coverage_for_multiple_files
109107
"first_updated_at" => current_time.to_i,
110108
"last_updated_at" => current_time.to_i,
111109
"file_hash" => "abcd",
112-
"data" => [0, nil, 1, 2]
110+
"data" => [0, nil, 1, 2],
111+
"timedata" => [nil, nil, Time.at(current_time.to_i), Time.at(current_time.to_i)]
113112
}, @store.coverage["./dog.rb"]
114113
)
115114
assert_equal [1, 2, 0, 1, 5], @store.coverage["./cat.rb"]["data"]
@@ -213,7 +212,8 @@ def test_get_coverage_cache
213212
"first_updated_at" => yesterday.to_i,
214213
"last_updated_at" => yesterday.to_i,
215214
"file_hash" => "abcd",
216-
"data" => [0, 1, 2]
215+
"data" => [0, 1, 2],
216+
"timedata" => [nil, Time.at(yesterday.to_i), Time.at(yesterday.to_i)]
217217
},
218218
@store.coverage["./dog.rb"]
219219
)
@@ -225,7 +225,8 @@ def test_get_coverage_cache
225225
"first_updated_at" => yesterday.to_i,
226226
"last_updated_at" => yesterday.to_i,
227227
"file_hash" => "abcd",
228-
"data" => [0, 1, 2]
228+
"data" => [0, 1, 2],
229+
"timedata" => [nil, Time.at(yesterday.to_i), Time.at(yesterday.to_i)]
229230
},
230231
@store.coverage["./dog.rb"]
231232
)
@@ -235,7 +236,8 @@ def test_get_coverage_cache
235236
"first_updated_at" => yesterday.to_i,
236237
"last_updated_at" => yesterday.to_i,
237238
"file_hash" => "abcd",
238-
"data" => [0, 2, 4]
239+
"data" => [0, 2, 4],
240+
"timedata" => [nil, Time.at(yesterday.to_i), Time.at(yesterday.to_i)]
239241
},
240242
@store.coverage["./dog.rb"]
241243
)

views/source_file.erb

+1
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
runtime:
4646
<%= result.file_with_type(source_file, Coverband::RUNTIME_TYPE)&.line_coverage(index) || 0 %>
4747
all: <%= line.coverage %>
48+
last posted: <%= timeago(result.file_with_type(source_file, Coverband::RUNTIME_TYPE)&.line_coverage_posted(index), "-") %>
4849
</span><% end %>
4950
<% if line.skipped? %><span class="hits">skipped</span><% end %>
5051
<code class="ruby"><%= CGI.escapeHTML(line.src.chomp) %></code>

0 commit comments

Comments
 (0)