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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 293537ff9297d5f5aa840aee43fcc4f80e01f6f386117211887be7f643b3c311
4
- data.tar.gz: 05d17ad02efabffa178b7ca1f414bdfe131b3f4a28c62d272359f4bcf3f8e4dc
3
+ metadata.gz: 074f86971202b3cb656203277d3032b669b36bd62fe6938633e57b0c50e6a151
4
+ data.tar.gz: 0c8660a5997eba0e6bb17b8b2c444bae52100c5bff099c90246637e9a9fb005d
5
5
  SHA512:
6
- metadata.gz: 555c67956799e0fd4284360938c64d41c3aea1b829306ef2e5d0a7308134694ccaa3250e591dd953ab8e816f4f62dcb53e49ddc120777ce92239ea1f47f4369a
7
- data.tar.gz: fe81e8fc2256a7b1792eb13719f6958a1a67198ed4082cf1f2821cf7f19f3f5f17875620b7aa6446ced775b0956806e38823faa599655f787e5f47c5ba724f35
6
+ metadata.gz: 6ce75ffbfe041e4f86b5e685fd0e7b8c2c5b58e7ece2095fc526243d129ec20d09a3c875e1a33cd5b779e10cf8b770ba936ae563c5cb3cc26b540d63bada3636
7
+ data.tar.gz: 977016fc11910a04de1d690a23bd6bb44a6bcf4e74ef2384b1d1aca01c1da784c95f8f97973781e52c142e4a27868bc6b431dd5495a3876521bb056556c33074
data/.gitignore CHANGED
@@ -94,3 +94,6 @@ build-iPhoneSimulator/
94
94
  /pkg/
95
95
  /spec/reports/
96
96
  /tmp/
97
+
98
+ target_app/coverage.json
99
+ target_app/coverage/
@@ -1,3 +1,7 @@
1
+ ## 0.4.1
2
+
3
+ - Add SimplecovReporter
4
+
1
5
  ## 0.4.0
2
6
 
3
7
  - Provide options for checking bundle_path (#7)
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).
@@ -22,7 +22,14 @@ module OneshotCoverage
22
22
  OneshotLog = Struct.new(:path, :md5_hash, :lines)
23
23
 
24
24
  class Reporter
25
- def initialize(target_path:, logger:, emit_term: nil, cover_bundle_path: false)
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
- Coverage.result(clear: true, stop: false).
54
+ @coverage_module.result(clear: true, stop: false).
48
55
  select { |k, v| is_target?(k, v) }.
49
56
  map do |filepath, v|
50
- OneshotLog.new(relative_path(filepath), md5_hash_for(filepath), v[:oneshot_lines])
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 @bundler_path && filepath.start_with?(@bundler_path)
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(target_path:, logger: OneshotCoverage::Logger::NullLogger.new, emit_term: nil, cover_bundle_path: false)
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
@@ -1,3 +1,3 @@
1
1
  module OneshotCoverage
2
- VERSION = "0.4.0"
2
+ VERSION = "0.4.1"
3
3
  end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+
5
+ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
6
+
7
+ gem "minitest"
8
+ gem "simplecov"
@@ -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
@@ -0,0 +1,10 @@
1
+ class Adder
2
+ def initialize(a, b)
3
+ @a = a
4
+ @b = b
5
+ end
6
+
7
+ def call
8
+ @a + @b
9
+ end
10
+ end
@@ -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.0
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-05 00:00:00.000000000 Z
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