Skip to content

Commit bc942e1

Browse files
authored
RUBY-3533 Make BSON::Binary objects comparable (#338)
The comparison is only meaningful if the two objects have the same Binary type, as well.
1 parent 86ddb75 commit bc942e1

File tree

2 files changed

+61
-7
lines changed

2 files changed

+61
-7
lines changed

lib/bson/binary.rb

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ module BSON
2424
# @since 2.0.0
2525
class Binary
2626
include JSON
27+
include Comparable
2728

2829
# A binary is type 0x05 in the BSON spec.
2930
#
@@ -90,6 +91,20 @@ def ==(other)
9091
end
9192
alias eql? ==
9293

94+
# Compare this binary object to another object. The two objects must have
95+
# the same type for any meaningful comparison.
96+
#
97+
# @param [ Object ] other The object to compare against.
98+
#
99+
# @return [ Integer | nil ] If the objects have the same type, the result
100+
# is -1 if self < other, 0 if self == other, and 1 if self > other. If
101+
# other is not a Binary, or is a Binary of a different type, returns nil.
102+
def <=>(other)
103+
return nil unless other.is_a?(Binary) && type == other.type
104+
105+
data <=> other.data
106+
end
107+
93108
# Generates a Fixnum hash value for this object.
94109
#
95110
# Allows using Binary as hash keys.

spec/bson/binary_spec.rb

Lines changed: 46 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -20,17 +20,56 @@
2020
let(:testing1) { described_class.new("testing") }
2121
let(:testing2) { described_class.new("testing") }
2222
let(:not_testing) { described_class.new("not testing") }
23+
let(:testing3) { described_class.new("testing", :user) }
2324

24-
describe "#eql?" do
25-
context "for two equal objects" do
26-
it "returns true" do
27-
expect(testing1).to eql(testing2)
25+
describe "Comparable" do
26+
describe "#eql?" do
27+
context "for two equal objects" do
28+
it "returns true" do
29+
expect(testing1).to eql(testing2)
30+
end
31+
end
32+
33+
context "for two different objects" do
34+
it "returns false" do
35+
expect(testing1).not_to eql(not_testing)
36+
end
37+
end
38+
39+
context 'for objects with identical data but different types' do
40+
it 'returns false' do
41+
expect(testing1).not_to eql(testing3)
42+
end
2843
end
2944
end
3045

31-
context "for two different objects" do
32-
it "returns false" do
33-
expect(testing1).not_to eql(not_testing)
46+
describe '#<=>' do
47+
context 'with a non-Binary object' do
48+
it 'returns nil' do
49+
expect(testing1 <=> 'bogus').to be_nil
50+
end
51+
end
52+
53+
context 'with identical type and data' do
54+
it 'returns 0' do
55+
expect(testing1 <=> testing2).to be == 0
56+
end
57+
end
58+
59+
context 'with mismatched type' do
60+
it 'returns nil' do
61+
expect(testing1 <=> testing3).to be_nil
62+
end
63+
end
64+
65+
context 'with identical type but mismatched data' do
66+
it 'returns -1 when a < b' do
67+
expect(not_testing <=> testing1).to be == -1
68+
end
69+
70+
it 'returns 1 when a > b' do
71+
expect(testing1 <=> not_testing).to be == 1
72+
end
3473
end
3574
end
3675
end

0 commit comments

Comments
 (0)