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..d9e3d030c 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 + described_class::ObjectId.new + end + + it 'returns the same object' do + expect(described_class::ObjectId(object_id)).to be(object_id) + end end end