Skip to content

Commit 4cdc2e6

Browse files
p-mongop
andauthored
MONGOID-5258 Review enumerable === implementation (#5180)
Co-authored-by: Oleg Pudeyev <[email protected]>
1 parent 1331f2c commit 4cdc2e6

File tree

3 files changed

+90
-33
lines changed

3 files changed

+90
-33
lines changed

docs/release-notes/mongoid-7.4.txt

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,17 +50,25 @@ Mongoid 7.4, the ``===`` operator will function as it did in Mongoid 7.3:
5050
``===`` returned ``true`` for some cases when the equivalent Ruby
5151
``===`` implementation returned false, as per the examples below.
5252

53-
Mongoid 7.4 behavior:
53+
Mongoid 7.4 with ``Mongoid.legacy_triple_equals`` set to ``false`` behavior:
5454

5555
.. code-block:: ruby
5656

5757
class Band
5858
include Mongoid::Document
59+
60+
has_many :members
5961
end
6062

6163
class CoverBand < Band
6264
end
6365

66+
class Member
67+
include Mongoid::Document
68+
69+
belongs_to :band
70+
end
71+
6472
band = Band.new
6573
cover_band = CoverBand.new
6674

@@ -75,8 +83,15 @@ Mongoid 7.4 behavior:
7583

7684
CoverBand === Band
7785
# => false
86+
87+
band.members === Array
88+
# => false
89+
90+
band.members === Mongoid::Association::Referenced::HasMany::Enumerable
91+
# => false
7892

79-
Mongoid 7.3 behavior:
93+
Mongoid 7.3 and 7.4 with ``Mongoid.legacy_triple_equals`` set to ``true``
94+
behavior:
8095

8196
.. code-block:: ruby
8297

@@ -91,6 +106,12 @@ Mongoid 7.3 behavior:
91106

92107
CoverBand === Band
93108
# => true
109+
110+
band.members === Array
111+
# => true
112+
113+
band.members === Mongoid::Association::Referenced::HasMany::Enumerable
114+
# => true
94115

95116
The standard invocation of ``===``, that is having the class on the left and
96117
the instance on the right, works the same in Mongoid 7.4 as it did previously

lib/mongoid/association/referenced/has_many/enumerable.rb

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ def ==(other)
3434
entries == other.entries
3535
end
3636

37-
# Check equality of the enumerable against the provided object for case
38-
# statements.
37+
# Check equality of the enumerable against the provided object for
38+
# case statements.
3939
#
4040
# @example Check case equality.
4141
# enumerable === Array
@@ -44,7 +44,12 @@ def ==(other)
4444
#
4545
# @return [ true, false ] If the objects are equal in a case.
4646
def ===(other)
47-
other.class == Class ? (Array == other || Enumerable == other) : self == other
47+
return false unless other.respond_to?(:entries)
48+
if Mongoid.legacy_triple_equals
49+
other.class == Class ? (Array == other || Enumerable == other) : self == other
50+
else
51+
entries === other.entries
52+
end
4853
end
4954

5055
# Append a document to the enumerable.

spec/mongoid/association/referenced/has_many/enumerable_spec.rb

Lines changed: 59 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -113,55 +113,86 @@
113113

114114
describe "#===" do
115115

116-
let(:enumerable) do
117-
described_class.new([])
118-
end
116+
let(:data) { [] }
119117

120-
context "when compared to an array class" do
118+
shared_examples 'standard library-compatible enumerable' do
119+
context "when compared to an array class" do
121120

122-
it "returns true" do
123-
expect(enumerable === Array).to be true
121+
it "returns false" do
122+
expect(enumerable === Array).to be false
123+
end
124124
end
125-
end
126125

127-
context "when compared to an enumerable class" do
126+
context "when compared to an enumerable class" do
128127

129-
it "returns true" do
130-
expect(enumerable === described_class).to be true
128+
it "returns false" do
129+
expect(enumerable === described_class).to be false
130+
end
131131
end
132-
end
133132

134-
context "when compared to a different class" do
133+
context "when compared to a different class" do
135134

136-
it "returns false" do
137-
expect(enumerable === Mongoid::Document).to be false
135+
it "returns false" do
136+
expect(enumerable === Mongoid::Document).to be false
137+
end
138138
end
139-
end
140139

141-
context "when compared to an array instance" do
140+
context "when compared to an array instance" do
142141

143-
context "when the entries are equal" do
142+
context "when the entries are equal" do
144143

145-
let(:other) do
146-
described_class.new([])
147-
end
144+
let(:data) do
145+
[Post.new(id: 2)]
146+
end
148147

149-
it "returns true" do
150-
expect(enumerable === other).to be true
148+
let(:other) do
149+
described_class.new([Post.new(id: 2)])
150+
end
151+
152+
it "returns true" do
153+
expect(enumerable === other).to be true
154+
end
151155
end
152-
end
153156

154-
context "when the entries are not equal" do
157+
context "when the entries are both empty" do
155158

156-
let(:other) do
157-
described_class.new([ Band.new ])
159+
let(:other) do
160+
described_class.new([])
161+
end
162+
163+
it "returns true" do
164+
expect(enumerable === other).to be true
165+
end
158166
end
159167

160-
it "returns false" do
161-
expect(enumerable === other).to be false
168+
context "when the entries are not equal" do
169+
170+
let(:other) do
171+
described_class.new([ Band.new ])
172+
end
173+
174+
it "returns false" do
175+
expect(enumerable === other).to be false
176+
end
162177
end
163178
end
164179
end
180+
181+
context 'enumerable' do
182+
let(:enumerable) do
183+
described_class.new(data)
184+
end
185+
186+
include_examples 'standard library-compatible enumerable'
187+
end
188+
189+
context 'Array instance' do
190+
let(:enumerable) do
191+
data
192+
end
193+
194+
include_examples 'standard library-compatible enumerable'
195+
end
165196
end
166197

167198
describe "#<<" do

0 commit comments

Comments
 (0)