use crate::application::ports::MediaProcessorPort; use crate::domain::entities::Project; use anyhow::Result; /// Constrói o comando FFmpeg a partir do Project e delega a execução ao MediaProcessorPort. #[allow(dead_code)] pub struct GenerateOutput; impl GenerateOutput { #[allow(dead_code)] pub fn execute(project: &Project, port: &dyn MediaProcessorPort) -> Result<()> { use crate::adapters::ffmpeg::command_builder::FfmpegCommandBuilder; let args = FfmpegCommandBuilder::build(project); port.execute(args) } } #[cfg(test)] mod tests { use super::*; use crate::application::ports::MediaProcessorPort; use crate::application::use_cases::add_audio_track::AddAudioTrack; use crate::domain::entities::{MkvOutput, Project, VideoFile}; use crate::domain::value_objects::{FilePath, SyncOffset, TrackLanguage}; use anyhow::Result; use std::cell::RefCell; struct MockProcessor { captured_args: RefCell>, } impl MediaProcessorPort for MockProcessor { fn execute(&self, args: Vec) -> Result<()> { *self.captured_args.borrow_mut() = args; Ok(()) } } #[test] fn sempre_inclui_c_copy() { let mut project = Project::new( VideoFile::new(FilePath::from("input.mkv")), MkvOutput::new(FilePath::from("output.mkv")), ) .unwrap(); AddAudioTrack::execute( &mut project, FilePath::from("audio_pt.aac"), SyncOffset::from_ms(1200), TrackLanguage::new("por").unwrap(), false, String::new(), ) .unwrap(); let mock = MockProcessor { captured_args: RefCell::new(vec![]), }; GenerateOutput::execute(&project, &mock).unwrap(); let args = mock.captured_args.borrow(); assert!( args.contains(&"-c".to_string()) && args.contains(&"copy".to_string()), "Comando não continha '-c copy': {:?}", args ); } }