Files
jhonny-editor/code/engine/testes/test_mapeador_de_tempo.py
João Henrique 4308c72441 feat: criada a aba Análises no painel CEP para ler do banco (anali
- criada a aba Análises no painel CEP para ler do banco (analises.db) e copiar/abrir o J-SOM de som (transcrição por cena) e o de imagem (evidências visuais), com novo módulo engine/gerar_relatorio_de_analises.py e testes
- criado o módulo engine/editor (leitura do plano de edição em JSON, tradução de tempos de origem para a timeline ativa e aplicação de cortes/zooms/marcadores no Premiere via MCP) e o ponto de entrada engine/aplicar_plano_de_edicao.py, com testes; corrigido engine/integracoes/premiere/cliente_mcp.py para levantar os erros específicos já declarados em erros_mcp.py em vez de RuntimeError genérico

Resumo:
- 15 arquivos alterados
- 8 novos
- 5 modificados
- 2 removidos

 7 files changed, 172 insertions(+), 8 deletions(-)

Arquivos:
  - .jhonny/analises.db
  - .jhonny/analises.db-shm
  - .jhonny/analises.db-wal
  - code/cep-plugin/index.html
  - code/cep-plugin/main.js
  - code/cep-plugin/styles.css
  - code/engine/integracoes/premiere/cliente_mcp.py
  - code/engine/aplicar_plano_de_edicao.py
  - code/engine/editor/
  - code/engine/gerar_relatorio_de_analises.py
  - code/engine/testes/duplos_de_premiere.py
  - code/engine/testes/test_aplicador_de_plano_de_edicao.py
  - code/engine/testes/test_gerar_relatorio_de_analises.py
  - code/engine/testes/test_leitor_de_plano_de_edicao.py
  - code/engine/testes/test_mapeador_de_tempo.py
2026-09-08 19:35:30 -04:00

70 lines
3.4 KiB
Python

"""Testes do mapeamento de tempos de origem para a timeline (engine.editor.mapeamento)."""
import unittest
from engine.dominio import Clipe, Faixa, IntervaloDeTempo
from engine.editor.erros import ErroDeMapeamentoDeTempo
from engine.editor.mapeamento import MapeadorDeTempoDeOrigemParaTimeline
def _clipe(identificador, tl_inicio, tl_fim, origem_inicio, origem_fim, nome="0E6A8290.MP4"):
"""Monta um Clipe de teste com intervalo na timeline e na origem."""
return Clipe(
identificador=identificador,
nome=nome,
intervalo_na_timeline=IntervaloDeTempo(tl_inicio, tl_fim),
intervalo_na_origem=IntervaloDeTempo(origem_inicio, origem_fim),
)
class TesteMapeadorDeTempoDeOrigemParaTimeline(unittest.TestCase):
"""Cobre a tradução de tempos de origem, reproduzindo o caso real do projeto:
a timeline reindexada pelo detector de cena não bate com o tempo do arquivo."""
def setUp(self):
self.mapeador = MapeadorDeTempoDeOrigemParaTimeline()
# Reproduz o caso real: clip 000f4775 está em 86.2-114.0s de origem,
# mas em 58.1-86.0s na timeline reindexada pelo scanner.
self.faixa = Faixa("video_0", "Vídeo 1", "video", 0, clipes=[
_clipe("000f4763", 0.0, 38.3, 2.3, 40.6),
_clipe("000f4775", 58.1, 86.0, 86.2, 114.0),
_clipe("outro_arquivo", 86.0, 90.0, 0.0, 4.0, nome="outro.mp4"),
])
def test_clipes_do_arquivo_filtra_por_nome_ignorando_caixa(self):
clipes = self.mapeador.clipes_do_arquivo(self.faixa, "0e6a8290.mp4")
self.assertEqual([c.identificador for c in clipes], ["000f4763", "000f4775"])
def test_localizar_clipe_no_instante_encontra_o_clipe_certo(self):
clipes = self.mapeador.clipes_do_arquivo(self.faixa, "0E6A8290.MP4")
clipe = self.mapeador.localizar_clipe_no_instante(clipes, 90.0)
self.assertEqual(clipe.identificador, "000f4775")
def test_localizar_clipe_no_instante_fora_de_qualquer_clipe_devolve_none(self):
clipes = self.mapeador.clipes_do_arquivo(self.faixa, "0E6A8290.MP4")
self.assertIsNone(self.mapeador.localizar_clipe_no_instante(clipes, 500.0))
def test_instante_na_timeline_traduz_usando_o_deslocamento_do_clipe(self):
clipe = _clipe("000f4775", 58.1, 86.0, 86.2, 114.0)
# 86.42s de origem (início real da fala) cai 0.22s depois do início
# do clipe (86.2s) e deve mapear para 58.1 + 0.22 = 58.32s na timeline.
self.assertAlmostEqual(self.mapeador.instante_na_timeline(clipe, 86.42), 58.32, places=6)
def test_instante_na_timeline_sem_intervalo_de_origem_levanta_erro(self):
clipe = Clipe("x", "n", IntervaloDeTempo(0, 1), intervalo_na_origem=None)
with self.assertRaises(ErroDeMapeamentoDeTempo):
self.mapeador.instante_na_timeline(clipe, 0.5)
def test_instante_na_timeline_por_arquivo_encontra_e_traduz(self):
timeline = None # não é usado pelo atalho; mantido para deixar a chamada explícita
instante = self.mapeador.instante_na_timeline_por_arquivo(timeline, self.faixa, "0E6A8290.MP4", 90.0)
self.assertAlmostEqual(instante, 58.1 + (90.0 - 86.2), places=6)
def test_instante_na_timeline_por_arquivo_sem_clipe_levanta_erro(self):
with self.assertRaises(ErroDeMapeamentoDeTempo):
self.mapeador.instante_na_timeline_por_arquivo(None, self.faixa, "0E6A8290.MP4", 500.0)
if __name__ == "__main__":
unittest.main()