lib/covered/files.rb in covered-0.19.1 vs lib/covered/files.rb in covered-0.20.0

- old
+ new

@@ -1,46 +1,103 @@ # frozen_string_literal: true # Released under the MIT License. -# Copyright, 2018-2022, by Samuel Williams. +# Copyright, 2018-2023, by Samuel Williams. require_relative 'coverage' require_relative 'wrapper' require 'set' module Covered class Files < Base + class State + def self.for(path, **options) + self.new(Source.new(path, **options)) + end + + def initialize(source) + @source = source + @counts = [] + @annotations = {} + end + + def [](lineno) + @counts[lineno] + end + + attr :counts + attr :annotations + + def annotate(lineno, annotation) + @annotations[lineno] ||= [] + @annotations[lineno] << annotation + end + + def mark(lineno, value = 1) + if @counts[lineno] + @counts[lineno] += value + else + @counts[lineno] = value + end + end + + def merge!(coverage) + coverage.counts.each_with_index do |count, index| + if count + @counts[index] ||= 0 + @counts[index] += count + end + end + + @annotations.merge!(coverage.annotations) do |lineno, a, b| + Array(a) + Array(b) + end + end + + def coverage + Coverage.new(@source, @counts, @annotations) + end + end + def initialize(*) super @paths = {} end attr_accessor :paths def [](path) - @paths[path] + @paths[path] ||= State.for(path) end def empty? @paths.empty? end def mark(path, lineno, value) - coverage = (@paths[path] ||= Coverage.for(path)) - - coverage.mark(lineno, value) - - return coverage + self[path].mark(lineno, value) end - def add(source) - @paths[source.path] ||= Coverage.new(source) + def annotate(path, lineno, value) + self[path].annotate(lineno, value) end - def each(&block) - @paths.each_value(&block) + def add(coverage) + self[coverage.path].merge!(coverage) + end + + def each + return to_enum unless block_given? + + @paths.each_value do |state| + yield state.coverage + end + end + + def clear + @paths.clear end end class Include < Wrapper def initialize(output, pattern, base = "")