rspec-core: BigDecimal comparison failing

Hi, I ran into this bug while customizing the rspec-rails controller tests generated by scaffolding. The BigDecimal comparison is failing, with the change being the maximum (but not current) number of significant digits. Here’s the output of the test where I’m comparing the number 3 to the results of a PUT of the number 3:

$ rspec
Run options: include {:focus=>true}
F

Failures:

  1) CompaniesController PUT update with valid params updates the requested company
     Failure/Error: expect(assigns(:company).attributes.delete_mutable_attributes).to eq(new_attributes)

       expected: {"name"=>"New Name", "longitude"=>#<BigDecimal:7f90b6f0b970,'0.3E1',9(27)>, "date"=>Thu, 24 Jul 2014 02:29:13 UTC +00:00}
            got: {"name"=>"New Name", "longitude"=>#<BigDecimal:7f90b6ec9638,'0.3E1',9(18)>, "date"=>Thu, 24 Jul 2014 02:29:13 UTC +00:00}

       (compared using ==)

       Diff:
       @@ -1,4 +1,4 @@
        "date" => Thu, 24 Jul 2014 02:29:13 UTC +00:00,
       -"longitude" => #<BigDecimal:7f90b6f0b970,'0.3E1',9(27)>,
       +"longitude" => #<BigDecimal:7f90b6ec9638,'0.3E1',9(18)>,
        "name" => "New Name",

     # ./spec/controllers/companies_controller_spec.rb:23:in `block (4 levels) in <top (required)>'

Finished in 0.02568 seconds (files took 1 second to load)
1 example, 1 failure

Failed examples:

rspec ./spec/controllers/companies_controller_spec.rb:19 # CompaniesController PUT update with valid params updates the requested company

The failing test is:

require 'rails_helper'

RSpec.describe CompaniesController, :type => :controller do

  let(:valid_attributes) { Company.new(name: "Old Name", longitude: 2, date: 1.hour.ago).attributes }
  let(:valid_session) { {} }

  class Hash
    def delete_mutable_attributes
      self.delete_if { |k, v| %w[id created_at updated_at].member?(k) }
    end
  end

  describe "PUT update" do
    describe "with valid params" do
      let(:new_attributes) { Company.new(name: "New Name", longitude: 3, date: 1.minute.ago)
        .attributes.delete_mutable_attributes }
      fit "updates the requested company" do
        company = Company.create! valid_attributes
        put :update, {:id => company.to_param, :company => new_attributes}, valid_session
        company.reload
        expect(assigns(:company).attributes.delete_mutable_attributes).to eq(new_attributes)
      end
    end
  end
end

You can run the test yourself by cloning https://github.com/spreemo/shoulda-sqlite .

Also, one other odd symptom: if I remove the date attribute from this line, the test passes:

      let(:new_attributes) { Company.new(name: "New Name", longitude: 3)
        .attributes.delete_mutable_attributes }

About this issue

  • Original URL
  • State: closed
  • Created 10 years ago
  • Comments: 16 (10 by maintainers)

Most upvoted comments

@cupakromer – one thing we could do is to extend the time/BigDecimal logic we put in the eq matcher so that it is used as the output for all diffs:

https://github.com/rspec/rspec-expectations/blob/099d8821b579bc0916046ce623902999b47d07e3/lib/rspec/matchers/built_in/eq.rb#L38-L48