oneshot_coverage 0.4.0 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
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