rspec-specification-coverage 0.1.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 +7 -0
- data/LICENSE.md +23 -0
- data/README.md +170 -0
- data/lib/rspec/specification_coverage/git_files_changed.rb +24 -0
- data/lib/rspec/specification_coverage/matchers/be_covered_with_specification.rb +90 -0
- data/lib/rspec/specification_coverage/ruby_file_details.rb +42 -0
- data/lib/rspec/specification_coverage/spec_from_file.rb +64 -0
- data/lib/rspec/specification_coverage.rb +4 -0
- data/lib/rspec-specification-coverage.rb +4 -0
- metadata +320 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 1011217d1c9f1417e26c1f5d05c0d52eea22a37c95c4ee68885f99aaee5f4eb7
|
4
|
+
data.tar.gz: 2701216d0b6d077ae7197984287ec8405205205773c0b8b6c853523a7e76997a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: cf63950e38feb0a043a0cb7a3f0d402d1eb81897a0e0c4dd33b5c1f22b85d74bf79b68ec774b39f107a7f21f52063d2ad02ade544c271ac444c10f8a68cb944f
|
7
|
+
data.tar.gz: c93b517f646ecdd3ddf88e55fb69c127615fd1c60dc1e0f0092d07f33214d4b023d971ceacdb64530dbe479f268e43d1cfc5a2f1cf1bce9b6de73d0fc88e1aab
|
data/LICENSE.md
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
=====================
|
3
|
+
|
4
|
+
* Copyright © 2023 Marcin Nowicki
|
5
|
+
|
6
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
7
|
+
a copy of this software and associated documentation files (the
|
8
|
+
"Software"), to deal in the Software without restriction, including
|
9
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
10
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
11
|
+
permit persons to whom the Software is furnished to do so, subject to
|
12
|
+
the following conditions:
|
13
|
+
|
14
|
+
The above copyright notice and this permission notice shall be
|
15
|
+
included in all copies or substantial portions of the Software.
|
16
|
+
|
17
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
18
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
19
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
20
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
21
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
22
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
23
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA3RE.
|
data/README.md
ADDED
@@ -0,0 +1,170 @@
|
|
1
|
+
# rspec-specification-coverage
|
2
|
+
|
3
|
+
Allow specify coverage of files.
|
4
|
+
|
5
|
+
## Why
|
6
|
+
|
7
|
+
Allow specify the way RSpec files cover the implementation.
|
8
|
+
|
9
|
+
### Why such long name
|
10
|
+
|
11
|
+
There is a common misconception in the community that RSpec is mainly
|
12
|
+
about testing - where it is mostly about specifying with ability to run
|
13
|
+
that specification. Well written specification makes most documentation
|
14
|
+
redundant - by reading the specification you should understand the
|
15
|
+
implementation.
|
16
|
+
|
17
|
+
## Usage
|
18
|
+
|
19
|
+
### Install
|
20
|
+
|
21
|
+
Add following to your Gemfile:
|
22
|
+
|
23
|
+
```ruby
|
24
|
+
group :test do
|
25
|
+
gem 'rspec-specification-coverage', '~> 0.1', require: false
|
26
|
+
end
|
27
|
+
```
|
28
|
+
|
29
|
+
And run:
|
30
|
+
|
31
|
+
```bash
|
32
|
+
bundle install
|
33
|
+
```
|
34
|
+
|
35
|
+
### Basic
|
36
|
+
|
37
|
+
Ensures is respective spec file existing for implementation.
|
38
|
+
|
39
|
+
The following will ensure that `spec/models/user_spec.rb` file exist:
|
40
|
+
|
41
|
+
```ruby
|
42
|
+
require 'rspec/specification_coverage'
|
43
|
+
|
44
|
+
::RSpec.describe(::RSpec::SpecificationCoverage) do
|
45
|
+
subject(:file) { 'app/models/user.rb' }
|
46
|
+
|
47
|
+
it { is_expected.to(be_covered_with_specification) }
|
48
|
+
end
|
49
|
+
```
|
50
|
+
|
51
|
+
### With Reflection
|
52
|
+
|
53
|
+
The following will ensure that in case there are git changes to
|
54
|
+
`app/models/user.rb`, respective specification in
|
55
|
+
`spec/models/user_spec.rb` also needs to be updated:
|
56
|
+
|
57
|
+
```ruby
|
58
|
+
it { is_expected.to(be_covered_with_specification.with_reflection) }
|
59
|
+
```
|
60
|
+
|
61
|
+
### Spec Bigger
|
62
|
+
|
63
|
+
The following will ensure that `spec/models/user_spec.rb`
|
64
|
+
file is bigger than `app/models/user.rb`.
|
65
|
+
|
66
|
+
```ruby
|
67
|
+
it { is_expected.to(be_covered_with_specification.spec_bigger) }
|
68
|
+
```
|
69
|
+
|
70
|
+
### Mentioning Methods
|
71
|
+
|
72
|
+
The following will ensure that `spec/models/user_spec.rb`
|
73
|
+
file include method names from `app/models/user.rb`.
|
74
|
+
|
75
|
+
```ruby
|
76
|
+
it { is_expected.to(be_covered_with_specification.mentioning_methods) }
|
77
|
+
```
|
78
|
+
|
79
|
+
### All
|
80
|
+
|
81
|
+
We can mix all above ways together:
|
82
|
+
|
83
|
+
```ruby
|
84
|
+
it { is_expected.to(be_covered_with_specification.with_reflection.spec_bigger.mentioning_methods) }
|
85
|
+
```
|
86
|
+
|
87
|
+
## Real Life Example
|
88
|
+
|
89
|
+
The following is a running example in one of my projects:
|
90
|
+
|
91
|
+
```ruby
|
92
|
+
# frozen_string_literal: true
|
93
|
+
|
94
|
+
require 'rspec'
|
95
|
+
require 'rspec/specification_coverage'
|
96
|
+
|
97
|
+
::RSpec.describe(::RSpec::SpecificationCoverage) do
|
98
|
+
::Dir.glob('app/{helpers,models,channels,mailers}/**/*.rb').each do |a_file|
|
99
|
+
describe a_file do
|
100
|
+
subject(:file) { a_file }
|
101
|
+
|
102
|
+
it { is_expected.to(be_covered_with_specification.with_reflection.spec_bigger.mentioning_methods) }
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
::Dir.glob('app/jobs/**/*.rb').each do |a_file|
|
107
|
+
describe a_file do
|
108
|
+
subject(:file) { a_file }
|
109
|
+
|
110
|
+
it { is_expected.to(be_covered_with_specification.with_reflection) }
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
::Dir.glob('app/views/**/*.erb').each do |a_file|
|
115
|
+
describe a_file do
|
116
|
+
subject(:file) { a_file }
|
117
|
+
|
118
|
+
it { is_expected.to(be_covered_with_specification.with_reflection) }
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
::Dir.glob('lib/**/*.rb').each do |a_file|
|
123
|
+
describe a_file do
|
124
|
+
subject(:file) { a_file }
|
125
|
+
|
126
|
+
it { is_expected.to(be_covered_with_specification(type: :lib).with_reflection.mentioning_methods) }
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
::Dir.glob('app/controllers/**/*.rb').each do |a_file|
|
131
|
+
describe a_file do
|
132
|
+
subject(:file) { a_file }
|
133
|
+
|
134
|
+
it {
|
135
|
+
is_expected.to(
|
136
|
+
be_covered_with_specification(type: :requests).with_reflection.spec_bigger.mentioning_methods
|
137
|
+
)
|
138
|
+
}
|
139
|
+
|
140
|
+
it {
|
141
|
+
is_expected.to(
|
142
|
+
be_covered_with_specification(type: :routing).with_reflection.mentioning_methods
|
143
|
+
)
|
144
|
+
}
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
```
|
149
|
+
|
150
|
+
## Development
|
151
|
+
|
152
|
+
We use TDD on Guard.
|
153
|
+
|
154
|
+
### Setup
|
155
|
+
|
156
|
+
```bash
|
157
|
+
bash util/setup.sh
|
158
|
+
```
|
159
|
+
|
160
|
+
### Check if overcommit is operational
|
161
|
+
|
162
|
+
```bash
|
163
|
+
bash util/overcommit_spec.sh
|
164
|
+
```
|
165
|
+
|
166
|
+
### Run your TDD reactor
|
167
|
+
|
168
|
+
```bash
|
169
|
+
bundle exec guard
|
170
|
+
```
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# Copyright (c) 2023 by Marcin Nowicki
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'active_support/core_ext/module'
|
5
|
+
require 'rspec'
|
6
|
+
require 'singleton'
|
7
|
+
|
8
|
+
# We store it within rspec as it relies on it.
|
9
|
+
module RSpec
|
10
|
+
# "RSpec specification coverage" is a term we use to go beyond testing.
|
11
|
+
module SpecificationCoverage
|
12
|
+
# Stores instance of currently changed git files.
|
13
|
+
class GitFilesChanged
|
14
|
+
include ::Singleton
|
15
|
+
|
16
|
+
delegate :include?, to: :ALL
|
17
|
+
|
18
|
+
# All git files changed.
|
19
|
+
ALL = `git status --porcelain | grep -v "^D" | cut -b4-`.split("\n").reject(&:empty?).freeze
|
20
|
+
|
21
|
+
private_constant :ALL
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
# Copyright (c) 2023 by Marcin Nowicki
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'active_support/core_ext/object/blank'
|
5
|
+
require 'rspec'
|
6
|
+
require_relative '../spec_from_file'
|
7
|
+
|
8
|
+
::RSpec::Matchers.define(:be_covered_with_specification) do |type: nil|
|
9
|
+
match do |actual|
|
10
|
+
@spec_file = ::RSpec::SpecificationCoverage::SpecFromFile.is(actual, type)
|
11
|
+
|
12
|
+
return false unless ::File.exist?(@spec_file)
|
13
|
+
|
14
|
+
if @spec_bigger || @mentioning_methods
|
15
|
+
if ::File.exist?(actual)
|
16
|
+
file_contents = ::File.read(actual)
|
17
|
+
@file_size = file_contents.size
|
18
|
+
else
|
19
|
+
file_contents = nil
|
20
|
+
@file_size = 0
|
21
|
+
end
|
22
|
+
if ::File.exist?(@spec_file)
|
23
|
+
spec_contents = ::File.read(@spec_file)
|
24
|
+
@spec_size = spec_contents.size
|
25
|
+
else
|
26
|
+
spec_contents = nil
|
27
|
+
@spec_size = 0
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
if @spec_bigger
|
32
|
+
@spec_is_bigger = @spec_size > @file_size
|
33
|
+
|
34
|
+
return false unless @spec_is_bigger
|
35
|
+
end
|
36
|
+
|
37
|
+
if @with_reflection
|
38
|
+
require_relative '../git_files_changed'
|
39
|
+
file_changed = ::RSpec::SpecificationCoverage::GitFilesChanged.instance.include?(actual)
|
40
|
+
|
41
|
+
if file_changed
|
42
|
+
@have_reflection = ::RSpec::SpecificationCoverage::GitFilesChanged.instance.include?(@spec_file)
|
43
|
+
|
44
|
+
return false unless @have_reflection
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
if @mentioning_methods && @file_size.positive? && @spec_size.positive?
|
49
|
+
@missing_methods = []
|
50
|
+
|
51
|
+
require_relative '../ruby_file_details'
|
52
|
+
file_details = ::RSpec::SpecificationCoverage::RubyFileDetails.new(file_contents)
|
53
|
+
file_details.methods.each do |method|
|
54
|
+
@missing_methods << method unless spec_contents.include?(method)
|
55
|
+
end
|
56
|
+
|
57
|
+
return false if @missing_methods.present?
|
58
|
+
end
|
59
|
+
|
60
|
+
true
|
61
|
+
end
|
62
|
+
|
63
|
+
failure_message do |actual|
|
64
|
+
message = "expected that '#{actual}'\n"
|
65
|
+
message += "would have respective spec '#{@spec_file}'\n"
|
66
|
+
if @spec_bigger && @spec_is_bigger == false
|
67
|
+
message += "which is bigger than the implementation (#{@spec_size} > #{@file_size})\n"
|
68
|
+
end
|
69
|
+
if @with_reflection && @have_reflection == false
|
70
|
+
message += "in case you change '#{actual}' then you have to specify it in '#{@spec_file}'\n"
|
71
|
+
end
|
72
|
+
if @mentioning_methods && @missing_methods.present?
|
73
|
+
message += 'the spec is missing mention of following methods: '
|
74
|
+
message += @missing_methods.join(', ')
|
75
|
+
end
|
76
|
+
message
|
77
|
+
end
|
78
|
+
|
79
|
+
chain :with_reflection do
|
80
|
+
@with_reflection = true
|
81
|
+
end
|
82
|
+
|
83
|
+
chain :spec_bigger do
|
84
|
+
@spec_bigger = true
|
85
|
+
end
|
86
|
+
|
87
|
+
chain :mentioning_methods do
|
88
|
+
@mentioning_methods = true
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# Copyright (c) 2023 by Marcin Nowicki
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'rspec'
|
5
|
+
|
6
|
+
# We store it within rspec as it relies on it.
|
7
|
+
module RSpec
|
8
|
+
# "RSpec specification coverage" is a term we use to go beyond testing.
|
9
|
+
module SpecificationCoverage
|
10
|
+
# Text-based ruby file details analysis.
|
11
|
+
class RubyFileDetails
|
12
|
+
# Match method definitions with empty spaces at the beginning.
|
13
|
+
REGEXP_METHODS = /\s+def ([a-z_.?]+)/
|
14
|
+
|
15
|
+
# @param file_contents [String]
|
16
|
+
def initialize(file_contents)
|
17
|
+
@file_contents = file_contents
|
18
|
+
end
|
19
|
+
|
20
|
+
# All methods matching regexp except initialize.
|
21
|
+
#
|
22
|
+
# @return [String]
|
23
|
+
def methods
|
24
|
+
@methods ||= scan(REGEXP_METHODS)
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
# Using external method with "!" methods due to improved performance.
|
30
|
+
# @return [String]
|
31
|
+
def scan(regexp)
|
32
|
+
output = @file_contents.scan(regexp)
|
33
|
+
output.flatten!
|
34
|
+
output.reject! { |method| method == 'initialize' }
|
35
|
+
output.map! { |method| method.gsub(/^self\./, '') }
|
36
|
+
output
|
37
|
+
end
|
38
|
+
|
39
|
+
private_constant :REGEXP_METHODS
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# Copyright (c) 2023 by Marcin Nowicki
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'rspec'
|
5
|
+
|
6
|
+
# We store it within rspec as it relies on it.
|
7
|
+
module RSpec
|
8
|
+
# "RSpec specification coverage" is a term we use to go beyond testing.
|
9
|
+
module SpecificationCoverage
|
10
|
+
# Allows getting getting spec name from file name.
|
11
|
+
class SpecFromFile
|
12
|
+
# @param actual [String] for example `app/models/user.rb`
|
13
|
+
# @param type [Symbol] the type, `nil`, `:routing`, `:requests`, `:lib`
|
14
|
+
def self.is(actual, type)
|
15
|
+
new(actual, type).is
|
16
|
+
end
|
17
|
+
|
18
|
+
# @param actual [String] for example `app/models/user.rb`
|
19
|
+
# @param type [Symbol] the type, `nil`, `:routing`, `:requests`, `:lib`
|
20
|
+
def initialize(actual, type)
|
21
|
+
@actual = actual
|
22
|
+
@type = type
|
23
|
+
|
24
|
+
raise(::ArgumentError) unless valid?
|
25
|
+
end
|
26
|
+
|
27
|
+
# @return [String] like `spec/models/user_spec.rb`
|
28
|
+
def is
|
29
|
+
case @type
|
30
|
+
when :routing
|
31
|
+
controller_replaced.gsub(/\.rb$/, "_#{@type}_spec.rb")
|
32
|
+
when :requests
|
33
|
+
controller_replaced.gsub(/\.rb$/, '_spec.rb')
|
34
|
+
when :lib
|
35
|
+
suffix_replaced.gsub(/^lib/, 'spec/lib')
|
36
|
+
else
|
37
|
+
suffix_replaced.gsub(/^lib/, 'spec')
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
# @return [String]
|
44
|
+
def controller_replaced
|
45
|
+
app_replaced.gsub('_controller.', '.').gsub(%r{/controllers/}, "/#{@type}/")
|
46
|
+
end
|
47
|
+
|
48
|
+
# @return [String]
|
49
|
+
def app_replaced
|
50
|
+
@actual.gsub(/^app/, 'spec')
|
51
|
+
end
|
52
|
+
|
53
|
+
# @return [String]
|
54
|
+
def suffix_replaced
|
55
|
+
app_replaced.gsub(/\.rb$/, '_spec.rb').gsub(/\.erb$/, '.erb_spec.rb')
|
56
|
+
end
|
57
|
+
|
58
|
+
# @return [Boolean]
|
59
|
+
def valid?
|
60
|
+
@actual.is_a?(::String) && (@type.is_a?(::Symbol) || @type.is_a?(::NilClass))
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
metadata
ADDED
@@ -0,0 +1,320 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rspec-specification-coverage
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Marcin Nowicki
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2023-01-22 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activesupport
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 7.0.4.1
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 7.0.4.1
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: alfonsox
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0.2'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0.2'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: bundle-audit
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0.1'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0.1'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: guard
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '2.18'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '2.18'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: guard-rspec
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '4.7'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '4.7'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: guard-rubocop
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '1.5'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '1.5'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: guard-yard
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '2.2'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '2.2'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: mdl
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0.12'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0.12'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: overcommit
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - "~>"
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0.60'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - "~>"
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0.60'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: parallel_tests
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - "~>"
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '4.0'
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - "~>"
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '4.0'
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: rake
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - "~>"
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: 13.0.6
|
160
|
+
type: :development
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - "~>"
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: 13.0.6
|
167
|
+
- !ruby/object:Gem::Dependency
|
168
|
+
name: reek
|
169
|
+
requirement: !ruby/object:Gem::Requirement
|
170
|
+
requirements:
|
171
|
+
- - "~>"
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '6.1'
|
174
|
+
type: :development
|
175
|
+
prerelease: false
|
176
|
+
version_requirements: !ruby/object:Gem::Requirement
|
177
|
+
requirements:
|
178
|
+
- - "~>"
|
179
|
+
- !ruby/object:Gem::Version
|
180
|
+
version: '6.1'
|
181
|
+
- !ruby/object:Gem::Dependency
|
182
|
+
name: rspec
|
183
|
+
requirement: !ruby/object:Gem::Requirement
|
184
|
+
requirements:
|
185
|
+
- - "~>"
|
186
|
+
- !ruby/object:Gem::Version
|
187
|
+
version: '3.12'
|
188
|
+
type: :development
|
189
|
+
prerelease: false
|
190
|
+
version_requirements: !ruby/object:Gem::Requirement
|
191
|
+
requirements:
|
192
|
+
- - "~>"
|
193
|
+
- !ruby/object:Gem::Version
|
194
|
+
version: '3.12'
|
195
|
+
- !ruby/object:Gem::Dependency
|
196
|
+
name: rubocop
|
197
|
+
requirement: !ruby/object:Gem::Requirement
|
198
|
+
requirements:
|
199
|
+
- - "~>"
|
200
|
+
- !ruby/object:Gem::Version
|
201
|
+
version: '1.41'
|
202
|
+
type: :development
|
203
|
+
prerelease: false
|
204
|
+
version_requirements: !ruby/object:Gem::Requirement
|
205
|
+
requirements:
|
206
|
+
- - "~>"
|
207
|
+
- !ruby/object:Gem::Version
|
208
|
+
version: '1.41'
|
209
|
+
- !ruby/object:Gem::Dependency
|
210
|
+
name: rubocop-performance
|
211
|
+
requirement: !ruby/object:Gem::Requirement
|
212
|
+
requirements:
|
213
|
+
- - "~>"
|
214
|
+
- !ruby/object:Gem::Version
|
215
|
+
version: '1.15'
|
216
|
+
type: :development
|
217
|
+
prerelease: false
|
218
|
+
version_requirements: !ruby/object:Gem::Requirement
|
219
|
+
requirements:
|
220
|
+
- - "~>"
|
221
|
+
- !ruby/object:Gem::Version
|
222
|
+
version: '1.15'
|
223
|
+
- !ruby/object:Gem::Dependency
|
224
|
+
name: rubocop-require_tools
|
225
|
+
requirement: !ruby/object:Gem::Requirement
|
226
|
+
requirements:
|
227
|
+
- - "~>"
|
228
|
+
- !ruby/object:Gem::Version
|
229
|
+
version: '0.1'
|
230
|
+
type: :development
|
231
|
+
prerelease: false
|
232
|
+
version_requirements: !ruby/object:Gem::Requirement
|
233
|
+
requirements:
|
234
|
+
- - "~>"
|
235
|
+
- !ruby/object:Gem::Version
|
236
|
+
version: '0.1'
|
237
|
+
- !ruby/object:Gem::Dependency
|
238
|
+
name: rubocop-rspec
|
239
|
+
requirement: !ruby/object:Gem::Requirement
|
240
|
+
requirements:
|
241
|
+
- - "~>"
|
242
|
+
- !ruby/object:Gem::Version
|
243
|
+
version: '2.16'
|
244
|
+
type: :development
|
245
|
+
prerelease: false
|
246
|
+
version_requirements: !ruby/object:Gem::Requirement
|
247
|
+
requirements:
|
248
|
+
- - "~>"
|
249
|
+
- !ruby/object:Gem::Version
|
250
|
+
version: '2.16'
|
251
|
+
- !ruby/object:Gem::Dependency
|
252
|
+
name: rubocop-thread_safety
|
253
|
+
requirement: !ruby/object:Gem::Requirement
|
254
|
+
requirements:
|
255
|
+
- - "~>"
|
256
|
+
- !ruby/object:Gem::Version
|
257
|
+
version: '0.4'
|
258
|
+
type: :development
|
259
|
+
prerelease: false
|
260
|
+
version_requirements: !ruby/object:Gem::Requirement
|
261
|
+
requirements:
|
262
|
+
- - "~>"
|
263
|
+
- !ruby/object:Gem::Version
|
264
|
+
version: '0.4'
|
265
|
+
- !ruby/object:Gem::Dependency
|
266
|
+
name: simplecov
|
267
|
+
requirement: !ruby/object:Gem::Requirement
|
268
|
+
requirements:
|
269
|
+
- - "~>"
|
270
|
+
- !ruby/object:Gem::Version
|
271
|
+
version: '0.22'
|
272
|
+
type: :development
|
273
|
+
prerelease: false
|
274
|
+
version_requirements: !ruby/object:Gem::Requirement
|
275
|
+
requirements:
|
276
|
+
- - "~>"
|
277
|
+
- !ruby/object:Gem::Version
|
278
|
+
version: '0.22'
|
279
|
+
description: Allow specify how RSpec specification files cover the implementation.
|
280
|
+
email: pr0d1r2@gmail.com
|
281
|
+
executables: []
|
282
|
+
extensions: []
|
283
|
+
extra_rdoc_files:
|
284
|
+
- LICENSE.md
|
285
|
+
- README.md
|
286
|
+
files:
|
287
|
+
- LICENSE.md
|
288
|
+
- README.md
|
289
|
+
- lib/rspec-specification-coverage.rb
|
290
|
+
- lib/rspec/specification_coverage.rb
|
291
|
+
- lib/rspec/specification_coverage/git_files_changed.rb
|
292
|
+
- lib/rspec/specification_coverage/matchers/be_covered_with_specification.rb
|
293
|
+
- lib/rspec/specification_coverage/ruby_file_details.rb
|
294
|
+
- lib/rspec/specification_coverage/spec_from_file.rb
|
295
|
+
homepage: https://github.com/pr0d1r2/rspec-specification-coverage
|
296
|
+
licenses:
|
297
|
+
- MIT
|
298
|
+
metadata:
|
299
|
+
source_code_uri: https://github.com/pr0d1r2/rspec-specification-coverage
|
300
|
+
rubygems_mfa_required: 'true'
|
301
|
+
post_install_message:
|
302
|
+
rdoc_options: []
|
303
|
+
require_paths:
|
304
|
+
- lib
|
305
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
306
|
+
requirements:
|
307
|
+
- - "~>"
|
308
|
+
- !ruby/object:Gem::Version
|
309
|
+
version: '3.1'
|
310
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
311
|
+
requirements:
|
312
|
+
- - ">="
|
313
|
+
- !ruby/object:Gem::Version
|
314
|
+
version: '0'
|
315
|
+
requirements: []
|
316
|
+
rubygems_version: 3.3.26
|
317
|
+
signing_key:
|
318
|
+
specification_version: 4
|
319
|
+
summary: Specify RSpec specification coverage.
|
320
|
+
test_files: []
|