number_helper_test.rb 19.8 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 23 24 25 26 27 28 29 30
  def silence_deprecation_warnings
    @old_deprecatios_silenced = ActiveSupport::Deprecation.silenced
    ActiveSupport::Deprecation.silenced  = true
  end

  def restore_deprecation_warnings
    ActiveSupport::Deprecation.silenced  = @old_deprecatios_silenced
  end

31
  def test_number_to_phone
32
    assert_equal("555-1234", number_to_phone(5551234))
33 34
    assert_equal("800-555-1212", number_to_phone(8005551212))
    assert_equal("(800) 555-1212", number_to_phone(8005551212, {:area_code => true}))
35
    assert_equal("", number_to_phone("", {:area_code => true}))
36 37 38 39 40 41 42 43
    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))
44 45 46 47 48
  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))
49 50 51
    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)"}))
52
    assert_equal("$1,234,567,892", number_to_currency(1234567891.50, {:precision => 0}))
53
    assert_equal("$1,234,567,890.5", number_to_currency(1234567890.50, {:precision => 1}))
54
    assert_equal("&pound;1234567890,50", number_to_currency(1234567890.50, {:unit => "&pound;", :separator => ",", :delimiter => ""}))
55
    assert_equal("$1,234,567,890.50", number_to_currency("1234567890.50"))
56
    assert_equal("1,234,567,890.50 K&#269;", number_to_currency("1234567890.50", {:unit => "K&#269;", :format => "%n %u"}))
57
    assert_equal("1,234,567,890.50 - K&#269;", number_to_currency("-1234567890.50", {:unit => "K&#269;", :format => "%n %u", :negative_format => "%n - %u"}))
58 59 60 61 62 63
  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}))
64
    assert_equal("100.000%", number_to_percentage("100"))
65
    assert_equal("1000.000%", number_to_percentage("1000"))
66
    assert_equal("123.4%", number_to_percentage(123.400, :precision => 3, :strip_insignificant_zeros => true))
67
    assert_equal("1.000,000%", number_to_percentage(1000, :delimiter => '.', :separator => ','))
68 69 70 71
  end

  def test_number_with_delimiter
    assert_equal("12,345,678", number_with_delimiter(12345678))
72 73 74 75 76 77 78 79
    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))
80
    assert_equal("123,456.78", number_with_delimiter("123456.78"))
81
  end
82

83 84 85 86 87 88 89
  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

90
  def test_number_with_precision
91
    assert_equal("-111.235", number_with_precision(-111.2346))
92
    assert_equal("111.235", number_with_precision(111.2346))
93 94 95
    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))
96
    assert_equal("111.235", number_with_precision("111.2346"))
97
    assert_equal("31.83", number_with_precision("31.825", :precision => 2))
98
    assert_equal("3268", number_with_precision((32.6751 * 100.00), :precision => 0))
99 100
    assert_equal("112", number_with_precision(111.50, :precision => 0))
    assert_equal("1234567892", number_with_precision(1234567891.50, :precision => 0))
101 102 103
    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))
104 105
    assert_equal("10.00", number_with_precision(9.995, :precision => 2))
    assert_equal("11.00", number_with_precision(10.995, :precision => 2))
106
  end
107

108 109 110
  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 => '.')
111 112
  end

113 114 115 116 117 118 119 120 121 122 123 124 125
  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 )
126
    assert_equal "0.0", number_with_precision(0, :precision => 2, :significant => true )
127
    assert_equal "0", number_with_precision(0, :precision => 1, :significant => true )
128 129 130
    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 )
131 132 133
    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)
134 135
  end

136 137 138
  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 )
139
    assert_equal "0", number_with_precision(0, :precision => 6, :significant => true, :strip_insignificant_zeros => true )
140 141 142 143
  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 已提交
144
    # so we treat it as if significant was false (increases backwards compatibility for number_to_human_size)
145 146 147 148 149
    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

150 151 152 153 154 155
  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)
156
    assert_equal '1.21 KB',    number_to_human_size(1234)
157
    assert_equal '12.1 KB',   number_to_human_size(12345)
158 159 160 161
    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))
162
    assert_equal '444 KB',    number_to_human_size(kilobytes(444))
163
    assert_equal '1020 MB',   number_to_human_size(megabytes(1023))
164
    assert_equal '3 TB',      number_to_human_size(terabytes(3))
165
    assert_equal '1.2 MB',   number_to_human_size(1234567, :precision => 2)
166
    assert_equal '3 Bytes',   number_to_human_size(3.14159265, :precision => 4)
167 168
    assert_equal '123 Bytes', number_to_human_size('123')
    assert_equal '1 KB',   number_to_human_size(kilobytes(1.0123), :precision => 2)
169 170
    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)
171
    assert_equal '1 Byte',   number_to_human_size(1.1)
172
    assert_equal '10 Bytes', number_to_human_size(10)
173
  end
174

175 176 177 178 179 180 181 182 183 184 185
  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

186
  def test_number_to_human_size_with_options_hash
187
    assert_equal '1.2 MB',   number_to_human_size(1234567, :precision => 2)
188
    assert_equal '3 Bytes',   number_to_human_size(3.14159265, :precision => 4)
189
    assert_equal '1 KB',   number_to_human_size(kilobytes(1.0123), :precision => 2)
190 191
    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)
192 193
    assert_equal '1 TB', number_to_human_size(1234567890123, :precision => 1)
    assert_equal '500 MB', number_to_human_size(524288000, :precision=>3)
194
    assert_equal '10 MB', number_to_human_size(9961472, :precision=>0)
195 196
    assert_equal '40 KB', number_to_human_size(41010, :precision => 1)
    assert_equal '40 KB', number_to_human_size(41100, :precision => 2)
197
    assert_equal '1.0 KB',   number_to_human_size(kilobytes(1.0123), :precision => 2, :strip_insignificant_zeros => false)
198 199
    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
200
  end
201 202

  def test_number_to_human_size_with_custom_delimiter_and_separator
203
    assert_equal '1,01 KB',     number_to_human_size(kilobytes(1.0123), :precision => 3, :separator => ',')
204
    assert_equal '1,01 KB',     number_to_human_size(kilobytes(1.0100), :precision => 4, :separator => ',')
205 206 207 208
    assert_equal '1.000,1 TB',  number_to_human_size(terabytes(1000.1), :precision => 5, :delimiter => '.', :separator => ',')
  end

  def test_number_to_human
209
    assert_equal '-123', number_to_human(-123)
210 211 212
    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 已提交
213 214 215 216 217 218 219 220 221 222 223 224 225 226 227
    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
228 229 230
  end

  def test_number_to_human_with_custom_units
S
Santiago Pastorino 已提交
231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259
    #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   '})
260
  end
261 262 263 264 265 266 267

  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

268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300
  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?

    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?

301 302
    assert number_with_precision(1, :strip_insignificant_zeros => false).html_safe?
    assert number_with_precision(1, :strip_insignificant_zeros => true).html_safe?
303 304 305 306 307 308 309 310 311 312 313 314
    assert !number_with_precision("<script></script>").html_safe?
    assert number_with_precision("asdf".html_safe).html_safe?

    assert number_to_currency(1).html_safe?
    assert !number_to_currency("<script></script>").html_safe?
    assert number_to_currency("asdf".html_safe).html_safe?

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

    assert number_to_phone(1).html_safe?
315 316
    assert_equal "&lt;script&gt;&lt;/script&gt;", number_to_phone("<script></script>")
    assert number_to_phone("<script></script>").html_safe?
317 318 319 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 369 370
    assert number_to_phone("asdf".html_safe).html_safe?

    assert number_with_delimiter(1).html_safe?
    assert !number_with_delimiter("<script></script>").html_safe?
    assert number_with_delimiter("asdf".html_safe).html_safe?
  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 已提交
371
      number_with_delimiter("x", :raise => true)
372 373 374 375 376 377 378 379
    end
    begin
      number_with_delimiter("x", :raise => true)
    rescue InvalidNumberError => e
      assert_equal "x", e.number
    end

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

  end

390
end