rspec / rspec-rails

RSpec for Rails 6+
https://rspec.info
MIT License
5.18k stars 1.04k forks source link

time comparison fails because it's off by subsecond #2571

Closed slicksammy closed 2 years ago

slicksammy commented 2 years ago

What Ruby, Rails and RSpec versions are you using?

Ruby version: 3.1 Rails version: 7.0.0 RSpec version: 3.10 rspec-rails 5.0.2

Observed behaviour

Locally, my tests work. But on Heroku CI they are failing because they are off by some fraction of a second.

Expected #<ActiveSupport::TimeWithZone 2022-02-01 20:36:35+(266343/1000000) +00:00 (UTC)>
            to eq #<ActiveSupport::TimeWithZone 2022-02-01 20:36:35+(133171587/500000000) +00:00 (UTC)>
         Diff:
         ┌ (Key) ──────────────────────────┐
         │ ‹-› in expected, not in actual  │
         │ ‹+› in actual, not in expected  │
         │ ‹ › in both expected and actual │
         └───────���─────────────────────────┘
           #<ActiveSupport::TimeWithZone {
             year: 2022,
             month: 2,
             day: 1,
             hour: 20,
             min: 36,
             sec: 35,
         -   subsec: (133171587/500000000),
         +   subsec: (266343/1000000),
             zone: "UTC",
             utc_offset: 0
           }>

Couldn't find anything online and was wondering if anyone had a solution to this

pirj commented 2 years ago

Can you please share the code of the failing example?

Might be related https://github.com/rails/rails/pull/40137

I guess your local is not Linux?

By the way, if you check on Linux, Time.current actually returns non-zero nanoseconds (as opposed to macOS).

JonRowe commented 2 years ago

:wave: Time precision is a configurable part of a database field, so they are not equal (likely because the precision is different on Heroku than your machine), you can use the be_within matcher to say you want the times to be within an also configurable precision (which is also often helpful when you just want to assert on something was done just now so you don't have to stub out Time.now).

Closing because this is not a bug, and rspec-rails doesn't contain the matchers involved any way, also we normally direct people towards the mailing list or forums etc for help requests and keep our issues for bug reports.

slicksammy commented 2 years ago

Thanks @JonRowe. Definitely not a bug with rspec-rails, was just wondering if anyone had a similar issue.

Ultimately we decided to do expect(time1.to_i).to eq(time2.to_i) and this was because the precision on linux is different than that on mac (more precise on Linux).