rspec / rspec/rspec

Raise an error when calling custom matcher without using `.and`

Open
#142 5 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Ruby
Stars
117
Forks
51
Avg merge
59m
Merged PRs (30d)
3

Description

Subject of the issue

Hi there folks 👋 ,

First of all, thank you for this great gem! I created this issue here just to offer a small idea, I encountered a small scenario when using custom matchers.

Let's say we have this custom matcher

RSpec::Matchers.define(:create_some_model) do
  chain(:method1) {}
  chain(:method2) {}
  chain(:method3) {}
  ...
end

describe do
  it do
    expect { some_action }.to create_some_model(Model).method1.method2.method3.create_some_model(Model2)
  end
end

As you can see, it is easy to make mistake as we sometime might forget to add .and between create_some_model and this could create false-positive test result as it will only run create_some_model(Model2). I understand that this is more human error but I would love to prevent it.

My idea is in RSpec::Matchers::DSL::Matcher, we also define

class RSpec::Matchers::DSL::Matcher
  define_method(method) do
    raise "You did not use .and between your 'create_some_model' test expectation"
  end
end

So calling create_some_model twice will resulting in error like that. There is one catch with this approach is you cannot call the same create_some_model inside the matcher itself but IMHO, I don't think it is a good idea to do such

RSpec::Matchers.define(:create_some_model) do
  chain(:method1) {}
  chain(:method2) {}
  chain(:method3) {}
  
 def something
   expect { }.to create_some_model <-- this doesn't work
 end
  ...
end

I can create a PR to apply this idea, please let me know what do you guys think. Thank you for reading!

P/S:

There is 1 more approach besides that is to get rid of the defined custom matcher method from RSpec::Matchers::DSL::Matcher but if we do that we also have to get rid of the method_missing as well which I don't think it is a good idea.

Your environment
  • Ruby version: 2.7.5
  • rspec-expectations version: 3.13.0.pre

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in RSpec::Matchers::DSL::Matcher and reproduce the custom matcher chain shown in the issue, comparing a repeated matcher call with one separated by .and. Review the existing matcher DSL behavior before deciding how the error should interact with matcher internals; done means the accidental repeated call raises an informative error without breaking the intended chained form.

Written by the indexing model from the issue text.

Assessment

Tech stack
ruby
Domain
testing
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.