import pytest from datetime import datetime from dateutil.relativedelta import relativedelta from src.domain.value_objects.periodo import ( Periodo, mesclar_periodos, anos_completos_periodos, ) class TestPeriodo: def test_periodo_ativo_sem_fim(self): inicio = datetime(2020, 1, 1) periodo = Periodo(inicio=inicio, fim=None) assert periodo.ativo is True def test_periodo_inativo_com_fim(self): inicio = datetime(2020, 1, 1) fim = datetime(2023, 1, 1) periodo = Periodo(inicio=inicio, fim=fim) assert periodo.ativo is False def test_anos_decorridos_3_anos(self): inicio = datetime.now() - relativedelta(years=3) fim = datetime.now() periodo = Periodo(inicio=inicio, fim=fim) assert periodo.anos_decorridos >= 2.9 assert periodo.anos_decorridos <= 3.1 def test_anos_decorridos_periodo_ativo(self): inicio = datetime.now() - relativedelta(years=5) periodo = Periodo(inicio=inicio, fim=None) assert periodo.anos_decorridos >= 4.9 assert periodo.anos_decorridos <= 5.1 def test_anos_completos_retorna_inteiro(self): inicio = datetime(2020, 1, 1) fim = datetime(2023, 6, 15) periodo = Periodo(inicio=inicio, fim=fim) assert periodo.anos_completos() == 3 def test_anos_completos_menos_de_um_ano(self): inicio = datetime.now() - relativedelta(months=6) fim = datetime.now() periodo = Periodo(inicio=inicio, fim=fim) assert periodo.anos_completos() == 0 def test_anos_completos_com_data_referencia(self): inicio = datetime(2020, 1, 1) periodo = Periodo(inicio=inicio, fim=None) data_ref = datetime(2025, 1, 1) assert periodo.anos_completos(data_ref) == 5 def test_fim_anterior_inicio_corrige_para_none(self): inicio = datetime(2023, 1, 1) fim = datetime(2020, 1, 1) periodo = Periodo(inicio=inicio, fim=fim) assert periodo.fim is None assert periodo.ativo is True class TestMesclarPeriodos: def test_lista_vazia_retorna_vazia(self): resultado = mesclar_periodos([]) assert resultado == [] def test_um_periodo_retorna_mesmo(self): periodo = Periodo(datetime(2020, 1, 1), datetime(2023, 1, 1)) resultado = mesclar_periodos([periodo]) assert len(resultado) == 1 assert resultado[0].inicio == periodo.inicio def test_periodos_consecutivos_mesclados(self): p1 = Periodo(datetime(2020, 1, 1), datetime(2022, 1, 1)) p2 = Periodo(datetime(2021, 6, 1), datetime(2024, 1, 1)) resultado = mesclar_periodos([p1, p2]) assert len(resultado) == 1 assert resultado[0].inicio == datetime(2020, 1, 1) assert resultado[0].fim == datetime(2024, 1, 1) def test_periodos_separados_nao_mesclados(self): p1 = Periodo(datetime(2015, 1, 1), datetime(2017, 1, 1)) p2 = Periodo(datetime(2020, 1, 1), datetime(2023, 1, 1)) resultado = mesclar_periodos([p1, p2]) assert len(resultado) == 2 def test_periodo_ativo_preservado(self): p1 = Periodo(datetime(2020, 1, 1), datetime(2022, 1, 1)) p2 = Periodo(datetime(2021, 1, 1), None) resultado = mesclar_periodos([p1, p2]) assert len(resultado) == 1 assert resultado[0].ativo is True def test_tres_periodos_mesclados(self): p1 = Periodo(datetime(2018, 1, 1), datetime(2020, 1, 1)) p2 = Periodo(datetime(2019, 1, 1), datetime(2021, 1, 1)) p3 = Periodo(datetime(2020, 6, 1), datetime(2023, 1, 1)) resultado = mesclar_periodos([p1, p2, p3]) assert len(resultado) == 1 assert resultado[0].inicio == datetime(2018, 1, 1) assert resultado[0].fim == datetime(2023, 1, 1) def test_ordenacao_automatica(self): p1 = Periodo(datetime(2022, 1, 1), datetime(2024, 1, 1)) p2 = Periodo(datetime(2018, 1, 1), datetime(2020, 1, 1)) resultado = mesclar_periodos([p1, p2]) assert resultado[0].inicio == datetime(2018, 1, 1) class TestAnosCompletosPeriodos: def test_lista_vazia_retorna_zero(self): resultado = anos_completos_periodos([]) assert resultado == 0 def test_um_periodo_3_anos(self): periodo = Periodo(datetime(2020, 1, 1), datetime(2023, 1, 1)) resultado = anos_completos_periodos([periodo]) assert resultado == 3 def test_dois_periodos_soma(self): p1 = Periodo(datetime(2015, 1, 1), datetime(2017, 1, 1)) p2 = Periodo(datetime(2020, 1, 1), datetime(2023, 1, 1)) resultado = anos_completos_periodos([p1, p2]) assert resultado == 5 def test_com_data_referencia(self): p1 = Periodo(datetime(2020, 1, 1), None) p2 = Periodo(datetime(2015, 1, 1), datetime(2017, 1, 1)) data_ref = datetime(2025, 1, 1) resultado = anos_completos_periodos([p1, p2], data_ref) assert resultado == 7 class TestCasosEspeciais: def test_periodo_muito_curto(self): inicio = datetime.now() - relativedelta(days=30) fim = datetime.now() periodo = Periodo(inicio=inicio, fim=fim) assert periodo.anos_completos() == 0 def test_periodo_exatamente_um_ano(self): inicio = datetime(2023, 1, 1) fim = datetime(2024, 1, 1) periodo = Periodo(inicio=inicio, fim=fim) assert periodo.anos_completos() == 1 def test_periodo_quase_um_ano(self): inicio = datetime(2023, 1, 1) fim = datetime(2023, 12, 31) periodo = Periodo(inicio=inicio, fim=fim) assert periodo.anos_completos() == 0 def test_mesclagem_periodos_sobrepostos_complexos(self): periodos = [ Periodo(datetime(2010, 1, 1), datetime(2012, 1, 1)), Periodo(datetime(2011, 6, 1), datetime(2014, 1, 1)), Periodo(datetime(2013, 1, 1), datetime(2015, 1, 1)), Periodo(datetime(2018, 1, 1), datetime(2020, 1, 1)), Periodo(datetime(2019, 6, 1), None), ] resultado = mesclar_periodos(periodos) assert len(resultado) == 2 assert resultado[0].fim == datetime(2015, 1, 1) assert resultado[1].ativo is True