lib/oneshot_coverage.rb in oneshot_coverage-0.2.2 vs lib/oneshot_coverage.rb in oneshot_coverage-0.3.0
- old
+ new
@@ -17,93 +17,104 @@
OneshotCoverage.emit
end
end
end
+ OneshotLog = Struct.new(:path, :md5_hash, :lines)
+
class Reporter
- def initialize(target_path:, logger:, max_emit_at_once:)
+ def initialize(target_path:, logger:, emit_term: nil)
@target_path = target_path
@logger = logger
- @buffer = []
- @max_emit_at_once = max_emit_at_once
+ @emit_term = emit_term
+ if @emit_term
+ @next_emit_time = Time.now.to_i + rand(@emit_term)
+ end
+
if defined?(Bundler)
@bundler_path = Bundler.bundle_path.to_s
end
end
- def emit
- Coverage.result(clear: true, stop: false).
+ def emit(force_emit)
+ if !force_emit
+ if !time_to_emit?
+ return true
+ end
+ end
+
+ logs =
+ Coverage.result(clear: true, stop: false).
select { |k, v| is_target?(k, v) }.
- flat_map { |k, v| transform(k, v) }.
- each { |row| @buffer << row }
+ map do |filepath, v|
+ OneshotLog.new(relative_path(filepath), md5_hash_for(filepath), v[:oneshot_lines])
+ end
- @buffer.shift(emit_at_once).each do |row|
- # Retry when fail to post
- unless @logger.post(row)
- @buffer << row
+ @logger.post(logs)
+ end
+
+ private
+
+ def time_to_emit?
+ if @emit_term
+ if @next_emit_time > Time.now.to_i
+ return false # Do not emit until next_emit_time
+ else
+ @next_emit_time += @emit_term
end
end
+ true
end
def is_target?(filepath, value)
return false if value[:oneshot_lines].empty?
return false if !filepath.start_with?(@target_path)
return false if @bundler_path && filepath.start_with?(@bundler_path)
true
end
- def transform(filepath, value)
- rel_path = filepath[@target_path.size..-1]
- md5_hash =
- if md5_hash_cache.key?(filepath)
- md5_hash_cache[filepath]
- else
- md5_hash_cache[filepath] = Digest::MD5.file(filepath).hexdigest
- end
-
- value[:oneshot_lines].map do |line|
- {
- path: rel_path,
- md5_hash: md5_hash,
- lineno: line
- }
- end
+ def relative_path(filepath)
+ filepath[@target_path.size..-1]
end
def md5_hash_cache
@md5_hash_cache ||= {}
end
- def emit_at_once
- @max_emit_at_once || @buffer.size
+ def md5_hash_for(filepath)
+ if md5_hash_cache.key? filepath
+ md5_hash_cache[filepath]
+ else
+ md5_hash_cache[filepath] = Digest::MD5.file(filepath).hexdigest
+ end
end
end
module_function
def start
Coverage.start(oneshot_lines: true)
# To handle execution with exit immediatly
at_exit do
- OneshotCoverage.emit
+ OneshotCoverage.emit(force_emit: true)
end
end
- def emit
- @reporter&.emit
+ def emit(force_emit: false)
+ @reporter&.emit(force_emit)
end
- def configure(target_path:, logger: OneshotCoverage::Logger::NullLogger.new, max_emit_at_once: nil)
+ def configure(target_path:, logger: OneshotCoverage::Logger::NullLogger.new, emit_term: nil)
target_path_by_pathname =
if target_path.is_a? Pathname
target_path
else
Pathname.new(target_path)
end
@reporter = OneshotCoverage::Reporter.new(
target_path: target_path_by_pathname.cleanpath.to_s + "/",
logger: logger,
- max_emit_at_once: max_emit_at_once
+ emit_term: emit_term,
)
end
end