require File.dirname(__FILE__) + '/test_helper' class DinheiroTest < Test::Unit::TestCase CONTABIL = { "(2,00)" => -2, "2,00" => 2, "0,00" => 0, "0,32" => 0.32, "(0,01)" => -0.01 } REAL_CONTABIL = { "R$ (1,00)" => -1, "R$ (0,12)" => -0.12, "R$ 1,00" => 1, "R$ 1,00" => 1, "R$ 1,00" => 1, "R$ 0,00" => 0 } SOMA = { 0.real => 0.real + 0.real, 1.real => 0.real + 1.real, 1.real => 1.real + 0.real, 2.reais => 1.real + 1.real, 2.reais => 0.real + 2.reais, 2.reais => 2.reais + 0.real, 0.real => 2.real + -2.real, 0.real => 0.real + BigDecimal.new("0"), 0.3.real => 0.real + 0.3.real, -0.3.real => 0.real + -0.3.real, -0.03.real => 0 + -0.03.real, -0.03.real => 0.real + -0.03, -1.03.real => -1.real + -0.03, -1.03.real => -1.real + BigDecimal.new("-0.03") } SUBTRACAO = { 0.real => 0.real - 0.real, -1.real => 0.real - 1.real, 1.real => 1.real - 0.real, 0.real => 1.real - 1.real, -2.reais => 0.real - 2.reais, 2.reais => 2.reais - 0.real, -4.reais => -2.reais - 2.reais, 0.3.real => 0.3.real - 0.real, 0.03.real => 0.03.real - 0.real, 0.03.real => 0.06.real - 0.03.real, -0.03.real => 0 - 0.03.real, -0.03.real => 0.real - 0.03, -1.03.real => -1.real - 0.03, -1.03.real => -1.real - BigDecimal.new("0.03") } MULTIPLICACAO = { 0.real => 0.real * 0, 0.real => 0.real * 1, 0.real => 0.real * -1, 1.real => 1.real * 1, 10.real => 10.real * 1, 100.real => 100.real * 1, 1000.real => 1000.real * 1, 1.real => -1.real * -1, -1.real => 1.real * -1, -1.real => -1.real * 1, 0.1.real => 1.real * 0.1, 0.01.real => 1.real * 0.01, 0.01.real => 1.real * 0.009, 0.01.real => 1.real * 0.005, 0.00.real => 1.real * 0.0049, 0.1.real => 0.1.real * 1, 0.01.real => 0.01.real * 1, 0.01.real => 0.009.real * 1, 0.00.real => 0.00049.real * 1, 0.real => 0.real * 0.real, 0.real => 0.real * BigDecimal("0"), 1.real => 1.real * 1.real, 1.real => 1.real * BigDecimal("1"), 1.real => 0.5.real * 2.real, 1.real => 0.5.real * BigDecimal("2"), 1.real => 1 * 1.real, -1.real => -1 * 1.real, 1.real => -1 * -1.real, 0.01.real => 0.01 * 1.real, 0.01.real => 1.real * BigDecimal("0.01"), 0.01.real => BigDecimal("0.01") * 1.real } DIVISAO = { Dinheiro.new(0.33) => Dinheiro.new(1) / 3, Dinheiro.new(33.33) => Dinheiro.new(100) / 3, Dinheiro.new(50.00) => Dinheiro.new(100) / 2, Dinheiro.new(0.25) => Dinheiro.new(0.5) / 2, Dinheiro.new(0.17) => Dinheiro.new(0.5) / 3, Dinheiro.new(0.33) => Dinheiro.new(0.33) / 1 } PARCELAS = { [Dinheiro.new(0.33), Dinheiro.new(0.33), Dinheiro.new(0.34)] => Dinheiro.new(1).parcelar(3), [Dinheiro.new(33.33), Dinheiro.new(33.33), Dinheiro.new(33.34)] => Dinheiro.new(100).parcelar(3), [Dinheiro.new(50.00), Dinheiro.new(50)] => Dinheiro.new(100).parcelar(2), [Dinheiro.new(0.25), Dinheiro.new(0.25)] => Dinheiro.new(0.5).parcelar(2), [Dinheiro.new(0.16), Dinheiro.new(0.17),Dinheiro.new(0.17)] => Dinheiro.new(0.5).parcelar(3), [Dinheiro.new(0.33)] => Dinheiro.new(0.33).parcelar(1), [Dinheiro.new(0.33)] => Dinheiro.new(0.33).parcelar(1), } QUANTIA_COM_FORMATO_VALIDO = [ "1211", "1211.", "1211.0", "1211.23", "1211,23", "1.211", "1.211,00", "1.211,01", "1.211,1", "1.211,", "1,", "12,", "32349898989912,", "32.349.898.989.912,", "32.349.898.989.912,1", "32.349.898.989.912,12", "1", "1.00", "1.01", "1.1", "1.", ".1", ".12", "0.12", "1.12", "12.12", "12.12", "123.12", "1,234.12", "12,234.12", "123,234.12", "2,123,234.12", ",1", ",11", ",01", "0,01" ] QUANTIA_COM_FORMATO_INVALIDO = [ 'teste', '12,123,99', '12.123.99', '1,123,99', '1212,39.90' ] COMPARACAO = [ 1.real < 2.reais, 1.real <= 2.reais, 2.real > 1.real, 2.real >= 1.real, 1.real == 1.real, 1.real >= 1.real, 1.real <= 1.real ] COMPARACAO_COM_ESCALAR = [ 1.real < 2.00, 1.real <= 2.00, 2.real > 1.00, 2.real >= 1.00, 1.real == 1.00, 1.real >= 1.00, 1.real <= 1.00 ] ARREDONDAMENTO = { 23049 => 230.49, 23049 => 230.4949999999, 23050 => 230.495 } PONTO_NO_MILHAR = { "234.175.211" => "234175211", "" => "", "1" => "1", "12" => "12", "123" => "123", "1.234" => "1234", "12.345" => "12345", "123.456" => "123456", "123.112.211" => "123112211", "1.234.567" => "1234567" } QUANTIA_VALIDA = { "0,00" => 0 , "0,00" => 0.0 , "0,00" => "0" , "0,00" => "0,00" , "1,00" => 1 , "1,03" => 1.03 , "1,03" => "1,03" , "0,03" => ",03" , "0,30" => ",3" , "0,03" => ".03" , "0,30" => ".3" , "-0,30" => -0.3 , "-0,03" => -0.03 , "1,00" => "1,00" , "-1,00" => -1 , "-1,00" => -1.0 , "-1,00" => "-1" , "-1,00" => "-1,00" , "-2,30" => "-2,30" , "2,30" => "2,30" , "2,30" => 2.30 , "2,30" => 2.3 , "1.211,00" => "1211,00" , "1.211,01" => "1211,01" , "1.211,50" => "1211,5" , "1.211,00" => "1211," , "1.211,00" => "1211" , "1.211,00" => "1211.00" , "1.211,01" => "1211.01" , "1.211,20" => "1211.2" , "1.211,00" => "1211." , "1.211,00" => "1211" , "1.211,00" => "1.211" , "123.112.211,35" => "123112211,35" , "-123.112.211,35" => "-123112211,35" , "123.112.211,35" => "+123112211,35" } PARTE_INTEIRA = [ -1, -123112211, 0, 1, 12344545 ] def setup tornar_metodos_publicos Dinheiro @dinheiro = 1.real end def testa_se_cria_dinheiro_a_partir_de_quantias_validos QUANTIA_VALIDA.each do |esperado, quantia| assert_equal esperado, Dinheiro.new(quantia).to_s, "Deveria ter vindo o quantia: #{esperado} quando recebeu #{quantia}" end end # coloca_ponto_no_milhar def testa_se_coloca_ponto_no_milhar PONTO_NO_MILHAR.each do |esperado, quantia| { esperado => quantia, "-#{esperado}" => "-#{quantia}" }.each do |esperado, quantia| assert_equal esperado, @dinheiro.inteiro_com_milhar(quantia) end end end def testa_to_s assert_equal "1,00", Dinheiro.new(1).to_s assert_equal "1.000,00", Dinheiro.new(1000).to_s end # real def testa_real_nao_eh_dinheiro assert_kind_of(Dinheiro, 1.real) end def testa_real_eh_dinheiro assert_kind_of(Dinheiro, Dinheiro.new(1).real) end def testa_real_contabil REAL_CONTABIL.each { |esperado, quantia| assert_equal esperado, Dinheiro.new(quantia).real_contabil } end def testa_reais_contabeis REAL_CONTABIL.each { |esperado, quantia| assert_equal esperado, Dinheiro.new(quantia).reais_contabeis } end # reais def testa_reais assert_equal Dinheiro.new("2,00"), Dinheiro.new(2).reais end def testa_contabil CONTABIL.each { |esperado, quantia| assert_equal esperado, Dinheiro.new(quantia).contabil } end # real_formatado def test_real_formatado assert_equal "R$ 2,00", Dinheiro.new(2).real_formatado end # == def testa_igualdade assert_equal Dinheiro.new(1), Dinheiro.new(1) end def testa_igualdade_quando_passa_possivel_dinheiro assert_equal Dinheiro.new(1), 1.0 end def testa_igualdade_quando_passa_algo_que_nao_seja_dinheiro assert_equal false, Dinheiro.new(1) == 'salario' end # / (divisao) def testa_divisao DIVISAO.each { |parcelas, divisao| assert_equal parcelas, divisao } end def testa_divisao_por_zero assert_raise(ZeroDivisionError) { 1.real / 0 } end def testa_divisao_por_algo_que_nao_seja_um_escalar assert_raise(DivisaPorNaoEscalarError) { 10.reais / 2.reais } end # parcelar def testa_parcelar PARCELAS.each { |parcelas, divisao| assert_equal parcelas, divisao } end def testa_parcelar_por_zero assert_raise(ZeroDivisionError) { 1.real.parcelar 0 } end def testa_parcelar_por_algo_que_nao_seja_um_escalar assert_raise(DivisaPorNaoEscalarError) { 10.reais.parcelar(2.reais) } end # initialize def testa_se_cria_dinheiro_a_partir_de_float verifica_se_cria_dinheiro_para 1.0 end def testa_se_cria_dinheiro_a_partir_de_fixnum verifica_se_cria_dinheiro_para 1 end def testa_se_cria_dinheiro_a_partir_de_bigdecimal verifica_se_cria_dinheiro_para BigDecimal.new("1") end def testa_se_cria_dinheiro_a_partir_de_string verifica_se_cria_dinheiro_para "1" end def testa_se_rejeita_criacao_de_dinheiro_a_partir_de_string_invalida QUANTIA_COM_FORMATO_INVALIDO.each do |quantia| assert_raise DinheiroInvalidoError, "Deveria ter rejeitado [#{quantia}]" do Dinheiro.new quantia end end end # + (soma) def testa_soma SOMA.each{ |esperado, soma| assert_equal esperado, soma } end # - (subtracao) def testa_subtracao SUBTRACAO.each { |esperado, subtracao| assert_equal esperado, subtracao } end # * (multiplicacao) def testa_multiplicacao MULTIPLICACAO.each { |esperado, multiplicacao| assert_equal esperado, multiplicacao } end # quantia_de def testa_quantia_de assert_equal 0, @dinheiro.quantia_de(0.real) assert_equal 0, @dinheiro.quantia_de(0) end #por_extenso def testa_por_extenso assert_equal 'um real', 1.real.por_extenso assert_equal 'um centavo', (0.01).real.por_extenso assert_equal 'cem reais', 100.real.por_extenso assert_equal 'cem reais e um centavo', (100.01).real.por_extenso end #por_extenso_em_reais def testa_por_extenso_em_reais assert_equal 'um real', 1.real.por_extenso_em_reais assert_equal 'um centavo', (0.01).real.por_extenso_em_reais assert_equal 'cem reais', 100.real.por_extenso_em_reais assert_equal 'cem reais e um centavo', (100.01).real.por_extenso_em_reais end def testa_por_extenso_negativo assert_equal 'um real negativo', -1.real.por_extenso_em_reais assert_equal 'um centavo negativo', (-0.01).real.por_extenso_em_reais assert_equal 'cem reais negativos', -100.real.por_extenso_em_reais assert_equal 'cem reais e um centavo negativos', (-100.01).real.por_extenso_em_reais assert_equal 'cento e dez reais negativos', (-110).real.por_extenso_em_reais assert_equal 'vinte e dois reais negativos', -22.reais.por_extenso assert_not_equal 'vinte e dois centavos negativos', -22.reais.por_extenso assert_not_equal 'vinte e dois centavos', -22.reais.por_extenso end # to_f def testa_to_f assert_equal 2.30, 2.30.real.to_f assert_equal 1000, 1000.real.to_f end # quantia_respeita_formato? def testa_se_quantia_respeita_formato QUANTIA_COM_FORMATO_VALIDO.each { |quantia| verifica_se_quantia_respeita_formato quantia } end # >, <, == (ordenacao) def testa_comparacao_entre_dinheiro COMPARACAO.each { |comparacao| assert comparacao } end def testa_comparacao_entre_possivel_dinheiro COMPARACAO_COM_ESCALAR.each { |comparacao_com_escalar| assert comparacao_com_escalar } end # decimal def testa_decimal_quando_todas_as_casas_estao_preenchidas verifica_decimal("12") end def testa_decimal_quando_apenas_uma_das_casas_esta_preenchida verifica_decimal("10", "1") end def testa_decimal_quando_nenhuma_das_casas_esta_preenchida verifica_decimal("00", "") end def testa_se_transforma_em_string_que_represente_a_quantia_quando_tem_tres_digitos verifica_se_transforma_em_string_corretamente "1.23", 123 end def testa_se_transforma_em_string_que_represente_a_quantia_quando_tem_dois_digitos verifica_se_transforma_em_string_corretamente "0.12", 12 end def testa_se_transforma_em_string_que_represente_a_quantia_quando_tem_um_digito verifica_se_transforma_em_string_corretamente "0.03", 3 end def testa_se_transforma_em_string_para_valores_especiais verifica_se_transforma_em_string_corretamente "-123112211.00", -12311221100 end # parte_inteira def testa_parte_inteira PARTE_INTEIRA.each { |quantia| assert_equal "#{quantia}", Dinheiro.new(quantia).parte_inteira } end def testa_se_arredonda_valores_corretamente ARREDONDAMENTO.each do |esperado, quantia| assert_equal esperado, Dinheiro.new(quantia).quantia, "Deveria retornar #{esperado} para #{quantia}" end end def testa_se_valor_decimal_cria_o_big_decimal_corretamente assert_equal BigDecimal.new("1234.56"), Dinheiro.new("1234,56").valor_decimal end def testa_soma_de_dinheiro_com_big_decimal assert_equal Dinheiro.new(200), BigDecimal.new("100").reais + "100".reais end def testa_zero_quando_eh_zero assert Dinheiro.new(0).zero? end def testa_zero_quando_nao_eh_zero assert !Dinheiro.new(1).zero? end private def verifica_se_transforma_em_string_corretamente(quantia_esperada, quantia) assert_equal quantia_esperada, @dinheiro.transforma_em_string_que_represente_a_quantia(quantia) end def verifica_decimal(esperado, quantia = esperado) assert_equal esperado, @dinheiro.decimal("." + quantia) assert_equal esperado, @dinheiro.decimal("," + quantia) assert_equal esperado, @dinheiro.decimal(quantia) if quantia.blank? end def verifica_se_quantia_respeita_formato(quantia) formatos_validos(quantia).each do |quantia_str| assert 1.real.quantia_respeita_formato?(quantia_str), "O sistema deveria considerar o quantia '#{quantia_str}' dentro do formato valido." end end def formatos_validos(quantia) formatos_validos = [] quantias_validas(quantia).each do |quantia| formatos_validos << quantia [ "R$", "r$" ].each do |simbolo| [ "", " ", " " ].each do |espacos| formatos_validos << "#{simbolo}#{espacos}#{quantia}" end end end formatos_validos end def quantias_validas(quantia) return [quantia] if [ ".", "," ].include?(quantia[0..0]) [ quantia, "-#{quantia}" ] end def verifica_se_cria_dinheiro_para(quantia) assert quantia.para_dinheiro.kind_of?(Dinheiro) end end