From 7966e65bd0fa8d75003f8216d75b01f77d3db1d3 Mon Sep 17 00:00:00 2001 From: johnnyshields <27655+johnnyshields@users.noreply.github.com> Date: Tue, 6 May 2025 02:57:35 +0900 Subject: [PATCH 1/2] RUBY-3667 - If BSON::ObjectId(...) is given an existing object ID, it should return it without creating a new one. I implemented this in BSON::ObjectId#from_string. --- lib/bson.rb | 8 +++++--- lib/bson/object_id.rb | 10 +++++++--- spec/bson/object_id_spec.rb | 10 ++++++++++ spec/bson_spec.rb | 20 ++++++++++++++++---- 4 files changed, 38 insertions(+), 10 deletions(-) diff --git a/lib/bson.rb b/lib/bson.rb index 2148abfd4..20766bc9e 100644 --- a/lib/bson.rb +++ b/lib/bson.rb @@ -21,16 +21,18 @@ # @since 0.0.0 module BSON - # Create a new object id from a string using ObjectId.from_string + # Create a new object id from a string. If given a BSON::ObjectId object instead, + # this method returns that object id without creating a new one. # # @example Create an object id from the string. # BSON::ObjectId(id) # - # @param [ String ] string The string to create the id from. + # @param [ String | BSON::ObjectId ] string The string to create the id from, + # or the existing object id to return. # # @raise [ BSON::Error::InvalidObjectId ] If the provided string is invalid. # - # @return [ BSON::ObjectId ] The new object id. + # @return [ BSON::ObjectId ] The new or existing object id. # # @see ObjectId.from_string def self.ObjectId(string) diff --git a/lib/bson/object_id.rb b/lib/bson/object_id.rb index cf3076339..25062672a 100644 --- a/lib/bson/object_id.rb +++ b/lib/bson/object_id.rb @@ -284,19 +284,23 @@ def from_data(data) object_id end - # Create a new object id from a string. + # Create a new object id from a string. If given a BSON::ObjectId object instead, + # this method returns that object id without creating a new one. # # @example Create an object id from the string. # BSON::ObjectId.from_string(id) # - # @param [ String ] string The string to create the id from. + # @param [ String | BSON::ObjectId ] string The string to create the id from, + # or the existing object id to return. # # @raise [ BSON::Error::InvalidObjectId ] If the provided string is invalid. # - # @return [ BSON::ObjectId ] The new object id. + # @return [ BSON::ObjectId ] The new or existing object id. # # @since 2.0.0 def from_string(string) + return string if string.is_a?(self) + raise Error::InvalidObjectId, "'#{string}' is an invalid ObjectId." unless legal?(string) from_data([ string ].pack('H*')) diff --git a/spec/bson/object_id_spec.rb b/spec/bson/object_id_spec.rb index 42293e60b..2ff9e8aa9 100644 --- a/spec/bson/object_id_spec.rb +++ b/spec/bson/object_id_spec.rb @@ -326,6 +326,16 @@ }.to raise_error(BSON::Error::InvalidObjectId) end end + + context 'when given an object id' do + let(:object_id) do + described_class.new + end + + it 'returns the same object' do + expect(described_class.from_string(object_id)).to be(object_id) + end + end end describe ".from_time" do diff --git a/spec/bson_spec.rb b/spec/bson_spec.rb index d849b7158..fa34e4600 100644 --- a/spec/bson_spec.rb +++ b/spec/bson_spec.rb @@ -19,11 +19,23 @@ describe ".ObjectId" do - let(:string) { "4e4d66343b39b68407000001" } + context 'when given a string' do + let(:string) { "4e4d66343b39b68407000001" } - it "returns an BSON::ObjectId from given string" do - expect(described_class::ObjectId(string)).to be_a BSON::ObjectId - expect(described_class::ObjectId(string)).to eq BSON::ObjectId.from_string(string) + it "returns an BSON::ObjectId from given string" do + expect(described_class::ObjectId(string)).to be_a BSON::ObjectId + expect(described_class::ObjectId(string)).to eq BSON::ObjectId.from_string(string) + end + end + + context 'when given an object id' do + let(:object_id) do + BSON::ObjectId.new + end + + it 'returns the same object' do + expect(described_class::ObjectId(object_id)).to be(object_id) + end end end From acde87a60b8814b9620ee04b1319858cd1a9f083 Mon Sep 17 00:00:00 2001 From: Johnny Shields <27655+johnnyshields@users.noreply.github.com> Date: Tue, 6 May 2025 03:05:32 +0900 Subject: [PATCH 2/2] Update bson_spec.rb --- spec/bson_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/bson_spec.rb b/spec/bson_spec.rb index fa34e4600..d9e3d030c 100644 --- a/spec/bson_spec.rb +++ b/spec/bson_spec.rb @@ -30,7 +30,7 @@ context 'when given an object id' do let(:object_id) do - BSON::ObjectId.new + described_class::ObjectId.new end it 'returns the same object' do