Skip to content

Commit

Permalink
RUBY-3533 Make BSON::Binary objects comparable
Browse files Browse the repository at this point in the history
The comparison is only meaningful if the two objects have the
same Binary type, as well.
  • Loading branch information
jamis committed Oct 11, 2024
1 parent 86ddb75 commit 5c35bc1
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 7 deletions.
15 changes: 15 additions & 0 deletions lib/bson/binary.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ module BSON
# @since 2.0.0
class Binary
include JSON
include Comparable

# A binary is type 0x05 in the BSON spec.
#
Expand Down Expand Up @@ -90,6 +91,20 @@ def ==(other)
end
alias eql? ==

# Compare this binary object to another object. The two objects must have
# the same type for any meaningful comparison.
#
# @param [ Object ] other The object to compare against.
#
# @return [ Integer | nil ] If the objects have the same type, the result
# is -1 if self < other, 0 if self == other, and 1 if self > other. If
# other is not a Binary, or is a Binary of a different type, returns nil.
def <=>(other)
return nil unless other.is_a?(Binary) && type == other.type

data <=> other.data
end

# Generates a Fixnum hash value for this object.
#
# Allows using Binary as hash keys.
Expand Down
53 changes: 46 additions & 7 deletions spec/bson/binary_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,56 @@
let(:testing1) { described_class.new("testing") }
let(:testing2) { described_class.new("testing") }
let(:not_testing) { described_class.new("not testing") }
let(:testing3) { described_class.new("testing", :user) }

describe "#eql?" do
context "for two equal objects" do
it "returns true" do
expect(testing1).to eql(testing2)
describe "Comparable" do
describe "#eql?" do
context "for two equal objects" do
it "returns true" do
expect(testing1).to eql(testing2)
end
end

context "for two different objects" do
it "returns false" do
expect(testing1).not_to eql(not_testing)
end
end

context 'for objects with identical data but different types' do
it 'returns false' do
expect(testing1).not_to eql(testing3)
end
end
end

context "for two different objects" do
it "returns false" do
expect(testing1).not_to eql(not_testing)
describe '#<=>' do
context 'with a non-Binary object' do
it 'returns nil' do
expect(testing1 <=> 'bogus').to be_nil
end
end

context 'with identical type and data' do
it 'returns 0' do
expect(testing1 <=> testing2).to be == 0
end
end

context 'with mismatched type' do
it 'returns nil' do
expect(testing1 <=> testing3).to be_nil
end
end

context 'with identical type but mismatched data' do
it 'returns -1 when a < b' do
expect(not_testing <=> testing1).to be == -1
end

it 'returns 1 when a > b' do
expect(testing1 <=> not_testing).to be == 1
end
end
end
end
Expand Down

0 comments on commit 5c35bc1

Please sign in to comment.