Actualización

This commit is contained in:
Xes
2025-04-10 12:24:57 +02:00
parent 8969cc929d
commit 45420b6f0d
39760 changed files with 4303286 additions and 0 deletions

View File

@@ -0,0 +1,36 @@
<?php
namespace Test\Fixture\Document;
use Doctrine\ODM\MongoDB\Mapping\Annotations as ODM;
/**
* @ODM\Document
*/
class Article
{
/**
* @ODM\Id
*/
private $id;
/**
* @ODM\Field(type="string")
*/
private $title;
public function getId()
{
return $this->id;
}
public function setTitle($title)
{
$this->title = $title;
}
public function getTitle()
{
return $this->title;
}
}

View File

@@ -0,0 +1,63 @@
<?php
namespace Test\Fixture\Document;
use Doctrine\ODM\MongoDB\Mapping\Annotations as ODM;
/**
* @ODM\Document
*/
class Image
{
/**
* @ODM\Id
*/
private $id;
/**
* @ODM\Field
*/
private $title;
/**
* @ODM\File
*/
private $file;
/**
* Set file.
*
* @param integer $file
* @return Image
*/
public function setFile($file)
{
$this->file = $file;
return $this;
}
/**
* Get file.
*
* @return integer
*/
public function getFile()
{
return $this->file;
}
public function getId()
{
return $this->id;
}
public function setTitle($title)
{
$this->title = $title;
}
public function getTitle()
{
return $this->title;
}
}

View File

@@ -0,0 +1,51 @@
<?php
namespace Test\Fixture\Document\PHPCR;
use Doctrine\ODM\PHPCR\Mapping\Annotations as PHPCR;
/**
* @PHPCR\Document
*/
class Article
{
/**
* @PHPCR\Id
*/
private $id;
/**
* @PHPCR\ParentDocument
*/
private $parent;
/**
* @PHPCR\Field(type="string")
*/
private $title;
public function getId()
{
return $this->id;
}
public function getParent()
{
return $this->parent;
}
public function setParent($parent)
{
$this->parent = $parent;
}
public function setTitle($title)
{
$this->title = $title;
}
public function getTitle()
{
return $this->title;
}
}

View File

@@ -0,0 +1,53 @@
<?php
namespace Test\Fixture\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
*/
class Article
{
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(length=64)
*/
private $title;
/**
* @ORM\Column(type="boolean")
*/
private $enabled = true;
public function getId()
{
return $this->id;
}
public function setTitle($title)
{
$this->title = $title;
}
public function getTitle()
{
return $this->title;
}
public function setEnabled($enabled)
{
$this->enabled = $enabled;
}
public function isEnabled()
{
return $this->enabled;
}
}

View File

@@ -0,0 +1,78 @@
<?php
namespace Test\Fixture\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
*/
class Composite
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(length=64)
*/
private $title;
/**
* @ORM\Id
* @ORM\Column(type="string")
*/
private $uid;
/**
* Sets uid.
*
* @param mixed $uid
*/
public function setUid($uid)
{
$this->uid = $uid;
}
/**
* Returns uid.
*
* @return mixed
*/
public function getUid()
{
return $this->uid;
}
/**
* Sets Id.
*
* @param $id
*/
public function setId($id)
{
$this->id = $id;
}
/**
* Returns Id.
*
* @return integer
*/
public function getId()
{
return $this->id;
}
public function setTitle($title)
{
$this->title = $title;
}
public function getTitle()
{
return $this->title;
}
}

View File

@@ -0,0 +1,95 @@
<?php
namespace Test\Fixture\Entity\Shop;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* @ORM\Entity
*/
class Product
{
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(length=64)
*/
private $title;
/**
* @ORM\Column(length=255, nullable=true)
*/
private $description;
/**
* @ORM\Column(type="float", nullable=false)
*/
private $price;
/**
* @ORM\ManyToMany(targetEntity="Tag")
*/
private $tags;
/**
* @ORM\Column(type="integer")
*/
private $numTags = 0;
public function __construct()
{
$this->tags = new ArrayCollection;
}
public function getId()
{
return $this->id;
}
public function setTitle($title)
{
$this->title = $title;
}
public function getTitle()
{
return $this->title;
}
public function setDescription($description)
{
$this->description = $description;
}
public function getDescription()
{
return $this->description;
}
public function setPrice($price)
{
$this->price = $price;
}
public function getPrice()
{
return $this->price;
}
public function addTag(Tag $tag)
{
$this->numTags++;
$this->tags[] = $tag;
}
public function getTags()
{
return $this->tags;
}
}

View File

@@ -0,0 +1,38 @@
<?php
namespace Test\Fixture\Entity\Shop;
use Doctrine\ORM\Mapping as ORM;
/**
* @ORM\Entity
*/
class Tag
{
/**
* @ORM\Id
* @ORM\GeneratedValue
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(length=64)
*/
private $name;
public function getId()
{
return $this->id;
}
public function setName($name)
{
$this->name = $name;
}
public function getName()
{
return $this->name;
}
}

View File

@@ -0,0 +1,22 @@
<?php
namespace Test\Mock;
use Knp\Component\Pager\Event\ItemsEvent;
use Knp\Component\Pager\Event\Subscriber\Paginate\ArraySubscriber;
class CustomParameterSubscriber extends ArraySubscriber
{
static function getSubscribedEvents()
{
return array(
'knp_pager.items' => array('items', 10)
);
}
function items(ItemsEvent $e)
{
$e->setCustomPaginationParameter('test', 'val');
parent::items($e);
}
}

View File

@@ -0,0 +1,23 @@
<?php
namespace Test\Mock;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Knp\Component\Pager\Event\PaginationEvent;
use Knp\Component\Pager\Pagination\SlidingPagination;
class PaginationSubscriber implements EventSubscriberInterface
{
static function getSubscribedEvents()
{
return array(
'knp_pager.pagination' => array('pagination', 0)
);
}
function pagination(PaginationEvent $e)
{
$e->setPagination(new SlidingPagination);
$e->stopPropagation();
}
}

View File

@@ -0,0 +1,63 @@
<?php
use Test\Tool\BaseTestCase;
use Knp\Component\Pager\Paginator;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Test\Mock\PaginationSubscriber as MockPaginationSubscriber;
use Test\Mock\CustomParameterSubscriber;
use Knp\Component\Pager\Event\Subscriber\Paginate\ArraySubscriber;
use Knp\Component\Pager\PaginatorInterface;
class AbstractPaginationTest extends BaseTestCase
{
/**
* @test
*/
function shouldCustomizeParameterNames()
{
$dispatcher = new EventDispatcher;
$dispatcher->addSubscriber(new MockPaginationSubscriber); // pagination view
$dispatcher->addSubscriber(new ArraySubscriber);
$p = new Paginator($dispatcher);
$items = array('first', 'second');
$view = $p->paginate($items, 1, 10);
// test default names first
$this->assertEquals('page', $view->getPaginatorOption(PaginatorInterface::PAGE_PARAMETER_NAME));
$this->assertEquals('sort', $view->getPaginatorOption(PaginatorInterface::SORT_FIELD_PARAMETER_NAME));
$this->assertEquals('direction', $view->getPaginatorOption(PaginatorInterface::SORT_DIRECTION_PARAMETER_NAME));
$this->assertTrue($view->getPaginatorOption(PaginatorInterface::DISTINCT));
$this->assertNull($view->getPaginatorOption(PaginatorInterface::SORT_FIELD_WHITELIST));
// now customize
$options = array(
PaginatorInterface::PAGE_PARAMETER_NAME => 'p',
PaginatorInterface::SORT_FIELD_PARAMETER_NAME => 's',
PaginatorInterface::SORT_DIRECTION_PARAMETER_NAME => 'd',
PaginatorInterface::DISTINCT => false,
PaginatorInterface::SORT_FIELD_WHITELIST => array('a.f', 'a.d')
);
$view = $p->paginate($items, 1, 10, $options);
$this->assertEquals('p', $view->getPaginatorOption(PaginatorInterface::PAGE_PARAMETER_NAME));
$this->assertEquals('s', $view->getPaginatorOption(PaginatorInterface::SORT_FIELD_PARAMETER_NAME));
$this->assertEquals('d', $view->getPaginatorOption(PaginatorInterface::SORT_DIRECTION_PARAMETER_NAME));
$this->assertFalse($view->getPaginatorOption(PaginatorInterface::DISTINCT));
$this->assertEquals(array('a.f', 'a.d'), $view->getPaginatorOption(PaginatorInterface::SORT_FIELD_WHITELIST));
// change default paginator options
$p->setDefaultPaginatorOptions(array(
PaginatorInterface::PAGE_PARAMETER_NAME => 'pg',
PaginatorInterface::SORT_FIELD_PARAMETER_NAME => 'srt',
PaginatorInterface::SORT_DIRECTION_PARAMETER_NAME => 'dir'
));
$view = $p->paginate($items, 1, 10);
$this->assertEquals('pg', $view->getPaginatorOption(PaginatorInterface::PAGE_PARAMETER_NAME));
$this->assertEquals('srt', $view->getPaginatorOption(PaginatorInterface::SORT_FIELD_PARAMETER_NAME));
$this->assertEquals('dir', $view->getPaginatorOption(PaginatorInterface::SORT_DIRECTION_PARAMETER_NAME));
$this->assertTrue($view->getPaginatorOption(PaginatorInterface::DISTINCT));
}
}

View File

@@ -0,0 +1,27 @@
<?php
use Test\Tool\BaseTestCase;
use Knp\Component\Pager\Paginator;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Test\Mock\PaginationSubscriber as MockPaginationSubscriber;
use Test\Mock\CustomParameterSubscriber;
class CustomParameterTest extends BaseTestCase
{
/**
* @test
*/
function shouldGiveCustomParametersToPaginationView()
{
$dispatcher = new EventDispatcher;
$dispatcher->addSubscriber(new CustomParameterSubscriber);
$dispatcher->addSubscriber(new MockPaginationSubscriber); // pagination view
$p = new Paginator($dispatcher);
$items = array('first', 'second');
$view = $p->paginate($items, 1, 10);
$this->assertEquals('val', $view->getCustomParameter('test'));
$this->assertNull($view->getCustomParameter('nonExisting'));
}
}

View File

@@ -0,0 +1,106 @@
<?php
use Test\Tool\BaseTestCase;
use Knp\Component\Pager\Paginator;
use Knp\Component\Pager\Pagination\SlidingPagination;
use Knp\Component\Pager\Pagination\PaginationInterface;
use Knp\Component\Pager\Event\Subscriber\Paginate\PaginationSubscriber;
class SlidingTest extends BaseTestCase
{
/**
* @test
*/
function shouldBeAbleToProducePagination()
{
$p = new Paginator;
$items = range(1, 23);
$view = $p->paginate($items, 1, 10);
$view->renderer = function($data) {
return 'custom';
};
$this->assertEquals('custom', (string)$view);
$pagination = $view->getPaginationData();
$this->assertEquals(3, $pagination['last']);
$this->assertEquals(1, $pagination['first']);
$this->assertEquals(1, $pagination['current']);
$this->assertEquals(10, $pagination['numItemsPerPage']);
$this->assertEquals(3, $pagination['pageCount']);
$this->assertEquals(23, $pagination['totalCount']);
$this->assertEquals(2, $pagination['next']);
$this->assertEquals(array(1, 2, 3), $pagination['pagesInRange']);
$this->assertEquals(1, $pagination['firstPageInRange']);
$this->assertEquals(3, $pagination['lastPageInRange']);
$this->assertEquals(10, $pagination['currentItemCount']);
$this->assertEquals(1, $pagination['firstItemNumber']);
$this->assertEquals(10, $pagination['lastItemNumber']);
}
/**
* @test
*/
function shouldBeAbleToProduceWiderPagination()
{
$p = new Paginator;
$items = range(1, 43);
$view = $p->paginate($items, 4, 5);
$pagination = $view->getPaginationData();
$this->assertEquals(9, $pagination['last']);
$this->assertEquals(1, $pagination['first']);
$this->assertEquals(4, $pagination['current']);
$this->assertEquals(5, $pagination['numItemsPerPage']);
$this->assertEquals(9, $pagination['pageCount']);
$this->assertEquals(43, $pagination['totalCount']);
$this->assertEquals(5, $pagination['next']);
$this->assertEquals(3, $pagination['previous']);
$this->assertEquals(array(2, 3, 4, 5, 6), $pagination['pagesInRange']);
$this->assertEquals(2, $pagination['firstPageInRange']);
$this->assertEquals(6, $pagination['lastPageInRange']);
$this->assertEquals(5, $pagination['currentItemCount']);
$this->assertEquals(16, $pagination['firstItemNumber']);
$this->assertEquals(20, $pagination['lastItemNumber']);
}
/**
* @test
*/
function shouldHandleOddAndEvenRange()
{
$p = new Paginator;
$items = range(1, 43);
$view = $p->paginate($items, 4, 5);
$view->setPageRange(4);
$pagination = $view->getPaginationData();
$this->assertEquals(3, $pagination['previous']);
$this->assertEquals(array(3, 4, 5, 6), $pagination['pagesInRange']);
$this->assertEquals(3, $pagination['firstPageInRange']);
$this->assertEquals(6, $pagination['lastPageInRange']);
$view->setPageRange(3);
$pagination = $view->getPaginationData();
$this->assertEquals(3, $pagination['previous']);
$this->assertEquals(array(3, 4, 5), $pagination['pagesInRange']);
$this->assertEquals(3, $pagination['firstPageInRange']);
$this->assertEquals(5, $pagination['lastPageInRange']);
}
/**
* @test
*/
function shouldNotFallbackToPageInCaseIfExceedsItemLimit()
{
$p = new Paginator;
$view = $p->paginate(range(1, 9), 2, 10);
$items = $view->getItems();
$this->assertTrue(empty($items));
}
}

View File

@@ -0,0 +1,33 @@
<?php
use Test\Tool\BaseTestCase;
use Knp\Component\Pager\Paginator;
use Knp\Component\Pager\Pagination\SlidingPagination;
use Knp\Component\Pager\Pagination\PaginationInterface;
use Knp\Component\Pager\Event\Subscriber\Paginate\PaginationSubscriber;
class TraversableItemsTest extends BaseTestCase
{
/**
* @test
*/
function shouldBeAbleToUseTraversableItems()
{
$p = new Paginator;
$items = new \ArrayObject(range(1, 23));
$view = $p->paginate($items, 3, 10);
$view->renderer = function($data) {
return 'custom';
};
$this->assertEquals('custom', (string)$view);
$items = $view->getItems();
$this->assertTrue($items instanceof \ArrayObject);
$i = 21;
foreach ($view as $item) {
$this->assertEquals($i++, $item);
}
}
}

View File

@@ -0,0 +1,33 @@
<?php
use Test\Tool\BaseTestCase;
use Knp\Component\Pager\Paginator;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Knp\Component\Pager\Pagination\PaginationInterface;
use Knp\Component\Pager\Event\Subscriber\Paginate\PaginationSubscriber;
class PaginatorTest extends BaseTestCase
{
/**
* @test
* @expectedException RuntimeException
*/
function shouldNotBeAbleToPaginateWithoutListeners()
{
$p = new Paginator(new EventDispatcher);
$p->paginate(array());
}
/**
* @test
* @expectedException RuntimeException
*/
function shouldFailToPaginateUnsupportedValue()
{
$dispatcher = new EventDispatcher;
$dispatcher->addSubscriber(new PaginationSubscriber);
$p = new Paginator($dispatcher);
$view = $p->paginate(null, 1, 10);
}
}

View File

@@ -0,0 +1,706 @@
<?php
namespace Test\Pager\Subscriber\Filtration\Doctrine\ORM;
use Test\Tool\BaseTestCaseORM;
use Knp\Component\Pager\Paginator;
use Knp\Component\Pager\Pagination\SlidingPagination;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Knp\Component\Pager\Event\Subscriber\Paginate\PaginationSubscriber;
use Knp\Component\Pager\Event\Subscriber\Filtration\FiltrationSubscriber as Filtration;
use Test\Fixture\Entity\Article;
use Knp\Component\Pager\Event\Subscriber\Paginate\Doctrine\ORM\QuerySubscriber\UsesPaginator;
use Knp\Component\Pager\PaginatorInterface;
class QueryTest extends BaseTestCaseORM
{
/**
* @test
*/
public function shouldHandleApcQueryCache()
{
if (!extension_loaded('apc') || !ini_get('apc.enable_cli')) {
$this->markTestSkipped('APC extension is not loaded.');
}
$config = new \Doctrine\ORM\Configuration();
$config->setMetadataCacheImpl(new \Doctrine\Common\Cache\ApcCache());
$config->setQueryCacheImpl(new \Doctrine\Common\Cache\ApcCache());
$config->setProxyDir(__DIR__);
$config->setProxyNamespace('Gedmo\Mapping\Proxy');
$config->getAutoGenerateProxyClasses(false);
$config->setMetadataDriverImpl($this->getMetadataDriverImplementation());
$conn = array(
'driver' => 'pdo_sqlite',
'memory' => true,
);
$em = \Doctrine\ORM\EntityManager::create($conn, $config);
$schema = array_map(function ($class) use ($em) {
return $em->getClassMetadata($class);
}, (array) $this->getUsedEntityFixtures());
$schemaTool = new \Doctrine\ORM\Tools\SchemaTool($em);
$schemaTool->dropSchema(array());
$schemaTool->createSchema($schema);
$this->populate($em);
$_GET['filterField'] = 'a.title';
$_GET['filterValue'] = 'summer';
$query = $em->createQuery('SELECT a FROM Test\Fixture\Entity\Article a');
$p = new Paginator();
$view = $p->paginate($query, 1, 10);
$query = $em->createQuery('SELECT a FROM Test\Fixture\Entity\Article a');
$view = $p->paginate($query, 1, 10);
}
/**
* @test
*/
public function shouldFilterSimpleDoctrineQuery()
{
$em = $this->getMockSqliteEntityManager();
$this->populate($em);
$dispatcher = new EventDispatcher();
$dispatcher->addSubscriber(new PaginationSubscriber());
$dispatcher->addSubscriber(new Filtration());
$p = new Paginator($dispatcher);
$_GET['filterParam'] = 'a.title';
$_GET['filterValue'] = '*er';
$this->startQueryLog();
$query = $this->em->createQuery('SELECT a FROM Test\Fixture\Entity\Article a');
$query->setHint(UsesPaginator::HINT_FETCH_JOIN_COLLECTION, false);
$view = $p->paginate($query, 1, 10);
$items = $view->getItems();
$this->assertEquals(2, count($items));
$this->assertEquals('summer', $items[0]->getTitle());
$this->assertEquals('winter', $items[1]->getTitle());
$_GET['filterValue'] = 'summer';
$view = $p->paginate($query, 1, 10);
$items = $view->getItems();
$this->assertEquals(1, count($items));
$this->assertEquals('summer', $items[0]->getTitle());
$this->assertEquals(4, $this->queryAnalyzer->getNumExecutedQueries());
$executed = $this->queryAnalyzer->getExecutedQueries();
// Different aliases separators according to Doctrine version
if (version_compare(\Doctrine\ORM\Version::VERSION, '2.5', '<')) {
$this->assertEquals('SELECT a0_.id AS id0, a0_.title AS title1, a0_.enabled AS enabled2 FROM Article a0_ WHERE a0_.title LIKE \'%er\' LIMIT 10 OFFSET 0', $executed[1]);
$this->assertEquals('SELECT a0_.id AS id0, a0_.title AS title1, a0_.enabled AS enabled2 FROM Article a0_ WHERE a0_.title LIKE \'summer\' LIMIT 10 OFFSET 0', $executed[3]);
} else {
$this->assertEquals('SELECT a0_.id AS id_0, a0_.title AS title_1, a0_.enabled AS enabled_2 FROM Article a0_ WHERE a0_.title LIKE \'%er\' LIMIT 10 OFFSET 0', $executed[1]);
$this->assertEquals('SELECT a0_.id AS id_0, a0_.title AS title_1, a0_.enabled AS enabled_2 FROM Article a0_ WHERE a0_.title LIKE \'summer\' LIMIT 10 OFFSET 0', $executed[3]);
}
}
/**
* @test
*/
public function shouldFilterBooleanFilterValues()
{
$em = $this->getMockSqliteEntityManager();
$this->populate($em);
$dispatcher = new EventDispatcher();
$dispatcher->addSubscriber(new PaginationSubscriber());
$dispatcher->addSubscriber(new Filtration());
$p = new Paginator($dispatcher);
$this->startQueryLog();
$_GET['filterParam'] = 'a.enabled';
$_GET['filterValue'] = '1';
$query = $this->em->createQuery('SELECT a FROM Test\Fixture\Entity\Article a');
$query->setHint(UsesPaginator::HINT_FETCH_JOIN_COLLECTION, false);
$view = $p->paginate($query, 1, 10);
$items = $view->getItems();
$this->assertEquals(2, count($items));
$this->assertEquals('summer', $items[0]->getTitle());
$this->assertEquals('winter', $items[1]->getTitle());
$_GET['filterValue'] = 'true';
$query = $this->em->createQuery('SELECT a FROM Test\Fixture\Entity\Article a');
$query->setHint(UsesPaginator::HINT_FETCH_JOIN_COLLECTION, false);
$view = $p->paginate($query, 1, 10);
$items = $view->getItems();
$this->assertEquals(2, count($items));
$this->assertEquals('summer', $items[0]->getTitle());
$this->assertEquals('winter', $items[1]->getTitle());
$_GET['filterValue'] = '0';
$view = $p->paginate($query, 1, 10);
$items = $view->getItems();
$this->assertEquals(2, count($items));
$this->assertEquals('autumn', $items[0]->getTitle());
$this->assertEquals('spring', $items[1]->getTitle());
$_GET['filterValue'] = 'false';
$view = $p->paginate($query, 1, 10);
$items = $view->getItems();
$this->assertEquals(2, count($items));
$this->assertEquals('autumn', $items[0]->getTitle());
$this->assertEquals('spring', $items[1]->getTitle());
$this->assertEquals(8, $this->queryAnalyzer->getNumExecutedQueries());
$executed = $this->queryAnalyzer->getExecutedQueries();
// Different aliases separators according to Doctrine version
if (version_compare(\Doctrine\ORM\Version::VERSION, '2.5', '<')) {
$this->assertEquals('SELECT a0_.id AS id0, a0_.title AS title1, a0_.enabled AS enabled2 FROM Article a0_ WHERE a0_.enabled = 1 LIMIT 10 OFFSET 0', $executed[1]);
$this->assertEquals('SELECT a0_.id AS id0, a0_.title AS title1, a0_.enabled AS enabled2 FROM Article a0_ WHERE a0_.enabled = 1 LIMIT 10 OFFSET 0', $executed[3]);
$this->assertEquals('SELECT a0_.id AS id0, a0_.title AS title1, a0_.enabled AS enabled2 FROM Article a0_ WHERE a0_.enabled = 0 LIMIT 10 OFFSET 0', $executed[5]);
$this->assertEquals('SELECT a0_.id AS id0, a0_.title AS title1, a0_.enabled AS enabled2 FROM Article a0_ WHERE a0_.enabled = 0 LIMIT 10 OFFSET 0', $executed[7]);
} else {
$this->assertEquals('SELECT a0_.id AS id_0, a0_.title AS title_1, a0_.enabled AS enabled_2 FROM Article a0_ WHERE a0_.enabled = 1 LIMIT 10 OFFSET 0', $executed[1]);
$this->assertEquals('SELECT a0_.id AS id_0, a0_.title AS title_1, a0_.enabled AS enabled_2 FROM Article a0_ WHERE a0_.enabled = 1 LIMIT 10 OFFSET 0', $executed[3]);
$this->assertEquals('SELECT a0_.id AS id_0, a0_.title AS title_1, a0_.enabled AS enabled_2 FROM Article a0_ WHERE a0_.enabled = 0 LIMIT 10 OFFSET 0', $executed[5]);
$this->assertEquals('SELECT a0_.id AS id_0, a0_.title AS title_1, a0_.enabled AS enabled_2 FROM Article a0_ WHERE a0_.enabled = 0 LIMIT 10 OFFSET 0', $executed[7]);
}
}
/**
* @test
*/
public function shouldNotFilterInvalidBooleanFilterValues()
{
$em = $this->getMockSqliteEntityManager();
$this->populate($em);
$dispatcher = new EventDispatcher();
$dispatcher->addSubscriber(new PaginationSubscriber());
$dispatcher->addSubscriber(new Filtration());
$p = new Paginator($dispatcher);
$this->startQueryLog();
$_GET['filterParam'] = 'a.enabled';
$_GET['filterValue'] = 'invalid_boolean';
$query = $this->em->createQuery('SELECT a FROM Test\Fixture\Entity\Article a');
$query->setHint(UsesPaginator::HINT_FETCH_JOIN_COLLECTION, false);
$view = $p->paginate($query, 1, 10);
$items = $view->getItems();
$this->assertEquals(4, count($items));
$this->assertEquals(2, $this->queryAnalyzer->getNumExecutedQueries());
$executed = $this->queryAnalyzer->getExecutedQueries();
// Different aliases separators according to Doctrine version
if (version_compare(\Doctrine\ORM\Version::VERSION, '2.5', '<')) {
$this->assertEquals('SELECT a0_.id AS id0, a0_.title AS title1, a0_.enabled AS enabled2 FROM Article a0_ LIMIT 10 OFFSET 0', $executed[1]);
} else {
$this->assertEquals('SELECT a0_.id AS id_0, a0_.title AS title_1, a0_.enabled AS enabled_2 FROM Article a0_ LIMIT 10 OFFSET 0', $executed[1]);
}
}
/**
* @test
*/
public function shouldFilterNumericFilterValues()
{
$em = $this->getMockSqliteEntityManager();
$this->populateNumeric($em);
$dispatcher = new EventDispatcher();
$dispatcher->addSubscriber(new PaginationSubscriber());
$dispatcher->addSubscriber(new Filtration());
$p = new Paginator($dispatcher);
$this->startQueryLog();
$_GET['filterParam'] = 'a.title';
$_GET['filterValue'] = '0';
$query = $this->em->createQuery('SELECT a FROM Test\Fixture\Entity\Article a');
$query->setHint(UsesPaginator::HINT_FETCH_JOIN_COLLECTION, false);
$view = $p->paginate($query, 1, 10);
$items = $view->getItems();
$this->assertEquals(1, count($items));
$this->assertEquals('0', $items[0]->getTitle());
$_GET['filterValue'] = '1';
$query = $this->em->createQuery('SELECT a FROM Test\Fixture\Entity\Article a');
$query->setHint(UsesPaginator::HINT_FETCH_JOIN_COLLECTION, false);
$view = $p->paginate($query, 1, 10);
$items = $view->getItems();
$this->assertEquals(1, count($items));
$this->assertEquals('1', $items[0]->getTitle());
$this->assertEquals(4, $this->queryAnalyzer->getNumExecutedQueries());
$executed = $this->queryAnalyzer->getExecutedQueries();
// Different aliases separators according to Doctrine version
if (version_compare(\Doctrine\ORM\Version::VERSION, '2.5', '<')) {
$this->assertEquals('SELECT a0_.id AS id0, a0_.title AS title1, a0_.enabled AS enabled2 FROM Article a0_ WHERE a0_.title = 0 LIMIT 10 OFFSET 0', $executed[1]);
$this->assertEquals('SELECT a0_.id AS id0, a0_.title AS title1, a0_.enabled AS enabled2 FROM Article a0_ WHERE a0_.title = 1 LIMIT 10 OFFSET 0', $executed[3]);
} else {
$this->assertEquals('SELECT a0_.id AS id_0, a0_.title AS title_1, a0_.enabled AS enabled_2 FROM Article a0_ WHERE a0_.title = 0 LIMIT 10 OFFSET 0', $executed[1]);
$this->assertEquals('SELECT a0_.id AS id_0, a0_.title AS title_1, a0_.enabled AS enabled_2 FROM Article a0_ WHERE a0_.title = 1 LIMIT 10 OFFSET 0', $executed[3]);
}
}
/**
* @test
*/
public function shouldFilterComplexDoctrineQuery()
{
$em = $this->getMockSqliteEntityManager();
$this->populate($em);
$dispatcher = new EventDispatcher();
$dispatcher->addSubscriber(new PaginationSubscriber());
$dispatcher->addSubscriber(new Filtration());
$p = new Paginator($dispatcher);
$_GET['filterParam'] = 'a.title';
$_GET['filterValue'] = '*er';
$this->startQueryLog();
$query = $this->em->createQuery('SELECT a FROM Test\Fixture\Entity\Article a WHERE a.title <> \'\' AND (a.title LIKE \'summer\' OR a.title LIKE \'spring\')');
$query->setHint(UsesPaginator::HINT_FETCH_JOIN_COLLECTION, false);
$view = $p->paginate($query, 1, 10);
$items = $view->getItems();
$this->assertEquals(1, count($items));
$this->assertEquals('summer', $items[0]->getTitle());
$_GET['filterParam'] = 'a.id,a.title';
$view = $p->paginate($query, 1, 10);
$items = $view->getItems();
$this->assertEquals(1, count($items));
$this->assertEquals('summer', $items[0]->getTitle());
$executed = $this->queryAnalyzer->getExecutedQueries();
$query = $this->em->createQuery('SELECT a FROM Test\Fixture\Entity\Article a WHERE a.title <> \'\' OR (a.title LIKE \'summer\' OR a.title LIKE \'spring\')');
$query->setHint(UsesPaginator::HINT_FETCH_JOIN_COLLECTION, false);
$view = $p->paginate($query, 1, 10);
$items = $view->getItems();
$this->assertEquals(2, count($items));
$this->assertEquals('summer', $items[0]->getTitle());
$this->assertEquals('winter', $items[1]->getTitle());
$executed = $this->queryAnalyzer->getExecutedQueries();
$query = $this->em->createQuery('SELECT a FROM Test\Fixture\Entity\Article a WHERE a.title <> \'\'');
$query->setHint(UsesPaginator::HINT_FETCH_JOIN_COLLECTION, false);
$view = $p->paginate($query, 1, 10);
$items = $view->getItems();
$this->assertEquals(2, count($items));
$this->assertEquals('summer', $items[0]->getTitle());
$this->assertEquals('winter', $items[1]->getTitle());
$executed = $this->queryAnalyzer->getExecutedQueries();
$_GET['filterParam'] = 'a.title';
$view = $p->paginate($query, 1, 10);
$items = $view->getItems();
$this->assertEquals(2, count($items));
$this->assertEquals('summer', $items[0]->getTitle());
$this->assertEquals('winter', $items[1]->getTitle());
$executed = $this->queryAnalyzer->getExecutedQueries();
// Different aliases separators according to Doctrine version
if (version_compare(\Doctrine\ORM\Version::VERSION, '2.5', '<')) {
$this->assertEquals('SELECT a0_.id AS id0, a0_.title AS title1, a0_.enabled AS enabled2 FROM Article a0_ WHERE a0_.title LIKE \'%er\' AND a0_.title <> \'\' AND (a0_.title LIKE \'summer\' OR a0_.title LIKE \'spring\') LIMIT 10 OFFSET 0', $executed[1]);
$this->assertEquals('SELECT a0_.id AS id0, a0_.title AS title1, a0_.enabled AS enabled2 FROM Article a0_ WHERE (a0_.id LIKE \'%er\' OR a0_.title LIKE \'%er\') AND a0_.title <> \'\' AND (a0_.title LIKE \'summer\' OR a0_.title LIKE \'spring\') LIMIT 10 OFFSET 0', $executed[3]);
$this->assertEquals('SELECT a0_.id AS id0, a0_.title AS title1, a0_.enabled AS enabled2 FROM Article a0_ WHERE (a0_.id LIKE \'%er\' OR a0_.title LIKE \'%er\') AND (a0_.title <> \'\' OR (a0_.title LIKE \'summer\' OR a0_.title LIKE \'spring\')) LIMIT 10 OFFSET 0', $executed[5]);
$this->assertEquals('SELECT a0_.id AS id0, a0_.title AS title1, a0_.enabled AS enabled2 FROM Article a0_ WHERE (a0_.id LIKE \'%er\' OR a0_.title LIKE \'%er\') AND a0_.title <> \'\' LIMIT 10 OFFSET 0', $executed[7]);
$this->assertEquals('SELECT a0_.id AS id0, a0_.title AS title1, a0_.enabled AS enabled2 FROM Article a0_ WHERE a0_.title LIKE \'%er\' AND a0_.title <> \'\' LIMIT 10 OFFSET 0', $executed[9]);
} else {
$this->assertEquals('SELECT a0_.id AS id_0, a0_.title AS title_1, a0_.enabled AS enabled_2 FROM Article a0_ WHERE a0_.title LIKE \'%er\' AND a0_.title <> \'\' AND (a0_.title LIKE \'summer\' OR a0_.title LIKE \'spring\') LIMIT 10 OFFSET 0', $executed[1]);
$this->assertEquals('SELECT a0_.id AS id_0, a0_.title AS title_1, a0_.enabled AS enabled_2 FROM Article a0_ WHERE (a0_.id LIKE \'%er\' OR a0_.title LIKE \'%er\') AND a0_.title <> \'\' AND (a0_.title LIKE \'summer\' OR a0_.title LIKE \'spring\') LIMIT 10 OFFSET 0', $executed[3]);
$this->assertEquals('SELECT a0_.id AS id_0, a0_.title AS title_1, a0_.enabled AS enabled_2 FROM Article a0_ WHERE (a0_.id LIKE \'%er\' OR a0_.title LIKE \'%er\') AND (a0_.title <> \'\' OR (a0_.title LIKE \'summer\' OR a0_.title LIKE \'spring\')) LIMIT 10 OFFSET 0', $executed[5]);
$this->assertEquals('SELECT a0_.id AS id_0, a0_.title AS title_1, a0_.enabled AS enabled_2 FROM Article a0_ WHERE (a0_.id LIKE \'%er\' OR a0_.title LIKE \'%er\') AND a0_.title <> \'\' LIMIT 10 OFFSET 0', $executed[7]);
$this->assertEquals('SELECT a0_.id AS id_0, a0_.title AS title_1, a0_.enabled AS enabled_2 FROM Article a0_ WHERE a0_.title LIKE \'%er\' AND a0_.title <> \'\' LIMIT 10 OFFSET 0', $executed[9]);
}
}
/**
* @test
*/
public function shouldFilterSimpleDoctrineQueryWithMultipleProperties()
{
$em = $this->getMockSqliteEntityManager();
$this->populate($em);
$dispatcher = new EventDispatcher();
$dispatcher->addSubscriber(new PaginationSubscriber());
$dispatcher->addSubscriber(new Filtration());
$p = new Paginator($dispatcher);
$_GET['filterParam'] = 'a.id,a.title';
$_GET['filterValue'] = '*er';
$this->startQueryLog();
$query = $this->em->createQuery('SELECT a FROM Test\Fixture\Entity\Article a');
$query->setHint(UsesPaginator::HINT_FETCH_JOIN_COLLECTION, false);
$view = $p->paginate($query, 1, 10);
$items = $view->getItems();
$this->assertEquals(2, count($items));
$this->assertEquals('summer', $items[0]->getTitle());
$this->assertEquals('winter', $items[1]->getTitle());
$_GET['filterParam'] = array('a.id', 'a.title');
$view = $p->paginate($query, 1, 10);
$items = $view->getItems();
$this->assertEquals(2, count($items));
$this->assertEquals('summer', $items[0]->getTitle());
$this->assertEquals('winter', $items[1]->getTitle());
$executed = $this->queryAnalyzer->getExecutedQueries();
// Different aliases separators according to Doctrine version
if (version_compare(\Doctrine\ORM\Version::VERSION, '2.5', '<')) {
$this->assertEquals('SELECT a0_.id AS id0, a0_.title AS title1, a0_.enabled AS enabled2 FROM Article a0_ WHERE a0_.id LIKE \'%er\' OR a0_.title LIKE \'%er\' LIMIT 10 OFFSET 0', $executed[1]);
$this->assertEquals('SELECT a0_.id AS id0, a0_.title AS title1, a0_.enabled AS enabled2 FROM Article a0_ WHERE a0_.id LIKE \'%er\' OR a0_.title LIKE \'%er\' LIMIT 10 OFFSET 0', $executed[3]);
} else {
$this->assertEquals('SELECT a0_.id AS id_0, a0_.title AS title_1, a0_.enabled AS enabled_2 FROM Article a0_ WHERE a0_.id LIKE \'%er\' OR a0_.title LIKE \'%er\' LIMIT 10 OFFSET 0', $executed[1]);
$this->assertEquals('SELECT a0_.id AS id_0, a0_.title AS title_1, a0_.enabled AS enabled_2 FROM Article a0_ WHERE a0_.id LIKE \'%er\' OR a0_.title LIKE \'%er\' LIMIT 10 OFFSET 0', $executed[3]);
}
}
/**
* @test
*/
public function shouldFilterComplexDoctrineQueryWithMultipleProperties()
{
$em = $this->getMockSqliteEntityManager();
$this->populate($em);
$dispatcher = new EventDispatcher();
$dispatcher->addSubscriber(new PaginationSubscriber());
$dispatcher->addSubscriber(new Filtration());
$p = new Paginator($dispatcher);
$_GET['filterParam'] = 'a.id,a.title';
$_GET['filterValue'] = '*er';
$this->startQueryLog();
$query = $this->em->createQuery('SELECT a FROM Test\Fixture\Entity\Article a WHERE a.title <> \'\' AND (a.title LIKE \'summer\' OR a.title LIKE \'spring\')');
$query->setHint(UsesPaginator::HINT_FETCH_JOIN_COLLECTION, false);
$view = $p->paginate($query, 1, 10);
$items = $view->getItems();
$this->assertEquals(1, count($items));
$this->assertEquals('summer', $items[0]->getTitle());
$executed = $this->queryAnalyzer->getExecutedQueries();
// Different aliases separators according to Doctrine version
if (version_compare(\Doctrine\ORM\Version::VERSION, '2.5', '<')) {
$this->assertEquals('SELECT a0_.id AS id0, a0_.title AS title1, a0_.enabled AS enabled2 FROM Article a0_ WHERE (a0_.id LIKE \'%er\' OR a0_.title LIKE \'%er\') AND a0_.title <> \'\' AND (a0_.title LIKE \'summer\' OR a0_.title LIKE \'spring\') LIMIT 10 OFFSET 0', $executed[1]);
} else {
$this->assertEquals('SELECT a0_.id AS id_0, a0_.title AS title_1, a0_.enabled AS enabled_2 FROM Article a0_ WHERE (a0_.id LIKE \'%er\' OR a0_.title LIKE \'%er\') AND a0_.title <> \'\' AND (a0_.title LIKE \'summer\' OR a0_.title LIKE \'spring\') LIMIT 10 OFFSET 0', $executed[1]);
}
}
/**
* @test
* @expectedException UnexpectedValueException
*/
public function shouldValidateFiltrationParameter()
{
$_GET['filterParam'] = '"a.title\'';
$_GET['filterValue'] = 'summer';
$query = $this
->getMockSqliteEntityManager()
->createQuery('SELECT a FROM Test\Fixture\Entity\Article a')
;
$dispatcher = new EventDispatcher();
$dispatcher->addSubscriber(new PaginationSubscriber());
$dispatcher->addSubscriber(new Filtration());
$p = new Paginator($dispatcher);
$view = $p->paginate($query, 1, 10);
$items = $view->getItems();
}
/**
* @test
* @expectedException UnexpectedValueException
*/
public function shouldValidateFiltrationParameterWithoutAlias()
{
$_GET['filterParam'] = 'title';
$_GET['filterValue'] = 'summer';
$query = $this
->getMockSqliteEntityManager()
->createQuery('SELECT a FROM Test\Fixture\Entity\Article a')
;
$dispatcher = new EventDispatcher();
$dispatcher->addSubscriber(new PaginationSubscriber());
$dispatcher->addSubscriber(new Filtration());
$p = new Paginator($dispatcher);
$view = $p->paginate($query, 1, 10);
$items = $view->getItems();
}
/**
* @test
* @expectedException UnexpectedValueException
*/
public function shouldValidateFiltrationParameterExistance()
{
$_GET['filterParam'] = 'a.nonExistantField';
$_GET['filterValue'] = 'summer';
$query = $this
->getMockSqliteEntityManager()
->createQuery('SELECT a FROM Test\Fixture\Entity\Article a')
;
$dispatcher = new EventDispatcher();
$dispatcher->addSubscriber(new PaginationSubscriber());
$dispatcher->addSubscriber(new Filtration());
$p = new Paginator($dispatcher);
$view = $p->paginate($query, 1, 10);
$items = $view->getItems();
}
/**
* @test
*/
public function shouldFilterByAnyAvailableAlias()
{
$em = $this->getMockSqliteEntityManager();
$this->populate($em);
$_GET['filterParam'] = 'test_alias';
$_GET['filterValue'] = '*er';
$dql = <<<___SQL
SELECT a, a.title AS test_alias
FROM Test\Fixture\Entity\Article a
___SQL;
$query = $this->em->createQuery($dql);
$query->setHint(UsesPaginator::HINT_FETCH_JOIN_COLLECTION, false);
$dispatcher = new EventDispatcher();
$dispatcher->addSubscriber(new PaginationSubscriber());
$dispatcher->addSubscriber(new Filtration());
$p = new Paginator($dispatcher);
$this->startQueryLog();
$view = $p->paginate($query, 1, 10, array(PaginatorInterface::DISTINCT => false));
$items = $view->getItems();
$this->assertEquals(2, count($items));
$this->assertEquals('summer', $items[0][0]->getTitle());
$this->assertEquals('winter', $items[1][0]->getTitle());
$this->assertEquals(2, $this->queryAnalyzer->getNumExecutedQueries());
$executed = $this->queryAnalyzer->getExecutedQueries();
// Different aliases separators according to Doctrine version
if (version_compare(\Doctrine\ORM\Version::VERSION, '2.5', '<')) {
$this->assertEquals('SELECT a0_.id AS id0, a0_.title AS title1, a0_.enabled AS enabled2, a0_.title AS title3 FROM Article a0_ WHERE a0_.title LIKE \'%er\' LIMIT 10 OFFSET 0', $executed[1]);
} else {
$this->assertEquals('SELECT a0_.id AS id_0, a0_.title AS title_1, a0_.enabled AS enabled_2, a0_.title AS title_3 FROM Article a0_ WHERE a0_.title LIKE \'%er\' LIMIT 10 OFFSET 0', $executed[1]);
}
}
/**
* @test
*/
public function shouldNotWorkWithInitialPaginatorEventDispatcher()
{
$em = $this->getMockSqliteEntityManager();
$this->populate($em);
$_GET['filterParam'] = 'a.title';
$_GET['filterValue'] = 'summer';
$query = $this
->em
->createQuery('SELECT a FROM Test\Fixture\Entity\Article a')
;
$query->setHint(UsesPaginator::HINT_FETCH_JOIN_COLLECTION, false);
$p = new Paginator();
$this->startQueryLog();
$view = $p->paginate($query, 1, 10);
$this->assertTrue($view instanceof SlidingPagination);
$this->assertEquals(2, $this->queryAnalyzer->getNumExecutedQueries());
$executed = $this->queryAnalyzer->getExecutedQueries();
// Different aliases separators according to Doctrine version
if (version_compare(\Doctrine\ORM\Version::VERSION, '2.5', '<')) {
$this->assertEquals('SELECT a0_.id AS id0, a0_.title AS title1, a0_.enabled AS enabled2 FROM Article a0_ LIMIT 10 OFFSET 0', $executed[1]);
} else {
$this->assertEquals('SELECT a0_.id AS id_0, a0_.title AS title_1, a0_.enabled AS enabled_2 FROM Article a0_ LIMIT 10 OFFSET 0', $executed[1]);
}
}
/**
* @test
*/
public function shouldNotExecuteExtraQueriesWhenCountIsZero()
{
$_GET['filterParam'] = 'a.title';
$_GET['filterValue'] = 'asc';
$query = $this
->getMockSqliteEntityManager()
->createQuery('SELECT a FROM Test\Fixture\Entity\Article a')
;
$p = new Paginator();
$this->startQueryLog();
$view = $p->paginate($query, 1, 10);
$this->assertTrue($view instanceof SlidingPagination);
$this->assertEquals(2, $this->queryAnalyzer->getNumExecutedQueries());
}
/**
* @test
*/
public function shouldFilterWithEmptyParametersAndDefaults()
{
$em = $this->getMockSqliteEntityManager();
$this->populate($em);
$dispatcher = new EventDispatcher();
$dispatcher->addSubscriber(new PaginationSubscriber());
$dispatcher->addSubscriber(new Filtration());
$p = new Paginator($dispatcher);
$_GET['filterParam'] = '';
$_GET['filterValue'] = 'summer';
$this->startQueryLog();
$query = $this->em->createQuery('SELECT a FROM Test\Fixture\Entity\Article a');
$query->setHint(UsesPaginator::HINT_FETCH_JOIN_COLLECTION, false);
$defaultFilterFields = 'a.title';
$view = $p->paginate($query, 1, 10, compact(PaginatorInterface::DEFAULT_FILTER_FIELDS));
$items = $view->getItems();
$this->assertEquals(1, count($items));
$this->assertEquals('summer', $items[0]->getTitle());
$defaultFilterFields = 'a.id,a.title';
$view = $p->paginate($query, 1, 10, compact(PaginatorInterface::DEFAULT_FILTER_FIELDS));
$items = $view->getItems();
$this->assertEquals(1, count($items));
$this->assertEquals('summer', $items[0]->getTitle());
$defaultFilterFields = array('a.id', 'a.title');
$view = $p->paginate($query, 1, 10, compact(PaginatorInterface::DEFAULT_FILTER_FIELDS));
$items = $view->getItems();
$this->assertEquals(1, count($items));
$this->assertEquals('summer', $items[0]->getTitle());
$executed = $this->queryAnalyzer->getExecutedQueries();
// Different aliases separators according to Doctrine version
if (version_compare(\Doctrine\ORM\Version::VERSION, '2.5', '<')) {
$this->assertEquals('SELECT a0_.id AS id0, a0_.title AS title1, a0_.enabled AS enabled2 FROM Article a0_ WHERE a0_.title LIKE \'summer\' LIMIT 10 OFFSET 0', $executed[1]);
$this->assertEquals('SELECT a0_.id AS id0, a0_.title AS title1, a0_.enabled AS enabled2 FROM Article a0_ WHERE a0_.id LIKE \'summer\' OR a0_.title LIKE \'summer\' LIMIT 10 OFFSET 0', $executed[3]);
$this->assertEquals('SELECT a0_.id AS id0, a0_.title AS title1, a0_.enabled AS enabled2 FROM Article a0_ WHERE a0_.id LIKE \'summer\' OR a0_.title LIKE \'summer\' LIMIT 10 OFFSET 0', $executed[5]);
} else {
$this->assertEquals('SELECT a0_.id AS id_0, a0_.title AS title_1, a0_.enabled AS enabled_2 FROM Article a0_ WHERE a0_.title LIKE \'summer\' LIMIT 10 OFFSET 0', $executed[1]);
$this->assertEquals('SELECT a0_.id AS id_0, a0_.title AS title_1, a0_.enabled AS enabled_2 FROM Article a0_ WHERE a0_.id LIKE \'summer\' OR a0_.title LIKE \'summer\' LIMIT 10 OFFSET 0', $executed[3]);
$this->assertEquals('SELECT a0_.id AS id_0, a0_.title AS title_1, a0_.enabled AS enabled_2 FROM Article a0_ WHERE a0_.id LIKE \'summer\' OR a0_.title LIKE \'summer\' LIMIT 10 OFFSET 0', $executed[5]);
}
}
/**
* @test
*/
public function shouldNotFilterWithEmptyParametersAndDefaults()
{
$em = $this->getMockSqliteEntityManager();
$this->populate($em);
$dispatcher = new EventDispatcher();
$dispatcher->addSubscriber(new PaginationSubscriber());
$dispatcher->addSubscriber(new Filtration());
$p = new Paginator($dispatcher);
$_GET['filterParam'] = 'a.title';
$_GET['filterValue'] = '';
$this->startQueryLog();
$query = $this->em->createQuery('SELECT a FROM Test\Fixture\Entity\Article a');
$query->setHint(UsesPaginator::HINT_FETCH_JOIN_COLLECTION, false);
$view = $p->paginate($query, 1, 10);
$items = $view->getItems();
$this->assertEquals(4, count($items));
$_GET['filterParam'] = '';
$_GET['filterValue'] = 'summer';
$view = $p->paginate($query, 1, 10);
$items = $view->getItems();
$this->assertEquals(4, count($items));
$_GET['filterParam'] = '';
$_GET['filterValue'] = '';
$view = $p->paginate($query, 1, 10);
$items = $view->getItems();
$this->assertEquals(4, count($items));
$executed = $this->queryAnalyzer->getExecutedQueries();
// Different aliases separators according to Doctrine version
if (version_compare(\Doctrine\ORM\Version::VERSION, '2.5', '<')) {
$this->assertEquals('SELECT a0_.id AS id0, a0_.title AS title1, a0_.enabled AS enabled2 FROM Article a0_ LIMIT 10 OFFSET 0', $executed[1]);
$this->assertEquals('SELECT a0_.id AS id0, a0_.title AS title1, a0_.enabled AS enabled2 FROM Article a0_ LIMIT 10 OFFSET 0', $executed[3]);
$this->assertEquals('SELECT a0_.id AS id0, a0_.title AS title1, a0_.enabled AS enabled2 FROM Article a0_ LIMIT 10 OFFSET 0', $executed[5]);
} else {
$this->assertEquals('SELECT a0_.id AS id_0, a0_.title AS title_1, a0_.enabled AS enabled_2 FROM Article a0_ LIMIT 10 OFFSET 0', $executed[1]);
$this->assertEquals('SELECT a0_.id AS id_0, a0_.title AS title_1, a0_.enabled AS enabled_2 FROM Article a0_ LIMIT 10 OFFSET 0', $executed[3]);
$this->assertEquals('SELECT a0_.id AS id_0, a0_.title AS title_1, a0_.enabled AS enabled_2 FROM Article a0_ LIMIT 10 OFFSET 0', $executed[5]);
}
}
protected function getUsedEntityFixtures()
{
return array('Test\Fixture\Entity\Article');
}
private function populate($em)
{
$summer = new Article();
$summer->setTitle('summer');
$summer->setEnabled(true);
$winter = new Article();
$winter->setTitle('winter');
$winter->setEnabled(true);
$autumn = new Article();
$autumn->setTitle('autumn');
$autumn->setEnabled(false);
$spring = new Article();
$spring->setTitle('spring');
$spring->setEnabled(false);
$em->persist($summer);
$em->persist($winter);
$em->persist($autumn);
$em->persist($spring);
$em->flush();
}
private function populateNumeric($em)
{
$zero = new Article();
$zero->setTitle('0');
$zero->setEnabled(true);
$one = new Article();
$one->setTitle('1');
$one->setEnabled(true);
$lower = new Article();
$lower->setTitle('123');
$lower->setEnabled(false);
$upper = new Article();
$upper->setTitle('234');
$upper->setEnabled(false);
$em->persist($zero);
$em->persist($one);
$em->persist($lower);
$em->persist($upper);
$em->flush();
}
private function getApcEntityManager()
{
$config = new \Doctrine\ORM\Configuration();
$config->setMetadataCacheImpl(new \Doctrine\Common\Cache\ApcCache());
$config->setQueryCacheImpl(new \Doctrine\Common\Cache\ApcCache());
$config->setProxyDir(__DIR__);
$config->setProxyNamespace('Gedmo\Mapping\Proxy');
$config->setAutoGenerateProxyClasses(false);
$config->setMetadataDriverImpl($this->getMetadataDriverImplementation());
$conn = array(
'driver' => 'pdo_sqlite',
'memory' => true,
);
$em = \Doctrine\ORM\EntityManager::create($conn, $config);
return $em;
}
}

View File

@@ -0,0 +1,93 @@
<?php
namespace Test\Pager\Subscriber\Filtration\Doctrine\ORM;
use Knp\Component\Pager\PaginatorInterface;
use Test\Tool\BaseTestCaseORM;
use Knp\Component\Pager\Paginator;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Knp\Component\Pager\Event\Subscriber\Paginate\PaginationSubscriber;
use Knp\Component\Pager\Event\Subscriber\Filtration\FiltrationSubscriber as Filtration;
use Test\Fixture\Entity\Article;
class WhitelistTest extends BaseTestCaseORM
{
/**
* @test
* @expectedException \UnexpectedValueException
*/
public function shouldWhitelistFiltrationFields()
{
$this->populate();
$_GET['filterParam'] = 'a.title';
$_GET['filterValue'] = 'summer';
$query = $this->em->createQuery('SELECT a FROM Test\Fixture\Entity\Article a');
$dispatcher = new EventDispatcher();
$dispatcher->addSubscriber(new PaginationSubscriber());
$dispatcher->addSubscriber(new Filtration());
$p = new Paginator($dispatcher);
$filterFieldWhitelist = array('a.title');
$view = $p->paginate($query, 1, 10, compact(PaginatorInterface::FILTER_FIELD_WHITELIST));
$items = $view->getItems();
$this->assertEquals(1, count($items));
$this->assertEquals('summer', $items[0]->getTitle());
$_GET['filterParam'] = 'a.id';
$view = $p->paginate($query, 1, 10, compact(PaginatorInterface::FILTER_FIELD_WHITELIST));
}
/**
* @test
*/
public function shouldFilterWithoutSpecificWhitelist()
{
$this->populate();
$_GET['filterParam'] = 'a.title';
$_GET['filterValue'] = 'autumn';
$query = $this->em->createQuery('SELECT a FROM Test\Fixture\Entity\Article a');
$dispatcher = new EventDispatcher();
$dispatcher->addSubscriber(new PaginationSubscriber());
$dispatcher->addSubscriber(new Filtration());
$p = new Paginator($dispatcher);
$view = $p->paginate($query, 1, 10);
$items = $view->getItems();
$this->assertEquals('autumn', $items[0]->getTitle());
$_GET['filterParam'] = 'a.id';
$view = $p->paginate($query, 1, 10);
$items = $view->getItems();
$this->assertEquals(0, count($items));
}
protected function getUsedEntityFixtures()
{
return array('Test\Fixture\Entity\Article');
}
private function populate()
{
$em = $this->getMockSqliteEntityManager();
$summer = new Article();
$summer->setTitle('summer');
$winter = new Article();
$winter->setTitle('winter');
$autumn = new Article();
$autumn->setTitle('autumn');
$spring = new Article();
$spring->setTitle('spring');
$em->persist($summer);
$em->persist($winter);
$em->persist($autumn);
$em->persist($spring);
$em->flush();
}
}

View File

@@ -0,0 +1,25 @@
<?php
use Test\Tool\BaseTestCase;
use Knp\Component\Pager\Event\Subscriber\Filtration\FiltrationSubscriber;
use Knp\Component\Pager\Event\BeforeEvent;
class FiltrationSubscriberTest extends BaseTestCase
{
/**
* @test
*/
function shouldRegisterExpectedSubscribersOnlyOnce()
{
$dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcherInterface')->getMock();
$dispatcher->expects($this->exactly(2))->method('addSubscriber');
$subscriber = new FiltrationSubscriber;
$beforeEvent = new BeforeEvent($dispatcher);
$subscriber->before($beforeEvent);
// Subsequent calls do not add more subscribers
$subscriber->before($beforeEvent);
}
}

View File

@@ -0,0 +1,75 @@
<?php
use Test\Tool\BaseTestCase;
use Knp\Component\Pager\Paginator;
use Knp\Component\Pager\Pagination\SlidingPagination;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Test\Mock\PaginationSubscriber as MockPaginationSubscriber;
use Knp\Component\Pager\Pagination\PaginationInterface;
use Knp\Component\Pager\Event\Subscriber\Paginate\ArraySubscriber;
use Knp\Component\Pager\Event\Subscriber\Paginate\PaginationSubscriber;
class ArrayTest extends BaseTestCase
{
/**
* @test
*/
function shouldPaginateAnArray()
{
$dispatcher = new EventDispatcher;
$dispatcher->addSubscriber(new ArraySubscriber);
$dispatcher->addSubscriber(new MockPaginationSubscriber); // pagination view
$p = new Paginator($dispatcher);
$items = array('first', 'second');
$view = $p->paginate($items, 1, 10);
$this->assertTrue($view instanceof PaginationInterface);
$this->assertEquals(1, $view->getCurrentPageNumber());
$this->assertEquals(10, $view->getItemNumberPerPage());
$this->assertEquals(2, count($view->getItems()));
$this->assertEquals(2, $view->getTotalItemCount());
}
/**
* @test
*/
function shouldSlicePaginateAnArray()
{
$dispatcher = new EventDispatcher;
$dispatcher->addSubscriber(new ArraySubscriber);
$dispatcher->addSubscriber(new MockPaginationSubscriber); // pagination view
$p = new Paginator($dispatcher);
$items = range('a', 'u');
$view = $p->paginate($items, 2, 10);
$this->assertEquals(2, $view->getCurrentPageNumber());
$this->assertEquals(10, $view->getItemNumberPerPage());
$this->assertEquals(10, count($view->getItems()));
$this->assertEquals(21, $view->getTotalItemCount());
}
/**
* @test
*/
function shouldSupportPaginateStrategySubscriber()
{
$items = array('first', 'second');
$p = new Paginator;
$view = $p->paginate($items, 1, 10);
$this->assertTrue($view instanceof PaginationInterface);
}
/**
* @test
*/
function shouldPaginateArrayObject()
{
$items = array('first', 'second');
$array = new \ArrayObject($items);
$p = new Paginator;
$view = $p->paginate($array, 1, 10);
$this->assertTrue($view instanceof PaginationInterface);
}
}

View File

@@ -0,0 +1,63 @@
<?php
use Test\Tool\BaseTestCase;
use Knp\Component\Pager\Paginator;
use Knp\Component\Pager\Pagination\SlidingPagination;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Test\Mock\PaginationSubscriber as MockPaginationSubscriber;
use Knp\Component\Pager\Pagination\PaginationInterface;
use Knp\Component\Pager\Event\Subscriber\Paginate\Doctrine\CollectionSubscriber;
use Knp\Component\Pager\Event\Subscriber\Paginate\PaginationSubscriber;
use Doctrine\Common\Collections\ArrayCollection;
class CollectionTest extends BaseTestCase
{
/**
* @test
*/
function shouldPaginateCollection()
{
$dispatcher = new EventDispatcher;
$dispatcher->addSubscriber(new CollectionSubscriber);
$dispatcher->addSubscriber(new MockPaginationSubscriber); // pagination view
$p = new Paginator($dispatcher);
$items = new ArrayCollection(array('first', 'second'));
$view = $p->paginate($items, 1, 10);
$this->assertEquals(1, $view->getCurrentPageNumber());
$this->assertEquals(10, $view->getItemNumberPerPage());
$this->assertEquals(2, count($view->getItems()));
$this->assertEquals(2, $view->getTotalItemCount());
}
/**
* @test
*/
function shouldSlicePaginateAnArray()
{
$dispatcher = new EventDispatcher;
$dispatcher->addSubscriber(new CollectionSubscriber);
$dispatcher->addSubscriber(new MockPaginationSubscriber); // pagination view
$p = new Paginator($dispatcher);
$items = new ArrayCollection(range('a', 'u'));
$view = $p->paginate($items, 2, 10);
$this->assertEquals(2, $view->getCurrentPageNumber());
$this->assertEquals(10, $view->getItemNumberPerPage());
$this->assertEquals(10, count($view->getItems()));
$this->assertEquals(21, $view->getTotalItemCount());
}
/**
* @test
*/
function shouldSupportPaginateStrategySubscriber()
{
$items = new ArrayCollection(array('first', 'second'));
$p = new Paginator;
$view = $p->paginate($items, 1, 10);
$this->assertTrue($view instanceof PaginationInterface);
}
}

View File

@@ -0,0 +1,62 @@
<?php
namespace Test\Pager\Subscriber\Paginate\Doctrine;
use Test\Tool\BaseTestCaseORM;
use Doctrine\DBAL\Query\QueryBuilder;
use Knp\Component\Pager\Paginator;
use Test\Fixture\Entity\Article;
class DBALQueryBuilderTest extends BaseTestCaseORM
{
/**
* @test
*/
function shouldPaginateSimpleDoctrineQuery()
{
$this->populate();
$p = new Paginator;
$qb = new QueryBuilder($this->em->getConnection());
$qb->select('*')
->from('Article', 'a')
;
$view = $p->paginate($qb, 1, 2);
$this->assertEquals(1, $view->getCurrentPageNumber());
$this->assertEquals(2, $view->getItemNumberPerPage());
$this->assertEquals(4, $view->getTotalItemCount());
$items = $view->getItems();
$this->assertEquals(2, count($items));
$this->assertEquals('summer', $items[0]['title']);
$this->assertEquals('winter', $items[1]['title']);
}
protected function getUsedEntityFixtures()
{
return array('Test\Fixture\Entity\Article');
}
private function populate()
{
$em = $this->getMockSqliteEntityManager();
$summer = new Article;
$summer->setTitle('summer');
$winter = new Article;
$winter->setTitle('winter');
$autumn = new Article;
$autumn->setTitle('autumn');
$spring = new Article;
$spring->setTitle('spring');
$em->persist($summer);
$em->persist($winter);
$em->persist($autumn);
$em->persist($spring);
$em->flush();
}
}

View File

@@ -0,0 +1,56 @@
<?php
namespace Test\Pager\Subscriber\Sortable\Doctrine\ODM\MongoDB;
use Test\Tool\BaseTestCaseMongoODM;
use Knp\Component\Pager\Paginator;
use Test\Fixture\Document\Image;
class GridFsTest extends BaseTestCaseMongoODM
{
/**
* @test
*/
function shouldPaginate()
{
$this->populate();
$query = $this->dm
->createQueryBuilder('Test\Fixture\Document\Image')
->getQuery()
;
$p = new Paginator;
$view = $p->paginate($query, 1, 10);
$cursor = $query->execute();
$this->assertEquals(4, count($view->getItems()));
}
private function populate()
{
$mockFile = __DIR__.'/summer.gif';
$dm = $this->getMockDocumentManager();
$summer = new Image;
$summer->setTitle('summer');
$summer->setFile($mockFile);
$winter = new Image;
$winter->setTitle('winter');
$winter->setFile($mockFile);
$autumn = new Image;
$autumn->setTitle('autumn');
$autumn->setFile($mockFile);
$spring = new Image;
$spring->setTitle('spring');
$spring->setFile($mockFile);
$dm->persist($summer);
$dm->persist($winter);
$dm->persist($autumn);
$dm->persist($spring);
$dm->flush();
}
}

View File

@@ -0,0 +1,54 @@
<?php
namespace Test\Pager\Subscriber\Paginate\Doctrine\ODM\MongoDB;
use Test\Tool\BaseTestCaseMongoODM;
use Knp\Component\Pager\Paginator;
use Test\Fixture\Document\Article;
class QueryBuilderTest extends BaseTestCaseMongoODM
{
/**
* @test
*/
function shouldSupportPaginateStrategySubscriber()
{
$this->populate();
$qb = $this
->getMockDocumentManager()
->createQueryBuilder('Test\Fixture\Document\Article')
;
$p = new Paginator;
$pagination = $p->paginate($qb, 1, 2);
$this->assertEquals(1, $pagination->getCurrentPageNumber());
$this->assertEquals(2, $pagination->getItemNumberPerPage());
$this->assertEquals(4, $pagination->getTotalItemCount());
$items = array_values($pagination->getItems());
$this->assertEquals(2, count($items));
$this->assertEquals('summer', $items[0]->getTitle());
$this->assertEquals('winter', $items[1]->getTitle());
}
private function populate()
{
$em = $this->getMockDocumentManager();
$summer = new Article;
$summer->setTitle('summer');
$winter = new Article;
$winter->setTitle('winter');
$autumn = new Article;
$autumn->setTitle('autumn');
$spring = new Article;
$spring->setTitle('spring');
$em->persist($summer);
$em->persist($winter);
$em->persist($autumn);
$em->persist($spring);
$em->flush();
}
}

View File

@@ -0,0 +1,78 @@
<?php
namespace Test\Pager\Subscriber\Paginate\Doctrine\ODM\MongoDB;
use Test\Tool\BaseTestCaseMongoODM;
use Knp\Component\Pager\Paginator;
use Knp\Component\Pager\Pagination\SlidingPagination;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Knp\Component\Pager\Event\Subscriber\Paginate\Doctrine\ODM\MongoDB\QuerySubscriber;
use Knp\Component\Pager\Event\Subscriber\Paginate\PaginationSubscriber;
use Test\Fixture\Document\Article;
class QueryTest extends BaseTestCaseMongoODM
{
/**
* @test
*/
function shouldPaginateSimpleDoctrineMongoDBQuery()
{
$this->populate();
$dispatcher = new EventDispatcher;
$dispatcher->addSubscriber(new QuerySubscriber);
$dispatcher->addSubscriber(new PaginationSubscriber); // pagination view
$p = new Paginator($dispatcher);
$qb = $this->dm->createQueryBuilder('Test\Fixture\Document\Article');
$query = $qb->getQuery();
$pagination = $p->paginate($query, 1, 2);
$this->assertTrue($pagination instanceof SlidingPagination);
$this->assertEquals(1, $pagination->getCurrentPageNumber());
$this->assertEquals(2, $pagination->getItemNumberPerPage());
$this->assertEquals(4, $pagination->getTotalItemCount());
$items = array_values($pagination->getItems());
$this->assertEquals(2, count($items));
$this->assertEquals('summer', $items[0]->getTitle());
$this->assertEquals('winter', $items[1]->getTitle());
}
/**
* @test
*/
function shouldSupportPaginateStrategySubscriber()
{
$query = $this
->getMockDocumentManager()
->createQueryBuilder('Test\Fixture\Document\Article')
->getQuery()
;
$p = new Paginator;
$pagination = $p->paginate($query, 1, 10);
$this->assertTrue($pagination instanceof SlidingPagination);
}
private function populate()
{
$em = $this->getMockDocumentManager();
$summer = new Article;
$summer->setTitle('summer');
$winter = new Article;
$winter->setTitle('winter');
$autumn = new Article;
$autumn->setTitle('autumn');
$spring = new Article;
$spring->setTitle('spring');
$em->persist($summer);
$em->persist($winter);
$em->persist($autumn);
$em->persist($spring);
$em->flush();
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

View File

@@ -0,0 +1,62 @@
<?php
namespace Test\Pager\Subscriber\Paginate\Doctrine\ODM\PHPCR;
use Knp\Component\Pager\Paginator;
use Test\Fixture\Document\PHPCR\Article;
use Test\Tool\BaseTestCasePHPCRODM;
class QueryBuilderSubscriberTest extends BaseTestCasePHPCRODM
{
/**
* @test
*/
public function shouldSupportPaginateStrategySubscriber()
{
$this->populate();
$qb = $this->dm->createQueryBuilder();
$qb->fromDocument('Test\Fixture\Document\PHPCR\Article', 'a');
$p = new Paginator();
$pagination = $p->paginate($qb, 1, 2);
$this->assertEquals(1, $pagination->getCurrentPageNumber());
$this->assertEquals(2, $pagination->getItemNumberPerPage());
$this->assertEquals(4, $pagination->getTotalItemCount());
$items = $pagination->getItems();
$this->assertEquals(2, count($items));
$this->assertEquals('summer', $items->first()->getTitle());
$this->assertEquals('winter', $items->last()->getTitle());
}
private function populate()
{
$dm = $this->getMockDocumentManager();
$root = $dm->find(null, '/');
$summer = new Article();
$summer->setTitle('summer');
$summer->setParent($root);
$winter = new Article();
$winter->setTitle('winter');
$winter->setParent($root);
$autumn = new Article();
$autumn->setTitle('autumn');
$autumn->setParent($root);
$spring = new Article();
$spring->setTitle('spring');
$spring->setParent($root);
$dm->persist($summer);
$dm->persist($winter);
$dm->persist($autumn);
$dm->persist($spring);
$dm->flush();
}
}

View File

@@ -0,0 +1,84 @@
<?php
namespace Test\Pager\Subscriber\Paginate\Doctrine\ODM\PHPCR;
use Knp\Component\Pager\Event\Subscriber\Paginate\Doctrine\ODM\PHPCR\QuerySubscriber;
use Knp\Component\Pager\Pagination\SlidingPagination;
use Knp\Component\Pager\Paginator;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Test\Fixture\Document\PHPCR\Article;
use Test\Mock\PaginationSubscriber;
use Test\Tool\BaseTestCasePHPCRODM;
class QuerySubscriberTest extends BaseTestCasePHPCRODM
{
/**
* @test
*/
function shouldPaginateSimpleDoctrinePHPCRQuery()
{
$this->populate();
$dispatcher = new EventDispatcher();
$dispatcher->addSubscriber(new QuerySubscriber());
$dispatcher->addSubscriber(new PaginationSubscriber()); // pagination view
$p = new Paginator($dispatcher);
$query = $this->dm->createQueryBuilder()->fromDocument('Test\Fixture\Document\PHPCR\Article', 'a')->getQuery();
$pagination = $p->paginate($query, 1, 2);
$this->assertTrue($pagination instanceof SlidingPagination);
$this->assertEquals(1, $pagination->getCurrentPageNumber());
$this->assertEquals(2, $pagination->getItemNumberPerPage());
$this->assertEquals(4, $pagination->getTotalItemCount());
$items = $pagination->getItems();
$this->assertEquals(2, count($items));
$this->assertEquals('summer', $items->first()->getTitle());
$this->assertEquals('winter', $items->last()->getTitle());
}
/**
* @test
*/
function shouldSupportPaginateStrategySubscriber()
{
$this->getMockDocumentManager();
$query = $this->dm->createQueryBuilder()->fromDocument('Test\Fixture\Document\PHPCR\Article', 'a')->getQuery();
$p = new Paginator();
$pagination = $p->paginate($query, 1, 10);
$this->assertTrue($pagination instanceof SlidingPagination);
}
private function populate()
{
$dm = $this->getMockDocumentManager();
$root = $dm->find(null, '/');
$summer = new Article();
$summer->setTitle('summer');
$summer->setParent($root);
$winter = new Article();
$winter->setTitle('winter');
$winter->setParent($root);
$autumn = new Article();
$autumn->setTitle('autumn');
$autumn->setParent($root);
$spring = new Article();
$spring->setTitle('spring');
$spring->setParent($root);
$dm->persist($summer);
$dm->persist($winter);
$dm->persist($autumn);
$dm->persist($spring);
$dm->flush();
}
}

View File

@@ -0,0 +1,194 @@
<?php
namespace Test\Pager\Subscriber\Paginate\Doctrine\ORM;
use Test\Tool\BaseTestCaseORM;
use Knp\Component\Pager\Paginator;
use Knp\Component\Pager\Pagination\SlidingPagination;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Knp\Component\Pager\Pagination\PaginationInterface;
use Knp\Component\Pager\Event\Subscriber\Paginate\Doctrine\ORM\QuerySubscriber;
use Knp\Component\Pager\Event\Subscriber\Paginate\PaginationSubscriber;
use Test\Fixture\Entity\Shop\Product;
use Test\Fixture\Entity\Shop\Tag;
use Doctrine\ORM\Query;
class AdvancedQueryTest extends BaseTestCaseORM
{
/**
* Its not possible to make distinction and predict
* count of such query
*
* @test
* @expectedException RuntimeException
*/
function shouldFailToPaginateMultiRootQuery()
{
$this->populate();
$dql = <<<___SQL
SELECT p FROM
Test\Fixture\Entity\Shop\Product p,
Test\Fixture\Entity\Shop\Tag t
___SQL;
$q = $this->em->createQuery($dql);
$p = new Paginator;
$this->startQueryLog();
$view = $p->paginate($q, 1, 2);
}
/**
* @test
*/
function shouldBeAbleToPaginateWithHavingClause()
{
$this->populate();
$dql = <<<___SQL
SELECT p, t
FROM Test\Fixture\Entity\Shop\Product p
INNER JOIN p.tags t
GROUP BY p.id
HAVING p.numTags = COUNT(t)
___SQL;
$q = $this->em->createQuery($dql);
$q->setHydrationMode(Query::HYDRATE_ARRAY);
$p = new Paginator;
$view = $p->paginate($q, 1, 10, array('wrap-queries' => true));
$this->assertEquals(3, count($view));
}
/**
* @test
*/
function shouldBeAbleToPaginateMixedKeyArray()
{
$this->populate();
$dql = <<<___SQL
SELECT p, t, p.title FROM
Test\Fixture\Entity\Shop\Product p
LEFT JOIN
p.tags t
___SQL;
$q = $this->em->createQuery($dql);
$p = new Paginator;
$view = $p->paginate($q, 1, 10);
$this->assertEquals(3, count($view));
$items = $view->getItems();
// and should be hydrated as array
$this->assertTrue(isset($items[0]['title']));
}
/**
* @test
*/
function shouldBeAbleToPaginateCaseBasedQuery()
{
if (version_compare(\Doctrine\ORM\Version::VERSION, '2.2.0-DEV', '<')) {
$this->markTestSkipped('Only recent orm version can test against this query.');
}
$this->populate();
$dql = <<<___SQL
SELECT p,
CASE
WHEN p.title LIKE :keyword
AND p.description LIKE :keyword
THEN 0
WHEN p.title LIKE :keyword
THEN 1
WHEN p.description LIKE :keyword
THEN 2
ELSE 3
END AS relevance
FROM Test\Fixture\Entity\Shop\Product p
WHERE (
p.title LIKE :keyword
OR p.description LIKE :keyword
)
GROUP BY p.id
ORDER BY relevance ASC, p.id DESC
___SQL;
$q = $this->em->createQuery($dql);
$q->setParameter('keyword', '%Star%');
$q->setHydrationMode(\Doctrine\ORM\Query::HYDRATE_ARRAY);
$p = new Paginator;
$view = $p->paginate($q, 1, 10);
$this->assertEquals(1, count($view));
$items = $view->getItems();
// and should be hydrated as array
$this->assertEquals('Starship', $items[0][0]['title']);
$this->assertEquals(1, $items[0]['relevance']);
}
/**
* @test
*/
function shouldUseOutputWalkersIfHinted()
{
$this->populate();
$dql = <<<___SQL
SELECT p, t
FROM Test\Fixture\Entity\Shop\Product p
INNER JOIN p.tags t
GROUP BY p.id
HAVING p.numTags = COUNT(t)
___SQL;
$q = $this->em->createQuery($dql);
$q->setHydrationMode(Query::HYDRATE_ARRAY);
$p = new Paginator;
$view = $p->paginate($q, 1, 10, array('wrap-queries' => true));
$this->assertEquals(3, count($view));
}
protected function getUsedEntityFixtures()
{
return array(
'Test\Fixture\Entity\Shop\Product',
'Test\Fixture\Entity\Shop\Tag'
);
}
private function populate()
{
$em = $this->getMockSqliteEntityManager();
$cheep = new Tag;
$cheep->setName('Cheep');
$new = new Tag;
$new->setName('New');
$special = new Tag;
$special->setName('Special');
$starship = new Product;
$starship->setTitle('Starship');
$starship->setPrice(277.66);
$starship->addTag($new);
$starship->addTag($special);
$cheese = new Product;
$cheese->setTitle('Cheese');
$cheese->setPrice(7.66);
$cheese->addTag($cheep);
$shoe = new Product;
$shoe->setTitle('Shoe');
$shoe->setPrice(2.66);
$shoe->addTag($special);
$em->persist($special);
$em->persist($cheep);
$em->persist($new);
$em->persist($starship);
$em->persist($cheese);
$em->persist($shoe);
$em->flush();
}
}

View File

@@ -0,0 +1,72 @@
<?php
namespace Test\Pager\Subscriber\Paginate\Doctrine\ORM;
use Test\Tool\BaseTestCaseORM;
use Knp\Component\Pager\Paginator;
use Test\Fixture\Entity\Composite;
use Knp\Component\Pager\Event\Subscriber\Paginate\Doctrine\ORM\QuerySubscriber\UsesPaginator;
use Doctrine\ORM\Query;
class CompositeKeyTest extends BaseTestCaseORM
{
/**
* @test
*/
function shouldBeHandledByQueryHintByPassingCount()
{
$p = new Paginator;
$em = $this->getMockSqliteEntityManager();
$this->populate($em);
$count = $em
->createQuery('SELECT COUNT(c) FROM Test\Fixture\Entity\Composite c')
->getSingleScalarResult()
;
$query = $em
->createQuery('SELECT c FROM Test\Fixture\Entity\Composite c')
->setHint('knp_paginator.count', $count)
;
$query->setHint(UsesPaginator::HINT_FETCH_JOIN_COLLECTION, false);
$view = $p->paginate($query, 1, 10, array('wrap-queries' => true));
$items = $view->getItems();
$this->assertEquals(4, count($items));
}
protected function getUsedEntityFixtures()
{
return array('Test\Fixture\Entity\Composite');
}
private function populate($em)
{
$summer = new Composite;
$summer->setId(1);
$summer->setTitle('summer');
$summer->setUid(100);
$winter = new Composite;
$winter->setId(2);
$winter->setTitle('winter');
$winter->setUid(200);
$autumn = new Composite;
$autumn->setId(3);
$autumn->setTitle('autumn');
$autumn->setUid(300);
$spring = new Composite;
$spring->setId(4);
$spring->setTitle('spring');
$spring->setUid(400);
$em->persist($summer);
$em->persist($winter);
$em->persist($autumn);
$em->persist($spring);
$em->flush();
}
}

View File

@@ -0,0 +1,62 @@
<?php
namespace Test\Pager\Subscriber\Paginate\Doctrine\ORM;
use Test\Tool\BaseTestCaseORM;
use Knp\Component\Pager\Paginator;
use Test\Fixture\Entity\Article;
class QueryBuilderTest extends BaseTestCaseORM
{
/**
* @test
*/
function shouldPaginateSimpleDoctrineQuery()
{
$this->populate();
$p = new Paginator;
$qb = $this->em->createQueryBuilder();
$qb
->select('a')
->from('Test\Fixture\Entity\Article', 'a')
;
$view = $p->paginate($qb, 1, 2);
$this->assertEquals(1, $view->getCurrentPageNumber());
$this->assertEquals(2, $view->getItemNumberPerPage());
$this->assertEquals(4, $view->getTotalItemCount());
$items = $view->getItems();
$this->assertEquals(2, count($items));
$this->assertEquals('summer', $items[0]->getTitle());
$this->assertEquals('winter', $items[1]->getTitle());
}
protected function getUsedEntityFixtures()
{
return array('Test\Fixture\Entity\Article');
}
private function populate()
{
$em = $this->getMockSqliteEntityManager();
$summer = new Article;
$summer->setTitle('summer');
$winter = new Article;
$winter->setTitle('winter');
$autumn = new Article;
$autumn->setTitle('autumn');
$spring = new Article;
$spring->setTitle('spring');
$em->persist($summer);
$em->persist($winter);
$em->persist($autumn);
$em->persist($spring);
$em->flush();
}
}

View File

@@ -0,0 +1,82 @@
<?php
namespace Test\Pager\Subscriber\Paginate\Doctrine\ORM;
use Test\Tool\BaseTestCaseORM;
use Knp\Component\Pager\Paginator;
use Knp\Component\Pager\Pagination\SlidingPagination;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Knp\Component\Pager\Pagination\PaginationInterface;
use Knp\Component\Pager\Event\Subscriber\Paginate\Doctrine\ORM\QuerySubscriber;
use Test\Fixture\Entity\Article;
use Test\Mock\PaginationSubscriber;
class QueryTest extends BaseTestCaseORM
{
/**
* @test
*/
function shouldPaginateSimpleDoctrineQuery()
{
$this->populate();
$dispatcher = new EventDispatcher;
$dispatcher->addSubscriber(new QuerySubscriber\UsesPaginator);
$dispatcher->addSubscriber(new PaginationSubscriber);
$p = new Paginator($dispatcher);
$query = $this->em->createQuery('SELECT a FROM Test\Fixture\Entity\Article a');
$view = $p->paginate($query, 1, 2);
$this->assertTrue($view instanceof PaginationInterface);
$this->assertEquals(1, $view->getCurrentPageNumber());
$this->assertEquals(2, $view->getItemNumberPerPage());
$this->assertEquals(4, $view->getTotalItemCount());
$items = $view->getItems();
$this->assertEquals(2, count($items));
$this->assertEquals('summer', $items[0]->getTitle());
$this->assertEquals('winter', $items[1]->getTitle());
}
/**
* @test
*/
function shouldSupportPaginateStrategySubscriber()
{
$query = $this
->getMockSqliteEntityManager()
->createQuery('SELECT a FROM Test\Fixture\Entity\Article a')
;
$p = new Paginator;
$view = $p->paginate($query, 1, 10);
$this->assertTrue($view instanceof PaginationInterface);
}
protected function getUsedEntityFixtures()
{
return array('Test\Fixture\Entity\Article');
}
private function populate()
{
$em = $this->getMockSqliteEntityManager();
$summer = new Article;
$summer->setTitle('summer');
$winter = new Article;
$winter->setTitle('winter');
$autumn = new Article;
$autumn->setTitle('autumn');
$spring = new Article;
$spring->setTitle('spring');
$em->persist($summer);
$em->persist($winter);
$em->persist($autumn);
$em->persist($spring);
$em->flush();
}
}

View File

@@ -0,0 +1,133 @@
<?php
namespace Test\Pager\Subscriber\Paginate\Doctrine\ORM\QueryTest;
use Test\Tool\BaseTestCaseORM;
use Knp\Component\Pager\Paginator;
use Knp\Component\Pager\Pagination\SlidingPagination;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Knp\Component\Pager\Pagination\PaginationInterface;
use Knp\Component\Pager\Event\Subscriber\Paginate\Doctrine\ORM\QuerySubscriber;
use Knp\Component\Pager\Event\Subscriber\Paginate\PaginationSubscriber;
use Test\Fixture\Entity\Shop\Product;
use Test\Fixture\Entity\Shop\Tag;
use Doctrine\ORM\Query;
use Knp\Component\Pager\Event\Subscriber\Paginate\Doctrine\ORM\QuerySubscriber\UsesPaginator;
class UsesPaginatorTest extends BaseTestCaseORM
{
/**
* @test
*/
function shouldUseOutputWalkersIfAskedTo()
{
$this->populate();
$dql = <<<___SQL
SELECT p, t
FROM Test\Fixture\Entity\Shop\Product p
INNER JOIN p.tags t
GROUP BY p.id
HAVING p.numTags = COUNT(t)
___SQL;
$q = $this->em->createQuery($dql);
$q->setHydrationMode(Query::HYDRATE_ARRAY);
$q->setHint(UsesPaginator::HINT_FETCH_JOIN_COLLECTION, true);
$this->startQueryLog();
$p = new Paginator;
$view = $p->paginate($q, 1, 10, array('wrap-queries' => true));
$this->assertEquals(3, $this->queryAnalyzer->getNumExecutedQueries());
$this->assertEquals(3, count($view));
}
/**
* @test
*/
function shouldNotUseOutputWalkersByDefault()
{
$this->populate();
$dql = <<<___SQL
SELECT p
FROM Test\Fixture\Entity\Shop\Product p
GROUP BY p.id
___SQL;
$q = $this->em->createQuery($dql);
$q->setHint(UsesPaginator::HINT_FETCH_JOIN_COLLECTION, false);
$q->setHydrationMode(Query::HYDRATE_ARRAY);
$this->startQueryLog();
$p = new Paginator;
$view = $p->paginate($q, 1, 10, array('wrap-queries' => false));
$this->assertEquals(2, $this->queryAnalyzer->getNumExecutedQueries());
$this->assertEquals(3, count($view));
}
/**
* @test
*/
function shouldFetchJoinCollectionsIfNeeded()
{
$this->populate();
$dql = <<<___SQL
SELECT p, t
FROM Test\Fixture\Entity\Shop\Product p
INNER JOIN p.tags t
GROUP BY p.id
HAVING p.numTags = COUNT(t)
___SQL;
$q = $this->em->createQuery($dql);
$q->setHydrationMode(Query::HYDRATE_ARRAY);
$q->setHint(UsesPaginator::HINT_FETCH_JOIN_COLLECTION, true);
$this->startQueryLog();
$p = new Paginator;
$view = $p->paginate($q, 1, 10, array('wrap-queries' => true));
$this->assertEquals(3, $this->queryAnalyzer->getNumExecutedQueries());
$this->assertEquals(3, count($view));
}
protected function getUsedEntityFixtures()
{
return array(
'Test\Fixture\Entity\Shop\Product',
'Test\Fixture\Entity\Shop\Tag'
);
}
private function populate()
{
$em = $this->getMockSqliteEntityManager();
$cheep = new Tag;
$cheep->setName('Cheep');
$new = new Tag;
$new->setName('New');
$special = new Tag;
$special->setName('Special');
$starship = new Product;
$starship->setTitle('Starship');
$starship->setPrice(277.66);
$starship->addTag($new);
$starship->addTag($special);
$cheese = new Product;
$cheese->setTitle('Cheese');
$cheese->setPrice(7.66);
$cheese->addTag($cheep);
$shoe = new Product;
$shoe->setTitle('Shoe');
$shoe->setPrice(2.66);
$shoe->addTag($special);
$em->persist($special);
$em->persist($cheep);
$em->persist($new);
$em->persist($starship);
$em->persist($cheese);
$em->persist($shoe);
$em->flush();
}
}

View File

@@ -0,0 +1,68 @@
<?php
use Elastica\Query;
use Elastica\Query\Term;
use Elastica\Result;
use Elastica\Type;
use Knp\Component\Pager\Paginator;
use Knp\Component\Pager\Event\Subscriber\Paginate\ElasticaQuerySubscriber;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Test\Mock\PaginationSubscriber as MockPaginationSubscriber;
use Test\Tool\BaseTestCase;
class ElasticaTest extends BaseTestCase
{
public function testElasticaSubscriber()
{
$dispatcher = new EventDispatcher;
$dispatcher->addSubscriber(new ElasticaQuerySubscriber());
$dispatcher->addSubscriber(new MockPaginationSubscriber); // pagination view
$p = new Paginator($dispatcher);
$query = Query::create(new Term(array(
'name' => 'Fred',
)));
$response = $this->getMockBuilder('Elastica\\ResultSet')->disableOriginalConstructor()->getMock();
$response->expects($this->once())
->method('getTotalHits')
->will($this->returnValue(2));
$response->expects($this->once())
->method('getResults')
->will($this->returnValue(array(new Result(array()), new Result(array()))));
$searchable = $this->getMockBuilder('Elastica\\SearchableInterface')->getMock();
$searchable->expects($this->once())
->method('search')
->with($query)
->will($this->returnValue($response));
$view = $p->paginate(array($searchable, $query), 1, 10);
$this->assertEquals(0, $query->getParam('from'), 'Query offset set correctly');
$this->assertEquals(10, $query->getParam('size'), 'Query limit set correctly');
$this->assertSame($response, $view->getCustomParameter('resultSet'), 'Elastica ResultSet available in Paginator');
$this->assertEquals(1, $view->getCurrentPageNumber());
$this->assertEquals(10, $view->getItemNumberPerPage());
$this->assertEquals(2, count($view->getItems()));
$this->assertEquals(2, $view->getTotalItemCount());
}
/**
* @test
*/
function shouldSlicePaginateAnArray()
{
/*$dispatcher = new EventDispatcher;
$dispatcher->addSubscriber(new ArraySubscriber);
$dispatcher->addSubscriber(new MockPaginationSubscriber); // pagination view
$p = new Paginator($dispatcher);
$items = range('a', 'u');
$view = $p->paginate($items, 2, 10);
$this->assertEquals(2, $view->getCurrentPageNumber());
$this->assertEquals(10, $view->getItemNumberPerPage());
$this->assertEquals(10, count($view->getItems()));
$this->assertEquals(21, $view->getTotalItemCount());*/
}
}

View File

@@ -0,0 +1,25 @@
<?php
use Test\Tool\BaseTestCase;
use Knp\Component\Pager\Event\Subscriber\Paginate\PaginationSubscriber;
use Knp\Component\Pager\Event\BeforeEvent;
class PaginationSubscriberTest extends BaseTestCase
{
/**
* @test
*/
function shouldRegisterExpectedSubscribersOnlyOnce()
{
$dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcherInterface')->getMock();
$dispatcher->expects($this->exactly(13))->method('addSubscriber');
$subscriber = new PaginationSubscriber;
$beforeEvent = new BeforeEvent($dispatcher);
$subscriber->before($beforeEvent);
// Subsequent calls do not add more subscribers
$subscriber->before($beforeEvent);
}
}

View File

@@ -0,0 +1,31 @@
<?php
namespace Test\Pager\Subscriber\Paginate;
use Knp\Component\Pager\Paginator;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Knp\Component\Pager\Pagination\PaginationInterface;
use Knp\Component\Pager\Event\Subscriber\Paginate\ArraySubscriber;
use Knp\Component\Pager\Event\Subscriber\Paginate\SolariumQuerySubscriber;
use Test\Mock\PaginationSubscriber as MockPaginationSubscriber;
class SolariumQuerySubscriberTest extends \PHPUnit_Framework_TestCase
{
/**
* @test
* @expectedException RuntimeException
* @expectedExceptionMessage One of listeners must count and slice given target
*/
function testArrayShouldNotBeHandled()
{
$array = array(1 => 'foo', 2 => 'bar');
$dispatcher = new EventDispatcher;
$dispatcher->addSubscriber(new SolariumQuerySubscriber);
$dispatcher->addSubscriber(new MockPaginationSubscriber);
$p = new Paginator($dispatcher);
$p->paginate($array, 1, 10);
}
}

View File

@@ -0,0 +1,115 @@
<?php
namespace Test\Pager\Subscriber\Sortable;
use Knp\Component\Pager\Event\ItemsEvent;
use Knp\Component\Pager\Event\Subscriber\Sortable\ArraySubscriber;
use Test\Tool\BaseTestCase;
use Knp\Component\Pager\PaginatorInterface;
class ArraySubscriberTest extends BaseTestCase
{
/**
* @test
*/
public function shouldSort()
{
$array = array(
array('entry' => array('sortProperty' => 2)),
array('entry' => array('sortProperty' => 3)),
array('entry' => array('sortProperty' => 1)),
);
$itemsEvent = new ItemsEvent(0, 10);
$itemsEvent->target = &$array;
$itemsEvent->options = array(PaginatorInterface::SORT_FIELD_PARAMETER_NAME => 'sort', PaginatorInterface::SORT_DIRECTION_PARAMETER_NAME => 'ord');
$arraySubscriber = new ArraySubscriber();
// test asc sort
$_GET = array('sort' => '[entry][sortProperty]', 'ord' => 'asc');
$arraySubscriber->items($itemsEvent);
$this->assertEquals(1, $array[0]['entry']['sortProperty']);
$itemsEvent->unsetCustomPaginationParameter('sorted');
// test desc sort
$_GET ['ord'] = 'desc';
$arraySubscriber->items($itemsEvent);
$this->assertEquals(3, $array[0]['entry']['sortProperty']);
}
/**
* @test
*/
public function shouldSortWithCustomCallback()
{
$array = array(
array('name' => 'hot'),
array('name' => 'cold'),
array('name' => 'hot'),
);
$itemsEvent = new ItemsEvent(0, 10);
$itemsEvent->target = &$array;
$itemsEvent->options = array(
PaginatorInterface::SORT_FIELD_PARAMETER_NAME => 'sort',
PaginatorInterface::SORT_DIRECTION_PARAMETER_NAME => 'ord',
'sortFunction' => function (&$target, $sortField, $sortDirection) {
usort($target, function($object1, $object2) use ($sortField, $sortDirection) {
if ($object1[$sortField] === $object2[$sortField]) {
return 0;
}
return ($object1[$sortField] === 'hot' ? 1 : -1) * ($sortDirection === 'asc' ? 1 : -1);
});
},
);
$arraySubscriber = new ArraySubscriber();
// test asc sort
$_GET = array('sort' => '.name', 'ord' => 'asc');
$arraySubscriber->items($itemsEvent);
$this->assertEquals('cold', $array[0]['name']);
$itemsEvent->unsetCustomPaginationParameter('sorted');
// test desc sort
$_GET['ord'] = 'desc';
$arraySubscriber->items($itemsEvent);
$this->assertEquals('hot', $array[0]['name']);
}
/**
* @test
*/
public function shouldSortEvenWhenTheSortPropertyIsNotAccessible()
{
$array = array(
array('entry' => array('sortProperty' => 2)),
array('entry' => array()),
array('entry' => array('sortProperty' => 1)),
);
$itemsEvent = new ItemsEvent(0, 10);
$itemsEvent->target = &$array;
$itemsEvent->options = array(PaginatorInterface::SORT_FIELD_PARAMETER_NAME => 'sort', PaginatorInterface::SORT_DIRECTION_PARAMETER_NAME => 'ord');
$arraySubscriber = new ArraySubscriber();
// test asc sort
$_GET = array('sort' => '[entry][sortProperty]', 'ord' => 'asc');
$arraySubscriber->items($itemsEvent);
$this->assertEquals(false, isset($array[0]['entry']['sortProperty']));
$itemsEvent->unsetCustomPaginationParameter('sorted');
// test desc sort
$_GET ['ord'] = 'desc';
$arraySubscriber->items($itemsEvent);
$this->assertEquals(2, $array[0]['entry']['sortProperty']);
}
}

View File

@@ -0,0 +1,89 @@
<?php
namespace Test\Pager\Subscriber\Sortable\Doctrine\ODM\MongoDB;
use Test\Tool\BaseTestCaseMongoODM;
use Knp\Component\Pager\Paginator;
use Knp\Component\Pager\Pagination\SlidingPagination;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Knp\Component\Pager\Pagination\PaginationInterface;
use Knp\Component\Pager\Event\Subscriber\Paginate\PaginationSubscriber;
use Knp\Component\Pager\Event\Subscriber\Sortable\Doctrine\ODM\MongoDB\QuerySubscriber as Sortable;
use Test\Fixture\Document\Article;
class QueryTest extends BaseTestCaseMongoODM
{
/**
* @test
*/
function shouldSortSimpleDoctrineQuery()
{
$this->populate();
$dispatcher = new EventDispatcher;
$dispatcher->addSubscriber(new PaginationSubscriber);
$dispatcher->addSubscriber(new Sortable);
$p = new Paginator($dispatcher);
$_GET['sort'] = 'title';
$_GET['direction'] = 'asc';
$qb = $this->dm->createQueryBuilder('Test\Fixture\Document\Article');
$query = $qb->getQuery();
$view = $p->paginate($query, 1, 10);
$items = array_values($view->getItems());
$this->assertEquals(4, count($items));
$this->assertEquals('autumn', $items[0]->getTitle());
$this->assertEquals('spring', $items[1]->getTitle());
$this->assertEquals('summer', $items[2]->getTitle());
$this->assertEquals('winter', $items[3]->getTitle());
$_GET['direction'] = 'desc';
$view = $p->paginate($query, 1, 10);
$items = array_values($view->getItems());
$this->assertEquals(4, count($items));
$this->assertEquals('winter', $items[0]->getTitle());
$this->assertEquals('summer', $items[1]->getTitle());
$this->assertEquals('spring', $items[2]->getTitle());
$this->assertEquals('autumn', $items[3]->getTitle());
}
/**
* @test
*/
function shouldSortOnAnyField()
{
$_GET['sort'] = '"title\'';
$_GET['direction'] = 'asc';
$query = $this
->getMockDocumentManager()
->createQueryBuilder('Test\Fixture\Document\Article')
->getQuery()
;
$p = new Paginator;
$view = $p->paginate($query, 1, 10);
}
private function populate()
{
$em = $this->getMockDocumentManager();
$summer = new Article;
$summer->setTitle('summer');
$winter = new Article;
$winter->setTitle('winter');
$autumn = new Article;
$autumn->setTitle('autumn');
$spring = new Article;
$spring->setTitle('spring');
$em->persist($summer);
$em->persist($winter);
$em->persist($autumn);
$em->persist($spring);
$em->flush();
}
}

View File

@@ -0,0 +1,90 @@
<?php
namespace Test\Pager\Subscriber\Sortable\Doctrine\ODM\MongoDB;
use Knp\Component\Pager\PaginatorInterface;
use Test\Tool\BaseTestCaseMongoODM;
use Knp\Component\Pager\Paginator;
use Knp\Component\Pager\Pagination\SlidingPagination;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Knp\Component\Pager\Pagination\PaginationInterface;
use Knp\Component\Pager\Event\Subscriber\Paginate\PaginationSubscriber;
use Knp\Component\Pager\Event\Subscriber\Sortable\Doctrine\ODM\MongoDB\QuerySubscriber as Sortable;
use Test\Fixture\Document\Article;
class WhitelistTest extends BaseTestCaseMongoODM
{
/**
* @test
* @expectedException UnexpectedValueException
*/
function shouldWhitelistSortableFields()
{
$this->populate();
$_GET['sort'] = 'title';
$_GET['direction'] = 'asc';
$query = $this->dm
->createQueryBuilder('Test\Fixture\Document\Article')
->getQuery()
;
$p = new Paginator;
$sortFieldWhitelist = array('title');
$view = $p->paginate($query, 1, 10, compact(PaginatorInterface::SORT_FIELD_WHITELIST));
$items = array_values($view->getItems());
$this->assertEquals(4, count($items));
$this->assertEquals('autumn', $items[0]->getTitle());
$_GET['sort'] = 'id';
$view = $p->paginate($query, 1, 10, compact(PaginatorInterface::SORT_FIELD_WHITELIST));
}
/**
* @test
*/
function shouldSortWithoutSpecificWhitelist()
{
$this->populate();
$_GET['sort'] = 'title';
$_GET['direction'] = 'asc';
$query = $this->dm
->createQueryBuilder('Test\Fixture\Document\Article')
->getQuery()
;
$p = new Paginator;
$view = $p->paginate($query, 1, 10);
$items = array_values($view->getItems());
$this->assertEquals('autumn', $items[0]->getTitle());
$_GET['sort'] = 'id';
$view = $p->paginate($query, 1, 10);
$items = array_values($view->getItems());
$this->assertEquals('summer', $items[0]->getTitle());
}
private function populate()
{
$em = $this->getMockDocumentManager();
$summer = new Article;
$summer->setTitle('summer');
$winter = new Article;
$winter->setTitle('winter');
$autumn = new Article;
$autumn->setTitle('autumn');
$spring = new Article;
$spring->setTitle('spring');
$em->persist($summer);
$em->persist($winter);
$em->persist($autumn);
$em->persist($spring);
$em->flush();
}
}

View File

@@ -0,0 +1,254 @@
<?php
namespace Test\Pager\Subscriber\Sortable\Doctrine\ORM;
use Knp\Component\Pager\PaginatorInterface;
use Test\Tool\BaseTestCaseORM;
use Knp\Component\Pager\Paginator;
use Knp\Component\Pager\Pagination\SlidingPagination;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Knp\Component\Pager\Pagination\PaginationInterface;
use Knp\Component\Pager\Event\Subscriber\Paginate\Doctrine\ORM\QuerySubscriber;
use Knp\Component\Pager\Event\Subscriber\Paginate\PaginationSubscriber;
use Knp\Component\Pager\Event\Subscriber\Sortable\Doctrine\ORM\QuerySubscriber as Sortable;
use Test\Fixture\Entity\Article;
use Knp\Component\Pager\Event\Subscriber\Paginate\Doctrine\ORM\QuerySubscriber\UsesPaginator;
class QueryTest extends BaseTestCaseORM
{
/**
* @test
*/
function shouldHandleApcQueryCache()
{
if (!extension_loaded('apc') || !ini_get('apc.enable_cli')) {
$this->markTestSkipped('APC extension is not loaded.');
}
$config = new \Doctrine\ORM\Configuration();
$config->setMetadataCacheImpl(new \Doctrine\Common\Cache\ApcCache);
$config->setQueryCacheImpl(new \Doctrine\Common\Cache\ApcCache);
$config->setProxyDir(__DIR__);
$config->setProxyNamespace('Gedmo\Mapping\Proxy');
$config->getAutoGenerateProxyClasses(false);
$config->setMetadataDriverImpl($this->getMetadataDriverImplementation());
$conn = array(
'driver' => 'pdo_sqlite',
'memory' => true,
);
$em = \Doctrine\ORM\EntityManager::create($conn, $config);
$schema = array_map(function($class) use ($em) {
return $em->getClassMetadata($class);
}, (array)$this->getUsedEntityFixtures());
$schemaTool = new \Doctrine\ORM\Tools\SchemaTool($em);
$schemaTool->dropSchema(array());
$schemaTool->createSchema($schema);
$this->populate($em);
$_GET['sort'] = 'a.title';
$_GET['direction'] = 'asc';
$query = $em->createQuery('SELECT a FROM Test\Fixture\Entity\Article a');
$p = new Paginator;
$view = $p->paginate($query, 1, 10);
$query = $em->createQuery('SELECT a FROM Test\Fixture\Entity\Article a');
$view = $p->paginate($query, 1, 10);
}
/**
* @test
*/
function shouldSortSimpleDoctrineQuery()
{
$em = $this->getMockSqliteEntityManager();
$this->populate($em);
$dispatcher = new EventDispatcher;
$dispatcher->addSubscriber(new PaginationSubscriber);
$dispatcher->addSubscriber(new Sortable);
$p = new Paginator($dispatcher);
$_GET['sort'] = 'a.title';
$_GET['direction'] = 'asc';
$this->startQueryLog();
$query = $this->em->createQuery('SELECT a FROM Test\Fixture\Entity\Article a');
$query->setHint(UsesPaginator::HINT_FETCH_JOIN_COLLECTION, false);
$view = $p->paginate($query, 1, 10);
$items = $view->getItems();
$this->assertEquals(4, count($items));
$this->assertEquals('autumn', $items[0]->getTitle());
$this->assertEquals('spring', $items[1]->getTitle());
$this->assertEquals('summer', $items[2]->getTitle());
$this->assertEquals('winter', $items[3]->getTitle());
$_GET['direction'] = 'desc';
$view = $p->paginate($query, 1, 10);
$items = $view->getItems();
$this->assertEquals(4, count($items));
$this->assertEquals('winter', $items[0]->getTitle());
$this->assertEquals('summer', $items[1]->getTitle());
$this->assertEquals('spring', $items[2]->getTitle());
$this->assertEquals('autumn', $items[3]->getTitle());
$this->assertEquals(4, $this->queryAnalyzer->getNumExecutedQueries());
$executed = $this->queryAnalyzer->getExecutedQueries();
// Different aliases separators according to Doctrine version
if (version_compare(\Doctrine\ORM\Version::VERSION, '2.5', '<')) {
$this->assertEquals('SELECT a0_.id AS id0, a0_.title AS title1, a0_.enabled AS enabled2 FROM Article a0_ ORDER BY a0_.title ASC LIMIT 10 OFFSET 0', $executed[1]);
$this->assertEquals('SELECT a0_.id AS id0, a0_.title AS title1, a0_.enabled AS enabled2 FROM Article a0_ ORDER BY a0_.title DESC LIMIT 10 OFFSET 0', $executed[3]);
} else {
$this->assertEquals('SELECT a0_.id AS id_0, a0_.title AS title_1, a0_.enabled AS enabled_2 FROM Article a0_ ORDER BY a0_.title ASC LIMIT 10 OFFSET 0', $executed[1]);
$this->assertEquals('SELECT a0_.id AS id_0, a0_.title AS title_1, a0_.enabled AS enabled_2 FROM Article a0_ ORDER BY a0_.title DESC LIMIT 10 OFFSET 0', $executed[3]);
}
}
/**
* @test
* @expectedException UnexpectedValueException
*/
function shouldValidateSortableParameters()
{
$_GET['sort'] = '"a.title\'';
$_GET['direction'] = 'asc';
$query = $this
->getMockSqliteEntityManager()
->createQuery('SELECT a FROM Test\Fixture\Entity\Article a')
;
$p = new Paginator;
$view = $p->paginate($query, 1, 10);
}
/**
* @test
*/
function shouldSortByAnyAvailableAlias()
{
$em = $this->getMockSqliteEntityManager();
$this->populate($em);
$_GET['sort'] = 'counter';
$_GET['direction'] = 'asc';
$dql = <<<___SQL
SELECT a, COUNT(a) AS counter
FROM Test\Fixture\Entity\Article a
___SQL;
$query = $this->em->createQuery($dql);
$query->setHint(UsesPaginator::HINT_FETCH_JOIN_COLLECTION, false);
$p = new Paginator;
$this->startQueryLog();
$view = $p->paginate($query, 1, 10, array(PaginatorInterface::DISTINCT => false));
$this->assertEquals(2, $this->queryAnalyzer->getNumExecutedQueries());
$executed = $this->queryAnalyzer->getExecutedQueries();
// Different aliases separators according to Doctrine version
if (version_compare(\Doctrine\ORM\Version::VERSION, '2.5', '<')) {
$this->assertEquals('SELECT a0_.id AS id0, a0_.title AS title1, a0_.enabled AS enabled2, COUNT(a0_.id) AS sclr3 FROM Article a0_ ORDER BY sclr3 ASC LIMIT 10 OFFSET 0', $executed[1]);
} else {
$this->assertEquals('SELECT a0_.id AS id_0, a0_.title AS title_1, a0_.enabled AS enabled_2, COUNT(a0_.id) AS sclr_3 FROM Article a0_ ORDER BY sclr_3 ASC LIMIT 10 OFFSET 0', $executed[1]);
}
}
/**
* @test
*/
function shouldWorkWithInitialPaginatorEventDispatcher()
{
$em = $this->getMockSqliteEntityManager();
$this->populate($em);
$_GET['sort'] = 'a.title';
$_GET['direction'] = 'asc';
$query = $this
->em
->createQuery('SELECT a FROM Test\Fixture\Entity\Article a')
;
$query->setHint(UsesPaginator::HINT_FETCH_JOIN_COLLECTION, false);
$p = new Paginator;
$this->startQueryLog();
$view = $p->paginate($query, 1, 10);
$this->assertTrue($view instanceof SlidingPagination);
$this->assertEquals(2, $this->queryAnalyzer->getNumExecutedQueries());
$executed = $this->queryAnalyzer->getExecutedQueries();
// Different aliases separators according to Doctrine version
if (version_compare(\Doctrine\ORM\Version::VERSION, '2.5', '<')) {
$this->assertEquals('SELECT a0_.id AS id0, a0_.title AS title1, a0_.enabled AS enabled2 FROM Article a0_ ORDER BY a0_.title ASC LIMIT 10 OFFSET 0', $executed[1]);
} else {
$this->assertEquals('SELECT a0_.id AS id_0, a0_.title AS title_1, a0_.enabled AS enabled_2 FROM Article a0_ ORDER BY a0_.title ASC LIMIT 10 OFFSET 0', $executed[1]);
}
}
/**
* @test
*/
function shouldNotExecuteExtraQueriesWhenCountIsZero()
{
$_GET['sort'] = 'a.title';
$_GET['direction'] = 'asc';
$query = $this
->getMockSqliteEntityManager()
->createQuery('SELECT a FROM Test\Fixture\Entity\Article a')
;
$p = new Paginator;
$this->startQueryLog();
$view = $p->paginate($query, 1, 10);
$this->assertTrue($view instanceof SlidingPagination);
$this->assertEquals(2, $this->queryAnalyzer->getNumExecutedQueries());
}
protected function getUsedEntityFixtures()
{
return array('Test\Fixture\Entity\Article');
}
private function populate($em)
{
$summer = new Article;
$summer->setTitle('summer');
$winter = new Article;
$winter->setTitle('winter');
$autumn = new Article;
$autumn->setTitle('autumn');
$spring = new Article;
$spring->setTitle('spring');
$em->persist($summer);
$em->persist($winter);
$em->persist($autumn);
$em->persist($spring);
$em->flush();
}
private function getApcEntityManager()
{
$config = new \Doctrine\ORM\Configuration();
$config->setMetadataCacheImpl(new \Doctrine\Common\Cache\ApcCache);
$config->setQueryCacheImpl(new \Doctrine\Common\Cache\ApcCache);
$config->setProxyDir(__DIR__);
$config->setProxyNamespace('Gedmo\Mapping\Proxy');
$config->setAutoGenerateProxyClasses(false);
$config->setMetadataDriverImpl($this->getMetadataDriverImplementation());
$conn = array(
'driver' => 'pdo_sqlite',
'memory' => true,
);
$em = \Doctrine\ORM\EntityManager::create($conn, $config);
return $em;
}
}

View File

@@ -0,0 +1,90 @@
<?php
namespace Test\Pager\Subscriber\Sortable\Doctrine\ORM;
use Knp\Component\Pager\PaginatorInterface;
use Test\Tool\BaseTestCaseORM;
use Knp\Component\Pager\Paginator;
use Knp\Component\Pager\Pagination\SlidingPagination;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Knp\Component\Pager\Pagination\PaginationInterface;
use Knp\Component\Pager\Event\Subscriber\Paginate\Doctrine\ORM\QuerySubscriber;
use Knp\Component\Pager\Event\Subscriber\Paginate\PaginationSubscriber;
use Knp\Component\Pager\Event\Subscriber\Sortable\Doctrine\ORM\QuerySubscriber as Sortable;
use Test\Fixture\Entity\Article;
class WhitelistTest extends BaseTestCaseORM
{
/**
* @test
* @expectedException UnexpectedValueException
*/
function shouldWhitelistSortableFields()
{
$this->populate();
$_GET['sort'] = 'a.title';
$_GET['direction'] = 'asc';
$query = $this->em->createQuery('SELECT a FROM Test\Fixture\Entity\Article a');
$p = new Paginator;
$sortFieldWhitelist = array('a.title');
$view = $p->paginate($query, 1, 10, compact(PaginatorInterface::SORT_FIELD_WHITELIST));
$items = $view->getItems();
$this->assertEquals(4, count($items));
$this->assertEquals('autumn', $items[0]->getTitle());
$_GET['sort'] = 'a.id';
$view = $p->paginate($query, 1, 10, compact(PaginatorInterface::SORT_FIELD_WHITELIST));
}
/**
* @test
*/
function shouldSortWithoutSpecificWhitelist()
{
$this->populate();
$_GET['sort'] = 'a.title';
$_GET['direction'] = 'asc';
$query = $this->em->createQuery('SELECT a FROM Test\Fixture\Entity\Article a');
$p = new Paginator;
$view = $p->paginate($query, 1, 10);
$items = $view->getItems();
$this->assertEquals('autumn', $items[0]->getTitle());
$_GET['sort'] = 'a.id';
$view = $p->paginate($query, 1, 10);
$items = $view->getItems();
$this->assertEquals('summer', $items[0]->getTitle());
}
protected function getUsedEntityFixtures()
{
return array('Test\Fixture\Entity\Article');
}
private function populate()
{
$em = $this->getMockSqliteEntityManager();
$summer = new Article;
$summer->setTitle('summer');
$winter = new Article;
$winter->setTitle('winter');
$autumn = new Article;
$autumn->setTitle('autumn');
$spring = new Article;
$spring->setTitle('spring');
$em->persist($summer);
$em->persist($winter);
$em->persist($autumn);
$em->persist($spring);
$em->flush();
}
}

View File

@@ -0,0 +1,42 @@
<?php
namespace Test\Pager\Subscriber\Sortable;
use Knp\Component\Pager\Paginator;
use Symfony\Component\EventDispatcher\EventDispatcher;
use Knp\Component\Pager\Pagination\PaginationInterface;
use Knp\Component\Pager\Event\Subscriber\Sortable\SolariumQuerySubscriber;
use Test\Mock\PaginationSubscriber as MockPaginationSubscriber;
class SolariumQuerySubscriberTest extends \PHPUnit_Framework_TestCase
{
/**
* @test
* @expectedException RuntimeException
* @expectedExceptionMessage One of listeners must count and slice given target
*/
function testArrayShouldNotBeHandled()
{
$array = array(
'results' => array(
0 => array(
'city' => 'Lyon',
'market' => 'E'
),
1 => array(
'city' => 'Paris',
'market' => 'G'
),
),
'nbTotalResults' => 2
);
$dispatcher = new EventDispatcher;
$dispatcher->addSubscriber(new SolariumQuerySubscriber);
$dispatcher->addSubscriber(new MockPaginationSubscriber);
$p = new Paginator($dispatcher);
$p->paginate($array, 1, 10);
}
}

View File

@@ -0,0 +1,25 @@
<?php
use Test\Tool\BaseTestCase;
use Knp\Component\Pager\Event\Subscriber\Sortable\SortableSubscriber;
use Knp\Component\Pager\Event\BeforeEvent;
class SortableSubscriberTest extends BaseTestCase
{
/**
* @test
*/
function shouldRegisterExpectedSubscribersOnlyOnce()
{
$dispatcher = $this->getMockBuilder('Symfony\Component\EventDispatcher\EventDispatcherInterface')->getMock();
$dispatcher->expects($this->exactly(6))->method('addSubscriber');
$subscriber = new SortableSubscriber;
$beforeEvent = new BeforeEvent($dispatcher);
$subscriber->before($beforeEvent);
// Subsequent calls do not add more subscribers
$subscriber->before($beforeEvent);
}
}

View File

@@ -0,0 +1,19 @@
<?php
namespace Test\Tool;
use PHPUnit_Framework_TestCase;
/**
* Base test case
*/
abstract class BaseTestCase extends PHPUnit_Framework_TestCase
{
/**
* {@inheritdoc}
*/
protected function setUp()
{
}
}

View File

@@ -0,0 +1,162 @@
<?php
namespace Test\Tool;
use Doctrine\Common\Annotations\AnnotationReader;
use Doctrine\ODM\MongoDB\Mapping\Driver\AnnotationDriver;
use Doctrine\ODM\MongoDB\DocumentManager;
use Doctrine\Common\EventManager;
use Doctrine\MongoDB\Connection;
/**
* Base test case contains common mock objects
*/
abstract class BaseTestCaseMongoODM extends \PHPUnit_Framework_TestCase
{
/**
* @var DocumentManager
*/
protected $dm;
/**
* {@inheritdoc}
*/
protected function setUp()
{
if (!class_exists('MongoClient')) {
$this->markTestSkipped('Missing Mongo extension.');
}
}
/**
* {@inheritdoc}
*/
protected function tearDown()
{
if ($this->dm) {
foreach ($this->dm->getDocumentDatabases() as $db) {
foreach ($db->listCollections() as $collection) {
$collection->drop();
}
}
$this->dm->getConnection()->close();
$this->dm = null;
}
}
/**
* DocumentManager mock object together with
* annotation mapping driver and database
*
* @param EventManager $evm
* @return DocumentManager
*/
protected function getMockDocumentManager(EventManager $evm = null)
{
$conn = new Connection;
$config = $this->getMockAnnotatedConfig();
try {
$this->dm = DocumentManager::create($conn, $config, $evm ?: $this->getEventManager());
$this->dm->getConnection()->connect();
} catch (\MongoException $e) {
$this->markTestSkipped('Doctrine MongoDB ODM failed to connect');
}
return $this->dm;
}
/**
* DocumentManager mock object with
* annotation mapping driver
*
* @param EventManager $evm
* @return DocumentManager
*/
protected function getMockMappedDocumentManager(EventManager $evm = null)
{
$conn = $this->getMock('Doctrine\\MongoDB\\Connection');
$config = $this->getMockAnnotatedConfig();
$this->dm = DocumentManager::create($conn, $config, $evm ?: $this->getEventManager());
return $this->dm;
}
/**
* Creates default mapping driver
*
* @return \Doctrine\ORM\Mapping\Driver\Driver
*/
protected function getMetadataDriverImplementation()
{
return new AnnotationDriver($_ENV['annotation_reader']);
}
/**
* Build event manager
*
* @return EventManager
*/
private function getEventManager()
{
$evm = new EventManager;
return $evm;
}
/**
* Get annotation mapping configuration
*
* @return Doctrine\ORM\Configuration
*/
private function getMockAnnotatedConfig()
{
$config = $this->getMock('Doctrine\\ODM\\MongoDB\\Configuration');
$config->expects($this->once())
->method('getProxyDir')
->will($this->returnValue(__DIR__.'/../../temp'));
$config->expects($this->once())
->method('getProxyNamespace')
->will($this->returnValue('Proxy'));
$config->expects($this->once())
->method('getHydratorDir')
->will($this->returnValue(__DIR__.'/../../temp'));
$config->expects($this->once())
->method('getHydratorNamespace')
->will($this->returnValue('Hydrator'));
$config->expects($this->any())
->method('getDefaultDB')
->will($this->returnValue('knp_pager_tests'));
$config->expects($this->once())
->method('getAutoGenerateProxyClasses')
->will($this->returnValue(true));
$config->expects($this->once())
->method('getAutoGenerateHydratorClasses')
->will($this->returnValue(true));
$config->expects($this->once())
->method('getClassMetadataFactoryName')
->will($this->returnValue('Doctrine\\ODM\\MongoDB\\Mapping\\ClassMetadataFactory'));
$config->expects($this->any())
->method('getMongoCmd')
->will($this->returnValue('$'));
$config
->expects($this->any())
->method('getDefaultCommitOptions')
->will($this->returnValue(array('safe' => true)))
;
$mappingDriver = $this->getMetadataDriverImplementation();
$config->expects($this->any())
->method('getMetadataDriverImpl')
->will($this->returnValue($mappingDriver));
return $config;
}
}

View File

@@ -0,0 +1,264 @@
<?php
namespace Test\Tool;
use Doctrine\Common\Annotations\AnnotationReader;
use Doctrine\ORM\Mapping\DefaultNamingStrategy;
use Doctrine\ORM\Mapping\DefaultQuoteStrategy;
use Doctrine\ORM\Mapping\Driver\AnnotationDriver;
use Doctrine\ORM\EntityManager;
use Doctrine\Common\EventManager;
use Doctrine\ORM\Tools\SchemaTool;
/**
* Base test case contains common mock objects
* and functionality among all extensions using
* ORM object manager
*
* @author Gediminas Morkevicius <gediminas.morkevicius@gmail.com>
* @package Gedmo
* @subpackage BaseTestCase
* @link http://www.gediminasm.org
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
abstract class BaseTestCaseORM extends \PHPUnit_Framework_TestCase
{
/**
* @var EntityManager
*/
protected $em;
/**
* @var QueryAnalyzer
*/
protected $queryAnalyzer;
/**
* {@inheritdoc}
*/
protected function setUp()
{
}
/**
* EntityManager mock object together with
* annotation mapping driver and pdo_sqlite
* database in memory
*
* @param EventManager $evm
* @return EntityManager
*/
protected function getMockSqliteEntityManager(EventManager $evm = null)
{
$conn = array(
'driver' => 'pdo_sqlite',
'memory' => true,
);
$config = $this->getMockAnnotatedConfig();
$em = EntityManager::create($conn, $config, $evm ?: $this->getEventManager());
$schema = array_map(function($class) use ($em) {
return $em->getClassMetadata($class);
}, (array)$this->getUsedEntityFixtures());
$schemaTool = new SchemaTool($em);
$schemaTool->dropSchema(array());
$schemaTool->createSchema($schema);
return $this->em = $em;
}
/**
* EntityManager mock object together with
* annotation mapping driver and custom
* connection
*
* @param array $conn
* @param EventManager $evm
* @return EntityManager
*/
protected function getMockCustomEntityManager(array $conn, EventManager $evm = null)
{
$config = $this->getMockAnnotatedConfig();
$em = EntityManager::create($conn, $config, $evm ?: $this->getEventManager());
$schema = array_map(function($class) use ($em) {
return $em->getClassMetadata($class);
}, (array)$this->getUsedEntityFixtures());
$schemaTool = new SchemaTool($em);
$schemaTool->dropSchema(array());
$schemaTool->createSchema($schema);
return $this->em = $em;
}
/**
* EntityManager mock object with
* annotation mapping driver
*
* @param EventManager $evm
* @return EntityManager
*/
protected function getMockMappedEntityManager(EventManager $evm = null)
{
$driver = $this->getMock('Doctrine\DBAL\Driver');
$driver->expects($this->once())
->method('getDatabasePlatform')
->will($this->returnValue($this->getMock('Doctrine\DBAL\Platforms\MySqlPlatform')));
$conn = $this->getMock('Doctrine\DBAL\Connection', array(), array(array(), $driver));
$conn->expects($this->once())
->method('getEventManager')
->will($this->returnValue($evm ?: $this->getEventManager()));
$config = $this->getMockAnnotatedConfig();
$this->em = EntityManager::create($conn, $config);
return $this->em;
}
/**
* Starts query statistic log
*
* @throws \RuntimeException
*/
protected function startQueryLog()
{
if (!$this->em || !$this->em->getConnection()->getDatabasePlatform()) {
throw new \RuntimeException('EntityManager and database platform must be initialized');
}
$this->queryAnalyzer = new QueryAnalyzer($this->em->getConnection()->getDatabasePlatform());
$this->em
->getConfiguration()
->expects($this->any())
->method('getSQLLogger')
->will($this->returnValue($this->queryAnalyzer));
}
/**
* Stops query statistic log and outputs
* the data to screen or file
*
* @param boolean $dumpOnlySql
* @param boolean $writeToLog
* @throws \RuntimeException
*/
protected function stopQueryLog($dumpOnlySql = false, $writeToLog = false)
{
if ($this->queryAnalyzer) {
$output = $this->queryAnalyzer->getOutput($dumpOnlySql);
if ($writeToLog) {
$fileName = __DIR__.'/../../temp/query_debug_'.time().'.log';
if (($file = fopen($fileName, 'w+')) !== false) {
fwrite($file, $output);
fclose($file);
} else {
throw new \RuntimeException('Unable to write to the log file');
}
} else {
echo $output;
}
}
}
/**
* Creates default mapping driver
*
* @return \Doctrine\ORM\Mapping\Driver\Driver
*/
protected function getMetadataDriverImplementation()
{
return new AnnotationDriver($_ENV['annotation_reader']);
}
/**
* Get a list of used fixture classes
*
* @return array
*/
abstract protected function getUsedEntityFixtures();
/**
* Build event manager
*
* @return EventManager
*/
private function getEventManager()
{
$evm = new EventManager;
return $evm;
}
/**
* Get annotation mapping configuration
*
* @return Doctrine\ORM\Configuration
*/
private function getMockAnnotatedConfig()
{
$config = $this->getMock('Doctrine\ORM\Configuration');
$config
->expects($this->once())
->method('getProxyDir')
->will($this->returnValue(__DIR__.'/../../temp'))
;
$config
->expects($this->once())
->method('getProxyNamespace')
->will($this->returnValue('Proxy'))
;
$config
->expects($this->once())
->method('getAutoGenerateProxyClasses')
->will($this->returnValue(true))
;
$config
->expects($this->once())
->method('getClassMetadataFactoryName')
->will($this->returnValue('Doctrine\\ORM\\Mapping\\ClassMetadataFactory'))
;
$mappingDriver = $this->getMetadataDriverImplementation();
$config
->expects($this->any())
->method('getMetadataDriverImpl')
->will($this->returnValue($mappingDriver))
;
$config
->expects($this->any())
->method('getDefaultRepositoryClassName')
->will($this->returnValue('Doctrine\\ORM\\EntityRepository'))
;
$config
->expects($this->any())
->method('getQuoteStrategy')
->will($this->returnValue(new DefaultQuoteStrategy()))
;
$config
->expects($this->any())
->method('getNamingStrategy')
->will($this->returnValue(new DefaultNamingStrategy()))
;
$config
->expects($this->any())
->method('getCustomHydrationMode')
->will($this->returnValue('Knp\Component\Pager\Event\Subscriber\Paginate\Doctrine\ORM\Query\AsIsHydrator'))
;
$config
->expects($this->any())
->method('getDefaultQueryHints')
->will($this->returnValue(array()))
;
return $config;
}
}

View File

@@ -0,0 +1,88 @@
<?php
namespace Test\Tool;
use Doctrine\Common\Annotations\AnnotationReader;
use Doctrine\DBAL\DriverManager;
use Doctrine\ODM\PHPCR\Mapping\Driver\AnnotationDriver;
use Doctrine\ODM\PHPCR\DocumentManager;
use Doctrine\Common\EventManager;
use Doctrine\MongoDB\Connection;
use Jackalope\RepositoryFactoryDoctrineDBAL;
use Jackalope\Session;
use Jackalope\Transport\DoctrineDBAL\RepositorySchema;
/**
* Base test case contains common mock objects
*/
abstract class BaseTestCasePHPCRODM extends \PHPUnit_Framework_TestCase
{
/**
* @var DocumentManager
*/
protected $dm;
protected function setUp()
{
if (!class_exists('Doctrine\ODM\PHPCR\Query\Query')) {
$this->markTestSkipped('Doctrine PHPCR-ODM is not available');
}
}
protected function tearDown()
{
if ($this->dm) {
$this->dm = null;
}
}
protected function getMockDocumentManager(EventManager $evm = null)
{
$config = new \Doctrine\ODM\PHPCR\Configuration();
$config->setMetadataDriverImpl($this->getMetadataDriverImplementation());
$this->dm = DocumentManager::create($this->getSession(), $config, $evm ?: $this->getEventManager());
return $this->dm;
}
protected function getMetadataDriverImplementation()
{
return new AnnotationDriver($_ENV['annotation_reader']);
}
private function getSession()
{
$connection = DriverManager::getConnection(array(
'driver' => 'pdo_sqlite',
'path' => ':memory:',
));
$factory = new RepositoryFactoryDoctrineDBAL();
$repository = $factory->getRepository(array(
'jackalope.doctrine_dbal_connection' => $connection,
));
$schema = new RepositorySchema(array('disable_fks' => true), $connection);
$schema->reset();
$session = $repository->login(new \PHPCR\SimpleCredentials('', ''));
$cnd = <<<CND
<phpcr='http://www.doctrine-project.org/projects/phpcr_odm'>
[phpcr:managed]
mixin
- phpcr:class (STRING)
- phpcr:classparents (STRING) multiple
CND;
$session->getWorkspace()->getNodeTypeManager()->registerNodeTypesCnd($cnd, true);
return $session;
}
private function getEventManager()
{
$evm = new EventManager();
return $evm;
}
}

View File

@@ -0,0 +1,242 @@
<?php
namespace Test\Tool;
use Doctrine\DBAL\Logging\SQLLogger;
use Doctrine\DBAL\Types\Type;
use Doctrine\DBAL\Platforms\AbstractPlatform;
/**
* @author Gediminas Morkevicius <gediminas.morkevicius@gmail.com>
* @package Gedmo.Tool.Logging.DBAL
* @subpackage QueryAnalyzer
* @link http://www.gediminasm.org
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
class QueryAnalyzer implements SQLLogger
{
/**
* Used database platform
*
* @var AbstractPlatform
*/
protected $platform;
/**
* Start time of currently executed query
*
* @var integer
*/
private $queryStartTime = null;
/**
* Total execution time of all queries
*
* @var integer
*/
private $totalExecutionTime = 0;
/**
* List of queries executed
*
* @var array
*/
private $queries = array();
/**
* Query execution times indexed
* in same order as queries
*
* @var array
*/
private $queryExecutionTimes = array();
/**
* Initialize log listener with database
* platform, which is needed for parameter
* conversion
*
* @param AbstractPlatform $platform
*/
public function __construct(AbstractPlatform $platform)
{
$this->platform = $platform;
}
/**
* {@inheritdoc}
*/
public function startQuery($sql, array $params = null, array $types = null)
{
$this->queryStartTime = microtime(true);
$this->queries[] = $this->generateSql($sql, $params, $types);
}
/**
* {@inheritdoc}
*/
public function stopQuery()
{
$ms = round(microtime(true) - $this->queryStartTime, 4) * 1000;
$this->queryExecutionTimes[] = $ms;
$this->totalExecutionTime += $ms;
}
/**
* Clean all collected data
*
* @return QueryAnalyzer
*/
public function cleanUp()
{
$this->queries = array();
$this->queryExecutionTimes = array();
$this->totalExecutionTime = 0;
return $this;
}
/**
* Dump the statistics of executed queries
*
* @param boolean $dumpOnlySql
* @return void
*/
public function getOutput($dumpOnlySql = false)
{
$output = '';
if (!$dumpOnlySql) {
$output .= 'Platform: ' . $this->platform->getName() . PHP_EOL;
$output .= 'Executed queries: ' . count($this->queries) . ', total time: ' . $this->totalExecutionTime . ' ms' . PHP_EOL;
}
foreach ($this->queries as $index => $sql) {
if (!$dumpOnlySql) {
$output .= 'Query(' . ($index+1) . ') - ' . $this->queryExecutionTimes[$index] . ' ms' . PHP_EOL;
}
$output .= $sql . ';' . PHP_EOL;
}
$output .= PHP_EOL;
return $output;
}
/**
* Index of the slowest query executed
*
* @return integer
*/
public function getSlowestQueryIndex()
{
$index = 0;
$slowest = 0;
foreach ($this->queryExecutionTimes as $i => $time) {
if ($time > $slowest) {
$slowest = $time;
$index = $i;
}
}
return $index;
}
/**
* Get total execution time of queries
*
* @return integer
*/
public function getTotalExecutionTime()
{
return $this->totalExecutionTime;
}
/**
* Get all queries
*
* @return array
*/
public function getExecutedQueries()
{
return $this->queries;
}
/**
* Get number of executed queries
*
* @return integer
*/
public function getNumExecutedQueries()
{
return count($this->queries);
}
/**
* Get all query execution times
*
* @return array
*/
public function getExecutionTimes()
{
return $this->queryExecutionTimes;
}
/**
* Create the SQL with mapped parameters
*
* @param string $sql
* @param array $params
* @param array $types
* @return sql
*/
private function generateSql($sql, $params, $types)
{
if (!count($params)) {
return $sql;
}
$converted = $this->getConvertedParams($params, $types);
if (is_int(key($params))) {
$index = key($converted);
$sql = preg_replace_callback('@\?@sm', function($match) use (&$index, $converted) {
return implode(' ', $converted[$index++]);
}, $sql);
} else {
foreach ($converted as $key => $value) {
$sql = str_replace(':' . $key, $value, $sql);
}
}
return $sql;
}
/**
* Get the converted parameter list
*
* @param array $params
* @param array $types
* @return array
*/
private function getConvertedParams($params, $types)
{
$result = array();
foreach ($params as $position => $value) {
if (isset($types[$position])) {
$type = $types[$position];
if (is_string($type)) {
$type = Type::getType($type);
}
if ($type instanceof Type) {
$value = $type->convertToDatabaseValue($value, $this->platform);
}
} else {
if (is_object($value) && $value instanceof \DateTime) {
$value = $value->format($this->platform->getDateTimeFormatString());
} elseif (!is_null($value)) {
$type = Type::getType(gettype($value));
$value = $type->convertToDatabaseValue($value, $this->platform);
}
}
if (is_string($value)) {
$value = "'{$value}'";
} elseif (is_null($value)) {
$value = 'NULL';
}
$result[$position] = $value;
}
return $result;
}
}

View File

@@ -0,0 +1,9 @@
<?php
require __DIR__.'/../vendor/autoload.php';
\Doctrine\Common\Annotations\AnnotationRegistry::registerLoader('class_exists');
$reader = new \Doctrine\Common\Annotations\AnnotationReader();
$reader = new \Doctrine\Common\Annotations\CachedReader($reader, new \Doctrine\Common\Cache\ArrayCache());
$_ENV['annotation_reader'] = $reader;

View File