mikel / mikel/mail

Mail::Message#== does not work when on the cusp between two seconds

Open
#1,407 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Ruby
Stars
3.7k
Forks
934
PR merge metrics
No merged PRs in 30d

Description

I was scratching my head over a strange RSpec test failure for a while:

```
Failure/Error: expect(subject).to eq(mail_obj)
expected: #
got: #

(compared using ==)

Diff:
(Diff is actually empty) # I wrote this line myself

```

Note that the object_ids are the same for "expected" and "got".

I'm pretty sure it's this line in `def ==(other)`
```ruby
dup.tap { |m| m.message_id = '' }.encoded ==
other.dup.tap { |m| m.message_id = '' }.encoded
```

I think that `dup.tap { |m| m.message_id = '' }.encoded` was evaluated right at the end of a second, and `other.dup.tap { |m| m.message_id = '' }.encoded` was evaluated right at the start of the next second. This would explain the failure.

Further evidence:
```ruby
m = Mail::Message.new

Timecop.scale(1000) { m == m } # Evaluates to false
m == m # Evaluates to true

(1..10000).to_a.reject { |_index| m == m } # This evaluated to [12, 5013, 5928, 7780] for me

# Second to make sure it wasn't a fluke
(1..10000).to_a.reject { |_index| m == m } # This evaluated to [1022, 2717, 4377, 5292, 6012] for me

# This returns empty array
Timecop.freeze(Time.now) do
(1..10000).to_a.reject { |_index| m == m }
end

```

Contributor guide

Open the contributing guide

Research direction

Start at Mail::Message#==, particularly the two encoded comparisons shown in the issue. Reproduce the failure with Timecop.scale or verify the stable behavior with Timecop.freeze. Done means comparing a message with itself remains true across the second boundary and the reported RSpec equality failure is resolved.

Written by the indexing model from the issue text.

Assessment

Tech stack
ruby
Domain
backend
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.