rubocop-rspec-extra 0.1.0 → 0.3.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b6d37e0a9b8e12b308c8f45612176fd83edd6a6ce1852746dc0140efba3efb6b
4
- data.tar.gz: ef9b88f0c670940a7f79b8c4ae6e73f1f8b492b630cceb540dab1c6a85ec003e
3
+ metadata.gz: d885353b04e17a9ba6e002a3aeaa1d58726f13d9134edfdbfb5adac37d72d312
4
+ data.tar.gz: 0720cb32f2ce81e26e687870cccd9fc6174e10340f077f50bdbc89661278ae45
5
5
  SHA512:
6
- metadata.gz: 6ba9025e60e671873a082672d0677fc2eacd07c60f1d1fca1d9ac6068fdd9d1894faf6336e37d63f86bfbc9bcb482477bd246176e23967cd9f36df316107a323
7
- data.tar.gz: e6b5eda765dd616f7ba4d9e24c93462b0440986b00098f11c21993c45e93e8391723e6301db74f2a53beae6745caf7e51cee045f4696a03b8f44d1808669aa37
6
+ metadata.gz: cfd41a33039afbd015fb9ee731ddb16055ecc42e29f844dfba12b307595dd9f06ab1f7d317e8e204ed39932d23b8a679eb3458d0da97e55274909d9e2b3407b8
7
+ data.tar.gz: e178ee6def16d08d667df04bd4fd4514fdc69d110d00dc825f213e5f797deacd8b6078f8b125d7a441643eef32ee5dbfd5a803f6bbc6735ae3d548fa98172751
data/.rubocop.yml CHANGED
@@ -1,7 +1,7 @@
1
1
  inherit_from: .rubocop_todo.yml
2
2
 
3
- require:
4
- - rubocop/cop/internal_affairs
3
+ plugins:
4
+ - rubocop-internal_affairs
5
5
  - rubocop-performance
6
6
  - rubocop-rake
7
7
  - rubocop-rspec
@@ -9,7 +9,7 @@ require:
9
9
 
10
10
  AllCops:
11
11
  NewCops: enable
12
- TargetRubyVersion: 2.6
12
+ TargetRubyVersion: 2.7
13
13
  SuggestExtensions: false
14
14
 
15
15
  Layout/LineLength:
data/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
- ## Unreleased
1
+ # Changelog
2
2
 
3
- ## 0.1.0 - 2023-04-18
3
+ ## Master (Unreleased)
4
+
5
+ ## 0.3.0 (2025-03-19)
6
+
7
+ - Pluginfy RuboCop RSpec Extra. ([@ydah])
8
+ - Add `RSpec/Extra/FlatExamples` cop. ([@ydah])
9
+
10
+ ## 0.2.0 (2024-03-01)
11
+
12
+ - Fix an error for `RSpec/Extra/RestrictBlockTag`. ([@ydah])
13
+ - Fix an error for `RSpec/Extra/RestrictBlockTagValue`. ([@ydah])
14
+ - Drop Ruby 2.6 support. ([@ydah])
15
+
16
+ ## 0.1.0 (2023-04-18)
4
17
 
5
18
  - Initial release
19
+
20
+ <!-- Contributors (alphabetically) -->
21
+
22
+ [@ydah]: https://github.com/ydah
data/Gemfile CHANGED
@@ -9,5 +9,5 @@ gem "rake"
9
9
  gem "rspec", "~> 3.11"
10
10
  gem "rubocop-performance", "~> 1.7"
11
11
  gem "rubocop-rake", "~> 0.6"
12
- gem "rubocop-rspec", "~> 2.18"
12
+ gem "rubocop-rspec", "~> 3.0"
13
13
  gem "yard"
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Rubocop::Rspec::Extra
2
2
 
3
- ![GitHub top language](https://img.shields.io/github/languages/top/ydah/rubocop-rspec-extra) ![GitHub](https://img.shields.io/github/license/ydah/rubocop-rspec-extra) ![Ruby Style Guide](https://img.shields.io/badge/code_style-rubocop-brightgreen.svg) [![CI](https://github.com/ydah/rubocop-rspec-extra/actions/workflows/ci.yml/badge.svg)](https://github.com/ydah/rubocop-rspec-extra/actions/workflows/ci.yml) [![Maintainability](https://api.codeclimate.com/v1/badges/6b1f27edd867a4b64661/maintainability)](https://codeclimate.com/github/ydah/rubocop-rspec-extra/maintainability)
3
+ ![GitHub top language](https://img.shields.io/github/languages/top/ydah/rubocop-rspec-extra) ![GitHub](https://img.shields.io/github/license/ydah/rubocop-rspec-extra) [![Gem Version](https://badge.fury.io/rb/rubocop-rspec-extra.svg)](https://badge.fury.io/rb/rubocop-rspec-extra) ![Ruby Style Guide](https://img.shields.io/badge/code_style-rubocop-brightgreen.svg) [![CI](https://github.com/ydah/rubocop-rspec-extra/actions/workflows/ci.yml/badge.svg)](https://github.com/ydah/rubocop-rspec-extra/actions/workflows/ci.yml) [![Maintainability](https://api.codeclimate.com/v1/badges/6b1f27edd867a4b64661/maintainability)](https://codeclimate.com/github/ydah/rubocop-rspec-extra/maintainability)
4
4
 
5
5
  A [RuboCop](https://github.com/rubocop/rubocop) extension focused on enforcing RSpec. A place where no one is officially employed, but where useful cops can gather.
6
6
 
@@ -28,13 +28,13 @@ ways to do this:
28
28
  Put this into your `.rubocop.yml`.
29
29
 
30
30
  ```yaml
31
- require: rubocop-rspec-extra
31
+ plugins: rubocop-rspec-extra
32
32
  ```
33
33
 
34
34
  Alternatively, use the following array notation when specifying multiple extensions.
35
35
 
36
36
  ```yaml
37
- require:
37
+ plugins:
38
38
  - rubocop-rspec
39
39
  - rubocop-rspec-extra
40
40
  ```
@@ -42,17 +42,20 @@ require:
42
42
  Now you can run `rubocop` and it will automatically load the RuboCop RSpec Extra
43
43
  cops together with the standard cops.
44
44
 
45
+ > [!NOTE]
46
+ > The plugin system is supported in RuboCop 1.72+. In earlier versions, use `require` instead of `plugins`.
47
+
45
48
  ### Command line
46
49
 
47
50
  ```bash
48
- rubocop --require rubocop-rspec-extra
51
+ rubocop --plugins rubocop-rspec-extra
49
52
  ```
50
53
 
51
54
  ### Rake task
52
55
 
53
56
  ```ruby
54
57
  RuboCop::RakeTask.new do |task|
55
- task.requires << 'rubocop-rspec-extra'
58
+ task.plugins << 'rubocop-rspec-extra'
56
59
  end
57
60
  ```
58
61
 
@@ -62,7 +65,7 @@ All cops are located under
62
65
  [`lib/rubocop/cop/rspec/extra`](lib/rubocop/cop/rspec/extra), and contain
63
66
  examples/documentation.
64
67
 
65
- In your `.rubocop.yml`, you may treat the Committee cops just like any other
68
+ In your `.rubocop.yml`, you may treat the RSpec extra cops just like any other
66
69
  cop. For example:
67
70
 
68
71
  ```yaml
@@ -77,5 +80,5 @@ Checkout the [contribution guidelines](.github/CONTRIBUTING.md).
77
80
 
78
81
  ## License
79
82
 
80
- `rubocop-committee` is MIT licensed. [See the accompanying file](MIT-LICENSE.md) for
83
+ `rubocop-rspec-extra` is MIT licensed. [See the accompanying file](MIT-LICENSE.md) for
81
84
  the full text.
data/config/default.yml CHANGED
@@ -5,17 +5,22 @@ RSpec/Extra:
5
5
  RSpec/Extra/BeEmpty:
6
6
  Description: Prefer using `be_empty` when checking for an empty array.
7
7
  Enabled: pending
8
- VersionAdded: '<<next>>'
8
+ VersionAdded: '0.1'
9
9
  Reference: https://www.rubydoc.info/gems/rubocop-rspec-extra/RuboCop/Cop/RSpec/Extra/BeEmpty
10
10
 
11
+ RSpec/Extra/FlatExamples:
12
+ Description: 'Restrict unnecessary nesting by example groups.'
13
+ Enabled: false
14
+ VersionAdded: '0.3'
15
+
11
16
  RSpec/Extra/RestrictBlockTag:
12
17
  Description: 'Restrict to only allowed block tags.'
13
18
  Enabled: false
14
- VersionAdded: '<<next>>'
19
+ VersionAdded: '0.1'
15
20
  AllowTags: []
16
21
 
17
22
  RSpec/Extra/RestrictBlockTagValue:
18
23
  Description: 'Restrict to only allowed block tag value.'
19
24
  Enabled: pending
20
- VersionAdded: '<<next>>'
25
+ VersionAdded: '0.1'
21
26
  AllowTagValues: {}
data/docs/antora.yml CHANGED
@@ -1,5 +1,5 @@
1
1
  name: rubocop-rspec-extra
2
2
  title: RuboCop RSpec Extra
3
- version: ~
3
+ version: '0.2'
4
4
  nav:
5
5
  - modules/ROOT/nav.adoc
@@ -2,8 +2,9 @@
2
2
 
3
3
  === Department xref:cops_rspec_extra.adoc[RSpec/Extra]
4
4
 
5
- * xref:cops_rspec_extra.adoc#rspecextra/beempty[RSpec/Extra/BeEmpty]
6
- * xref:cops_rspec_extra.adoc#rspecextra/restrictblocktag[RSpec/Extra/RestrictBlockTag]
7
- * xref:cops_rspec_extra.adoc#rspecextra/restrictblocktagvalue[RSpec/Extra/RestrictBlockTagValue]
5
+ * xref:cops_rspec_extra.adoc#rspecextrabeempty[RSpec/Extra/BeEmpty]
6
+ * xref:cops_rspec_extra.adoc#rspecextraflatexamples[RSpec/Extra/FlatExamples]
7
+ * xref:cops_rspec_extra.adoc#rspecextrarestrictblocktag[RSpec/Extra/RestrictBlockTag]
8
+ * xref:cops_rspec_extra.adoc#rspecextrarestrictblocktagvalue[RSpec/Extra/RestrictBlockTagValue]
8
9
 
9
10
  // END_COP_LIST
@@ -1,19 +1,27 @@
1
+ ////
2
+ Do NOT edit this file by hand directly, as it is automatically generated.
3
+
4
+ Please make any necessary changes to the cop documentation within the source files themselves.
5
+ ////
6
+
1
7
  = RSpec/Extra
2
8
 
9
+ [#rspecextrabeempty]
3
10
  == RSpec/Extra/BeEmpty
4
11
 
5
12
  |===
6
13
  | Enabled by default | Safe | Supports autocorrection | Version Added | Version Changed
7
14
 
8
- | Pending
9
- | Yes
15
+ | Enabled
10
16
  | Yes
11
- | <<next>>
17
+ | Always
18
+ | -
12
19
  | -
13
20
  |===
14
21
 
15
22
  Prefer using `be_empty` when checking for an empty array.
16
23
 
24
+ [#examples-rspecextrabeempty]
17
25
  === Examples
18
26
 
19
27
  [source,ruby]
@@ -32,26 +40,56 @@ expect(array).to match_array([])
32
40
  expect(array).to be_empty
33
41
  ----
34
42
 
35
- === References
43
+ [#rspecextraflatexamples]
44
+ == RSpec/Extra/FlatExamples
36
45
 
37
- * https://www.rubydoc.info/gems/rubocop-rspec-extra/RuboCop/Cop/RSpec/Extra/BeEmpty
46
+ |===
47
+ | Enabled by default | Safe | Supports autocorrection | Version Added | Version Changed
38
48
 
49
+ | Enabled
50
+ | Yes
51
+ | No
52
+ | -
53
+ | -
54
+ |===
55
+
56
+ Restrict unnecessary nesting by example groups.
57
+
58
+ [#examples-rspecextraflatexamples]
59
+ === Examples
60
+
61
+ [source,ruby]
62
+ ----
63
+ # bad
64
+ context 'when condition' do
65
+ it 'tests something' do
66
+ end
67
+ end
68
+
69
+ # good
70
+ it 'tests something when condition' do
71
+ end
72
+ ----
73
+
74
+ [#rspecextrarestrictblocktag]
39
75
  == RSpec/Extra/RestrictBlockTag
40
76
 
41
77
  |===
42
78
  | Enabled by default | Safe | Supports autocorrection | Version Added | Version Changed
43
79
 
44
- | Disabled
80
+ | Enabled
45
81
  | Yes
46
82
  | No
47
- | <<next>>
83
+ | -
48
84
  | -
49
85
  |===
50
86
 
51
87
  Restrict to only allowed block tags.
52
88
 
89
+ [#examples-rspecextrarestrictblocktag]
53
90
  === Examples
54
91
 
92
+ [#allowtags_-__foo__-_bar__-rspecextrarestrictblocktag]
55
93
  ==== AllowTags: ['foo', 'bar']
56
94
 
57
95
  [source,ruby]
@@ -77,32 +115,25 @@ RSpec.describe 'Something' do
77
115
  end
78
116
  ----
79
117
 
80
- === Configurable attributes
81
-
82
- |===
83
- | Name | Default value | Configurable values
84
-
85
- | AllowTags
86
- | `[]`
87
- | Array
88
- |===
89
-
118
+ [#rspecextrarestrictblocktagvalue]
90
119
  == RSpec/Extra/RestrictBlockTagValue
91
120
 
92
121
  |===
93
122
  | Enabled by default | Safe | Supports autocorrection | Version Added | Version Changed
94
123
 
95
- | Pending
124
+ | Enabled
96
125
  | Yes
97
126
  | No
98
- | <<next>>
127
+ | -
99
128
  | -
100
129
  |===
101
130
 
102
131
  Restrict to only allowed block tag value.
103
132
 
133
+ [#examples-rspecextrarestrictblocktagvalue]
104
134
  === Examples
105
135
 
136
+ [#allowtagvalues_-_-foo_-_baz_-_-rspecextrarestrictblocktagvalue]
106
137
  ==== AllowTagValues: { foo: 'baz' }
107
138
 
108
139
  [source,ruby]
@@ -115,13 +146,3 @@ end
115
146
  RSpec.describe 'Something', foo: :baz do
116
147
  end
117
148
  ----
118
-
119
- === Configurable attributes
120
-
121
- |===
122
- | Name | Default value | Configurable values
123
-
124
- | AllowTagValues
125
- | `{}`
126
- |
127
- |===
@@ -8,13 +8,13 @@ There are some ways to do this:
8
8
  Put this into your `.rubocop.yml`:
9
9
 
10
10
  ----
11
- require: rubocop-rspec-extra
11
+ plugins: rubocop-rspec-extra
12
12
  ----
13
13
 
14
14
  or, if you are using several extensions:
15
15
 
16
16
  ----
17
- require:
17
+ plugins:
18
18
  - rubocop-rspec
19
19
  - rubocop-rspec-extra
20
20
  ----
@@ -24,7 +24,7 @@ cops together with the standard cops.
24
24
 
25
25
  [source,bash]
26
26
  ----
27
- $ rubocop --require rubocop-rspec-extra
27
+ $ rubocop --plugins rubocop-rspec-extra
28
28
  ----
29
29
 
30
30
  == Rake task
@@ -32,6 +32,8 @@ $ rubocop --require rubocop-rspec-extra
32
32
  [source,ruby]
33
33
  ----
34
34
  RuboCop::RakeTask.new do |task|
35
- task.requires << 'rubocop-rspec-extra'
35
+ task.plugins << 'rubocop-rspec-extra'
36
36
  end
37
37
  ----
38
+
39
+ NOTE: The plugin system is supported in RuboCop 1.72+. In earlier versions, use `require` instead of `plugins`.
@@ -57,7 +57,7 @@ module RuboCop
57
57
  )
58
58
  PATTERN
59
59
 
60
- def on_send(node)
60
+ def on_send(node) # rubocop:disable InternalAffairs/OnSendWithoutOnCSend
61
61
  expect_array_empty_true?(node.parent) do |actual, expect|
62
62
  register_offense(actual, expect)
63
63
  end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RuboCop
4
+ module Cop
5
+ module RSpec
6
+ module Extra
7
+ # Restrict unnecessary nesting by example groups.
8
+ #
9
+ # @example
10
+ # # bad
11
+ # context 'when condition' do
12
+ # it 'tests something' do
13
+ # end
14
+ # end
15
+ #
16
+ # # good
17
+ # it 'tests something when condition' do
18
+ # end
19
+ #
20
+ class FlatExamples < Base
21
+ MSG = "Unnecessary nesting by example groups detected."
22
+
23
+ # @!method redundant?(node)
24
+ def_node_matcher :redundant?, <<~PATTERN
25
+ (block (send #rspec? #ExampleGroups.regular ...) _ (block (send _ #Examples.regular ...) ...))
26
+ PATTERN
27
+
28
+ def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
29
+ return unless redundant?(node)
30
+
31
+ add_offense(node)
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -30,8 +30,9 @@ module RuboCop
30
30
  class RestrictBlockTag < Base
31
31
  include Metadata
32
32
 
33
- def on_metadata(symbols, pairs)
34
- offenses = (symbols + pairs.map(&:key)).filter do |symbol|
33
+ def on_metadata(symbols, hash)
34
+ symbols += hash.pairs.map(&:key) unless hash.nil?
35
+ offenses = symbols.filter do |symbol|
35
36
  !allow_tags.include?(symbol.value.to_s)
36
37
  end
37
38
 
@@ -19,8 +19,10 @@ module RuboCop
19
19
  include Metadata
20
20
  MSG = "This value is not allowed in this tag. Allowed tag value: %<allow_tag_value>s."
21
21
 
22
- def on_metadata(_symbols, pairs)
23
- offenses = pairs.filter do |pair|
22
+ def on_metadata(_symbols, hash)
23
+ return if hash.nil?
24
+
25
+ offenses = hash.pairs.filter do |pair|
24
26
  allow_tag_values.any? do |k, v|
25
27
  pair.key.value.to_s == k &&
26
28
  pair.value.value.to_s != v
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "lint_roller"
4
+
5
+ module RuboCop
6
+ module RSpec
7
+ module Extra
8
+ # A plugin that integrates RuboCop RSpec Extra with RuboCop's plugin system.
9
+ class Plugin < LintRoller::Plugin
10
+ def about
11
+ LintRoller::About.new(
12
+ name: "rubocop-rspec-extra",
13
+ version: Version::STRING,
14
+ homepage: "https://github.com/ydah/rubocop-rspec-extra",
15
+ description: "A RuboCop extension focused on enforcing RSpec. A place where no one is officially employed, but where useful cops can gather."
16
+ )
17
+ end
18
+
19
+ def supported?(context)
20
+ context.engine == :rubocop
21
+ end
22
+
23
+ def rules(_context)
24
+ project_root = Pathname.new(__dir__).join("../../../..")
25
+
26
+ LintRoller::Rules.new(type: :path, config_format: :rubocop, value: project_root.join("config", "default.yml"))
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -1,9 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Rubocop
4
- module Rspec
4
+ module RSpec
5
5
  module Extra
6
- VERSION = "0.1.0"
6
+ VERSION = "0.3.0"
7
7
  end
8
8
  end
9
9
  end
@@ -2,22 +2,17 @@
2
2
 
3
3
  require "rubocop-rspec"
4
4
 
5
- require_relative "rubocop/rspec/extra/inject"
6
5
  require_relative "rubocop/rspec/extra/version"
7
-
6
+ require_relative "rubocop/rspec/extra/plugin"
8
7
  require_relative "rubocop/cop/rspec/extra/be_empty"
8
+ require_relative "rubocop/cop/rspec/extra/flat_examples"
9
9
  require_relative "rubocop/cop/rspec/extra/restrict_block_tag"
10
10
  require_relative "rubocop/cop/rspec/extra/restrict_block_tag_value"
11
11
 
12
- module RuboCop
12
+ module Rubocop
13
13
  module RSpec
14
+ # RuboCop RSpec Rails project namespace.
14
15
  module Extra
15
- PROJECT_ROOT = ::Pathname.new(__dir__).parent.expand_path.freeze
16
- CONFIG_DEFAULT = PROJECT_ROOT.join("config", "default.yml").freeze
17
- CONFIG = ::YAML.safe_load(CONFIG_DEFAULT.read).freeze
18
- private_constant(:CONFIG_DEFAULT, :PROJECT_ROOT)
19
16
  end
20
17
  end
21
18
  end
22
-
23
- RuboCop::RSpec::Extra::Inject.defaults!
@@ -5,7 +5,7 @@ require "bump"
5
5
  namespace :cut_release do
6
6
  %w[major minor patch pre].each do |release_type|
7
7
  desc "Cut a new #{release_type} release and create release notes."
8
- task release_type => "changelog:check_clean" do
8
+ task release_type do
9
9
  run(release_type)
10
10
  end
11
11
  end
@@ -13,7 +13,7 @@ namespace :cut_release do
13
13
  def add_header_to_changelog(version)
14
14
  update_file("CHANGELOG.md") do |changelog|
15
15
  changelog.sub("## Master (Unreleased)\n\n",
16
- '\0' "## #{version} (#{Time.now.strftime("%F")})\n\n")
16
+ "\\0## #{version} (#{Time.now.strftime("%F")})\n\n")
17
17
  end
18
18
  end
19
19
 
metadata CHANGED
@@ -1,31 +1,49 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubocop-rspec-extra
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - ydah
8
- autorequire:
9
8
  bindir: exe
10
9
  cert_chain: []
11
- date: 2023-04-17 00:00:00.000000000 Z
10
+ date: 2025-03-18 00:00:00.000000000 Z
12
11
  dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: lint_roller
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - "~>"
17
+ - !ruby/object:Gem::Version
18
+ version: '1.1'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - "~>"
24
+ - !ruby/object:Gem::Version
25
+ version: '1.1'
13
26
  - !ruby/object:Gem::Dependency
14
27
  name: rubocop
15
28
  requirement: !ruby/object:Gem::Requirement
16
29
  requirements:
17
30
  - - ">="
18
31
  - !ruby/object:Gem::Version
19
- version: '0'
32
+ version: 1.72.1
33
+ - - "<"
34
+ - !ruby/object:Gem::Version
35
+ version: '2.0'
20
36
  type: :runtime
21
37
  prerelease: false
22
38
  version_requirements: !ruby/object:Gem::Requirement
23
39
  requirements:
24
40
  - - ">="
25
41
  - !ruby/object:Gem::Version
26
- version: '0'
42
+ version: 1.72.1
43
+ - - "<"
44
+ - !ruby/object:Gem::Version
45
+ version: '2.0'
27
46
  description: |
28
- Automatic committee code style checking tool.
29
47
  A RuboCop extension focused on enforcing RSpec.
30
48
  A place where no one is officially employed, but where useful cops can gather.
31
49
  email:
@@ -56,12 +74,11 @@ files:
56
74
  - docs/modules/ROOT/pages/usage.adoc
57
75
  - lib/rubocop-rspec-extra.rb
58
76
  - lib/rubocop/cop/rspec/extra/be_empty.rb
77
+ - lib/rubocop/cop/rspec/extra/flat_examples.rb
59
78
  - lib/rubocop/cop/rspec/extra/restrict_block_tag.rb
60
79
  - lib/rubocop/cop/rspec/extra/restrict_block_tag_value.rb
61
- - lib/rubocop/rspec/extra/inject.rb
80
+ - lib/rubocop/rspec/extra/plugin.rb
62
81
  - lib/rubocop/rspec/extra/version.rb
63
- - tasks/changelog.rake
64
- - tasks/changelog.rb
65
82
  - tasks/cops_documentation.rake
66
83
  - tasks/cut_release.rake
67
84
  - tasks/new_cop.rake
@@ -72,8 +89,8 @@ metadata:
72
89
  homepage_uri: https://github.com/ydah/rubocop-rspec-extra
73
90
  source_code_uri: https://github.com/ydah/rubocop-rspec-extra
74
91
  changelog_uri: https://github.com/ydah/rubocop-rspec-extra/blob/master/CHANGELOG.md
92
+ default_lint_roller_plugin: RuboCop::RSpec::Extra::Plugin
75
93
  rubygems_mfa_required: 'true'
76
- post_install_message:
77
94
  rdoc_options: []
78
95
  require_paths:
79
96
  - lib
@@ -81,15 +98,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
81
98
  requirements:
82
99
  - - ">="
83
100
  - !ruby/object:Gem::Version
84
- version: 2.6.0
101
+ version: 2.7.0
85
102
  required_rubygems_version: !ruby/object:Gem::Requirement
86
103
  requirements:
87
104
  - - ">="
88
105
  - !ruby/object:Gem::Version
89
106
  version: '0'
90
107
  requirements: []
91
- rubygems_version: 3.4.5
92
- signing_key:
108
+ rubygems_version: 3.7.0.dev
93
109
  specification_version: 4
94
- summary: Automatic committee code style checking tool.
110
+ summary: A RuboCop extension focused on enforcing RSpec.
95
111
  test_files: []
@@ -1,18 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module RuboCop
4
- module RSpec
5
- module Extra
6
- module Inject
7
- def self.defaults!
8
- path = CONFIG_DEFAULT.to_s
9
- hash = ::RuboCop::ConfigLoader.send(:load_yaml_configuration, path)
10
- config = ::RuboCop::Config.new(hash, path).tap(&:make_excludes_absolute)
11
- puts "configuration from #{path}" if ::RuboCop::ConfigLoader.debug?
12
- config = ::RuboCop::ConfigLoader.merge_with_default(config, path)
13
- ::RuboCop::ConfigLoader.instance_variable_set(:@default_configuration, config)
14
- end
15
- end
16
- end
17
- end
18
- end
data/tasks/changelog.rake DELETED
@@ -1,35 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- autoload :Changelog, "#{__dir__}/changelog"
4
-
5
- namespace :changelog do
6
- %i[new fix change].each do |type|
7
- desc "Create a Changelog entry (#{type})"
8
- task type, [:id] do |_task, args|
9
- ref_type = :pull if args[:id]
10
- path = Changelog::Entry.new(type: type, ref_id: args[:id], ref_type: ref_type).write
11
- cmd = "git add #{path}"
12
- system cmd
13
- puts "Entry '#{path}' created and added to git index"
14
- end
15
- end
16
-
17
- desc "Merge entries and delete them"
18
- task :merge do
19
- raise "No entries!" unless Changelog.pending?
20
-
21
- Changelog.new.merge!.and_delete!
22
- cmd = "git commit -a -m 'Update Changelog'"
23
- puts cmd
24
- system cmd
25
- end
26
-
27
- desc "Check to see if there are any entries left"
28
- task :check_clean do
29
- next unless Changelog.pending?
30
-
31
- puts "*** Pending changelog entries!"
32
- puts "Do `bundle exec rake changelog:merge`"
33
- exit(1)
34
- end
35
- end
data/tasks/changelog.rb DELETED
@@ -1,193 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- if RUBY_VERSION < "2.6"
4
- puts "Changelog utilities available only for Ruby 2.6+"
5
- exit(1)
6
- end
7
-
8
- # Changelog utility
9
- class Changelog
10
- ENTRIES_PATH = "changelog/"
11
- FIRST_HEADER = /#{Regexp.escape("## Master (Unreleased)\n")}/m.freeze
12
- CONTRIBUTORS_HEADER = /#{Regexp.escape("<!-- Contributors (alphabetically) -->\n\n")}/m.freeze
13
- ENTRIES_PATH_TEMPLATE = "#{ENTRIES_PATH}%<type>s_%<name>s.md"
14
- TYPE_REGEXP = /#{Regexp.escape(ENTRIES_PATH)}([a-z]+)_/.freeze
15
- TYPE_TO_HEADER = { new: "New features", fix: "Bug fixes", change: "Changes" }.freeze
16
- HEADER = /### (.*)/.freeze
17
- PATH = "CHANGELOG.md"
18
- REF_URL = "https://github.com/rubocop/rubocop-rspec-extra"
19
- MAX_LENGTH = 40
20
- CONTRIBUTOR = "[@%<link>s]: https://github.com/%<user>s"
21
- SIGNATURE = Regexp.new(format(Regexp.escape("[@%<user>s]"), user: '([\w-]+)'))
22
- EOF = "\n"
23
-
24
- # New entry
25
- Entry = Struct.new(:type, :body, :ref_type, :ref_id, :user, keyword_init: true) do
26
- def initialize(type:, body: last_commit_title, ref_type: nil, ref_id: nil, user: github_user)
27
- id, body = extract_id(body)
28
- ref_id ||= id || "x"
29
- ref_type ||= id ? :issues : :pull
30
- super
31
- end
32
-
33
- def write
34
- FileUtils.mkdir_p(ENTRIES_PATH)
35
- File.write(path, content)
36
- path
37
- end
38
-
39
- def path
40
- format(ENTRIES_PATH_TEMPLATE, type: type, name: str_to_filename(body))
41
- end
42
-
43
- def content
44
- period = "." unless body.end_with? "."
45
- "- #{ref}: #{body}#{period} ([@#{user}])\n"
46
- end
47
-
48
- def ref
49
- "[##{ref_id}](#{REF_URL}/#{ref_type}/#{ref_id})"
50
- end
51
-
52
- def last_commit_title
53
- `git log -1 --pretty=%B`.lines.first.chomp
54
- end
55
-
56
- def extract_id(body)
57
- /^\[Fix(?:es)? #(\d+)\] (.*)/.match(body)&.captures || [nil, body]
58
- end
59
-
60
- def str_to_filename(str)
61
- str
62
- .split
63
- .reject(&:empty?)
64
- .map { |s| prettify(s) }
65
- .inject do |result, word|
66
- s = "#{result}_#{word}"
67
- return result if s.length > MAX_LENGTH
68
-
69
- s
70
- end
71
- end
72
-
73
- def github_user
74
- user = `git config --global credential.username`.chomp
75
- warn 'Set your username with `git config --global credential.username "myusernamehere"`' if user.empty?
76
-
77
- user
78
- end
79
-
80
- private
81
-
82
- def prettify(str)
83
- str.gsub!(/\W/, "_")
84
-
85
- # Separate word boundaries by `_`.
86
- str.gsub!(/([A-Z]+)(?=[A-Z][a-z])|([a-z\d])(?=[A-Z])/) do
87
- (Regexp.last_match(1) || Regexp.last_match(2)) << "_"
88
- end
89
-
90
- str.gsub!(/\A_+|_+\z/, "")
91
- str.downcase!
92
- str
93
- end
94
- end
95
-
96
- def self.pending?
97
- entry_paths.any?
98
- end
99
-
100
- def self.entry_paths
101
- Dir["#{ENTRIES_PATH}*"]
102
- end
103
-
104
- def self.read_entries
105
- entry_paths.to_h { |path| [path, File.read(path)] }
106
- end
107
-
108
- attr_reader :header, :rest
109
-
110
- def initialize(content: File.read(PATH), entries: Changelog.read_entries)
111
- require "strscan"
112
-
113
- parse(content)
114
- @entries = entries
115
- end
116
-
117
- def and_delete!
118
- @entries.each_key { |path| File.delete(path) }
119
- end
120
-
121
- def merge!
122
- File.write(PATH, merge_content)
123
- self
124
- end
125
-
126
- def unreleased_content
127
- entry_map = parse_entries(@entries)
128
- merged_map = merge_entries(entry_map)
129
- merged_map.flat_map do |header, things|
130
- ["### #{header}\n", *things, ""]
131
- end.join("\n")
132
- end
133
-
134
- def merge_content
135
- merged_content = [@header, unreleased_content, @changes.chomp, *all_contributors].join("\n")
136
-
137
- merged_content << EOF
138
- end
139
-
140
- def all_contributors
141
- (@contributors.split(/\R/) + new_contributors).uniq.sort
142
- end
143
-
144
- def new_contributors
145
- contributors
146
- .map { |user| format(CONTRIBUTOR, link: user.downcase, user: user) }
147
- end
148
-
149
- def contributors
150
- contributors = @entries.values.flat_map do |entry|
151
- entry.match(/\. \((?<contributors>.+)\)\n/)[:contributors].split(",")
152
- end
153
-
154
- contributors.join.scan(SIGNATURE).flatten
155
- end
156
-
157
- private
158
-
159
- def merge_entries(entry_map)
160
- all = @unreleased.merge(entry_map) { |_k, v1, v2| v1.concat(v2) }
161
- canonical = TYPE_TO_HEADER.values.to_h { |v| [v, nil] }
162
- canonical.merge(all).compact
163
- end
164
-
165
- def parse(content)
166
- ss = StringScanner.new(content)
167
- @header = ss.scan_until(FIRST_HEADER)
168
- @unreleased = parse_release(ss.scan_until(/\n(?=## )/m))
169
- @changes = ss.scan_until(CONTRIBUTORS_HEADER)
170
- @contributors = ss.rest
171
- end
172
-
173
- # @return [Hash<type, Array<String>]]
174
- def parse_release(unreleased)
175
- unreleased
176
- .lines
177
- .map(&:chomp)
178
- .reject(&:empty?)
179
- .slice_before(HEADER)
180
- .to_h do |header, *entries|
181
- [HEADER.match(header)[1], entries]
182
- end
183
- end
184
-
185
- def parse_entries(path_content_map)
186
- changes = Hash.new { |h, k| h[k] = [] }
187
- path_content_map.each do |path, content|
188
- header = TYPE_TO_HEADER.fetch(TYPE_REGEXP.match(path)[1].to_sym)
189
- changes[header].concat(content.lines.map(&:chomp))
190
- end
191
- changes
192
- end
193
- end