Review fixes

This commit is contained in:
Jan Goralski 2015-11-24 15:03:11 +01:00
parent f4265fa249
commit acb8e9bb20
19 changed files with 345 additions and 217 deletions

View file

@ -8,10 +8,11 @@ This chapter references the relevant changes done in 0.16 version.
To get the diff between two versions, go to https://github.com/Sylius/Sylius/compare/v0.15.0...master To get the diff between two versions, go to https://github.com/Sylius/Sylius/compare/v0.15.0...master
* feature #3110 [BC BREAK] Bumped minimal versions, major changes: PHP >=5.5.9, Symfony ^2.7 * feature #3110 [BC BREAK] Bumped minimal versions, major changes: PHP >=5.5.9, Symfony ^2.7
* feature #3288 [BC BREAK][Product] Removed ProductBuilder class
* bc break #3364 [BC BREAK] Renamed setDefaultOptions to configureOptions * bc break #3364 [BC BREAK] Renamed setDefaultOptions to configureOptions
* bc break #3536 [BC BREAK] Renamed label to type on adjustment * bc break #3536 [BC BREAK] Renamed label to type on adjustment
* bc break #3610 [BC BREAK] Renamed `sylius_payum.classes.payment_config` to `sylius_payum.classes.gateway_config` * bc break #3610 [BC BREAK] Renamed `sylius_payum.classes.payment_config` to `sylius_payum.classes.gateway_config`
* feature #3288 [BC BREAK][Product] Removed ProductBuilder class
* feature #3617 [BC BREAK][Resource] Created InMemoryRepository and implemented ResourceInterface
## v0.15 (2015-09-08) ## v0.15 (2015-09-08)

View file

@ -6,6 +6,10 @@ UPGRADE
## PayumBundle ## PayumBundle
* Changed configuration key `sylius_payum.classes.payment_config` to `sylius_payum.classes.gateway_config` * Changed configuration key `sylius_payum.classes.payment_config` to `sylius_payum.classes.gateway_config`
## Resource
* RepositoryInterface now has two additional methods `add` and `remove`
# From 0.14.0 to 0.15.x # From 0.14.0 to 0.15.x

View file

@ -11,13 +11,12 @@
namespace Sylius\Bundle\CoreBundle\Doctrine\ORM; namespace Sylius\Bundle\CoreBundle\Doctrine\ORM;
use Pagerfanta\PagerfantaInterface;
use Sylius\Bundle\ResourceBundle\Doctrine\ORM\EntityRepository; use Sylius\Bundle\ResourceBundle\Doctrine\ORM\EntityRepository;
class ShipmentRepository extends EntityRepository class ShipmentRepository extends EntityRepository
{ {
/** /**
* Create filter paginator.
*
* @param array $criteria * @param array $criteria
* @param array $sorting * @param array $sorting
* *

View file

@ -15,6 +15,7 @@ use Doctrine\MongoDB\Query\Builder as QueryBuilder;
use Doctrine\ODM\MongoDB\DocumentRepository as BaseDocumentRepository; use Doctrine\ODM\MongoDB\DocumentRepository as BaseDocumentRepository;
use Pagerfanta\Adapter\DoctrineODMMongoDBAdapter; use Pagerfanta\Adapter\DoctrineODMMongoDBAdapter;
use Pagerfanta\Pagerfanta; use Pagerfanta\Pagerfanta;
use Sylius\Component\Resource\Model\ResourceInterface;
use Sylius\Component\Resource\Repository\RepositoryInterface; use Sylius\Component\Resource\Repository\RepositoryInterface;
/** /**
@ -110,6 +111,28 @@ class DocumentRepository extends BaseDocumentRepository implements RepositoryInt
return $this->getPaginator($queryBuilder); return $this->getPaginator($queryBuilder);
} }
/**
* {@inheritdoc}
*/
public function add(ResourceInterface $resource)
{
$this->dm->persist($resource);
$this->dm->flush();
}
/**
* {@inheritdoc}
*/
public function remove(ResourceInterface $resource)
{
if (null !== $this->find($resource->getId())) {
$this->dm->remove($resource);
$this->dm->flush();
}
}
/** /**
* @param QueryBuilder $queryBuilder * @param QueryBuilder $queryBuilder
* *

View file

@ -15,6 +15,7 @@ use Doctrine\ODM\PHPCR\DocumentRepository as BaseDocumentRepository;
use Doctrine\ODM\PHPCR\Query\Builder\QueryBuilder; use Doctrine\ODM\PHPCR\Query\Builder\QueryBuilder;
use Pagerfanta\Adapter\DoctrineODMPhpcrAdapter; use Pagerfanta\Adapter\DoctrineODMPhpcrAdapter;
use Pagerfanta\Pagerfanta; use Pagerfanta\Pagerfanta;
use Sylius\Component\Resource\Model\ResourceInterface;
use Sylius\Component\Resource\Repository\RepositoryInterface; use Sylius\Component\Resource\Repository\RepositoryInterface;
/** /**
@ -38,6 +39,28 @@ class DocumentRepository extends BaseDocumentRepository implements RepositoryInt
return $this->getPaginator($queryBuilder); return $this->getPaginator($queryBuilder);
} }
/**
* {@inheritdoc}
*/
public function add(ResourceInterface $resource)
{
$this->dm->persist($resource);
$this->dm->flush();
}
/**
* {@inheritdoc}
*/
public function remove(ResourceInterface $resource)
{
if (null !== $this->find($resource->getId())) {
$this->dm->remove($resource);
$this->dm->flush();
}
}
/** /**
* @param QueryBuilder $queryBuilder * @param QueryBuilder $queryBuilder
* *

View file

@ -16,6 +16,7 @@ use Doctrine\ORM\QueryBuilder;
use Pagerfanta\Adapter\ArrayAdapter; use Pagerfanta\Adapter\ArrayAdapter;
use Pagerfanta\Adapter\DoctrineORMAdapter; use Pagerfanta\Adapter\DoctrineORMAdapter;
use Pagerfanta\Pagerfanta; use Pagerfanta\Pagerfanta;
use Sylius\Component\Resource\Model\ResourceInterface;
use Sylius\Component\Resource\Repository\RepositoryInterface; use Sylius\Component\Resource\Repository\RepositoryInterface;
/** /**
@ -98,6 +99,28 @@ class EntityRepository extends BaseEntityRepository implements RepositoryInterfa
; ;
} }
/**
* {@inheritdoc}
*/
public function add(ResourceInterface $resource)
{
$this->_em->persist($resource);
$this->_em->flush();
}
/**
* {@inheritdoc}
*/
public function remove(ResourceInterface $resource)
{
if (null !== $this->find($resource->getId())) {
$this->_em->remove($resource);
$this->_em->flush();
}
}
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */

View file

@ -11,7 +11,6 @@
namespace Sylius\Component\Payment\Model; namespace Sylius\Component\Payment\Model;
use Sylius\Component\Resource\Model\ResourceInterface;
use Sylius\Component\Resource\Model\TimestampableInterface; use Sylius\Component\Resource\Model\TimestampableInterface;
/** /**

View file

@ -5,3 +5,6 @@ CHANGELOG
* Introduce Factory and FactoryInterface for creating new resources. * Introduce Factory and FactoryInterface for creating new resources.
* ``createNew`` method removed from RepositoryInterface. * ``createNew`` method removed from RepositoryInterface.
* Introduce InMemoryRepository for object storage using the memory.
* Extracted ``getId`` method into ResourceInterface.
* Extended RepositoryInterface by ``add`` and ``remove`` methods

View file

@ -19,7 +19,7 @@ class UnknownDriverException extends \Exception
public function __construct($driver) public function __construct($driver)
{ {
parent::__construct(sprintf( parent::__construct(sprintf(
'Unknown driver "%s"', 'Unknown driver "%s".',
$driver $driver
)); ));
} }

View file

@ -0,0 +1,29 @@
<?php
/*
* This file is part of the Sylius package.
*
* (c) Paweł Jędrzejewski
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Sylius\Component\Resource\Exception;
/**
* @author Jan Góralski <jan.goralski@lakion.com>
*/
class UnsupportedMethodException extends \Exception
{
/**
* @param string $methodName
*/
public function __construct($methodName)
{
parent::__construct(sprintf(
'The method "%s" is not supported.',
$methodName
));
}
}

View file

@ -15,6 +15,7 @@ use ArrayObject;
use Pagerfanta\Adapter\ArrayAdapter; use Pagerfanta\Adapter\ArrayAdapter;
use Pagerfanta\Pagerfanta; use Pagerfanta\Pagerfanta;
use Sylius\Component\Resource\Exception\UnexpectedTypeException; use Sylius\Component\Resource\Exception\UnexpectedTypeException;
use Sylius\Component\Resource\Exception\UnsupportedMethodException;
use Sylius\Component\Resource\Model\ResourceInterface; use Sylius\Component\Resource\Model\ResourceInterface;
use Symfony\Component\PropertyAccess\PropertyAccess; use Symfony\Component\PropertyAccess\PropertyAccess;
use Symfony\Component\PropertyAccess\PropertyAccessor; use Symfony\Component\PropertyAccess\PropertyAccessor;
@ -40,7 +41,7 @@ class InMemoryRepository implements RepositoryInterface
protected $interface; protected $interface;
/** /**
* @param string $interface * @param string $interface | Fully qualified name of the interface.
* *
* @throws \InvalidArgumentException * @throws \InvalidArgumentException
* @throws UnexpectedTypeException * @throws UnexpectedTypeException
@ -61,54 +62,46 @@ class InMemoryRepository implements RepositoryInterface
} }
/** /**
* @param ResourceInterface $resource * {@inheritdoc}
* *
* @throws \InvalidArgumentException * @throws \InvalidArgumentException
* @throws UnexpectedTypeException * @throws UnexpectedTypeException
*/ */
public function add(ResourceInterface $resource) public function add(ResourceInterface $resource)
{ {
if (!in_array($this->interface, class_implements($resource))) { if (!$resource instanceof $this->interface) {
throw new UnexpectedTypeException($resource, $this->interface); throw new UnexpectedTypeException($resource, $this->interface);
} }
if (null === $resource->getId()) { if (in_array($resource, $this->findAll())) {
throw new \InvalidArgumentException('Resource\'s id needs to be set in order to add.');
}
if ($this->arrayObject->offsetExists($resource->getId())) {
throw new \InvalidArgumentException( throw new \InvalidArgumentException(
sprintf('An object with id \'%s\' is already in the repository.', $resource->getId()) sprintf('Given object is already in the repository.')
); );
} }
$this->arrayObject->offsetSet($resource->getId(), $resource); $this->arrayObject->append($resource);
}
/**
* @param ResourceInterface $resource
*/
public function remove(ResourceInterface $resource)
{
if ($this->arrayObject->offsetExists($resource->getId())) {
$this->arrayObject->offsetUnset($resource->getId());
}
} }
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function find($id) public function remove(ResourceInterface $resource)
{ {
if (empty($id)) { $newResources = array_filter($this->findAll(), function($object) use ($resource) {
return null; return $object !== $resource;
} });
if ($this->arrayObject->offsetExists($id)) { $this->arrayObject->exchangeArray($newResources);
return $this->arrayObject->offsetGet($id); }
}
return null; /**
* {@inheritdoc}
*
* @throws UnsupportedMethodException
*/
public function find($id = null)
{
throw new UnsupportedMethodException('find');
} }
/** /**
@ -116,21 +109,21 @@ class InMemoryRepository implements RepositoryInterface
*/ */
public function findAll() public function findAll()
{ {
return array_values($this->arrayObject->getArrayCopy()); return $this->arrayObject->getArrayCopy();
} }
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function findBy(array $criteria = array(), array $orderBy = null, $limit = null, $offset = null) public function findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
{ {
$results = $this->arrayObject->getArrayCopy(); $results = $this->findAll();
if (isset($criteria)) { if (!empty($criteria)) {
$results = $this->applyCriteria($results, $criteria); $results = $this->applyCriteria($results, $criteria);
} }
if (isset($orderBy)) { if (!empty($orderBy)) {
$results = $this->applyOrder($results, $orderBy); $results = $this->applyOrder($results, $orderBy);
} }
@ -142,17 +135,21 @@ class InMemoryRepository implements RepositoryInterface
/** /**
* {@inheritdoc} * {@inheritdoc}
* *
* @throws \UnexpectedValueException * @throws \InvalidArgumentException
*/ */
public function findOneBy(array $criteria) public function findOneBy(array $criteria)
{ {
$results = $this->applyCriteria($this->findAll(), $criteria); if (empty($criteria)){
throw new \InvalidArgumentException('The criteria array needs to be set.');
if (1 < $length = count($results)) {
throw new \UnexpectedValueException(sprintf('Non unique result. Number of results: %s.', $length));
} }
return $results[0]; $results = $this->applyCriteria($this->findAll(), $criteria);
if ($result = reset($results)) {
return $result;
}
return null;
} }
/** /**
@ -168,36 +165,29 @@ class InMemoryRepository implements RepositoryInterface
*/ */
public function createPaginator(array $criteria = null, array $orderBy = null) public function createPaginator(array $criteria = null, array $orderBy = null)
{ {
$results = $this->findAll(); $resources = $this->findAll();
if (isset($orderBy)) { if (!empty($orderBy)) {
$results = $this->applyOrder($results, $orderBy); $resources = $this->applyOrder($resources, $orderBy);
} }
if (isset($criteria)) { if (!empty($criteria)) {
$results = $this->applyCriteria($results, $criteria); $resources = $this->applyCriteria($resources, $criteria);
} }
$adapter = new ArrayAdapter($results); $adapter = new ArrayAdapter($resources);
$pagerfanta = new Pagerfanta($adapter); $pagerfanta = new Pagerfanta($adapter);
return $pagerfanta; return $pagerfanta;
} }
/**
* {@inheritdoc}
*/
public function createNew()
{
}
/** /**
* @param ResourceInterface[] $resources * @param ResourceInterface[] $resources
* @param array $criteria * @param array $criteria
* *
* @return ResourceInterface[]|array * @return ResourceInterface[]|array
*/ */
private function applyCriteria(array $resources, array $criteria = array()) private function applyCriteria(array $resources, array $criteria)
{ {
foreach ($this->arrayObject as $object) { foreach ($this->arrayObject as $object) {
foreach ($criteria as $criterion => $value) { foreach ($criteria as $criterion => $value) {
@ -225,19 +215,19 @@ class InMemoryRepository implements RepositoryInterface
$sortable = array(); $sortable = array();
$results = array(); $results = array();
foreach ($resources as $object) { foreach ($resources as $key => $object) {
$sortable[$object->getId()] = $this->accessor->getValue($object, $property); $sortable[$key] = $this->accessor->getValue($object, $property);
} }
if ('ASC' === $order) { if (RepositoryInterface::ORDER_ASCENDING === $order) {
asort($sortable); asort($sortable);
} }
if ('DSC' === $order) { if (RepositoryInterface::ORDER_DESCENDING === $order) {
arsort($sortable); arsort($sortable);
} }
foreach ($sortable as $id => $value) { foreach ($sortable as $key => $object) {
$results[$id] = $resources[$id]; $results[$key] = $resources[$key];
} }
return $results; return $results;

View file

@ -12,21 +12,32 @@
namespace Sylius\Component\Resource\Repository; namespace Sylius\Component\Resource\Repository;
use Doctrine\Common\Persistence\ObjectRepository; use Doctrine\Common\Persistence\ObjectRepository;
use Sylius\Component\Resource\Model\ResourceInterface;
/** /**
* Model repository interface.
*
* @author Saša Stamenković <umpirsky@gmail.com> * @author Saša Stamenković <umpirsky@gmail.com>
* @author Jan Góralski <jan.goralski@lakion.com>
*/ */
interface RepositoryInterface extends ObjectRepository interface RepositoryInterface extends ObjectRepository
{ {
const ORDER_ASCENDING = 'ASC';
const ORDER_DESCENDING = 'DESC';
/** /**
* Get paginated collection
*
* @param array $criteria * @param array $criteria
* @param array $orderBy * @param array $orderBy
* *
* @return mixed * @return mixed
*/ */
public function createPaginator(array $criteria = null, array $orderBy = null); public function createPaginator(array $criteria = null, array $orderBy = null);
/**
* @param ResourceInterface $resource
*/
public function add(ResourceInterface $resource);
/**
* @param ResourceInterface $resource
*/
public function remove(ResourceInterface $resource);
} }

View file

@ -25,6 +25,7 @@
"doctrine/collections": "~1.0", "doctrine/collections": "~1.0",
"doctrine/common": "~2.3", "doctrine/common": "~2.3",
"symfony/event-dispatcher": "^2.7", "symfony/event-dispatcher": "^2.7",
"symfony/property-access": "^2.7",
"winzou/state-machine": "~0.1" "winzou/state-machine": "~0.1"
}, },
"require-dev": { "require-dev": {

View file

@ -28,8 +28,13 @@ class InvalidDriverExceptionSpec extends ObjectBehavior
$this->shouldHaveType('Sylius\Component\Resource\Exception\Driver\InvalidDriverException'); $this->shouldHaveType('Sylius\Component\Resource\Exception\Driver\InvalidDriverException');
} }
function it_should_extends_exception() function it_extends_exception()
{ {
$this->shouldHaveType('\Exception'); $this->shouldHaveType('\Exception');
} }
function it_has_a_message()
{
$this->getMessage()->shouldReturn('Driver "driver" is not supported by className.');
}
} }

View file

@ -28,8 +28,13 @@ class UnknownDriverExceptionSpec extends ObjectBehavior
$this->shouldHaveType('Sylius\Component\Resource\Exception\Driver\UnknownDriverException'); $this->shouldHaveType('Sylius\Component\Resource\Exception\Driver\UnknownDriverException');
} }
function it_should_extends_exception() function it_extends_exception()
{ {
$this->shouldHaveType('\Exception'); $this->shouldHaveType('\Exception');
} }
function it_has_a_message()
{
$this->getMessage()->shouldReturn('Unknown driver "driver".');
}
} }

View file

@ -3,13 +3,12 @@
namespace spec\Sylius\Component\Resource\Exception; namespace spec\Sylius\Component\Resource\Exception;
use PhpSpec\ObjectBehavior; use PhpSpec\ObjectBehavior;
use Prophecy\Argument;
class UnexpectedTypeExceptionSpec extends ObjectBehavior class UnexpectedTypeExceptionSpec extends ObjectBehavior
{ {
function let() function let()
{ {
$this->beConstructedWith('givenType', 'expectedType'); $this->beConstructedWith('stringValue', '\ExpectedType');
} }
function it_is_initializable() function it_is_initializable()
@ -21,4 +20,9 @@ class UnexpectedTypeExceptionSpec extends ObjectBehavior
{ {
$this->shouldHaveType('\InvalidArgumentException'); $this->shouldHaveType('\InvalidArgumentException');
} }
function it_has_a_message()
{
$this->getMessage()->shouldReturn('Expected argument of type "\ExpectedType", "string" given.');
}
} }

View file

@ -0,0 +1,40 @@
<?php
/*
* This file is part of the Sylius package.
*
* (c) Paweł Jędrzejewski
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace spec\Sylius\Component\Resource\Exception;
use PhpSpec\ObjectBehavior;
/**
* @author Jan Góralski <jan.goralski@lakion.com>
*/
class UnsupportedMethodExceptionSpec extends ObjectBehavior
{
function let()
{
$this->beConstructedWith('methodName');
}
function it_is_initializable()
{
$this->shouldHaveType('Sylius\Component\Resource\Exception\UnsupportedMethodException');
}
function it_extends_exception()
{
$this->shouldHaveType('\Exception');
}
function it_has_a_message()
{
$this->getMessage()->shouldReturn(sprintf('The method "methodName" is not supported.'));
}
}

View file

@ -0,0 +1,30 @@
<?php
/*
* This file is part of the Sylius package.
*
* (c) Paweł Jędrzejewski
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace spec\Sylius\Component\Resource\Fixtures;
use Sylius\Component\Resource\Model\ResourceInterface;
/**
* @author Jan Góralski <jan.goralski@lakion.com>
*/
interface SampleResourceInterface extends ResourceInterface
{
/**
* @return string
*/
public function getName();
/**
* @return int
*/
public function getRating();
}

View file

@ -13,29 +13,23 @@ namespace spec\Sylius\Component\Resource\Repository;
use Pagerfanta\Pagerfanta; use Pagerfanta\Pagerfanta;
use PhpSpec\ObjectBehavior; use PhpSpec\ObjectBehavior;
use Sylius\Component\Resource\Model\ResourceInterface; use spec\Sylius\Component\Resource\Fixtures\SampleResourceInterface;
use Sylius\Component\Resource\Exception\UnsupportedMethodException;
use Sylius\Component\Resource\Exception\UnexpectedTypeException; use Sylius\Component\Resource\Exception\UnexpectedTypeException;
use Sylius\Component\Resource\Model\ResourceInterface;
use Sylius\Component\Resource\Repository\InMemoryRepository; use Sylius\Component\Resource\Repository\InMemoryRepository;
use Sylius\Component\Resource\Repository\RepositoryInterface; use Sylius\Component\Resource\Repository\RepositoryInterface;
require_once __DIR__ . '/../Fixtures/SampleResourceInterface.php';
/** /**
* @author Jan Góralski <jan.goralski@lakion.com> * @author Jan Góralski <jan.goralski@lakion.com>
*/ */
class InMemoryRepositorySpec extends ObjectBehavior class InMemoryRepositorySpec extends ObjectBehavior
{ {
function let(RepositableInterface $book, RepositableInterface $shirt) function let()
{ {
$this->beConstructedWith(RepositableInterface::class); $this->beConstructedWith(SampleResourceInterface::class);
$book->getId()->willReturn(10);
$book->getName()->willReturn('Book');
$book->getRating()->willReturn(5);
$shirt->getId()->willReturn(5);
$shirt->getName()->willReturn('Shirt');
$this->add($book);
$this->add($shirt);
} }
function it_throws_invalid_argument_exception_when_constructing_with_null() function it_throws_invalid_argument_exception_when_constructing_with_null()
@ -43,7 +37,7 @@ class InMemoryRepositorySpec extends ObjectBehavior
$this->shouldThrow(\InvalidArgumentException::class)->during('__construct', array(null)); $this->shouldThrow(\InvalidArgumentException::class)->during('__construct', array(null));
} }
function it_throws_unexpected_type_exception_when_constructing_without_resource_interface(Void $void) function it_throws_unexpected_type_exception_when_constructing_without_resource_interface($void = 1)
{ {
$this->shouldThrow(UnexpectedTypeException::class)->during('__construct', array($void)); $this->shouldThrow(UnexpectedTypeException::class)->during('__construct', array($void));
} }
@ -63,123 +57,126 @@ class InMemoryRepositorySpec extends ObjectBehavior
$this->shouldThrow(\InvalidArgumentException::class)->during('add', array($resource)); $this->shouldThrow(\InvalidArgumentException::class)->during('add', array($resource));
} }
function it_throws_invalid_argument_exception_when_adding_object_with_null_id(RepositableInterface $mug) function it_adds_an_object(SampleResourceInterface $monocle)
{
$mug->getId()->willReturn(null);
$this->shouldThrow(\InvalidArgumentException::class)->during('add', array($mug));
}
function it_throws_invalid_argument_exception_when_adding_different_objects_with_same_id(
RepositableInterface $leftShoe,
RepositableInterface $rightShoe
) {
$leftShoe->getId()->willReturn(1);
$leftShoe->getName()->willReturn('leftShoe');
$rightShoe->getId()->willReturn(1);
$rightShoe->getName()->willReturn('rightShoe');
$this->add($leftShoe);
$this->shouldThrow(\InvalidArgumentException::class)->during('add', array($rightShoe));
}
function it_adds_an_object(RepositableInterface $monocle)
{ {
$monocle->getId()->willReturn(2); $monocle->getId()->willReturn(2);
$this->add($monocle); $this->add($monocle);
$this->find(2)->shouldReturn($monocle); $this->findOneBy(array('id' => 2))->shouldReturn($monocle);
} }
function it_removes_a_resource(RepositableInterface $shirt) function it_removes_a_resource(SampleResourceInterface $shirt)
{ {
$shirt->getId()->willReturn(5);
$this->add($shirt);
$this->remove($shirt); $this->remove($shirt);
$this->find(5)->shouldReturn(null); $this->findOneBy(array('id' => 5))->shouldReturn(null);
} }
function it_finds_an_object_by_id(RepositableInterface $book) function it_throws_unsupported_method_exception_while_using_find()
{ {
$this->find(10)->shouldReturn($book); $this->shouldThrow(UnsupportedMethodException::class)->during('find', array());
} }
function it_returns_null_when_finding_with_null_parameter() function it_finds_many_objects_with_parameter(SampleResourceInterface $book)
{ {
$this->find(null)->shouldReturn(null); $book->getName()->willReturn('Book');
}
function it_returns_null_when_finding_unavailable_id() $this->add($book);
{
$this->find(11)->shouldReturn(null);
}
function it_finds_many_objects_with_parameter(RepositableInterface $book)
{
$book->getName()->shouldBeCalled();
$this->findBy(array('name' => 'Book'))->shouldReturn(array($book)); $this->findBy(array('name' => 'Book'))->shouldReturn(array($book));
} }
function it_finds_all_objects_when_parameter_is_not_set(RepositableInterface $book, RepositableInterface $shirt) function it_returns_all_objects_when_finding_by_an_empty_array_parameter(
{ SampleResourceInterface $book,
$this->findBy()->shouldReturn(array($book, $shirt)); SampleResourceInterface $shirt
) {
$book->getId()->willReturn(10);
$book->getName()->willReturn('Book');
$shirt->getId()->willReturn(5);
$shirt->getName()->willReturn('Shirt');
$this->add($book);
$this->add($shirt);
$this->findBy(array())->shouldReturn(array($book, $shirt));
} }
function it_finds_many_objects_with_parameter_order_limit_offset( function it_finds_many_objects_by_multiple_criteria_order_limit_offset(
RepositableInterface $secondBook, SampleResourceInterface $firstBook,
RepositableInterface $thirdBook, SampleResourceInterface $secondBook,
RepositableInterface $fourthBook SampleResourceInterface $thirdBook
) { ) {
$secondBook->getId()->willReturn(80); $id = 80;
$thirdBook->getId()->willReturn(81); $name = 'Book';
$fourthBook->getId()->willReturn(82);
$secondBook->getName()->willReturn('Book'); $firstBook->getId()->willReturn($id);
$thirdBook->getName()->willReturn('Book'); $secondBook->getId()->willReturn($id);
$fourthBook->getName()->willReturn('Book'); $thirdBook->getId()->willReturn($id);
$secondBook->getRating()->willReturn(3); $firstBook->getName()->willReturn($name);
$thirdBook->getRating()->willReturn(2); $secondBook->getName()->willReturn($name);
$fourthBook->getRating()->willReturn(1); $thirdBook->getName()->willReturn($name);
$firstBook->getRating()->willReturn(3);
$secondBook->getRating()->willReturn(2);
$thirdBook->getRating()->willReturn(1);
$this->add($firstBook);
$this->add($secondBook); $this->add($secondBook);
$this->add($thirdBook); $this->add($thirdBook);
$this->add($fourthBook);
$this->findBy( $this->findBy(
array('name' => 'Book'), $criteria = array('name' => $name, 'id' => $id),
array('rating' => 'ASC'), $orderBy = array('rating' => RepositoryInterface::ORDER_ASCENDING),
$limit = 2, $limit = 2,
$offset = 1 $offset = 1
)->shouldReturn(array($thirdBook, $secondBook)); )->shouldReturn(array($secondBook, $firstBook));
} }
function it_throws_unexpected_value_exception_on_multiple_results_while_finding_one_object_by_parameter(RepositableInterface $secondBook) function it_throws_invalid_argument_exception_when_finding_one_object_with_empty_parameter_array()
{ {
$secondBook->getId()->willReturn(81); $this->shouldThrow(\InvalidArgumentException::class)->during('findOneBy', array(array()));
$secondBook->getName()->willReturn('Book');
$this->add($secondBook);
$this->shouldThrow(\UnexpectedValueException::class)->during('findOneBy', array(array('name' => 'Book')));
} }
function it_finds_one_object_by_parameter(RepositableInterface $book) function it_finds_one_object_by_parameter(SampleResourceInterface $book, SampleResourceInterface $shirt)
{ {
$book->getName()->willReturn('Book');
$shirt->getName()->willReturn('Shirt');
$this->add($book);
$this->add($shirt);
$this->findOneBy(array('name' => 'Book'))->shouldReturn($book); $this->findOneBy(array('name' => 'Book'))->shouldReturn($book);
} }
function it_finds_all_objects_in_memory(RepositableInterface $book, RepositableInterface $shirt) function it_returns_first_result_while_finding_one_by_parameters(
SampleResourceInterface $book,
SampleResourceInterface $secondBook
) {
$book->getName()->willReturn('Book');
$secondBook->getName()->willReturn('Book');
$this->add($book);
$this->add($secondBook);
$this->findOneBy(array('name' => 'Book'))->shouldReturn($book);
}
function it_finds_all_objects_in_memory(SampleResourceInterface $book, SampleResourceInterface $shirt)
{ {
$this->add($book);
$this->add($shirt);
$this->findAll()->shouldReturn(array($book, $shirt)); $this->findAll()->shouldReturn(array($book, $shirt));
} }
function it_return_empty_array_when_memory_is_empty(RepositableInterface $book, RepositableInterface $shirt) function it_return_empty_array_when_memory_is_empty()
{ {
$this->remove($book);
$this->remove($shirt);
$this->findAll()->shouldReturn(array()); $this->findAll()->shouldReturn(array());
} }
@ -190,65 +187,6 @@ class InMemoryRepositorySpec extends ObjectBehavior
function it_returns_stated_class_name() function it_returns_stated_class_name()
{ {
$this->getClassName()->shouldReturn(RepositableInterface::class); $this->getClassName()->shouldReturn(SampleResourceInterface::class);
}
}
class Void
{
}
interface RepositableInterface extends ResourceInterface
{
/**
* @return string
*/
public function getName();
/**
* @return int
*/
public function getRating();
}
class Repositable implements RepositableInterface
{
/**
* @var mixed
*/
private $id;
/**
* @var string
*/
private $name;
/**
* @var int
*/
private $rating;
/**
* {@inheritdoc}
*/
public function getId()
{
return $this->id;
}
/**
* {@inheritdoc}
*/
public function getName()
{
return $this->name;
}
/**
* {@inheritdoc}
*/
public function getRating()
{
return $this->rating;
} }
} }