aarona
aarona

Reputation: 37302

Getting fractions of seconds difference instead of equal times when comparing dates with TimeCop

I've TimeCop installed and using the travel: option with my tests but my tests seem to be failing when I know they shouldn't be. I thought it was my code but it seems that I'm getting fractions of a second added somewhere which is causing dates that should be equal to not be.

Given the following rspec test:

it 'Testing TimeCop', travel: Time.new(2021, 10, 5, 9, 0, 0, '-07:00') do
  puts "Time.now:                                              #{Time.now}"
  puts "Time.new(2021, 10, 5, 9, 0, 0, '-07:00')}:             #{Time.new(2021, 10, 5, 9, 0, 0, '-07:00')}"
  puts "Time.now == Time.new(2021, 10, 5, 9, 0, 0, '-07:00')}: #{Time.now == Time.new(2021, 10, 5, 9, 0, 0, '-07:00')}"
  puts "Time.now -  Time.new(2021, 10, 5, 9, 0, 0, '-07:00')}: #{Time.now - Time.new(2021, 10, 5, 9, 0, 0, '-07:00')}"
end

I'm getting the following output:

Time.now:                                              2021-10-05 09:00:00 -0700
Time.new(2021, 10, 5, 9, 0, 0, '-07:00')}:             2021-10-05 09:00:00 -0700
Time.now == Time.new(2021, 10, 5, 9, 0, 0, '-07:00')}: false
Time.now -  Time.new(2021, 10, 5, 9, 0, 0, '-07:00')}: 0.0004161418930646181

As you can see these times are not equal and the reason being is there seems to be a 4/10000th of a second discrepancy between the two. I don't know whats going on here. Is there something I'm doing wrong with TimeCop or is this a bug?

Upvotes: 0

Views: 545

Answers (1)

spickermann
spickermann

Reputation: 106952

This is how Timecop#travel works and it is the expected behavior.

Setting a time to travel to sets the time to that timestamp but allows the time to move on. Because you have multiple Time.now calls in your test and the time moved on in between those calls those instances of time cannot be the same.

That means that you in your test must allow small differences in time between two instances, for example like this:

expect(Time.now).to be_within(1.second).of Time.now

Or you can freeze the time like Christian already mentioned in the comments. Freezing the time means that you set the current time to a specific time and it will not move on. For example like this:

before do
  Timecop.freeze(Time.new(2021, 10, 5, 9, 0, 0, '-07:00'))
end

after do
  Timecop.return
end

it "Testing TimeCop" do
  time = Time.new
  pause 10

  expect(time).to eq Time.now
end

Upvotes: 1

Related Questions