simplecov 0.20.0 → 0.21.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.
@@ -19,81 +19,130 @@ module SimpleCov
19
19
  File.join(SimpleCov.coverage_path, ".resultset.json.lock")
20
20
  end
21
21
 
22
- # Loads the cached resultset from JSON and returns it as a Hash,
23
- # caching it for subsequent accesses.
24
- def resultset
25
- @resultset ||= begin
26
- data = stored_data
27
- if data
28
- begin
29
- JSON.parse(data) || {}
30
- rescue StandardError
31
- {}
32
- end
33
- else
34
- {}
35
- end
22
+ def merge_and_store(*file_paths, ignore_timeout: false)
23
+ result = merge_results(*file_paths, ignore_timeout: ignore_timeout)
24
+ store_result(result) if result
25
+ result
26
+ end
27
+
28
+ def merge_results(*file_paths, ignore_timeout: false)
29
+ # It is intentional here that files are only read in and parsed one at a time.
30
+ #
31
+ # In big CI setups you might deal with 100s of CI jobs and each one producing Megabytes
32
+ # of data. Reading them all in easily produces Gigabytes of memory consumption which
33
+ # we want to avoid.
34
+ #
35
+ # For similar reasons a SimpleCov::Result is only created in the end as that'd create
36
+ # even more data especially when it also reads in all source files.
37
+ initial_memo = valid_results(file_paths.shift, ignore_timeout: ignore_timeout)
38
+
39
+ command_names, coverage = file_paths.reduce(initial_memo) do |memo, file_path|
40
+ merge_coverage(memo, valid_results(file_path, ignore_timeout: ignore_timeout))
36
41
  end
42
+
43
+ create_result(command_names, coverage)
37
44
  end
38
45
 
39
- # Returns the contents of the resultset cache as a string or if the file is missing or empty nil
40
- def stored_data
41
- synchronize_resultset do
42
- return unless File.exist?(resultset_path)
46
+ def valid_results(file_path, ignore_timeout: false)
47
+ results = parse_file(file_path)
48
+ merge_valid_results(results, ignore_timeout: ignore_timeout)
49
+ end
50
+
51
+ def parse_file(path)
52
+ data = read_file(path)
53
+ parse_json(data)
54
+ end
43
55
 
44
- data = File.read(resultset_path)
45
- return if data.nil? || data.length < 2
56
+ def read_file(path)
57
+ return unless File.exist?(path)
46
58
 
47
- data
59
+ data = File.read(path)
60
+ return if data.nil? || data.length < 2
61
+
62
+ data
63
+ end
64
+
65
+ def parse_json(content)
66
+ return {} unless content
67
+
68
+ JSON.parse(content) || {}
69
+ rescue StandardError
70
+ warn "[SimpleCov]: Warning! Parsing JSON content of resultset file failed"
71
+ {}
72
+ end
73
+
74
+ def merge_valid_results(results, ignore_timeout: false)
75
+ results = results.select { |_command_name, data| within_merge_timeout?(data) } unless ignore_timeout
76
+
77
+ command_plus_coverage = results.map do |command_name, data|
78
+ [[command_name], adapt_result(data.fetch("coverage"))]
48
79
  end
80
+
81
+ # one file itself _might_ include multiple test runs
82
+ merge_coverage(*command_plus_coverage)
49
83
  end
50
84
 
51
- # Gets the resultset hash and re-creates all included instances
52
- # of SimpleCov::Result from that.
53
- # All results that are above the SimpleCov.merge_timeout will be
54
- # dropped. Returns an array of SimpleCov::Result items.
55
- def results
56
- results = Result.from_hash(resultset)
57
- results.select { |result| result.time_since_creation < SimpleCov.merge_timeout }
85
+ def within_merge_timeout?(data)
86
+ time_since_result_creation(data) < SimpleCov.merge_timeout
58
87
  end
59
88
 
60
- def merge_and_store(*results)
61
- result = merge_results(*results)
62
- store_result(result) if result
63
- result
89
+ def time_since_result_creation(data)
90
+ Time.now - Time.at(data.fetch("timestamp"))
64
91
  end
65
92
 
66
- # Merge two or more SimpleCov::Results into a new one with merged
67
- # coverage data and the command_name for the result consisting of a join
68
- # on all source result's names
69
- def merge_results(*results)
70
- parsed_results = JSON.parse(JSON.dump(results.map(&:original_result)))
71
- combined_result = SimpleCov::Combine::ResultsCombiner.combine(*parsed_results)
72
- result = SimpleCov::Result.new(combined_result)
73
- # Specify the command name
74
- result.command_name = results.map(&:command_name).sort.join(", ")
75
- result
93
+ def create_result(command_names, coverage)
94
+ return nil unless coverage
95
+
96
+ command_name = command_names.reject(&:empty?).sort.join(", ")
97
+ SimpleCov::Result.new(coverage, command_name: command_name)
98
+ end
99
+
100
+ def merge_coverage(*results)
101
+ return [[""], nil] if results.empty?
102
+ return results.first if results.size == 1
103
+
104
+ results.reduce do |(memo_command, memo_coverage), (command, coverage)|
105
+ # timestamp is dropped here, which is intentional (we merge it, it gets a new time stamp as of now)
106
+ merged_coverage = Combine.combine(Combine::ResultsCombiner, memo_coverage, coverage)
107
+ merged_command = memo_command + command
108
+
109
+ [merged_command, merged_coverage]
110
+ end
76
111
  end
77
112
 
78
113
  #
79
- # Gets all SimpleCov::Results from cache, merges them and produces a new
114
+ # Gets all SimpleCov::Results stored in resultset, merges them and produces a new
80
115
  # SimpleCov::Result with merged coverage data and the command_name
81
116
  # for the result consisting of a join on all source result's names
82
- #
83
117
  def merged_result
84
- merge_results(*results)
118
+ # conceptually this is just doing `merge_results(resultset_path)`
119
+ # it's more involved to make syre `synchronize_resultset` is only used around reading
120
+ resultset_hash = read_resultset
121
+ command_names, coverage = merge_valid_results(resultset_hash)
122
+
123
+ create_result(command_names, coverage)
124
+ end
125
+
126
+ def read_resultset
127
+ resultset_content =
128
+ synchronize_resultset do
129
+ read_file(resultset_path)
130
+ end
131
+
132
+ parse_json(resultset_content)
85
133
  end
86
134
 
87
135
  # Saves the given SimpleCov::Result in the resultset cache
88
136
  def store_result(result)
89
137
  synchronize_resultset do
90
138
  # Ensure we have the latest, in case it was already cached
91
- clear_resultset
92
- new_set = resultset
139
+ new_resultset = read_resultset
140
+
141
+ # A single result only ever has one command_name, see `SimpleCov::Result#to_hash`
93
142
  command_name, data = result.to_hash.first
94
- new_set[command_name] = data
143
+ new_resultset[command_name] = data
95
144
  File.open(resultset_path, "w+") do |f_|
96
- f_.puts JSON.pretty_generate(new_set)
145
+ f_.puts JSON.pretty_generate(new_resultset)
97
146
  end
98
147
  end
99
148
  true
@@ -116,9 +165,29 @@ module SimpleCov
116
165
  end
117
166
  end
118
167
 
119
- # Clear out the previously cached .resultset
120
- def clear_resultset
121
- @resultset = nil
168
+ # We changed the format of the raw result data in simplecov, as people are likely
169
+ # to have "old" resultsets lying around (but not too old so that they're still
170
+ # considered we can adapt them).
171
+ # See https://github.com/simplecov-ruby/simplecov/pull/824#issuecomment-576049747
172
+ def adapt_result(result)
173
+ if pre_simplecov_0_18_result?(result)
174
+ adapt_pre_simplecov_0_18_result(result)
175
+ else
176
+ result
177
+ end
178
+ end
179
+
180
+ # pre 0.18 coverage data pointed from file directly to an array of line coverage
181
+ def pre_simplecov_0_18_result?(result)
182
+ _key, data = result.first
183
+
184
+ data.is_a?(Array)
185
+ end
186
+
187
+ def adapt_pre_simplecov_0_18_result(result)
188
+ result.transform_values do |line_coverage_data|
189
+ {"lines" => line_coverage_data}
190
+ end
122
191
  end
123
192
  end
124
193
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module SimpleCov
4
- VERSION = "0.20.0"
4
+ VERSION = "0.21.1"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: simplecov
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.20.0
4
+ version: 0.21.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Christoph Olszowka
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2020-11-29 00:00:00.000000000 Z
12
+ date: 2021-01-04 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: docile
@@ -63,9 +63,6 @@ extensions: []
63
63
  extra_rdoc_files: []
64
64
  files:
65
65
  - CHANGELOG.md
66
- - CODE_OF_CONDUCT.md
67
- - CONTRIBUTING.md
68
- - ISSUE_TEMPLATE.md
69
66
  - LICENSE
70
67
  - README.md
71
68
  - doc/alternate-formatters.md
@@ -119,9 +116,9 @@ licenses:
119
116
  metadata:
120
117
  bug_tracker_uri: https://github.com/simplecov-ruby/simplecov/issues
121
118
  changelog_uri: https://github.com/simplecov-ruby/simplecov/blob/main/CHANGELOG.md
122
- documentation_uri: https://www.rubydoc.info/gems/simplecov/0.20.0
119
+ documentation_uri: https://www.rubydoc.info/gems/simplecov/0.21.1
123
120
  mailing_list_uri: https://groups.google.com/forum/#!forum/simplecov
124
- source_code_uri: https://github.com/simplecov-ruby/simplecov/tree/v0.20.0
121
+ source_code_uri: https://github.com/simplecov-ruby/simplecov/tree/v0.21.1
125
122
  post_install_message:
126
123
  rdoc_options: []
127
124
  require_paths:
@@ -137,7 +134,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
137
134
  - !ruby/object:Gem::Version
138
135
  version: '0'
139
136
  requirements: []
140
- rubygems_version: 3.1.2
137
+ rubygems_version: 3.2.3
141
138
  signing_key:
142
139
  specification_version: 4
143
140
  summary: Code coverage for Ruby
@@ -1,76 +0,0 @@
1
- # SimpleCov Code of Conduct
2
-
3
- ## Our Pledge
4
-
5
- In the interest of fostering an open and welcoming environment, we as
6
- contributors and maintainers pledge to making participation in our project and
7
- our community a harassment-free experience for everyone, regardless of age, body
8
- size, disability, ethnicity, sex characteristics, gender identity and expression,
9
- level of experience, education, socio-economic status, nationality, personal
10
- appearance, race, religion, or sexual identity and orientation.
11
-
12
- ## Our Standards
13
-
14
- Examples of behavior that contributes to creating a positive environment
15
- include:
16
-
17
- * Using welcoming and inclusive language
18
- * Being respectful of differing viewpoints and experiences
19
- * Gracefully accepting constructive criticism
20
- * Focusing on what is best for the community
21
- * Showing empathy towards other community members
22
-
23
- Examples of unacceptable behavior by participants include:
24
-
25
- * The use of sexualized language or imagery and unwelcome sexual attention or
26
- advances
27
- * Trolling, insulting/derogatory comments, and personal or political attacks
28
- * Public or private harassment
29
- * Publishing others' private information, such as a physical or electronic
30
- address, without explicit permission
31
- * Other conduct which could reasonably be considered inappropriate in a
32
- professional setting
33
-
34
- ## Our Responsibilities
35
-
36
- Project maintainers are responsible for clarifying the standards of acceptable
37
- behavior and are expected to take appropriate and fair corrective action in
38
- response to any instances of unacceptable behavior.
39
-
40
- Project maintainers have the right and responsibility to remove, edit, or
41
- reject comments, commits, code, wiki edits, issues, and other contributions
42
- that are not aligned to this Code of Conduct, or to ban temporarily or
43
- permanently any contributor for other behaviors that they deem inappropriate,
44
- threatening, offensive, or harmful.
45
-
46
- ## Scope
47
-
48
- This Code of Conduct applies both within project spaces and in public spaces
49
- when an individual is representing the project or its community. Examples of
50
- representing a project or community include using an official project e-mail
51
- address, posting via an official social media account, or acting as an appointed
52
- representative at an online or offline event. Representation of a project may be
53
- further defined and clarified by project maintainers.
54
-
55
- ## Enforcement
56
-
57
- Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
- reported by contacting the project team at simplecov.team@gmail.com. All
59
- complaints will be reviewed and investigated and will result in a response that
60
- is deemed necessary and appropriate to the circumstances. The project team is
61
- obligated to maintain confidentiality with regard to the reporter of an incident.
62
- Further details of specific enforcement policies may be posted separately.
63
-
64
- Project maintainers who do not follow or enforce the Code of Conduct in good
65
- faith may face temporary or permanent repercussions as determined by other
66
- members of the project's leadership.
67
-
68
- ## Attribution
69
-
70
- This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
- available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
72
-
73
- [homepage]: https://www.contributor-covenant.org
74
-
75
- For answers to common questions about this code of conduct, see
76
- https://www.contributor-covenant.org/faq
@@ -1,51 +0,0 @@
1
- ## Reporting Issues
2
-
3
- You can report issues at https://github.com/simplecov-ruby/simplecov/issues
4
-
5
- Before you go ahead please search existing issues for your problem, chances are someone else already reported it.
6
-
7
- To make sure that we can help you quickly please include and check the following information:
8
-
9
- * Include how you run your tests and which testing framework or frameworks you are running.
10
- - please ensure you are requiring and starting SimpleCov before requiring any application code.
11
- - If running via rake, please ensure you are requiring SimpleCov at the top of your Rakefile
12
- For example, if running via RSpec, this would be at the top of your spec_helper.
13
- - Have you tried using a [`.simplecov` file](https://github.com/simplecov-ruby/simplecov#using-simplecov-for-centralized-config)?
14
- * Include the SimpleCov version you are running in your report.
15
- * If you are not running the latest version (please check), and you cannot update it,
16
- please specify in your report why you can't update to the latest version.
17
- * Include your `ruby -e "puts RUBY_DESCRIPTION"`.
18
- * Please also specify the gem versions of Rails (if applicable).
19
- * Include any other coverage gems you may be using and their versions.
20
-
21
- Include as much sample code as you can to help us reproduce the issue. (Inline, repo link, or gist, are fine. A failing test would help the most.)
22
-
23
- This is extremely important for narrowing down the cause of your problem.
24
-
25
- Thanks!
26
-
27
- ## Making Contributions
28
-
29
- To fetch & test the library for development, do:
30
-
31
- $ git clone https://github.com/simplecov-ruby/simplecov.git
32
- $ cd simplecov
33
- $ bundle
34
- $ bundle exec rake
35
-
36
- If you want to contribute, please:
37
-
38
- * Fork the project.
39
- * Make your feature addition or bug fix.
40
- * Add tests for it. This is important so I don't break it in a future version unintentionally.
41
- * **Bonus Points** go out to anyone who also updates `CHANGELOG.md` :)
42
- * Send me a pull request on GitHub.
43
-
44
- ## Running Individual Tests
45
-
46
- This project uses RSpec and Cucumber. Individual tests can be run like this:
47
-
48
- ```bash
49
- bundle exec rspec path/to/test.rb
50
- bundle exec cucumber path/to/test.feature
51
- ```
@@ -1,23 +0,0 @@
1
- Howdy! Thanks for reporting an issue <3
2
-
3
- Before you go ahead please search existing issues for your problem, chances are someone else already reported it.
4
-
5
- To make sure that we can help you quickly please include and check the following information:
6
-
7
- * Include how you run your tests and which testing framework or frameworks you are running.
8
- - please ensure you are requiring and starting SimpleCov before requiring any application code.
9
- - If running via rake, please ensure you are requiring SimpleCov at the top of your Rakefile
10
- For example, if running via RSpec, this would be at the top of your spec_helper.
11
- - Have you tried using a [`.simplecov` file](https://github.com/simplecov-ruby/simplecov#using-simplecov-for-centralized-config)?
12
- * Include the SimpleCov version you are running in your report.
13
- * If you are not running the latest version (please check), and you cannot update it,
14
- please specify in your report why you can't update to the latest version.
15
- * Include your `ruby -e "puts RUBY_DESCRIPTION"`.
16
- * Please also specify the gem versions of Rails (if applicable).
17
- * Include any other coverage gems you may be using and their versions.
18
-
19
- Include as much sample code as you can to help us reproduce the issue. (Inline, repo link, or gist, are fine. A failing test would help the most.)
20
-
21
- This is extremely important for narrowing down the cause of your problem.
22
-
23
- Thanks!