Class: ChefSpec::Coverage
- Inherits:
-
Object
- Object
- ChefSpec::Coverage
- Includes:
- Singleton
- Defined in:
- lib/chefspec/coverage.rb,
lib/chefspec/coverage/filters.rb
Defined Under Namespace
Classes: BerkshelfFilter, BlockFilter, Filter, RegexpFilter, ResourceWrapper, StringFilter
Constant Summary collapse
- EXIT_FAILURE =
1
- EXIT_SUCCESS =
0
Instance Attribute Summary collapse
-
#filters ⇒ Object
readonly
Returns the value of attribute filters.
Class Method Summary collapse
Instance Method Summary collapse
-
#add(resource) ⇒ Object
Add a resource to the resource collection.
-
#add_filter(filter = nil, &block) ⇒ true
Add a filter to the coverage analysis.
-
#add_output(&block) ⇒ true
Add an output to send the coverage results to.
-
#cover!(resource) ⇒ Object
Called when a resource is matched to indicate it has been tested.
-
#filtered?(resource) ⇒ Boolean
Called to check if a resource belongs to a cookbook from the specified directories.
-
#initialize ⇒ Coverage
constructor
Create a new coverage object singleton.
-
#report! ⇒ Object
Generate a coverage report.
-
#set_template(file = "human.erb") ⇒ true
Change the template for reporting of converage analysis.
-
#start!(&block) ⇒ Object
Start the coverage reporting analysis.
Constructor Details
#initialize ⇒ Coverage
Create a new coverage object singleton.
28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
# File 'lib/chefspec/coverage.rb', line 28 def initialize @collection = {} @filters = {} @outputs = [] add_output do |report| erb = Erubis::Eruby.new(File.read(@template)) puts erb.evaluate(report) rescue NameError => e raise Error::ErbTemplateParseError.new(original_error: e.) end @template = ChefSpec.root.join("templates", "coverage", "human.erb") end |
Instance Attribute Details
#filters ⇒ Object (readonly)
Returns the value of attribute filters.
23 24 25 |
# File 'lib/chefspec/coverage.rb', line 23 def filters @filters end |
Class Method Details
.method_added(name) ⇒ Object
9 10 11 12 13 14 15 16 17 18 |
# File 'lib/chefspec/coverage.rb', line 9 def method_added(name) # Only delegate public methods if method_defined?(name) instance_eval <<-EOH, __FILE__, __LINE__ + 1 def #{name}(*args, &block) instance.public_send(:#{name}, *args, &block) end EOH end end |
Instance Method Details
#add(resource) ⇒ Object
Add a resource to the resource collection. Only new resources are added and only resources that match the given filter are covered (which is * by default).
116 117 118 119 120 |
# File 'lib/chefspec/coverage.rb', line 116 def add(resource) if !exists?(resource) && !filtered?(resource) @collection[resource.to_s] = ResourceWrapper.new(resource) end end |
#add_filter(filter = nil, &block) ⇒ true
Add a filter to the coverage analysis.
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/chefspec/coverage.rb', line 63 def add_filter(filter = nil, &block) id = "#{filter.inspect}/#{block.inspect}".hash @filters[id] = if filter.is_a?(Filter) filter elsif filter.is_a?(String) StringFilter.new(filter) elsif filter.is_a?(Regexp) RegexpFilter.new(filter) elsif block BlockFilter.new(block) else raise ArgumentError, "Please specify either a string, " \ "filter, or block to filter source files with!" end true end |
#add_output(&block) ⇒ true
Add an output to send the coverage results to.
89 90 91 |
# File 'lib/chefspec/coverage.rb', line 89 def add_output(&block) @outputs << block end |
#cover!(resource) ⇒ Object
Called when a resource is matched to indicate it has been tested.
127 128 129 130 |
# File 'lib/chefspec/coverage.rb', line 127 def cover!(resource) wrapper = find(resource) wrapper.touch! if wrapper end |
#filtered?(resource) ⇒ Boolean
Called to check if a resource belongs to a cookbook from the specified directories.
138 139 140 |
# File 'lib/chefspec/coverage.rb', line 138 def filtered?(resource) filters.any? { |_, filter| filter.matches?(resource) } end |
#report! ⇒ Object
Generate a coverage report. This report must be generated at_exit
or else the entire resource collection may not be complete!
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 |
# File 'lib/chefspec/coverage.rb', line 150 def report! # Borrowed from simplecov#41 # # If an exception is thrown that isn't a "SystemExit", we need to capture # that error and re-raise. if $! exit_status = $!.is_a?(SystemExit) ? $!.status : EXIT_FAILURE else exit_status = EXIT_SUCCESS end report = {}.tap do |h| h[:total] = @collection.size h[:touched] = @collection.count { |_, resource| resource.touched? } h[:coverage] = ((h[:touched] / h[:total].to_f) * 100).round(2) end report[:untouched_resources] = @collection.collect do |_, resource| resource unless resource.touched? end.compact report[:all_resources] = @collection.values @outputs.each do |block| instance_exec(report, &block) end # Ensure we exit correctly (#351) Kernel.exit(exit_status) if exit_status && exit_status > 0 end |
#set_template(file = "human.erb") ⇒ true
Change the template for reporting of converage analysis.
101 102 103 104 105 106 107 |
# File 'lib/chefspec/coverage.rb', line 101 def set_template(file = "human.erb") @template = [ ChefSpec.root.join("templates", "coverage", file), File.(file, Dir.pwd), ].find { |f| File.exist?(f) } raise Error::TemplateNotFound.new(path: file) unless @template end |
#start!(&block) ⇒ Object
Start the coverage reporting analysis. This method also adds the the at_exit
handler for printing the coverage report.
47 48 49 50 51 |
# File 'lib/chefspec/coverage.rb', line 47 def start!(&block) warn("ChefSpec's coverage reporting is deprecated and will be removed in a future version") instance_eval(&block) if block at_exit { ChefSpec::Coverage.report! } end |