covered 0.22.1 → 0.23.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c83b08be821b20f583a8e9f7c0c5eff4ded0852016e73e93d3a29f63ed33d79b
4
- data.tar.gz: 8a8cf40418633108d9b5bbb491eaf0c06dc7be5f53a11f2bbc3fac4abfca5cd3
3
+ metadata.gz: 0a79659c74af1e795823f64d18c4829240e5be7cdcf03b3f719680b9d29f9522
4
+ data.tar.gz: f0d8ad9bb7330adf479b0a028bc7a03e73ff35f091d79c4308f461f984f65f77
5
5
  SHA512:
6
- metadata.gz: 25f75fb59e078f2d89ca296a583a70d3b93817a4bb3e7863dbecc40a0bc13c21d0a0a66a536960c967483f27a036e25063960d40d52c20dde94fe320b34cb634
7
- data.tar.gz: 7e594df30c68df8df4cf71f0b8063f69dc0e3885d962cc176bbf0a2bf1c2408d6ab6fe2df31f524bcfc5d6162954a7e6f598084d76c851266fad317e0fbb65f0
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
@@ -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
- def validate(paths: nil, minimum: 1.0)
16
- policy = Covered::Policy.new
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
@@ -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.new(path, **options))
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 fresh:
108
- return true
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
@@ -12,7 +12,7 @@ module Covered
12
12
  class Files < Base
13
13
  class State
14
14
  def self.for(path, **options)
15
- self.new(Source.new(path, **options))
15
+ self.new(Source.for(path, **options))
16
16
  end
17
17
 
18
18
  def initialize(source)
@@ -21,9 +21,7 @@ module Covered
21
21
  end
22
22
 
23
23
  if $covered.record?
24
- class << Minitest
25
- prepend Covered::Minitest
26
- end
24
+ Minitest.singleton_class.prepend(Covered::Minitest)
27
25
 
28
26
  Minitest.after_run do
29
27
  $covered.finish
@@ -26,8 +26,13 @@ module Covered
26
26
  coverage.path = path
27
27
  end
28
28
 
29
- add(coverage)
29
+ if ignore_mtime || coverage.fresh?
30
+ add(coverage)
31
+ return true
32
+ end
30
33
  end
34
+
35
+ return false
31
36
  end
32
37
 
33
38
  def serialize(coverage)
@@ -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
@@ -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
 
@@ -4,5 +4,5 @@
4
4
  # Copyright, 2018-2023, by Samuel Williams.
5
5
 
6
6
  module Covered
7
- VERSION = "0.22.1"
7
+ VERSION = "0.23.0"
8
8
  end
data/readme.md CHANGED
@@ -1,86 +1,40 @@
1
1
  # Covered
2
2
 
3
- [![Development Status](https://github.com/ioquatix/covered/workflows/Test/badge.svg)](https://github.com/ioquatix/covered/actions?workflow=Test)
3
+ ![Screenshot](media/example.png)
4
4
 
5
- Covered uses modern Ruby features to generate comprehensive coverage, including support for templates which are compiled into Ruby.
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 coverage - so you can incrementally work on improving coverage.
8
- - Integration with RSpec, Minitest, Travis & Coveralls - no need to configure anything - out of the box support for these platforms.
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
- ![Screenshot](media/example.png)
14
+ [![Development
15
+ Status](https://github.com/ioquatix/covered/workflows/Test/badge.svg)](https://github.com/ioquatix/covered/actions?workflow=Test)
12
16
 
13
17
  ## Motivation
14
18
 
15
- Existing Ruby coverage tools are unable to handle `eval`ed code. This is because the `coverage` module built into Ruby doesn't expose the necessary hooks to capture it. Using the [parser](https://github.com/whitequark/parser) gem allows us to do our own source code analysis to compute executable lines, thus making it possible to compute coverage for "templates".
16
-
17
- It's still tricky to do it correctly, but it is feasible now to compute coverage of web application "views" by using this technique. This gem is an exploration to see what is possible.
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
- In your `test/test_helper.rb` add the following before loading any other code:
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
- When running `rspec`, you can specify the kind of coverage analysis you would like:
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
- This report lists several files in order of least coverage.l
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
- - [coveralls-ruby](https://github.com/lemurheavy/coveralls-ruby) – the official Coveralls implementation for Ruby.
83
- - [simplecov](https://github.com/colszowka/simplecov) – one of the original coverage implementations for Ruby, uses the built-in `coverage` library.
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 project must agree to this document to have their contributions accepted.
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 participants agree to abide by its terms.
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.22.1
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-17 00:00:00.000000000 Z
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