Hey, everyone!

We planned to add a guideline to recommend against using an RSpec practice codenamed “Implicit Block Expectation Syntax”, but received some controversial feedback. In order to keep the RSpec style guide reflecting the opinion of the Ruby community, we decided to highlight this topic and start a discussion.

The syntax is as following:

subject { -> { do_something } }
it { is_expected.to change(something).to(new_value) }

As you know, change is a block matcher. The above Implicit Block Expectation Syntax can be expressed with explicit syntax:

it 'changes something to a new value' do
  expect { do_something }.to change(something).to(new_value)
end

Pros for using the syntax in question that we’re aware of are:

  • allows to use block matchers with one-liner syntax (is_expected)
  • no need to repeat expect { ... }

Cons:

  • an exception to the case when subject is cached, e.g. on each is_subject call the passed lambda will be re-executed
  • rarely used and unfamiliar to many people
  • barely possible to detect it as a block expectation syntax with static analysis tools (RuboCop, Reek)
  • the guide doesn’t recommend using one-liner syntax except in some cases
  • there are no tests or documentation in RSpec that cover this syntax

Here’s RSpec core team opinion on the topic:

pretty obtuse and not something I’d recommend, generally.

Myron Marston

Should we add one-liner Relish documentation about using block matchers?

We should mention they’re not supported.

Jon Rowe

The discussion is here.1

In the spirit of broader community collaboration we’ve started this blog so that more people can see what we’re working on, and participate in the discussions around introducing new guidelines and changing existing ones.2

Feel free to leave your reaction (a thumbs up or down, heart, rocket, or even a confused face) on the issue. Thumbs up will count towards recommending against this syntax, and thumbs down to leave out this guideline.

We encourage you to bring additional arguments for and against the syntax being discussed in the comments.

The expected outcome of the discussion can be either leaving the guideline out, or adding a guideline that would recommend avoiding this syntax, adding a rubocop-rspec cop to enforce it, and doing our best to make it practically impossible in the next major release of RSpec itself. But it’s all up to you how it will end up!

We highly appreciate if you take the time to glance over the other open questions and leave your reaction. Basing on your activity, we’ll pick what to discuss next, or will go ahead and add guidelines that got a prevailing number of positive reactions.

  1. Please keep to the point of this practice, and feel free to open issues for other, even closely related topics. 

  2. Discussions traditionally happen on the issue trackers of the style guides, we’re announcing them on this blog to reach out to more people.