diff options
Diffstat (limited to 'test/ruby/test_random_formatter.rb')
-rw-r--r-- | test/ruby/test_random_formatter.rb | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/test/ruby/test_random_formatter.rb b/test/ruby/test_random_formatter.rb index a5072099e1..f927522d96 100644 --- a/test/ruby/test_random_formatter.rb +++ b/test/ruby/test_random_formatter.rb @@ -75,6 +75,47 @@ module Random::Formatter assert_match(/\A\h{8}-\h{4}-\h{4}-\h{4}-\h{12}\z/, uuid) end + def assert_uuid_v7(**opts) + t1 = current_uuid7_time(**opts) + uuid = @it.uuid_v7(**opts) + t3 = current_uuid7_time(**opts) + + assert_match(/\A\h{8}-\h{4}-7\h{3}-[89ab]\h{3}-\h{12}\z/, uuid) + + t2 = get_uuid7_time(uuid, **opts) + assert_operator(t1, :<=, t2) + assert_operator(t2, :<=, t3) + end + + def test_uuid_v7 + assert_uuid_v7 + 0.upto(12) do |extra_timestamp_bits| + assert_uuid_v7 extra_timestamp_bits: extra_timestamp_bits + end + end + + # It would be nice to simply use Time#floor here. But that is problematic + # due to the difference between decimal vs binary fractions. + def current_uuid7_time(extra_timestamp_bits: 0) + denominator = (1 << extra_timestamp_bits).to_r + Process.clock_gettime(Process::CLOCK_REALTIME, :nanosecond) + .then {|ns| ((ns / 1_000_000r) * denominator).floor / denominator } + .then {|ms| Time.at(ms / 1000r, in: "+00:00") } + end + + def get_uuid7_time(uuid, extra_timestamp_bits: 0) + denominator = (1 << extra_timestamp_bits) * 1000r + extra_chars = extra_timestamp_bits / 4 + last_char_bits = extra_timestamp_bits % 4 + extra_chars += 1 if last_char_bits != 0 + timestamp_re = /\A(\h{8})-(\h{4})-7(\h{#{extra_chars}})/ + timestamp_chars = uuid.match(timestamp_re).captures.join + timestamp = timestamp_chars.to_i(16) + timestamp >>= 4 - last_char_bits unless last_char_bits == 0 + timestamp /= denominator + Time.at timestamp, in: "+00:00" + end + def test_alphanumeric 65.times do |n| an = @it.alphanumeric(n) @@ -83,6 +124,20 @@ module Random::Formatter end end + def test_alphanumeric_chars + [ + [[*"0".."9"], /\A\d*\z/], + [[*"a".."t"], /\A[a-t]*\z/], + ["一二三四五六七八九十".chars, /\A[一二三四五六七八九十]*\z/], + ].each do |chars, pattern| + 10.times do |n| + an = @it.alphanumeric(n, chars: chars) + assert_match(pattern, an) + assert_equal(n, an.length) + end + end + end + def assert_in_range(range, result, mesg = nil) assert(range.cover?(result), build_message(mesg, "Expected #{result} to be in #{range}")) end |