Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RSpec/SpecFilePathFormat allow multiple values for same key in IgnoreMetadata #2070

Conversation

sriedel
Copy link

@sriedel sriedel commented Apr 4, 2025

RSpec/SpecFilePathFormat allows ignoring certain values in rspec metadata through the IgnoreMetadata option, as given in the documentation:

      # @example `IgnoreMetadata: {type=>routing}` (default)
      #   # good
      #   whatever_spec.rb         # describe MyClass, type: :routing do; end

However the current implementation does not seem to allow supplying multiple values for the same key - e.g. if you have some specs marked type: controller, others as type: :model etc, only one of controller, model, ... can be supplied to be ignored.

This is probably due to an oversight (or me not being able to figure out how to properly supply an array of values to be ignored).

The PR allows for either an array or a single value to be given for a key in the IgnoreMetadata option.

While it would also be desirable to give a true value to ignore all metadata, in the format that IgnoreMethods use, this should probably be part of a different PR.

@sriedel sriedel requested a review from a team as a code owner April 4, 2025 10:51
@@ -281,4 +281,14 @@ class Foo
RUBY
end
end

context 'when configured with `IgnoreMetadata: { "foo" => ["bar"] }`' do
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think maybe you should write a spec for IgnoreMetadata: { "foo" => ["bar", "baz"] } and validate that it ignores specs with either value. And that it does not ignore a spec without another value for foo, or no foo metadata at all.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair, are the amended specs what you had in mind? I needed to play around with the wording a bit, since I was over the line length limit by one and two characters respectively, by using the existing phrasing.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for ignorance, but what if the value of the metdata value is an array of bar baz?
Or an array of just bar?

I haven’t glanced over the changes, but if we happen to want to allow multiple values, there will be less ambiguity if we accept accept a list of metadata to ignore. Will it work?

@@ -925,6 +925,7 @@ RSpec/SpecFilePathFormat:
IgnoreMetadata:
type: routing
VersionAdded: '2.24'
VersionChanged: "<<next>>"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change is unnecessary. Could you please revert?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, however I'd like to confirm that the revert would be correct, as the Pull Request template specifically states:

If you have modified an existing cop's configuration options:

- [ ] Set `VersionChanged: "<<next>>"` in `config/default.yml`.

and this PR does change an existing cops configuration options.

Copy link
Member

@ydah ydah Apr 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to my understanding, "modified an existing cop's configuration options" refers to instances such as when adding a new configuration option, changing a name, or for example, when adding autocorrect functionality and adding Autocorrect: true, we should add VersionChanged: "<<next>>".

Comment on lines 81 to 82
ignore_values = ignore_metadata[key.to_s]
ignore_values = [ignore_values] unless ignore_values.is_a?(Array)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can use Array() instead:

Suggested change
ignore_values = ignore_metadata[key.to_s]
ignore_values = [ignore_values] unless ignore_values.is_a?(Array)
ignore_values = Array(ignore_metadata[key.to_s])

@ydah
Copy link
Member

ydah commented Apr 4, 2025

Could you rebase to the latest master branch?

@@ -32,6 +32,11 @@ module RSpec
# # good
# whatever_spec.rb # describe MyClass, type: :routing do; end
#
# @example `IgnoreMetadata: {type=>[routing,models]}` (default)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it really configured like this in YAML?

# @example `IgnoreMetadata: {type=>[routing,models]}` (default)
# # good
# whatever_spec.rb # describe MyClass, type: :routing do; end
# whatever_spec.rb # describe MyClass, type: :models do; end
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if the metadata's value IS an array?

RSpec.describe Airplane, prepare: [:fuel] do

How do we define IgnoreMetadata in YAML?

@@ -102,6 +102,8 @@ def on_send(node)
private

def register_offense(node, change_node)
return unless node.parent.send_type?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unrelated?

@@ -137,7 +137,7 @@ class EmptyExampleGroup < Base
PATTERN

def on_block(node) # rubocop:disable InternalAffairs/NumblockHandler
return if node.each_ancestor(:def, :defs).any?
return if node.each_ancestor(:any_def).any?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This, too, and related specs

# @example `IgnoreMetadata: {type=>[routing,models]}` (default)
# # good
# whatever_spec.rb # describe MyClass, type: :routing do; end
# whatever_spec.rb # describe MyClass, type: :models do; end
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Side note: how do we ignore any value for a key?

# @example `IgnoreMetadata: {type=>[routing,models]}` (default)
# # good
# whatever_spec.rb # describe MyClass, type: :routing do; end
# whatever_spec.rb # describe MyClass, type: :models do; end
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm hinting towards:

IgnoreMetadata:
  - prepare
  - type: model
  - type: routing
  - skip: [database]

Luckily enough, YAML allows to mix all that, and to cover all ignored cases unambiguously.

@sriedel
Copy link
Author

sriedel commented Apr 7, 2025

I seem to have fat-fingered the rebase. I'll close this PR and reopen a new one with the current state of changes tomorrow.

@sriedel
Copy link
Author

sriedel commented Apr 10, 2025

Clean rebase PR in #2076

@sriedel sriedel closed this Apr 10, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants