Don't cast and extract normalization
We are not trying to handle user input so `cast` can be a no-op. Also extract the base36 normalization logic, let the binary class handle the serialize encoding and add some tests.
This commit is contained in:
committed by
Mike Dalessio
parent
8ec5c1af5c
commit
a8412449e3
@@ -7,7 +7,11 @@ module ActiveRecord
|
||||
def self.generate
|
||||
uuid = SecureRandom.uuid_v7
|
||||
hex = uuid.delete("-")
|
||||
hex.to_i(16).to_s(36).rjust(25, "0")
|
||||
normalize_base36(hex.to_i(16))
|
||||
end
|
||||
|
||||
def self.normalize_base36(integer)
|
||||
integer.to_s(36).rjust(BASE36_LENGTH, "0")
|
||||
end
|
||||
|
||||
def serialize(value)
|
||||
@@ -15,19 +19,18 @@ module ActiveRecord
|
||||
|
||||
hex = value.to_s.to_i(36).to_s(16).rjust(32, "0")
|
||||
binary = hex.scan(/../).map(&:hex).pack("C*")
|
||||
binary.force_encoding(Encoding::BINARY)
|
||||
Data.new(binary)
|
||||
super(binary)
|
||||
end
|
||||
|
||||
def deserialize(value)
|
||||
return unless value
|
||||
|
||||
hex = value.to_s.unpack1("H*")
|
||||
hex.to_i(16).to_s(36).rjust(BASE36_LENGTH, "0")
|
||||
Uuid.normalize_base36(hex.to_i(16))
|
||||
end
|
||||
|
||||
def cast(value)
|
||||
deserialize(serialize(value))
|
||||
value
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
require "test_helper"
|
||||
|
||||
class ActiveRecordUuidTypeTest < ActiveSupport::TestCase
|
||||
setup do
|
||||
@type = ActiveRecord::Type::Uuid.new
|
||||
@sample_uuid = "01jcqzx8h0000000000000000" # base36 UUID
|
||||
end
|
||||
|
||||
test "cast nil returns nil" do
|
||||
assert_nil @type.cast(nil)
|
||||
end
|
||||
|
||||
test "cast returns value as-is" do
|
||||
result = @type.cast(@sample_uuid)
|
||||
assert_equal @sample_uuid, result
|
||||
end
|
||||
|
||||
test "serialize returns binary Data object" do
|
||||
result = @type.serialize(@sample_uuid)
|
||||
|
||||
assert_instance_of ActiveModel::Type::Binary::Data, result
|
||||
assert_equal 16, result.to_s.bytesize
|
||||
assert_equal Encoding::BINARY, result.to_s.encoding
|
||||
end
|
||||
|
||||
test "serialize nil returns nil" do
|
||||
assert_nil @type.serialize(nil)
|
||||
end
|
||||
|
||||
test "deserialize converts binary to base36" do
|
||||
binary_data = @type.serialize(@sample_uuid)
|
||||
|
||||
result = @type.deserialize(binary_data)
|
||||
|
||||
assert_equal @sample_uuid, result
|
||||
end
|
||||
|
||||
test "deserialize handles raw binary string" do
|
||||
binary_data = @type.serialize(@sample_uuid)
|
||||
raw_binary = binary_data.to_s
|
||||
|
||||
result = @type.deserialize(raw_binary)
|
||||
|
||||
assert_equal @sample_uuid, result
|
||||
end
|
||||
|
||||
test "deserialize nil returns nil" do
|
||||
assert_nil @type.deserialize(nil)
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user