rspec-cover_it 0.0.2
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 +7 -0
- data/.gitignore +6 -0
- data/Gemfile +3 -0
- data/LICENSE +20 -0
- data/README.md +105 -0
- data/lib/rspec/cover_it/context.rb +33 -0
- data/lib/rspec/cover_it/context_coverage.rb +54 -0
- data/lib/rspec/cover_it/coverage_state.rb +53 -0
- data/lib/rspec/cover_it/pretest_coverage.rb +17 -0
- data/lib/rspec/cover_it/version.rb +5 -0
- data/lib/rspec/cover_it.rb +30 -0
- data/rspec-cover_it.gemspec +36 -0
- metadata +130 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 528de4fe406f539d93d8632624714721d8cded1463a35776c16423d387c13c30
|
4
|
+
data.tar.gz: 57fc958451fb2dfeafb94aaaed56aba38befd938a4ea24d2f82d0ac09a46ee4e
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 6c636b00bd14fd976d53f9f97cbd2d53334ecb5677ad480ef00e737b51144da2f0ae76fffc1f6d1fb0366381961311e8aec93dfe6453cc2942c10dc652d87a88
|
7
|
+
data.tar.gz: 93c2432a8ce2725b2ca3ff9f1c8115a38154dc7c4426f7aa5667d12ed9546b9890d83885bcbe727064ea78972e58ab4e721b6dcef82d93c004d95f8a8ae6609f
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2023 Eric Mueller
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
# RSpec::CoverIt
|
2
|
+
|
3
|
+
Still a work in progress, but this gem is intended to give us a simpler and
|
4
|
+
more _targeted_ way to manage coverage. The usual system for a large project
|
5
|
+
is a single overarching SimpleCov target; with good tooling, there will be
|
6
|
+
something checking that all of the lines of each PR get covered by the tests
|
7
|
+
in that PR, and there are checks that the overall coverage number doesn't drop
|
8
|
+
too far.. but it's a _sloppy, messy, lossy_ approach. Code loses coverage,
|
9
|
+
code gets added with no tests, tests get removed and other code becomes less
|
10
|
+
covered, and a lot of the time, that's because the _coverage is a lie_.
|
11
|
+
|
12
|
+
Your coverage tool is telling you.. how many times each line of code _got run_
|
13
|
+
during your entire test suite. But it's not telling you what is doing the
|
14
|
+
running, which means that often large swathes of code are actually only covered
|
15
|
+
incidentally, through tests that aren't intended to exercise that code, but
|
16
|
+
_happens to_.
|
17
|
+
|
18
|
+
This approach was moderately inspired by https://github.com/jamesdabbs/rspec-coverage,
|
19
|
+
which was itself apparently inspired by a rubyconf 2016 talk by Ryan Davis. That
|
20
|
+
talk and library are mostly concerned with making sure that we don't _overcount_
|
21
|
+
coverage though, while this one has three goals:
|
22
|
+
|
23
|
+
1. Make coverage enforcement simpler
|
24
|
+
1. Enforce coverage _in the test suite_ (or nearly so)
|
25
|
+
1. Make coverage enforcement more local and specific.
|
26
|
+
|
27
|
+
## Tentative Usage
|
28
|
+
|
29
|
+
Note that this bit isn't really implemented, but is more of an outline of how I
|
30
|
+
intend the library to work. This is currently a spike, and not a functioning gem.
|
31
|
+
|
32
|
+
You set up `RSpec::CoverIt` in your `spec_helper.rb` - require `rspec/cover_it`,
|
33
|
+
and then `RSpec::CoverIt.setup(**config_options)` (before loading your code, as
|
34
|
+
you would with any other coverage library). It's.. _semi_ compatible with other
|
35
|
+
coverage systems - it only starts Coverage if it's not already running, and it
|
36
|
+
only uses `peek_result`, so it doesn't affect other systems outcomes. But if you
|
37
|
+
setup SimpleCov to do branch-coverage or something, that will break this gem,
|
38
|
+
for now (we assume basic line-coverage style results).
|
39
|
+
|
40
|
+
Rough configuration options:
|
41
|
+
|
42
|
+
* `filter`: Only paths starting with this (matching this regex?) can matter
|
43
|
+
* `autoenforce`: off by default - with this disabled, you turn on coverage
|
44
|
+
enforcement for a given top-level describe ExampleGroup by adding metadata
|
45
|
+
like `cover_it: true` or `cover_it: 95`. If it's enabled though, you instead
|
46
|
+
can turn enforcement _off_ for an example group by setting `cover_it: false`.
|
47
|
+
* `global_threshold`: 100% by default. This whole "90% coverage is the right
|
48
|
+
target" thing is mostly a side-effect of the way we check the entire project
|
49
|
+
under one number.. but it's an easy setting to support, and I'm sure people
|
50
|
+
will disagree with me.
|
51
|
+
|
52
|
+
## Example Group Metadata
|
53
|
+
|
54
|
+
In example groups, you can use metadata to control the behavior of
|
55
|
+
`rspec-cover_it`. These keys have meaning:
|
56
|
+
|
57
|
+
* `cover_it`: if boolean, it enables or disables the coverage enforcement for
|
58
|
+
this ExampleGroup. If numeric, it's enabling, and specifying the coverage
|
59
|
+
threshold at the same time (as a percentage - `cover_it: 95` requires 95%
|
60
|
+
coverage of the target class by this example group).
|
61
|
+
* `covers`: An array of classes and modules that this example groups _thinks
|
62
|
+
it is completely testing_. Ideally, you'd have a separate test file for each,
|
63
|
+
but sometimes that's hard to do - you can let one spec claim responsibility
|
64
|
+
for multiple classes and modules (such as Concerns) using this. Be default
|
65
|
+
it is just `[described_class]`. Additionally, if your top-level example
|
66
|
+
group _does not describe a Class or Module_, you may use `covers` to let it
|
67
|
+
invoke `rspec-cover_it` anyway.
|
68
|
+
|
69
|
+
## Implementation
|
70
|
+
|
71
|
+
We record the coverage information in a `before(:suite)` rspec hook using
|
72
|
+
`Coverage.peek_result`, and hold onto that information. Then before and after
|
73
|
+
each 'context' (which really amounts to 'each spec file'), we grab the coverage
|
74
|
+
information again.
|
75
|
+
|
76
|
+
We use `Object.const_source_location` to find the file that defines the
|
77
|
+
`described_class`, and _that_ is what is being assessed for coverage. This
|
78
|
+
means that, if you are reopening the class somewhere else, that coverage won't
|
79
|
+
be checked; if you are including 15 Concerns, and don't intend to write separate
|
80
|
+
specs for them, be sure to list them as `covers:` metadata on the test. Also,
|
81
|
+
shame!.
|
82
|
+
|
83
|
+
## Drawbacks and Shortcomings
|
84
|
+
|
85
|
+
There's nothing in here that stops you from failing to write tests for a class
|
86
|
+
at all! If you're using SimpleCov and you've got 100% coverage already, that's
|
87
|
+
one of the benefits.. I could pretty reasonably include some kind of
|
88
|
+
`after(:suite)` hook that optionally checks net coverage, but.. simplecov does
|
89
|
+
that, and the concurrent-testing game makes this a _painful_ topic in reality.
|
90
|
+
That's not the goal here, and I'm not going to worry about it.
|
91
|
+
|
92
|
+
As initially implemented, it fails your tests if you don't run the entire test
|
93
|
+
file. `rspec spec/foo_spec.rb:32` will error, because .. running only one of
|
94
|
+
your tests _doesn't cover the class_. I have a solution for this, but it uses
|
95
|
+
some non-public bits of RSpec, so I'm trying to find a better answer first.
|
96
|
+
(Conversation started in their
|
97
|
+
[issue tracker](https://github.com/rspec/rspec-core/issues/3037))
|
98
|
+
|
99
|
+
So far, I haven't found a _great_ way to report that there's a problem. The
|
100
|
+
output from having insufficient coverage is _raising an exception from an
|
101
|
+
`after(:context)` hook_, which RSpec rescues and formats for itself, and there
|
102
|
+
aren't a lot of controls - it works, but it's a bit ugly and doesn't really
|
103
|
+
give the right immediate impression. I'm contemplating using an `after(:suite)`
|
104
|
+
hook and aggregating them myself, but at the end of the day RSpec is in control
|
105
|
+
of the output stream, and we don't entirely fit its metaphor.
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module RSpec
|
2
|
+
module CoverIt
|
3
|
+
class Context
|
4
|
+
def initialize(scope:, rspec_context:)
|
5
|
+
@scope, @rspec_context = scope, rspec_context
|
6
|
+
end
|
7
|
+
|
8
|
+
def cover_it?
|
9
|
+
target_class && metadata.fetch(:cover_it, nil)
|
10
|
+
end
|
11
|
+
|
12
|
+
def target_path
|
13
|
+
Object.const_source_location(target_class_name).first
|
14
|
+
end
|
15
|
+
|
16
|
+
def target_class
|
17
|
+
metadata.fetch(:described_class, nil)
|
18
|
+
end
|
19
|
+
|
20
|
+
def target_class_name
|
21
|
+
target_class.name
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
attr_reader :scope, :rspec_context
|
27
|
+
|
28
|
+
def metadata
|
29
|
+
scope.metadata
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module RSpec
|
2
|
+
module CoverIt
|
3
|
+
class ContextCoverage
|
4
|
+
def initialize(context:, pretest_results:)
|
5
|
+
@context, @pretest_results = context, pretest_results
|
6
|
+
@precontext_coverage = @postcontext_coverage = nil
|
7
|
+
end
|
8
|
+
|
9
|
+
attr_accessor :precontext_coverage, :postcontext_coverage
|
10
|
+
|
11
|
+
def local_coverage
|
12
|
+
return nil unless precontext_coverage && postcontext_coverage
|
13
|
+
@_local_coverage ||= pretest_coverage
|
14
|
+
.zip(precontext_coverage, postcontext_coverage)
|
15
|
+
.map { |a, b, c| line_calculation(a, b, c) }
|
16
|
+
end
|
17
|
+
|
18
|
+
def local_coverage_rate
|
19
|
+
return nil unless covered_line_count
|
20
|
+
covered_line_count.to_f / coverable_line_count.to_f
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
attr_reader :context, :pretest_results, :precontext_coverage, :postcontext_coverage
|
26
|
+
|
27
|
+
def target_path
|
28
|
+
@_target_path ||= context.target_path
|
29
|
+
end
|
30
|
+
|
31
|
+
def pretest_coverage
|
32
|
+
@_pretest_coverage ||= pretest_results[target_path]
|
33
|
+
end
|
34
|
+
|
35
|
+
# Really, we shouldn't see nil for any of these values unless they are all
|
36
|
+
# nil. We want the coverage we'd expect to have seen if we ran _just_ this
|
37
|
+
# groups of examples, which ought boe the pretest coverage, plus the
|
38
|
+
# number of times each line was run _during_ the context.
|
39
|
+
def line_calculation(pretest, precontext, postcontext)
|
40
|
+
return nil if pretest.nil? || precontext.nil? || postcontext.nil?
|
41
|
+
pretest + (postcontext - precontext)
|
42
|
+
end
|
43
|
+
|
44
|
+
def coverable_line_count
|
45
|
+
pretest_coverage.compact.count
|
46
|
+
end
|
47
|
+
|
48
|
+
def covered_line_count
|
49
|
+
return nil unless local_coverage
|
50
|
+
local_coverage.count { |executions| executions && executions > 0 }
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module RSpec
|
2
|
+
module CoverIt
|
3
|
+
class CoverageState
|
4
|
+
attr_reader :filter
|
5
|
+
|
6
|
+
def initialize(filter:)
|
7
|
+
@filter = filter
|
8
|
+
@pretest_results = nil
|
9
|
+
@context_coverages = {}
|
10
|
+
end
|
11
|
+
|
12
|
+
# If SimpleCov or something like it is already running, Coverage may be
|
13
|
+
# started already. For our purposes, that should be fine.
|
14
|
+
def start_tracking
|
15
|
+
Coverage.start unless Coverage.running?
|
16
|
+
end
|
17
|
+
|
18
|
+
def finish_load_tracking
|
19
|
+
@pretest_results = PretestCoverage.new(filter: filter, results: Coverage.peek_result)
|
20
|
+
end
|
21
|
+
|
22
|
+
def start_tracking_for(scope, rspec_context)
|
23
|
+
context = Context.new(scope: scope, rspec_context: rspec_context)
|
24
|
+
return unless context.cover_it?
|
25
|
+
|
26
|
+
context_coverage_for(context).tap do |context_coverage|
|
27
|
+
context_coverage.precontext_coverage = Coverage.peek_result[context.target_path]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def finish_tracking_for(scope, rspec_context)
|
32
|
+
context = Context.new(scope: scope, rspec_context: rspec_context)
|
33
|
+
return unless context.cover_it?
|
34
|
+
|
35
|
+
context_coverage_for(context).tap do |context_coverage|
|
36
|
+
context_coverage.postcontext_coverage = Coverage.peek_result[context.target_path]
|
37
|
+
fail("missing coverage!") if context_coverage.local_coverage_rate < 1.0
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
attr_reader :pretest_results
|
44
|
+
|
45
|
+
def context_coverage_for(context)
|
46
|
+
@context_coverages[context.target_class] ||= ContextCoverage.new(
|
47
|
+
context: context,
|
48
|
+
pretest_results: pretest_results
|
49
|
+
)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module RSpec
|
2
|
+
module CoverIt
|
3
|
+
class PretestCoverage
|
4
|
+
def initialize(filter:, results:)
|
5
|
+
@filter = filter
|
6
|
+
@results = results
|
7
|
+
.select { |k, _v| k.start_with?(filter) }
|
8
|
+
.map { |k, v| [k, v.dup] }
|
9
|
+
.to_h
|
10
|
+
end
|
11
|
+
|
12
|
+
def [](path)
|
13
|
+
@results[path]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require "coverage"
|
2
|
+
|
3
|
+
module RSpec
|
4
|
+
module CoverIt
|
5
|
+
Error = Class.new(StandardError)
|
6
|
+
MissingCoverage = Class.new(Error)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
glob = File.expand_path("../cover_it/*.rb", __FILE__)
|
11
|
+
Dir.glob(glob).sort.each { |f| require(f) }
|
12
|
+
|
13
|
+
module RSpec
|
14
|
+
module CoverIt
|
15
|
+
class << self
|
16
|
+
attr_accessor :state
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.setup(filter:)
|
20
|
+
RSpec::CoverIt.state = CoverageState.new(filter: filter)
|
21
|
+
RSpec::CoverIt.state.start_tracking
|
22
|
+
|
23
|
+
RSpec.configure do |config|
|
24
|
+
config.prepend_before(:suite) { RSpec::CoverIt.state.finish_load_tracking }
|
25
|
+
config.prepend_before(:context) { |context| RSpec::CoverIt.state.start_tracking_for(self.class, context) }
|
26
|
+
config.append_after(:context) { |context| RSpec::CoverIt.state.finish_tracking_for(self.class, context) }
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require_relative "lib/rspec/cover_it/version"
|
2
|
+
|
3
|
+
Gem::Specification.new do |spec|
|
4
|
+
spec.name = "rspec-cover_it"
|
5
|
+
spec.version = RSpec::CoverIt::VERSION
|
6
|
+
spec.authors = ["Eric Mueller"]
|
7
|
+
spec.email = ["nevinera@gmail.com"]
|
8
|
+
|
9
|
+
spec.summary = "A system to enforce test coverage on each class"
|
10
|
+
spec.description = <<~DESC
|
11
|
+
We're all used to tools that enforce _total_ coverage numbers, but this gem
|
12
|
+
tries for something different. Instead of keeping your whole project above
|
13
|
+
some threshold, we treat the coverage of _each class_ as a testable quality
|
14
|
+
and then enforce that coverage as part of the test suite!
|
15
|
+
DESC
|
16
|
+
spec.homepage = "https://github.com/nevinera/rspec-cover_it"
|
17
|
+
spec.license = "MIT"
|
18
|
+
spec.required_ruby_version = Gem::Requirement.new(">= 2.7.0")
|
19
|
+
|
20
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
21
|
+
spec.metadata["source_code_uri"] = spec.homepage
|
22
|
+
|
23
|
+
spec.require_paths = ["lib"]
|
24
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
25
|
+
`git ls-files -z`
|
26
|
+
.split("\x0")
|
27
|
+
.reject { |f| f.start_with?("spec") }
|
28
|
+
end
|
29
|
+
|
30
|
+
spec.add_dependency "rspec", "~> 3.10"
|
31
|
+
|
32
|
+
spec.add_development_dependency "pry", "~> 0.14"
|
33
|
+
spec.add_development_dependency "standard", "~> 1.28"
|
34
|
+
spec.add_development_dependency "mdl", "~> 0.12"
|
35
|
+
spec.add_development_dependency "quiet_quality", "~> 1.2"
|
36
|
+
end
|
metadata
ADDED
@@ -0,0 +1,130 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rspec-cover_it
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Eric Mueller
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2023-06-07 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rspec
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '3.10'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '3.10'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: pry
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0.14'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0.14'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: standard
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.28'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.28'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: mdl
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0.12'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0.12'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: quiet_quality
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '1.2'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '1.2'
|
83
|
+
description: |
|
84
|
+
We're all used to tools that enforce _total_ coverage numbers, but this gem
|
85
|
+
tries for something different. Instead of keeping your whole project above
|
86
|
+
some threshold, we treat the coverage of _each class_ as a testable quality
|
87
|
+
and then enforce that coverage as part of the test suite!
|
88
|
+
email:
|
89
|
+
- nevinera@gmail.com
|
90
|
+
executables: []
|
91
|
+
extensions: []
|
92
|
+
extra_rdoc_files: []
|
93
|
+
files:
|
94
|
+
- ".gitignore"
|
95
|
+
- Gemfile
|
96
|
+
- LICENSE
|
97
|
+
- README.md
|
98
|
+
- lib/rspec/cover_it.rb
|
99
|
+
- lib/rspec/cover_it/context.rb
|
100
|
+
- lib/rspec/cover_it/context_coverage.rb
|
101
|
+
- lib/rspec/cover_it/coverage_state.rb
|
102
|
+
- lib/rspec/cover_it/pretest_coverage.rb
|
103
|
+
- lib/rspec/cover_it/version.rb
|
104
|
+
- rspec-cover_it.gemspec
|
105
|
+
homepage: https://github.com/nevinera/rspec-cover_it
|
106
|
+
licenses:
|
107
|
+
- MIT
|
108
|
+
metadata:
|
109
|
+
homepage_uri: https://github.com/nevinera/rspec-cover_it
|
110
|
+
source_code_uri: https://github.com/nevinera/rspec-cover_it
|
111
|
+
post_install_message:
|
112
|
+
rdoc_options: []
|
113
|
+
require_paths:
|
114
|
+
- lib
|
115
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
116
|
+
requirements:
|
117
|
+
- - ">="
|
118
|
+
- !ruby/object:Gem::Version
|
119
|
+
version: 2.7.0
|
120
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
requirements: []
|
126
|
+
rubygems_version: 3.3.26
|
127
|
+
signing_key:
|
128
|
+
specification_version: 4
|
129
|
+
summary: A system to enforce test coverage on each class
|
130
|
+
test_files: []
|