diff --git a/tests/Config/ConfigTest.php b/tests/Config/ConfigTest.php new file mode 100644 index 0000000..0658c28 --- /dev/null +++ b/tests/Config/ConfigTest.php @@ -0,0 +1,22 @@ +assertSame(sys_get_temp_dir(), $config->getTmpFileDir()); + $this->assertSame('php', $config->getTmpFilePrefix()); + } +} diff --git a/tests/Container/ContainerTest.php b/tests/Container/ContainerTest.php new file mode 100644 index 0000000..a869052 --- /dev/null +++ b/tests/Container/ContainerTest.php @@ -0,0 +1,90 @@ +addTmpFile($tmpFile); + + $this->assertCount(1, $container->getTmpFiles()); + } + + public function testAddTheSameTmpFile(): void + { + $container = new Container(); + $tmpFile = new TmpFile('meow.txt'); + $container->addTmpFile($tmpFile); + + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage('Temp file "meow.txt" has been already added.'); + + $container->addTmpFile($tmpFile); + } + + public function testHasTmpFile(): void + { + $container = new Container(); + $tmpFile = new TmpFile('meow.txt'); + + $container->addTmpFile($tmpFile); + + $this->assertTrue($container->hasTmpFile($tmpFile)); + } + + public function testRemoveTmpFile(): void + { + $container = new Container(); + $tmpFile = new TmpFile('meow.txt'); + $container->addTmpFile($tmpFile); + + $container->removeTmpFile($tmpFile); + + $this->assertCount(0, $container->getTmpFiles()); + } + + public function testRemoveNotAddedTmpFile(): void + { + $container = new Container(); + $tmpFile = new TmpFile('meow.txt'); + + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage('Temp file "meow.txt" hasn\'t been added yet.'); + + $container->removeTmpFile($tmpFile); + } + + public function testCleatTmpFiles(): void + { + $container = new Container(); + $container->addTmpFile(new TmpFile('cat.jpg')); + $container->addTmpFile(new TmpFile('dog.jpg')); + $container->addTmpFile(new TmpFile('fish.jpg')); + + $container->clearTmpFiles(); + + $this->assertCount(0, $container->getTmpFiles()); + } + + public function testGetTmpFiles(): void + { + $container = new Container(); + $container->addTmpFile(new TmpFile('cat.jpg')); + $container->addTmpFile(new TmpFile('dog.jpg')); + $container->addTmpFile(new TmpFile('fish.jpg')); + + $tmpFiles = $container->getTmpFiles(); + + $this->assertNotEmpty($tmpFiles); + } +} diff --git a/tests/Event/TmpFileEventSpy.php b/tests/Event/TmpFileEventSpy.php new file mode 100644 index 0000000..7607dde --- /dev/null +++ b/tests/Event/TmpFileEventSpy.php @@ -0,0 +1,52 @@ + $eventsCounter + * @param array $tmpFiles + */ + public function __construct( + private array $eventsCounter = [], + private array $tmpFiles = [], + ) { + } + + public function __invoke(AbstractTmpFileEvent $event): void + { + if (!isset($this->eventsCounter[$event::class])) { + $this->eventsCounter[$event::class] = 0; + } + + ++$this->eventsCounter[$event::class]; + $this->tmpFiles[$event->getTmpFile()->getFilename()] = $event->getTmpFile(); + } + + public function getEventsCount(string $className = null): int + { + if (null === $className) { + return array_sum($this->eventsCounter); + } + + if (!isset($this->eventsCounter[$className])) { + return 0; + } + + return $this->eventsCounter[$className]; + } + + /** + * @return TmpFileInterface[] + */ + public function getTmpFiles(): array + { + return array_values($this->tmpFiles); + } +} diff --git a/tests/Event/TmpFileManagerEventSpy.php b/tests/Event/TmpFileManagerEventSpy.php new file mode 100644 index 0000000..bd4404a --- /dev/null +++ b/tests/Event/TmpFileManagerEventSpy.php @@ -0,0 +1,60 @@ + $eventsCounter + * @param array $tmpFilesCount + */ + public function __construct( + private array $eventsCounter = [], + private array $tmpFilesCount = [], + ) { + } + + public function __invoke(AbstractTmpFileManagerEvent $event): void + { + if (!isset($this->eventsCounter[$event::class])) { + $this->eventsCounter[$event::class] = 0; + } + + if (!isset($this->tmpFilesCount[$event::class])) { + $this->tmpFilesCount[$event::class] = 0; + } + + ++$this->eventsCounter[$event::class]; + $this->tmpFilesCount[$event::class] = $event->getContainer()->count(); + } + + public function getEventsCount(string $className = null): int + { + if (null === $className) { + return array_sum($this->eventsCounter); + } + + if (!isset($this->eventsCounter[$className])) { + return 0; + } + + return $this->eventsCounter[$className]; + } + + public function getTmpFilesCount(string $className = null): int + { + if (null === $className) { + return array_sum($this->tmpFilesCount); + } + + if (!isset($this->tmpFilesCount[$className])) { + return 0; + } + + return $this->tmpFilesCount[$className]; + } +} diff --git a/tests/Filesystem/FilesystemTest.php b/tests/Filesystem/FilesystemTest.php new file mode 100644 index 0000000..368ad23 --- /dev/null +++ b/tests/Filesystem/FilesystemTest.php @@ -0,0 +1,44 @@ +createTmpFile(sys_get_temp_dir(), 'php'); + + $this->assertFileExists($tmpFile->getFilename()); + + $filesystem->removeTmpFile($tmpFile); + } + + public function testExistTmpFile(): void + { + $filesystem = new Filesystem(); + + $tmpFile = $filesystem->createTmpFile(sys_get_temp_dir(), 'php'); + + $this->assertTrue($filesystem->existsTmpFile($tmpFile)); + + $filesystem->removeTmpFile($tmpFile); + } + + public function testRemoveTmpFile(): void + { + $filesystem = new Filesystem(); + + $tmpFile = $filesystem->createTmpFile(sys_get_temp_dir(), 'php'); + + $filesystem->removeTmpFile($tmpFile); + + $this->assertFileDoesNotExist($tmpFile->getFilename()); + } +} diff --git a/tests/Handler/GarbageCollectionHandler/GarbageCollectionHandlerTest.php b/tests/Handler/GarbageCollectionHandler/GarbageCollectionHandlerTest.php new file mode 100644 index 0000000..fc192f6 --- /dev/null +++ b/tests/Handler/GarbageCollectionHandler/GarbageCollectionHandlerTest.php @@ -0,0 +1,30 @@ +tempnam(sys_get_temp_dir(), 'php'); + $fs->touch($tmpFile, time() - 7_200); + + $handler = new GarbageCollectionHandler( + probability: 100, + divisor: 1, + lifetime: 3_600, + processor: new SyncProcessor(), + ); + $handler->handle(sys_get_temp_dir(), 'php'); + + $this->assertFileDoesNotExist($tmpFile); + } +} diff --git a/tests/Handler/GarbageCollectionHandler/Processor/AsyncProcessorTest.php b/tests/Handler/GarbageCollectionHandler/Processor/AsyncProcessorTest.php new file mode 100644 index 0000000..764f7b9 --- /dev/null +++ b/tests/Handler/GarbageCollectionHandler/Processor/AsyncProcessorTest.php @@ -0,0 +1,26 @@ +tempnam(sys_get_temp_dir(), 'php'); + $fs->touch($tmpFile, time() - 7_200); + + $processor = new AsyncProcessor( + isParallel: false, + ); + $processor->process(sys_get_temp_dir(), 'php', 3_600); + + $this->assertFileDoesNotExist($tmpFile); + } +} diff --git a/tests/Handler/GarbageCollectionHandler/Processor/SyncProcessorTest.php b/tests/Handler/GarbageCollectionHandler/Processor/SyncProcessorTest.php new file mode 100644 index 0000000..cda90ab --- /dev/null +++ b/tests/Handler/GarbageCollectionHandler/Processor/SyncProcessorTest.php @@ -0,0 +1,24 @@ +tempnam(sys_get_temp_dir(), 'php'); + $fs->touch($tmpFile, time() - 7_200); + + $processor = new SyncProcessor(); + $processor->process(sys_get_temp_dir(), 'php', 3_600); + + $this->assertFileDoesNotExist($tmpFile); + } +} diff --git a/tests/Handler/UnclosedResourcesHandler/UnclosedResourcesHandlerTest.php b/tests/Handler/UnclosedResourcesHandler/UnclosedResourcesHandlerTest.php new file mode 100644 index 0000000..8a8231a --- /dev/null +++ b/tests/Handler/UnclosedResourcesHandler/UnclosedResourcesHandlerTest.php @@ -0,0 +1,28 @@ +createTmpFile(sys_get_temp_dir(), 'php'); + $fh = fopen($tmpFile->getFilename(), 'r'); + + try { + $handler = new UnclosedResourcesHandler(); + $handler->handle([$tmpFile]); + + $this->assertFalse(\is_resource($fh)); + } finally { + $filesystem->removeTmpFile($tmpFile); + } + } +} diff --git a/tests/TmpFileMangerBuilderTest.php b/tests/TmpFileMangerBuilderTest.php new file mode 100644 index 0000000..34b9055 --- /dev/null +++ b/tests/TmpFileMangerBuilderTest.php @@ -0,0 +1,100 @@ +withTmpFileDir(sys_get_temp_dir()) + ->build() + ; + + $tmpFile = $tmpFileManager->create(); + + $this->assertStringStartsWith(sys_get_temp_dir(), $tmpFile->getFilename()); + } + + public function testBuildWithTmpFilePrefix(): void + { + $tmpFileManager = (new TmpFileManagerBuilder()) + ->withTmpFileDir(sys_get_temp_dir()) + ->withTmpFilePrefix('php') + ->build() + ; + + $tmpFile = $tmpFileManager->create(); + + $this->assertStringStartsWith(sys_get_temp_dir().'/php', $tmpFile->getFilename()); + } + + public function testBuildTmpFileManagerWithoutAutoPurge(): void + { + $spy = new TmpFileManagerEventSpy(); + $tmpFileManager = (new TmpFileManagerBuilder()) + ->withoutAutoPurge() + ->withEventListener(TmpFileManagerPostPurge::class, $spy) + ->build() + ; + + $tmpFileManager->create(); + $tmpFileManager->purge(); + + $this->assertEquals(0, $spy->getTmpFilesCount()); + } + + public function testBuildWithUnclosedResourcesHandler(): void + { + $spy = new TmpFileManagerEventSpy(); + $tmpFileManager = (new TmpFileManagerBuilder()) + ->withUnclosedResourcesHandler(new UnclosedResourcesHandler()) + ->withEventListener(TmpFileManagerPrePurge::class, $spy) + ->build() + ; + + $tmpFile = $tmpFileManager->create(); + $fh = fopen($tmpFile->getFilename(), 'r'); + $tmpFileManager->purge(); + + $this->assertFalse(\is_resource($fh)); + $this->assertEquals(1, $spy->getEventsCount()); + } + + public function testBuildWithGarbageCollectionHandler(): void + { + $spy = new TmpFileManagerEventSpy(); + $tmpFileManager = (new TmpFileManagerBuilder()) + ->withoutAutoPurge() + ->withGarbageCollectionHandler(new GarbageCollectionHandler( + probability: 100, + divisor: 1, + lifetime: 3_600, + processor: new SyncProcessor(), + )) + ->withEventListener(TmpFileManagerPostPurge::class, $spy) + ->build() + ; + + $fs = new Fs(); + $tmpFile = new TmpFile($fs->tempnam(sys_get_temp_dir(), 'php')); + $fs->touch($tmpFile->getFilename(), time() - 7_200); + $tmpFileManager->purge(); + + $this->assertFileDoesNotExist($tmpFile->getFilename()); + $this->assertEquals(1, $spy->getEventsCount()); + } +} diff --git a/tests/TmpFileMangerLifecycleTest.php b/tests/TmpFileMangerLifecycleTest.php new file mode 100644 index 0000000..7471013 --- /dev/null +++ b/tests/TmpFileMangerLifecycleTest.php @@ -0,0 +1,190 @@ +withEventListener(TmpFileManagerOnStart::class, $spy) + ->build() + ; + + $this->assertEquals(1, $spy->getEventsCount()); + } + + public function testTmpFileManagerPreCreate(): void + { + $spy = new TmpFileManagerEventSpy(); + $tmpFileManager = (new TmpFileManagerBuilder()) + ->withEventListener(TmpFileManagerPreCreate::class, $spy) + ->build() + ; + + $tmpFileManager->create(); + + $this->assertEquals(1, $spy->getEventsCount()); + } + + public function testTmpFileOnCreate(): void + { + $spy = new TmpFileEventSpy(); + $tmpFileManager = (new TmpFileManagerBuilder()) + ->withEventListener(TmpFileOnCreate::class, $spy) + ->build() + ; + + $tmpFileManager->create(); + + $this->assertEquals(1, $spy->getEventsCount()); + } + + public function testTmpFileManagerPostCreate(): void + { + $spy = new TmpFileManagerEventSpy(); + $tmpFileManager = (new TmpFileManagerBuilder()) + ->withEventListener(TmpFileManagerPostCreate::class, $spy) + ->build() + ; + + $tmpFileManager->create(); + + $this->assertEquals(1, $spy->getEventsCount()); + } + + public function testTmpFileManagerPreLoad(): void + { + $spy = new TmpFileManagerEventSpy(); + $filesystem = new Filesystem(); + $tmpFileManager = (new TmpFileManagerBuilder()) + ->withEventListener(TmpFileManagerPreLoad::class, $spy) + ->build() + ; + + $tmpFile = $filesystem->createTmpFile(sys_get_temp_dir(), 'php'); + $tmpFileManager->load($tmpFile); + + $this->assertEquals(1, $spy->getEventsCount()); + } + + public function testTmpFileOnLoad(): void + { + $spy = new TmpFileEventSpy(); + $filesystem = new Filesystem(); + $tmpFileManager = (new TmpFileManagerBuilder()) + ->withEventListener(TmpFileOnLoad::class, $spy) + ->build() + ; + + $tmpFileManager->load(...[ + $filesystem->createTmpFile(sys_get_temp_dir(), 'php'), + $filesystem->createTmpFile(sys_get_temp_dir(), 'php'), + $filesystem->createTmpFile(sys_get_temp_dir(), 'php'), + ]); + + $this->assertEquals(3, $spy->getEventsCount()); + } + + public function testTmpFileManagerPostLoad(): void + { + $spy = new TmpFileManagerEventSpy(); + $filesystem = new Filesystem(); + $tmpFileManager = (new TmpFileManagerBuilder()) + ->withEventListener(TmpFileManagerPostLoad::class, $spy) + ->build() + ; + + $tmpFile = $filesystem->createTmpFile(sys_get_temp_dir(), 'php'); + $tmpFileManager->load($tmpFile); + + $this->assertEquals(1, $spy->getEventsCount()); + } + + public function testTmpFilePreRemove(): void + { + $spy = new TmpFileEventSpy(); + $tmpFileManager = (new TmpFileManagerBuilder()) + ->withEventListener(TmpFilePreRemove::class, $spy) + ->build() + ; + + $tmpFile = $tmpFileManager->create(); + $tmpFileManager->remove($tmpFile); + + $this->assertEquals(1, $spy->getEventsCount()); + } + + public function testTmpFilePostRemove(): void + { + $spy = new TmpFileEventSpy(); + $tmpFileManager = (new TmpFileManagerBuilder()) + ->withEventListener(TmpFilePostRemove::class, $spy) + ->build() + ; + + $tmpFile = $tmpFileManager->create(); + $tmpFileManager->remove($tmpFile); + + $this->assertEquals(1, $spy->getEventsCount()); + } + + public function testTmpFileManagerPrePurge(): void + { + $spy = new TmpFileManagerEventSpy(); + $tmpFileManager = (new TmpFileManagerBuilder()) + ->withEventListener(TmpFileManagerPrePurge::class, $spy) + ->build() + ; + + $tmpFileManager->purge(); + + $this->assertEquals(1, $spy->getEventsCount()); + } + + public function testTmpFileManagerPostPurge(): void + { + $spy = new TmpFileManagerEventSpy(); + $tmpFileManager = (new TmpFileManagerBuilder()) + ->withEventListener(TmpFileManagerPostPurge::class, $spy) + ->build() + ; + + $tmpFileManager->purge(); + + $this->assertEquals(1, $spy->getEventsCount()); + } + + public function testTmpFileManagerOnFinish(): void + { + $spy = new TmpFileManagerEventSpy(); + (new TmpFileManagerBuilder()) + ->withoutAutoPurge() + ->withEventListener(TmpFileManagerOnFinish::class, $spy) + ->build() + ; + + $this->assertEquals(1, $spy->getEventsCount()); + } +} diff --git a/tests/TmpFileMangerTest.php b/tests/TmpFileMangerTest.php new file mode 100644 index 0000000..1fb94bc --- /dev/null +++ b/tests/TmpFileMangerTest.php @@ -0,0 +1,147 @@ +build(); + + $tmpFile = $tmpFileManager->create(); + + $this->assertFileExists($tmpFile->getFilename()); + } + + public function testLoadTmpFile(): void + { + $fs = new Filesystem(); + $tmpFile = $fs->createTmpFile(sys_get_temp_dir(), 'php'); + $spy = new TmpFileManagerEventSpy(); + $tmpFileManager = (new TmpFileManagerBuilder()) + ->withEventListener(TmpFileManagerPostLoad::class, $spy) + ->build() + ; + + try { + $tmpFileManager->load($tmpFile); + } catch (\Throwable) { + if ($fs->existsTmpFile($tmpFile)) { + $fs->removeTmpFile($tmpFile); + } + } + + $this->assertEquals(1, $spy->getTmpFilesCount()); + } + + public function testLoadTheSameTmpFile(): void + { + $tmpFileManager = (new TmpFileManagerBuilder())->build(); + + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessageMatches('/^Temp file ".+" has been already added.$/'); + + $tmpFileManager->load($tmpFileManager->create()); + } + + public function testLoadDoesNotExistTmpFile(): void + { + $tmpFileManager = (new TmpFileManagerBuilder())->build(); + + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessageMatches('/^Temp file ".+" doesn\'t exist.$/'); + + $tmpFileManager->load(new TmpFile('meow.txt')); + } + + public function testIsolateTmpFile(): void + { + $spy = new TmpFileEventSpy(); + $tmpFileManager = (new TmpFileManagerBuilder()) + ->withEventListener(TmpFilePostRemove::class, $spy) + ->build() + ; + + $tmpFileManager->isolate(function (TmpFileInterface $tmpFile): void { + $this->assertFileExists($tmpFile->getFilename()); + }); + + $this->assertEquals(1, $spy->getEventsCount()); + + foreach ($spy->getTmpFiles() as $tmpFile) { + $this->assertFileDoesNotExist($tmpFile->getFilename()); + } + } + + public function testRemoveTmpFile(): void + { + $tmpFileManager = (new TmpFileManagerBuilder())->build(); + $tmpFile = $tmpFileManager->create(); + + $tmpFileManager->remove($tmpFile); + + $this->assertFileDoesNotExist($tmpFile->getFilename()); + } + + public function testRemoveDoesNotExistTmpFile(): void + { + $tmpFileManager = (new TmpFileManagerBuilder())->build(); + + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessageMatches('/^Temp file ".+" has been already removed.$/'); + + $tmpFileManager->remove(new TmpFile('meow.txt')); + } + + public function testRemoveDoesNotAddTmpFile(): void + { + $fs = new Filesystem(); + $tmpFile = $fs->createTmpFile(sys_get_temp_dir(), 'php'); + $tmpFileManager = (new TmpFileManagerBuilder())->build(); + + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessageMatches('/^Temp file ".+" wasn\'t create through temp file manager.$/'); + + try { + $tmpFileManager->remove($tmpFile); + } finally { + if ($fs->existsTmpFile($tmpFile)) { + $fs->removeTmpFile($tmpFile); + } + } + } + + public function testPurgeTmpFile(): void + { + $tmpFileManager = (new TmpFileManagerBuilder())->build(); + $tmpFile = $tmpFileManager->create(); + + $tmpFileManager->purge(); + + $this->assertFileDoesNotExist($tmpFile->getFilename()); + } + + public function testPurgeTmpFileAfterLoad(): void + { + $fs = new Filesystem(); + $tmpFile = $fs->createTmpFile(sys_get_temp_dir(), 'php'); + $tmpFileManager = (new TmpFileManagerBuilder())->build(); + $tmpFileManager->load($tmpFile); + + $tmpFileManager->purge(); + + $this->assertFileDoesNotExist($tmpFile->getFilename()); + } +}