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| begin erb = Erubis::Eruby.new(File.read(@template)) puts erb.evaluate(report) rescue NameError => e raise Error::ErbTemplateParseError.new(original_error: e.) end 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).
120 121 122 123 124 |
# File 'lib/chefspec/coverage.rb', line 120 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.kind_of?(Filter) filter elsif filter.kind_of?(String) StringFilter.new(filter) elsif filter.kind_of?(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.
131 132 133 134 135 |
# File 'lib/chefspec/coverage.rb', line 131 def cover!(resource) if wrapper = find(resource) wrapper.touch! end end |
#filtered?(resource) ⇒ Boolean
Called to check if a resource belongs to a cookbook from the specified directories.
143 144 145 |
# File 'lib/chefspec/coverage.rb', line 143 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!
155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 |
# File 'lib/chefspec/coverage.rb', line 155 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| self.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 108 109 110 111 112 |
# File 'lib/chefspec/coverage.rb', line 101 def set_template(file = 'human.erb') [ ChefSpec.root.join('templates', 'coverage', file), File.(file, Dir.pwd) ].each do |temp| if File.exist?(temp) @template = temp return end end raise Error::TemplateNotFound.new(path: file) 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 |