summaryrefslogtreecommitdiff
path: root/test/ruby/test_random_formatter.rb
blob: 2c01d99b3dbe78b461108b6f71e503f1258f0dc4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
require 'test/unit'
require 'random/formatter'

module Random::Formatter
  module FormatterTest
    def test_random_bytes
      assert_equal(16, @it.random_bytes.size)
      assert_equal(Encoding::ASCII_8BIT, @it.random_bytes.encoding)
      65.times do |idx|
        assert_equal(idx, @it.random_bytes(idx).size)
      end
    end

    def test_hex
      s = @it.hex
      assert_equal(16 * 2, s.size)
      assert_match(/\A\h+\z/, s)
      33.times do |idx|
        s = @it.hex(idx)
        assert_equal(idx * 2, s.size)
        assert_match(/\A\h*\z/, s)
      end
    end

    def test_hex_encoding
      assert_equal(Encoding::US_ASCII, @it.hex.encoding)
    end

    def test_base64
      assert_equal(16, @it.base64.unpack1('m*').size)
      17.times do |idx|
        assert_equal(idx, @it.base64(idx).unpack1('m*').size)
      end
    end

    def test_urlsafe_base64
      safe = /[\n+\/]/
      65.times do |idx|
        assert_not_match(safe, @it.urlsafe_base64(idx))
      end
      # base64 can include unsafe byte
      assert((0..10000).any? {|idx| safe =~ @it.base64(idx)}, "None of base64(0..10000) is url-safe")
    end

    def test_random_number_float
      101.times do
        v = @it.random_number
        assert_in_range(0.0...1.0, v)
      end
    end

    def test_random_number_float_by_zero
      101.times do
        v = @it.random_number(0)
        assert_in_range(0.0...1.0, v)
      end
    end

    def test_random_number_int
      101.times do |idx|
        next if idx.zero?
        v = @it.random_number(idx)
        assert_in_range(0...idx, v)
      end
    end

    def test_uuid
      uuid = @it.uuid
      assert_equal(36, uuid.size)

      # Check time_hi_and_version and clock_seq_hi_res bits (RFC 4122 4.4)
      assert_equal('4', uuid[14])
      assert_include(%w'8 9 a b', uuid[19])

      assert_match(/\A\h{8}-\h{4}-\h{4}-\h{4}-\h{12}\z/, uuid)
    end

    def test_alphanumeric
      65.times do |n|
        an = @it.alphanumeric(n)
        assert_match(/\A[0-9a-zA-Z]*\z/, an)
        assert_equal(n, an.length)
      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
  end

  module NotDefaultTest
    def test_random_number_not_default
      msg = "random_number should not be affected by srand"
      seed = srand(0)
      x = @it.random_number(1000)
      10.times do|i|
        srand(0)
        return unless @it.random_number(1000) == x
      end
      srand(0)
      assert_not_equal(x, @it.random_number(1000), msg)
    ensure
      srand(seed) if seed
    end
  end

  class TestClassMethods < Test::Unit::TestCase
    include FormatterTest

    def setup
      @it = Random
    end
  end

  class TestInstanceMethods < Test::Unit::TestCase
    include FormatterTest
    include NotDefaultTest

    def setup
      @it = Random.new
    end
  end
end