Spaces:
Runtime error
Runtime error
| import test from "node:test"; | |
| import assert from "node:assert/strict"; | |
| import { | |
| calcularIndicadoresSecundario, | |
| calcularSimulacao, | |
| listarPerfisFluxoScpDefault, | |
| montarFluxoClienteScp, | |
| simularModoConversaoScpConsorcio, | |
| simularSecundarioComPerfilScp, | |
| } from "../src/index.js"; | |
| const baseInput = { | |
| credito_desejado: 300000, | |
| parametros: { | |
| id_plano: "PADRAO", | |
| nome_plano: "Plano Padrao Imovel", | |
| prazo_meses: 180, | |
| taxa_administracao_total: 0.15, | |
| fundo_reserva_mensal: 0.0005, | |
| seguro_prestamista: 0.035, | |
| }, | |
| tem_lance: false, | |
| }; | |
| test("calcula parcela integral com valores esperados", () => { | |
| const result = calcularSimulacao(baseInput); | |
| assert.equal(result.prazo, 180); | |
| assert.equal(result.credito, 300000); | |
| assert.ok(result.parcela_integral.total > 0); | |
| assert.equal(Number(result.parcela_integral.fundo_comum.toFixed(2)), 1666.67); | |
| }); | |
| test("calcula cenario com lance e reduz prazo", () => { | |
| const result = calcularSimulacao({ | |
| ...baseInput, | |
| tem_lance: true, | |
| lance_percentual: 0.3, | |
| }); | |
| assert.ok(result.valor_lance); | |
| assert.equal(result.valor_lance, 90000); | |
| assert.ok(result.prazo_apos_lance); | |
| assert.ok(result.prazo_apos_lance < result.prazo); | |
| }); | |
| test("falha quando prazo_meses for invalido", () => { | |
| assert.throws(() => { | |
| calcularSimulacao({ | |
| ...baseInput, | |
| parametros: { | |
| ...baseInput.parametros, | |
| prazo_meses: 0, | |
| }, | |
| }); | |
| }, /prazo_meses/); | |
| }); | |
| test("calcula payback do secundario com offset apos ultima contemplacao", () => { | |
| const fluxos = []; | |
| for (let i = 0; i < 10; i += 1) { | |
| fluxos.push(-100); | |
| } | |
| for (let i = 0; i < 50; i += 1) { | |
| fluxos.push(20); | |
| } | |
| const result = calcularIndicadoresSecundario({ | |
| fluxos_mensais: fluxos, | |
| meses_pos_ultima_contemplacao: 3, | |
| }); | |
| assert.equal(result.caixa_maximo_negativo, -1000); | |
| assert.equal(result.payback_meses, 63); | |
| assert.equal(result.regras_aplicadas.fee_sobre_volume_reduzido_70, true); | |
| }); | |
| test("deduz portabilidade e fee com parcela reduzida em 70% do volume", () => { | |
| const result = calcularIndicadoresSecundario({ | |
| fluxos_mensais: [-1000, 500, 700], | |
| transacoes_portabilidade: [ | |
| { valor: 100000, contemplada: true }, | |
| { valor: 100000, contemplada: false }, | |
| ], | |
| volume_contratado: 300000, | |
| fee_percentual: 0.02, | |
| percentual_cartas_parcela_reduzida: 1, | |
| }); | |
| assert.equal(result.custo_portabilidade, 1500); | |
| assert.equal(result.custo_fee_parcela_reduzida, 4200); | |
| assert.equal(result.custo_total_deducoes, 5700); | |
| assert.equal(result.fluxo_ajustado[0], -6700); | |
| }); | |
| test("valida entradas invalidas no secundario", () => { | |
| assert.throws(() => { | |
| calcularIndicadoresSecundario({ | |
| fluxos_mensais: [-100, 100], | |
| percentual_cartas_parcela_reduzida: 1.2, | |
| }); | |
| }, /percentual_cartas_parcela_reduzida/); | |
| }); | |
| test("calcula tir mensal e anual no secundario", () => { | |
| const result = calcularIndicadoresSecundario({ | |
| fluxos_mensais: [-1000, 1100], | |
| }); | |
| assert.ok(result.tir_mensal !== null); | |
| assert.ok(result.tir_anual !== null); | |
| assert.ok(Math.abs(result.tir_mensal - 0.1) < 1e-6); | |
| }); | |
| test("lista perfis SCP default com clientes entregues", () => { | |
| const catalogo = listarPerfisFluxoScpDefault(); | |
| assert.ok(catalogo.clients.length >= 6); | |
| assert.ok(catalogo.patterns.length >= 2); | |
| assert.ok(catalogo.clients.find((c) => c.client_id === "extrato_investidor_6")); | |
| }); | |
| test("monta fluxo SCP parametrizado por escala e deslocamento", () => { | |
| const fluxo = montarFluxoClienteScp({ | |
| client_id: "extrato_investidor_6", | |
| escala_fluxo: 0.5, | |
| deslocamento_meses: 2, | |
| novo_client_id: "cliente_novo", | |
| novo_client_name: "Cliente Novo", | |
| }); | |
| assert.equal(fluxo.client_id, "cliente_novo"); | |
| assert.equal(fluxo.client_name, "Cliente Novo"); | |
| assert.equal(fluxo.source_client_id, "extrato_investidor_6"); | |
| assert.ok(fluxo.pontos.length > 10); | |
| assert.equal(fluxo.pontos[0].periodo, "2021-04-01"); | |
| }); | |
| test("simula secundario com perfil SCP default", () => { | |
| const result = simularSecundarioComPerfilScp({ | |
| client_id: "extrato_investidor_6", | |
| fee_percentual: 0.02, | |
| volume_contratado: 100000, | |
| percentual_cartas_parcela_reduzida: 0.5, | |
| }); | |
| assert.equal(result.fluxo_cliente.client_id, "extrato_investidor_6"); | |
| assert.ok(result.fluxo_ajustado.length > 10); | |
| assert.ok(typeof result.caixa_maximo_negativo === "number"); | |
| }); | |
| test("simula modo conversao fechado SCP -> imovel + secundario", () => { | |
| const result = simularModoConversaoScpConsorcio({ | |
| client_id: "extrato_investidor_6", | |
| valor_imovel_base: 600000, | |
| desconto_imovel_percentual: 0.15, | |
| percentual_entrada_imovel: 0.25, | |
| agio_consorcio_percentual: 0.1, | |
| taxa_custos_transacao_percentual: 0.02, | |
| fee_percentual: 0.02, | |
| volume_contratado: 120000, | |
| percentual_cartas_parcela_reduzida: 0.5, | |
| }); | |
| assert.ok(result.modo_conversao); | |
| assert.equal(result.modo_conversao.valor_imovel_com_desconto, 510000); | |
| assert.equal(result.modo_conversao.valor_entrada_imovel, 127500); | |
| assert.ok(typeof result.modo_conversao.lucro_projetado_conversao === "number"); | |
| }); | |