covered 0.22.1 → 0.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/bake/covered/policy.rb +31 -0
- data/bake/covered/validate.rb +3 -16
- data/lib/covered/coverage.rb +11 -58
- data/lib/covered/files.rb +1 -1
- data/lib/covered/minitest.rb +1 -3
- data/lib/covered/persist.rb +6 -1
- data/lib/covered/source.rb +66 -0
- data/lib/covered/statistics.rb +19 -0
- data/lib/covered/version.rb +1 -1
- data/readme.md +24 -68
- data.tar.gz.sig +0 -0
- metadata +4 -2
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0a79659c74af1e795823f64d18c4829240e5be7cdcf03b3f719680b9d29f9522
|
4
|
+
data.tar.gz: f0d8ad9bb7330adf479b0a028bc7a03e73ff35f091d79c4308f461f984f65f77
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d205944455af6959144bc22e7456ed165d308fde5989b5e6b781458aead3ded563fc7efcea3fa3ede628e85d0b678dcad82f0caa4ce851c3fa02ebd2f3432a08
|
7
|
+
data.tar.gz: 5f1d51e92917387f004e38e4e7ad0754ff1063ea348a7a4a36d52b27703fc1bb66ecd8dbc8a5815aeeaeaf71663e49c6faf072e7e7fec984c5c7c368d0035719
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Released under the MIT License.
|
4
|
+
# Copyright, 2023, by Samuel Williams.
|
5
|
+
|
6
|
+
def initialize(context)
|
7
|
+
super
|
8
|
+
|
9
|
+
require_relative '../../lib/covered/config'
|
10
|
+
end
|
11
|
+
|
12
|
+
# Load the current coverage policy.
|
13
|
+
def current(paths: nil)
|
14
|
+
policy = Covered::Policy.new
|
15
|
+
|
16
|
+
# Load the default path if no paths are specified:
|
17
|
+
paths ||= Dir.glob(Covered::Persist::DEFAULT_PATH, base: context.root)
|
18
|
+
|
19
|
+
# If no paths are specified, raise an error:
|
20
|
+
if paths.empty?
|
21
|
+
raise ArgumentError, "No coverage paths specified!"
|
22
|
+
end
|
23
|
+
|
24
|
+
# Load all coverage information:
|
25
|
+
paths.each do |path|
|
26
|
+
# It would be nice to have a better algorithm here than just ignoring mtime - perhaps using checksums?
|
27
|
+
Covered::Persist.new(policy.output, path).load!(ignore_mtime: true)
|
28
|
+
end
|
29
|
+
|
30
|
+
return policy
|
31
|
+
end
|
data/bake/covered/validate.rb
CHANGED
@@ -12,22 +12,9 @@ end
|
|
12
12
|
# Validate the coverage of multiple test runs.
|
13
13
|
# @parameter paths [Array(String)] The coverage database paths.
|
14
14
|
# @parameter minimum [Float] The minimum required coverage in order to pass.
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
# Load the default path if no paths are specified:
|
19
|
-
paths ||= Dir.glob(Covered::Persist::DEFAULT_PATH, base: context.root)
|
20
|
-
|
21
|
-
# If no paths are specified, raise an error:
|
22
|
-
if paths.empty?
|
23
|
-
raise ArgumentError, "No coverage paths specified!"
|
24
|
-
end
|
25
|
-
|
26
|
-
# Load all coverage information:
|
27
|
-
paths.each do |path|
|
28
|
-
# It would be nice to have a better algorithm here than just ignoring mtime - perhaps using checksums?
|
29
|
-
Covered::Persist.new(policy.output, path).load!(ignore_mtime: true)
|
30
|
-
end
|
15
|
+
# @parameter input [Covered::Policy] The input policy to validate.
|
16
|
+
def validate(paths: nil, minimum: 1.0, input:)
|
17
|
+
policy ||= context.lookup("covered:policy:current").call(paths: paths)
|
31
18
|
|
32
19
|
# Calculate statistics:
|
33
20
|
statistics = Covered::Statistics.new
|
data/lib/covered/coverage.rb
CHANGED
@@ -3,6 +3,8 @@
|
|
3
3
|
# Released under the MIT License.
|
4
4
|
# Copyright, 2018-2023, by Samuel Williams.
|
5
5
|
|
6
|
+
require_relative 'source'
|
7
|
+
|
6
8
|
module Covered
|
7
9
|
module Ratio
|
8
10
|
def ratio
|
@@ -20,66 +22,11 @@ module Covered
|
|
20
22
|
end
|
21
23
|
end
|
22
24
|
|
23
|
-
class Source
|
24
|
-
def self.for(path, code, line_offset)
|
25
|
-
self.new(path, code: code, line_offset: line_offset)
|
26
|
-
end
|
27
|
-
|
28
|
-
def initialize(path, code: nil, line_offset: 1, modified_time: nil)
|
29
|
-
@path = path
|
30
|
-
@code = code
|
31
|
-
@line_offset = line_offset
|
32
|
-
@modified_time = modified_time
|
33
|
-
end
|
34
|
-
|
35
|
-
attr_accessor :path
|
36
|
-
attr :code
|
37
|
-
attr :line_offset
|
38
|
-
attr :modified_time
|
39
|
-
|
40
|
-
def to_s
|
41
|
-
"\#<#{self.class} path=#{path}>"
|
42
|
-
end
|
43
|
-
|
44
|
-
def read(&block)
|
45
|
-
if block_given?
|
46
|
-
File.open(self.path, "r", &block)
|
47
|
-
else
|
48
|
-
File.read(self.path)
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
# The actual code which is being covered. If a template generates the source, this is the generated code, while the path refers to the template itself.
|
53
|
-
def code!
|
54
|
-
self.code || self.read
|
55
|
-
end
|
56
|
-
|
57
|
-
def code?
|
58
|
-
!!self.code
|
59
|
-
end
|
60
|
-
|
61
|
-
def serialize(packer)
|
62
|
-
packer.write(self.path)
|
63
|
-
packer.write(self.code)
|
64
|
-
packer.write(self.line_offset)
|
65
|
-
packer.write(self.modified_time)
|
66
|
-
end
|
67
|
-
|
68
|
-
def self.deserialize(unpacker)
|
69
|
-
path = unpacker.read
|
70
|
-
code = unpacker.read
|
71
|
-
line_offset = unpacker.read
|
72
|
-
modified_time = unpacker.read
|
73
|
-
|
74
|
-
self.new(path, code: code, line_offset: line_offset, modified_time: modified_time)
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
25
|
class Coverage
|
79
26
|
include Ratio
|
80
27
|
|
81
28
|
def self.for(path, **options)
|
82
|
-
self.new(Source.
|
29
|
+
self.new(Source.for(path, **options))
|
83
30
|
end
|
84
31
|
|
85
32
|
def initialize(source, counts = [], annotations = {}, total = nil)
|
@@ -94,6 +41,12 @@ module Covered
|
|
94
41
|
@executed_lines = nil
|
95
42
|
end
|
96
43
|
|
44
|
+
# Construct a new coverage object for the given line numbers. Only the given line numbers will be considered for the purposes of computing coverage.
|
45
|
+
# @parameter line_numbers [Array(Integer)] The line numbers to include in the new coverage object.
|
46
|
+
def for_lines(line_numbers)
|
47
|
+
self.class.new(@source, @counts.values_at(*line_numbers), @annotations)
|
48
|
+
end
|
49
|
+
|
97
50
|
def path
|
98
51
|
@source.path
|
99
52
|
end
|
@@ -104,8 +57,8 @@ module Covered
|
|
104
57
|
|
105
58
|
def fresh?
|
106
59
|
if @source.modified_time.nil?
|
107
|
-
# We don't know when the file was last modified, so we assume it is
|
108
|
-
return
|
60
|
+
# We don't know when the file was last modified, so we assume it is stale:
|
61
|
+
return false
|
109
62
|
end
|
110
63
|
|
111
64
|
unless File.exist?(@source.path)
|
data/lib/covered/files.rb
CHANGED
data/lib/covered/minitest.rb
CHANGED
data/lib/covered/persist.rb
CHANGED
@@ -0,0 +1,66 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Released under the MIT License.
|
4
|
+
# Copyright, 2018-2023, by Samuel Williams.
|
5
|
+
|
6
|
+
module Covered
|
7
|
+
class Source
|
8
|
+
def self.for(path, **options)
|
9
|
+
if File.exist?(path)
|
10
|
+
options[:code] ||= File.read(path)
|
11
|
+
options[:modified_time] ||= File.mtime(path)
|
12
|
+
end
|
13
|
+
|
14
|
+
self.new(path, **options)
|
15
|
+
end
|
16
|
+
|
17
|
+
def initialize(path, code: nil, line_offset: 1, modified_time: nil)
|
18
|
+
@path = path
|
19
|
+
@code = code
|
20
|
+
@line_offset = line_offset
|
21
|
+
@modified_time = modified_time
|
22
|
+
end
|
23
|
+
|
24
|
+
attr_accessor :path
|
25
|
+
attr :code
|
26
|
+
attr :line_offset
|
27
|
+
attr :modified_time
|
28
|
+
|
29
|
+
def to_s
|
30
|
+
"\#<#{self.class} path=#{path}>"
|
31
|
+
end
|
32
|
+
|
33
|
+
def read(&block)
|
34
|
+
if block_given?
|
35
|
+
File.open(self.path, "r", &block)
|
36
|
+
else
|
37
|
+
File.read(self.path)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# The actual code which is being covered. If a template generates the source, this is the generated code, while the path refers to the template itself.
|
42
|
+
def code!
|
43
|
+
self.code || self.read
|
44
|
+
end
|
45
|
+
|
46
|
+
def code?
|
47
|
+
!!self.code
|
48
|
+
end
|
49
|
+
|
50
|
+
def serialize(packer)
|
51
|
+
packer.write(self.path)
|
52
|
+
packer.write(self.code)
|
53
|
+
packer.write(self.line_offset)
|
54
|
+
packer.write(self.modified_time)
|
55
|
+
end
|
56
|
+
|
57
|
+
def self.deserialize(unpacker)
|
58
|
+
path = unpacker.read
|
59
|
+
code = unpacker.read
|
60
|
+
line_offset = unpacker.read
|
61
|
+
modified_time = unpacker.read
|
62
|
+
|
63
|
+
self.new(path, code: code, line_offset: line_offset, modified_time: modified_time)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
data/lib/covered/statistics.rb
CHANGED
@@ -11,6 +11,12 @@ module Covered
|
|
11
11
|
end
|
12
12
|
|
13
13
|
class Statistics < Wrapper
|
14
|
+
def self.for(coverage)
|
15
|
+
self.new.tap do |statistics|
|
16
|
+
statistics << coverage
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
14
20
|
def initialize
|
15
21
|
@count = 0
|
16
22
|
@executable_count = 0
|
@@ -26,6 +32,19 @@ module Covered
|
|
26
32
|
# The number of lines that were executed.
|
27
33
|
attr :executed_count
|
28
34
|
|
35
|
+
def as_json
|
36
|
+
{
|
37
|
+
count: count,
|
38
|
+
executable_count: executable_count,
|
39
|
+
executed_count: executed_count,
|
40
|
+
percentage: percentage.to_f.round(2),
|
41
|
+
}
|
42
|
+
end
|
43
|
+
|
44
|
+
def to_json(options)
|
45
|
+
as_json.to_json(options)
|
46
|
+
end
|
47
|
+
|
29
48
|
def << coverage
|
30
49
|
@count += 1
|
31
50
|
|
data/lib/covered/version.rb
CHANGED
data/readme.md
CHANGED
@@ -1,86 +1,40 @@
|
|
1
1
|
# Covered
|
2
2
|
|
3
|
-
|
3
|
+

|
4
4
|
|
5
|
-
Covered uses modern Ruby features to generate comprehensive coverage, including support for templates which are compiled
|
5
|
+
Covered uses modern Ruby features to generate comprehensive coverage, including support for templates which are compiled
|
6
|
+
into Ruby.
|
6
7
|
|
7
|
-
- Incremental coverage - if you run your full test suite, and the run a subset, it will still report the correct
|
8
|
-
|
8
|
+
- Incremental coverage - if you run your full test suite, and the run a subset, it will still report the correct
|
9
|
+
coverage - so you can incrementally work on improving coverage.
|
10
|
+
- Integration with Sus, Git, RSpec and Minitest- no need to configure anything - out of the box support for these
|
11
|
+
platforms.
|
9
12
|
- Supports coverage of views - templates compiled to Ruby code can be tracked for coverage reporting.
|
10
13
|
|
11
|
-
](https://github.com/ioquatix/covered/actions?workflow=Test)
|
12
16
|
|
13
17
|
## Motivation
|
14
18
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
## Installation
|
20
|
-
|
21
|
-
Add this line to your application's `Gemfile`:
|
22
|
-
|
23
|
-
``` ruby
|
24
|
-
gem 'covered'
|
25
|
-
```
|
26
|
-
|
27
|
-
### RSpec Integration
|
28
|
-
|
29
|
-
In your `spec/spec_helper.rb` add the following before loading any other code:
|
30
|
-
|
31
|
-
``` ruby
|
32
|
-
require 'covered/rspec'
|
33
|
-
```
|
34
|
-
|
35
|
-
Ensure that you have a `.rspec` file with `--require spec_helper`:
|
36
|
-
|
37
|
-
--require spec_helper
|
38
|
-
--format documentation
|
39
|
-
--warnings
|
40
|
-
|
41
|
-
### Minitest Integration
|
19
|
+
Originally, Ruby coverage tools were unable to handle `eval`ed code. This is because the `coverage` module built into
|
20
|
+
Ruby doesn't expose the necessary hooks to capture it. Using the [parser](https://github.com/whitequark/parser) gem and
|
21
|
+
trace points allows us to do our own source code analysis to compute executable lines, thus making it possible to
|
22
|
+
compute coverage for "templates".
|
42
23
|
|
43
|
-
|
44
|
-
|
45
|
-
``` ruby
|
46
|
-
require 'covered/minitest'
|
47
|
-
require 'minitest/autorun'
|
48
|
-
```
|
49
|
-
|
50
|
-
In your test files, e.g. `test/dummy_test.rb` add the following at the top:
|
51
|
-
|
52
|
-
``` ruby
|
53
|
-
require_relative 'test_helper'
|
54
|
-
```
|
24
|
+
After this concept prooved useful, [it was integrated directly into Ruby](https://bugs.ruby-lang.org/issues/19008).
|
55
25
|
|
56
26
|
## Usage
|
57
27
|
|
58
|
-
|
59
|
-
|
60
|
-
COVERAGE=Summary rspec
|
61
|
-
|
62
|
-
If no `COVERAGE` is specified, coverage tracking will be finishd.
|
63
|
-
|
64
|
-
### Template Coverage
|
65
|
-
|
66
|
-
Covered supports coverage of templates which are compiled into Ruby code. This is only supported on Ruby 3.2+ due to enhancements in the coverage interface.
|
67
|
-
|
68
|
-
### Partial Summary
|
69
|
-
|
70
|
-
COVERAGE=PartialSummary rspec
|
71
|
-
|
72
|
-
This report only shows snippets of source code with incomplete coverage.
|
73
|
-
|
74
|
-
### Brief Summary
|
75
|
-
|
76
|
-
COVERAGE=BriefSummary rspec
|
28
|
+
Please see the [project documentation](https://github.com/ioquatix/covered) for more details.
|
77
29
|
|
78
|
-
|
30
|
+
- [Getting Started](https://github.com/ioquatix/coveredguides/getting-started/index) - This guide explains how to get
|
31
|
+
started with `covered` and integrate it with your test suite.
|
79
32
|
|
80
33
|
## See Also
|
81
34
|
|
82
|
-
- [
|
83
|
-
|
35
|
+
- [simplecov](https://github.com/colszowka/simplecov) – one of the original coverage implementations for Ruby, uses
|
36
|
+
the built-in `coverage` library.
|
37
|
+
- [sus](https://github.com/ioquatix/sus) - a test framework which uses `covered` to generate coverage reports.
|
84
38
|
|
85
39
|
## Contributing
|
86
40
|
|
@@ -94,8 +48,10 @@ We welcome contributions to this project.
|
|
94
48
|
|
95
49
|
### Developer Certificate of Origin
|
96
50
|
|
97
|
-
This project uses the [Developer Certificate of Origin](https://developercertificate.org/). All contributors to this
|
51
|
+
This project uses the [Developer Certificate of Origin](https://developercertificate.org/). All contributors to this
|
52
|
+
project must agree to this document to have their contributions accepted.
|
98
53
|
|
99
54
|
### Contributor Covenant
|
100
55
|
|
101
|
-
This project is governed by [Contributor Covenant](https://www.contributor-covenant.org/). All contributors and
|
56
|
+
This project is governed by [Contributor Covenant](https://www.contributor-covenant.org/). All contributors and
|
57
|
+
participants agree to abide by its terms.
|
data.tar.gz.sig
CHANGED
Binary file
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: covered
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.23.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Samuel Williams
|
@@ -42,7 +42,7 @@ cert_chain:
|
|
42
42
|
Q2K9NVun/S785AP05vKkXZEFYxqG6EW012U4oLcFl5MySFajYXRYbuUpH6AY+HP8
|
43
43
|
voD0MPg1DssDLKwXyt1eKD/+Fq0bFWhwVM/1XiAXL7lyYUyOq24KHgQ2Csg=
|
44
44
|
-----END CERTIFICATE-----
|
45
|
-
date: 2023-07-
|
45
|
+
date: 2023-07-20 00:00:00.000000000 Z
|
46
46
|
dependencies:
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: console
|
@@ -79,6 +79,7 @@ extensions: []
|
|
79
79
|
extra_rdoc_files: []
|
80
80
|
files:
|
81
81
|
- bake/covered/debug.rb
|
82
|
+
- bake/covered/policy.rb
|
82
83
|
- bake/covered/validate.rb
|
83
84
|
- lib/covered.rb
|
84
85
|
- lib/covered/autostart.rb
|
@@ -92,6 +93,7 @@ files:
|
|
92
93
|
- lib/covered/persist.rb
|
93
94
|
- lib/covered/policy.rb
|
94
95
|
- lib/covered/rspec.rb
|
96
|
+
- lib/covered/source.rb
|
95
97
|
- lib/covered/statistics.rb
|
96
98
|
- lib/covered/summary.rb
|
97
99
|
- lib/covered/sus.rb
|
metadata.gz.sig
CHANGED
Binary file
|