number_helper_test.rb 19.9 KB
Newer Older
1
require 'abstract_unit'
2

3 4
class NumberHelperTest < ActionView::TestCase
  tests ActionView::Helpers::NumberHelper
5

6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
  def kilobytes(number)
    number * 1024
  end

  def megabytes(number)
    kilobytes(number) * 1024
  end

  def gigabytes(number)
    megabytes(number) * 1024
  end

  def terabytes(number)
    gigabytes(number) * 1024
  end

22
  def test_number_to_phone
23
    assert_equal("555-1234", number_to_phone(5551234))
24 25
    assert_equal("800-555-1212", number_to_phone(8005551212))
    assert_equal("(800) 555-1212", number_to_phone(8005551212, {:area_code => true}))
26
    assert_equal("", number_to_phone("", {:area_code => true}))
27 28 29 30 31 32 33 34
    assert_equal("800 555 1212", number_to_phone(8005551212, {:delimiter => " "}))
    assert_equal("(800) 555-1212 x 123", number_to_phone(8005551212, {:area_code => true, :extension => 123}))
    assert_equal("800-555-1212", number_to_phone(8005551212, :extension => "  "))
    assert_equal("800-555-1212", number_to_phone("8005551212"))
    assert_equal("+1-800-555-1212", number_to_phone(8005551212, :country_code => 1))
    assert_equal("+18005551212", number_to_phone(8005551212, :country_code => 1, :delimiter => ''))
    assert_equal("22-555-1212", number_to_phone(225551212))
    assert_equal("+45-22-555-1212", number_to_phone(225551212, :country_code => 45))
35 36 37 38 39
  end

  def test_number_to_currency
    assert_equal("$1,234,567,890.50", number_to_currency(1234567890.50))
    assert_equal("$1,234,567,890.51", number_to_currency(1234567890.506))
40 41 42
    assert_equal("-$1,234,567,890.50", number_to_currency(-1234567890.50))
    assert_equal("-$ 1,234,567,890.50", number_to_currency(-1234567890.50, {:format => "%u %n"}))
    assert_equal("($1,234,567,890.50)", number_to_currency(-1234567890.50, {:negative_format => "(%u%n)"}))
43
    assert_equal("$1,234,567,892", number_to_currency(1234567891.50, {:precision => 0}))
44
    assert_equal("$1,234,567,890.5", number_to_currency(1234567890.50, {:precision => 1}))
45
    assert_equal("&pound;1234567890,50", number_to_currency(1234567890.50, {:unit => "&pound;", :separator => ",", :delimiter => ""}))
46
    assert_equal("$1,234,567,890.50", number_to_currency("1234567890.50"))
47
    assert_equal("1,234,567,890.50 K&#269;", number_to_currency("1234567890.50", {:unit => "K&#269;", :format => "%n %u"}))
48
    assert_equal("1,234,567,890.50 - K&#269;", number_to_currency("-1234567890.50", {:unit => "K&#269;", :format => "%n %u", :negative_format => "%n - %u"}))
49 50 51 52 53 54
  end

  def test_number_to_percentage
    assert_equal("100.000%", number_to_percentage(100))
    assert_equal("100%", number_to_percentage(100, {:precision => 0}))
    assert_equal("302.06%", number_to_percentage(302.0574, {:precision => 2}))
55
    assert_equal("100.000%", number_to_percentage("100"))
56
    assert_equal("1000.000%", number_to_percentage("1000"))
57
    assert_equal("123.4%", number_to_percentage(123.400, :precision => 3, :strip_insignificant_zeros => true))
58
    assert_equal("1.000,000%", number_to_percentage(1000, :delimiter => '.', :separator => ','))
59 60 61 62
  end

  def test_number_with_delimiter
    assert_equal("12,345,678", number_with_delimiter(12345678))
63 64 65 66 67 68 69 70
    assert_equal("0", number_with_delimiter(0))
    assert_equal("123", number_with_delimiter(123))
    assert_equal("123,456", number_with_delimiter(123456))
    assert_equal("123,456.78", number_with_delimiter(123456.78))
    assert_equal("123,456.789", number_with_delimiter(123456.789))
    assert_equal("123,456.78901", number_with_delimiter(123456.78901))
    assert_equal("123,456,789.78901", number_with_delimiter(123456789.78901))
    assert_equal("0.78901", number_with_delimiter(0.78901))
71
    assert_equal("123,456.78", number_with_delimiter("123456.78"))
72
  end
73

74 75 76 77 78 79 80
  def test_number_with_delimiter_with_options_hash
    assert_equal '12 345 678', number_with_delimiter(12345678, :delimiter => ' ')
    assert_equal '12,345,678-05', number_with_delimiter(12345678.05, :separator => '-')
    assert_equal '12.345.678,05', number_with_delimiter(12345678.05, :separator => ',', :delimiter => '.')
    assert_equal '12.345.678,05', number_with_delimiter(12345678.05, :delimiter => '.', :separator => ',')
  end

81
  def test_number_with_precision
82
    assert_equal("-111.235", number_with_precision(-111.2346))
83
    assert_equal("111.235", number_with_precision(111.2346))
84 85 86
    assert_equal("31.83", number_with_precision(31.825, :precision => 2))
    assert_equal("111.23", number_with_precision(111.2346, :precision => 2))
    assert_equal("111.00", number_with_precision(111, :precision => 2))
87
    assert_equal("111.235", number_with_precision("111.2346"))
88
    assert_equal("31.83", number_with_precision("31.825", :precision => 2))
89
    assert_equal("3268", number_with_precision((32.6751 * 100.00), :precision => 0))
90 91
    assert_equal("112", number_with_precision(111.50, :precision => 0))
    assert_equal("1234567892", number_with_precision(1234567891.50, :precision => 0))
92 93 94
    assert_equal("0", number_with_precision(0, :precision => 0))
    assert_equal("0.00100", number_with_precision(0.001, :precision => 5))
    assert_equal("0.001", number_with_precision(0.00111, :precision => 3))
95 96
    assert_equal("10.00", number_with_precision(9.995, :precision => 2))
    assert_equal("11.00", number_with_precision(10.995, :precision => 2))
97
  end
98

99 100 101
  def test_number_with_precision_with_custom_delimiter_and_separator
    assert_equal '31,83',       number_with_precision(31.825, :precision => 2, :separator => ',')
    assert_equal '1.231,83',    number_with_precision(1231.825, :precision => 2, :separator => ',', :delimiter => '.')
102 103
  end

104 105 106 107 108 109 110 111 112 113 114 115 116
  def test_number_with_precision_with_significant_digits
    assert_equal "124000", number_with_precision(123987, :precision => 3, :significant => true)
    assert_equal "120000000", number_with_precision(123987876, :precision => 2, :significant => true )
    assert_equal "40000", number_with_precision("43523", :precision => 1, :significant => true )
    assert_equal "9775", number_with_precision(9775, :precision => 4, :significant => true )
    assert_equal "5.4", number_with_precision(5.3923, :precision => 2, :significant => true )
    assert_equal "5", number_with_precision(5.3923, :precision => 1, :significant => true )
    assert_equal "1", number_with_precision(1.232, :precision => 1, :significant => true )
    assert_equal "7", number_with_precision(7, :precision => 1, :significant => true )
    assert_equal "1", number_with_precision(1, :precision => 1, :significant => true )
    assert_equal "53", number_with_precision(52.7923, :precision => 2, :significant => true )
    assert_equal "9775.00", number_with_precision(9775, :precision => 6, :significant => true )
    assert_equal "5.392900", number_with_precision(5.3929, :precision => 7, :significant => true )
117
    assert_equal "0.0", number_with_precision(0, :precision => 2, :significant => true )
118
    assert_equal "0", number_with_precision(0, :precision => 1, :significant => true )
119 120 121
    assert_equal "0.0001", number_with_precision(0.0001, :precision => 1, :significant => true )
    assert_equal "0.000100", number_with_precision(0.0001, :precision => 3, :significant => true )
    assert_equal "0.0001", number_with_precision(0.0001111, :precision => 1, :significant => true )
122 123 124
    assert_equal "10.0", number_with_precision(9.995, :precision => 3, :significant => true)
    assert_equal "9.99", number_with_precision(9.994, :precision => 3, :significant => true)
    assert_equal "11.0", number_with_precision(10.995, :precision => 3, :significant => true)
125 126
  end

127 128 129
  def test_number_with_precision_with_strip_insignificant_zeros
    assert_equal "9775.43", number_with_precision(9775.43, :precision => 4, :strip_insignificant_zeros => true )
    assert_equal "9775.2", number_with_precision(9775.2, :precision => 6, :significant => true, :strip_insignificant_zeros => true )
130
    assert_equal "0", number_with_precision(0, :precision => 6, :significant => true, :strip_insignificant_zeros => true )
131 132 133 134
  end

  def test_number_with_precision_with_significant_true_and_zero_precision
    # Zero precision with significant is a mistake (would always return zero),
R
R.T. Lechow 已提交
135
    # so we treat it as if significant was false (increases backwards compatibility for number_to_human_size)
136 137 138 139 140
    assert_equal "124", number_with_precision(123.987, :precision => 0, :significant => true)
    assert_equal "12", number_with_precision(12, :precision => 0, :significant => true )
    assert_equal "12", number_with_precision("12.3", :precision => 0, :significant => true )
  end

141 142 143 144 145 146
  def test_number_to_human_size
    assert_equal '0 Bytes',   number_to_human_size(0)
    assert_equal '1 Byte',    number_to_human_size(1)
    assert_equal '3 Bytes',   number_to_human_size(3.14159265)
    assert_equal '123 Bytes', number_to_human_size(123.0)
    assert_equal '123 Bytes', number_to_human_size(123)
147
    assert_equal '1.21 KB',    number_to_human_size(1234)
148
    assert_equal '12.1 KB',   number_to_human_size(12345)
149 150 151 152
    assert_equal '1.18 MB',    number_to_human_size(1234567)
    assert_equal '1.15 GB',    number_to_human_size(1234567890)
    assert_equal '1.12 TB',    number_to_human_size(1234567890123)
    assert_equal '1030 TB',   number_to_human_size(terabytes(1026))
153
    assert_equal '444 KB',    number_to_human_size(kilobytes(444))
154
    assert_equal '1020 MB',   number_to_human_size(megabytes(1023))
155
    assert_equal '3 TB',      number_to_human_size(terabytes(3))
156
    assert_equal '1.2 MB',   number_to_human_size(1234567, :precision => 2)
157
    assert_equal '3 Bytes',   number_to_human_size(3.14159265, :precision => 4)
158 159
    assert_equal '123 Bytes', number_to_human_size('123')
    assert_equal '1 KB',   number_to_human_size(kilobytes(1.0123), :precision => 2)
160 161
    assert_equal '1.01 KB',   number_to_human_size(kilobytes(1.0100), :precision => 4)
    assert_equal '10 KB',   number_to_human_size(kilobytes(10.000), :precision => 4)
162
    assert_equal '1 Byte',   number_to_human_size(1.1)
163
    assert_equal '10 Bytes', number_to_human_size(10)
164
  end
165

166 167 168 169 170 171 172 173 174 175 176
  def test_number_to_human_size_with_si_prefix
    assert_equal '3 Bytes',    number_to_human_size(3.14159265, :prefix => :si)
    assert_equal '123 Bytes',  number_to_human_size(123.0, :prefix => :si)
    assert_equal '123 Bytes',  number_to_human_size(123, :prefix => :si)
    assert_equal '1.23 KB',    number_to_human_size(1234, :prefix => :si)
    assert_equal '12.3 KB',    number_to_human_size(12345, :prefix => :si)
    assert_equal '1.23 MB',    number_to_human_size(1234567, :prefix => :si)
    assert_equal '1.23 GB',    number_to_human_size(1234567890, :prefix => :si)
    assert_equal '1.23 TB',    number_to_human_size(1234567890123, :prefix => :si)
  end

177
  def test_number_to_human_size_with_options_hash
178
    assert_equal '1.2 MB',   number_to_human_size(1234567, :precision => 2)
179
    assert_equal '3 Bytes',   number_to_human_size(3.14159265, :precision => 4)
180
    assert_equal '1 KB',   number_to_human_size(kilobytes(1.0123), :precision => 2)
181 182
    assert_equal '1.01 KB',   number_to_human_size(kilobytes(1.0100), :precision => 4)
    assert_equal '10 KB',     number_to_human_size(kilobytes(10.000), :precision => 4)
183 184
    assert_equal '1 TB', number_to_human_size(1234567890123, :precision => 1)
    assert_equal '500 MB', number_to_human_size(524288000, :precision=>3)
185
    assert_equal '10 MB', number_to_human_size(9961472, :precision=>0)
186 187
    assert_equal '40 KB', number_to_human_size(41010, :precision => 1)
    assert_equal '40 KB', number_to_human_size(41100, :precision => 2)
188
    assert_equal '1.0 KB',   number_to_human_size(kilobytes(1.0123), :precision => 2, :strip_insignificant_zeros => false)
189 190
    assert_equal '1.012 KB',   number_to_human_size(kilobytes(1.0123), :precision => 3, :significant => false)
    assert_equal '1 KB',   number_to_human_size(kilobytes(1.0123), :precision => 0, :significant => true) #ignores significant it precision is 0
191
  end
192 193

  def test_number_to_human_size_with_custom_delimiter_and_separator
194
    assert_equal '1,01 KB',     number_to_human_size(kilobytes(1.0123), :precision => 3, :separator => ',')
195
    assert_equal '1,01 KB',     number_to_human_size(kilobytes(1.0100), :precision => 4, :separator => ',')
196 197 198 199
    assert_equal '1.000,1 TB',  number_to_human_size(terabytes(1000.1), :precision => 5, :delimiter => '.', :separator => ',')
  end

  def test_number_to_human
200
    assert_equal '-123', number_to_human(-123)
201 202 203
    assert_equal '-0.5', number_to_human(-0.5)
    assert_equal '0',   number_to_human(0)
    assert_equal '0.5', number_to_human(0.5)
S
Santiago Pastorino 已提交
204 205 206 207 208 209 210 211 212 213 214 215 216 217 218
    assert_equal '123', number_to_human(123)
    assert_equal '1.23 Thousand', number_to_human(1234)
    assert_equal '12.3 Thousand', number_to_human(12345)
    assert_equal '1.23 Million', number_to_human(1234567)
    assert_equal '1.23 Billion', number_to_human(1234567890)
    assert_equal '1.23 Trillion', number_to_human(1234567890123)
    assert_equal '1.23 Quadrillion', number_to_human(1234567890123456)
    assert_equal '1230 Quadrillion', number_to_human(1234567890123456789)
    assert_equal '490 Thousand', number_to_human(489939, :precision => 2)
    assert_equal '489.9 Thousand', number_to_human(489939, :precision => 4)
    assert_equal '489 Thousand', number_to_human(489000, :precision => 4)
    assert_equal '489.0 Thousand', number_to_human(489000, :precision => 4, :strip_insignificant_zeros => false)
    assert_equal '1.2346 Million', number_to_human(1234567, :precision => 4, :significant => false)
    assert_equal '1,2 Million', number_to_human(1234567, :precision => 1, :significant => false, :separator => ',')
    assert_equal '1 Million', number_to_human(1234567, :precision => 0, :significant => true, :separator => ',') #significant forced to false
219 220 221
  end

  def test_number_to_human_with_custom_units
S
Santiago Pastorino 已提交
222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250
    #Only integers
    volume = {:unit => "ml", :thousand => "lt", :million => "m3"}
    assert_equal '123 lt', number_to_human(123456, :units => volume)
    assert_equal '12 ml', number_to_human(12, :units => volume)
    assert_equal '1.23 m3', number_to_human(1234567, :units => volume)

    #Including fractionals
    distance = {:mili => "mm", :centi => "cm", :deci => "dm", :unit => "m", :ten => "dam", :hundred => "hm", :thousand => "km"}
    assert_equal '1.23 mm', number_to_human(0.00123, :units => distance)
    assert_equal '1.23 cm', number_to_human(0.0123, :units => distance)
    assert_equal '1.23 dm', number_to_human(0.123, :units => distance)
    assert_equal '1.23 m', number_to_human(1.23, :units => distance)
    assert_equal '1.23 dam', number_to_human(12.3, :units => distance)
    assert_equal '1.23 hm', number_to_human(123, :units => distance)
    assert_equal '1.23 km', number_to_human(1230, :units => distance)
    assert_equal '1.23 km', number_to_human(1230, :units => distance)
    assert_equal '1.23 km', number_to_human(1230, :units => distance)
    assert_equal '12.3 km', number_to_human(12300, :units => distance)

    #The quantifiers don't need to be a continuous sequence
    gangster = {:hundred => "hundred bucks", :million => "thousand quids"}
    assert_equal '1 hundred bucks', number_to_human(100, :units => gangster)
    assert_equal '25 hundred bucks', number_to_human(2500, :units => gangster)
    assert_equal '25 thousand quids', number_to_human(25000000, :units => gangster)
    assert_equal '12300 thousand quids', number_to_human(12345000000, :units => gangster)

    #Spaces are stripped from the resulting string
    assert_equal '4', number_to_human(4, :units => {:unit => "", :ten => 'tens '})
    assert_equal '4.5  tens', number_to_human(45, :units => {:unit => "", :ten => ' tens   '})
251
  end
252 253 254 255 256 257 258

  def test_number_to_human_with_custom_format
    assert_equal '123 times Thousand', number_to_human(123456, :format => "%n times %u")
    volume = {:unit => "ml", :thousand => "lt", :million => "m3"}
    assert_equal '123.lt', number_to_human(123456, :units => volume, :format => "%n.%u")
  end

259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285
  def test_number_helpers_should_return_nil_when_given_nil
    assert_nil number_to_phone(nil)
    assert_nil number_to_currency(nil)
    assert_nil number_to_percentage(nil)
    assert_nil number_with_delimiter(nil)
    assert_nil number_with_precision(nil)
    assert_nil number_to_human_size(nil)
    assert_nil number_to_human(nil)
  end

  def test_number_helpers_should_return_non_numeric_param_unchanged
    assert_equal("+1-x x 123", number_to_phone("x", :country_code => 1, :extension => 123))
    assert_equal("x", number_to_phone("x"))
    assert_equal("$x.", number_to_currency("x."))
    assert_equal("$x", number_to_currency("x"))
    assert_equal("x%", number_to_percentage("x"))
    assert_equal("x", number_with_delimiter("x"))
    assert_equal("x.", number_with_precision("x."))
    assert_equal("x", number_with_precision("x"))
    assert_equal "x", number_to_human_size('x')
    assert_equal "x", number_to_human('x')
  end

  def test_number_helpers_outputs_are_html_safe
    assert number_to_human(1).html_safe?
    assert !number_to_human("<script></script>").html_safe?
    assert number_to_human("asdf".html_safe).html_safe?
286
    assert number_to_human("1".html_safe).html_safe?
287 288 289 290 291

    assert number_to_human_size(1).html_safe?
    assert number_to_human_size(1000000).html_safe?
    assert !number_to_human_size("<script></script>").html_safe?
    assert number_to_human_size("asdf".html_safe).html_safe?
292
    assert number_to_human_size("1".html_safe).html_safe?
293

294 295
    assert number_with_precision(1, :strip_insignificant_zeros => false).html_safe?
    assert number_with_precision(1, :strip_insignificant_zeros => true).html_safe?
296 297
    assert !number_with_precision("<script></script>").html_safe?
    assert number_with_precision("asdf".html_safe).html_safe?
298
    assert number_with_precision("1".html_safe).html_safe?
299 300 301 302

    assert number_to_currency(1).html_safe?
    assert !number_to_currency("<script></script>").html_safe?
    assert number_to_currency("asdf".html_safe).html_safe?
303
    assert number_to_currency("1".html_safe).html_safe?
304 305 306 307

    assert number_to_percentage(1).html_safe?
    assert !number_to_percentage("<script></script>").html_safe?
    assert number_to_percentage("asdf".html_safe).html_safe?
308
    assert number_to_percentage("1".html_safe).html_safe?
309 310

    assert number_to_phone(1).html_safe?
311 312
    assert_equal "&lt;script&gt;&lt;/script&gt;", number_to_phone("<script></script>")
    assert number_to_phone("<script></script>").html_safe?
313
    assert number_to_phone("asdf".html_safe).html_safe?
314
    assert number_to_phone("1".html_safe).html_safe?
315 316 317 318

    assert number_with_delimiter(1).html_safe?
    assert !number_with_delimiter("<script></script>").html_safe?
    assert number_with_delimiter("asdf".html_safe).html_safe?
319
    assert number_with_delimiter("1".html_safe).html_safe?
320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368
  end

  def test_number_helpers_should_raise_error_if_invalid_when_specified
    assert_raise InvalidNumberError do
      number_to_human("x", :raise => true)
    end
    begin
      number_to_human("x", :raise => true)
    rescue InvalidNumberError => e
      assert_equal "x", e.number
    end

    assert_raise InvalidNumberError do
      number_to_human_size("x", :raise => true)
    end
    begin
      number_to_human_size("x", :raise => true)
    rescue InvalidNumberError => e
      assert_equal "x", e.number
    end

    assert_raise InvalidNumberError do
      number_with_precision("x", :raise => true)
    end
    begin
      number_with_precision("x", :raise => true)
    rescue InvalidNumberError => e
      assert_equal "x", e.number
    end

    assert_raise InvalidNumberError do
      number_to_currency("x", :raise => true)
    end
    begin
      number_with_precision("x", :raise => true)
    rescue InvalidNumberError => e
      assert_equal "x", e.number
    end

    assert_raise InvalidNumberError do
      number_to_percentage("x", :raise => true)
    end
    begin
      number_to_percentage("x", :raise => true)
    rescue InvalidNumberError => e
      assert_equal "x", e.number
    end

    assert_raise InvalidNumberError do
S
Santiago Pastorino 已提交
369
      number_with_delimiter("x", :raise => true)
370 371 372 373 374 375 376 377
    end
    begin
      number_with_delimiter("x", :raise => true)
    rescue InvalidNumberError => e
      assert_equal "x", e.number
    end

    assert_raise InvalidNumberError do
S
Santiago Pastorino 已提交
378
      number_to_phone("x", :raise => true)
379 380 381 382 383 384 385 386 387
    end
    begin
      number_to_phone("x", :raise => true)
    rescue InvalidNumberError => e
      assert_equal "x", e.number
    end

  end

388
end