chefspec-coveragereports 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data.tar.gz.sig +2 -0
- data/LICENSE.txt +22 -0
- data/README.md +119 -0
- data/lib/chefspec/coverage.rb +35 -0
- data/lib/chefspec/coveragereports.rb +122 -0
- data/lib/chefspec/coveragereports/version.rb +13 -0
- data/templates/json.erb +1 -0
- metadata +132 -0
- metadata.gz.sig +0 -0
data.tar.gz.sig
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2015 Anthony Spring
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,119 @@
|
|
1
|
+
# ChefSpec::CoverageReports
|
2
|
+
|
3
|
+
Provides a generic interface to creating ChefSpec coverage reports, including a default JSON template.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem 'chefspec-coveragereports'
|
11
|
+
```
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install chefspec-coveragereports
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
To enable the Coverage Reports functionality, you must include the following inside of your spec_helper:
|
24
|
+
|
25
|
+
```ruby
|
26
|
+
require 'chefspec/coveragereports'
|
27
|
+
```
|
28
|
+
|
29
|
+
With this included you can now tell the Coverage Reports what reports to generate and where to place the reports.
|
30
|
+
|
31
|
+
#### Using one of the included templates
|
32
|
+
|
33
|
+
To utilize one of the included Erubis templates you can use the following:
|
34
|
+
|
35
|
+
```ruby
|
36
|
+
ChefSpec::CoverageReports.add('json', 'coverage.json')
|
37
|
+
```
|
38
|
+
|
39
|
+
This will utilize the built in json template, and create a file named coverage.json.
|
40
|
+
|
41
|
+
#### Proving your own template
|
42
|
+
|
43
|
+
To utilize your own Erubis template you can use the following:
|
44
|
+
|
45
|
+
```ruby
|
46
|
+
ChefSpec::CoverageReports.add_custom('some/path/template.erb', 'coverage.report')
|
47
|
+
```
|
48
|
+
|
49
|
+
Where you provide the path to the template, and the output file for the report.
|
50
|
+
|
51
|
+
## Template Functionality
|
52
|
+
|
53
|
+
Coverage Reports exposes a hash called `@coverage` that can be used to create your own custom Erubis templates.
|
54
|
+
|
55
|
+
This hash provides full access to the raw coverage data generated by ChefSpec, as well as some already processed data.
|
56
|
+
|
57
|
+
### raw
|
58
|
+
|
59
|
+
```ruby
|
60
|
+
@coverage['raw']
|
61
|
+
```
|
62
|
+
|
63
|
+
Provides full access to the array of raw data generated by ChefSpec
|
64
|
+
|
65
|
+
### coverage
|
66
|
+
|
67
|
+
```ruby
|
68
|
+
@coverage['coverage']
|
69
|
+
```
|
70
|
+
|
71
|
+
Provides acccess to the data processed by Coverage Reports.
|
72
|
+
|
73
|
+
##### files
|
74
|
+
|
75
|
+
```ruby
|
76
|
+
@coverage['coverage']['files']
|
77
|
+
```
|
78
|
+
|
79
|
+
Provides access to a hash of all of the files and the resources observed inside of them.
|
80
|
+
|
81
|
+
##### resources - all
|
82
|
+
|
83
|
+
```ruby
|
84
|
+
@coverage['coverage']['resources']['all']
|
85
|
+
```
|
86
|
+
|
87
|
+
Provides access to a hash of all of the resources, keyed by name.
|
88
|
+
|
89
|
+
##### resources - covered
|
90
|
+
|
91
|
+
```ruby
|
92
|
+
@coverage['coverage']['resources']['covered']
|
93
|
+
```
|
94
|
+
|
95
|
+
Provides access to a hash of all of the resources that were covered, keyed by name.
|
96
|
+
|
97
|
+
##### resources - uncovered
|
98
|
+
|
99
|
+
```ruby
|
100
|
+
@coverage['coverage']['resources']['uncovered']
|
101
|
+
```
|
102
|
+
|
103
|
+
Provides access to a hash of all of the resources that were **not** covered, keyed by name.
|
104
|
+
|
105
|
+
##### totals
|
106
|
+
|
107
|
+
```ruby
|
108
|
+
@coverage['coverage']['totals']
|
109
|
+
```
|
110
|
+
|
111
|
+
Provides a set of totals to help make reporting easier, including total resources, covered and uncovered resource counts, as well as percent coverage.
|
112
|
+
|
113
|
+
## Contributing
|
114
|
+
|
115
|
+
1. Fork it ( https://github.com/[my-github-username]/chefspec-reports/fork )
|
116
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
117
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
118
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
119
|
+
5. Create a new Pull Request
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'chefspec/coverage'
|
2
|
+
|
3
|
+
ChefSpec::Coverage.class_eval do
|
4
|
+
def report!
|
5
|
+
# Borrowed from simplecov#41
|
6
|
+
#
|
7
|
+
# If an exception is thrown that isn't a "SystemExit", we need to capture
|
8
|
+
# that error and re-raise.
|
9
|
+
if $ERROR_INFO
|
10
|
+
exit_status = $ERROR_INFO.is_a?(SystemExit) ? $ERROR_INFO.status : ChefSpec::Coverage::EXIT_FAILURE
|
11
|
+
else
|
12
|
+
exit_status = ChefSpec::Coverage::EXIT_SUCCESS
|
13
|
+
end
|
14
|
+
|
15
|
+
report = {}.tap do |h|
|
16
|
+
h[:total] = @collection.size
|
17
|
+
h[:touched] = @collection.count { |_, resource| resource.touched? }
|
18
|
+
h[:coverage] = ((h[:touched] / h[:total].to_f) * 100).round(2)
|
19
|
+
end
|
20
|
+
|
21
|
+
report[:untouched_resources] = @collection.map do |_, resource|
|
22
|
+
resource unless resource.touched?
|
23
|
+
end.compact
|
24
|
+
|
25
|
+
template = ChefSpec.root.join('templates', 'coverage', 'human.erb')
|
26
|
+
erb = Erubis::Eruby.new(File.read(template))
|
27
|
+
puts erb.evaluate(report)
|
28
|
+
|
29
|
+
# Generate the coverage reports
|
30
|
+
ChefSpec::CoverageReports.generate_reports(@collection)
|
31
|
+
|
32
|
+
# Ensure we exit correctly (#351)
|
33
|
+
Kernel.exit(exit_status) if exit_status && exit_status > 0
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,122 @@
|
|
1
|
+
require 'chefspec'
|
2
|
+
require 'chefspec/coveragereports/version'
|
3
|
+
require 'fileutils'
|
4
|
+
|
5
|
+
module ChefSpec
|
6
|
+
class CoverageReports
|
7
|
+
class << self
|
8
|
+
def method_added(name)
|
9
|
+
# Only delegate public methods
|
10
|
+
if method_defined?(name)
|
11
|
+
instance_eval <<-EOH, __FILE__, __LINE__ + 1
|
12
|
+
def #{name}(*args, &block)
|
13
|
+
instance.public_send(:#{name}, *args, &block)
|
14
|
+
end
|
15
|
+
EOH
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
include Singleton
|
21
|
+
|
22
|
+
attr_reader :reports
|
23
|
+
|
24
|
+
def initialize
|
25
|
+
@reports = {}
|
26
|
+
end
|
27
|
+
|
28
|
+
def add(type, output_file)
|
29
|
+
reports[root.join('templates', "#{type}.erb")] = output_file
|
30
|
+
end
|
31
|
+
|
32
|
+
def add_custom(template, output_file)
|
33
|
+
reports[template] = output_file
|
34
|
+
end
|
35
|
+
|
36
|
+
def clear_reports
|
37
|
+
@reports = {}
|
38
|
+
end
|
39
|
+
|
40
|
+
def delete(type)
|
41
|
+
reports[type] = nil
|
42
|
+
end
|
43
|
+
|
44
|
+
def generate_reports(data)
|
45
|
+
@coverage = {}
|
46
|
+
@coverage['raw'] = data
|
47
|
+
@coverage['coverage'] = process_report_data(data)
|
48
|
+
|
49
|
+
reports.each do |template, output_file|
|
50
|
+
erb = Erubis::Eruby.new(File.read(template))
|
51
|
+
|
52
|
+
# Create the output directory if it doesnt exist
|
53
|
+
dirname = File.dirname(output_file)
|
54
|
+
FileUtils.mkdir_p(dirname) unless File.directory?(dirname)
|
55
|
+
|
56
|
+
File.open(output_file, 'w') { |f| f.write(erb.evaluate(@coverage)) }
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
def root
|
63
|
+
@root ||= Pathname.new(File.expand_path('../../../', __FILE__))
|
64
|
+
end
|
65
|
+
|
66
|
+
def process_report_data(data)
|
67
|
+
results = {}
|
68
|
+
results['files'] = {}
|
69
|
+
results['resources'] = {}
|
70
|
+
results['resources']['all'] = {}
|
71
|
+
results['resources']['covered'] = {}
|
72
|
+
results['resources']['uncovered'] = {}
|
73
|
+
results['totals'] = {}
|
74
|
+
|
75
|
+
# Process the report data
|
76
|
+
data.map do |name, resource|
|
77
|
+
resource_hash = generate_resource_hash(resource)
|
78
|
+
|
79
|
+
# Store the file information
|
80
|
+
results['files'][resource.source_file] ||= {}
|
81
|
+
results['files'][resource.source_file][name] = resource_hash
|
82
|
+
|
83
|
+
# Store the resources information
|
84
|
+
results['resources']['all'][name] = resource_hash
|
85
|
+
results['resources']['covered'][name] = resource_hash if resource.touched?
|
86
|
+
results['resources']['uncovered'][name] = resource_hash unless resource.touched?
|
87
|
+
end
|
88
|
+
|
89
|
+
# Sort the results
|
90
|
+
results['files'].sort
|
91
|
+
results['files'].each do |f, _|
|
92
|
+
results['files'][f].sort
|
93
|
+
end
|
94
|
+
results['resources']['all'].sort
|
95
|
+
results['resources']['covered'].sort
|
96
|
+
results['resources']['uncovered'].sort
|
97
|
+
|
98
|
+
# Calculate the derived totals
|
99
|
+
results['totals']['resources'] = results['resources']['all'].size
|
100
|
+
results['totals']['covered'] = results['resources']['covered'].size
|
101
|
+
results['totals']['uncovered'] = results['resources']['uncovered'].size
|
102
|
+
results['totals']['percent'] = ((results['totals']['covered'] / results['totals']['resources'].to_f) * 100).round(2)
|
103
|
+
results['totals']['percent'] = 0 if results['totals']['percent'].nan?
|
104
|
+
results['totals']['percent'] = 100 if results['totals']['percent'].infinite?
|
105
|
+
|
106
|
+
results
|
107
|
+
end
|
108
|
+
|
109
|
+
def generate_resource_hash(resource)
|
110
|
+
result = {}
|
111
|
+
|
112
|
+
result['name'] = resource.to_s
|
113
|
+
result['source'] = resource.source_file
|
114
|
+
result['line'] = resource.source_line
|
115
|
+
result['covered'] = resource.touched?
|
116
|
+
|
117
|
+
result
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
require_relative 'coverage'
|
data/templates/json.erb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
<%= JSON.pretty_generate(@coverage) + "\n" %>
|
metadata
ADDED
@@ -0,0 +1,132 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: chefspec-coveragereports
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Anthony Spring
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain:
|
12
|
+
- !binary |-
|
13
|
+
LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURwakNDQW82Z0F3SUJB
|
14
|
+
Z0lCQVRBTkJna3Foa2lHOXcwQkFRVUZBREJNTVEwd0N3WURWUVFEREFSMGIy
|
15
|
+
NTUKTVNZd0pBWUtDWkltaVpQeUxHUUJHUllXY0c5eWEyTm9iM0J6WVc1a2NH
|
16
|
+
RnBiblJqYUdsd2N6RVRNQkVHQ2dtUwpKb21UOGl4a0FSa1dBMk52YlRBZUZ3
|
17
|
+
MHhOVEF6TWpneU1qUTVOREJhRncweE5qQXpNamN5TWpRNU5EQmFNRXd4CkRU
|
18
|
+
QUxCZ05WQkFNTUJIUnZibmt4SmpBa0Jnb0praWFKay9Jc1pBRVpGaFp3YjNK
|
19
|
+
clkyaHZjSE5oYm1Sd1lXbHUKZEdOb2FYQnpNUk13RVFZS0NaSW1pWlB5TEdR
|
20
|
+
QkdSWURZMjl0TUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQwpBUThBTUlJ
|
21
|
+
QkNnS0NBUUVBcUxDMzVTYmFLQnQ3YjdISncxdDh0ejRrYStSNDl5cjBrNFNx
|
22
|
+
eUxGd0JiOXRHSVBKCm9ORWNtUzJWL05pV0l0bWtlLzcrdVphaklROW9XKzlr
|
23
|
+
aDJJdzE1bDQ5S0JobkZDcTNrK2IxeVRTVm1OZXBLbXoKN21tdDA1Rjg4VkZ6
|
24
|
+
aDRkU2hyZjRMdnlGT1JuQVMyTmJVblNvTDBhMFUzVS9ielMyWVhGbGROdkdE
|
25
|
+
aTVIdVZ2WApvK21xMHpXemJnOERjdWhVUjVHWFA2dnNVVzJZVFErTURvRU1n
|
26
|
+
enNwcDRwTUNFbDRNc2d4UzhTb3NTRi9yQXl6Cml6bndXOGN5REVhNDFjUUlL
|
27
|
+
UzRySWkySnpwdkdKYjJVd0JNTXVXaGthRG84MUR4cGJaRktmSGo2cm1zK0Zi
|
28
|
+
OEMKVFhNUVpvd0JpR05DQ1lVS3ZrT3JXTXVqWW0zVWxIY2RCS0NOelFJREFR
|
29
|
+
QUJvNEdTTUlHUE1Ba0dBMVVkRXdRQwpNQUF3Q3dZRFZSMFBCQVFEQWdTd01C
|
30
|
+
MEdBMVVkRGdRV0JCVERheUdjT1Y1cXB1bnk2ejdjYVRjcW11MzJZakFxCkJn
|
31
|
+
TlZIUkVFSXpBaGdSOTBiMjU1UUhCdmNtdGphRzl3YzJGdVpIQmhhVzUwWTJo
|
32
|
+
cGNITXVZMjl0TUNvR0ExVWQKRWdRak1DR0JIM1J2Ym5sQWNHOXlhMk5vYjNC
|
33
|
+
ellXNWtjR0ZwYm5SamFHbHdjeTVqYjIwd0RRWUpLb1pJaHZjTgpBUUVGQlFB
|
34
|
+
RGdnRUJBSFJrL3gxTTAwd0o3OHVkTzlROUZFemw2ajhMWnF3NHoxdVRlZW1J
|
35
|
+
aHVlMlB2NWpWV0cxClF3ZlFsQ1pQKzFQajZiWFl2aWtrQkhoN1FSVkgxVFZM
|
36
|
+
cHVnTE5YY3BvVnNwVnhITnVvdTRjNmhHa0VlRTBBYVYKVVlqcGtTcTFSNGt5
|
37
|
+
Qy9ETzVmSU4rRGpNZDcvNFhDZXBNUWJLdWt6R2Yxait0QkgvclJEWkJEMXlO
|
38
|
+
Y245MHZOYQpXMGRmY0dLOW82Q05YU3NPcXVCeDd6R25uS2NGWGlrcjU1Z1Bx
|
39
|
+
VW5qdWxSQnFVT21LN3lYUlgxL2h6R3RrenVwCnRWM0ZWcmVPRmlpWFo2eXhE
|
40
|
+
djVxdUNQdUh0bzZmWnh0d0RTb0xlaWVHeXJNVDgwaEFTMW5FT1dWWVh4V3BS
|
41
|
+
VmEKWEJRZVBYREhnZmw1SkRMMDVLSXowK3grLzVkRnFsTW5XSVE9Ci0tLS0t
|
42
|
+
RU5EIENFUlRJRklDQVRFLS0tLS0K
|
43
|
+
date: 2015-03-28 00:00:00.000000000 Z
|
44
|
+
dependencies:
|
45
|
+
- !ruby/object:Gem::Dependency
|
46
|
+
name: chefspec
|
47
|
+
requirement: !ruby/object:Gem::Requirement
|
48
|
+
none: false
|
49
|
+
requirements:
|
50
|
+
- - ! '>='
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: '4.0'
|
53
|
+
type: :runtime
|
54
|
+
prerelease: false
|
55
|
+
version_requirements: !ruby/object:Gem::Requirement
|
56
|
+
none: false
|
57
|
+
requirements:
|
58
|
+
- - ! '>='
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '4.0'
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
name: bundler
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
64
|
+
none: false
|
65
|
+
requirements:
|
66
|
+
- - ~>
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '1.7'
|
69
|
+
type: :development
|
70
|
+
prerelease: false
|
71
|
+
version_requirements: !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ~>
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '1.7'
|
77
|
+
- !ruby/object:Gem::Dependency
|
78
|
+
name: rake
|
79
|
+
requirement: !ruby/object:Gem::Requirement
|
80
|
+
none: false
|
81
|
+
requirements:
|
82
|
+
- - ~>
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: '10.0'
|
85
|
+
type: :development
|
86
|
+
prerelease: false
|
87
|
+
version_requirements: !ruby/object:Gem::Requirement
|
88
|
+
none: false
|
89
|
+
requirements:
|
90
|
+
- - ~>
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: '10.0'
|
93
|
+
description: ChefSpec Coverage Reports
|
94
|
+
email:
|
95
|
+
- tony@porkchopsandpaintchips.com
|
96
|
+
executables: []
|
97
|
+
extensions: []
|
98
|
+
extra_rdoc_files: []
|
99
|
+
files:
|
100
|
+
- lib/chefspec/coverage.rb
|
101
|
+
- lib/chefspec/coveragereports/version.rb
|
102
|
+
- lib/chefspec/coveragereports.rb
|
103
|
+
- templates/json.erb
|
104
|
+
- LICENSE.txt
|
105
|
+
- README.md
|
106
|
+
homepage: https://github.com/aspring/chefspec-coveragereports
|
107
|
+
licenses:
|
108
|
+
- MIT
|
109
|
+
post_install_message:
|
110
|
+
rdoc_options: []
|
111
|
+
require_paths:
|
112
|
+
- lib
|
113
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
114
|
+
none: false
|
115
|
+
requirements:
|
116
|
+
- - ! '>='
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: '0'
|
119
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
120
|
+
none: false
|
121
|
+
requirements:
|
122
|
+
- - ! '>='
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
requirements: []
|
126
|
+
rubyforge_project:
|
127
|
+
rubygems_version: 1.8.23.2
|
128
|
+
signing_key:
|
129
|
+
specification_version: 3
|
130
|
+
summary: ChefSpec Coverage Reports
|
131
|
+
test_files: []
|
132
|
+
has_rdoc:
|
metadata.gz.sig
ADDED
Binary file
|