Adiciona test/
authorEduardo Elias Camponez <camponez@gmail.com>
Sat, 4 May 2013 16:59:33 +0000 (13:59 -0300)
committerEduardo Elias Camponez <camponez@gmail.com>
Sun, 7 Jul 2013 17:02:55 +0000 (14:02 -0300)
* Adiciona diretório dos testes

src/dirs.py
test/README [new file with mode: 0644]
test/fixtures/aplicacao/dados/34278161174/34278161174.xml [new file with mode: 0644]
test/fixtures/aplicacao/dados/iddeclaracoes.xml [new file with mode: 0644]
test/pytddmon.py [new file with mode: 0644]
test/res [new symlink]
test/run_all_tests.sh [new file with mode: 0644]

index 6b60be0..2647698 100644 (file)
@@ -36,6 +36,11 @@ class IRPFDevelDir(IRPFDir):
         self.resource_dir = "res/"
         self.userdata_dir = "aplicacao/dados/"
 
+class IRPFTestDir(IRPFDir):
+    def __init__(self):
+        self.resource_dir = "res/"
+        self.userdata_dir = "test/fixtures/aplicacao/dados/"
+
 class IRPFInstallDir(IRPFDir):
     def __init__(self):
         self.resource_dir = "/usr/share/irpflivre/res/"
diff --git a/test/README b/test/README
new file mode 100644 (file)
index 0000000..21243fe
--- /dev/null
@@ -0,0 +1,15 @@
+Running the tests
+-----------------
+On root directory of the project run:
+
+    * Simple test:
+
+        bash ./test/run_all_tests.sh
+
+    * Using py.test:
+
+        PYTHONPATH=./src py.test
+
+    * Using pytddmon:
+
+        PYTHONPATH=./src python ./test/pytddmon.py
diff --git a/test/fixtures/aplicacao/dados/34278161174/34278161174.xml b/test/fixtures/aplicacao/dados/34278161174/34278161174.xml
new file mode 100644 (file)
index 0000000..dc287c8
--- /dev/null
@@ -0,0 +1,221 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classe xmlns="http://www.receita.fazenda.gov.br/declaracao" classeJava="serpro.ppgd.irpf.DeclaracaoIRPF" dataHoraSalvamento="30/04/2013 14:27:06">
+    <contribuinte anoObito="" bairro="PEDRO II" bairroExt="" cep="31230-120"
+        cepExt="" cidade="" codigoExterior="" complemento="" complementoExt=""
+        cpfMeeiro="   .   .   -  " dataNascimento="17/11/1972" ddd="31" ddi=""
+        exterior="0" logradouro="Frei Orlando" logradouroExt="" municipio="4123"
+        naturezaOcupacao="01" numero="700" numeroExt="" ocupacaoPrincipal="212" pais="105" telefone="32443214" tipoLogradouro="RUA" tituloEleitor="127315030348" uf="MG"/>
+    <conjuge baseCalculoImposto="0,00" carneComImpComplementar="0,00" cpfConjuge="   .   .   -  " decEntregou="" impRetidoFonte="0,00" rendIsentoNaoTributaveis="0,00" rendPJExigibilidadeSuspensa="0,00" rendSujeitosTribExcl="0,00" resultado="0,00"/>
+    <rendPJ totalRendRecebPessoaJuridica="0,00">
+        <colecaoRendPJTitular niMaiorFontePagadora="02.244.592/0001-12" tipoItens="serpro.ppgd.irpf.rendpj.RendPJTitular" totaisContribuicaoPrevOficial="4.411,23" totaisDecimoTerceiro="2.919,70" totaisImpostoRetidoFonte="2.066,39" totaisRendRecebidoPJ="40.385,40">
+            <item NIFontePagadora="07.114.644/0001-50" contribuicaoPrevOficial="4.411,23" decimoTerceiro="2.919,70" impostoRetidoFonte="2.066,39" nomeFontePagadora="EMPRESA FANTASMA DE TESTE" rendRecebidoPJ="40.385,40"/>
+        </colecaoRendPJTitular>
+        <colecaoRendPJDependente niMaiorFontePagadora="" tipoItens="serpro.ppgd.irpf.rendpj.RendPJDependente" totaisContribuicaoPrevOficial="0,00" totaisDecimoTerceiro="0,00" totaisImpostoRetidoFonte="0,00" totaisRendRecebidoPJ="0,00"/>
+    </rendPJ>
+    <rendPJComExigibilidade>
+        <colecaoRendPJComExigibilidadeTitular tipoItens="serpro.ppgd.irpf.rendpjexigibilidade.RendPJComExigibilidadeTitular" totaisDepositoJudicial="0,00" totaisRendPJExigSuspensa="0,00"/>
+        <colecaoRendPJComExigibilidadeDependente tipoItens="serpro.ppgd.irpf.rendpjexigibilidade.RendPJComExigibilidadeDependente" totaisDepositoJudicial="0,00" totaisRendPJExigSuspensa="0,00"/>
+    </rendPJComExigibilidade>
+    <rendPFTitular totalDarfPago="0,00" totalDependentes="0,00" totalExterior="0,00" totalLivroCaixa="0,00" totalPensao="0,00" totalPessoaFisica="0,00" totalPrevidencia="0,00">
+        <janeiro carneLeao="0,00" darfPago="0,00" dependentes="0,00" exterior="0,00" livroCaixa="0,00" mes="0" pensao="0,00" pessoaFisica="0,00" previdencia="0,00"/>
+        <fevereiro carneLeao="0,00" darfPago="0,00" dependentes="0,00" exterior="0,00" livroCaixa="0,00" mes="0" pensao="0,00" pessoaFisica="0,00" previdencia="0,00"/>
+        <marco carneLeao="0,00" darfPago="0,00" dependentes="0,00" exterior="0,00" livroCaixa="0,00" mes="0" pensao="0,00" pessoaFisica="0,00" previdencia="0,00"/>
+        <abril carneLeao="0,00" darfPago="0,00" dependentes="0,00" exterior="0,00" livroCaixa="0,00" mes="0" pensao="0,00" pessoaFisica="0,00" previdencia="0,00"/>
+        <maio carneLeao="0,00" darfPago="0,00" dependentes="0,00" exterior="0,00" livroCaixa="0,00" mes="0" pensao="0,00" pessoaFisica="0,00" previdencia="0,00"/>
+        <junho carneLeao="0,00" darfPago="0,00" dependentes="0,00" exterior="0,00" livroCaixa="0,00" mes="0" pensao="0,00" pessoaFisica="0,00" previdencia="0,00"/>
+        <julho carneLeao="0,00" darfPago="0,00" dependentes="0,00" exterior="0,00" livroCaixa="0,00" mes="0" pensao="0,00" pessoaFisica="0,00" previdencia="0,00"/>
+        <agosto carneLeao="0,00" darfPago="0,00" dependentes="0,00" exterior="0,00" livroCaixa="0,00" mes="0" pensao="0,00" pessoaFisica="0,00" previdencia="0,00"/>
+        <setembro carneLeao="0,00" darfPago="0,00" dependentes="0,00" exterior="0,00" livroCaixa="0,00" mes="0" pensao="0,00" pessoaFisica="0,00" previdencia="0,00"/>
+        <outubro carneLeao="0,00" darfPago="0,00" dependentes="0,00" exterior="0,00" livroCaixa="0,00" mes="0" pensao="0,00" pessoaFisica="0,00" previdencia="0,00"/>
+        <novembro carneLeao="0,00" darfPago="0,00" dependentes="0,00" exterior="0,00" livroCaixa="0,00" mes="0" pensao="0,00" pessoaFisica="0,00" previdencia="0,00"/>
+        <dezembro carneLeao="0,00" darfPago="0,00" dependentes="0,00" exterior="0,00" livroCaixa="0,00" mes="0" pensao="0,00" pessoaFisica="0,00" previdencia="0,00"/>
+    </rendPFTitular>
+    <rendPFDependente tipoItens="serpro.ppgd.irpf.rendpf.ItemRendPFDependente" totalDarfPago="0,00" totalDependentes="0,00" totalExterior="0,00" totalLivroCaixa="0,00" totalPensao="0,00" totalPessoaFisica="0,00" totalPrevidencia="0,00"/>
+    <rendAcm totalRendRecebAcumuladamente="0,00">
+        <colecaoRendAcmTitular tipoItens="serpro.ppgd.irpf.rendacm.RendAcmTitular" totaisContribuicaoPrevOficial="0,00" totaisContribuicaoPrevOficialAjuste="0,00" totaisContribuicaoPrevOficialExclusiva="0,00" totaisImpostoDevidoRRA="0,00" totaisImpostoRetidoFonte="0,00" totaisImpostoRetidoFonteAjuste="0,00" totaisImpostoRetidoFonteExclusiva="0,00" totaisPensaoAlimenticia="0,00" totaisPensaoAlimenticiaAjuste="0,00" totaisPensaoAlimenticiaExclusiva="0,00" totaisRendRecebidos="0,00" totaisRendRecebidosAjuste="0,00" totaisRendRecebidosExclusiva="0,00"/>
+        <colecaoRendAcmDependente tipoItens="serpro.ppgd.irpf.rendacm.RendAcmDependente" totaisContribuicaoPrevOficial="0,00" totaisContribuicaoPrevOficialAjuste="0,00" totaisContribuicaoPrevOficialExclusiva="0,00" totaisImpostoDevidoRRA="0,00" totaisImpostoRetidoFonte="0,00" totaisImpostoRetidoFonteAjuste="0,00" totaisImpostoRetidoFonteExclusiva="0,00" totaisPensaoAlimenticia="0,00" totaisPensaoAlimenticiaAjuste="0,00" totaisPensaoAlimenticiaExclusiva="0,00" totaisRendRecebidos="0,00" totaisRendRecebidosAjuste="0,00" totaisRendRecebidosExclusiva="0,00"/>
+    </rendAcm>
+    <rendIsentos bensPequenoValorInformado="0,00" bensPequenoValorTransportado="0,00" bolsaEstudos="0,00" capitalApolices="0,00" descOutros="" impostoRendasAnterioresCompensadoJudicialmente="0,00" incorporacaoReservaCapital="0,00" indenizacoes="0,00" lucroAlienacao="0,00" lucroRecebido="0,00" moedaEstrangeiraEspecieInformado="0,00" outros="0,00" outrosBensImoveisGCAPTransportado="0,00" outrosBensImoveisInformado="0,00" outrosBensImoveisMETransportado="0,00" outrosBensImoveisTransportado="0,00" parcIsentaAposentadoria="0,00" parcIsentaAtivRural="0,00" pensao="0,00" poupanca="520,98" rendAssalariadosMoedaEstrangeira="0,00" rendDependentes="0,00" rendSocio="0,00" total="520,98" totalInformado="0,00" totalTransportado="0,00" transferencias="0,00" unicoImovelInformado="0,00" unicoImovelTransportado="0,00">
+        <lucroRecebidoQuadroAuxiliar tipoItens="serpro.ppgd.irpf.ItemQuadroTransporteDetalhado" totais="0,00"/>
+        <pensaoQuadroAuxiliar tipoItens="serpro.ppgd.irpf.ItemQuadroTransporteDetalhado" totais="0,00"/>
+        <poupancaQuadroAuxiliar tipoItens="serpro.ppgd.irpf.ItemQuadroAuxiliar" totais="520,98">
+            <item especificacao="Petrobrás dividendos" valor="6,63"/>
+            <item especificacao="Itau" valor="431,55"/>
+            <item especificacao="Santander" valor="17,64"/>
+            <item especificacao="Bradesco" valor="65,16"/>
+        </poupancaQuadroAuxiliar>
+        <rendAssalariadoMoedaEstrangeiraQuadroAuxiliar tipoItens="serpro.ppgd.irpf.ItemQuadroTransporteDetalhado" totais="0,00"/>
+        <incorporacaoReservaCapitalQuadroAuxiliar tipoItens="serpro.ppgd.irpf.ItemQuadroTransporteDetalhado" totais="0,00"/>
+        <outrosQuadroAuxiliar tipoItens="serpro.ppgd.irpf.ItemQuadroAuxiliar" totais="0,00"/>
+        <rendDependentesQuadroAuxiliar tipoItens="serpro.ppgd.irpf.ItemQuadroAuxiliar" totais="0,00"/>
+    </rendIsentos>
+    <rendTributacaoExclusiva decimoTerceiro="2.919,70" decimoTerceiroDependentes="0,00" descTotal="" descTotalDependentes="" ganhosCapital="0,00" ganhosCapitalEmEspecie="0,00" ganhosCapitalEstrangeira="0,00" ganhosRendaVariavel="0,00" outros="0,00" outrosDependentes="0,00" rendAplicacoes="706,57" rraDependentes="0,00" rraTitular="0,00" total="3.626,27">
+        <rendAplicacoesQuadroAuxiliar tipoItens="serpro.ppgd.irpf.ItemQuadroAuxiliar" totais="706,57">
+            <item especificacao="Petrobras" valor="64,62"/>
+            <item especificacao="Itau Fundos" valor="602,05"/>
+            <item especificacao="Santander" valor="39,90"/>
+        </rendAplicacoesQuadroAuxiliar>
+        <outrosQuadroAuxiliar tipoItens="serpro.ppgd.irpf.ItemQuadroAuxiliar" totais="0,00"/>
+        <outrosDependentesQuadroAuxiliar tipoItens="serpro.ppgd.irpf.ItemQuadroAuxiliar" totais="0,00"/>
+    </rendTributacaoExclusiva>
+    <impostoPago carneLeaoDependentes="0,00" carneLeaoTitular="0,00" impostoComplementar="0,00" impostoDevidoComRendExterior="0,00" impostoDevidoSemRendExterior="0,00" impostoPagoExterior="0,00" impostoRetidoFonte="0,00" impostoRetidoFonteDependentes="0,00" impostoRetidoFonteTitular="2.066,39" limiteImpPagoExterior="0,00"/>
+    <dependentes tipoItens="serpro.ppgd.irpf.dependentes.Dependente"/>
+    <alimentandos tipoItens="serpro.ppgd.irpf.alimentandos.Alimentando"/>
+    <herdeiros tipoItens="serpro.ppgd.irpf.herdeiros.Herdeiro"/>
+    <pagamentos tipoItens="serpro.ppgd.irpf.pagamentos.Pagamento" totalContribEmpregadoDomestico="0,00" totalContribuicaoFAPI="0,00" totalDeducaoIncentivo="0,00" totalDeducoesInstrucao="0,00" totalDespesasMedicas="0,00" totalPensao="0,00" totalPensaoCartoral="0,00" ultimoIndiceGerado=""/>
+    <bens tipoItens="serpro.ppgd.irpf.bens.Bem" totalExercicioAnterior="5.200,00" totalExercicioAtual="0,00" ultimoIndiceGerado="0">
+        <item areaTotal="0,0" bairro="" cep="" cidade="" codigo="45" complemento="" discriminacao="CDB" indice="4" logradouro="" matricula="" municipio="" nomeCartorio="" nomeMunicipio="" nomePais="Brasil" numero="" pais="105" registrado="2" registro="" uf="" unidade="2" valorExercicioAnterior="5.200,00" valorExercicioAtual="0,00">
+            <participacoesInventario tipoItens="serpro.ppgd.irpf.bens.ItemPercentualParticipacaoInventario" totalPercentual="0,00"/>
+        </item>
+    </bens>
+    <dividas tipoItens="serpro.ppgd.irpf.dividas.Divida" totalExercicioAnterior="0,00" totalExercicioAtual="0,00" ultimoIndiceGerado=""/>
+    <espolio comarca="" cpfInventariante="   .   .   -  " dtDecisaoJud="  /  /    " dtTransito="  /  /    " endInventariante="" idVaraCivil="" nomeInventariante="" numProcessoJudicial="" tipoJudicial="1" uf="">
+        <escrituracaoPublica cnpjCartorio="" dataLavratura="  /  /    " folhas="" livro="" municipio="" nome="" uf=""/>
+    </espolio>
+    <resumo>
+        <outrasInformacoes bensDireitosExercicioAnterior="5.200,00" bensDireitosExercicioAtual="0,00" depositosJudiciais="0,00" dividasOnusReaisExercicioAnterior="0,00" dividasOnusReaisExercicioAtual="0,00" impostoPagoGCAP="0,00" impostoPagoME="0,00" impostoPagoSobreRendaVariavel="0,00" informacoesConjuge="0,00" rendIsentosNaoTributaveis="520,98" rendIsentosTributacaoExclusiva="3.626,27" rendTributaveisExigibilidadeSuspensa="0,00" totalDoacoesCampanhasEleitorais="0,00" totalImpostoRetidoNaFonte="0,00"/>
+        <calculoImposto agencia="3055" banco="341" baseCalculo="32.308,32" carneLeaoDependentes="0,00" carneLeaoTitular="0,00" contaCredito="11198" debitoAutomatico="N" deducaoIncentivo="0,00" descontoSimplificado="8.077,08" dvAgencia="" dvContaCredito="7" imposto="2.026,74" impostoComplementar="0,00" impostoDevido="1.474,93" impostoDevidoI="1.474,93" impostoDevidoII="1.474,93" impostoDevidoRRA="0,00" impostoEspecie="0,00" impostoPagoExterior="0,00" impostoRestituir="591,46" impostoRetidoFonteDependentes="0,00" impostoRetidoFonteLei11033="0,00" impostoRetidoFonteTitular="2.066,39" impostoRetidoRRA="0,00" indicadorPrimeiraQuota="" numQuotas="0" rendAcmDependentes="0,00" rendAcmTitular="0,00" rendPFEXTRecebidoDependentes="0,00" rendPFEXTRecebidoTitular="0,00" rendPJRecebidoDependentes="0,00" rendPJRecebidoTitular="40.385,40" resultadoTributavelAR="0,00" saldoImpostoPagar="0,00" totalContribEmpregadoDomestico="0,00" totalImpostoPago="2.066,39" totalResultadosTributaveis="40.385,40" valorQuota="0,00">
+            <identificadorDec cpf="342.781.611-74" dataUltimoAcesso="30/04/2013 14:28:09" declaracaoRetificadora="0" enderecoDiferente="0" exercicio="2011" nome="MARIA DA SILVA DE SOUZA" numReciboDecRetif="" numeroReciboDecAnterior="401917396500" resultadoDeclaracao="IAR" tipoDeclaracao="1" tipoDeclaracaoAES="A" transmitida="0"/>
+        </calculoImposto>
+        <rendimentosTributaveisDeducoes dependentes="0,00" despesasInstrucao="0,00" despesasMedicas="0,00" livroCaixa="0,00" pensaoAlimenticia="0,00" pensaoAlimenticiaRRA="0,00" pensaoCartoral="0,00" previdenciaFAPI="0,00" previdenciaOficial="4.411,23" previdenciaOficialRRA="0,00" rendRecebidoAcmDependentes="0,00" rendRecebidoAcmTitular="0,00" rendRecebidoPFEXTDependentes="0,00" rendRecebidoPFEXTTitular="0,00" rendRecebidoPJDependentes="0,00" rendRecebidoPJTitular="40.385,40" rendTributavelAR="0,00" totalDeducoes="4.411,23" totalRendimentos="44.532,65"/>
+        <identificadorDeclaracao cpf="342.781.611-74" dataUltimoAcesso="30/04/2013 14:28:09" declaracaoRetificadora="0" enderecoDiferente="0" exercicio="2011" nome="MARIA DA SILVA DE SOUZA" numReciboDecRetif="" numeroReciboDecAnterior="401917396500" resultadoDeclaracao="IAR" tipoDeclaracao="1" tipoDeclaracaoAES="A" transmitida="0"/>
+    </resumo>
+    <comparativo baseCalcCompleta="35.974,17" baseCalcSimplificada="32.308,32" impRestituirCompleta="39,65" impRestituirSimplificada="591,46" saldoPagarCompleta="0,00" saldoPagarSimplificada="0,00" totalRendTribCompleta="40.385,40" totalRendTribSimplificada="40.385,40"/>
+    <doacoes tipoItens="serpro.ppgd.irpf.eleicoes.Doacao" totalDoacoes="0,00"/>
+    <saida cpfProcurador="   .   .   -  " dtCondicaoNaoResidente="  /  /    " dtCondicaoResidente="  /  /    " endProcurador="" nomeProcurador=""/>
+    <rendaVariavel totalBaseCalculo="0,00" totalIRFonteDayTrade="0,00" totalImpostoPago="0,00" totalImpostoPagoComFundInvest="0,00" totalImpostoRetidoFonteLei11033="0,00">
+        <janeiro impostoApagar="0,00" impostoPago="0,00" impostoRetidoFonteLei11033="0,00" impostoRetidoFonteLei11033MesesAnteriores="0,00" impostoRetidoFonteLei11033MesesCompensar="0,00" irFonteDayTradeAcompensar="0,00" irFonteDayTradeMesAtual="0,00" irFonteDayTradeMesesAnteriores="0,00" totalImpostoDevido="0,00">
+            <operacoesComuns aliquotaDoImposto="15%" baseCalculoImposto="0,00" impostoDevido="0,00" mercadoFuturoDolar="0,00" mercadoFuturoIndices="0,00" mercadoFuturoJuros="0,00" mercadoFuturoOutros="0,00" mercadoOpcoesAcoes="0,00" mercadoOpcoesForaDeBolsa="0,00" mercadoOpcoesOuro="0,00" mercadoOpcoesOutros="0,00" mercadoTermoAcoes="0,00" mercadoTermoOutros="0,00" mercadoVistaAcoes="0,00" mercadoVistaForaBolsa="0,00" mercadoVistaOuro="0,00" prejuizoCompensar="0,00" resultadoLiquidoMes="0,00" resultadoNegativoMesAnterior="0,00"/>
+            <operacoesDayTrade aliquotaDoImposto="20%" baseCalculoImposto="0,00" impostoDevido="0,00" mercadoFuturoDolar="0,00" mercadoFuturoIndices="0,00" mercadoFuturoJuros="0,00" mercadoFuturoOutros="0,00" mercadoOpcoesAcoes="0,00" mercadoOpcoesForaDeBolsa="0,00" mercadoOpcoesOuro="0,00" mercadoOpcoesOutros="0,00" mercadoTermoAcoes="0,00" mercadoTermoOutros="0,00" mercadoVistaAcoes="0,00" mercadoVistaForaBolsa="0,00" mercadoVistaOuro="0,00" prejuizoCompensar="0,00" resultadoLiquidoMes="0,00" resultadoNegativoMesAnterior="0,00"/>
+            <colecaoItemImpostoPagar tipoItens="serpro.ppgd.irpf.rendavariavel.ItemImpostoPagar" total="0,00"/>
+        </janeiro>
+        <fevereiro impostoApagar="0,00" impostoPago="0,00" impostoRetidoFonteLei11033="0,00" impostoRetidoFonteLei11033MesesAnteriores="0,00" impostoRetidoFonteLei11033MesesCompensar="0,00" irFonteDayTradeAcompensar="0,00" irFonteDayTradeMesAtual="0,00" irFonteDayTradeMesesAnteriores="0,00" totalImpostoDevido="0,00">
+            <operacoesComuns aliquotaDoImposto="15%" baseCalculoImposto="0,00" impostoDevido="0,00" mercadoFuturoDolar="0,00" mercadoFuturoIndices="0,00" mercadoFuturoJuros="0,00" mercadoFuturoOutros="0,00" mercadoOpcoesAcoes="0,00" mercadoOpcoesForaDeBolsa="0,00" mercadoOpcoesOuro="0,00" mercadoOpcoesOutros="0,00" mercadoTermoAcoes="0,00" mercadoTermoOutros="0,00" mercadoVistaAcoes="0,00" mercadoVistaForaBolsa="0,00" mercadoVistaOuro="0,00" prejuizoCompensar="0,00" resultadoLiquidoMes="0,00" resultadoNegativoMesAnterior="0,00"/>
+            <operacoesDayTrade aliquotaDoImposto="20%" baseCalculoImposto="0,00" impostoDevido="0,00" mercadoFuturoDolar="0,00" mercadoFuturoIndices="0,00" mercadoFuturoJuros="0,00" mercadoFuturoOutros="0,00" mercadoOpcoesAcoes="0,00" mercadoOpcoesForaDeBolsa="0,00" mercadoOpcoesOuro="0,00" mercadoOpcoesOutros="0,00" mercadoTermoAcoes="0,00" mercadoTermoOutros="0,00" mercadoVistaAcoes="0,00" mercadoVistaForaBolsa="0,00" mercadoVistaOuro="0,00" prejuizoCompensar="0,00" resultadoLiquidoMes="0,00" resultadoNegativoMesAnterior="0,00"/>
+            <colecaoItemImpostoPagar tipoItens="serpro.ppgd.irpf.rendavariavel.ItemImpostoPagar" total="0,00"/>
+        </fevereiro>
+        <marco impostoApagar="0,00" impostoPago="0,00" impostoRetidoFonteLei11033="0,00" impostoRetidoFonteLei11033MesesAnteriores="0,00" impostoRetidoFonteLei11033MesesCompensar="0,00" irFonteDayTradeAcompensar="0,00" irFonteDayTradeMesAtual="0,00" irFonteDayTradeMesesAnteriores="0,00" totalImpostoDevido="0,00">
+            <operacoesComuns aliquotaDoImposto="15%" baseCalculoImposto="0,00" impostoDevido="0,00" mercadoFuturoDolar="0,00" mercadoFuturoIndices="0,00" mercadoFuturoJuros="0,00" mercadoFuturoOutros="0,00" mercadoOpcoesAcoes="0,00" mercadoOpcoesForaDeBolsa="0,00" mercadoOpcoesOuro="0,00" mercadoOpcoesOutros="0,00" mercadoTermoAcoes="0,00" mercadoTermoOutros="0,00" mercadoVistaAcoes="0,00" mercadoVistaForaBolsa="0,00" mercadoVistaOuro="0,00" prejuizoCompensar="0,00" resultadoLiquidoMes="0,00" resultadoNegativoMesAnterior="0,00"/>
+            <operacoesDayTrade aliquotaDoImposto="20%" baseCalculoImposto="0,00" impostoDevido="0,00" mercadoFuturoDolar="0,00" mercadoFuturoIndices="0,00" mercadoFuturoJuros="0,00" mercadoFuturoOutros="0,00" mercadoOpcoesAcoes="0,00" mercadoOpcoesForaDeBolsa="0,00" mercadoOpcoesOuro="0,00" mercadoOpcoesOutros="0,00" mercadoTermoAcoes="0,00" mercadoTermoOutros="0,00" mercadoVistaAcoes="0,00" mercadoVistaForaBolsa="0,00" mercadoVistaOuro="0,00" prejuizoCompensar="0,00" resultadoLiquidoMes="0,00" resultadoNegativoMesAnterior="0,00"/>
+            <colecaoItemImpostoPagar tipoItens="serpro.ppgd.irpf.rendavariavel.ItemImpostoPagar" total="0,00"/>
+        </marco>
+        <abril impostoApagar="0,00" impostoPago="0,00" impostoRetidoFonteLei11033="0,00" impostoRetidoFonteLei11033MesesAnteriores="0,00" impostoRetidoFonteLei11033MesesCompensar="0,00" irFonteDayTradeAcompensar="0,00" irFonteDayTradeMesAtual="0,00" irFonteDayTradeMesesAnteriores="0,00" totalImpostoDevido="0,00">
+            <operacoesComuns aliquotaDoImposto="15%" baseCalculoImposto="0,00" impostoDevido="0,00" mercadoFuturoDolar="0,00" mercadoFuturoIndices="0,00" mercadoFuturoJuros="0,00" mercadoFuturoOutros="0,00" mercadoOpcoesAcoes="0,00" mercadoOpcoesForaDeBolsa="0,00" mercadoOpcoesOuro="0,00" mercadoOpcoesOutros="0,00" mercadoTermoAcoes="0,00" mercadoTermoOutros="0,00" mercadoVistaAcoes="0,00" mercadoVistaForaBolsa="0,00" mercadoVistaOuro="0,00" prejuizoCompensar="0,00" resultadoLiquidoMes="0,00" resultadoNegativoMesAnterior="0,00"/>
+            <operacoesDayTrade aliquotaDoImposto="20%" baseCalculoImposto="0,00" impostoDevido="0,00" mercadoFuturoDolar="0,00" mercadoFuturoIndices="0,00" mercadoFuturoJuros="0,00" mercadoFuturoOutros="0,00" mercadoOpcoesAcoes="0,00" mercadoOpcoesForaDeBolsa="0,00" mercadoOpcoesOuro="0,00" mercadoOpcoesOutros="0,00" mercadoTermoAcoes="0,00" mercadoTermoOutros="0,00" mercadoVistaAcoes="0,00" mercadoVistaForaBolsa="0,00" mercadoVistaOuro="0,00" prejuizoCompensar="0,00" resultadoLiquidoMes="0,00" resultadoNegativoMesAnterior="0,00"/>
+            <colecaoItemImpostoPagar tipoItens="serpro.ppgd.irpf.rendavariavel.ItemImpostoPagar" total="0,00"/>
+        </abril>
+        <maio impostoApagar="0,00" impostoPago="0,00" impostoRetidoFonteLei11033="0,00" impostoRetidoFonteLei11033MesesAnteriores="0,00" impostoRetidoFonteLei11033MesesCompensar="0,00" irFonteDayTradeAcompensar="0,00" irFonteDayTradeMesAtual="0,00" irFonteDayTradeMesesAnteriores="0,00" totalImpostoDevido="0,00">
+            <operacoesComuns aliquotaDoImposto="15%" baseCalculoImposto="0,00" impostoDevido="0,00" mercadoFuturoDolar="0,00" mercadoFuturoIndices="0,00" mercadoFuturoJuros="0,00" mercadoFuturoOutros="0,00" mercadoOpcoesAcoes="0,00" mercadoOpcoesForaDeBolsa="0,00" mercadoOpcoesOuro="0,00" mercadoOpcoesOutros="0,00" mercadoTermoAcoes="0,00" mercadoTermoOutros="0,00" mercadoVistaAcoes="0,00" mercadoVistaForaBolsa="0,00" mercadoVistaOuro="0,00" prejuizoCompensar="0,00" resultadoLiquidoMes="0,00" resultadoNegativoMesAnterior="0,00"/>
+            <operacoesDayTrade aliquotaDoImposto="20%" baseCalculoImposto="0,00" impostoDevido="0,00" mercadoFuturoDolar="0,00" mercadoFuturoIndices="0,00" mercadoFuturoJuros="0,00" mercadoFuturoOutros="0,00" mercadoOpcoesAcoes="0,00" mercadoOpcoesForaDeBolsa="0,00" mercadoOpcoesOuro="0,00" mercadoOpcoesOutros="0,00" mercadoTermoAcoes="0,00" mercadoTermoOutros="0,00" mercadoVistaAcoes="0,00" mercadoVistaForaBolsa="0,00" mercadoVistaOuro="0,00" prejuizoCompensar="0,00" resultadoLiquidoMes="0,00" resultadoNegativoMesAnterior="0,00"/>
+            <colecaoItemImpostoPagar tipoItens="serpro.ppgd.irpf.rendavariavel.ItemImpostoPagar" total="0,00"/>
+        </maio>
+        <junho impostoApagar="0,00" impostoPago="0,00" impostoRetidoFonteLei11033="0,00" impostoRetidoFonteLei11033MesesAnteriores="0,00" impostoRetidoFonteLei11033MesesCompensar="0,00" irFonteDayTradeAcompensar="0,00" irFonteDayTradeMesAtual="0,00" irFonteDayTradeMesesAnteriores="0,00" totalImpostoDevido="0,00">
+            <operacoesComuns aliquotaDoImposto="15%" baseCalculoImposto="0,00" impostoDevido="0,00" mercadoFuturoDolar="0,00" mercadoFuturoIndices="0,00" mercadoFuturoJuros="0,00" mercadoFuturoOutros="0,00" mercadoOpcoesAcoes="0,00" mercadoOpcoesForaDeBolsa="0,00" mercadoOpcoesOuro="0,00" mercadoOpcoesOutros="0,00" mercadoTermoAcoes="0,00" mercadoTermoOutros="0,00" mercadoVistaAcoes="0,00" mercadoVistaForaBolsa="0,00" mercadoVistaOuro="0,00" prejuizoCompensar="0,00" resultadoLiquidoMes="0,00" resultadoNegativoMesAnterior="0,00"/>
+            <operacoesDayTrade aliquotaDoImposto="20%" baseCalculoImposto="0,00" impostoDevido="0,00" mercadoFuturoDolar="0,00" mercadoFuturoIndices="0,00" mercadoFuturoJuros="0,00" mercadoFuturoOutros="0,00" mercadoOpcoesAcoes="0,00" mercadoOpcoesForaDeBolsa="0,00" mercadoOpcoesOuro="0,00" mercadoOpcoesOutros="0,00" mercadoTermoAcoes="0,00" mercadoTermoOutros="0,00" mercadoVistaAcoes="0,00" mercadoVistaForaBolsa="0,00" mercadoVistaOuro="0,00" prejuizoCompensar="0,00" resultadoLiquidoMes="0,00" resultadoNegativoMesAnterior="0,00"/>
+            <colecaoItemImpostoPagar tipoItens="serpro.ppgd.irpf.rendavariavel.ItemImpostoPagar" total="0,00"/>
+        </junho>
+        <julho impostoApagar="0,00" impostoPago="0,00" impostoRetidoFonteLei11033="0,00" impostoRetidoFonteLei11033MesesAnteriores="0,00" impostoRetidoFonteLei11033MesesCompensar="0,00" irFonteDayTradeAcompensar="0,00" irFonteDayTradeMesAtual="0,00" irFonteDayTradeMesesAnteriores="0,00" totalImpostoDevido="0,00">
+            <operacoesComuns aliquotaDoImposto="15%" baseCalculoImposto="0,00" impostoDevido="0,00" mercadoFuturoDolar="0,00" mercadoFuturoIndices="0,00" mercadoFuturoJuros="0,00" mercadoFuturoOutros="0,00" mercadoOpcoesAcoes="0,00" mercadoOpcoesForaDeBolsa="0,00" mercadoOpcoesOuro="0,00" mercadoOpcoesOutros="0,00" mercadoTermoAcoes="0,00" mercadoTermoOutros="0,00" mercadoVistaAcoes="0,00" mercadoVistaForaBolsa="0,00" mercadoVistaOuro="0,00" prejuizoCompensar="0,00" resultadoLiquidoMes="0,00" resultadoNegativoMesAnterior="0,00"/>
+            <operacoesDayTrade aliquotaDoImposto="20%" baseCalculoImposto="0,00" impostoDevido="0,00" mercadoFuturoDolar="0,00" mercadoFuturoIndices="0,00" mercadoFuturoJuros="0,00" mercadoFuturoOutros="0,00" mercadoOpcoesAcoes="0,00" mercadoOpcoesForaDeBolsa="0,00" mercadoOpcoesOuro="0,00" mercadoOpcoesOutros="0,00" mercadoTermoAcoes="0,00" mercadoTermoOutros="0,00" mercadoVistaAcoes="0,00" mercadoVistaForaBolsa="0,00" mercadoVistaOuro="0,00" prejuizoCompensar="0,00" resultadoLiquidoMes="0,00" resultadoNegativoMesAnterior="0,00"/>
+            <colecaoItemImpostoPagar tipoItens="serpro.ppgd.irpf.rendavariavel.ItemImpostoPagar" total="0,00"/>
+        </julho>
+        <agosto impostoApagar="0,00" impostoPago="0,00" impostoRetidoFonteLei11033="0,00" impostoRetidoFonteLei11033MesesAnteriores="0,00" impostoRetidoFonteLei11033MesesCompensar="0,00" irFonteDayTradeAcompensar="0,00" irFonteDayTradeMesAtual="0,00" irFonteDayTradeMesesAnteriores="0,00" totalImpostoDevido="0,00">
+            <operacoesComuns aliquotaDoImposto="15%" baseCalculoImposto="0,00" impostoDevido="0,00" mercadoFuturoDolar="0,00" mercadoFuturoIndices="0,00" mercadoFuturoJuros="0,00" mercadoFuturoOutros="0,00" mercadoOpcoesAcoes="0,00" mercadoOpcoesForaDeBolsa="0,00" mercadoOpcoesOuro="0,00" mercadoOpcoesOutros="0,00" mercadoTermoAcoes="0,00" mercadoTermoOutros="0,00" mercadoVistaAcoes="0,00" mercadoVistaForaBolsa="0,00" mercadoVistaOuro="0,00" prejuizoCompensar="0,00" resultadoLiquidoMes="0,00" resultadoNegativoMesAnterior="0,00"/>
+            <operacoesDayTrade aliquotaDoImposto="20%" baseCalculoImposto="0,00" impostoDevido="0,00" mercadoFuturoDolar="0,00" mercadoFuturoIndices="0,00" mercadoFuturoJuros="0,00" mercadoFuturoOutros="0,00" mercadoOpcoesAcoes="0,00" mercadoOpcoesForaDeBolsa="0,00" mercadoOpcoesOuro="0,00" mercadoOpcoesOutros="0,00" mercadoTermoAcoes="0,00" mercadoTermoOutros="0,00" mercadoVistaAcoes="0,00" mercadoVistaForaBolsa="0,00" mercadoVistaOuro="0,00" prejuizoCompensar="0,00" resultadoLiquidoMes="0,00" resultadoNegativoMesAnterior="0,00"/>
+            <colecaoItemImpostoPagar tipoItens="serpro.ppgd.irpf.rendavariavel.ItemImpostoPagar" total="0,00"/>
+        </agosto>
+        <setembro impostoApagar="0,00" impostoPago="0,00" impostoRetidoFonteLei11033="0,00" impostoRetidoFonteLei11033MesesAnteriores="0,00" impostoRetidoFonteLei11033MesesCompensar="0,00" irFonteDayTradeAcompensar="0,00" irFonteDayTradeMesAtual="0,00" irFonteDayTradeMesesAnteriores="0,00" totalImpostoDevido="0,00">
+            <operacoesComuns aliquotaDoImposto="15%" baseCalculoImposto="0,00" impostoDevido="0,00" mercadoFuturoDolar="0,00" mercadoFuturoIndices="0,00" mercadoFuturoJuros="0,00" mercadoFuturoOutros="0,00" mercadoOpcoesAcoes="0,00" mercadoOpcoesForaDeBolsa="0,00" mercadoOpcoesOuro="0,00" mercadoOpcoesOutros="0,00" mercadoTermoAcoes="0,00" mercadoTermoOutros="0,00" mercadoVistaAcoes="0,00" mercadoVistaForaBolsa="0,00" mercadoVistaOuro="0,00" prejuizoCompensar="0,00" resultadoLiquidoMes="0,00" resultadoNegativoMesAnterior="0,00"/>
+            <operacoesDayTrade aliquotaDoImposto="20%" baseCalculoImposto="0,00" impostoDevido="0,00" mercadoFuturoDolar="0,00" mercadoFuturoIndices="0,00" mercadoFuturoJuros="0,00" mercadoFuturoOutros="0,00" mercadoOpcoesAcoes="0,00" mercadoOpcoesForaDeBolsa="0,00" mercadoOpcoesOuro="0,00" mercadoOpcoesOutros="0,00" mercadoTermoAcoes="0,00" mercadoTermoOutros="0,00" mercadoVistaAcoes="0,00" mercadoVistaForaBolsa="0,00" mercadoVistaOuro="0,00" prejuizoCompensar="0,00" resultadoLiquidoMes="0,00" resultadoNegativoMesAnterior="0,00"/>
+            <colecaoItemImpostoPagar tipoItens="serpro.ppgd.irpf.rendavariavel.ItemImpostoPagar" total="0,00"/>
+        </setembro>
+        <outubro impostoApagar="0,00" impostoPago="0,00" impostoRetidoFonteLei11033="0,00" impostoRetidoFonteLei11033MesesAnteriores="0,00" impostoRetidoFonteLei11033MesesCompensar="0,00" irFonteDayTradeAcompensar="0,00" irFonteDayTradeMesAtual="0,00" irFonteDayTradeMesesAnteriores="0,00" totalImpostoDevido="0,00">
+            <operacoesComuns aliquotaDoImposto="15%" baseCalculoImposto="0,00" impostoDevido="0,00" mercadoFuturoDolar="0,00" mercadoFuturoIndices="0,00" mercadoFuturoJuros="0,00" mercadoFuturoOutros="0,00" mercadoOpcoesAcoes="0,00" mercadoOpcoesForaDeBolsa="0,00" mercadoOpcoesOuro="0,00" mercadoOpcoesOutros="0,00" mercadoTermoAcoes="0,00" mercadoTermoOutros="0,00" mercadoVistaAcoes="0,00" mercadoVistaForaBolsa="0,00" mercadoVistaOuro="0,00" prejuizoCompensar="0,00" resultadoLiquidoMes="0,00" resultadoNegativoMesAnterior="0,00"/>
+            <operacoesDayTrade aliquotaDoImposto="20%" baseCalculoImposto="0,00" impostoDevido="0,00" mercadoFuturoDolar="0,00" mercadoFuturoIndices="0,00" mercadoFuturoJuros="0,00" mercadoFuturoOutros="0,00" mercadoOpcoesAcoes="0,00" mercadoOpcoesForaDeBolsa="0,00" mercadoOpcoesOuro="0,00" mercadoOpcoesOutros="0,00" mercadoTermoAcoes="0,00" mercadoTermoOutros="0,00" mercadoVistaAcoes="0,00" mercadoVistaForaBolsa="0,00" mercadoVistaOuro="0,00" prejuizoCompensar="0,00" resultadoLiquidoMes="0,00" resultadoNegativoMesAnterior="0,00"/>
+            <colecaoItemImpostoPagar tipoItens="serpro.ppgd.irpf.rendavariavel.ItemImpostoPagar" total="0,00"/>
+        </outubro>
+        <novembro impostoApagar="0,00" impostoPago="0,00" impostoRetidoFonteLei11033="0,00" impostoRetidoFonteLei11033MesesAnteriores="0,00" impostoRetidoFonteLei11033MesesCompensar="0,00" irFonteDayTradeAcompensar="0,00" irFonteDayTradeMesAtual="0,00" irFonteDayTradeMesesAnteriores="0,00" totalImpostoDevido="0,00">
+            <operacoesComuns aliquotaDoImposto="15%" baseCalculoImposto="0,00" impostoDevido="0,00" mercadoFuturoDolar="0,00" mercadoFuturoIndices="0,00" mercadoFuturoJuros="0,00" mercadoFuturoOutros="0,00" mercadoOpcoesAcoes="0,00" mercadoOpcoesForaDeBolsa="0,00" mercadoOpcoesOuro="0,00" mercadoOpcoesOutros="0,00" mercadoTermoAcoes="0,00" mercadoTermoOutros="0,00" mercadoVistaAcoes="0,00" mercadoVistaForaBolsa="0,00" mercadoVistaOuro="0,00" prejuizoCompensar="0,00" resultadoLiquidoMes="0,00" resultadoNegativoMesAnterior="0,00"/>
+            <operacoesDayTrade aliquotaDoImposto="20%" baseCalculoImposto="0,00" impostoDevido="0,00" mercadoFuturoDolar="0,00" mercadoFuturoIndices="0,00" mercadoFuturoJuros="0,00" mercadoFuturoOutros="0,00" mercadoOpcoesAcoes="0,00" mercadoOpcoesForaDeBolsa="0,00" mercadoOpcoesOuro="0,00" mercadoOpcoesOutros="0,00" mercadoTermoAcoes="0,00" mercadoTermoOutros="0,00" mercadoVistaAcoes="0,00" mercadoVistaForaBolsa="0,00" mercadoVistaOuro="0,00" prejuizoCompensar="0,00" resultadoLiquidoMes="0,00" resultadoNegativoMesAnterior="0,00"/>
+            <colecaoItemImpostoPagar tipoItens="serpro.ppgd.irpf.rendavariavel.ItemImpostoPagar" total="0,00"/>
+        </novembro>
+        <dezembro impostoApagar="0,00" impostoPago="0,00" impostoRetidoFonteLei11033="0,00" impostoRetidoFonteLei11033MesesAnteriores="0,00" impostoRetidoFonteLei11033MesesCompensar="0,00" irFonteDayTradeAcompensar="0,00" irFonteDayTradeMesAtual="0,00" irFonteDayTradeMesesAnteriores="0,00" totalImpostoDevido="0,00">
+            <operacoesComuns aliquotaDoImposto="15%" baseCalculoImposto="0,00" impostoDevido="0,00" mercadoFuturoDolar="0,00" mercadoFuturoIndices="0,00" mercadoFuturoJuros="0,00" mercadoFuturoOutros="0,00" mercadoOpcoesAcoes="0,00" mercadoOpcoesForaDeBolsa="0,00" mercadoOpcoesOuro="0,00" mercadoOpcoesOutros="0,00" mercadoTermoAcoes="0,00" mercadoTermoOutros="0,00" mercadoVistaAcoes="0,00" mercadoVistaForaBolsa="0,00" mercadoVistaOuro="0,00" prejuizoCompensar="0,00" resultadoLiquidoMes="0,00" resultadoNegativoMesAnterior="0,00"/>
+            <operacoesDayTrade aliquotaDoImposto="20%" baseCalculoImposto="0,00" impostoDevido="0,00" mercadoFuturoDolar="0,00" mercadoFuturoIndices="0,00" mercadoFuturoJuros="0,00" mercadoFuturoOutros="0,00" mercadoOpcoesAcoes="0,00" mercadoOpcoesForaDeBolsa="0,00" mercadoOpcoesOuro="0,00" mercadoOpcoesOutros="0,00" mercadoTermoAcoes="0,00" mercadoTermoOutros="0,00" mercadoVistaAcoes="0,00" mercadoVistaForaBolsa="0,00" mercadoVistaOuro="0,00" prejuizoCompensar="0,00" resultadoLiquidoMes="0,00" resultadoNegativoMesAnterior="0,00"/>
+            <colecaoItemImpostoPagar tipoItens="serpro.ppgd.irpf.rendavariavel.ItemImpostoPagar" total="0,00"/>
+        </dezembro>
+        <fundInvest>
+            <jan aliquotaImposto="20,00" baseCalcImposto="0,00" impostoDevido="0,00" impostoPago="0,00" prejuizoCompensar="0,00" resultLiquidoMes="0,00" resultNegativoAnterior="0,00"/>
+            <fev aliquotaImposto="20,00" baseCalcImposto="0,00" impostoDevido="0,00" impostoPago="0,00" prejuizoCompensar="0,00" resultLiquidoMes="0,00" resultNegativoAnterior="0,00"/>
+            <mar aliquotaImposto="20,00" baseCalcImposto="0,00" impostoDevido="0,00" impostoPago="0,00" prejuizoCompensar="0,00" resultLiquidoMes="0,00" resultNegativoAnterior="0,00"/>
+            <abr aliquotaImposto="20,00" baseCalcImposto="0,00" impostoDevido="0,00" impostoPago="0,00" prejuizoCompensar="0,00" resultLiquidoMes="0,00" resultNegativoAnterior="0,00"/>
+            <mai aliquotaImposto="20,00" baseCalcImposto="0,00" impostoDevido="0,00" impostoPago="0,00" prejuizoCompensar="0,00" resultLiquidoMes="0,00" resultNegativoAnterior="0,00"/>
+            <jun aliquotaImposto="20,00" baseCalcImposto="0,00" impostoDevido="0,00" impostoPago="0,00" prejuizoCompensar="0,00" resultLiquidoMes="0,00" resultNegativoAnterior="0,00"/>
+            <jul aliquotaImposto="20,00" baseCalcImposto="0,00" impostoDevido="0,00" impostoPago="0,00" prejuizoCompensar="0,00" resultLiquidoMes="0,00" resultNegativoAnterior="0,00"/>
+            <ago aliquotaImposto="20,00" baseCalcImposto="0,00" impostoDevido="0,00" impostoPago="0,00" prejuizoCompensar="0,00" resultLiquidoMes="0,00" resultNegativoAnterior="0,00"/>
+            <set aliquotaImposto="20,00" baseCalcImposto="0,00" impostoDevido="0,00" impostoPago="0,00" prejuizoCompensar="0,00" resultLiquidoMes="0,00" resultNegativoAnterior="0,00"/>
+            <out aliquotaImposto="20,00" baseCalcImposto="0,00" impostoDevido="0,00" impostoPago="0,00" prejuizoCompensar="0,00" resultLiquidoMes="0,00" resultNegativoAnterior="0,00"/>
+            <nov aliquotaImposto="20,00" baseCalcImposto="0,00" impostoDevido="0,00" impostoPago="0,00" prejuizoCompensar="0,00" resultLiquidoMes="0,00" resultNegativoAnterior="0,00"/>
+            <dez aliquotaImposto="20,00" baseCalcImposto="0,00" impostoDevido="0,00" impostoPago="0,00" prejuizoCompensar="0,00" resultLiquidoMes="0,00" resultNegativoAnterior="0,00"/>
+        </fundInvest>
+    </rendaVariavel>
+    <atividadeRural>
+        <brasil>
+            <identificacaoImovel tipoItens="serpro.ppgd.irpf.atividaderural.brasil.ImovelARBrasil" ultimoIndiceGerado=""/>
+            <receitasDespesas totalDespesas="0,00" totalReceita="0,00">
+                <janeiro despesaCusteioInvestimento="0,00" receitaBrutaMensal="0,00"/>
+                <fevereiro despesaCusteioInvestimento="0,00" receitaBrutaMensal="0,00"/>
+                <marco despesaCusteioInvestimento="0,00" receitaBrutaMensal="0,00"/>
+                <abril despesaCusteioInvestimento="0,00" receitaBrutaMensal="0,00"/>
+                <maio despesaCusteioInvestimento="0,00" receitaBrutaMensal="0,00"/>
+                <junho despesaCusteioInvestimento="0,00" receitaBrutaMensal="0,00"/>
+                <julho despesaCusteioInvestimento="0,00" receitaBrutaMensal="0,00"/>
+                <agosto despesaCusteioInvestimento="0,00" receitaBrutaMensal="0,00"/>
+                <setembro despesaCusteioInvestimento="0,00" receitaBrutaMensal="0,00"/>
+                <outubro despesaCusteioInvestimento="0,00" receitaBrutaMensal="0,00"/>
+                <novembro despesaCusteioInvestimento="0,00" receitaBrutaMensal="0,00"/>
+                <dezembro despesaCusteioInvestimento="0,00" receitaBrutaMensal="0,00"/>
+            </receitasDespesas>
+            <apuracaoResultado despesaCusteio="0,00" opcaoArbitramento="0,00" prejuizoCompensar="0,00" prejuizoExercicioAnterior="0,00" receitaBrutaTotal="0,00" receitaRecebidaContaVenda="0,00" resultadoAposCompensacaoPrejuizo="0,00" resultadoI="0,00" resultadoNaoTributavel="0,00" resultadoTributavel="0,00" valorAdiantamento="0,00"/>
+            <movimentacaoRebanho>
+                <bovinos aquisicoesAno="0,00" consumo="0,00" estoqueFinal="0,00" estoqueInicial="0,00" nascidosAno="0,00" vendas="0,00"/>
+                <suinos aquisicoesAno="0,00" consumo="0,00" estoqueFinal="0,00" estoqueInicial="0,00" nascidosAno="0,00" vendas="0,00"/>
+                <caprinos aquisicoesAno="0,00" consumo="0,00" estoqueFinal="0,00" estoqueInicial="0,00" nascidosAno="0,00" vendas="0,00"/>
+                <asininos aquisicoesAno="0,00" consumo="0,00" estoqueFinal="0,00" estoqueInicial="0,00" nascidosAno="0,00" vendas="0,00"/>
+                <outros aquisicoesAno="0,00" consumo="0,00" estoqueFinal="0,00" estoqueInicial="0,00" nascidosAno="0,00" vendas="0,00"/>
+            </movimentacaoRebanho>
+            <bens tipoItens="serpro.ppgd.irpf.atividaderural.BemAR" ultimoIndiceGerado=""/>
+            <dividas tipoItens="serpro.ppgd.irpf.atividaderural.DividaAR"/>
+        </brasil>
+        <exterior>
+            <identificacaoImovel tipoItens="serpro.ppgd.irpf.atividaderural.ImovelAR" ultimoIndiceGerado=""/>
+            <receitasDespesas tipoItens="serpro.ppgd.irpf.atividaderural.exterior.ReceitaDespesa" totais="0,00"/>
+            <apuracaoResultado opcaoArbitramento="0,00" prejuizoCompensar="0,00" prejuizoExercicioAnterior="0,00" receitaRecebidaContaVenda="0,00" resultadoAposCompensacaoPrejuizo="0,00" resultadoI_EmDolar="0,00" resultadoI_EmReais="0,00" resultadoNaoTributavel="0,00" resultadoTributavel="0,00" valorAdiantamento="0,00"/>
+            <movimentacaoRebanho>
+                <bovinos aquisicoesAno="0,00" consumo="0,00" estoqueFinal="0,00" estoqueInicial="0,00" nascidosAno="0,00" vendas="0,00"/>
+                <suinos aquisicoesAno="0,00" consumo="0,00" estoqueFinal="0,00" estoqueInicial="0,00" nascidosAno="0,00" vendas="0,00"/>
+                <caprinos aquisicoesAno="0,00" consumo="0,00" estoqueFinal="0,00" estoqueInicial="0,00" nascidosAno="0,00" vendas="0,00"/>
+                <asininos aquisicoesAno="0,00" consumo="0,00" estoqueFinal="0,00" estoqueInicial="0,00" nascidosAno="0,00" vendas="0,00"/>
+                <outros aquisicoesAno="0,00" consumo="0,00" estoqueFinal="0,00" estoqueInicial="0,00" nascidosAno="0,00" vendas="0,00"/>
+            </movimentacaoRebanho>
+            <bens tipoItens="serpro.ppgd.irpf.atividaderural.exterior.BemARExterior" ultimoIndiceGerado=""/>
+            <dividas tipoItens="serpro.ppgd.irpf.atividaderural.DividaAR"/>
+        </exterior>
+    </atividadeRural>
+    <ganhosDeCapital totalImpostoPagoSobreGanhosCapital="0,00" totalImpostoRetidoFonteSobreGanhosCapital="0,00">
+        <bensImoveis tipoItens="serpro.ppgd.irpf.ganhosdecapital.bensimoveis.ItemDadosBemImovel"/>
+        <bensMoveis tipoItens="serpro.ppgd.irpf.ganhosdecapital.bensmoveis.ItemDadosBemMovel"/>
+        <participacoesSocietarias tipoItens="serpro.ppgd.irpf.ganhosdecapital.psocietarias.ItemDadosPSocietarias"/>
+        <declarantes tipoItens="serpro.ppgd.irpf.ganhosdecapital.IdentificacaoDeclaranteGCAP"/>
+    </ganhosDeCapital>
+    <moedaEstrangeira totalImpostoPagoSobreGanhosCapital="0,00">
+        <rendAuferidosReais tipoItens="serpro.ppgd.irpf.moedaestrangeira.rendreais.ItemDadosRendReais"/>
+        <rendAuferidosMoedaEstrangeira tipoItens="serpro.ppgd.irpf.moedaestrangeira.rendme.ItemDadosRendME"/>
+        <rendAuferidosReaisMoedaEstrangeira tipoItens="serpro.ppgd.irpf.moedaestrangeira.rendreaisme.ItemDadosRendReaisME"/>
+        <especie tipoItens="serpro.ppgd.irpf.moedaestrangeira.especie.ItemDadosEspecie"/>
+        <colecaoDadoConsolidadoGeral tipoItens="serpro.ppgd.irpf.moedaestrangeira.DadoConsolidadoGeral"/>
+    </moedaEstrangeira>
+    <copiaIdentificador cpf="342.781.611-74" dataUltimoAcesso="30/04/2013 14:28:09" declaracaoRetificadora="0" enderecoDiferente="0"
+        exercicio="2011" nome="MARIA DA SILVA DE SOUZA" numReciboDecRetif="" numeroReciboDecAnterior="401917396500" resultadoDeclaracao="IAR"
+        tipoDeclaracao="1" tipoDeclaracaoAES="A" transmitida="0"/>
+</classe>
diff --git a/test/fixtures/aplicacao/dados/iddeclaracoes.xml b/test/fixtures/aplicacao/dados/iddeclaracoes.xml
new file mode 100644 (file)
index 0000000..1a3770d
--- /dev/null
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classe xmlns="http://www.receita.fazenda.gov.br/declaracao" classeJava="serpro.ppgd.irpf.ColecaoIdDeclaracao"
+    tipoItens="serpro.ppgd.irpf.IdentificadorDeclaracao">
+    <item cpf="342.781.611-74" dataUltimoAcesso="30/04/2013 14:27:06" declaracaoRetificadora="0" enderecoDiferente="0"
+        exercicio="2011" nome="MARIA DA SILVA DE SOUZA" numReciboDecRetif="" numeroReciboDecAnterior="401915496574"
+        resultadoDeclaracao="IAR" tipoDeclaracao="1" tipoDeclaracaoAES="A"
+        transmitida="0"/>
+</classe>
\ No newline at end of file
diff --git a/test/pytddmon.py b/test/pytddmon.py
new file mode 100644 (file)
index 0000000..a1c059c
--- /dev/null
@@ -0,0 +1,634 @@
+#! /usr/bin/env python
+#coding: utf-8
+
+'''
+COPYRIGHT (c) 2009, 2010, 2011, 2012
+.. in order of first contribution
+Olof Bjarnason
+    Initial proof-of-concept pygame implementation.
+Fredrik Wendt
+    Help with Tkinter implementation (replacing the pygame dependency)
+Krunoslav Saho
+    Added always-on-top to the pytddmon window
+Samuel Ytterbrink
+    Print(".") will not screw up test-counting (it did before)
+    Docstring support
+    Recursive discovery of tests
+    Refactoring to increase Pylint score from 6 to 9.5 out of 10 (!)
+    Numerous refactorings & other improvements
+Rafael Capucho
+    Python shebang at start of script, enabling "./pytddmon.py" on unix systems
+Ilian Iliev
+    Use integers instead of floats in file modified time (checksum calc)
+    Auto-update of text in Details window when the log changes
+Henrik Bohre
+    Status bar in pytddmon window, showing either last time tests were
+    run, or "Testing..." during a test run
+    
+
+LICENSE
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+'''
+
+import os
+import sys
+import platform
+import optparse
+import re
+import unittest
+import doctest
+import time
+import multiprocessing
+import fnmatch
+import functools
+
+ON_PYTHON3 = sys.version_info[0] == 3
+ON_WINDOWS = platform.system() == "Windows"
+
+####
+## Core
+####
+
+class Pytddmon:
+    "The core class, all functionality is combined into this class"
+    def __init__(
+        self,
+        file_finder,
+        monitor,
+        project_name = "<pytddmon>"
+    ):
+        self.file_finder = file_finder
+        self.project_name = project_name
+        self.monitor = monitor
+        self.change_detected = False
+
+        self.total_tests_run = 0
+        self.total_tests_passed = 0
+        self.last_testrun_time = -1
+        self.log = ""
+        self.status_message = 'n/a'
+
+        self.run_tests()
+
+    def run_tests(self):
+        """Runs all tests and updates state variables with results."""
+        
+        file_paths = self.file_finder()
+        
+        # We need to run the tests in a separate process, since
+        # Python caches loaded modules, and unittest/doctest
+        # imports modules to run them.
+        # However, we do not want to assume users' unit tests
+        # are thread-safe, so we only run one test module at a
+        # time, using processes = 1.
+        start = time.time()
+        if file_paths:
+            pool = multiprocessing.Pool(processes = 1)
+            results = pool.map(run_tests_in_file, file_paths)
+            pool.close()
+            pool.join()
+        else:
+            results = []
+        self.last_testrun_time = time.time() - start
+        
+        now = time.strftime("%H:%M:%S", time.localtime())
+        self.log = ""
+        self.log += "Monitoring folder %s.\n" % self.project_name
+        self.log += "Found <TOTALTESTS> tests in %i files.\n" % len(results)
+        self.log += "Last change detected at %s.\n" % now
+        self.log += "Test run took %.2f seconds.\n" % self.last_testrun_time
+        self.log += "\n"
+        self.total_tests_passed = 0
+        self.total_tests_run = 0
+        module_logs = []  # Summary for each module with errors first
+        for packed in results:
+            (module, green, total, logtext) = packed
+            self.total_tests_passed += green
+            self.total_tests_run += total
+            module_log = "\nLog from " + module + ":\n" + logtext
+            if not isinstance(total, int) or total - green > 0:
+                module_logs.insert(0, module_log)
+            else:
+                module_logs.append(module_log)
+        self.log += ''.join(module_logs)
+        self.log = self.log.replace('<TOTALTESTS>', 
+                str(int(self.total_tests_run.real)))
+        self.status_message = now
+
+    def get_and_set_change_detected(self):
+        self.change_detected = self.monitor.look_for_changes()
+        return self.change_detected
+
+    def main(self):
+        """This is the main loop body"""
+        self.change_detected = self.monitor.look_for_changes()
+        if self.change_detected:
+            self.run_tests()
+
+    def get_log(self):
+        """Access the log string created during test run"""
+        return self.log
+
+    def get_status_message(self):
+        """Return message in status bar"""
+        return self.status_message
+
+class Monitor:
+    'Looks for file changes when prompted to'
+    
+    def __init__(self, file_finder, get_file_size, get_file_modtime):
+        self.file_finder = file_finder
+        self.get_file_size = get_file_size
+        self.get_file_modtime = get_file_modtime
+        self.snapshot = self.get_snapshot()
+
+    def get_snapshot(self):
+        snapshot = {}
+        for file in self.file_finder():
+            file_size = self.get_file_size(file)
+            file_modtime = self.get_file_modtime(file)
+            snapshot[file] = (file_size, file_modtime)
+        return snapshot
+
+    def look_for_changes(self):
+        new_snapshot = self.get_snapshot()
+        change_detected = new_snapshot != self.snapshot
+        self.snapshot = new_snapshot
+        return change_detected
+
+
+####
+## Finding files
+####
+
+class FileFinder:
+    "Returns all files matching given regular expression from root downwards"
+    
+    def __init__(self, root, regexp):
+        self.root = os.path.abspath(root)
+        self.regexp = regexp
+        
+    def __call__(self):
+        return self.find_files()
+
+    def find_files(self):
+        "recursively finds files matching regexp"
+        file_paths = set()
+        for path, _folder, filenames in os.walk(self.root):
+            for filename in filenames:
+                if self.re_complete_match(filename):
+                    file_paths.add(
+                        os.path.abspath(os.path.join(path, filename))
+                    )
+        return file_paths
+        
+    def re_complete_match(self, string_to_match):
+        "full string regexp check"
+        return bool(re.match(self.regexp + "$", string_to_match))
+
+wildcard_to_regex = fnmatch.translate
+
+####
+## Finding & running tests
+####
+
+def log_exceptions(func):
+    """Decorator that forwards the error message from an exception to the log
+    slot of the return value, and also returns a complexnumber to signal that
+    the result is an error."""
+    wraps = functools.wraps
+
+    @wraps(func)
+    def wrapper(*a, **k):
+        "Docstring"
+        try:
+            return func(*a, **k)
+        except:
+            import traceback
+            return ('Exception(%s)' % a[0] , 0, 1j, traceback.format_exc())
+    return wrapper
+
+@log_exceptions
+def run_tests_in_file(file_path):
+    module = file_name_to_module("", file_path)
+    return run_module(module)
+
+def run_module(module):
+    suite = find_tests_in_module(module)
+    (green, total, log) = run_suite(suite)
+    return (module, green, total, log)
+
+def file_name_to_module(base_path, file_name):
+    r"""Converts filenames of files in packages to import friendly dot
+    separated paths.
+
+    Examples:
+    >>> print(file_name_to_module("","pytddmon.pyw"))
+    pytddmon
+    >>> print(file_name_to_module("","pytddmon.py"))
+    pytddmon
+    >>> print(file_name_to_module("","tests/pytddmon.py"))
+    tests.pytddmon
+    >>> print(file_name_to_module("","./tests/pytddmon.py"))
+    tests.pytddmon
+    >>> print(file_name_to_module("",".\\tests\\pytddmon.py"))
+    tests.pytddmon
+    >>> print(
+    ...     file_name_to_module(
+    ...         "/User/pytddmon\\ geek/pytddmon/",
+    ...         "/User/pytddmon\\ geek/pytddmon/tests/pytddmon.py"
+    ...     )
+    ... )
+    tests.pytddmon
+    """
+    symbol_stripped = os.path.relpath(file_name, base_path)
+    for symbol in r"/\.":
+        symbol_stripped = symbol_stripped.replace(symbol, " ")
+    words = symbol_stripped.split()
+    # remove .py/.pyw
+    module_words = words[:-1]
+    module_name = '.'.join(module_words)
+    return module_name
+
+def find_tests_in_module(module):
+    suite = unittest.TestSuite()
+    suite.addTests(find_unittests_in_module(module))
+    suite.addTests(find_doctests_in_module(module))
+    return suite
+
+def find_unittests_in_module(module):
+    test_loader = unittest.TestLoader()
+    return test_loader.loadTestsFromName(module)
+
+def find_doctests_in_module(module):
+    try:
+        return doctest.DocTestSuite(module, optionflags = doctest.ELLIPSIS)
+    except ValueError:
+        return unittest.TestSuite()
+
+def run_suite(suite):
+    def StringIO():
+        if ON_PYTHON3:
+            import io as StringIO
+        else:
+            import StringIO 
+        return StringIO.StringIO()
+    err_log = StringIO()
+    text_test_runner = unittest.TextTestRunner(stream = err_log, verbosity = 1)
+    result = text_test_runner.run(suite)
+    green = result.testsRun - len(result.failures) - len(result.errors)
+    total = result.testsRun
+    log = err_log.getvalue() if green<total else "All %i tests passed\n" % green
+    return (green, total, log)
+
+
+####
+## GUI
+####
+
+def import_tkinter():
+    "imports tkinter from python 3.x or python 2.x"
+    if not ON_PYTHON3:
+        import Tkinter as tkinter
+    else:
+        import tkinter
+    return tkinter
+
+def import_tkFont():
+    "imports tkFont from python 3.x or python 2.x"
+    if not ON_PYTHON3:
+        import tkFont
+    else:
+        from tkinter import font as tkFont 
+    return tkFont
+    
+class TKGUIButton(object):
+    """Encapsulate the button(label)"""
+    def __init__(self, tkinter, tkFont, toplevel, display_log_callback):
+        self.font = tkFont.Font(name="Helvetica", size=28)
+        self.label = tkinter.Label(
+            toplevel,
+            text="loading...",
+            relief='raised',
+            font=self.font,
+            justify=tkinter.CENTER,
+            anchor=tkinter.CENTER
+        )
+        self.bind_click(display_log_callback)
+        self.pack()
+
+    def bind_click(self, display_log_callback):
+        """Binds the left mous button click event to trigger the logg_windows\
+        diplay method"""
+        self.label.bind(
+            '<Button-1>',
+            display_log_callback
+        )
+
+    def pack(self):
+        "packs the lable"
+        self.label.pack(
+            expand=1,
+            fill='both'
+        )
+
+    def update(self, text, color):
+        "updates the collor and displayed text."
+        self.label.configure(
+            bg=color,
+            activebackground=color,
+            text=text
+        )
+
+class TkGUI(object):
+    """Connect pytddmon engine to Tkinter GUI toolkit"""
+    def __init__(self, pytddmon, tkinter, tkFont):
+        self.pytddmon = pytddmon
+        self.tkinter = tkinter
+        self.tkFont = tkFont
+        self.color_picker = ColorPicker()
+        self.root = None
+        self.building_root()
+        self.title_font = None
+        self.building_fonts()
+        self.frame = None
+        self.building_frame()
+        self.button = TKGUIButton(
+            tkinter,
+            tkFont,
+            self.frame,
+            self.display_log_message
+        )
+        self.status_bar = None
+        self.building_status_bar()
+        self.frame.grid()
+        self.message_window = None
+        self.text = None
+
+        if ON_WINDOWS:
+            buttons_width = 25
+        else:
+            buttons_width = 75
+        self.root.minsize(
+            width=self.title_font.measure(
+                self.pytddmon.project_name
+            ) + buttons_width, 
+            height=0
+        )
+        self.frame.pack(expand=1, fill="both")
+        self.create_text_window()
+        self.update_text_window()
+
+    def building_root(self):
+        """take hold of the tk root object as self.root"""
+        self.root = self.tkinter.Tk()
+        self.root.wm_attributes("-topmost", 1)
+        if ON_WINDOWS:
+            self.root.attributes("-toolwindow", 1)
+            print("Minimize me!")
+
+    def building_fonts(self):
+        "building fonts"
+        self.title_font = self.tkFont.nametofont("TkCaptionFont")
+
+    def building_frame(self):
+        """Creates a frame and assigns it to self.frame"""
+        # Calculate the width of the tilte + buttons
+        self.frame = self.tkinter.Frame(
+            self.root
+        )
+        # Sets the title of the gui
+        self.frame.master.title(self.pytddmon.project_name)
+        # Forces the window to not be resizeable
+        self.frame.master.resizable(False, False)
+        self.frame.pack(expand=1, fill="both")
+
+    def building_status_bar(self):
+        """Add status bar and assign it to self.status_bar"""
+        self.status_bar = self.tkinter.Label(
+            self.frame,
+            text="n/a"
+        )
+        self.status_bar.pack(expand=1, fill="both")
+
+    def _update_and_get_color(self):
+        "Calculate the current color and trigger pulse"
+        self.color_picker.set_result(
+            self.pytddmon.total_tests_passed,
+            self.pytddmon.total_tests_run,
+        )
+        light, color = self.color_picker.pick()
+        rgb = self.color_picker.translate_color(light, color)
+        self.color_picker.pulse()
+        return rgb
+
+    def _get_text(self):
+        "Calculates the text to show the user(passed/total or Error!)"
+        if self.pytddmon.total_tests_run.imag!=0:
+            text = "?ERROR"
+        else:
+            text = "%r/%r" % (
+                self.pytddmon.total_tests_passed,
+                self.pytddmon.total_tests_run
+            )
+        return text
+
+    def update(self):
+        """updates the tk gui"""
+        rgb = self._update_and_get_color()
+        text = self._get_text()
+        self.button.update(text, rgb)
+        self.root.configure(bg=rgb)
+        self.update_status(self.pytddmon.get_status_message())
+    
+        if self.pytddmon.change_detected:
+            self.update_text_window()
+
+    def update_status(self, message):
+        self.status_bar.configure(
+            text=message
+        )
+        self.status_bar.update_idletasks()
+
+    def get_text_message(self):
+        """returns the logmessage from pytddmon"""
+        message = self.pytddmon.get_log()
+        return message
+
+    def create_text_window(self):
+        """creates new window and text widget""" 
+        win = self.tkinter.Toplevel()
+        if ON_WINDOWS:
+            win.attributes("-toolwindow", 1)
+        win.title('Details')
+        self.message_window = win
+        self.text = self.tkinter.Text(win)
+        self.message_window.withdraw()
+
+    def update_text_window(self):
+        """inserts/replaces the log message in the text widget"""
+        text = self.text
+        text['state'] = self.tkinter.NORMAL
+        text.delete(1.0, self.tkinter.END)
+        text.insert(self.tkinter.INSERT, self.get_text_message())
+        text['state'] = self.tkinter.DISABLED
+        text.pack(expand=1, fill='both')
+        text.focus_set()
+
+    def display_log_message(self, _arg):
+        """displays/close the logmessage from pytddmon in a window"""
+        if self.message_window.state() == 'normal':
+            self.message_window.state('iconic')
+        else:
+            self.message_window.state('normal')
+
+    def loop(self):
+        """the main loop"""
+        if self.pytddmon.get_and_set_change_detected():
+            self.update_status('Testing...')
+            self.pytddmon.run_tests()
+        self.update()
+        self.frame.after(750, self.loop)
+
+    def run(self):
+        """starts the main loop and goes into sleep"""
+        self.loop()
+        self.root.mainloop()
+
+class ColorPicker:
+    """
+    ColorPicker decides the background color the pytddmon window,
+    based on the number of green tests, and the total number of
+    tests. Also, there is a "pulse" (light color, dark color),
+    to increase the feeling of continous testing.
+    """
+    color_table = {
+        (True, 'green'): '0f0',
+        (False, 'green'): '0c0',
+        (True, 'red'): 'f00',
+        (False, 'red'): 'c00',
+        (True, 'orange'): 'fc0',
+        (False, 'orange'): 'ca0',
+        (True, 'gray'): '999',
+        (False, 'gray'): '555'
+    }
+
+    def __init__(self):
+        self.color = 'green'
+        self.light = True
+
+    def pick(self):
+        "returns the tuple (light, color) with the types(bool ,str)"
+        return (self.light, self.color)
+
+    def pulse(self):
+        "updates the light state"
+        self.light = not self.light
+
+    def reset_pulse(self):
+        "resets the light state"
+        self.light = True
+
+    def set_result(self, green, total):
+        "calculates what color should be used and may reset the lightness"
+        old_color = self.color
+        self.color = 'green'
+        if green.imag or total.imag:
+            self.color = "orange"
+        elif green == total - 1:
+            self.color = 'red'
+        elif green < total - 1:
+            self.color = 'gray'
+        if self.color != old_color:
+            self.reset_pulse()
+
+    @classmethod
+    def translate_color(cls, light, color):
+        """helper method to create a rgb string"""
+        return "#" + cls.color_table[(light, color)]
+
+
+def parse_commandline():
+    """
+    returns (files, test_mode) created from the command line arguments
+    passed to pytddmon.
+    """
+    parser = optparse.OptionParser()
+    parser.add_option(
+        "--log-and-exit",
+        action="store_true",
+        default=False,
+        help='Run all tests, write the results to "pytddmon.log" and exit.')
+    (options, args) = parser.parse_args()
+    return (args, options.log_and_exit)
+
+def build_monitor(file_finder):
+    os.stat_float_times(False)
+    def get_file_size(file_path):
+        stat = os.stat(file_path)
+        return stat.st_size
+    def get_file_modtime(file_path):
+        stat = os.stat(file_path)
+        return stat.st_mtime
+    return Monitor(file_finder, get_file_size, get_file_modtime)
+
+def run():
+    """
+    The main function: basic initialization and program start
+    """
+    cwd = os.getcwd()
+    
+    # Include current work directory in Python path
+    sys.path[:0] = [cwd]
+    
+    # Command line argument handling
+    (static_file_set, test_mode) = parse_commandline()
+    
+    # What files to monitor?
+    if not static_file_set:
+        regex = wildcard_to_regex("*.py")
+    else:
+        regex = '|'.join(static_file_set)
+    file_finder = FileFinder(cwd, regex)
+    
+    # The change detector: Monitor
+    monitor = build_monitor(file_finder)
+    
+    # Python engine ready to be setup
+    pytddmon = Pytddmon(
+        file_finder,
+        monitor,
+        project_name = os.path.basename(cwd)
+    )
+    
+    # Start the engine!
+    if not test_mode:
+        TkGUI(pytddmon, import_tkinter(), import_tkFont()).run()
+    else:
+        pytddmon.main()
+        with open("pytddmon.log", "w") as log_file:
+            log_file.write(
+                "green=%r\ntotal=%r\n" % (
+                    pytddmon.total_tests_passed,
+                    pytddmon.total_tests_run
+                )
+            )
+
+if __name__ == '__main__':
+    run()
diff --git a/test/res b/test/res
new file mode 120000 (symlink)
index 0000000..dbbfe3c
--- /dev/null
+++ b/test/res
@@ -0,0 +1 @@
+../res/
\ No newline at end of file
diff --git a/test/run_all_tests.sh b/test/run_all_tests.sh
new file mode 100644 (file)
index 0000000..f0bc868
--- /dev/null
@@ -0,0 +1,4 @@
+
+for i in $(ls ./test/test_*.py);do
+    PYTHONPATH=./src python $i
+done