CoveredSourceCoveredConfig

class Config

Loads project coverage configuration and controls a configured policy.

Definitions

def self.root

The root directory used for coverage configuration.

Signature

returns String

The value of COVERED_ROOT, or the current working directory.

Implementation

def self.root
	ENV["COVERED_ROOT"] || Dir.pwd
end

def self.path(root)

The coverage configuration path under the given root.

Signature

parameter root String

The project root.

returns String | Nil

The expanded configuration path if it exists.

Implementation

def self.path(root)
	path = ::File.expand_path(PATH, root)
	
	if ::File.exist?(path)
		return path
	end
end

def self.reports

The report names requested by the environment.

Signature

returns String | Nil

The COVERAGE environment value.

Implementation

def self.reports
	ENV["COVERAGE"]
end

def self.load(root: self.root, reports: self.reports, persist: true)

Load the project coverage configuration for the given root.

Signature

parameter root String

The project root.

parameter reports String | Boolean | Array | Object | Nil

The report configuration.

parameter persist Boolean

Whether the configured policy should persist coverage to the default database.

returns Covered::Config

The loaded configuration instance.

Implementation

def self.load(root: self.root, reports: self.reports, persist: true)
	derived = Class.new(self)
	
	if path = self.path(root)
		config = Module.new
		config.module_eval(::File.read(path), path)
		derived.prepend(config)
	end
	
	return derived.new(root, reports, persist)
end

def initialize(root, reports, persist = true)

Initialize the configuration for a project root and reports.

Signature

parameter root String

The project root.

parameter reports String | Boolean | Array | Object | Nil

The report configuration.

parameter persist Boolean

Whether the configured policy should persist coverage to the default database.

Implementation

def initialize(root, reports, persist = true)
	@root = root
	@reports = reports
	@policy = nil
	@persist = persist
	
	@environment = nil
end

def report?

Whether reports should be generated.

Signature

returns Boolean

Whether reporting is enabled.

Implementation

def report?
	!!@reports
end

attr :coverage

Signature

attribute Covered::Policy | Nil

The active coverage policy, if assigned by an integration.

def policy

The configured coverage policy.

Signature

returns Covered::Policy

The memoized, frozen policy.

Implementation

def policy
	@policy ||= Policy.new.tap{|policy| make_policy(policy)}.freeze
end

def output

The configured policy output wrapper.

Signature

returns Covered::Base

The output wrapper at the end of the policy pipeline.

Implementation

def output
	policy.output
end

def start

Start coverage tracking. Stores the current environment, configures child process autostart, and starts the policy capture pipeline.

Implementation

def start
	# Save and setup the environment:
	@environment = ENV.to_h
	autostart!
	
	# Start coverage tracking:
	policy.start
end

def finish

Finish coverage tracking. Stops the policy capture pipeline and restores the environment saved by Covered::Config#start.

Implementation

def finish
	# Finish coverage tracking:
	policy.finish
	
	# Restore the environment:
	ENV.replace(@environment)
	@environment = nil
end

def call(output)

Generate coverage reports to the given output.

Signature

parameter output IO

The output stream to write the coverage report to.

Implementation

def call(output)
	policy.call(output)
end

def each(&block)

Enumerate the coverage data from the configured policy.

Signature

yields {|coverage| ...}

Each coverage object from the policy.

parameter coverage Covered::Coverage

The current coverage object.

Implementation

def each(&block)
	policy.each(&block)
end

def policy_for(paths = nil, ignore_mtime: true)

Build a configured policy using coverage data from persistent storage.

Signature

parameter paths Array(String)

The coverage database paths.

parameter ignore_mtime Boolean

Whether to ignore source file modification times.

returns Covered::Policy

The configured policy with loaded coverage data.

Implementation

def policy_for(paths = nil, ignore_mtime: true)
	paths ||= Dir.glob(Persist::DEFAULT_PATH, base: @root)
	paths = Array(paths)
	
	if paths.empty?
		raise ArgumentError, "No coverage paths specified!"
	end
	
	paths.each do |path|
		# It would be nice to have a better algorithm here than just ignoring mtime - perhaps using checksums:
		Persist.new(policy.output, path).load!(ignore_mtime: ignore_mtime)
	end
	
	return policy
end

def ignore_paths

Which paths to ignore when computing coverage for a given project.

Signature

returns Array(String)

An array of relative paths to ignore.

Implementation

def ignore_paths
	["test/", "fixtures/", "spec/", "vendor/", "config/"]
end

def include_patterns

Which paths to include when computing coverage for a given project.

Signature

returns Array(String)

An array of relative patterns to include, e.g. "lib/**/*.rb".

Implementation

def include_patterns
	["lib/**/*.rb"]
end

def make_policy(policy)

Override this method to implement your own policy.

Signature

parameter policy Covered::Policy

The policy to configure.

Implementation

def make_policy(policy)
	# Only files in the root would be tracked:
	policy.root(@root)
	
	patterns = ignore_paths.map do |path|
		File.join(@root, path)
	end
	
	# We will ignore any files in the test or spec directory:
	policy.skip(Regexp.union(patterns))
	
	# We will include all files under lib, even if they aren't loaded:
	include_patterns.each do |pattern|
		policy.include(pattern)
	end
	
	policy.persist! if @persist
	
	policy.reports!(@reports)
end