oneshot_coverage 0.4.0 → 0.4.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.
- checksums.yaml +4 -4
- data/.gitignore +3 -0
- data/{CHANGELOG → CHANGELOG.md} +4 -0
- data/README.md +22 -0
- data/lib/oneshot_coverage.rb +32 -5
- data/lib/oneshot_coverage/simplecov_reporter.rb +95 -0
- data/lib/oneshot_coverage/version.rb +1 -1
- data/target_app/Gemfile +8 -0
- data/target_app/Gemfile.lock +21 -0
- data/target_app/adder.rb +10 -0
- data/target_app/cover_code_test.rb +17 -0
- data/target_app/gen_simplecov_report.rb +10 -0
- metadata +9 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 074f86971202b3cb656203277d3032b669b36bd62fe6938633e57b0c50e6a151
|
4
|
+
data.tar.gz: 0c8660a5997eba0e6bb17b8b2c444bae52100c5bff099c90246637e9a9fb005d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6ce75ffbfe041e4f86b5e685fd0e7b8c2c5b58e7ece2095fc526243d129ec20d09a3c875e1a33cd5b779e10cf8b770ba936ae563c5cb3cc26b540d63bada3636
|
7
|
+
data.tar.gz: 977016fc11910a04de1d690a23bd6bb44a6bcf4e74ef2384b1d1aca01c1da784c95f8f97973781e52c142e4a27868bc6b431dd5495a3876521bb056556c33074
|
data/.gitignore
CHANGED
data/{CHANGELOG → CHANGELOG.md}
RENAMED
data/README.md
CHANGED
@@ -99,6 +99,28 @@ to emit via `at_exit`.
|
|
99
99
|
On the other hand, it's not, then you need to emit it manually
|
100
100
|
at proper timing(i.e. when batch finished)
|
101
101
|
|
102
|
+
### Generate report with simplecov
|
103
|
+
|
104
|
+
You can generate pretty report using simplecov(confirmed with 0.21.2). Here is some example:
|
105
|
+
|
106
|
+
```ruby
|
107
|
+
require 'simplecov'
|
108
|
+
require 'oneshot_coverage/simplecov_reporter'
|
109
|
+
|
110
|
+
OneshotCoverage::SimplecovReporter.new(
|
111
|
+
project_path: Dir.pwd, # target project path. Dir.pwd is default.
|
112
|
+
log_path: 'coverage.json', # oneshot coverage log generated by FileLogger or same scheme json file acceptable
|
113
|
+
file_filter: OneshotCoverage::SimplecovReporter::DefaultFilter # Object respond to #call with return true | false. this filter used for coverage target. file_filter.call(path) return false, then path will not be included to report. DefaultFilter is default, which exclude non-ruby file, files under /spec/, /test/, /script/, /config/
|
114
|
+
).run
|
115
|
+
```
|
116
|
+
|
117
|
+
This code generates html report under 'project_path/`coverage/`'
|
118
|
+
|
119
|
+
### Note
|
120
|
+
|
121
|
+
Note that `cover_bundle_path` only cover managed gem by bundler.
|
122
|
+
In the other words, the gem installed with `path` option, which bundler just load it, will not be included by this.
|
123
|
+
|
102
124
|
## License
|
103
125
|
|
104
126
|
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/lib/oneshot_coverage.rb
CHANGED
@@ -22,7 +22,14 @@ module OneshotCoverage
|
|
22
22
|
OneshotLog = Struct.new(:path, :md5_hash, :lines)
|
23
23
|
|
24
24
|
class Reporter
|
25
|
-
def initialize(
|
25
|
+
def initialize(
|
26
|
+
coverage_module:,
|
27
|
+
target_path:,
|
28
|
+
logger:,
|
29
|
+
emit_term: nil,
|
30
|
+
cover_bundle_path: false
|
31
|
+
)
|
32
|
+
@coverage_module = coverage_module
|
26
33
|
@target_path = target_path
|
27
34
|
@logger = logger
|
28
35
|
@emit_term = emit_term
|
@@ -44,10 +51,11 @@ module OneshotCoverage
|
|
44
51
|
end
|
45
52
|
|
46
53
|
logs =
|
47
|
-
|
54
|
+
@coverage_module.result(clear: true, stop: false).
|
48
55
|
select { |k, v| is_target?(k, v) }.
|
49
56
|
map do |filepath, v|
|
50
|
-
|
57
|
+
formatted_path = format_filepath(filepath)
|
58
|
+
OneshotLog.new(format_filepath(filepath), md5_hash_for(filepath), v[:oneshot_lines])
|
51
59
|
end
|
52
60
|
|
53
61
|
if logs.size > 0
|
@@ -70,11 +78,23 @@ module OneshotCoverage
|
|
70
78
|
|
71
79
|
def is_target?(filepath, value)
|
72
80
|
return false if value[:oneshot_lines].empty?
|
73
|
-
return @cover_bundle_path if
|
81
|
+
return @cover_bundle_path if from_bundler?(filepath)
|
74
82
|
return false if !filepath.start_with?(@target_path)
|
75
83
|
true
|
76
84
|
end
|
77
85
|
|
86
|
+
def from_bundler?(filepath)
|
87
|
+
@bundler_path && filepath.start_with?(@bundler_path)
|
88
|
+
end
|
89
|
+
|
90
|
+
def format_filepath(filepath)
|
91
|
+
if from_bundler?(filepath)
|
92
|
+
filepath
|
93
|
+
else
|
94
|
+
relative_path(filepath)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
78
98
|
def relative_path(filepath)
|
79
99
|
if filepath.include?(@target_path)
|
80
100
|
filepath[@target_path.size..-1]
|
@@ -111,8 +131,15 @@ module OneshotCoverage
|
|
111
131
|
@reporter&.emit(force_emit)
|
112
132
|
end
|
113
133
|
|
114
|
-
def configure(
|
134
|
+
def configure(
|
135
|
+
target_path:,
|
136
|
+
logger: OneshotCoverage::Logger::NullLogger.new,
|
137
|
+
coverage_module: Coverage,
|
138
|
+
emit_term: nil,
|
139
|
+
cover_bundle_path: false
|
140
|
+
)
|
115
141
|
@reporter = OneshotCoverage::Reporter.new(
|
142
|
+
coverage_module: coverage_module,
|
116
143
|
target_path: Pathname.new(target_path).cleanpath.to_s + "/",
|
117
144
|
logger: logger,
|
118
145
|
emit_term: emit_term,
|
@@ -0,0 +1,95 @@
|
|
1
|
+
require 'coverage'
|
2
|
+
require 'find'
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
module OneshotCoverage
|
6
|
+
class SimplecovReporter
|
7
|
+
module DefaultFilter
|
8
|
+
module_function def call(path)
|
9
|
+
return false unless File.extname(path) == '.rb'
|
10
|
+
return false if path.include?('/spec/')
|
11
|
+
return false if path.include?('/test/')
|
12
|
+
return false if path.include?('/script/')
|
13
|
+
return false if path.include?('/config/')
|
14
|
+
|
15
|
+
true
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# @option log_path [String] oneshot coverage log generated by FileLogger or same scheme json file acceptable
|
20
|
+
# @option project_path [String] target project path.
|
21
|
+
# @option file_filter [Object] Object respond to #call with return true | false. this filter used for coverage target. file_filter.call(path) return false, then path will not be included to report
|
22
|
+
def initialize(
|
23
|
+
log_path:,
|
24
|
+
project_path: Dir.pwd,
|
25
|
+
file_filter: DefaultFilter
|
26
|
+
)
|
27
|
+
@project_path = project_path.end_with?('/') ? project_path : "#{project_path}/"
|
28
|
+
@log_path = log_path
|
29
|
+
@file_filter = file_filter
|
30
|
+
end
|
31
|
+
|
32
|
+
def run
|
33
|
+
raise "Please install & require 'simplecov' if you want to use this" unless defined? SimpleCov
|
34
|
+
|
35
|
+
coverages = coverage_stubs
|
36
|
+
fill_lines(coverages)
|
37
|
+
gen_html(coverages)
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def coverage_candidates
|
43
|
+
@coverage_candidates ||=
|
44
|
+
Find.find(@project_path).
|
45
|
+
select { |fp| @file_filter.call(fp) }
|
46
|
+
# map { |fp| fp.sub(@project_path, '') }
|
47
|
+
end
|
48
|
+
|
49
|
+
def coverage_stubs
|
50
|
+
{}.tap do |stubs|
|
51
|
+
coverage_candidates.each do |filepath|
|
52
|
+
stub = Coverage.line_stub(filepath)
|
53
|
+
stubs[filepath] = stub
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def oneshot_coverage_logs
|
59
|
+
@oneshot_coverage_logs ||= begin
|
60
|
+
raise "#{@log_path} isn't exist!" unless File.exist?(@log_path)
|
61
|
+
|
62
|
+
JSON.parse(File.read(@log_path)).transform_keys do |filepath_with_md5_hash|
|
63
|
+
*path_tokens, _md5_hash = filepath_with_md5_hash.split('-')
|
64
|
+
"#{@project_path}#{path_tokens.join('-')}"
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def fill_lines(coverages)
|
70
|
+
oneshot_coverage_logs.each do |filepath, linenums|
|
71
|
+
linenums.each do |linenum|
|
72
|
+
coverages[filepath][linenum - 1] = 1
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def format_data(coverages)
|
78
|
+
coverages.transform_values do |lines|
|
79
|
+
{ "lines" => lines }
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def gen_html(coverages)
|
84
|
+
coverages_for_simcov = format_data(coverages)
|
85
|
+
SimpleCov.root(@project_path)
|
86
|
+
result = SimpleCov::Result.from_hash({
|
87
|
+
'oneshot' => {
|
88
|
+
'coverage' => coverages_for_simcov,
|
89
|
+
'timestamp' => Time.now.to_i
|
90
|
+
}
|
91
|
+
}).first
|
92
|
+
SimpleCov::Formatter::HTMLFormatter.new.format(result)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
data/target_app/Gemfile
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
GEM
|
2
|
+
remote: https://rubygems.org/
|
3
|
+
specs:
|
4
|
+
docile (1.4.0)
|
5
|
+
minitest (5.14.4)
|
6
|
+
simplecov (0.21.2)
|
7
|
+
docile (~> 1.1)
|
8
|
+
simplecov-html (~> 0.11)
|
9
|
+
simplecov_json_formatter (~> 0.1)
|
10
|
+
simplecov-html (0.12.3)
|
11
|
+
simplecov_json_formatter (0.1.3)
|
12
|
+
|
13
|
+
PLATFORMS
|
14
|
+
x86_64-darwin-20
|
15
|
+
|
16
|
+
DEPENDENCIES
|
17
|
+
minitest
|
18
|
+
simplecov
|
19
|
+
|
20
|
+
BUNDLED WITH
|
21
|
+
2.2.3
|
data/target_app/adder.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
$LOAD_PATH.unshift File.expand_path("../lib", __dir__)
|
2
|
+
require "oneshot_coverage"
|
3
|
+
require "oneshot_coverage/logger/file_logger"
|
4
|
+
|
5
|
+
OneshotCoverage.configure(
|
6
|
+
target_path: Dir.pwd,
|
7
|
+
logger: OneshotCoverage::Logger::FileLogger.new('coverage.json'),
|
8
|
+
emit_term: nil,
|
9
|
+
cover_bundle_path: ENV["COVER_BUNDLE_PATH"] == "1",
|
10
|
+
)
|
11
|
+
|
12
|
+
OneshotCoverage.start
|
13
|
+
|
14
|
+
require "minitest"
|
15
|
+
require_relative "adder"
|
16
|
+
|
17
|
+
Adder.new(1, 2).call
|
@@ -0,0 +1,10 @@
|
|
1
|
+
$LOAD_PATH.unshift File.expand_path("../lib", __dir__)
|
2
|
+
|
3
|
+
require 'simplecov'
|
4
|
+
require 'oneshot_coverage/simplecov_reporter'
|
5
|
+
|
6
|
+
OneshotCoverage::SimplecovReporter.new(
|
7
|
+
project_path: Dir.pwd,
|
8
|
+
log_path: 'coverage.json',
|
9
|
+
file_filter: OneshotCoverage::SimplecovReporter::DefaultFilter
|
10
|
+
).run
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: oneshot_coverage
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shia
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-07-
|
11
|
+
date: 2021-07-14 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: OneshotCoverage will help you to measure oneshot coverage on production
|
14
14
|
email:
|
@@ -19,7 +19,7 @@ extra_rdoc_files: []
|
|
19
19
|
files:
|
20
20
|
- ".github/workflows/main.yml"
|
21
21
|
- ".gitignore"
|
22
|
-
- CHANGELOG
|
22
|
+
- CHANGELOG.md
|
23
23
|
- CODE_OF_CONDUCT.md
|
24
24
|
- Gemfile
|
25
25
|
- LICENSE.txt
|
@@ -32,8 +32,14 @@ files:
|
|
32
32
|
- lib/oneshot_coverage/logger/null_logger.rb
|
33
33
|
- lib/oneshot_coverage/logger/stdout_logger.rb
|
34
34
|
- lib/oneshot_coverage/railtie.rb
|
35
|
+
- lib/oneshot_coverage/simplecov_reporter.rb
|
35
36
|
- lib/oneshot_coverage/version.rb
|
36
37
|
- oneshot_coverage.gemspec
|
38
|
+
- target_app/Gemfile
|
39
|
+
- target_app/Gemfile.lock
|
40
|
+
- target_app/adder.rb
|
41
|
+
- target_app/cover_code_test.rb
|
42
|
+
- target_app/gen_simplecov_report.rb
|
37
43
|
homepage: https://github.com/riseshia/oneshot_coverage
|
38
44
|
licenses:
|
39
45
|
- MIT
|