From 1a9ca1d17899520a76ca952fe25cb1519e081157 Mon Sep 17 00:00:00 2001 From: Emily Date: Fri, 16 Sep 2016 12:08:41 +0200 Subject: [PATCH] RUBY-1124 Allow instantiating Int64 and Int32 objects explicitly and calling #to_bson on them --- lib/bson/int32.rb | 46 ++++++++++++++++++++++++++++++++ lib/bson/int64.rb | 46 ++++++++++++++++++++++++++++++++ spec/bson/int32_spec.rb | 58 +++++++++++++++++++++++++++++++++++++++++ spec/bson/int64_spec.rb | 58 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 208 insertions(+) diff --git a/lib/bson/int32.rb b/lib/bson/int32.rb index 27a68ec5d..061dace70 100644 --- a/lib/bson/int32.rb +++ b/lib/bson/int32.rb @@ -50,6 +50,52 @@ def self.from_bson(buffer) buffer.get_int32 end + # Instantiate a BSON Int32. + # + # @param [ Integer ] integer The 32-bit integer. + # + # @see http://bsonspec.org/#/specification + # + # @since 4.2.0 + def initialize(integer) + out_of_range! unless integer.bson_int32? + @integer = integer.freeze + end + + # Append the integer as encoded BSON to a ByteBuffer. + # + # @example Encoded the integer and append to a ByteBuffer. + # int32.to_bson + # + # @return [ BSON::ByteBuffer ] The buffer with the encoded integer. + # + # @see http://bsonspec.org/#/specification + # + # @since 4.2.0 + def to_bson(buffer = ByteBuffer.new, validating_keys = Config.validating_keys?) + buffer.put_int32(@integer) + end + + # Convert the integer to a BSON string key. + # + # @example Convert the integer to a BSON key string. + # int.to_bson_key + # + # @param [ true, false ] validating_keys If BSON should validate the key. + # + # @return [ String ] The string key. + # + # @since 4.2.0 + def to_bson_key(validating_keys = Config.validating_keys?) + @integer.to_bson_key(validating_keys) + end + + private + + def out_of_range! + raise RangeError.new("#{self} is not a valid 4 byte integer value.") + end + # Register this type when the module is loaded. # # @since 2.0.0 diff --git a/lib/bson/int64.rb b/lib/bson/int64.rb index 012a136ae..b4c6b1622 100644 --- a/lib/bson/int64.rb +++ b/lib/bson/int64.rb @@ -45,6 +45,52 @@ def self.from_bson(buffer) buffer.get_int64 end + # Instantiate a BSON Int64. + # + # @param [ Integer ] integer The 64-bit integer. + # + # @see http://bsonspec.org/#/specification + # + # @since 4.2.0 + def initialize(integer) + out_of_range! unless integer.bson_int64? + @integer = integer.freeze + end + + # Append the integer as encoded BSON to a ByteBuffer. + # + # @example Encoded the integer and append to a ByteBuffer. + # int64.to_bson + # + # @return [ BSON::ByteBuffer ] The buffer with the encoded integer. + # + # @see http://bsonspec.org/#/specification + # + # @since 4.2.0 + def to_bson(buffer = ByteBuffer.new, validating_keys = Config.validating_keys?) + buffer.put_int64(@integer) + end + + # Convert the integer to a BSON string key. + # + # @example Convert the integer to a BSON key string. + # int.to_bson_key + # + # @param [ true, false ] validating_keys If BSON should validate the key. + # + # @return [ String ] The string key. + # + # @since 4.2.0 + def to_bson_key(validating_keys = Config.validating_keys?) + @integer.to_bson_key(validating_keys) + end + + private + + def out_of_range! + raise RangeError.new("#{self} is not a valid 8 byte integer value.") + end + # Register this type when the module is loaded. # # @since 2.0.0 diff --git a/spec/bson/int32_spec.rb b/spec/bson/int32_spec.rb index 361d46405..bce1e6c93 100644 --- a/spec/bson/int32_spec.rb +++ b/spec/bson/int32_spec.rb @@ -16,6 +16,42 @@ describe BSON::Int32 do + describe "#intiialize" do + + let(:obj) { described_class.new(integer) } + + context "when the integer is 32-bit" do + + let(:integer) { Integer::MAX_32BIT } + + it "wraps the integer" do + expect(obj.instance_variable_get(:@integer)).to be(integer) + end + end + + context "when the integer is too large" do + + let(:integer) { Integer::MAX_32BIT + 1 } + + it "raises an out of range error" do + expect { + obj + }.to raise_error(RangeError) + end + end + + context "when the integer is too small" do + + let(:integer) { Integer::MIN_32BIT - 1 } + + it "raises an out of range error" do + expect { + obj + }.to raise_error(RangeError) + end + end + end + describe "#from_bson" do let(:type) { 16.chr } @@ -41,4 +77,26 @@ expect(BSON::Int32.from_bson(encoded_2)).to eq(decoded_2) end end + + describe "#to_bson" do + + context "when the integer is 32 bit" do + + let(:type) { 16.chr } + let(:obj) { BSON::Int32.new(Integer::MAX_32BIT - 1) } + let(:bson) { [ Integer::MAX_32BIT - 1 ].pack(BSON::Int32::PACK) } + + it_behaves_like "a serializable bson element" + end + end + + describe "#to_bson_key" do + + let(:obj) { BSON::Int32.new(Integer::MAX_32BIT - 1) } + let(:encoded) { (Integer::MAX_32BIT - 1).to_s } + + it "returns the key as a string" do + expect(obj.to_bson_key).to eq(encoded) + end + end end diff --git a/spec/bson/int64_spec.rb b/spec/bson/int64_spec.rb index 52d28db8d..712881db7 100644 --- a/spec/bson/int64_spec.rb +++ b/spec/bson/int64_spec.rb @@ -16,6 +16,42 @@ describe BSON::Int64 do + describe "#intiialize" do + + let(:obj) { described_class.new(integer) } + + context "when the integer is 64-bit" do + + let(:integer) { Integer::MAX_64BIT - 1 } + + it "wraps the integer" do + expect(obj.instance_variable_get(:@integer)).to be(integer) + end + end + + context "when the integer is too large" do + + let(:integer) { Integer::MAX_64BIT + 1 } + + it "raises an out of range error" do + expect { + obj + }.to raise_error(RangeError) + end + end + + context "when the integer is too small" do + + let(:integer) { Integer::MIN_64BIT - 1 } + + it "raises an out of range error" do + expect { + obj + }.to raise_error(RangeError) + end + end + end + describe "#from_bson" do let(:type) { 18.chr } @@ -25,4 +61,26 @@ it_behaves_like "a bson element" it_behaves_like "a deserializable bson element" end + + describe "#to_bson" do + + context "when the integer is 64 bit" do + + let(:type) { 18.chr } + let(:obj) { BSON::Int64.new(Integer::MAX_64BIT - 1) } + let(:bson) { [ Integer::MAX_64BIT - 1 ].pack(BSON::Int64::PACK) } + + it_behaves_like "a serializable bson element" + end + end + + describe "#to_bson_key" do + + let(:obj) { BSON::Int64.new(Integer::MAX_64BIT - 1) } + let(:encoded) { (Integer::MAX_64BIT - 1).to_s } + + it "returns the key as a string" do + expect(obj.to_bson_key).to eq(encoded) + end + end end