diff --git a/index.php b/index.php index 814c076..587acd0 100644 --- a/index.php +++ b/index.php @@ -13,6 +13,10 @@ pr($sampleSimple->queryNonExistingFileWithRequirementOne()); pr($sampleSimple->queryNonExistingFileWithRequirementLast()); pr($sampleSimple->queryNonExistingFileWithRequirementAll()); +pr($sampleSimple->executeQueryChild1()); +pr($sampleSimple->executeQueryChild1()); +pr($sampleSimple->executeQueryChild1('File2')); +pr($sampleSimple->executeQueryChild1()); function pr($var) { diff --git a/samples/FQ/Samples/Simple.php b/samples/FQ/Samples/Simple.php index 735e6ba..60e52cf 100644 --- a/samples/FQ/Samples/Simple.php +++ b/samples/FQ/Samples/Simple.php @@ -2,13 +2,17 @@ namespace FQ\Samples; +use FQ\Collections\Query\QueryCollection; use FQ\Dirs\ChildDir; use FQ\Dirs\RootDir; +use FQ\Query\FilesQuery; use FQ\Query\FilesQueryBuilder; use FQ\Query\FilesQueryRequirements; class Simple extends SampleBootstrapper { + private $_queryCollection; + function __construct() { parent::__construct('simple'); @@ -17,6 +21,20 @@ function __construct() { $this->addChildDir(new ChildDir('child1', 'child1')); $this->addChildDir(new ChildDir('child2', 'child2')); + + $this->_queryCollection = new QueryCollection($this); + + $queryChild1 = new FilesQuery($this); + $queryChild1ChildSelection = $queryChild1->getChildDirSelection(); + $queryChild1ChildSelection->includeDirById('child1'); + + $this->_queryCollection->addQuery('child1', $queryChild1); + + $queryChild2 = new FilesQuery($this); + $queryChild2ChildSelection = $queryChild2->getChildDirSelection(); + $queryChild2ChildSelection->includeDirById('child2'); + + $this->_queryCollection->addQuery('child2', $queryChild2); } public function queryFile1FromChild1() { @@ -46,4 +64,10 @@ public function queryNonExistingFileWithRequirementAll() { $builder = new FilesQueryBuilder($this->query()); return $builder->addRequirement(FilesQueryRequirements::REQUIRE_ALL)->run('File1')->listPaths(); } + + public function executeQueryChild1($fileName = 'File1') { + $query = $this->_queryCollection->getQueryById('child1'); + $query->run($fileName); + return $query->listPaths(); + } } \ No newline at end of file diff --git a/src/FQ/collections/query/QueryCollection.php b/src/FQ/collections/query/QueryCollection.php new file mode 100644 index 0000000..0dc37be --- /dev/null +++ b/src/FQ/collections/query/QueryCollection.php @@ -0,0 +1,106 @@ +_queries = array(); + } + + /** + * @param $id + * @param FilesQuery $query + * @return FilesQuery + */ + public function addQuery($id, FilesQuery $query) { + if ($this->queryExists($id)) { + throw new QueryCollectionException(sprintf('Query with id "%s" already defined', $id)); + } + $this->_queries[$id] = $query; + return $query; + } + + /** + * @param string|FilesQuery $query + * @return FilesQuery|null + */ + public function getQuery($query) { + if (is_string($query)) { + return $this->getQueryById($query); + } + else if (is_object($query) && $this->isInCollection($query)) { + return $query; + } + return null; + } + + public function getQueryById($id) { + if ($this->queryExists($id)) { + return $this->_queries[$id]; + } + return null; + } + + /** + * @param string $id + * @return bool + */ + public function removeQuery($id) { + if ($this->queryExists($id)) { + unset($this->_queries[$id]); + return true; + } + return false; + } + + /** + * + */ + public function removeAllQueries() { + $this->_queries = array(); + } + + /** + * @param FilesQuery $query Query that will be checked + * @return bool Returns true if dir is in the collection and false when it's not + */ + public function isInCollection(FilesQuery $query) { + foreach ($this->_queries as $queryTemp) { + if ($query === $queryTemp) return true; + } + return false; + } + + /** + * @param $id + * @return bool + */ + public function queryExists($id) { + return isset($this->_queries[$id]); + } + + /** + * @return FilesQuery[] + */ + public function queries() { + return $this->_queries; + } + + /** + * @return int Total amount of queries in this collection + */ + public function totalQueries() { + return count($this->queries()); + } + +} \ No newline at end of file diff --git a/src/FQ/exceptions/QueryCollectionException.php b/src/FQ/exceptions/QueryCollectionException.php new file mode 100644 index 0000000..dd3a102 --- /dev/null +++ b/src/FQ/exceptions/QueryCollectionException.php @@ -0,0 +1,9 @@ +_cachedQueryRootDirs = null; - $this->_currentQueryChildren = array(); - - $this->_cachedPaths = null; - $this->_cachedPathsSimple = null; - $this->_cachedRawPaths = null; - $this->_cachedRawPathsSimple = null; + $this->_clearRootDirCache(); + $this->_clearChildDirCache(); + $this->_clearPathCache(); $this->requirements()->removeAll(); $this->filters(self::FILTER_EXISTING, false); @@ -130,6 +136,20 @@ public function reset() { $this->_hasRun = false; $this->_queryError = null; } + protected function _clearRootDirCache() { + $this->_cachedQueryRootDirs = null; + } + protected function _clearChildDirCache() { + $this->_cachedQueryChildDirs = null; + } + protected function _clearPathCache() { + $this->_currentQueryChildren = array(); + + $this->_cachedPaths = null; + $this->_cachedPathsSimple = null; + $this->_cachedRawPaths = null; + $this->_cachedRawPathsSimple = null; + } public function resetSelection() { $this->getRootDirSelection()->reset(); $this->getChildDirSelection()->reset(); @@ -256,21 +276,30 @@ protected function _hasRunCheck() { /** * @param string $fileName The name of the file the query will be executing + * @param bool $throwExceptions + * @throws \Exception * @return bool */ - public function run($fileName) { - if ($this->files()->totalRootDirs() === 0) { + public function run($fileName, $throwExceptions = false) { + $files = $this->files(); + if ($files->totalRootDirs() === 0) { throw new FileQueryException(sprintf('Query is trying to run with file "%s" but no root directories are configured. Make sure sure you have added at least one root directory with Files::addRootDir() before you run a query', $fileName)); } - $this->_queriedFileName = $fileName; + $this->_clearPathCache(); - if ($this->getRootDirSelection()->isInvalidated()) { - $this->_cachedQueryRootDirs; + $currentRootDirs = $files->rootDirs(); + if (!Dirs::equalDirs($this->_cachedRootDirs, $currentRootDirs) || $this->getRootDirSelection()->isInvalidated()) { + $this->_clearRootDirCache(); } - if ($this->getChildDirSelection()->isInvalidated()) { - $this->_cachedQueryChildren; + $this->_cachedRootDirs = $currentRootDirs; + $currentChildDirs = $files->childDirs(); + if (!Dirs::equalDirs($this->_cachedChildDirs, $currentChildDirs) || $this->getChildDirSelection()->isInvalidated()) { + $this->_clearChildDirCache(); } + $this->_cachedChildDirs = $currentChildDirs; + + $this->_queriedFileName = $fileName; $rootDirsSelection = $this->_getCachedRootDirSelection(); $this->_currentQueryChildren = array(); @@ -281,6 +310,9 @@ public function run($fileName) { $meetsRequirements = $this->requirements()->meetsRequirements(false); if ($meetsRequirements !== true) { $this->_queryError = $meetsRequirements; + if ($throwExceptions === true) { + throw new $this->_queryError; + } } return $this->_queryError === null; } diff --git a/src/FQ/utils/Dirs.php b/src/FQ/utils/Dirs.php new file mode 100644 index 0000000..62878f8 --- /dev/null +++ b/src/FQ/utils/Dirs.php @@ -0,0 +1,22 @@ + $dir) { + if ($array2[$index] !== $dir) { + return false; + } + } + return true; + } +} \ No newline at end of file diff --git a/tests/FQ/Tests/Collections/AbstractDirCollectionTests.php b/tests/FQ/Tests/Collections/AbstractDirCollectionTests.php index 8dd50b8..de701d8 100644 --- a/tests/FQ/Tests/Collections/AbstractDirCollectionTests.php +++ b/tests/FQ/Tests/Collections/AbstractDirCollectionTests.php @@ -3,6 +3,7 @@ namespace FQ\Tests\Collections; use FQ\Collections\DirCollection; +use FQ\Dirs\Dir; use FQ\Tests\AbstractFQTest; class AbstractDirCollectionTests extends AbstractFQTest { @@ -11,6 +12,7 @@ class AbstractDirCollectionTests extends AbstractFQTest { protected function setUp() { + parent::setUp(); // Create a new FQ app, // since we need one pretty much everywhere $this->_dirCollection = $this->_createNewDirCollection(); @@ -30,7 +32,7 @@ protected function _createNewDirCollection() { return new DirCollection(); } - protected function _addDirToCollection($dir = null, $index = null) { + protected function _addDirToCollection(Dir $dir = null, $index = null) { $dir = $dir === null ? $this->_createNewDir() : $dir; $collection = $this->dirCollection(); return $collection->addDir($dir, $index); diff --git a/tests/FQ/Tests/Collections/Query/AbstractQueryCollectionTests.php b/tests/FQ/Tests/Collections/Query/AbstractQueryCollectionTests.php new file mode 100644 index 0000000..99b5dc6 --- /dev/null +++ b/tests/FQ/Tests/Collections/Query/AbstractQueryCollectionTests.php @@ -0,0 +1,50 @@ +_queryCollection = $this->_createNewQueryCollection(); + } + + /** + * @return QueryCollection + */ + protected function queryCollection() + { + return $this->_queryCollection; + } + + /** + * @return QueryCollection + */ + protected function _createNewQueryCollection() + { + return new QueryCollection($this->_fqApp); + } + + protected function _addQueryToCollection($id = self::DEFAULT_QUERY_ID, FilesQuery $query = null) + { + $query = $query === null ? new FilesQuery($this->_fqApp) : $query; + $collection = $this->queryCollection(); + return $collection->addQuery($id, $query); + } + + function testIgnore() { + + } +} \ No newline at end of file diff --git a/tests/FQ/Tests/Collections/Query/QueryCollectionTest.php b/tests/FQ/Tests/Collections/Query/QueryCollectionTest.php new file mode 100644 index 0000000..d0c3c1f --- /dev/null +++ b/tests/FQ/Tests/Collections/Query/QueryCollectionTest.php @@ -0,0 +1,71 @@ +_fqApp); + $this->assertNotNull($queryCollection); + $this->assertTrue($queryCollection instanceof QueryCollection); + } + + public function testAddQuery() { + $query = $this->_addQueryToCollection(); + $this->assertNotNull($query); + $this->assertEquals(1, $this->queryCollection()->totalQueries()); + } + public function testAddQueryWithSameId() { + $this->setExpectedException('\FQ\Exceptions\QueryCollectionException'); + $this->_addQueryToCollection(); + $this->_addQueryToCollection(); + } + + public function testAddMultipleQueries() { + $firstQuery = $this->_addQueryToCollection(); + $secondQuery = $this->_addQueryToCollection(self::SECOND_QUERY_ID); + $this->assertNotNull($firstQuery); + $this->assertNotNull($secondQuery); + $this->assertEquals(2, $this->queryCollection()->totalQueries()); + } + + public function testRemoveQuery() { + $query = $this->_addQueryToCollection(); + $this->_addQueryToCollection('custom-id'); + $collection = $this->queryCollection(); + $this->assertTrue($collection->removeQuery('custom-id')); + $this->assertEquals(array( + self::DEFAULT_QUERY_ID => $query + ), $collection->queries()); + } + public function testRemoveQueryNotPresentInTheCollection() { + $collection = $this->queryCollection(); + $this->assertFalse($collection->removeQuery('does-not-exist')); + } + public function testRemoveAllDirs() { + $this->_addQueryToCollection(); + $this->_addQueryToCollection(self::SECOND_QUERY_ID); + $collection = $this->queryCollection(); + $collection->removeAllQueries(); + $this->assertEquals(array(), $collection->queries()); + } + public function testGetDirByIdThatDoesNotExist() { + $this->assertNull($this->queryCollection()->getQueryById('id_that_does_not_exist')); + } + + public function testGetDir() { + $dir = $this->_addQueryToCollection(); + $this->assertEquals($dir, $this->queryCollection()->getQuery($dir)); + $this->assertEquals($dir, $this->queryCollection()->getQuery(self::DEFAULT_QUERY_ID)); + $this->assertNull($this->queryCollection()->getQuery(null)); + } + + public function testIsInCollection() { + $query = $this->_addQueryToCollection(); + $this->assertTrue($this->queryCollection()->isInCollection($query)); + $this->assertFalse($this->queryCollection()->isInCollection(new FilesQuery($this->_fqApp))); + } +} \ No newline at end of file diff --git a/tests/FQ/Tests/Query/AbstractFilesQueryTests.php b/tests/FQ/Tests/Query/AbstractFilesQueryTests.php index cb304c4..e1a07bc 100644 --- a/tests/FQ/Tests/Query/AbstractFilesQueryTests.php +++ b/tests/FQ/Tests/Query/AbstractFilesQueryTests.php @@ -2,8 +2,6 @@ namespace FQ\Tests\Query; -use FQ\Collections\Dirs\DirCollection; -use FQ\Dirs\ChildDir; use FQ\Query\FilesQuery; use FQ\Query\FilesQueryChild; use FQ\Tests\AbstractFQTest; @@ -45,8 +43,8 @@ protected function queryChild() { return $this->_queryChild; } - protected function runQuery($filename = 'File2') { - return $this->query()->run($filename); + protected function runQuery($filename = 'File2', $throwErrors = false) { + return $this->query()->run($filename, $throwErrors); } /** diff --git a/tests/FQ/Tests/Query/FilesQueryTest.php b/tests/FQ/Tests/Query/FilesQueryTest.php index 1e5f2b8..c97dbeb 100644 --- a/tests/FQ/Tests/Query/FilesQueryTest.php +++ b/tests/FQ/Tests/Query/FilesQueryTest.php @@ -177,6 +177,15 @@ public function testRunQueryWhenRequirementsAreNotMet() { $this->assertNotNull($query->queryError()); } + public function testRunQueryWhenRequirementsAreNotMetAndThrowErrorsIsSetToTrue() { + $this->setExpectedException('FQ\Exceptions\FileQueryRequirementsException'); + $query = $this->query(); + $query->requirements()->addRequirement(FilesQueryRequirements::REQUIRE_ALL); + $rootDir = $this->_newFictitiousRootDir(false); + $this->files()->addRootDir($rootDir); + $this->runQuery('File2', true); + } + public function testRunQueryWhenNoRootDirsAreSet() { $this->setExpectedException('FQ\Exceptions\FileQueryException', 'Query is trying to run with file "File2" but no root directories are configured. Make sure sure you have added at least one root directory with Files::addRootDir() before you run a query'); $this->files()->removeAllRootDirs(); @@ -197,6 +206,17 @@ public function testRunQueryAndLoadFileAfterwardsButFails() { $query->load(); $this->assertTrue(class_exists('File2')); } + public function testRunQueryTwice() { + $query = $this->query(); + + $this->runQuery(); + $query->load(); + $this->assertTrue(class_exists('File2')); + + $this->runQuery('File1'); + $query->load(); + $this->assertTrue(class_exists('File1')); + } public function testListPathsWhenQueryHasNotRan() { $this->setExpectedException('FQ\Exceptions\FileQueryException', 'You must first call the "run" method before you can retrieve query information'); diff --git a/tests/FQ/Tests/Utils/DirsTest.php b/tests/FQ/Tests/Utils/DirsTest.php new file mode 100644 index 0000000..daa8b61 --- /dev/null +++ b/tests/FQ/Tests/Utils/DirsTest.php @@ -0,0 +1,45 @@ +assertTrue(Dirs::equalDirs(array(), array())); + + $rootDir1 = $this->_newActualRootDir(); + $rootDir2 = $this->_newActualRootDir('id'); + + $this->assertFalse(Dirs::equalDirs(array( + $this->_newActualRootDir() + ), array( + $this->_newActualRootDir() + ))); + + $this->assertTrue(Dirs::equalDirs(array( + $rootDir1 + ), array( + $rootDir1 + ))); + + $this->assertTrue(Dirs::equalDirs(array( + $rootDir1, + $rootDir2 + ), array( + $rootDir1, + $rootDir2 + ))); + + $this->assertFalse(Dirs::equalDirs(array( + $rootDir2, + $rootDir1 + ), array( + $rootDir1, + $rootDir2 + ))); + } + +} \ No newline at end of file