simplecov-0.18.1/ 0000755 0000041 0000041 00000000000 13617303170 013633 5 ustar www-data www-data simplecov-0.18.1/README.md 0000644 0000041 0000041 00000074164 13617303170 015126 0 ustar www-data www-data SimpleCov [](https://badge.fury.io/rb/simplecov) [][Continuous Integration] [](https://codeclimate.com/github/colszowka/simplecov) [](http://inch-ci.org/github/colszowka/simplecov)
=========
**Code coverage for Ruby**
* [Source Code]
* [API documentation]
* [Changelog]
* [Rubygem]
* [Continuous Integration]
[Coverage]: https://ruby-doc.org/stdlib/libdoc/coverage/rdoc/Coverage.html "API doc for Ruby's Coverage library"
[Source Code]: https://github.com/colszowka/simplecov "Source Code @ GitHub"
[API documentation]: http://rubydoc.info/gems/simplecov/frames "RDoc API Documentation at Rubydoc.info"
[Configuration]: http://rubydoc.info/gems/simplecov/SimpleCov/Configuration "Configuration options API documentation"
[Changelog]: https://github.com/colszowka/simplecov/blob/master/CHANGELOG.md "Project Changelog"
[Rubygem]: http://rubygems.org/gems/simplecov "SimpleCov @ rubygems.org"
[Continuous Integration]: https://github.com/colszowka/simplecov/actions?query=workflow%3Astable "SimpleCov is built around the clock by github.com"
[Dependencies]: https://gemnasium.com/colszowka/simplecov "SimpleCov dependencies on Gemnasium"
[simplecov-html]: https://github.com/colszowka/simplecov-html "SimpleCov HTML Formatter Source Code @ GitHub"
SimpleCov is a code coverage analysis tool for Ruby. It uses [Ruby's built-in Coverage][Coverage] library to gather code
coverage data, but makes processing its results much easier by providing a clean API to filter, group, merge, format,
and display those results, giving you a complete code coverage suite that can be set up with just a couple lines of
code.
SimpleCov/Coverage track covered ruby code, gathering coverage for common templating solutions like erb, slim and haml is not supported.
In most cases, you'll want overall coverage results for your projects, including all types of tests, Cucumber features,
etc. SimpleCov automatically takes care of this by caching and merging results when generating reports, so your
report actually includes coverage across your test suites and thereby gives you a better picture of blank spots.
The official formatter of SimpleCov is packaged as a separate gem called [simplecov-html], but will be installed and
configured automatically when you launch SimpleCov. If you're curious, you can find it [on GitHub, too][simplecov-html].
## Contact
*Code and Bug Reports*
* [Issue Tracker](https://github.com/colszowka/simplecov/issues)
* See [CONTRIBUTING](https://github.com/colszowka/simplecov/blob/master/CONTRIBUTING.md) for how to contribute along
with some common problems to check out before creating an issue.
*Questions, Problems, Suggestions, etc.*
* [Mailing List](https://groups.google.com/forum/#!forum/simplecov) "Open mailing list for discussion and announcements
on Google Groups"
Getting started
---------------
1. Add SimpleCov to your `Gemfile` and `bundle install`:
```ruby
gem 'simplecov', require: false, group: :test
```
2. Load and launch SimpleCov **at the very top** of your `test/test_helper.rb`
(*or `spec_helper.rb`, `rails_helper`, cucumber `env.rb`, or whatever your preferred test
framework uses*):
```ruby
require 'simplecov'
SimpleCov.start
# Previous content of test helper now starts here
```
**Note:** If SimpleCov starts after your application code is already loaded
(via `require`), it won't be able to track your files and their coverage!
The `SimpleCov.start` **must** be issued **before any of your application
code is required!**
SimpleCov must be running in the process that you want the code coverage
analysis to happen on. When testing a server process (e.g. a JSON API
endpoint) via a separate test process (e.g. when using Selenium) where you
want to see all code executed by the `rails server`, and not just code
executed in your actual test files, you'll want to add something like this
to the top of `bin/rails`, but below the "shebang" line (`#! /usr/bin/env
ruby`):
```ruby
if ENV['RAILS_ENV'] == 'test'
require 'simplecov'
SimpleCov.start 'rails'
puts "required simplecov"
end
```
3. Run your full test suite to see the percent coverage that your application has.
4. After running your tests, open `coverage/index.html` in the browser of your choice. For example, in a Mac Terminal,
run the following command from your application's root directory:
```
open coverage/index.html
```
in a debian/ubuntu Terminal,
```
xdg-open coverage/index.html
```
**Note:** [This guide](https://dwheeler.com/essays/open-files-urls.html) can help if you're unsure which command your particular
operating system requires.
5. Add the following to your `.gitignore` file to ensure that coverage results
are not tracked by Git (optional):
```
echo "coverage" >> .gitignore
```
Or if you use Windows:
```
echo coverage >> .gitignore
```
If you're making a Rails application, SimpleCov comes with built-in configurations (see below for information on
profiles) that will get you started with groups for your Controllers, Models and Helpers. To use it, the
first two lines of your test_helper should be like this:
```ruby
require 'simplecov'
SimpleCov.start 'rails'
```
## Example output
**Coverage results report, fully browsable locally with sorting and much more:**

**Source file coverage details view:**

## Use it with any framework!
Similarly to the usage with Test::Unit described above, the only thing you have to do is to add the SimpleCov
config to the very top of your Cucumber/RSpec/whatever setup file.
Add the setup code to the **top** of `features/support/env.rb` (for Cucumber) or `spec/spec_helper.rb` (for RSpec).
Other test frameworks should work accordingly, whatever their setup file may be:
```ruby
require 'simplecov'
SimpleCov.start 'rails'
```
You could even track what kind of code your UI testers are touching if you want to go overboard with things. SimpleCov
does not care what kind of framework it is running in; it just looks at what code is being executed and generates a
report about it.
### Notes on specific frameworks and test utilities
For some frameworks and testing tools there are quirks and problems you might want to know about if you want
to use SimpleCov with them. Here's an overview of the known ones:
Framework | Notes | Issue |
parallel_tests
|
As of 0.8.0, SimpleCov should correctly recognize parallel_tests and
supplement your test suite names with their corresponding test env
numbers. SimpleCov locks the resultset cache while merging, ensuring no
race conditions occur when results are merged.
|
#64 &
#185
|
knapsack_pro
|
To make SimpleCov work with Knapsack Pro Queue Mode to split tests in parallel on CI jobs you need to provide CI node index number to the SimpleCov.command_name in KnapsackPro::Hooks::Queue.before_queue hook.
|
Tip
|
RubyMine
|
The RubyMine IDE has
built-in support for SimpleCov's coverage reports, though you might need
to explicitly set the output root using `SimpleCov.root('foo/bar/baz')`
|
#95
|
Spork
|
Because of how Spork works internally (using preforking), there used to
be trouble when using SimpleCov with it, but that has apparently been
resolved with a specific configuration strategy. See this
comment.
|
#42
|
Spring
|
See section below.
|
#381
|
Test/Unit
|
Test Unit 2 used to mess with ARGV, leading to a failure to detect the
test process name in SimpleCov. test-unit releases 2.4.3+
(Dec 11th, 2011) should have this problem resolved.
|
#45 &
test-unit/test-unit#12
|
## Configuring SimpleCov
[Configuration] settings can be applied in three formats, which are completely equivalent:
* The most common way is to configure it directly in your start block:
```ruby
SimpleCov.start do
some_config_option 'foo'
end
```
* You can also set all configuration options directly:
```ruby
SimpleCov.some_config_option 'foo'
```
* If you do not want to start coverage immediately after launch or want to add additional configuration later on in a
concise way, use:
```ruby
SimpleCov.configure do
some_config_option 'foo'
end
```
Please check out the [Configuration] API documentation to find out what you can customize.
## Using .simplecov for centralized config
If you use SimpleCov to merge multiple test suite results (e.g. Test/Unit and Cucumber) into a single report, you'd
normally have to set up all your config options twice, once in `test_helper.rb` and once in `env.rb`.
To avoid this, you can place a file called `.simplecov` in your project root. You can then just leave the
`require 'simplecov'` in each test setup helper (**at the top**) and move the `SimpleCov.start` code with all your
custom config options into `.simplecov`:
```ruby
# test/test_helper.rb
require 'simplecov'
# features/support/env.rb
require 'simplecov'
# .simplecov
SimpleCov.start 'rails' do
# any custom configs like groups and filters can be here at a central place
end
```
Using `.simplecov` rather than separately requiring SimpleCov multiple times is recommended if you are merging multiple
test frameworks like Cucumber and RSpec that rely on each other, as invoking SimpleCov multiple times can cause coverage
information to be lost.
## Branch coverage (ruby "~> 2.5")
Add branch coverage measurement statistics to your results. Supported in CRuby versions 2.5+.
```ruby
# or in configure or just SimpleCov.enable_coverage :branch
SimpleCov.start do
enable_coverage :branch
end
```
Branch coverage is a feature introduced in Ruby 2.5 concerning itself with whether a
particular branch of a condition had been executed. Line coverage on the other hand
is only interested in whether a line of code has been executed.
This comes in handy for instance for one line conditionals:
```ruby
number.odd? ? "odd" : "even"
```
In line coverage this line would always be marked as executed but you'd never know if both
conditions were met. Guard clauses have a similar story:
```ruby
return if number.odd?
# more code
```
If all the code in that method was covered you'd never know if the guard clause was ever
triggered! With line coverage as just evaluating the condition marks it as covered.
In the HTML report the lines of code will be annotated like `branch_type: hit_count`:
* `then: 2` - the then branch (of an `if`) was executed twice
* `else: 0` - the else branch (of an `if` or `case`) was never executed
Not that even if you don't declare an `else` branch it will still show up in the coverage
reports meaning that the condition of the `if` was not hit or that no `when` of `case`
was hit during the test runs.
**Is branch coverage strictly better?** No. Branch coverage really only concerns itself with
conditionals - meaning coverage of sequential code is of no interest to it. A file without
conditional logic will have no branch coverage data and SimpleCov will report 0 of 0
branches covered as 100% (as everything that can be covered was covered).
Hence, we recommend looking at both metrics together. Branch coverage might also be a good
overall metric to look at - while you might be missing only 10% of your lines that might
account for 50% of your branches for instance.
## Filters
Filters can be used to remove selected files from your coverage data. By default, a filter is applied that removes all
files OUTSIDE of your project's root directory - otherwise you'd end up with billions of coverage reports for source
files in the gems you are using.
You can define your own to remove things like configuration files, tests or whatever you don't need in your coverage
report.
### Defining custom filters
You can currently define a filter using either a String or Regexp (that will then be Regexp-matched against each source
file's path), a block or by passing in your own Filter class.
#### String filter
```ruby
SimpleCov.start do
add_filter "/test/"
end
```
This simple string filter will remove all files that match "/test/" in their path.
#### Regex filter
```ruby
SimpleCov.start do
add_filter %r{^/test/}
end
```
This simple regex filter will remove all files that start with /test/ in their path.
#### Block filter
```ruby
SimpleCov.start do
add_filter do |source_file|
source_file.lines.count < 5
end
end
```
Block filters receive a SimpleCov::SourceFile instance and expect your block to return either true (if the file is to be
removed from the result) or false (if the result should be kept). Please check out the RDoc for SimpleCov::SourceFile to
learn about the methods available to you. In the above example, the filter will remove all files that have less than 5
lines of code.
#### Custom filter class
```ruby
class LineFilter < SimpleCov::Filter
def matches?(source_file)
source_file.lines.count < filter_argument
end
end
SimpleCov.add_filter LineFilter.new(5)
```
Defining your own filters is pretty easy: Just inherit from SimpleCov::Filter and define a method
'matches?(source_file)'. When running the filter, a true return value from this method will result in the removal of the
given source_file. The filter_argument method is being set in the SimpleCov::Filter initialize method and thus is set to
5 in this example.
#### Array filter
```ruby
SimpleCov.start do
proc = Proc.new { |source_file| false }
add_filter ["string", /regex/, proc, LineFilter.new(5)]
end
```
You can pass in an array containing any of the other filter types.
#### Ignoring/skipping code
You can exclude code from the coverage report by wrapping it in `# :nocov:`.
```ruby
# :nocov:
def skip_this_method
never_reached
end
# :nocov:
```
The name of the token can be changed to your liking. [Learn more about the nocov feature.]( https://github.com/colszowka/simplecov/blob/master/features/config_nocov_token.feature)
**Note:** You shouldn't have to use the nocov token to skip private methods that are being included in your coverage. If
you appropriately test the public interface of your classes and objects you should automatically get full coverage of
your private methods.
## Default root filter and coverage for things outside of it
By default, SimpleCov filters everything outside of the `SimpleCov.root` directory. However, sometimes you may want
to include coverage reports for things you include as a gem, for example a Rails Engine.
Here's an example by [@lsaffie](https://github.com/lsaffie) from [#221](https://github.com/colszowka/simplecov/issues/221)
that shows how you can achieve just that:
```ruby
SimpleCov.start :rails do
filters.clear # This will remove the :root_filter and :bundler_filter that come via simplecov's defaults
add_filter do |src|
!(src.filename =~ /^#{SimpleCov.root}/) unless src.filename =~ /my_engine/
end
end
```
## Groups
You can separate your source files into groups. For example, in a Rails app, you'll want to have separate listings for
Models, Controllers, Helpers, and Libs. Group definition works similarly to Filters (and also accepts custom
filter classes), but source files end up in a group when the filter passes (returns true), as opposed to filtering
results, which exclude files from results when the filter results in a true value.
Add your groups with:
```ruby
SimpleCov.start do
add_group "Models", "app/models"
add_group "Controllers", "app/controllers"
add_group "Long files" do |src_file|
src_file.lines.count > 100
end
add_group "Multiple Files", ["app/models", "app/controllers"] # You can also pass in an array
add_group "Short files", LineFilter.new(5) # Using the LineFilter class defined in Filters section above
end
```
## Merging results
You normally want to have your coverage analyzed across ALL of your test suites, right?
Simplecov automatically caches coverage results in your
(coverage_path)/.resultset.json, and will merge or override those with
subsequent runs, depending on whether simplecov considers those subsequent runs
as different test suites or as the same test suite as the cached results. To
make this distinction, simplecov has the concept of "test suite names".
### Test suite names
SimpleCov tries to guess the name of the currently running test suite based upon the shell command the tests
are running on. This should work fine for Unit Tests, RSpec, and Cucumber. If it fails, it will use the shell
command that invoked the test suite as a command name.
If you have some non-standard setup and still want nicely labeled test suites, you have to give Simplecov a
cue as to what the name of the currently running test suite is. You can do so by specifying
`SimpleCov.command_name` in one test file that is part of your specific suite.
To customize the suite names on a Rails app (yeah, sorry for being Rails-biased, but everyone knows what
the structure of those projects is. You can apply this accordingly to the RSpecs in your
Outlook-WebDAV-Calendar-Sync gem), you could do something like this:
```ruby
# test/unit/some_test.rb
SimpleCov.command_name 'test:units'
# test/functionals/some_controller_test.rb
SimpleCov.command_name "test:functionals"
# test/integration/some_integration_test.rb
SimpleCov.command_name "test:integration"
# features/support/env.rb
SimpleCov.command_name "features"
```
Note that this only has to be invoked ONCE PER TEST SUITE, so even if you have 200 unit test files,
specifying it in `some_test.rb` is enough.
Last but not least **if multiple suites resolve to the same `command_name`** be aware that the coverage results **will
clobber each other instead of being merged**. SimpleCov is smart enough to detect unique names for the most common
setups, but if you have more than one test suite that doesn't follow a common pattern then you will want to manually
ensure that each suite gets a unique `command_name`.
If you are running tests in parallel each process has the potential to clobber results from the other test processes.
If you are relying on the default `command_name` then SimpleCov will attempt to detect and avoid parallel test suite
`command_name` collisions based on the presence of `ENV['PARALLEL_TEST_GROUPS']` and `ENV['TEST_ENV_NUMBER']`. If your
parallel test runner does not set one or both of these then *you must* set a `command_name` and ensure that it is unique
per process (eg. `command_name "Unit Tests PID #{$$}"`).
If you are using parallel_tests, you must incorporate `TEST_ENV_NUMBER` into the command name yourself, in
order for SimpleCov to merge the results correctly. For example:
```ruby
# spec/spec_helper.rb
SimpleCov.command_name "features" + (ENV['TEST_ENV_NUMBER'] || '')
```
[simplecov-html] prints the used test suites in the footer of the generated coverage report.
### Merging test runs under the same execution environment
Test results are automatically merged with previous runs in the same execution
environment when generating the result, so when coverage is set up properly for
Cucumber and your unit / functional / integration tests, all of those test
suites will be taken into account when building the coverage report.
#### Timeout for merge
Of course, your cached coverage data is likely to become invalid at some point. Thus, when automatically merging
subsequent test runs, result sets that are older than `SimpleCov.merge_timeout` will not be used any more. By default,
the timeout is 600 seconds (10 minutes), and you can raise (or lower) it by specifying `SimpleCov.merge_timeout 3600`
(1 hour), or, inside a configure/start block, with just `merge_timeout 3600`.
You can deactivate this automatic merging altogether with `SimpleCov.use_merging false`.
### Merging test runs under different execution environments
If your tests are done in parallel across multiple build machines, you can fetch them all and merge them into a single
result set using the `SimpleCov.collate` method. This can be added to a Rakefile or script file, having downloaded a set of
`.resultset.json` files from each parallel test run.
```ruby
# lib/tasks/coverage_report.rake
namespace :coverage do
desc "Collates all result sets generated by the different test runners"
task :report do
require 'simplecov'
SimpleCov.collate Dir["simplecov-resultset-*/.resultset.json"]
end
end
```
`SimpleCov.collate` also takes an optional simplecov profile and an optional
block for configuration, just the same as `SimpleCov.start` or
`SimpleCov.configure`. This means you can configure a separate formatter for
the collated output. For instance, you can make the formatter in
`SimpleCov.start` the `SimpleCov::Formatter::SimpleFormatter`, and only use more
complex formatters in the final `SimpleCov.collate` run.
```ruby
# spec/spec_helper.rb
require 'simplecov'
SimpleCov.start 'rails' do
# Disambiguates individual test runs
command_name "Job #{ENV["TEST_ENV_NUMBER"]}" if ENV["TEST_ENV_NUMBER"]
if ENV['CI']
formatter SimpleCov::Formatter::SimpleFormatter
else
formatter SimpleCov::Formatter::MultiFormatter.new([
SimpleCov::Formatter::SimpleFormatter,
SimpleCov::Formatter::HTMLFormatter
])
end
track_files "**/*.rb"
end
```
```ruby
# lib/tasks/coverage_report.rake
namespace :coverage do
task :report do
require 'simplecov'
SimpleCov.collate Dir["simplecov-resultset-*/.resultset.json"], 'rails' do
formatter SimpleCov::Formatter::MultiFormatter.new([
SimpleCov::Formatter::SimpleFormatter,
SimpleCov::Formatter::HTMLFormatter
])
end
end
end
```
## Running coverage only on demand
The Ruby STDLIB Coverage library that SimpleCov builds upon is *very* fast (on a ~10 min Rails test suite, the speed
drop was only a couple seconds for me), and therefore it's SimpleCov's policy to just generate coverage every time you
run your tests because it doesn't do your test speed any harm and you're always equipped with the latest and greatest
coverage results.
Because of this, SimpleCov has no explicit built-in mechanism to run coverage only on demand.
However, you can still accomplish this very easily by introducing an ENV variable conditional into your SimpleCov setup
block, like this:
```ruby
SimpleCov.start if ENV["COVERAGE"]
```
Then, SimpleCov will only run if you execute your tests like this:
```shell
COVERAGE=true rake test
```
## Errors and exit statuses
To aid in debugging issues, if an error is raised, SimpleCov will print a message to `STDERR`
with the exit status of the error, like:
```
SimpleCov failed with exit 1
```
This `STDERR` message can be disabled with:
```
SimpleCov.print_error_status = false
```
## Profiles
By default, SimpleCov's only config assumption is that you only want coverage reports for files inside your project
root. To save yourself from repetitive configuration, you can use predefined blocks of configuration, called 'profiles',
or define your own.
You can then pass the name of the profile to be used as the first argument to SimpleCov.start. For example, simplecov
comes bundled with a 'rails' profile. It looks somewhat like this:
```ruby
SimpleCov.profiles.define 'rails' do
add_filter '/test/'
add_filter '/config/'
add_group 'Controllers', 'app/controllers'
add_group 'Models', 'app/models'
add_group 'Helpers', 'app/helpers'
add_group 'Libraries', 'lib'
end
```
As you can see, it's just a SimpleCov.configure block. In your test_helper.rb, launch SimpleCov with:
```ruby
SimpleCov.start 'rails'
```
or
```ruby
SimpleCov.start 'rails' do
# additional config here
end
```
### Custom profiles
You can load additional profiles with the SimpleCov.load_profile('xyz') method. This allows you to build upon an
existing profile and customize it so you can reuse it in unit tests and Cucumber features. For example:
```ruby
# lib/simplecov_custom_profile.rb
require 'simplecov'
SimpleCov.profiles.define 'myprofile' do
load_profile 'rails'
add_filter 'vendor' # Don't include vendored stuff
end
# features/support/env.rb
require 'simplecov_custom_profile'
SimpleCov.start 'myprofile'
# test/test_helper.rb
require 'simplecov_custom_profile'
SimpleCov.start 'myprofile'
```
## Customizing exit behaviour
You can define what SimpleCov should do when your test suite finishes by customizing the at_exit hook:
```ruby
SimpleCov.at_exit do
SimpleCov.result.format!
end
```
Above is the default behaviour. Do whatever you like instead!
### Minimum coverage
You can define the minimum coverage percentage expected. SimpleCov will return non-zero if unmet.
```ruby
SimpleCov.minimum_coverage 90
# same as above (the default is to check line coverage)
SimpleCov.minimum_coverage line: 90
# check for a minimum line coverage of 90% and minimum 80% branch coverage
SimpleCov.minimum_coverage line: 90, branch: 80
```
### Minimum coverage by file
You can define the minimum coverage by file percentage expected. SimpleCov will return non-zero if unmet. This is useful
to help ensure coverage is relatively consistent, rather than being skewed by particularly good or bad areas of the code.
```ruby
SimpleCov.minimum_coverage_by_file 80
```
(not yet supported for branch coverage)
### Maximum coverage drop
You can define the maximum coverage drop percentage at once. SimpleCov will return non-zero if exceeded.
```ruby
SimpleCov.maximum_coverage_drop 5
```
(not yet supported for branch coverage)
### Refuse dropping coverage
You can also entirely refuse dropping coverage between test runs:
```ruby
SimpleCov.refuse_coverage_drop
```
(not yet supported for branch coverage)
## Using your own formatter
You can use your own formatter with:
```ruby
SimpleCov.formatter = SimpleCov::Formatter::HTMLFormatter
```
When calling SimpleCov.result.format!, it will be invoked with SimpleCov::Formatter::YourFormatter.new.format(result),
"result" being an instance of SimpleCov::Result. Do whatever your wish with that!
## Using multiple formatters
As of SimpleCov 0.9, you can specify multiple result formats:
```ruby
SimpleCov.formatters = SimpleCov::Formatter::MultiFormatter.new([
SimpleCov::Formatter::HTMLFormatter,
SimpleCov::Formatter::CSVFormatter,
])
```
## Available formatters, editor integrations and hosted services
* [Open Source formatter and integration plugins for SimpleCov](doc/alternate-formatters.md)
* [Editor Integration](doc/editor-integration.md)
* [Hosted (commercial) services](doc/commercial-services.md)
## Ruby version compatibility
SimpleCov is built in [Continuous Integration] on Ruby 2.4+ as well as JRuby 9.2+.
Note for JRuby => You need to pass JRUBY_OPTS="--debug" or create .jrubyrc and add debug.fullTrace=true
## Want to find dead code in production?
Try [Coverband](https://github.com/danmayer/coverband).
## Want to use Spring with SimpleCov?
If you're using [Spring](https://github.com/rails/spring) to speed up test suite runs and want to run SimpleCov along
with them, you'll find that it often misreports coverage with the default config due to some sort of eager loading
issue. Don't despair!
One solution is to [explicitly call eager
load](https://github.com/colszowka/simplecov/issues/381#issuecomment-347651728)
in your `test_helper.rb` / `spec_helper.rb` after calling `SimpleCov.start`.
```ruby
require 'simplecov'
SimpleCov.start 'rails'
Rails.application.eager_load!
```
Alternatively, you could disable Spring while running SimpleCov:
```
DISABLE_SPRING=1 rake test
```
Or you could remove `gem 'spring'` from your `Gemfile`.
## Troubleshooting
The **most common problem is that simplecov isn't required and started before everything else**. In order to track
coverage for your whole application **simplecov needs to be the first one** so that it (and the underlying coverage
library) can subsequently track loaded files and their usage.
If you are missing coverage for some code a simple trick is to put a puts statement in there and right after
`SimpleCov.start` so you can see if the file really was loaded after simplecov was started.
```ruby
# my_code.rb
class MyCode
puts "MyCode is being loaded!"
def my_method
# ...
end
end
# spec_helper.rb/rails_helper.rb/test_helper.rb/.simplecov whatever
SimpleCov.start
puts "SimpleCov started successfully!"
```
Now when you run your test suite and you see:
```
SimpleCov started successfully!
MyCode is being loaded!
```
then it's good otherwise you likely have a problem :)
## Code of Conduct
Everyone participating in this project's development, issue trackers and other channels is expected to follow our
[Code of Conduct](./CODE_OF_CONDUCT.md)
## Contributing
See the [contributing guide](https://github.com/colszowka/simplecov/blob/master/CONTRIBUTING.md).
## Kudos
Thanks to Aaron Patterson for the original idea for this!
## Copyright
Copyright (c) 2010-2017 Christoph Olszowka. See MIT-LICENSE for details.
simplecov-0.18.1/ISSUE_TEMPLATE.md 0000644 0000041 0000041 00000002577 13617303170 016353 0 ustar www-data www-data Howdy! Thanks for reporting an issue <3
Before you go ahead please search existing issues for your problem, chances are someone else already reported it.
To make sure that we can help you quickly please include and check the following information:
* Include how you run your tests and which testing framework or frameworks you are running.
- please ensure you are requiring and starting SimpleCov before requiring any application code.
- If running via rake, please ensure you are requiring SimpleCov at the top of your Rakefile
For example, if running via RSpec, this would be at the top of your spec_helper.
- Have you tried using a [`.simplecov` file](https://github.com/colszowka/simplecov#using-simplecov-for-centralized-config)?
* Include the SimpleCov version you are running in your report.
* If you are not running the latest version (please check), and you cannot update it,
please specify in your report why you can't update to the latest version.
* Include your `ruby -e "puts RUBY_DESCRIPTION"`.
* Please also specify the gem versions of Rails (if applicable).
* Include any other coverage gems you may be using and their versions.
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.)
This is extremely important for narrowing down the cause of your problem.
Thanks!
simplecov-0.18.1/CHANGELOG.md 0000644 0000041 0000041 00000107060 13617303170 015450 0 ustar www-data www-data 0.18.1 (2020-01-31)
===================
Small Bugfix release.
## Bugfixes
* Just putting `# :nocov:` on top of a file or having an uneven number of them in general works again and acts as if ignoring until the end of the file. See [#846](https://github.com/colszowka/simplecov/issues/846) and thanks [@DannyBen](https://github.com/DannyBen) for the report.
0.18.0 (2020-01-28)
===================
Huge release! Highlights are support for branch coverage (Ruby 2.5+) and dropping support for EOL'ed Ruby versions (< 2.4).
Please also read the other beta patch notes.
You can run with branch coverage by putting `enable_coverage :branch` into your SimpleCov configuration (like the `SimpleCov.start do .. end` block)
## Enhancements
* You can now define the minimum expected coverage by criterion like `minimum_coverage line: 90, branch: 80`
* Memoized some internal data structures that didn't change to reduce SimpleCov overhead
* Both `FileList` and `SourceFile` now have a `coverage` method that returns a hash that points from a coverage criterion to a `CoverageStatistics` object for uniform access to overall coverage statistics for both line and branch coverage
## Bugfixes
* we were losing precision by rounding the covered strength early, that has been removed. **For Formatters** this also means that you may need to round it yourself now.
* Removed an inconsistency in how we treat skipped vs. irrelevant lines (see [#565](https://github.com/colszowka/simplecov/issues/565)) - SimpleCov's definition of 100% is now "You covered everything that you could" so if coverage is 0/0 that's counted as a 100% no matter if the lines were irrelevant or ignored/skipped
## Noteworthy
* `FileList` stopped inheriting from Array, it includes Enumerable so if you didn't use Array specific methods on it in formatters you should be fine
0.18.0.beta3 (2020-01-20)
========================
## Enhancements
* Instead of ignoring old `.resultset.json`s that are inside the merge timeout, adapt and respect them
## Bugfixes
* Remove the constant warning printing if you still have a `.resultset.json` in pre 0.18 layout that is within your merge timeout
0.18.0.beta2 (2020-01-19)
===================
## Enhancements
* only turn on the requested coverage criteria (when activating branch coverage before SimpleCov would also instruct Ruby to take Method coverage)
* Change how branch coverage is displayed, now it's `branch_type: hit_count` which should be more self explanatory. See [#830](https://github.com/colszowka/simplecov/pull/830) for an example and feel free to give feedback!
* Allow early running exit tasks and avoid the `at_exit` hook through the `SimpleCov.run_exit_tasks!` method. (thanks [@macumber](https://github.com/macumber))
* Allow manual collation of result sets through the `SimpleCov.collate` entrypoint. See the README for more details (thanks [@ticky](https://github.com/ticky))
* Within `case`, even if there is no `else` branch declared show missing coverage for it (aka no branch of it). See [#825](https://github.com/colszowka/simplecov/pull/825)
* Stop symbolizing all keys when loading cache (should lead to be faster and consume less memory)
* Cache whether we can use/are using branch coverage (should be slightly faster)
## Bugfixes
* Fix a crash that happened when an old version of our internal cache file `.resultset.json` was still present
0.18.0.beta1 (2020-01-05)
===================
This is a huge release highlighted by changing our support for ruby versions to 2.4+ (so things that aren't EOL'ed) and finally adding branch coverage support!
This release is still beta because we'd love for you to test out branch coverage and get your feedback before doing a full release.
On a personal note from [@PragTob](https://github.com/PragTob/) thanks to [ruby together](https://rubytogether.org/) for sponsoring this work on SimpleCov making it possible to deliver this and subsequent releases.
## Breaking
* Dropped support for all EOL'ed rubies meaning we only support 2.4+. Simplecov can no longer be installed on older rubies, but older simplecov releases should still work. (thanks [@deivid-rodriguez](https://github.com/deivid-rodriguez))
* Dropped the `rake simplecov` task that "magically" integreated with rails. It was always undocumented, caused some issues and [had some issues](https://github.com/colszowka/simplecov/issues/689#issuecomment-561572327). Use the integration as described in the README please :)
## Enhancements
* Branch coverage is here! Please try it out and test it! You can activate it with `enable_coverage :branch`. See the README for more details. This is thanks to a bunch of people most notably [@som4ik](https://github.com/som4ik), [@tycooon](https://github.com/tycooon), [@stepozer](https://github.com/stepozer), [@klyonrad](https://github.com/klyonrad) and your humble maintainers also contributed ;)
* If the minimum coverage is set to be greater than 100, a warning will be shown. See [#737](https://github.com/colszowka/simplecov/pull/737) (thanks [@belfazt](https://github.com/belfazt))
* Add a configuration option to disable the printing of non-successful exit statuses. See [#747](https://github.com/colszowka/simplecov/pull/746) (thanks [@JacobEvelyn](https://github.com/JacobEvelyn))
* Calculating 100% coverage is now stricter, so 100% means 100%. See [#680](https://github.com/colszowka/simplecov/pull/680) thanks [@gleseur](https://github.com/gleseur)
## Bugfixes
* Add new instance of `Minitest` constant. The `MiniTest` constant (with the capital T) will be removed in the next major release of Minitest. See [#757](https://github.com/colszowka/simplecov/pull/757) (thanks [@adam12](https://github.com/adam12))
0.17.1 (2019-09-16)
===================
Bugfix release for problems with ParallelTests.
## Bugfixes
* Avoid hanging with parallel_tests. See [#746](https://github.com/colszowka/simplecov/pull/746) (thanks [@annaswims](https://github.com/annaswims))
0.17.0 (2019-07-02)
===================
Maintenance release with nice convenience features and important bugfixes.
Notably this **will be the last release to support ruby versions that have reached their end of life**. Moving forward official CRuby support will be 2.4+ and JRuby support will be 9.2+. Older versions might still work but no guarantees.
## Enhancements
* Per default filter hidden files and folders. See [#721](https://github.com/colszowka/simplecov/pull/721) (thanks [Renuo AG](https://www.renuo.ch))
* Print the exit status explicitly when it's not a successful build so it's easier figure out SimpleCov failed the build in the output. See [#688](https://github.com/colszowka/simplecov/pull/688) (thanks [@daemonsy](https://github.com/daemonsy))
## Bugfixes
* Avoid a premature failure exit code when setting `minimum_coverage` in combination with using [parallel_tests](https://github.com/grosser/parallel_tests). See [#706](https://github.com/colszowka/simplecov/pull/706) (thanks [@f1sherman](https://github.com/f1sherman))
* Project roots with special characters no longer cause crashes. See [#717](https://github.com/colszowka/simplecov/pull/717) (thanks [@deivid-rodriguez](https://github.com/deivid-rodriguez))
* Avoid continously overriding test results with manual `ResultMergere.store_results` usage. See [#674](https://github.com/colszowka/simplecov/pull/674) (thanks [@tomeon](https://github.com/tomeon))
0.16.1 (2018-03-16)
===================
## Bugfixes
* Include the LICENSE in the distributed gem again (accidentally removed in 0.16.0). (thanks @tas50)
0.16.0 (2018-03-15)
===================
## Enhancements
* Relax version constraint on `docile`, per SemVer
* exception that occurred on exit is available as `exit_exception`! See [#639](https://github.com/colszowka/simplecov/pull/639) (thanks @thomas07vt)
* Performance: processing results now runs from 2.5x to 3.75x faster. See [#662](https://github.com/colszowka/simplecov/pull/662) (thanks @BMorearty & @eregon)
* Decrease gem size by only shipping lib and docs
## Bugfixes
* (breaking) Stop handling string filters as regular expressions, use the dedicated regex filter if you need that behaviour. See [#616](https://github.com/colszowka/simplecov/pull/616) (thanks @yujinakayama)
* Avoid overwriting the last coverage results on unsuccessful test runs. See [#625](https://github.com/colszowka/simplecov/pull/625) (thanks @thomas07vt)
* Don't crash on invalid UTF-8 byte sequences. (thanks @BMorearty)
0.15.1 (2017-09-11) ([changes](https://github.com/colszowka/simplecov/compare/v0.15.0...v0.15.1))
=======
## Bugfixes
* Filter directories outside SimpleCov.root that have it as a prefix. See [#617](https://github.com/colszowka/simplecov/pull/617) (thanks @jenseng)
* Fix standard rails profile rails filter (didn't work). See [#618](https://github.com/colszowka/simplecov/pull/618) (thanks @jenseng again!)
0.15.0 (2017-08-14) ([changes](https://github.com/colszowka/simplecov/compare/v0.14.1...v0.15.0))
=======
## Enhancements
* Ability to use regex filters for removing files from the output. See [#589](https://github.com/colszowka/simplecov/pull/589) (thanks @jsteel)
## Bugfixes
* Fix merging race condition when running tests in parallel and merging them. See [#570](https://github.com/colszowka/simplecov/pull/570) (thanks @jenseng)
* Fix relevant lines for unloaded files - comments, skipped code etc. are correctly classified as irrelevant. See [#605](https://github.com/colszowka/simplecov/pull/605) (thanks @odlp)
* Allow using simplecov with frozen-string-literals enabled. See [#590](https://github.com/colszowka/simplecov/pull/590) (thanks @pat)
* Make sure Array Filter can use all other filter types. See [#589](https://github.com/colszowka/simplecov/pull/589) (thanks @jsteel)
* Make sure file names use `Simplecov.root` as base avoiding using full absolute project paths. See [#589](https://github.com/colszowka/simplecov/pull/589) (thanks @jsteel)
0.14.1 2017-03-18 ([changes](https://github.com/colszowka/simplecov/compare/v0.14.0...v0.14.1))
========
## Bugfixes
* Files that were skipped as a whole/had no relevant coverage could lead to Float errors. See [#564](https://github.com/colszowka/simplecov/pull/564) (thanks to @stevehanson for the report in [#563](https://github.com/colszowka/simplecov/issues/563))
0.14.0 2017-03-15 ([changes](https://github.com/colszowka/simplecov/compare/v0.13.0...v0.14.0))
==========
## Enhancements
* Officially support JRuby 9.1+ going forward (should also work with previous releases). See [#547](https://github.com/colszowka/simplecov/pull/547) (ping @PragTob when encountering issues)
* Add Channel group to Rails profile, when `ActionCable` is loaded. See [#492](https://github.com/colszowka/simplecov/pull/492) (thanks @BenMorganIO)
* Stop `extend`ing instances of `Array` and `Hash` during merging results avoiding problems frozen results while manually merging results. See [#558](https://github.com/colszowka/simplecov/pull/558) (thanks @aroben)
## Bugfixes
* Fix parallel_tests when a thread ends up running no tests. See [#533](https://github.com/colszowka/simplecov/pull/533) (thanks @cshaffer)
* Skip the `:nocov:` comments along with the code that they skip. See [#551](https://github.com/colszowka/simplecov/pull/551) (thanks @ebiven)
* Fix crash when Home environment variable is unset. See [#482](https://github.com/colszowka/simplecov/pull/482) (thanks @waldyr)
* Make track_files work again when explicitly setting it to nil. See [#463](https://github.com/colszowka/simplecov/pull/463) (thanks @craiglittle)
* Do not overwrite .last_run.json file when refuse_coverage_drop option is enabled and the coverage has dropped (lead to you being able to just rerun tests and everything was _fine_). See [#553](https://github.com/colszowka/simplecov/pull/553) (thanks @Miloshes)
0.13.0 2017-01-25 ([changes](https://github.com/colszowka/simplecov/compare/v0.12.0...v0.13.0))
==========
## Enhancements
* Faster run times when a very large number of files is loaded into SimpleCov. See [#520](https://github.com/colszowka/simplecov/pull/520) (thanks @alyssais)
* Only read in source code files that are actually used (faster when files are ignored etc.). See [#540](https://github.com/colszowka/simplecov/pull/540) (thanks @yui-knk)
## Bugfixes
* Fix merging of resultsets if a file is missing on one side. See [#513](https://github.com/colszowka/simplecov/pull/513) (thanks @hanazuki)
* Fix Ruby 2.4 deprecation warnings by using Integer instead of Fixnum. See [#523](https://github.com/colszowka/simplecov/pull/523) (thanks @nobu)
* Force Ruby 2 to json 2. See [dc7417d50](https://github.com/colszowka/simplecov/commit/dc7417d5049b1809cea214314c15dd93a5dd964f) (thanks @amatsuda)
* Various other gem dependency fixes for different gems on different ruby versions. (thanks @amatsuda)
0.12.0 2016-07-02 ([changes](https://github.com/colszowka/simplecov/compare/v0.11.2...v0.12.0))
=================
## Enhancements
* Add support for JSON versions 2.x
## Bugfixes
* Fix coverage rate of the parallel_tests. See [#441](https://github.com/colszowka/simplecov/pull/441) (thanks @sinsoku)
* Fix a regression on old rubies that failed to work with the recently introduced frozen VERSION string. See [#461](https://github.com/colszowka/simplecov/pull/461) (thanks @leafle)
0.11.2 2016-02-03 ([changes](https://github.com/colszowka/simplecov/compare/v0.11.1...v0.11.2))
=================
## Enhancements
* Do not globally pollute Array and Hash with `merge_resultset` utility methods. See [#449](https://github.com/colszowka/simplecov/pull/449) (thanks @amatsuda)
* Do not `mkdir_p` the `coverage_path` on every access of the method (See [#453](https://github.com/colszowka/simplecov/pull/453) (thanks @paddor)
* Fixes a Ruby warning related to the `track_files` configuration. See [#447](https://github.com/colszowka/simplecov/pull/447) (thanks @craiglittle)
* Add a group for background jobs to default Rails profile. See [#442](https://github.com/colszowka/simplecov/pull/442) (thanks @stve)
## Bugfixes
* Fix root_filter evaluates SimpleCov.root before initialization. See [#437](https://github.com/colszowka/simplecov/pull/437) (thanks @tmtm)
0.11.1 2015-12-01 ([changes](https://github.com/colszowka/simplecov/compare/v0.11.0...v0.11.1))
=================
## Enhancements
## Bugfixes
* Fixed regression in `MultiFormatter.[]` with multiple arguments. See [#431](https://github.com/colszowka/simplecov/pull/431) (thanks @dillondrobena)
0.11.0 2015-11-29 ([changes](https://github.com/colszowka/simplecov/compare/v0.10.0...v0.11.0))
=================
## Enhancements
* Added `SimpleCov.minimum_coverage_by_file` for per-file coverage thresholds. See [#392](https://github.com/colszowka/simplecov/pull/392) (thanks @ptashman)
* Added `track_files` configuration option to specify a glob to always include in coverage results, whether or not those files are required. By default, this is enabled in the Rails profile for common Rails directories. See [#422](https://github.com/colszowka/simplecov/pull/422) (thanks @hugopeixoto)
* Speed up `root_filter` by an order of magnitude. See [#396](https://github.com/colszowka/simplecov/pull/396) (thanks @raszi)
## Bugfixes
* Fix warning about global variable `$ERROR_INFO`. See [#400](https://github.com/colszowka/simplecov/pull/400) (thanks @amatsuda)
* Actually recurse upward looking for `.simplecov`, as claimed by the documentation, rather than only the working directory. See [#423](https://github.com/colszowka/simplecov/pull/423) (thanks @alexdowad)
0.10.0 2015-04-18 ([changes](https://github.com/colszowka/simplecov/compare/v0.9.2...v0.10.0))
=================
## Enhancements
* Add writeup about using with Spring to README. See [#341](https://github.com/colszowka/simplecov/issues/341) (thanks @swrobel and @onebree)
* Add support to pass in an Array when creating filter groups (original PR #104)
* Filter `/vendor/bundle` by default. See [#331](https://github.com/colszowka/simplecov/pull/331) (thanks @andyw8)
* Add some helpful singleton methods to the version string.
* Allow array to be passed in a filter. See [375](https://github.com/colszowka/simplecov/pull/375) (thanks @JanStevens)
* Enforce consistent code formatting with RuboCop.
## Bugfixes
* Fix order dependencies in unit tests. See [#376](https://github.com/colszowka/simplecov/pull/376) (thanks @hugopeixoto)
* Only run the at_exit behaviors if the current PID matches the PID that called SimpleCov.start. See [#377](https://github.com/colszowka/simplecov/pull/377) (thanks @coderanger)
0.9.2, 2015-02-18 ([changes](https://github.com/colszowka/simplecov/compare/v0.9.1...v0.9.2))
=================
This is a minor bugfix release for simplecov-html, released as `0.9.0`. Due to the tight version constraint in the gemspec
a new release of simplecov had to be shipped to allow using simplecov-html `~> 0.9.0`.
* The browser back / forward button should now work again. See [#36](https://github.com/colszowka/simplecov-html/pull/36) and
[#35](https://github.com/colszowka/simplecov-html/pull/35). Thanks @whatasunnyday and @justinsteele for submitting PRs to fix this.
* Fix "warning: possibly useless use of a variable in void context" See [#31](https://github.com/colszowka/simplecov-html/pull/31). Thanks @cbandy
* Always use binary file format. See [#32](https://github.com/colszowka/simplecov-html/pull/32). Thanks @andy128k
* Avoid slow file output with JRuby/Windows. See [#16](https://github.com/colszowka/simplecov-html/pull/16). Thanks @pschambacher
Other than the release includes a bunch of mostly documentation improvements:
* Update Rails path for Rails 4+. See [#336](https://github.com/colszowka/simplecov/pull/336). Thanks @yazinsai
* Encourage use of .simplecov to avoid lost files. See [#338](https://github.com/colszowka/simplecov/pull/338). thanks @dankohn
* Specified in the gemspec that simplecov needs ruby 1.8.7. See [#343](https://github.com/colszowka/simplecov/pull/343). thanks @iainbeeston
* Fix mispointed link in CHANGELOG.md. See [#353](https://github.com/colszowka/simplecov/pull/353). Thanks @dleve123
* Improve command name docs. See [#356](https://github.com/colszowka/simplecov/pull/356). Thanks @gtd
0.9.1, 2014-09-21 ([changes](https://github.com/colszowka/simplecov/compare/v0.9.0...v0.9.1))
=================
## Bugfixes
* In 0.9.0, we introduced a regression that made SimpleCov no-op mode fail on Ruby 1.8, while
dropping 1.8 support altogether is announced only for v1.0. This has been fixed.
See [#333](https://github.com/colszowka/simplecov/issues/333) (thanks (@sferik)
0.9.0, 2014-07-17 ([changes](https://github.com/colszowka/simplecov/compare/v0.8.2...v0.9.0))
=================
**A warm welcome and big thank you to the new contributors [@xaviershay](https://github.com/xaviershay), [@sferik](https://github.com/sferik) and especially [@bf4](https://github.com/bf4) for tackling a whole lot of issues and pull requests for this release!**
## Enhancements
* New interface to specify multiple formatters.
See [#317](https://github.com/colszowka/simplecov/pull/317) (thanks @sferik)
* Document in the README how to exclude code from coverage reports,
and that the feature shouldn't be abused for skipping untested
private code.
See [#304](https://github.com/colszowka/simplecov/issues/304)
* Clarify Ruby version support.
See [#279](https://github.com/colszowka/simplecov/pull/279) (thanks @deivid-rodriguez)
## Bugfixes
* Ensure calculations return Floats, not Fixnum or Rational. Fixes segfaults with mathn.
See [#245](https://github.com/colszowka/simplecov/pull/245) (thanks to @bf4)
* Using `Kernel.exit` instead of exit to avoid uncaught throw :IRB_EXIT when
exiting irb sessions.
See [#287](https://github.com/colszowka/simplecov/pull/287) (thanks @wless1)
See [#285](https://github.com/colszowka/simplecov/issues/285)
* Does not look for .simplecov in ~/ when $HOME is not set.
See [#311](https://github.com/colszowka/simplecov/pull/311) (thanks @lasseebert)
* Exit with code only if it's Numeric > 0.
See [#302](https://github.com/colszowka/simplecov/pull/302) (thanks @hajder)
* Make default filter case insensitive.
See [#280](https://github.com/colszowka/simplecov/pull/280) (thanks @ryanatball)
* Improve regexp that matches functional tests.
See [#276](https://github.com/colszowka/simplecov/pull/276) (thanks @sferik)
* Fix TravisCI [#272](https://github.com/colszowka/simplecov/pull/272) [#278](https://github.com/colszowka/simplecov/pull/278), [#302](https://github.com/colszowka/simplecov/pull/302)
* Fix global config load.
See [#311](https://github.com/colszowka/simplecov/pull/311) (thanks @lasseebert)
v0.8.2, 2013-11-20 ([changes](https://github.com/colszowka/simplecov/compare/v0.8.1...v0.8.2))
==================
## Bugfixes
* Replaced the locking behaviour [via lockfile gem](https://github.com/colszowka/simplecov/pull/185) with
plain Ruby explicit file locking when merging results. This should make simplecov merging to behave well
on Windows again.
See [#258](https://github.com/colszowka/simplecov/issues/258) and
[#223](https://github.com/colszowka/simplecov/pull/223) (thanks to @tomykaira)
v0.8.1, 2013-11-10 ([changes](https://github.com/colszowka/simplecov/compare/v0.8.0...v0.8.1))
==================
## Bugfixes
* Fixed a regression introduced in 0.8.0 - the Forwardable STDLIB module is now required explicitly.
See [#256](https://github.com/colszowka/simplecov/pull/256) (thanks to @kylev)
v0.8.0, 2013-11-10 ([changes](https://github.com/colszowka/simplecov/compare/v0.7.1...v0.8.0))
==================
**Note: Yanked the same day because of the regression that 0.8.1 fixes, see above**
## TL;DR
It's been way too long since the last official release 0.7.1, but this was partly due to it proving itself
quite stable in most circumstances. This release brings various further stability improvements to result set merging
(especially when working with parallel_tests), the configuration, source file encodings, and command name guessing.
The 0.8 line is the last one to cooperate with Ruby < 1.9. Starting with 0.9, SimpleCov will assume to be running in
Ruby 1.9+, and will not try to detect or bail silently on older Ruby versions. An appropriate deprecation warning
has been added.
## Features
* Configuration blocks now have access to variables and methods outside of the block's scope.
See [#238](https://github.com/colszowka/simplecov/pull/238) (thanks to @ms-tg)
* You can now have a global `~/.simplecov` configuration file.
See [#195](https://github.com/colszowka/simplecov/pull/195) (thanks to @spagalloco)
* simplecov-html now uses the MIT-licensed colorbox plugin. Some adjustments when viewing source files,
including retaining the currently open file on refresh have been added.
See [simplecov-html #15](https://github.com/colszowka/simplecov-html/pull/15) (thanks to @chetan)
* Adds support for Rails 4 command guessing, removes default group `vendor/plugins`.
See [#181](https://github.com/colszowka/simplecov/pull/181) and
[#203](https://github.com/colszowka/simplecov/pull/203) (thanks to @semanticart and @phallstrom)
* You can now load simplecov without the default settings by doing `require 'simplecov/no_defaults'`
or setting `ENV['SIMPLECOV_NO_DEFAULTS']`. Check `simplecov/defaults` to see what preconfigurations are getting
dropped by using this. See [#209](https://github.com/colszowka/simplecov/pull/209) (thanks to @ileitch)
* The result set merging now uses the `lockfile` gem to avoid race conditions.
See [#185](https://github.com/colszowka/simplecov/pull/185) (thanks to @jshraibman-mdsol).
* Automatically detect the usage of parallel_tests and adjust the command name with the test env number accordingly,
See [#64](https://github.com/colszowka/simplecov/issues/64) and
[#185](https://github.com/colszowka/simplecov/pull/185) (thanks to @jshraibman-mdsol).
## Enhancements
* Rename adapters to "profiles" given that they are bundles of settings. The old adapter methods are
deprecated, but remain available for now.
See [#207](https://github.com/colszowka/simplecov/pull/207) (thanks to @mikerobe)
* Tweaks to the automatic test suite naming. In particular, `rspec/features` should now
be correctly attributed to RSpec, not Cucumber.
See [#212](https://github.com/colszowka/simplecov/pull/212) (thanks to @ersatzryan and @betelgeuse)
* MiniTest should now be identified correctly by the command name guesser.
See [#244](https://github.com/colszowka/simplecov/pull/244) (thanks to @envygeeks)
* Makes SimpleCov resilient to inclusion of mathn library.
See [#175](https://github.com/colszowka/simplecov/pull/175) and
[#140](https://github.com/colszowka/simplecov/issues/140) (thanks to @scotje)
* Allow coverage_dir to be an absolute path.
* See [#190](https://github.com/colszowka/simplecov/pull/190) (thanks to @jshraibman-mdsol)
* The internal cucumber test suite now uses Capybara 2.
See [#206](https://github.com/colszowka/simplecov/pull/206) (thanks to @infertux)
* Work-arounds for the Coverage library shipped in JRuby 1.6 to behave in line with MRI.
See [#174](https://github.com/colszowka/simplecov/pull/174) (thanks to @grddev)
* Fix warning: instance variable @exit_status not initialized.
See [#242](https://github.com/colszowka/simplecov/pull/242) and
[#213](https://github.com/colszowka/simplecov/pull/213) (thanks to @sferik and @infertux)
## Bugfixes
* Correct result calculations for people using :nocov: tags.
See [#215](https://github.com/colszowka/simplecov/pull/215) (thanks to @aokolish)
* Average hits per line for groups of files is now computed correctly.
See [#192](http://github.com/colszowka/simplecov/pull/192) and
[#179](http://github.com/colszowka/simplecov/issues/179) (thanks to @graysonwright)
* Compatibility with BINARY internal encoding.
See [#194](https://github.com/colszowka/simplecov/pull/194) and
[#127](https://github.com/colszowka/simplecov/issues/127) (thanks to @justfalter)
* Special characters in `SimpleCov.root` are now correctly escaped before being used as a RegExp.
See [#204](https://github.com/colszowka/simplecov/issues/204) and
[#237](https://github.com/colszowka/simplecov/pull/237) (thanks to @rli9)
v0.7.1, 2012-10-12 ([changes](https://github.com/colszowka/simplecov/compare/v0.7.0...v0.7.1))
==================
* [BUGFIX] The gem packages of 0.7.0 (both simplecov and simplecov-html) pushed to Rubygems had some file
permission issues, leading to problems when installing SimpleCov in a root/system Rubygems install and then
trying to use it as a normal user (see https://github.com/colszowka/simplecov/issues/171, thanks @envygeeks
for bringing it up). The gem build process has been changed to always enforce proper permissions before packaging
to avoid this issue in the future.
v0.7.0, 2012-10-10 ([changes](https://github.com/colszowka/simplecov/compare/v0.6.4...v0.7.0))
==================
* [FEATURE] The new `maximum_coverage_drop` and `minimum_coverage` now allow you to fail your build when the
coverage dropped by more than what you allowed or is below a minimum value required. Also, `refuse_coverage_drop` disallows
any coverage drops between test runs.
See https://github.com/colszowka/simplecov/pull/151, https://github.com/colszowka/simplecov/issues/11,
https://github.com/colszowka/simplecov/issues/90, and https://github.com/colszowka/simplecov/issues/96 (thanks to @infertux)
* [FEATURE] SimpleCov now ships with a built-in MultiFormatter which allows the easy usage of multiple result formatters at
the same time without the need to write custom wrapper code.
See https://github.com/colszowka/simplecov/pull/158 (thanks to @nikitug)
* [BUGFIX] The usage of digits, hyphens and underscores in group names could lead to broken tab navigation
in the default simplecov-html reports. See https://github.com/colszowka/simplecov-html/pull/14 (thanks to @ebelgarts)
* [REFACTORING] A few more ruby warnings removed. See https://github.com/colszowka/simplecov/issues/106 and
https://github.com/colszowka/simplecov/pull/139. (thanks to @lukejahnke)
* A [Pledgie button](https://github.com/colszowka/simplecov/commit/63cfa99f8658fa5cc66a38c83b3195fdf71b9e93) for those that
feel generous :)
* The usual bunch of README fixes and documentation tweaks. Thanks to everyone who contributed those!
v0.6.4, 2012-05-10 ([changes](https://github.com/colszowka/simplecov/compare/v0.6.3...v0.6.4))
==================
* [BUGFIX] Encoding issues with ISO-8859-encoded source files fixed.
See https://github.com/colszowka/simplecov/pull/117. (thanks to @Deradon)
* [BUGFIX] Ensure ZeroDivisionErrors won't occur when calculating the coverage result, which previously
could happen in certain cases. See https://github.com/colszowka/simplecov/pull/128. (thanks to @japgolly)
* [REFACTORING] Changed a couple instance variable lookups so SimpleCov does not cause a lot of warnings when
running ruby at a higher warning level. See https://github.com/colszowka/simplecov/issues/106 and
https://github.com/colszowka/simplecov/pull/119. (thanks to @mvz and @gioele)
v0.6.3, 2012-05-10 ([changes](https://github.com/colszowka/simplecov/compare/v0.6.2...v0.6.3))
==================
* [BUGFIX] Modified the API-changes for newer multi_json versions introduced with #122 and v0.6.2 so
they are backwards-compatible with older multi_json gems in order to avoid simplecov polluting
the multi_json minimum version requirement for entire applications.
See https://github.com/colszowka/simplecov/issues/132
* Added appraisal gem to the test setup in order to run the test suite against both 1.0 and 1.3
multi_json gems and ensure the above actually works :)
v0.6.2, 2012-04-20 ([changes](https://github.com/colszowka/simplecov/compare/v0.6.1...v0.6.2))
==================
* [Updated to latest version of MultiJSON and its new API (thanks to @sferik and @ronen).
See https://github.com/colszowka/simplecov/pull/122
v0.6.1, 2012-02-24 ([changes](https://github.com/colszowka/simplecov/compare/v0.6.0...v0.6.1))
==================
* [BUGFIX] Don't force-load Railtie on Rails < 3. Fixes regression introduced with
#83. See https://github.com/colszowka/simplecov/issues/113
v0.6.0, 2012-02-22 ([changes](https://github.com/colszowka/simplecov/compare/v0.5.4...v0.6.0))
==================
* [FEATURE] Auto-magic `rake simplecov` task for rails
(see https://github.com/colszowka/simplecov/pull/83, thanks @sunaku)
* [BUGFIX] Treat source files as UTF-8 to avoid encoding errors
(see https://github.com/colszowka/simplecov/pull/103, thanks @joeyates)
* [BUGFIX] Store the invoking terminal command right after loading so they are safe from
other libraries tampering with ARGV. Among other makes automatic Rails test suite splitting
(Unit/Functional/Integration) work with recent rake versions again
(see https://github.com/colszowka/simplecov/issues/110)
* [FEATURE] If guessing command name from the terminal command fails, try guessing from defined constants
(see https://github.com/colszowka/simplecov/commit/37afca54ef503c33d888e910f950b3b943cb9a6c)
* Some refactorings and cleanups as usual. Please refer to the github compare view for a full
list of changes: https://github.com/colszowka/simplecov/compare/v0.5.4...v0.6.0
v0.5.4, 2011-10-12 ([changes](https://github.com/colszowka/simplecov/compare/v0.5.3...v0.5.4))
==================
* Do not give exit code 0 when there are exceptions prior to tests
(see https://github.com/colszowka/simplecov/issues/41, thanks @nbogie)
* The API for building custom filter classes is now more obvious, using #matches? instead of #passes? too.
(see https://github.com/colszowka/simplecov/issues/85, thanks @robinroestenburg)
* Mailers are now part of the Rails adapter as their own group (see
https://github.com/colszowka/simplecov/issues/79, thanks @geetarista)
* Removed fix for JRuby 1.6 RC1 float bug because it's been fixed
(see https://github.com/colszowka/simplecov/issues/86)
* Readme formatted in Markdown :)
v0.5.3, 2011-09-13 ([changes](https://github.com/colszowka/simplecov/compare/v0.5.2...v0.5.3))
==================
* Fix for encoding issues that came from the nocov processing mechanism
(see https://github.com/colszowka/simplecov/issues/71)
* :nocov: lines are now actually being reflected in the HTML report and are marked in yellow.
* The Favicon in the HTML report is now determined by the overall coverage and will have the color
that the coverage percentage gets as a css class to immediately indicate coverage status on first sight.
* Introduced SimpleCov::SourceFile::Line#status method that returns the coverage status
as a string for this line - made SimpleCov::HTML use that.
* Refactored nocov processing and made it configurable using SimpleCov.ncov_token (or it's
alias SimpleCov.skip_token)
v0.5.2, 2011-09-12 ([changes](https://github.com/colszowka/simplecov/compare/v0.5.1...v0.5.2))
==================
* Another fix for a bug in JSON processing introduced with MultiJSON in 0.5.1
(see https://github.com/colszowka/simplecov/pull/75, thanks @sferik)
v0.5.1, 2011-09-12 ([changes](https://github.com/colszowka/simplecov/compare/v0.5.0...v0.5.1))
==================
**Note: Yanked 2011-09-12 because the MultiJSON-patch had a crucial bug**
* Fix for invalid gemspec dependency string (see https://github.com/colszowka/simplecov/pull/70,
http://blog.rubygems.org/2011/08/31/shaving-the-yaml-yacc.html, thanks @jspradlin)
* Added JSON in the form of the multi_json gem as dependency for those cases when built-in JSON
is unavailable (see https://github.com/colszowka/simplecov/issues/72
and https://github.com/colszowka/simplecov/pull/74, thanks @sferik)
v0.5.0, 2011-09-09 ([changes](https://github.com/colszowka/simplecov/compare/v0.4.2...v0.5.4))
==================
**Note: Yanked 2011-09-09 because of trouble with the gemspec.**
* JSON is now used instead of YAML for resultset caching (used for merging). Should resolve
a lot of problems people used to have because of YAML parser errors.
* There's a new adapter 'test_frameworks'. Use it outside of Rails to remove `test/`,
`spec/`, `features/` and `autotest/` dirs from your coverage reports, either directly
with `SimpleCov.start 'test_frameworks'` or with `SimpleCov.load_adapter 'test_frameworks'`
* SimpleCov configuration can now be placed centrally in a text file `.simplecov`, which will
be automatically read on `require 'simplecov'`. This makes using custom configuration like
groups and filters across your test suites much easier as you only have to specify your config
once. Just put the whole `SimpleCov.start (...)` code into `APP_ROOT/.simplecov`
* Lines can now be skipped by using the :nocov: flag in comments that wrap the code that should be
skipped, like in this example (thanks @phillipkoebbe)
#:nocov:
def skipped
@foo * 2
end
#:nocov:
* Moved file set coverage analytics from simplecov-html to SimpleCov::FileList, a new subclass
of Array that is always returned for SourceFile lists (i.e. in groups) and can now be used
in all formatters without the need to roll your own.
* The exceptions you used to get after removing some code and re-running your tests because SimpleCov
couldn't find the cached source lines should be resolved (thanks @goneflyin)
* Coverage strength metric: Average hits/line per source file and result group (thanks @trans)
* Finally, SimpleCov has an extensive Cucumber test suite
* Full compatibility with Ruby 1.9.3.preview1
### HTML Formatter:
* The display of source files has been improved a lot. Weird scrolling trouble, out-of-scope line hit counts
and such should be a thing of the past. Also, it is prettier now.
* Source files are now syntax highlighted
* File paths no longer have that annoying './' in front of them
simplecov-0.18.1/simplecov.gemspec 0000644 0000041 0000041 00000007221 13617303170 017203 0 ustar www-data www-data #########################################################
# This file has been automatically generated by gem2tgz #
#########################################################
# -*- encoding: utf-8 -*-
# stub: simplecov 0.18.1 ruby lib
Gem::Specification.new do |s|
s.name = "simplecov".freeze
s.version = "0.18.1"
s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
s.metadata = { "bug_tracker_uri" => "https://github.com/colszowka/simplecov/issues", "changelog_uri" => "https://github.com/colszowka/simplecov/blob/master/CHANGELOG.md", "documentation_uri" => "https://www.rubydoc.info/gems/simplecov/0.18.1", "mailing_list_uri" => "https://groups.google.com/forum/#!forum/simplecov", "source_code_uri" => "https://github.com/colszowka/simplecov/tree/v0.18.1" } if s.respond_to? :metadata=
s.require_paths = ["lib".freeze]
s.authors = ["Christoph Olszowka".freeze]
s.date = "2020-01-31"
s.description = "Code coverage for Ruby with a powerful configuration library and automatic merging of coverage across test suites".freeze
s.email = ["christoph at olszowka de".freeze]
s.files = ["CHANGELOG.md".freeze, "CODE_OF_CONDUCT.md".freeze, "CONTRIBUTING.md".freeze, "ISSUE_TEMPLATE.md".freeze, "LICENSE".freeze, "README.md".freeze, "doc/alternate-formatters.md".freeze, "doc/commercial-services.md".freeze, "doc/editor-integration.md".freeze, "lib/simplecov.rb".freeze, "lib/simplecov/combine.rb".freeze, "lib/simplecov/combine/branches_combiner.rb".freeze, "lib/simplecov/combine/files_combiner.rb".freeze, "lib/simplecov/combine/lines_combiner.rb".freeze, "lib/simplecov/combine/results_combiner.rb".freeze, "lib/simplecov/command_guesser.rb".freeze, "lib/simplecov/configuration.rb".freeze, "lib/simplecov/coverage_statistics.rb".freeze, "lib/simplecov/defaults.rb".freeze, "lib/simplecov/exit_codes.rb".freeze, "lib/simplecov/file_list.rb".freeze, "lib/simplecov/filter.rb".freeze, "lib/simplecov/formatter.rb".freeze, "lib/simplecov/formatter/multi_formatter.rb".freeze, "lib/simplecov/formatter/simple_formatter.rb".freeze, "lib/simplecov/last_run.rb".freeze, "lib/simplecov/lines_classifier.rb".freeze, "lib/simplecov/load_global_config.rb".freeze, "lib/simplecov/no_defaults.rb".freeze, "lib/simplecov/profiles.rb".freeze, "lib/simplecov/profiles/bundler_filter.rb".freeze, "lib/simplecov/profiles/hidden_filter.rb".freeze, "lib/simplecov/profiles/rails.rb".freeze, "lib/simplecov/profiles/root_filter.rb".freeze, "lib/simplecov/profiles/test_frameworks.rb".freeze, "lib/simplecov/result.rb".freeze, "lib/simplecov/result_adapter.rb".freeze, "lib/simplecov/result_merger.rb".freeze, "lib/simplecov/simulate_coverage.rb".freeze, "lib/simplecov/source_file.rb".freeze, "lib/simplecov/source_file/branch.rb".freeze, "lib/simplecov/source_file/line.rb".freeze, "lib/simplecov/useless_results_remover.rb".freeze, "lib/simplecov/version.rb".freeze]
s.homepage = "https://github.com/colszowka/simplecov".freeze
s.licenses = ["MIT".freeze]
s.required_ruby_version = Gem::Requirement.new(">= 2.4.0".freeze)
s.rubygems_version = "2.5.2.1".freeze
s.summary = "Code coverage for Ruby".freeze
if s.respond_to? :specification_version then
s.specification_version = 4
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
s.add_runtime_dependency(%q.freeze, ["~> 1.1"])
s.add_runtime_dependency(%q.freeze, ["~> 0.11.0"])
else
s.add_dependency(%q.freeze, ["~> 1.1"])
s.add_dependency(%q.freeze, ["~> 0.11.0"])
end
else
s.add_dependency(%q.freeze, ["~> 1.1"])
s.add_dependency(%q.freeze, ["~> 0.11.0"])
end
end
simplecov-0.18.1/CODE_OF_CONDUCT.md 0000644 0000041 0000041 00000006421 13617303170 016435 0 ustar www-data www-data # SimpleCov Code of Conduct
## Our Pledge
In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, sex characteristics, gender identity and expression,
level of experience, education, socio-economic status, nationality, personal
appearance, race, religion, or sexual identity and orientation.
## Our Standards
Examples of behavior that contributes to creating a positive environment
include:
* Using welcoming and inclusive language
* Being respectful of differing viewpoints and experiences
* Gracefully accepting constructive criticism
* Focusing on what is best for the community
* Showing empathy towards other community members
Examples of unacceptable behavior by participants include:
* The use of sexualized language or imagery and unwelcome sexual attention or
advances
* Trolling, insulting/derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or electronic
address, without explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Our Responsibilities
Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.
Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.
## Scope
This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at simplecov.team@gmail.com. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see
https://www.contributor-covenant.org/faq
simplecov-0.18.1/LICENSE 0000644 0000041 0000041 00000002053 13617303170 014640 0 ustar www-data www-data Copyright (c) 2010-2017 Christoph Olszowka
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
simplecov-0.18.1/lib/ 0000755 0000041 0000041 00000000000 13617303170 014401 5 ustar www-data www-data simplecov-0.18.1/lib/simplecov/ 0000755 0000041 0000041 00000000000 13617303170 016402 5 ustar www-data www-data simplecov-0.18.1/lib/simplecov/coverage_statistics.rb 0000644 0000041 0000041 00000003563 13617303170 023003 0 ustar www-data www-data # frozen_string_literal: true
module SimpleCov
# Holds the individual data of a coverage result.
#
# This is uniform across coverage criteria as they all have:
#
# * total - how many things to cover there are (total relevant loc/branches)
# * covered - how many of the coverables are hit
# * missed - how many of the coverables are missed
# * percent - percentage as covered/missed
# * strength - average hits per/coverable (will not exist for one shot lines format)
class CoverageStatistics
attr_reader :total, :covered, :missed, :strength, :percent
def self.from(coverage_statistics)
sum_covered, sum_missed, sum_total_strength =
coverage_statistics.reduce([0, 0, 0.0]) do |(covered, missed, total_strength), file_coverage_statistics|
[
covered + file_coverage_statistics.covered,
missed + file_coverage_statistics.missed,
# gotta remultiply with loc because files have different strenght and loc
# giving them a different "weight" in total
total_strength + (file_coverage_statistics.strength * file_coverage_statistics.total)
]
end
new(covered: sum_covered, missed: sum_missed, total_strength: sum_total_strength)
end
# Requires only covered, missed and strength to be initialized.
#
# Other values are computed by this class.
def initialize(covered:, missed:, total_strength: 0.0)
@covered = covered
@missed = missed
@total = covered + missed
@percent = compute_percent(covered, total)
@strength = compute_strength(total_strength, @total)
end
private
def compute_percent(covered, total)
return 100.0 if total.zero?
covered * 100.0 / total
end
def compute_strength(total_strength, total)
return 0.0 if total.zero?
total_strength.to_f / total
end
end
end
simplecov-0.18.1/lib/simplecov/formatter.rb 0000644 0000041 0000041 00000000347 13617303170 020736 0 ustar www-data www-data # frozen_string_literal: true
module SimpleCov
# TODO: Documentation on how to build your own formatters
module Formatter
end
end
require "simplecov/formatter/simple_formatter"
require "simplecov/formatter/multi_formatter"
simplecov-0.18.1/lib/simplecov/version.rb 0000644 0000041 0000041 00000000111 13617303170 020405 0 ustar www-data www-data # frozen_string_literal: true
module SimpleCov
VERSION = "0.18.1"
end
simplecov-0.18.1/lib/simplecov/combine/ 0000755 0000041 0000041 00000000000 13617303170 020016 5 ustar www-data www-data simplecov-0.18.1/lib/simplecov/combine/results_combiner.rb 0000644 0000041 0000041 00000003434 13617303170 023726 0 ustar www-data www-data # frozen_string_literal: true
module SimpleCov
module Combine
# There might be reports from different kinds of tests,
# e.g. RSpec and Cucumber. We need to combine their results
# into unified one. This class does that.
# To unite the results on file basis, it leverages
# the combine of lines and branches inside each file within given results.
module ResultsCombiner
module_function
#
# Combine process explanation
# => ResultCombiner: define all present files between results and start combine on file level.
# ==> FileCombiner: collect result of next combine levels lines and branches.
# ===> LinesCombiner: combine lines results.
# ===> BranchesCombiner: combine branches results.
#
# @return [Hash]
#
def combine(*results)
results.reduce({}) do |combined_results, next_result|
combine_result_sets(combined_results, next_result)
end
end
#
# Manage combining results on files level
#
# @param [Hash] combined_results
# @param [Hash] result
#
# @return [Hash]
#
def combine_result_sets(combined_results, result)
results_files = combined_results.keys | result.keys
results_files.each_with_object({}) do |file_name, file_combination|
file_combination[file_name] = combine_file_coverage(
combined_results[file_name],
result[file_name]
)
end
end
#
# Combine two files coverage results
#
# @param [Hash] coverage_a
# @param [Hash] coverage_b
#
# @return [Hash]
#
def combine_file_coverage(coverage_a, coverage_b)
Combine.combine(Combine::FilesCombiner, coverage_a, coverage_b)
end
end
end
end
simplecov-0.18.1/lib/simplecov/combine/branches_combiner.rb 0000644 0000041 0000041 00000002255 13617303170 024012 0 ustar www-data www-data # frozen_string_literal: true
module SimpleCov
module Combine
#
# Combine different branch coverage results on single file.
#
# Should be called through `SimpleCov.combine`.
module BranchesCombiner
module_function
#
# Return merged branches or the existed branche if other is missing.
#
# Branches inside files are always same if they exists, the difference only in coverage count.
# Branch coverage report for any conditional case is built from hash, it's key is a condition and
# it's body is a hash << keys from condition and value is coverage rate >>.
# ex: branches =>{ [:if, 3, 8, 6, 8, 36] => {[:then, 4, 8, 6, 8, 12] => 1, [:else, 5, 8, 6, 8, 36]=>2}, other conditions...}
# We create copy of result and update it values depending on the combined branches coverage values.
#
# @return [Hash]
#
def combine(coverage_a, coverage_b)
coverage_a.merge(coverage_b) do |_condition, branches_inside_a, branches_inside_b|
branches_inside_a.merge(branches_inside_b) do |_branch, a_count, b_count|
a_count + b_count
end
end
end
end
end
end
simplecov-0.18.1/lib/simplecov/combine/lines_combiner.rb 0000644 0000041 0000041 00000001757 13617303170 023345 0 ustar www-data www-data # frozen_string_literal: true
module SimpleCov
module Combine
#
# Combine two different lines coverage results on same file
#
# Should be called through `SimpleCov.combine`.
module LinesCombiner
module_function
def combine(coverage_a, coverage_b)
coverage_a
.zip(coverage_b)
.map do |coverage_a_val, coverage_b_val|
merge_line_coverage(coverage_a_val, coverage_b_val)
end
end
# Return depends on coverage in a specific line
#
# @param [Integer || nil] first_val
# @param [Integer || nil] second_val
#
# Logic:
#
# => nil + 0 = nil
# => nil + nil = nil
# => int + int = int
#
# @return [Integer || nil]
def merge_line_coverage(first_val, second_val)
sum = first_val.to_i + second_val.to_i
if sum.zero? && (first_val.nil? || second_val.nil?)
nil
else
sum
end
end
end
end
end
simplecov-0.18.1/lib/simplecov/combine/files_combiner.rb 0000644 0000041 0000041 00000001250 13617303170 023321 0 ustar www-data www-data # frozen_string_literal: true
module SimpleCov
module Combine
#
# Handle combining two coverage results for same file
#
# Should be called through `SimpleCov.combine`.
module FilesCombiner
module_function
#
# Combines the results for 2 coverages of a file.
#
# @return [Hash]
#
def combine(coverage_a, coverage_b)
combination = {"lines" => Combine.combine(LinesCombiner, coverage_a["lines"], coverage_b["lines"])}
combination["branches"] = Combine.combine(BranchesCombiner, coverage_a["branches"], coverage_b["branches"]) if SimpleCov.branch_coverage?
combination
end
end
end
end
simplecov-0.18.1/lib/simplecov/command_guesser.rb 0000644 0000041 0000041 00000004007 13617303170 022103 0 ustar www-data www-data # frozen_string_literal: true
module SimpleCov
#
# Helper that tries to find out what test suite is running (for SimpleCov.command_name)
#
module CommandGuesser
class << self
# Storage for the original command line call that invoked the test suite.
# This has got to be stored as early as possible because i.e. rake and test/unit 2
# have a habit of tampering with ARGV, which makes i.e. the automatic distinction
# between rails unit/functional/integration tests impossible without this cached
# item.
attr_accessor :original_run_command
def guess
from_env || from_command_line_options || from_defined_constants
end
private
def from_env
# If being run from inside parallel_tests set the command name according to the process number
return unless ENV["PARALLEL_TEST_GROUPS"] && ENV["TEST_ENV_NUMBER"]
number = ENV["TEST_ENV_NUMBER"]
number = "1" if number.empty?
"(#{number}/#{ENV['PARALLEL_TEST_GROUPS']})"
end
def from_command_line_options
case original_run_command
when /test\/functional\//, /test\/\{.*functional.*\}\//
"Functional Tests"
when /test\/integration\//
"Integration Tests"
when /test\//
"Unit Tests"
when /spec/
"RSpec"
when /cucumber/, /features/
"Cucumber Features"
end
end
def from_defined_constants
# If the command regexps fail, let's try checking defined constants.
if defined?(RSpec)
"RSpec"
elsif defined?(Test::Unit)
"Unit Tests"
elsif defined?(Minitest)
"Minitest"
elsif defined?(MiniTest)
"MiniTest"
else
# TODO: Provide link to docs/wiki article
warn "SimpleCov failed to recognize the test framework and/or suite used. Please specify manually using SimpleCov.command_name 'Unit Tests'."
"Unknown Test Framework"
end
end
end
end
end
simplecov-0.18.1/lib/simplecov/load_global_config.rb 0000644 0000041 0000041 00000000461 13617303170 022514 0 ustar www-data www-data # frozen_string_literal: true
require "etc"
home_dir = (ENV["HOME"] && File.expand_path("~")) || Etc.getpwuid.dir || (ENV["USER"] && File.expand_path("~#{ENV['USER']}"))
if home_dir
global_config_path = File.join(home_dir, ".simplecov")
load global_config_path if File.exist?(global_config_path)
end
simplecov-0.18.1/lib/simplecov/file_list.rb 0000644 0000041 0000041 00000006456 13617303170 020714 0 ustar www-data www-data # frozen_string_literal: true
module SimpleCov
# An array of SimpleCov SourceFile instances with additional collection helper
# methods for calculating coverage across them etc.
class FileList
include Enumerable
extend Forwardable
def_delegators :@files,
# For Enumerable
:each,
# also delegating methods implemented in Enumerable as they have
# custom Array implementations which are presumably better/more
# resource efficient
:size, :map, :count,
# surprisingly not in Enumerable
:empty?, :length,
# still act like we're kinda an array
:to_a, :to_ary
def initialize(files)
@files = files
end
def coverage_statistics
@coverage_statistics ||= compute_coverage_statistics
end
# Returns the count of lines that have coverage
def covered_lines
coverage_statistics[:line]&.covered
end
# Returns the count of lines that have been missed
def missed_lines
coverage_statistics[:line]&.missed
end
# Returns the count of lines that are not relevant for coverage
def never_lines
return 0.0 if empty?
map { |f| f.never_lines.count }.inject(:+)
end
# Returns the count of skipped lines
def skipped_lines
return 0.0 if empty?
map { |f| f.skipped_lines.count }.inject(:+)
end
# Computes the coverage based upon lines covered and lines missed for each file
# Returns an array with all coverage percentages
def covered_percentages
map(&:covered_percent)
end
# Finds the least covered file and returns that file's name
def least_covered_file
min_by(&:covered_percent).filename
end
# Returns the overall amount of relevant lines of code across all files in this list
def lines_of_code
coverage_statistics[:line]&.total
end
# Computes the coverage based upon lines covered and lines missed
# @return [Float]
def covered_percent
coverage_statistics[:line]&.percent
end
# Computes the strength (hits / line) based upon lines covered and lines missed
# @return [Float]
def covered_strength
coverage_statistics[:line]&.strength
end
# Return total count of branches in all files
def total_branches
coverage_statistics[:branch]&.total
end
# Return total count of covered branches
def covered_branches
coverage_statistics[:branch]&.covered
end
# Return total count of covered branches
def missed_branches
coverage_statistics[:branch]&.missed
end
def branch_covered_percent
coverage_statistics[:branch]&.percent
end
private
def compute_coverage_statistics
total_coverage_statistics = @files.each_with_object(line: [], branch: []) do |file, together|
together[:line] << file.coverage_statistics[:line]
together[:branch] << file.coverage_statistics[:branch] if SimpleCov.branch_coverage?
end
coverage_statistics = {line: CoverageStatistics.from(total_coverage_statistics[:line])}
coverage_statistics[:branch] = CoverageStatistics.from(total_coverage_statistics[:branch]) if SimpleCov.branch_coverage?
coverage_statistics
end
end
end
simplecov-0.18.1/lib/simplecov/useless_results_remover.rb 0000644 0000041 0000041 00000000575 13617303170 023741 0 ustar www-data www-data # frozen_string_literal: true
module SimpleCov
#
# Select the files that related to working scope directory of SimpleCov
#
module UselessResultsRemover
ROOT_REGX = /\A#{Regexp.escape(SimpleCov.root + File::SEPARATOR)}/io.freeze
def self.call(coverage_result)
coverage_result.select do |path, _coverage|
path =~ ROOT_REGX
end
end
end
end
simplecov-0.18.1/lib/simplecov/combine.rb 0000644 0000041 0000041 00000001421 13617303170 020341 0 ustar www-data www-data # frozen_string_literal: true
module SimpleCov
# Functionally for combining coverage results
#
module Combine
module_function
#
# Combine two coverage based on the given combiner_module.
#
# Combiners should always be called throught his interface,
# as it takes care of short circuting of one of the coverages is nil.
#
# @return [Hash]
def combine(combiner_module, coverage_a, coverage_b)
return existing_coverage(coverage_a, coverage_b) if empty_coverage?(coverage_a, coverage_b)
combiner_module.combine(coverage_a, coverage_b)
end
def empty_coverage?(coverage_a, coverage_b)
!(coverage_a && coverage_b)
end
def existing_coverage(coverage_a, coverage_b)
coverage_a || coverage_b
end
end
end
simplecov-0.18.1/lib/simplecov/exit_codes.rb 0000644 0000041 0000041 00000000246 13617303170 021057 0 ustar www-data www-data # frozen_string_literal: true
module SimpleCov
module ExitCodes
SUCCESS = 0
EXCEPTION = 1
MINIMUM_COVERAGE = 2
MAXIMUM_COVERAGE_DROP = 3
end
end
simplecov-0.18.1/lib/simplecov/source_file/ 0000755 0000041 0000041 00000000000 13617303170 020701 5 ustar www-data www-data simplecov-0.18.1/lib/simplecov/source_file/line.rb 0000644 0000041 0000041 00000004571 13617303170 022164 0 ustar www-data www-data # frozen_string_literal: true
module SimpleCov
class SourceFile
# Representation of a single line in a source file including
# this specific line's source code, line_number and code coverage,
# with the coverage being either nil (coverage not applicable, e.g. comment
# line), 0 (line not covered) or >1 (the amount of times the line was
# executed)
class Line
# The source code for this line. Aliased as :source
attr_reader :src
# The line number in the source file. Aliased as :line, :number
attr_reader :line_number
# The coverage data for this line: either nil (never), 0 (missed) or >=1 (times covered)
attr_reader :coverage
# Whether this line was skipped
attr_reader :skipped
# Lets grab some fancy aliases, shall we?
alias source src
alias line line_number
alias number line_number
def initialize(src, line_number, coverage)
raise ArgumentError, "Only String accepted for source" unless src.is_a?(String)
raise ArgumentError, "Only Integer accepted for line_number" unless line_number.is_a?(Integer)
raise ArgumentError, "Only Integer and nil accepted for coverage" unless coverage.is_a?(Integer) || coverage.nil?
@src = src
@line_number = line_number
@coverage = coverage
@skipped = false
end
# Returns true if this is a line that should have been covered, but was not
def missed?
!never? && !skipped? && coverage.zero?
end
# Returns true if this is a line that has been covered
def covered?
!never? && !skipped? && coverage.positive?
end
# Returns true if this line is not relevant for coverage
def never?
!skipped? && coverage.nil?
end
# Flags this line as skipped
def skipped!
@skipped = true
end
# Returns true if this line was skipped, false otherwise. Lines are skipped if they are wrapped with
# # :nocov: comment lines.
def skipped?
!!skipped
end
# The status of this line - either covered, missed, skipped or never. Useful i.e. for direct use
# as a css class in report generation
def status
return "skipped" if skipped?
return "never" if never?
return "missed" if missed?
return "covered" if covered?
end
end
end
end
simplecov-0.18.1/lib/simplecov/source_file/branch.rb 0000644 0000041 0000041 00000003731 13617303170 022467 0 ustar www-data www-data # frozen_string_literal: true
module SimpleCov
class SourceFile
#
# Representing single branch that has been detected in coverage report.
# Give us support methods that handle needed calculations.
class Branch
attr_reader :start_line, :end_line, :coverage, :type
# rubocop:disable Metrics/ParameterLists
def initialize(start_line:, end_line:, coverage:, inline:, type:)
@start_line = start_line
@end_line = end_line
@coverage = coverage
@inline = inline
@type = type
@skipped = false
end
# rubocop:enable Metrics/ParameterLists
def inline?
@inline
end
#
# Return true if there is relevant count defined > 0
#
# @return [Boolean]
#
def covered?
!skipped? && coverage.positive?
end
#
# Check if branche missed or not
#
# @return [Boolean]
#
def missed?
!skipped? && coverage.zero?
end
# The line on which we want to report the coverage
#
# Usually we choose the line above the start of the branch (so that it shows up
# at if/else) because that
# * highlights the condition
# * makes it distinguishable if the first line of the branch is an inline branch
# (see the nested_branches fixture)
#
def report_line
if inline?
start_line
else
start_line - 1
end
end
# Flags the branch as skipped
def skipped!
@skipped = true
end
# Returns true if the branch was marked skipped by virtue of nocov comments.
def skipped?
@skipped
end
def overlaps_with?(line_range)
start_line <= line_range.end && end_line >= line_range.begin
end
#
# Return array with coverage count and badge
#
# @return [Array]
#
def report
[type, coverage]
end
end
end
end
simplecov-0.18.1/lib/simplecov/formatter/ 0000755 0000041 0000041 00000000000 13617303170 020405 5 ustar www-data www-data simplecov-0.18.1/lib/simplecov/formatter/simple_formatter.rb 0000644 0000041 0000041 00000001166 13617303170 024312 0 ustar www-data www-data # frozen_string_literal: true
module SimpleCov
module Formatter
#
# A ridiculously simple formatter for SimpleCov results.
#
class SimpleFormatter
# Takes a SimpleCov::Result and generates a string out of it
def format(result)
output = +""
result.groups.each do |name, files|
output << "Group: #{name}\n"
output << "=" * 40
output << "\n"
files.each do |file|
output << "#{file.filename} (coverage: #{file.covered_percent.round(2)}%)\n"
end
output << "\n"
end
output
end
end
end
end
simplecov-0.18.1/lib/simplecov/formatter/multi_formatter.rb 0000644 0000041 0000041 00000001522 13617303170 024147 0 ustar www-data www-data # frozen_string_literal: true
module SimpleCov
module Formatter
class MultiFormatter
module InstanceMethods
def format(result)
formatters.map do |formatter|
begin
formatter.new.format(result)
rescue StandardError => e
warn("Formatter #{formatter} failed with #{e.class}: #{e.message} (#{e.backtrace.first})")
nil
end
end
end
end
def self.new(formatters = nil)
Class.new do
define_method :formatters do
@formatters ||= Array(formatters)
end
include InstanceMethods
end
end
def self.[](*args)
warn "#{Kernel.caller.first}: [DEPRECATION] ::[] is deprecated. Use ::new instead."
new(Array([*args]))
end
end
end
end
simplecov-0.18.1/lib/simplecov/simulate_coverage.rb 0000644 0000041 0000041 00000001271 13617303170 022426 0 ustar www-data www-data # frozen_string_literal: true
module SimpleCov
#
# Responsible for producing file coverage metrics.
#
module SimulateCoverage
module_function
#
# Simulate normal file coverage report on
# ruby 2.5 and return similar hash with lines and branches keys
#
# Happens when a file wasn't required but still tracked.
#
# @return [Hash]
#
def call(absolute_path)
lines = File.foreach(absolute_path)
{
"lines" => LinesClassifier.new.classify(lines),
# we don't want to parse branches ourselves...
# requiring files can have side effects and we don't want to trigger that
"branches" => {}
}
end
end
end
simplecov-0.18.1/lib/simplecov/result.rb 0000644 0000041 0000041 00000007610 13617303170 020251 0 ustar www-data www-data # frozen_string_literal: true
require "digest/sha1"
require "forwardable"
module SimpleCov
#
# A simplecov code coverage result, initialized from the Hash Ruby's built-in coverage
# library generates (Coverage.result).
#
class Result
extend Forwardable
# Returns the original Coverage.result used for this instance of SimpleCov::Result
attr_reader :original_result
# Returns all files that are applicable to this result (sans filters!) as instances of SimpleCov::SourceFile. Aliased as :source_files
attr_reader :files
alias source_files files
# Explicitly set the Time this result has been created
attr_writer :created_at
# Explicitly set the command name that was used for this coverage result. Defaults to SimpleCov.command_name
attr_writer :command_name
def_delegators :files, :covered_percent, :covered_percentages, :least_covered_file, :covered_strength, :covered_lines, :missed_lines, :total_branches, :covered_branches, :missed_branches, :coverage_statistics
def_delegator :files, :lines_of_code, :total_lines
# Initialize a new SimpleCov::Result from given Coverage.result (a Hash of filenames each containing an array of
# coverage data)
def initialize(original_result)
result = adapt_result(original_result)
@original_result = result.freeze
@files = SimpleCov::FileList.new(result.map do |filename, coverage|
SimpleCov::SourceFile.new(filename, JSON.parse(JSON.dump(coverage))) if File.file?(filename)
end.compact.sort_by(&:filename))
filter!
end
# Returns all filenames for source files contained in this result
def filenames
files.map(&:filename)
end
# Returns a Hash of groups for this result. Define groups using SimpleCov.add_group 'Models', 'app/models'
def groups
@groups ||= SimpleCov.grouped(files)
end
# Applies the configured SimpleCov.formatter on this result
def format!
SimpleCov.formatter.new.format(self)
end
# Defines when this result has been created. Defaults to Time.now
def created_at
@created_at ||= Time.now
end
# The command name that launched this result.
# Delegated to SimpleCov.command_name if not set manually
def command_name
@command_name ||= SimpleCov.command_name
end
# Returns a hash representation of this Result that can be used for marshalling it into JSON
def to_hash
{
command_name => {
"coverage" => coverage,
"timestamp" => created_at.to_i
}
}
end
# Loads a SimpleCov::Result#to_hash dump
def self.from_hash(hash)
command_name, data = hash.first
result = SimpleCov::Result.new(data["coverage"])
result.command_name = command_name
result.created_at = Time.at(data["timestamp"])
result
end
private
# We changed the format of the raw result data in simplecov, as people are likely
# to have "old" resultsets lying around (but not too old so that they're still
# considered we can adapt them).
# See https://github.com/colszowka/simplecov/pull/824#issuecomment-576049747
def adapt_result(result)
if pre_simplecov_0_18_result?(result)
adapt_pre_simplecov_0_18_result(result)
else
result
end
end
# pre 0.18 coverage data pointed from file directly to an array of line coverage
def pre_simplecov_0_18_result?(result)
_key, data = result.first
data.is_a?(Array)
end
def adapt_pre_simplecov_0_18_result(result)
result.map do |file_path, line_coverage_data|
[file_path, {"lines" => line_coverage_data}]
end.to_h
end
def coverage
keys = original_result.keys & filenames
Hash[keys.zip(original_result.values_at(*keys))]
end
# Applies all configured SimpleCov filters on this result's source files
def filter!
@files = SimpleCov.filtered(files)
end
end
end
simplecov-0.18.1/lib/simplecov/configuration.rb 0000644 0000041 0000041 00000032053 13617303170 021601 0 ustar www-data www-data # frozen_string_literal: true
require "fileutils"
require "docile"
require "simplecov/formatter/multi_formatter"
module SimpleCov
#
# Bundles the configuration options used for SimpleCov. All methods
# defined here are usable from SimpleCov directly. Please check out
# SimpleCov documentation for further info.
#
module Configuration # rubocop:disable Metrics/ModuleLength
attr_writer :filters, :groups, :formatter, :print_error_status
#
# The root for the project. This defaults to the
# current working directory.
#
# Configure with SimpleCov.root('/my/project/path')
#
def root(root = nil)
return @root if defined?(@root) && root.nil?
@root = File.expand_path(root || Dir.getwd)
end
#
# The name of the output and cache directory. Defaults to 'coverage'
#
# Configure with SimpleCov.coverage_dir('cov')
#
def coverage_dir(dir = nil)
return @coverage_dir if defined?(@coverage_dir) && dir.nil?
@coverage_path = nil # invalidate cache
@coverage_dir = (dir || "coverage")
end
#
# Returns the full path to the output directory using SimpleCov.root
# and SimpleCov.coverage_dir, so you can adjust this by configuring those
# values. Will create the directory if it's missing
#
def coverage_path
@coverage_path ||= begin
coverage_path = File.expand_path(coverage_dir, root)
FileUtils.mkdir_p coverage_path
coverage_path
end
end
#
# Coverage results will always include files matched by this glob, whether
# or not they were explicitly required. Without this, un-required files
# will not be present in the final report.
#
def track_files(glob)
@tracked_files = glob
end
#
# Returns the glob that will be used to include files that were not
# explicitly required.
#
def tracked_files
@tracked_files if defined?(@tracked_files)
end
#
# Returns the list of configured filters. Add filters using SimpleCov.add_filter.
#
def filters
@filters ||= []
end
# The name of the command (a.k.a. Test Suite) currently running. Used for result
# merging and caching. It first tries to make a guess based upon the command line
# arguments the current test suite is running on and should automatically detect
# unit tests, functional tests, integration tests, rpsec and cucumber and label
# them properly. If it fails to recognize the current command, the command name
# is set to the shell command that the current suite is running on.
#
# You can specify it manually with SimpleCov.command_name("test:units") - please
# also check out the corresponding section in README.rdoc
def command_name(name = nil)
@name = name unless name.nil?
@name ||= SimpleCov::CommandGuesser.guess
@name
end
#
# Gets or sets the configured formatter.
#
# Configure with: SimpleCov.formatter(SimpleCov::Formatter::SimpleFormatter)
#
def formatter(formatter = nil)
return @formatter if defined?(@formatter) && formatter.nil?
@formatter = formatter
raise "No formatter configured. Please specify a formatter using SimpleCov.formatter = SimpleCov::Formatter::SimpleFormatter" unless @formatter
@formatter
end
#
# Sets the configured formatters.
#
def formatters=(formatters)
@formatter = SimpleCov::Formatter::MultiFormatter.new(formatters)
end
#
# Gets the configured formatters.
#
def formatters
if @formatter.is_a?(SimpleCov::Formatter::MultiFormatter)
@formatter.formatters
else
Array(formatter)
end
end
#
# Whether we should print non-success status codes. This can be
# configured with the #print_error_status= method.
#
def print_error_status
defined?(@print_error_status) ? @print_error_status : true
end
#
# Certain code blocks (i.e. Ruby-implementation specific code) can be excluded from
# the coverage metrics by wrapping it inside # :nocov: comment blocks. The nocov token
# can be configured to be any other string using this.
#
# Configure with SimpleCov.nocov_token('skip') or it's alias SimpleCov.skip_token('skip')
#
def nocov_token(nocov_token = nil)
return @nocov_token if defined?(@nocov_token) && nocov_token.nil?
@nocov_token = (nocov_token || "nocov")
end
alias skip_token nocov_token
#
# Returns the configured groups. Add groups using SimpleCov.add_group
#
def groups
@groups ||= {}
end
#
# Returns the hash of available profiles
#
def profiles
@profiles ||= SimpleCov::Profiles.new
end
def adapters
warn "#{Kernel.caller.first}: [DEPRECATION] #adapters is deprecated. Use #profiles instead."
profiles
end
#
# Allows you to configure simplecov in a block instead of prepending SimpleCov to all config methods
# you're calling.
#
# SimpleCov.configure do
# add_filter 'foobar'
# end
#
# This is equivalent to SimpleCov.add_filter 'foobar' and thus makes it easier to set a bunch of configure
# options at once.
#
def configure(&block)
Docile.dsl_eval(self, &block)
end
#
# Gets or sets the behavior to process coverage results.
#
# By default, it will call SimpleCov.result.format!
#
# Configure with:
#
# SimpleCov.at_exit do
# puts "Coverage done"
# SimpleCov.result.format!
# end
#
def at_exit(&block)
return proc {} unless running || block_given?
@at_exit = block if block_given?
@at_exit ||= proc { SimpleCov.result.format! }
end
#
# Returns the project name - currently assuming the last dirname in
# the SimpleCov.root is this.
#
def project_name(new_name = nil)
return @project_name if defined?(@project_name) && @project_name && new_name.nil?
@project_name = new_name if new_name.is_a?(String)
@project_name ||= File.basename(root.split("/").last).capitalize.tr("_", " ")
end
#
# Defines whether to use result merging so all your test suites (test:units, test:functionals, cucumber, ...)
# are joined and combined into a single coverage report
#
def use_merging(use = nil)
@use_merging = use unless use.nil?
@use_merging = true unless defined?(@use_merging) && @use_merging == false
end
#
# Defines the maximum age (in seconds) of a resultset to still be included in merged results.
# i.e. If you run cucumber features, then later rake test, if the stored cucumber resultset is
# more seconds ago than specified here, it won't be taken into account when merging (and is also
# purged from the resultset cache)
#
# Of course, this only applies when merging is active (e.g. SimpleCov.use_merging is not false!)
#
# Default is 600 seconds (10 minutes)
#
# Configure with SimpleCov.merge_timeout(3600) # 1hr
#
def merge_timeout(seconds = nil)
@merge_timeout = seconds if seconds.is_a?(Integer)
@merge_timeout ||= 600
end
#
# Defines the minimum overall coverage required for the testsuite to pass.
# SimpleCov will return non-zero if the current coverage is below this threshold.
#
# Default is 0% (disabled)
#
def minimum_coverage(coverage = nil)
return @minimum_coverage ||= {} unless coverage
coverage = {DEFAULT_COVERAGE_CRITERION => coverage} if coverage.is_a?(Numeric)
coverage.keys.each { |criterion| raise_if_criterion_disabled(criterion) }
coverage.values.each do |percent|
minimum_possible_coverage_exceeded("minimum_coverage") if percent && percent > 100
end
@minimum_coverage = coverage
end
#
# Defines the maximum coverage drop at once allowed for the testsuite to pass.
# SimpleCov will return non-zero if the coverage decreases by more than this threshold.
#
# Default is 100% (disabled)
#
def maximum_coverage_drop(coverage_drop = nil)
@maximum_coverage_drop ||= (coverage_drop || 100).to_f.round(2)
end
#
# Defines the minimum coverage per file required for the testsuite to pass.
# SimpleCov will return non-zero if the current coverage of the least covered file
# is below this threshold.
#
# Default is 0% (disabled)
#
def minimum_coverage_by_file(coverage = nil)
minimum_possible_coverage_exceeded("minimum_coverage_by_file") if coverage && coverage > 100
@minimum_coverage_by_file ||= (coverage || 0).to_f.round(2)
end
#
# Refuses any coverage drop. That is, coverage is only allowed to increase.
# SimpleCov will return non-zero if the coverage decreases.
#
def refuse_coverage_drop
maximum_coverage_drop 0
end
#
# Add a filter to the processing chain.
# There are four ways to define a filter:
#
# * as a String that will then be matched against all source files' file paths,
# SimpleCov.add_filter 'app/models' # will reject all your models
# * as a block which will be passed the source file in question and should either
# return a true or false value, depending on whether the file should be removed
# SimpleCov.add_filter do |src_file|
# File.basename(src_file.filename) == 'environment.rb'
# end # Will exclude environment.rb files from the results
# * as an array of strings that are matched against all sorce files' file
# paths and then ignored (basically string filter multiple times)
# SimpleCov.add_filter ['app/models', 'app/helpers'] # ignores both dirs
# * as an instance of a subclass of SimpleCov::Filter. See the documentation there
# on how to define your own filter classes
#
def add_filter(filter_argument = nil, &filter_proc)
filters << parse_filter(filter_argument, &filter_proc)
end
#
# Define a group for files. Works similar to add_filter, only that the first
# argument is the desired group name and files PASSING the filter end up in the group
# (while filters exclude when the filter is applicable).
#
def add_group(group_name, filter_argument = nil, &filter_proc)
groups[group_name] = parse_filter(filter_argument, &filter_proc)
end
SUPPORTED_COVERAGE_CRITERIA = %i[line branch].freeze
DEFAULT_COVERAGE_CRITERION = :line
#
# Define which coverage criterion should be evaluated.
#
# Possible coverage criteria:
# * :line - coverage based on lines aka has this line been executed?
# * :branch - coverage based on branches aka has this branch (think conditions) been executed?
#
# If not set the default is `:line`
#
# @param [Symbol] criterion
#
def coverage_criterion(criterion = nil)
return @coverage_criterion ||= DEFAULT_COVERAGE_CRITERION unless criterion
raise_if_criterion_unsupported(criterion)
@coverage_criterion = criterion
end
def enable_coverage(criterion)
raise_if_criterion_unsupported(criterion)
coverage_criteria << criterion
end
def coverage_criteria
@coverage_criteria ||= Set[DEFAULT_COVERAGE_CRITERION]
end
def coverage_criterion_enabled?(criterion)
coverage_criteria.member?(criterion)
end
def clear_coverage_criteria
@coverage_criteria = nil
end
def branch_coverage?
branch_coverage_supported? && coverage_criterion_enabled?(:branch)
end
def coverage_start_arguments_supported?
# safe to cache as within one process this value should never
# change
return @coverage_start_arguments_supported if defined?(@coverage_start_arguments_supported)
@coverage_start_arguments_supported = begin
require "coverage"
!Coverage.method(:start).arity.zero?
end
end
alias branch_coverage_supported? coverage_start_arguments_supported?
private
def raise_if_criterion_disabled(criterion)
raise_if_criterion_unsupported(criterion)
# rubocop:disable Style/IfUnlessModifier
unless coverage_criterion_enabled?(criterion)
raise "Coverage criterion #{criterion}, is disabled! Please enable it first through enable_coverage #{criterion} (if supported)"
end
# rubocop:enable Style/IfUnlessModifier
end
def raise_if_criterion_unsupported(criterion)
# rubocop:disable Style/IfUnlessModifier
unless SUPPORTED_COVERAGE_CRITERIA.member?(criterion)
raise "Unsupported coverage criterion #{criterion}, supported values are #{SUPPORTED_COVERAGE_CRITERIA}"
end
# rubocop:enable Style/IfUnlessModifier
end
def minimum_possible_coverage_exceeded(coverage_option)
warn "The coverage you set for #{coverage_option} is greater than 100%"
end
#
# The actual filter processor. Not meant for direct use
#
def parse_filter(filter_argument = nil, &filter_proc)
filter = filter_argument || filter_proc
if filter
SimpleCov::Filter.build_filter(filter)
else
raise ArgumentError, "Please specify either a filter or a block to filter with"
end
end
end
end
simplecov-0.18.1/lib/simplecov/filter.rb 0000644 0000041 0000041 00000005367 13617303170 020227 0 ustar www-data www-data # frozen_string_literal: true
module SimpleCov
#
# Base filter class. Inherit from this to create custom filters,
# and overwrite the passes?(source_file) instance method
#
# # A sample class that rejects all source files.
# class StupidFilter < SimpleCov::Filter
# def passes?(source_file)
# false
# end
# end
#
class Filter
attr_reader :filter_argument
def initialize(filter_argument)
@filter_argument = filter_argument
end
def matches?(_source_file)
raise "The base filter class is not intended for direct use"
end
def passes?(source_file)
warn "#{Kernel.caller.first}: [DEPRECATION] #passes? is deprecated. Use #matches? instead."
matches?(source_file)
end
def self.build_filter(filter_argument)
return filter_argument if filter_argument.is_a?(SimpleCov::Filter)
class_for_argument(filter_argument).new(filter_argument)
end
def self.class_for_argument(filter_argument)
if filter_argument.is_a?(String)
SimpleCov::StringFilter
elsif filter_argument.is_a?(Regexp)
SimpleCov::RegexFilter
elsif filter_argument.is_a?(Array)
SimpleCov::ArrayFilter
elsif filter_argument.is_a?(Proc)
SimpleCov::BlockFilter
else
raise ArgumentError, "You have provided an unrecognized filter type"
end
end
end
class StringFilter < SimpleCov::Filter
# Returns true when the given source file's filename matches the
# string configured when initializing this Filter with StringFilter.new('somestring)
def matches?(source_file)
source_file.project_filename.include?(filter_argument)
end
end
class RegexFilter < SimpleCov::Filter
# Returns true when the given source file's filename matches the
# regex configured when initializing this Filter with RegexFilter.new(/someregex/)
def matches?(source_file)
(source_file.project_filename =~ filter_argument)
end
end
class BlockFilter < SimpleCov::Filter
# Returns true if the block given when initializing this filter with BlockFilter.new {|src_file| ... }
# returns true for the given source file.
def matches?(source_file)
filter_argument.call(source_file)
end
end
class ArrayFilter < SimpleCov::Filter
def initialize(filter_argument)
filter_objects = filter_argument.map do |arg|
Filter.build_filter(arg)
end
super(filter_objects)
end
# Returns true if any of the filters in the array match the given source file.
# Configure this Filter like StringFilter.new(['some/path', /^some_regex/, Proc.new {|src_file| ... }])
def matches?(source_files_list)
filter_argument.any? do |arg|
arg.matches?(source_files_list)
end
end
end
end
simplecov-0.18.1/lib/simplecov/lines_classifier.rb 0000644 0000041 0000041 00000002236 13617303170 022250 0 ustar www-data www-data # frozen_string_literal: true
module SimpleCov
# Classifies whether lines are relevant for code coverage analysis.
# Comments & whitespace lines, and :nocov: token blocks, are considered not relevant.
class LinesClassifier
RELEVANT = 0
NOT_RELEVANT = nil
WHITESPACE_LINE = /^\s*$/.freeze
COMMENT_LINE = /^\s*#/.freeze
WHITESPACE_OR_COMMENT_LINE = Regexp.union(WHITESPACE_LINE, COMMENT_LINE)
def self.no_cov_line
/^(\s*)#(\s*)(\:#{SimpleCov.nocov_token}\:)/o
end
def self.no_cov_line?(line)
line =~ no_cov_line
rescue ArgumentError
# E.g., line contains an invalid byte sequence in UTF-8
false
end
def self.whitespace_line?(line)
line =~ WHITESPACE_OR_COMMENT_LINE
rescue ArgumentError
# E.g., line contains an invalid byte sequence in UTF-8
false
end
def classify(lines)
skipping = false
lines.map do |line|
if self.class.no_cov_line?(line)
skipping = !skipping
NOT_RELEVANT
elsif skipping || self.class.whitespace_line?(line)
NOT_RELEVANT
else
RELEVANT
end
end
end
end
end
simplecov-0.18.1/lib/simplecov/profiles.rb 0000644 0000041 0000041 00000001614 13617303170 020554 0 ustar www-data www-data # frozen_string_literal: true
module SimpleCov
#
# Profiles are SimpleCov configuration procs that can be easily
# loaded using SimpleCov.start :rails and defined using
# SimpleCov.profiles.define :foo do
# # SimpleCov configuration here, same as in SimpleCov.configure
# end
#
class Profiles < Hash
#
# Define a SimpleCov profile:
# SimpleCov.profiles.define 'rails' do
# # Same as SimpleCov.configure do .. here
# end
#
def define(name, &blk)
name = name.to_sym
raise "SimpleCov Profile '#{name}' is already defined" unless self[name].nil?
self[name] = blk
end
#
# Applies the profile of given name on SimpleCov.configure
#
def load(name)
name = name.to_sym
raise "Could not find SimpleCov Profile called '#{name}'" unless key?(name)
SimpleCov.configure(&self[name])
end
end
end
simplecov-0.18.1/lib/simplecov/result_merger.rb 0000644 0000041 0000041 00000007650 13617303170 021616 0 ustar www-data www-data # frozen_string_literal: true
require "json"
module SimpleCov
#
# Singleton that is responsible for caching, loading and merging
# SimpleCov::Results into a single result for coverage analysis based
# upon multiple test suites.
#
module ResultMerger
class << self
# The path to the .resultset.json cache file
def resultset_path
File.join(SimpleCov.coverage_path, ".resultset.json")
end
def resultset_writelock
File.join(SimpleCov.coverage_path, ".resultset.json.lock")
end
# Loads the cached resultset from JSON and returns it as a Hash,
# caching it for subsequent accesses.
def resultset
@resultset ||= begin
data = stored_data
if data
begin
JSON.parse(data) || {}
rescue StandardError
{}
end
else
{}
end
end
end
# Returns the contents of the resultset cache as a string or if the file is missing or empty nil
def stored_data
synchronize_resultset do
return unless File.exist?(resultset_path)
data = File.read(resultset_path)
return if data.nil? || data.length < 2
data
end
end
# Gets the resultset hash and re-creates all included instances
# of SimpleCov::Result from that.
# All results that are above the SimpleCov.merge_timeout will be
# dropped. Returns an array of SimpleCov::Result items.
def results
results = []
resultset.each do |command_name, data|
result = SimpleCov::Result.from_hash(command_name => data)
# Only add result if the timeout is above the configured threshold
results << result if (Time.now - result.created_at) < SimpleCov.merge_timeout
end
results
end
def merge_and_store(*results)
result = merge_results(*results)
store_result(result) if result
result
end
# Merge two or more SimpleCov::Results into a new one with merged
# coverage data and the command_name for the result consisting of a join
# on all source result's names
def merge_results(*results)
parsed_results = JSON.parse(JSON.dump(results.map(&:original_result)))
combined_result = SimpleCov::Combine::ResultsCombiner.combine(*parsed_results)
result = SimpleCov::Result.new(combined_result)
# Specify the command name
result.command_name = results.map(&:command_name).sort.join(", ")
result
end
#
# Gets all SimpleCov::Results from cache, merges them and produces a new
# SimpleCov::Result with merged coverage data and the command_name
# for the result consisting of a join on all source result's names
#
def merged_result
merge_results(*results)
end
# Saves the given SimpleCov::Result in the resultset cache
def store_result(result)
synchronize_resultset do
# Ensure we have the latest, in case it was already cached
clear_resultset
new_set = resultset
command_name, data = result.to_hash.first
new_set[command_name] = data
File.open(resultset_path, "w+") do |f_|
f_.puts JSON.pretty_generate(new_set)
end
end
true
end
# Ensure only one process is reading or writing the resultset at any
# given time
def synchronize_resultset
# make it reentrant
return yield if defined?(@resultset_locked) && @resultset_locked
begin
@resultset_locked = true
File.open(resultset_writelock, "w+") do |f|
f.flock(File::LOCK_EX)
yield
end
ensure
@resultset_locked = false
end
end
# Clear out the previously cached .resultset
def clear_resultset
@resultset = nil
end
end
end
end
simplecov-0.18.1/lib/simplecov/last_run.rb 0000644 0000041 0000041 00000001054 13617303170 020556 0 ustar www-data www-data # frozen_string_literal: true
require "json"
module SimpleCov
module LastRun
class << self
def last_run_path
File.join(SimpleCov.coverage_path, ".last_run.json")
end
def read
return nil unless File.exist?(last_run_path)
json = File.read(last_run_path)
return nil if json.strip.empty?
JSON.parse(json, symbolize_names: true)
end
def write(json)
File.open(last_run_path, "w+") do |f|
f.puts JSON.pretty_generate(json)
end
end
end
end
end
simplecov-0.18.1/lib/simplecov/defaults.rb 0000644 0000041 0000041 00000003041 13617303170 020534 0 ustar www-data www-data # frozen_string_literal: true
# Load default formatter gem
require "simplecov-html"
require "pathname"
require "simplecov/profiles/root_filter"
require "simplecov/profiles/test_frameworks"
require "simplecov/profiles/bundler_filter"
require "simplecov/profiles/hidden_filter"
require "simplecov/profiles/rails"
# Default configuration
SimpleCov.configure do
formatter SimpleCov::Formatter::HTMLFormatter
load_profile "bundler_filter"
load_profile "hidden_filter"
# Exclude files outside of SimpleCov.root
load_profile "root_filter"
end
# Gotta stash this a-s-a-p, see the CommandGuesser class and i.e. #110 for further info
SimpleCov::CommandGuesser.original_run_command = "#{$PROGRAM_NAME} #{ARGV.join(' ')}"
at_exit do
# If we are in a different process than called start, don't interfere.
next if SimpleCov.pid != Process.pid
# If SimpleCov is no longer running then don't run exit tasks
next unless SimpleCov.running
SimpleCov.run_exit_tasks!
end
# Autoload config from ~/.simplecov if present
require "simplecov/load_global_config"
# Autoload config from .simplecov if present
# Recurse upwards until we find .simplecov or reach the root directory
config_path = Pathname.new(SimpleCov.root)
loop do
filename = config_path.join(".simplecov")
if filename.exist?
begin
load filename
rescue LoadError, StandardError
warn "Warning: Error occurred while trying to load #{filename}. " \
"Error message: #{$!.message}"
end
break
end
config_path, = config_path.split
break if config_path.root?
end
simplecov-0.18.1/lib/simplecov/source_file.rb 0000644 0000041 0000041 00000021521 13617303170 021227 0 ustar www-data www-data # frozen_string_literal: true
module SimpleCov
#
# Representation of a source file including it's coverage data, source code,
# source lines and featuring helpers to interpret that data.
#
class SourceFile
# The full path to this source file (e.g. /User/colszowka/projects/simplecov/lib/simplecov/source_file.rb)
attr_reader :filename
# The array of coverage data received from the Coverage.result
attr_reader :coverage_data
def initialize(filename, coverage_data)
@filename = filename
@coverage_data = coverage_data
end
# The path to this source file relative to the projects directory
def project_filename
@filename.sub(Regexp.new("^#{Regexp.escape(SimpleCov.root)}"), "")
end
# The source code for this file. Aliased as :source
def src
# We intentionally read source code lazily to
# suppress reading unused source code.
@src ||= File.open(filename, "rb", &:readlines)
end
alias source src
def coverage_statistics
@coverage_statistics ||=
{
**line_coverage_statistics,
**branch_coverage_statistics
}
end
# Returns all source lines for this file as instances of SimpleCov::SourceFile::Line,
# and thus including coverage data. Aliased as :source_lines
def lines
@lines ||= build_lines
end
alias source_lines lines
# Returns all covered lines as SimpleCov::SourceFile::Line
def covered_lines
@covered_lines ||= lines.select(&:covered?)
end
# Returns all lines that should have been, but were not covered
# as instances of SimpleCov::SourceFile::Line
def missed_lines
@missed_lines ||= lines.select(&:missed?)
end
# Returns all lines that are not relevant for coverage as
# SimpleCov::SourceFile::Line instances
def never_lines
@never_lines ||= lines.select(&:never?)
end
# Returns all lines that were skipped as SimpleCov::SourceFile::Line instances
def skipped_lines
@skipped_lines ||= lines.select(&:skipped?)
end
# Returns the number of relevant lines (covered + missed)
def lines_of_code
coverage_statistics[:line]&.total
end
# Access SimpleCov::SourceFile::Line source lines by line number
def line(number)
lines[number - 1]
end
# The coverage for this file in percent. 0 if the file has no coverage lines
def covered_percent
coverage_statistics[:line]&.percent
end
def covered_strength
coverage_statistics[:line]&.strength
end
def no_lines?
lines.length.zero? || (lines.length == never_lines.size)
end
def relevant_lines
lines.size - never_lines.size - skipped_lines.size
end
#
# Return all the branches inside current source file
def branches
@branches ||= build_branches
end
def no_branches?
total_branches.empty?
end
def branches_coverage_percent
coverage_statistics[:branch]&.percent
end
#
# Return the relevant branches to source file
def total_branches
@total_branches ||= covered_branches + missed_branches
end
#
# Return hash with key of line number and branch coverage count as value
def branches_report
@branches_report ||= build_branches_report
end
#
# Select the covered branches
# Here we user tree schema because some conditions like case may have additional
# else that is not in declared inside the code but given by default by coverage report
#
# @return [Array]
#
def covered_branches
@covered_branches ||= branches.select(&:covered?)
end
#
# Select the missed branches with coverage equal to zero
#
# @return [Array]
#
def missed_branches
@missed_branches ||= branches.select(&:missed?)
end
def branches_for_line(line_number)
branches_report.fetch(line_number, [])
end
#
# Check if any branches missing on given line number
#
# @param [Integer] line_number
#
# @return [Boolean]
#
def line_with_missed_branch?(line_number)
branches_for_line(line_number).select { |_type, count| count.zero? }.any?
end
private
# no_cov_chunks is zero indexed to work directly with the array holding the lines
def no_cov_chunks
@no_cov_chunks ||= build_no_cov_chunks
end
def build_no_cov_chunks
no_cov_lines = src.map.with_index(1).select { |line_src, _index| LinesClassifier.no_cov_line?(line_src) }
# if we have an uneven number of nocovs we assume they go to the
# end of the file, the source doesn't really matter
# Can't deal with this within the each_slice due to differing
# behavior in JRuby: jruby/jruby#6048
no_cov_lines << ["", src.size] if no_cov_lines.size.odd?
no_cov_lines.each_slice(2).map do |(_line_src_start, index_start), (_line_src_end, index_end)|
index_start..index_end
end
end
def build_lines
coverage_exceeding_source_warn if coverage_data["lines"].size > src.size
lines = src.map.with_index(1) do |src, i|
SimpleCov::SourceFile::Line.new(src, i, coverage_data["lines"][i - 1])
end
process_skipped_lines(lines)
end
def process_skipped_lines(lines)
# the array the lines are kept in is 0-based whereas the line numbers in the nocov
# chunks are 1-based and are expected to be like this in other parts (and it's also
# arguably more understandable)
no_cov_chunks.each { |chunk| lines[(chunk.begin - 1)..(chunk.end - 1)].each(&:skipped!) }
lines
end
def lines_strength
lines.map(&:coverage).compact.reduce(:+)
end
# Warning to identify condition from Issue #56
def coverage_exceeding_source_warn
warn "Warning: coverage data provided by Coverage [#{coverage_data['lines'].size}] exceeds number of lines in #{filename} [#{src.size}]"
end
#
# Build full branches report
# Root branches represent the wrapper of all condition state that
# have inside the branches
#
# @return [Hash]
#
def build_branches_report
branches.reject(&:skipped?).each_with_object({}) do |branch, coverage_statistics|
coverage_statistics[branch.report_line] ||= []
coverage_statistics[branch.report_line] << branch.report
end
end
#
# Call recursive method that transform our static hash to array of objects
# @return [Array]
#
def build_branches
coverage_branch_data = coverage_data.fetch("branches", {})
branches = coverage_branch_data.flat_map do |condition, coverage_branches|
build_branches_from(condition, coverage_branches)
end
process_skipped_branches(branches)
end
def process_skipped_branches(branches)
return branches if no_cov_chunks.empty?
branches.each do |branch|
branch.skipped! if no_cov_chunks.any? { |no_cov_chunk| branch.overlaps_with?(no_cov_chunk) }
end
branches
end
# Since we are dumping to and loading from JSON, and we have arrays as keys those
# don't make their way back to us intact e.g. just as a string
#
# We should probably do something different here, but as it stands these are
# our data structures that we write so eval isn't _too_ bad.
#
# See #801
#
def restore_ruby_data_structure(structure)
# Tests use the real data structures (except for integration tests) so no need to
# put them through here.
return structure if structure.is_a?(Array)
# rubocop:disable Security/Eval
eval structure
# rubocop:enable Security/Eval
end
def build_branches_from(condition, branches)
# the format handed in from the coverage data is like this:
#
# [:then, 4, 6, 6, 6, 10]
#
# which is [type, id, start_line, start_col, end_line, end_col]
_condition_type, _condition_id, condition_start_line, * = restore_ruby_data_structure(condition)
branches.map do |branch_data, hit_count|
branch_data = restore_ruby_data_structure(branch_data)
build_branch(branch_data, hit_count, condition_start_line)
end
end
def build_branch(branch_data, hit_count, condition_start_line)
type, _id, start_line, _start_col, end_line, _end_col = branch_data
SourceFile::Branch.new(
start_line: start_line,
end_line: end_line,
coverage: hit_count,
inline: start_line == condition_start_line,
type: type
)
end
def line_coverage_statistics
{
line: CoverageStatistics.new(
total_strength: lines_strength,
covered: covered_lines.size,
missed: missed_lines.size
)
}
end
def branch_coverage_statistics
{
branch: CoverageStatistics.new(
covered: covered_branches.size,
missed: missed_branches.size
)
}
end
end
end
simplecov-0.18.1/lib/simplecov/result_adapter.rb 0000644 0000041 0000041 00000001246 13617303170 021750 0 ustar www-data www-data # frozen_string_literal: true
module SimpleCov
#
# Responsible for adapting the format of the coverage result whether it's default or with statistics
#
class ResultAdapter
attr_reader :result
def initialize(result)
@result = result
end
def self.call(*args)
new(*args).adapt
end
def adapt
return unless result
result.each_with_object({}) do |(file_name, cover_statistic), adapted_result|
if cover_statistic.is_a?(Array)
adapted_result.merge!(file_name => {"lines" => cover_statistic})
else
adapted_result.merge!(file_name => cover_statistic)
end
end
end
end
end
simplecov-0.18.1/lib/simplecov/profiles/ 0000755 0000041 0000041 00000000000 13617303170 020225 5 ustar www-data www-data simplecov-0.18.1/lib/simplecov/profiles/hidden_filter.rb 0000644 0000041 0000041 00000000150 13617303170 023346 0 ustar www-data www-data # frozen_string_literal: true
SimpleCov.profiles.define "hidden_filter" do
add_filter %r{^/\..*}
end
simplecov-0.18.1/lib/simplecov/profiles/test_frameworks.rb 0000644 0000041 0000041 00000000262 13617303170 023771 0 ustar www-data www-data # frozen_string_literal: true
SimpleCov.profiles.define "test_frameworks" do
add_filter "/test/"
add_filter "/features/"
add_filter "/spec/"
add_filter "/autotest/"
end
simplecov-0.18.1/lib/simplecov/profiles/bundler_filter.rb 0000644 0000041 0000041 00000000160 13617303170 023547 0 ustar www-data www-data # frozen_string_literal: true
SimpleCov.profiles.define "bundler_filter" do
add_filter "/vendor/bundle/"
end
simplecov-0.18.1/lib/simplecov/profiles/rails.rb 0000644 0000041 0000041 00000000716 13617303170 021670 0 ustar www-data www-data # frozen_string_literal: true
SimpleCov.profiles.define "rails" do
load_profile "test_frameworks"
add_filter %r{^/config/}
add_filter %r{^/db/}
add_group "Controllers", "app/controllers"
add_group "Channels", "app/channels"
add_group "Models", "app/models"
add_group "Mailers", "app/mailers"
add_group "Helpers", "app/helpers"
add_group "Jobs", %w[app/jobs app/workers]
add_group "Libraries", "lib/"
track_files "{app,lib}/**/*.rb"
end
simplecov-0.18.1/lib/simplecov/profiles/root_filter.rb 0000644 0000041 0000041 00000000433 13617303170 023102 0 ustar www-data www-data # frozen_string_literal: true
SimpleCov.profiles.define "root_filter" do
# Exclude all files outside of simplecov root
root_filter = nil
add_filter do |src|
root_filter ||= /\A#{Regexp.escape(SimpleCov.root + File::SEPARATOR)}/io
src.filename !~ root_filter
end
end
simplecov-0.18.1/lib/simplecov/no_defaults.rb 0000644 0000041 0000041 00000000145 13617303170 021232 0 ustar www-data www-data # frozen_string_literal: true
ENV["SIMPLECOV_NO_DEFAULTS"] = "yes, no defaults"
require "simplecov"
simplecov-0.18.1/lib/simplecov.rb 0000644 0000041 0000041 00000034771 13617303170 016743 0 ustar www-data www-data # frozen_string_literal: true
require "English"
# Coverage may be inaccurate under JRUBY.
if defined?(JRUBY_VERSION) && defined?(JRuby)
# @see https://github.com/jruby/jruby/issues/1196
# @see https://github.com/metricfu/metric_fu/pull/226
# @see https://github.com/colszowka/simplecov/issues/420
# @see https://github.com/colszowka/simplecov/issues/86
# @see https://jira.codehaus.org/browse/JRUBY-6106
unless org.jruby.RubyInstanceConfig.FULL_TRACE_ENABLED
warn 'Coverage may be inaccurate; set the "--debug" command line option,' \
' or do JRUBY_OPTS="--debug"' \
' or set the "debug.fullTrace=true" option in your .jrubyrc'
end
end
#
# Code coverage for ruby. Please check out README for a full introduction.
#
module SimpleCov
class << self
attr_accessor :running
attr_accessor :pid
attr_reader :exit_exception
#
# Sets up SimpleCov to run against your project.
# You can optionally specify a profile to use as well as configuration with a block:
# SimpleCov.start
# OR
# SimpleCov.start 'rails' # using rails profile
# OR
# SimpleCov.start do
# add_filter 'test'
# end
# OR
# SimpleCov.start 'rails' do
# add_filter 'test'
# end
#
# Please check out the RDoc for SimpleCov::Configuration to find about available config options
#
def start(profile = nil, &block)
require "coverage"
initial_setup(profile, &block)
@result = nil
self.pid = Process.pid
start_coverage_measurement
end
#
# Collate a series of SimpleCov result files into a single SimpleCov output.
# You can optionally specify configuration with a block:
# SimpleCov.collate Dir["simplecov-resultset-*/.resultset.json"]
# OR
# SimpleCov.collate Dir["simplecov-resultset-*/.resultset.json"], 'rails' # using rails profile
# OR
# SimpleCov.collate Dir["simplecov-resultset-*/.resultset.json"] do
# add_filter 'test'
# end
# OR
# SimpleCov.collate Dir["simplecov-resultset-*/.resultset.json"], 'rails' do
# add_filter 'test'
# end
#
# Please check out the RDoc for SimpleCov::Configuration to find about
# available config options, or checkout the README for more in-depth
# information about coverage collation
#
def collate(result_filenames, profile = nil, &block)
raise "There's no reports to be merged" if result_filenames.empty?
initial_setup(profile, &block)
results = result_filenames.flat_map do |filename|
# Re-create each included instance of SimpleCov::Result from the stored run data.
(JSON.parse(File.read(filename)) || {}).map do |command_name, coverage|
SimpleCov::Result.from_hash(command_name => coverage)
end
end
# Use the ResultMerger to produce a single, merged result, ready to use.
@result = SimpleCov::ResultMerger.merge_and_store(*results)
run_exit_tasks!
end
#
# Returns the result for the current coverage run, merging it across test suites
# from cache using SimpleCov::ResultMerger if use_merging is activated (default)
#
def result
return @result if result?
# Collect our coverage result
process_coverage_result if running
# If we're using merging of results, store the current result
# first (if there is one), then merge the results and return those
if use_merging
wait_for_other_processes
SimpleCov::ResultMerger.store_result(@result) if result?
@result = SimpleCov::ResultMerger.merged_result
end
@result
ensure
self.running = false
end
#
# Returns nil if the result has not been computed
# Otherwise, returns the result
#
def result?
defined?(@result) && @result
end
#
# Applies the configured filters to the given array of SimpleCov::SourceFile items
#
def filtered(files)
result = files.clone
filters.each do |filter|
result = result.reject { |source_file| filter.matches?(source_file) }
end
SimpleCov::FileList.new result
end
#
# Applies the configured groups to the given array of SimpleCov::SourceFile items
#
def grouped(files)
grouped = {}
grouped_files = []
groups.each do |name, filter|
grouped[name] = SimpleCov::FileList.new(files.select { |source_file| filter.matches?(source_file) })
grouped_files += grouped[name]
end
if !groups.empty? && !(other_files = files.reject { |source_file| grouped_files.include?(source_file) }).empty?
grouped["Ungrouped"] = SimpleCov::FileList.new(other_files)
end
grouped
end
#
# Applies the profile of given name on SimpleCov configuration
#
def load_profile(name)
profiles.load(name)
end
def load_adapter(name)
warn "#{Kernel.caller.first}: [DEPRECATION] #load_adapter is deprecated. Use #load_profile instead."
load_profile(name)
end
#
# Clear out the previously cached .result. Primarily useful in testing
#
def clear_result
@result = nil
end
#
# Capture the current exception if it exists
# This will get called inside the at_exit block
#
def set_exit_exception
@exit_exception = $ERROR_INFO
end
#
# Returns the exit status from the exit exception
#
def exit_status_from_exception
return SimpleCov::ExitCodes::SUCCESS unless exit_exception
if exit_exception.is_a?(SystemExit)
exit_exception.status
else
SimpleCov::ExitCodes::EXCEPTION
end
end
# @api private
#
# Called from at_exit block
#
def run_exit_tasks!
set_exit_exception
exit_status = SimpleCov.exit_status_from_exception
SimpleCov.at_exit.call
# Don't modify the exit status unless the result has already been
# computed
exit_status = SimpleCov.process_result(SimpleCov.result, exit_status) if SimpleCov.result?
# Force exit with stored status (see github issue #5)
# unless it's nil or 0 (see github issue #281)
if exit_status&.positive?
$stderr.printf("SimpleCov failed with exit %d\n", exit_status: exit_status) if print_error_status
Kernel.exit exit_status
end
end
# @api private
#
# Usage:
# exit_status = SimpleCov.process_result(SimpleCov.result, exit_status)
#
def process_result(result, exit_status)
return exit_status if exit_status != SimpleCov::ExitCodes::SUCCESS # Existing errors
covered_percent = result.covered_percent.floor(2)
result_exit_status = result_exit_status(result, covered_percent)
write_last_run(covered_percent) if result_exit_status == SimpleCov::ExitCodes::SUCCESS # No result errors
final_result_process? ? result_exit_status : SimpleCov::ExitCodes::SUCCESS
end
# @api private
#
# rubocop:disable Metrics/MethodLength
def result_exit_status(result, covered_percent)
covered_percentages = result.covered_percentages.map { |percentage| percentage.floor(2) }
if (minimum_violations = minimum_coverage_violated(result)).any?
report_minimum_violated(minimum_violations)
SimpleCov::ExitCodes::MINIMUM_COVERAGE
elsif covered_percentages.any? { |p| p < SimpleCov.minimum_coverage_by_file }
$stderr.printf(
"File (%s) is only (%.2f%%) covered. This is below the expected minimum coverage per file of (%.2f%%).\n",
file: result.least_covered_file,
least_covered_percentage: covered_percentages.min,
min_coverage: SimpleCov.minimum_coverage_by_file
)
SimpleCov::ExitCodes::MINIMUM_COVERAGE
elsif (last_run = SimpleCov::LastRun.read)
coverage_diff = last_run[:result][:covered_percent] - covered_percent
if coverage_diff > SimpleCov.maximum_coverage_drop
$stderr.printf(
"Coverage has dropped by %.2f%% since the last time (maximum allowed: %.2f%%).\n",
drop_percent: coverage_diff,
max_drop: SimpleCov.maximum_coverage_drop
)
SimpleCov::ExitCodes::MAXIMUM_COVERAGE_DROP
else
SimpleCov::ExitCodes::SUCCESS
end
else
SimpleCov::ExitCodes::SUCCESS
end
end
# rubocop:enable Metrics/MethodLength
#
# @api private
#
def final_result_process?
# checking for ENV["TEST_ENV_NUMBER"] to determine if the tess are being run in parallel
!defined?(ParallelTests) || !ENV["TEST_ENV_NUMBER"] || ParallelTests.number_of_running_processes <= 1
end
#
# @api private
#
def wait_for_other_processes
return unless defined?(ParallelTests) && final_result_process?
ParallelTests.wait_for_other_processes_to_finish
end
#
# @api private
#
def write_last_run(covered_percent)
SimpleCov::LastRun.write(result: {covered_percent: covered_percent})
end
private
def initial_setup(profile, &block)
load_profile(profile) if profile
configure(&block) if block_given?
self.running = true
end
#
# Trigger Coverage.start depends on given config coverage_criterion
#
# With Positive branch it supports all coverage measurement types
# With Negative branch it supports only line coverage measurement type
#
def start_coverage_measurement
# This blog post gives a good run down of the coverage criterias introduced
# in Ruby 2.5: https://blog.bigbinary.com/2018/04/11/ruby-2-5-supports-measuring-branch-and-method-coverages.html
# There is also a nice writeup of the different coverage criteria made in this
# comment https://github.com/colszowka/simplecov/pull/692#discussion_r281836176 :
# Ruby < 2.5:
# https://github.com/ruby/ruby/blob/v1_9_3_374/ext/coverage/coverage.c
# traditional mode (Array)
#
# Ruby 2.5:
# https://bugs.ruby-lang.org/issues/13901
# https://github.com/ruby/ruby/blob/v2_5_3/ext/coverage/coverage.c
# default: traditional/compatible mode (Array)
# :lines - like traditional mode but using Hash
# :branches
# :methods
# :all - same as lines + branches + methods
#
# Ruby >= 2.6:
# https://bugs.ruby-lang.org/issues/15022
# https://github.com/ruby/ruby/blob/v2_6_3/ext/coverage/coverage.c
# default: traditional/compatible mode (Array)
# :lines - like traditional mode but using Hash
# :branches
# :methods
# :oneshot_lines - can not be combined with lines
# :all - same as lines + branches + methods
#
if coverage_start_arguments_supported?
start_coverage_with_criteria
else
Coverage.start
end
end
def start_coverage_with_criteria
start_arguments = coverage_criteria.map do |criterion|
[lookup_corresponding_ruby_coverage_name(criterion), true]
end.to_h
Coverage.start(start_arguments)
end
CRITERION_TO_RUBY_COVERAGE = {
branch: :branches,
line: :lines
}.freeze
def lookup_corresponding_ruby_coverage_name(criterion)
CRITERION_TO_RUBY_COVERAGE.fetch(criterion)
end
#
# Finds files that were to be tracked but were not loaded and initializes
# the line-by-line coverage to zero (if relevant) or nil (comments / whitespace etc).
#
def add_not_loaded_files(result)
if tracked_files
result = result.dup
Dir[tracked_files].each do |file|
absolute_path = File.expand_path(file)
result[absolute_path] ||= SimulateCoverage.call(absolute_path)
end
end
result
end
#
# Call steps that handle process coverage result
#
# @return [Hash]
#
def process_coverage_result
adapt_coverage_result
remove_useless_results
result_with_not_loaded_files
end
#
# Unite the result so it wouldn't matter what coverage type was called
#
# @return [Hash]
#
def adapt_coverage_result
@result = SimpleCov::ResultAdapter.call(Coverage.result)
end
#
# Filter coverage result
# The result before filter also has result of coverage for files
# are not related to the project like loaded gems coverage.
#
# @return [Hash]
#
def remove_useless_results
@result = SimpleCov::UselessResultsRemover.call(@result)
end
#
# Initialize result with files that are not included by coverage
# and added inside the config block
#
# @return [Hash]
#
def result_with_not_loaded_files
@result = SimpleCov::Result.new(add_not_loaded_files(@result))
end
def minimum_coverage_violated(result)
coverage_achieved = minimum_coverage.map do |criterion, percent|
{
criterion: criterion,
minimum_expected: percent,
actual: result.coverage_statistics[criterion].percent
}
end
coverage_achieved.select do |achieved|
achieved.fetch(:actual) < achieved.fetch(:minimum_expected)
end
end
def report_minimum_violated(violations)
violations.each do |violation|
$stderr.printf(
"%s coverage (%.2f%%) is below the expected minimum coverage (%.2f%%).\n",
covered: violation.fetch(:actual).floor(2),
minimum_coverage: violation.fetch(:minimum_expected),
criterion: violation.fetch(:criterion).capitalize
)
end
end
end
end
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__)))
require "set"
require "forwardable"
require "simplecov/configuration"
SimpleCov.extend SimpleCov::Configuration
require "simplecov/coverage_statistics"
require "simplecov/exit_codes"
require "simplecov/profiles"
require "simplecov/source_file/line"
require "simplecov/source_file/branch"
require "simplecov/source_file"
require "simplecov/file_list"
require "simplecov/result"
require "simplecov/filter"
require "simplecov/formatter"
require "simplecov/last_run"
require "simplecov/lines_classifier"
require "simplecov/result_merger"
require "simplecov/command_guesser"
require "simplecov/version"
require "simplecov/result_adapter"
require "simplecov/combine"
require "simplecov/combine/branches_combiner"
require "simplecov/combine/files_combiner"
require "simplecov/combine/lines_combiner"
require "simplecov/combine/results_combiner"
require "simplecov/useless_results_remover"
require "simplecov/simulate_coverage"
# Load default config
require "simplecov/defaults" unless ENV["SIMPLECOV_NO_DEFAULTS"]
simplecov-0.18.1/CONTRIBUTING.md 0000644 0000041 0000041 00000004153 13617303170 016067 0 ustar www-data www-data ## Reporting Issues
You can report issues at https://github.com/colszowka/simplecov/issues
Before you go ahead please search existing issues for your problem, chances are someone else already reported it.
To make sure that we can help you quickly please include and check the following information:
* Include how you run your tests and which testing framework or frameworks you are running.
- please ensure you are requiring and starting SimpleCov before requiring any application code.
- If running via rake, please ensure you are requiring SimpleCov at the top of your Rakefile
For example, if running via RSpec, this would be at the top of your spec_helper.
- Have you tried using a [`.simplecov` file](https://github.com/colszowka/simplecov#using-simplecov-for-centralized-config)?
* Include the SimpleCov version you are running in your report.
* If you are not running the latest version (please check), and you cannot update it,
please specify in your report why you can't update to the latest version.
* Include your `ruby -e "puts RUBY_DESCRIPTION"`.
* Please also specify the gem versions of Rails (if applicable).
* Include any other coverage gems you may be using and their versions.
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.)
This is extremely important for narrowing down the cause of your problem.
Thanks!
## Making Contributions
To fetch & test the library for development, do:
$ git clone https://github.com/colszowka/simplecov.git
$ cd simplecov
$ bundle
$ bundle exec rake
If you want to contribute, please:
* Fork the project.
* Make your feature addition or bug fix.
* Add tests for it. This is important so I don't break it in a future version unintentionally.
* **Bonus Points** go out to anyone who also updates `CHANGELOG.md` :)
* Send me a pull request on GitHub.
## Running Individual Tests
This project uses RSpec and Cucumber. Individual tests can be run like this:
```bash
bundle exec rspec path/to/test.rb
bundle exec cucumber path/to/test.feature
```
simplecov-0.18.1/doc/ 0000755 0000041 0000041 00000000000 13617303170 014400 5 ustar www-data www-data simplecov-0.18.1/doc/commercial-services.md 0000644 0000041 0000041 00000001735 13617303170 020664 0 ustar www-data www-data ## Commercial Services with SimpleCov integration
There is a bunch of services that offer integration with your existing CI pipeline and SimpleCov coverage
reports. Please note these are not associated with the SimpleCov project itself, so please report problems with
these integrations with their respective owners.
#### [codeclimate](https://github.com/codeclimate/ruby-test-reporter)
*by [Code Climate](https://codeclimate.com/)*
Upload coverage reports to [codeclimate.com](https://codeclimate.com/), a hosted software quality analysis and that also includes coverage reporting.
#### [codecov](https://github.com/codecov/codecov-ruby)
*by [Codecov](https://codecov.io/)*
Upload coverage reports to [codecov.io](https://codecov.io/), a hosted coverage reporting solution.
#### [coveralls](https://github.com/lemurheavy/coveralls-ruby)
*by [Coveralls](https://coveralls.io/)*
Upload coverage reports to [coveralls.io](https://coveralls.io/), a hosted coverage reporting solution.
simplecov-0.18.1/doc/alternate-formatters.md 0000644 0000041 0000041 00000004227 13617303170 021072 0 ustar www-data www-data ## Alternate coverage report formatters
The community around simplecov provides a whole bunch of alternate formatters beyond the official
[simplecov-html](https://github.com/colszowka/simplecov-html) gem.
If you have built or found one that is missing here, please send a Pull Request for this document!
#### [simplecov-badge](https://github.com/matthew342/simplecov-badge)
*by Matt Hale*
A formatter that generates a coverage badge for use in your project's readme using ImageMagick.
#### [simplecov-small-badge](https://github.com/marcgrimme/simplecov-small-badge)
*by Marc Grimme*
A formatter that generates a small coverage badge for use in your project's readme using the SVG.
#### [simplecov-cobertura](https://github.com/dashingrocket/simplecov-cobertura)
*by Jesse Bowes*
A formatter that generates Cobertura XML.
#### [simplecov-csv](https://github.com/fguillen/simplecov-csv)
*by Fernando Guillen*
CSV formatter for SimpleCov
#### [simplecov-erb](https://github.com/kpaulisse/simplecov-erb)
*by [Kevin Paulisse](https://github.com/kpaulisse)*
Flexible formatter that generates the output from an ERB template.
#### [simplecov-json](https://github.com/vicentllongo/simplecov-json)
*by Vicent Llongo*
JSON formatter for SimpleCov
#### [simplecov-lcov](https://github.com/fortissimo1997/simplecov-lcov)
*by fortissimo1997*
lcov formatter for SimpleCov
#### [simplecov-rcov](https://github.com/fguillen/simplecov-rcov)
*by Fernando Guillen*
"The target of this formatter is to cheat on Hudson so I can use the Ruby metrics plugin with SimpleCov."
#### [simplecov-single_file_reporter](https://github.com/grosser/simplecov-single_file_reporter)
*by [Michael Grosser](http://grosser.it)*
A formatter that prints the coverage of the file under test when you run a single test file.
#### [simplecov-t_wada](https://github.com/ysksn/simplecov-t_wada)
*by [Yosuke Kabuto](https://github.com/ysksn)*
t_wada AA formatter for SimpleCov
#### [simplecov-material(https://github.com/chiefpansancolt/simplecov-material)
*by [Chiefpansancolt](https://github.com/chiefpansancolt)*
A Material Designed HTML formatter with clean and easy search of files with a tabular left Navigation.
simplecov-0.18.1/doc/editor-integration.md 0000644 0000041 0000041 00000001147 13617303170 020534 0 ustar www-data www-data ## Editor integration
Some editors have a graphical integration for the simplecov gem.
#### [Atom Editor: coverage](https://atom.io/packages/coverage)
*by Philip Giuliani*
Adds an overview of your current test coverage to Atom.
#### [Sublime Editor: SimpleCov](https://packagecontrol.io/packages/SimpleCov)
*by sentience*
Adds in editor live coverage highlighting, status bar coverage information, and summary coverage information.
#### [cadre](https://github.com/nyarly/cadre)
*by Judson Lester*
Includes a formatter for Simplecov that emits a Vim script to mark up code files with coverage information.