From 35f6fe997f0543d3f6ef6ca400738f94ff9c29ce Mon Sep 17 00:00:00 2001 From: andreas Date: Wed, 11 Sep 2019 07:23:13 +0200 Subject: [PATCH] fixed #47 - Merge fails with chapters shorter than 1 second --- src/library/M4bTool/Executables/Mp4info.php | 29 ++++-- .../M4bTool/Executables/Mp4infoTest.php | 97 +++++++++++++++++++ 2 files changed, 117 insertions(+), 9 deletions(-) create mode 100644 tests/library/M4bTool/Executables/Mp4infoTest.php diff --git a/src/library/M4bTool/Executables/Mp4info.php b/src/library/M4bTool/Executables/Mp4info.php index 529e6fe..9a425e0 100644 --- a/src/library/M4bTool/Executables/Mp4info.php +++ b/src/library/M4bTool/Executables/Mp4info.php @@ -4,6 +4,7 @@ namespace M4bTool\Executables; +use Exception; use Sandreas\Time\TimeUnit; use SplFileInfo; use Symfony\Component\Console\Helper\ProcessHelper; @@ -17,21 +18,31 @@ public function __construct($pathToBinary = "mp4info", ProcessHelper $processHel parent::__construct($pathToBinary, $processHelper, $output); } + /** + * @param SplFileInfo $file + * @return TimeUnit|null + * @throws Exception + */ public function estimateDuration(SplFileInfo $file): ?TimeUnit + { + return $this->inspectExactDuration($file); + } + + + /** + * @param SplFileInfo $file + * @return TimeUnit|null + * @throws Exception + */ + public function inspectExactDuration(SplFileInfo $file): ?TimeUnit { $process = $this->runProcess([$file]); $output = $process->getOutput() . $process->getErrorOutput(); - preg_match("/([1-9][0-9]*\.[0-9]{3}) secs,/isU", $output, $matches); + preg_match("/([0-9]+\.[0-9]{3}) secs,/isU", $output, $matches); if (!isset($matches[1])) { - return null; + throw new Exception(sprintf("Could not detect length for file %s, output '%s' does not contain a valid length value", $file->getBasename(), $output)); } return new TimeUnit($matches[1], TimeUnit::SECOND); } - - - public function inspectExactDuration(SplFileInfo $file): ?TimeUnit - { - return $this->estimateDuration($file); - } -} \ No newline at end of file +} diff --git a/tests/library/M4bTool/Executables/Mp4infoTest.php b/tests/library/M4bTool/Executables/Mp4infoTest.php new file mode 100644 index 0000000..93ceb04 --- /dev/null +++ b/tests/library/M4bTool/Executables/Mp4infoTest.php @@ -0,0 +1,97 @@ +mockProcess = m::mock(Process::class); + $this->mockProcess->shouldReceive('getErrorOutput')->andReturn(""); + $this->mockProcess->shouldReceive('stop'); + + $this->mockFile = new SplFileInfo(__FILE__); + /** @var ProcessHelper|m\MockInterface $mockProcessHelper */ + $mockProcessHelper = m::mock(ProcessHelper::class); + $mockProcessHelper->shouldReceive('run')->once()->andReturn($this->mockProcess); + + $this->subject = new Mp4info("mp4info", $mockProcessHelper); + } + + /** + * @throws Exception + */ + public function testInspectDuration() + { + $this->mockProcess->shouldReceive("getOutput")->andReturn(static::SAMPLE_OUTPUT); + $timeUnit = $this->subject->estimateDuration($this->mockFile); + $this->assertEquals(640684, $timeUnit->milliseconds()); + + $timeUnitExact = $this->subject->inspectExactDuration($this->mockFile); + $this->assertEquals(640684, $timeUnitExact->milliseconds()); + } + + /** + * @throws Exception + */ + public function testInspectDurationWithShortLength() + { + $this->mockProcess->shouldReceive("getOutput")->andReturn(static::SAMPLE_OUTPUT_SHORT_LENGTH); + $timeUnit = $this->subject->estimateDuration($this->mockFile); + $this->assertEquals(684, $timeUnit->milliseconds()); + + $timeUnitExact = $this->subject->inspectExactDuration($this->mockFile); + $this->assertEquals(684, $timeUnitExact->milliseconds()); + } + + /** + * @expectedException Exception + * @expectedExceptionMessage Could not detect length for file Mp4infoTest.php, output '' does not contain a valid length value + */ + public function testInspectExactDurationException() + { + $this->mockProcess->shouldReceive("getOutput")->andReturn(""); + $this->subject->estimateDuration($this->mockFile); + } +}