Rubocop-rspec: RSpec/ContextWording with nested contexts

Created on 8 Dec 2017  路  15Comments  路  Source: rubocop-hq/rubocop-rspec

How should one use the RSpec/ContextWording with nested contexts? Should it support 'and with/when' such that when I do:

describe 'The program' do
  context 'when configured' do
    context 'and when the user is valid' do
      it 'does the right thing'
    end
  end
end

and run $ rspec spec --format documentation

it shows a readable sentence?
"The program when configured and when the user is valid does the right thing"

Presently my example triggers:
Start context description with 'when', 'with' or 'without'.

If I follow that advice, the documentation is less readable:
"The program when configured when the user is valid does the right thing"

Most helpful comment

I was actually thinking of adding a when/with and without helpers, e.g.:

describe '...' do
  when 'the visitor has an email' do
    with 'a corresponding user' do
      without 'a confirmation' do
        ...
      end
    end
  end
end

Problem with an and is that it's a Ruby keyword ;)

All 15 comments

cc @pirj

when configured with valid user will pass the cop and IMO is better description.

@Darhazer I think you are implying that it is configured with the user, but I was saying something more along the lines of: when the program has a correct configuration and a valid user

It makes sense to open this issue on https://github.com/reachlocal/rspec-style-guide or https://github.com/lelylan/betterspecs, we're just soldiers here, we don't create rules.

@pirj I can appreciate that:

https://github.com/reachlocal/rspec-style-guide/issues/17

There's already a question about the and coupler on https://github.com/lelylan/betterspecs/issues/3#issuecomment-31960370

@pirj I just talked with @bikeonastick (from ReachLocal) tonight and he said that they are no longer maintaining https://github.com/reachlocal/rspec-style-guide

@Darhazer it's ok for the example above but what if we would have more than one nesting?

feature "As a visitor, who has given a purchase link, I should not be allowed to see purchase page" do
  context "when the visitor has an email set up in session" do
    context "and visitor has corresponding user in db" do
      context "and visitor's domain of email is white-listed" do
      end
    end
  end
end

I don't yet have a strong opinion on this, but one thought is that while "and" makes the final docstring seem neat and readable in some cases, it makes reading the spec itself feel a bit more awkward to me. "Here's the context: and {x}" feels strange to me in a way that "Here's the context: when {x}" doesn't.

@IlkhamGaysin I think your example is reasonable, but I'd be more likely to write it as:

feature "As a visitor, who has given a purchase link, I should not be allowed to see purchase page" do
  context "when the visitor has an email set up in session" do
    context "with a corresponding user in the db" do
      context "with a white-listed email domain" do
      end
    end
  end
end

But I'm not convinced one is clearly better than the other. I generally try to avoid having deeply nested contexts when i can so I don't think about this problem that often. I do sometimes end up with something like "with a corresponding user in the db and the user has a white-listed email domain" and just skipping a context level. That may be cheating for the purpose of the discussion though.

One other very minor thought is that if you allow "and" it wouldn't be flagged if there was no parent context string for it to be connected onto, but I confess that I expect that case is exceedingly rare.

Individual users, of course, are free to add 'and' to their rubocop config file as it suits them. I don't have a strong opinion about adding it or not adding it to the defaults at the moment though.

I was actually thinking of adding a when/with and without helpers, e.g.:

describe '...' do
  when 'the visitor has an email' do
    with 'a corresponding user' do
      without 'a confirmation' do
        ...
      end
    end
  end
end

Problem with an and is that it's a Ruby keyword ;)

@pirj looks good! :+1:

Related to #757.
Context Descriptions guideline is now more permissive:

When an example block description is composed with context block descriptions, it should result in a sentence with proper grammar. This typically means the context should start with a term such as 'when', 'with', or 'without'.

Would you agree to configure prefixes for the cop on a per-project basis, or is it a major effort you wouldn't want to deal with, @jcoyne ?

There's a lengthy list of the frequently used prefixes I've gathered from real-world-rails.

I think the advice that "it should result in a sentence with proper grammar" leads one to the use of "and".

"when x is true when y is true" would be properly written "when x is true and when y is true"

Personally, I don't mind configuring my own prefixes, but by default you can't make proper sentences for the documentation formatter without the use of "and"

@jcoyne You can just write a different sentence that reads better.
The program when configured with a valid user does the right thing

@IlkhamGaysin

feature "As a visitor, who has given a purchase link, I should not be allowed to see purchase page" do
  context "when the visitor has an email set up in session" do
    context "with a corresponding user in db" do
      context "with a white-listed email" do
      end
    end
  end
end

Granted in this context it makes it a little more reasonable that you might use and in a nested context, but I personally wonder if that starts being a code-smell when it gets too nested.
Maybe? Maybe not?

There is the option of turning off the cop, or perhaps it could be configurable to white-list other words in the cop?

I personally wouldn't want the and word added to start contexts with as the only places I've seen my team use it has been when their sentences are written confusingly anyway.

Do you think there is something actionable here, or can this be closed?

I think "and when" and "and with" could be added to the default acceptable prefixes.

Was this page helpful?
0 / 5 - 0 ratings