Add tests

This commit is contained in:
MGatner 2021-05-24 01:10:02 +00:00 committed by John Paul E. Balandan, CPA
parent 944152fe13
commit b2a16e9d40
4 changed files with 887 additions and 4 deletions

View File

@ -108,8 +108,8 @@ class Publisher
return [];
}
// Loop over each file checking to see if it is a Primer
foreach ($files as $file)
// Loop over each file checking to see if it is a Publisher
foreach (array_unique($files) as $file)
{
$className = $locator->findQualifiedNameFromPath($file);
@ -228,8 +228,10 @@ class Publisher
$attempts = 10;
while ((bool) $attempts && ! delete_files($directory, true, false, true))
{
// @codeCoverageIgnoreStart
$attempts--;
usleep(100000); // .1s
// @codeCoverageIgnoreEnd
}
@rmdir($directory);
@ -270,6 +272,13 @@ class Publisher
unlink($to);
}
// Make sure the directory exists
$directory = pathinfo($to, PATHINFO_DIRNAME);
if (! is_dir($directory))
{
mkdir($directory, 0775, true);
}
// Allow copy() to throw errors
copy($from, $to);
}
@ -311,10 +320,11 @@ class Publisher
* This method should be reimplemented by
* child classes intended for discovery.
*
* @return void
* @return bool
*/
public function publish()
{
return $this->addPath('/')->merge(true);
}
//--------------------------------------------------------------------
@ -686,7 +696,7 @@ class Publisher
$this->errors = [];
// Get the file from source for special handling
$sourced = self::matchFiles($this->getFiles(), $this->source);
$sourced = self::filterFiles($this->getFiles(), $this->source);
// Handle everything else with a flat copy
$this->files = array_diff($this->files, $sourced);

View File

@ -0,0 +1,472 @@
<?php namespace CodeIgniter\Pager;
use CodeIgniter\Publisher\Exceptions\PublisherException;
use CodeIgniter\Publisher\Publisher;
use CodeIgniter\Test\CIUnitTestCase;
use Tests\Support\Publishers\TestPublisher;
class PublisherInputTest extends CIUnitTestCase
{
/**
* A known, valid file
*
* @var string
*/
private $file = SUPPORTPATH . 'Files/baker/banana.php';
/**
* A known, valid directory
*
* @var string
*/
private $directory = SUPPORTPATH . 'Files/able/';
/**
* Initialize the helper, since some
* tests call static methods before
* the constructor would load it.
*/
public static function setUpBeforeClass(): void
{
parent::setUpBeforeClass();
helper(['filesystem']);
}
//--------------------------------------------------------------------
public function testAddFile()
{
$publisher = new Publisher();
$this->assertSame([], $this->getPrivateProperty($publisher, 'files'));
$publisher->addFile($this->file);
$this->assertSame([$this->file], $this->getPrivateProperty($publisher, 'files'));
}
public function testAddFileMissing()
{
$publisher = new Publisher();
$this->expectException(PublisherException::class);
$this->expectExceptionMessage(lang('Publisher.expectedFile', ['addFile']));
$publisher->addFile('TheHillsAreAlive.bmp');
}
public function testAddFileDirectory()
{
$publisher = new Publisher();
$this->expectException(PublisherException::class);
$this->expectExceptionMessage(lang('Publisher.expectedFile', ['addFile']));
$publisher->addFile($this->directory);
}
public function testAddFiles()
{
$publisher = new Publisher();
$files = [
$this->file,
$this->file,
];
$publisher->addFiles($files);
$this->assertSame($files, $this->getPrivateProperty($publisher, 'files'));
}
//--------------------------------------------------------------------
public function testGetFiles()
{
$publisher = new Publisher();
$publisher->addFile($this->file);
$this->assertSame([$this->file], $publisher->getFiles());
}
public function testGetFilesSorts()
{
$publisher = new Publisher();
$files = [
$this->file,
$this->directory . 'apple.php',
];
$publisher->addFiles($files);
$this->assertSame(array_reverse($files), $publisher->getFiles());
}
public function testGetFilesUniques()
{
$publisher = new Publisher();
$files = [
$this->file,
$this->file,
];
$publisher->addFiles($files);
$this->assertSame([$this->file], $publisher->getFiles());
}
public function testSetFiles()
{
$publisher = new Publisher();
$publisher->setFiles([$this->file]);
$this->assertSame([$this->file], $publisher->getFiles());
}
public function testSetFilesInvalid()
{
$publisher = new Publisher();
$this->expectException(PublisherException::class);
$this->expectExceptionMessage(lang('Publisher.expectedFile', ['addFile']));
$publisher->setFiles(['flerb']);
}
//--------------------------------------------------------------------
public function testRemoveFile()
{
$publisher = new Publisher();
$files = [
$this->file,
$this->directory . 'apple.php',
];
$publisher->addFiles($files);
$publisher->removeFile($this->file);
$this->assertSame([$this->directory . 'apple.php'], $publisher->getFiles());
}
public function testRemoveFiles()
{
$publisher = new Publisher();
$files = [
$this->file,
$this->directory . 'apple.php',
];
$publisher->addFiles($files);
$publisher->removeFiles($files);
$this->assertSame([], $publisher->getFiles());
}
//--------------------------------------------------------------------
public function testAddDirectoryInvalid()
{
$publisher = new Publisher();
$this->expectException(PublisherException::class);
$this->expectExceptionMessage(lang('Publisher.expectedDirectory', ['addDirectory']));
$publisher->addDirectory($this->file);
}
public function testAddDirectory()
{
$publisher = new Publisher();
$expected = [
$this->directory . 'apple.php',
$this->directory . 'fig_3.php',
$this->directory . 'prune_ripe.php',
];
$publisher->addDirectory($this->directory);
$this->assertSame($expected, $publisher->getFiles());
}
public function testAddDirectoryRecursive()
{
$publisher = new Publisher();
$expected = [
$this->directory . 'apple.php',
$this->directory . 'fig_3.php',
$this->directory . 'prune_ripe.php',
SUPPORTPATH . 'Files/baker/banana.php',
];
$publisher->addDirectory(SUPPORTPATH . 'Files', true);
$this->assertSame($expected, $publisher->getFiles());
}
public function testAddDirectories()
{
$publisher = new Publisher();
$expected = [
$this->directory . 'apple.php',
$this->directory . 'fig_3.php',
$this->directory . 'prune_ripe.php',
SUPPORTPATH . 'Files/baker/banana.php',
];
$publisher->addDirectories([
$this->directory,
SUPPORTPATH . 'Files/baker',
]);
$this->assertSame($expected, $publisher->getFiles());
}
public function testAddDirectoriesRecursive()
{
$publisher = new Publisher();
$expected = [
$this->directory . 'apple.php',
$this->directory . 'fig_3.php',
$this->directory . 'prune_ripe.php',
SUPPORTPATH . 'Files/baker/banana.php',
SUPPORTPATH . 'Log/Handlers/TestHandler.php',
];
$publisher->addDirectories([
SUPPORTPATH . 'Files',
SUPPORTPATH . 'Log',
], true);
$this->assertSame($expected, $publisher->getFiles());
}
//--------------------------------------------------------------------
public function testAddPathFile()
{
$publisher = new Publisher(SUPPORTPATH . 'Files');
$publisher->addPath('baker/banana.php');
$this->assertSame([$this->file], $publisher->getFiles());
}
public function testAddPathFileRecursiveDoesNothing()
{
$publisher = new Publisher(SUPPORTPATH . 'Files');
$publisher->addPath('baker/banana.php', true);
$this->assertSame([$this->file], $publisher->getFiles());
}
public function testAddPathDirectory()
{
$publisher = new Publisher(SUPPORTPATH . 'Files');
$expected = [
$this->directory . 'apple.php',
$this->directory . 'fig_3.php',
$this->directory . 'prune_ripe.php',
];
$publisher->addPath('able');
$this->assertSame($expected, $publisher->getFiles());
}
public function testAddPathDirectoryRecursive()
{
$publisher = new Publisher(SUPPORTPATH);
$expected = [
$this->directory . 'apple.php',
$this->directory . 'fig_3.php',
$this->directory . 'prune_ripe.php',
SUPPORTPATH . 'Files/baker/banana.php',
];
$publisher->addPath('Files');
$this->assertSame($expected, $publisher->getFiles());
}
public function testAddPaths()
{
$publisher = new Publisher(SUPPORTPATH . 'Files');
$expected = [
$this->directory . 'apple.php',
$this->directory . 'fig_3.php',
$this->directory . 'prune_ripe.php',
SUPPORTPATH . 'Files/baker/banana.php',
];
$publisher->addPaths([
'able',
'baker/banana.php',
]);
$this->assertSame($expected, $publisher->getFiles());
}
public function testAddPathsRecursive()
{
$publisher = new Publisher(SUPPORTPATH);
$expected = [
$this->directory . 'apple.php',
$this->directory . 'fig_3.php',
$this->directory . 'prune_ripe.php',
SUPPORTPATH . 'Files/baker/banana.php',
SUPPORTPATH . 'Log/Handlers/TestHandler.php',
];
$publisher->addPaths([
'Files',
'Log',
], true);
$this->assertSame($expected, $publisher->getFiles());
}
//--------------------------------------------------------------------
public function testAddUri()
{
$publisher = new Publisher();
$publisher->addUri('https://raw.githubusercontent.com/codeigniter4/CodeIgniter4/develop/composer.json');
$scratch = $this->getPrivateProperty($publisher, 'scratch');
$this->assertSame([$scratch . 'composer.json'], $publisher->getFiles());
}
public function testAddUris()
{
$publisher = new Publisher();
$publisher->addUris([
'https://raw.githubusercontent.com/codeigniter4/CodeIgniter4/develop/LICENSE',
'https://raw.githubusercontent.com/codeigniter4/CodeIgniter4/develop/composer.json',
]);
$scratch = $this->getPrivateProperty($publisher, 'scratch');
$this->assertSame([$scratch . 'LICENSE', $scratch . 'composer.json'], $publisher->getFiles());
}
//--------------------------------------------------------------------
public function testRemovePatternEmpty()
{
$publisher = new Publisher();
$publisher->addDirectory(SUPPORTPATH . 'Files', true);
$files = $publisher->getFiles();
$publisher->removePattern('');
$this->assertSame($files, $publisher->getFiles());
}
public function testRemovePatternRegex()
{
$publisher = new Publisher();
$publisher->addDirectory(SUPPORTPATH . 'Files', true);
$expected = [
$this->directory . 'apple.php',
SUPPORTPATH . 'Files/baker/banana.php',
];
$publisher->removePattern('#[a-z]+_.*#');
$this->assertSame($expected, $publisher->getFiles());
}
public function testRemovePatternPseudo()
{
$publisher = new Publisher();
$publisher->addDirectory(SUPPORTPATH . 'Files', true);
$expected = [
$this->directory . 'apple.php',
SUPPORTPATH . 'Files/baker/banana.php',
];
$publisher->removePattern('*_*.php');
$this->assertSame($expected, $publisher->getFiles());
}
public function testRemovePatternScope()
{
$publisher = new Publisher();
$publisher->addDirectory(SUPPORTPATH . 'Files', true);
$expected = [
SUPPORTPATH . 'Files/baker/banana.php',
];
$publisher->removePattern('*.php', $this->directory);
$this->assertSame($expected, $publisher->getFiles());
}
//--------------------------------------------------------------------
public function testRetainPatternEmpty()
{
$publisher = new Publisher();
$publisher->addDirectory(SUPPORTPATH . 'Files', true);
$files = $publisher->getFiles();
$publisher->retainPattern('');
$this->assertSame($files, $publisher->getFiles());
}
public function testRetainPatternRegex()
{
$publisher = new Publisher();
$publisher->addDirectory(SUPPORTPATH . 'Files', true);
$expected = [
$this->directory . 'fig_3.php',
$this->directory . 'prune_ripe.php',
];
$publisher->retainPattern('#[a-z]+_.*#');
$this->assertSame($expected, $publisher->getFiles());
}
public function testRetainPatternPseudo()
{
$publisher = new Publisher();
$publisher->addDirectory(SUPPORTPATH . 'Files', true);
$expected = [
$this->directory . 'fig_3.php',
];
$publisher->retainPattern('*_?.php');
$this->assertSame($expected, $publisher->getFiles());
}
public function testRetainPatternScope()
{
$publisher = new Publisher();
$publisher->addDirectory(SUPPORTPATH . 'Files', true);
$expected = [
$this->directory . 'fig_3.php',
SUPPORTPATH . 'Files/baker/banana.php',
];
$publisher->retainPattern('*_?.php', $this->directory);
$this->assertSame($expected, $publisher->getFiles());
}
}

View File

@ -0,0 +1,202 @@
<?php namespace CodeIgniter\Pager;
use CodeIgniter\Publisher\Exceptions\PublisherException;
use CodeIgniter\Publisher\Publisher;
use CodeIgniter\Test\CIUnitTestCase;
use Tests\Support\Publishers\TestPublisher;
use org\bovigo\vfs\vfsStream;
use org\bovigo\vfs\vfsStreamDirectory;
class PublisherOutputTest extends CIUnitTestCase
{
/**
* Files to seed to VFS
*
* @var array
*/
private $structure;
/**
* Virtual destination
*
* @var vfsStreamDirectory
*/
private $root;
/**
* A known, valid file
*
* @var string
*/
private $file = SUPPORTPATH . 'Files/baker/banana.php';
/**
* A known, valid directory
*
* @var string
*/
private $directory = SUPPORTPATH . 'Files/able/';
/**
* Initialize the helper, since some
* tests call static methods before
* the constructor would load it.
*/
public static function setUpBeforeClass(): void
{
parent::setUpBeforeClass();
helper(['filesystem']);
}
protected function setUp(): void
{
parent::setUp();
$this->structure = [
'able' => [
'apple.php' => 'Once upon a midnight dreary',
'bazam' => 'While I pondered weak and weary',
],
'boo' => [
'far' => 'Upon a tome of long-forgotten lore',
'faz' => 'There came a tapping up on the door',
],
'AnEmptyFolder' => [],
'simpleFile' => 'A tap-tap-tapping upon my door',
'.hidden' => 'There is no spoon',
];
$this->root = vfsStream::setup('root', null, $this->structure);
}
//--------------------------------------------------------------------
public function testCopy()
{
$publisher = new Publisher($this->directory, $this->root->url());
$publisher->addFile($this->file);
$this->assertFileDoesNotExist($this->root->url() . '/banana.php');
$result = $publisher->copy(false);
$this->assertTrue($result);
$this->assertFileExists($this->root->url() . '/banana.php');
}
public function testCopyReplace()
{
$file = $this->directory . 'apple.php';
$publisher = new Publisher($this->directory, $this->root->url() . '/able');
$publisher->addFile($file);
$this->assertFileExists($this->root->url() . '/able/apple.php');
$this->assertFalse(same_file($file, $this->root->url() . '/able/apple.php'));
$result = $publisher->copy(true);
$this->assertTrue($result);
$this->assertTrue(same_file($file, $this->root->url() . '/able/apple.php'));
}
public function testCopyIgnoresSame()
{
$publisher = new Publisher($this->directory, $this->root->url());
$publisher->addFile($this->file);
copy($this->file, $this->root->url() . '/banana.php');
$result = $publisher->copy(false);
$this->assertTrue($result);
$result = $publisher->copy(true);
$this->assertTrue($result);
}
public function testCopyIgnoresCollision()
{
$publisher = new Publisher($this->directory, $this->root->url());
mkdir($this->root->url() . '/banana.php');
$result = $publisher->addFile($this->file)->copy(false);
$errors = $publisher->getErrors();
$this->assertTrue($result);
$this->assertSame([], $errors);
}
public function testCopyCollides()
{
$publisher = new Publisher($this->directory, $this->root->url());
$expected = lang('Publisher.collision', ['dir', $this->file, $this->root->url() . '/banana.php']);
mkdir($this->root->url() . '/banana.php');
$result = $publisher->addFile($this->file)->copy(true);
$errors = $publisher->getErrors();
$this->assertFalse($result);
$this->assertCount(1, $errors);
$this->assertSame([$this->file], array_keys($errors));
$this->assertSame($expected, $errors[$this->file]->getMessage());
}
//--------------------------------------------------------------------
public function testMerge()
{
$publisher = new Publisher(SUPPORTPATH . 'Files', $this->root->url());
$this->assertFileDoesNotExist($this->root->url() . '/able/fig_3.php');
$this->assertDirectoryDoesNotExist($this->root->url() . '/baker');
$result = $publisher->addPath('/')->merge(false);
$this->assertTrue($result);
$this->assertFileExists($this->root->url() . '/able/fig_3.php');
$this->assertDirectoryExists($this->root->url() . '/baker');
}
public function testMergeReplace()
{
$this->assertFalse(same_file($this->directory . 'apple.php', $this->root->url() . '/able/apple.php'));
$publisher = new Publisher(SUPPORTPATH . 'Files', $this->root->url());
$result = $publisher->addPath('/')->merge(true);
$this->assertTrue($result);
$this->assertTrue(same_file($this->directory . 'apple.php', $this->root->url() . '/able/apple.php'));
}
public function testMergeCollides()
{
$publisher = new Publisher(SUPPORTPATH . 'Files', $this->root->url());
$expected = lang('Publisher.collision', ['dir', $this->directory . 'fig_3.php', $this->root->url() . '/able/fig_3.php']);
mkdir($this->root->url() . '/able/fig_3.php');
$result = $publisher->addPath('/')->merge(true);
$errors = $publisher->getErrors();
$this->assertFalse($result);
$this->assertCount(1, $errors);
$this->assertSame([$this->directory . 'fig_3.php'], array_keys($errors));
$this->assertSame($expected, $errors[$this->directory . 'fig_3.php']->getMessage());
}
//--------------------------------------------------------------------
public function testPublish()
{
$publisher = new Publisher(SUPPORTPATH . 'Files', $this->root->url());
$result = $publisher->publish();
$this->assertTrue($result);
$this->assertFileExists($this->root->url() . '/able/fig_3.php');
$this->assertDirectoryExists($this->root->url() . '/baker');
$this->assertTrue(same_file($this->directory . 'apple.php', $this->root->url() . '/able/apple.php'));
}
}

View File

@ -0,0 +1,199 @@
<?php namespace CodeIgniter\Pager;
use CodeIgniter\Publisher\Exceptions\PublisherException;
use CodeIgniter\Publisher\Publisher;
use CodeIgniter\Test\CIUnitTestCase;
use Tests\Support\Publishers\TestPublisher;
class PublisherSupportTest extends CIUnitTestCase
{
/**
* A known, valid file
*
* @var string
*/
private $file = SUPPORTPATH . 'Files/baker/banana.php';
/**
* A known, valid directory
*
* @var string
*/
private $directory = SUPPORTPATH . 'Files/able/';
/**
* Initialize the helper, since some
* tests call static methods before
* the constructor would load it.
*/
public static function setUpBeforeClass(): void
{
parent::setUpBeforeClass();
helper(['filesystem']);
}
//--------------------------------------------------------------------
public function testDiscoverDefault()
{
$result = Publisher::discover();
$this->assertCount(1, $result);
$this->assertInstanceOf(TestPublisher::class, $result[0]);
}
public function testDiscoverNothing()
{
$result = Publisher::discover('Nothing');
$this->assertSame([], $result);
}
public function testDiscoverStores()
{
$publisher = Publisher::discover()[0];
$publisher->addFile($this->file);
$result = Publisher::discover();
$this->assertSame($publisher, $result[0]);
$this->assertSame([$this->file], $result[0]->getFiles());
}
//--------------------------------------------------------------------
public function testResolveDirectoryDirectory()
{
$method = $this->getPrivateMethodInvoker(Publisher::class, 'resolveDirectory');
$this->assertSame($this->directory, $method($this->directory));
}
public function testResolveDirectoryFile()
{
$method = $this->getPrivateMethodInvoker(Publisher::class, 'resolveDirectory');
$this->expectException(PublisherException::class);
$this->expectExceptionMessage(lang('Publisher.expectedDirectory', ['invokeArgs']));
$method($this->file);
}
public function testResolveDirectorySymlink()
{
// Create a symlink to test
$link = sys_get_temp_dir() . DIRECTORY_SEPARATOR . bin2hex(random_bytes(4));
symlink($this->directory, $link);
$method = $this->getPrivateMethodInvoker(Publisher::class, 'resolveDirectory');
$this->assertSame($this->directory, $method($link));
unlink($link);
}
//--------------------------------------------------------------------
public function testResolveFileFile()
{
$method = $this->getPrivateMethodInvoker(Publisher::class, 'resolveFile');
$this->assertSame($this->file, $method($this->file));
}
public function testResolveFileSymlink()
{
// Create a symlink to test
$link = sys_get_temp_dir() . DIRECTORY_SEPARATOR . bin2hex(random_bytes(4));
symlink($this->file, $link);
$method = $this->getPrivateMethodInvoker(Publisher::class, 'resolveFile');
$this->assertSame($this->file, $method($link));
unlink($link);
}
public function testResolveFileDirectory()
{
$method = $this->getPrivateMethodInvoker(Publisher::class, 'resolveFile');
$this->expectException(PublisherException::class);
$this->expectExceptionMessage(lang('Publisher.expectedFile', ['invokeArgs']));
$method($this->directory);
}
//--------------------------------------------------------------------
public function testGetScratch()
{
$publisher = new Publisher();
$this->assertNull($this->getPrivateProperty($publisher, 'scratch'));
$method = $this->getPrivateMethodInvoker($publisher, 'getScratch');
$scratch = $method();
$this->assertIsString($scratch);
$this->assertDirectoryExists($scratch);
$this->assertDirectoryIsWritable($scratch);
$this->assertNotNull($this->getPrivateProperty($publisher, 'scratch'));
// Directory and contents should be removed on __destruct()
$file = $scratch . 'obvious_statement.txt';
file_put_contents($file, 'Bananas are a most peculiar fruit');
$publisher->__destruct();
$this->assertFileDoesNotExist($file);
$this->assertDirectoryDoesNotExist($scratch);
}
public function testGetErrors()
{
$publisher = new Publisher();
$this->assertSame([], $publisher->getErrors());
$expected = [
$this->file => PublisherException::forCollision($this->file, $this->file),
];
$this->setPrivateProperty($publisher, 'errors', $expected);
$this->assertSame($expected, $publisher->getErrors());
}
//--------------------------------------------------------------------
public function testWipeDirectory()
{
$directory = rtrim(sys_get_temp_dir(), DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . bin2hex(random_bytes(6));
mkdir($directory, 0700);
$this->assertDirectoryExists($directory);
$method = $this->getPrivateMethodInvoker(Publisher::class, 'wipeDirectory');
$method($directory);
$this->assertDirectoryDoesNotExist($directory);
}
public function testWipeIgnoresFiles()
{
$method = $this->getPrivateMethodInvoker(Publisher::class, 'wipeDirectory');
$method($this->file);
$this->assertFileExists($this->file);
}
public function testWipe()
{
$directory = rtrim(sys_get_temp_dir(), DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . bin2hex(random_bytes(6));
mkdir($directory, 0700);
$this->assertDirectoryExists($directory);
$publisher = new Publisher($this->directory, $directory);
$publisher->wipe();
$this->assertDirectoryDoesNotExist($directory);
}
}