diff --git a/lib/brazilian_cardinality/number.rb b/lib/brazilian_cardinality/number.rb index 05840f5..7f3196f 100644 --- a/lib/brazilian_cardinality/number.rb +++ b/lib/brazilian_cardinality/number.rb @@ -51,19 +51,41 @@ module Number class << self def number_cardinal(number) negative = number.negative? ? 'menos ' : '' - n = number.to_i.abs - - expression = case n - when 0..999 then cardinal_for_0_up_to_999(n) - when 1000..999_999_999_999_999 then cardinal_for_thousands_to_trillions(n) - else raise NumberTooBigError, "#{n} is too big" - end + abs_value = number.abs + decimals = abs_value.to_s.split('.')[1].to_s[0, 2] + integer = abs_value.to_i + expression = raw_cardinal_expression(integer, decimals) "#{negative}#{expression}" end private + def raw_cardinal_expression(integer, decimals) + integer_expression = cardinal_number_integer_part(integer) + cents_expression = cardinal_decimals(decimals) + [integer_expression, cents_expression].compact.join(' vírgula ') + end + + def cardinal_number_integer_part(value) + case value + when 0..999 then cardinal_for_0_up_to_999(value) + when 1000..999_999_999_999_999 then cardinal_for_thousands_to_trillions(value) + else raise NumberTooBigError, "#{value} is too big" + end + end + + def cardinal_decimals(decimals) + return if decimals.to_i.zero? + + if decimals[0].to_i.zero? + decimal_prefix = 'zero' + end + + decimals = decimals.to_i + [decimal_prefix, Number.number_cardinal(decimals)].compact.join(' ') + end + def cardinal_for_0_up_to_999(number) case number when 0..9 then ONES[number] @@ -102,6 +124,20 @@ def cardinal_for_scale_of_thousands(number, scale, singular, plural) return high_order_units if remainder.zero? "#{high_order_units} e #{number_cardinal(remainder)}" end + + def cardinal_for_fraction(fraction) + return '' unless fraction + + fraction = (fraction * 10).to_i + + fraction_expression = case fraction + when 0..999 then cardinal_for_0_up_to_999(fraction) + when 1000..999_999_999_999_999 then cardinal_for_thousands_to_trillions(fraction) + else raise NumberTooBigError, "#{fraction} is too big" + end + + ' vírgula ' + fraction_expression + end end end end diff --git a/test/brazilian_cardinality/number_test.rb b/test/brazilian_cardinality/number_test.rb index c50c29d..c5dcd17 100644 --- a/test/brazilian_cardinality/number_test.rb +++ b/test/brazilian_cardinality/number_test.rb @@ -309,4 +309,20 @@ def test_negative_trillions def test_when_number_has_a_scale_bigger_than_trillion assert_raises(BrazilianCardinality::Number::NumberTooBigError) { @klass.number_cardinal(1_000_000_000_000_000) } end + + def test_number_with_decimals + assert_equal 'zero vírgula zero um', @klass.number_cardinal(0.01) + assert_equal 'zero vírgula cinco', @klass.number_cardinal(0.5) + assert_equal 'zero vírgula um', @klass.number_cardinal(0.10) + assert_equal 'zero vírgula onze', @klass.number_cardinal(0.11) + assert_equal 'zero vírgula vinte e três', @klass.number_cardinal(0.23) + assert_equal 'zero vírgula cinquenta e dois', @klass.number_cardinal(0.52) + assert_equal 'um vírgula zero um', @klass.number_cardinal(1.01) + assert_equal 'um', @klass.number_cardinal(1.00) + assert_equal 'um vírgula cinco', @klass.number_cardinal(1.5) + assert_equal 'um vírgula um', @klass.number_cardinal(1.10) + assert_equal 'um vírgula onze', @klass.number_cardinal(1.11) + assert_equal 'um vírgula vinte e três', @klass.number_cardinal(1.23) + assert_equal 'um vírgula cinquenta e dois', @klass.number_cardinal(1.52) + end end