-
-
Notifications
You must be signed in to change notification settings - Fork 276
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/SortMetadata
autocorrect can break context groups having additional description
#1946
Comments
Thanks for reporting. But there’s a related discussion here rspec/rspec#40 We’re open to adjust the cop to match the RSpec semantics. Would you be interested in submitting a PR? |
Yes, I also searched for reference of this in the docs and in the Cucumber scenarios but without any success. The I'm not sure why it's not documented because it has been quite useful for us. The usage I'm referring to is in this spec.
Yes, once we agree on the RSpec semantics, that could be interesting. |
There’s also this PR. |
Here’s the interesting part rspec/rspec-core#2681 (comment) I think the takeaway here is that the second string argument works as an additional docstring. And will still be, for years to come. It is not, and will never be considered metadata, because it’s not a symbol. Basing on this, it makes sense to exclude literal str/xstr nodes from sorting. describe "foo", may_be_a_string_or_a_symbol, :c, :d do Only literal symbols should be passed to sorting. I have some doubts that this weird out-of-order zoo of arguments is even accepted by RSpec if the variable holds a symbol: it 'Something', variable, 'B', :a What do you think? |
Nice findings!
In an example definition, only the first arg is considered the description, then the rest is used to build up metadata. When metadata is build up from args, only the last arg hash and the last symbol args are used. Anything else is discarded. So Same for It's only for And for this kind of usage: > describe 'Something', variable, 'B', :a It will fail because there are too many remaining args once the metadata are extracted from the args ( What the cop could do anyway is to always sort like this:
Would that work? |
Nice! A few practical examples to what you state above to help to dissect this: Example group with string metadata-wannabe: fail vs swallowRSpec.describe "docstring", :real, "fake" do it fails with:
But it "docstring", :swallowed, "swallowed" do Tertiary docstring: fail vs swallow
it "docstring", "swallowed", "swallowed", "swallowed", :real_metadata do with no regards if there is or not any real metadata. It swallows strings, lambdas, hashes, anything.
RSpec.describe "Primary docstring", "secondary", "BOOM" do
If there's an RSpec error (and there is for I agree with your conclusion, with one correction:
docsting = "docstring"
about = :about
it docstring, about do
end will result in the lost docstring. I suggest not to sort variables. Does this change to conclusion sound reasonable? |
I'll also leave this small reference here just in case. |
Thanks for the clear examples.
Nice catch.
Yes, perfect. I'll start working on a PR to fix this. |
Actually, this is not correct because of this case: metadata = { foo: :bar }
it "works", :about, metadata do
end If the cop blindly changes the order to [strings, variables, symbols, hash], then it change it to this and produce an error: metadata = { foo: :bar }
it "works", metadata, :about do
end I feel like the last arg should be kept last if it's a hash or a variable, then apply the sorting [strings, other args, symbols]. Does it sound reasonable? |
Absolutely! |
Fixes rubocop#1946. Symbols in metadata are processed by RSpec only when they are positioned last, meaning the other parameter types must be positioned before the symbols. RSpec `context`/`describe` accepts second non-symbol argument as an additional description which is why strings are sorted first.
Fixes rubocop#1946. Symbols in metadata are processed by RSpec only when they are positioned last, meaning the other parameter types must be positioned before the symbols. RSpec `context`/`describe` accepts second non-symbol argument as an additional description which is why strings are sorted first.
Metadata processed by RSpec is: - the last argument when it's a hash - the trailing arguments when they are symbols Only this metadata is sorted by this cop. If the second argument to a `context`/`describe` block is used as an additional description, it is not sorted anymore. This fixes rubocop#1946.
Metadata processed by RSpec is: - the last argument when it's a hash - the trailing arguments when they are symbols Only this metadata is sorted by this cop. If the second argument to a `context`/`describe` block is used as an additional description, it is not sorted anymore. This fixes rubocop#1946.
rspec --format documentation spec/test_spec.rb
rubocop -A spec/test_spec.rb
File updated to:
rspec --format documentation spec/test_spec.rb
The number of arguments expected is from
#build_description_from(parent_description=nil, my_description=nil)
inlib/rspec/core/metadata.rb
from rspec-core.We sometimes use this ability to have an additional description parameter with
RSpec.describe
when writing spec for a specific feature flag or to split up a spec file in smaller parts when it becomes too big. Occasionally theRSpec/SortMetadata
breaks it depending on the metadata we use by swapping the description and the symbols like above. We disable the cop for the line and that's ok, but it would be nice to have it fixed upstream.It seems like it is somewhat an expected behavior though:
rubocop-rspec/spec/rubocop/cop/rspec/sort_metadata_spec.rb
Lines 98 to 111 in ff213ae
The text was updated successfully, but these errors were encountered: