thoughtbot / shoulda-matchers

Simple one-liner tests for common Rails functionality
https://matchers.shoulda.io
MIT License
3.51k stars 912 forks source link

Numericality matcher not working as expected on 6.0.0 #1601

Closed stephannv closed 9 months ago

stephannv commented 9 months ago

Description

After upgrading to 6.0.0 some tests using negated numericality matcher are failing. To be more specific: I'm using the greater_than qualifier, I didn't try the others numericality matcher qualifiers.

Reproduction Steps

Failures:

1) Product validations when is a test product is expected not to validate that :value looks like a number greater than 0 Failure/Error: it { is_expected.not_to validate_numericality_of(:value).is_greater_than(0) }

   Expected Product not to validate that :value looks like a number greater
   than 0, but this could not be proved.
     After setting :value to ‹1›, the matcher expected the Product to be
     invalid, but it was valid instead.
 # ./spec/models/product_spec.rb:9:in `block (4 levels) in <top (required)>'

Ps. I could not find the REPRODUCTION_SCRIPT.rb here: https://github.com/thoughtbot/shoulda-matchers/blob/main/.github/REPRODUCTION_SCRIPT.rb 
But I created a MRP: 
[mrp_shoulda_matchers.zip](https://github.com/thoughtbot/shoulda-matchers/files/13801203/mrp_shoulda_matchers.zip)

### Expected behavior

<!-- What you expected to happen. -->
All tests should pass
### Actual behavior

<!-- What happened instead. -->
One test is failing 

### System configuration
**shoulda_matchers version**:  6.0.0
**rails version**:  7.1.2
**ruby version**: 3.3.0
amalrik commented 9 months ago

I could reproduce the error on my local machine. I noticed if you remove the .is_greater_than(0) qualifier the tests pass so my guess is something related to that specific feature. so this wont pass:

# spec/models/product_spec.rb
RSpec.describe Product, type: :model do

  describe "validations" do
    context "when is a test product" do
      subject { Product.new(test: true) }

      it { is_expected.not_to validate_numericality_of(:value).is_greater_than(0) }
    end

    context "when is not a test product" do
      subject { Product.new(test: false) }

      it { is_expected.to validate_numericality_of(:value).is_greater_than(0) }
    end
  end
end

but this will:

# spec/models/product_spec.rb
RSpec.describe Product, type: :model do

  describe "validations" do
    context "when is a test product" do
      subject { Product.new(test: true) }

      it { is_expected.not_to validate_numericality_of(:value) }
    end

    context "when is not a test product" do
      subject { Product.new(test: false) }

      it { is_expected.to validate_numericality_of(:value).is_greater_than(0) }
    end
  end
end
amalrik commented 9 months ago

I could found the commit that created the problem. Its the commit 95c39285d9b0235d21a7e6ca6ee99f0166f1c06b. Its a pretty big commit so I need take some time to study it, but if any of you guys more familiar with that PR could take a look a it maybe you could find out whats wrong faster. EDIT: I forgot to mention the PR(1552)

matsales28 commented 9 months ago

Hi, thanks for reporting this problem. I’m travelling but can take a look at this next week.