Created
August 16, 2014 19:55
-
-
Save docteurklein/dc256bf05d284ca5e57e to your computer and use it in GitHub Desktop.
a phpspec extension to ease usage of Iterators
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace PhpSpec\Iterator; | |
use PhpSpec\Wrapper\Collaborator as Base; | |
use Prophecy\Prophecy\ObjectProphecy; | |
use Prophecy\Promise\ReturnPromise; | |
class Collaborator extends Base | |
{ | |
private $prophecy; | |
public function __construct(ObjectProphecy $prophecy, $class) | |
{ | |
parent::__construct($prophecy); | |
$this->prophecy = $prophecy; | |
$this->beADoubleOf($class); | |
} | |
public function iterates(array $elements) | |
{ | |
$this->prophecy->valid()->will(new ReturnPromise(array_merge(array_fill(0, count($elements), true), [false]))); | |
$this->prophecy->count()->willReturn(count($elements)); | |
$this->prophecy->current()->will(new ReturnPromise($elements)); | |
$this->prophecy->next()->willReturn(); | |
$this->prophecy->rewind()->willReturn(); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace PhpSpec\Iterator; | |
use PhpSpec\Extension\ExtensionInterface; | |
use PhpSpec\ServiceContainer; | |
use PhpSpec\Iterator\Maintainer; | |
class Extension implements ExtensionInterface | |
{ | |
public function load(ServiceContainer $container) | |
{ | |
$container->setShared('runner.maintainers.iterator', function ($c) { | |
return new Maintainer($c->get('unwrapper')); | |
}); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace PhpSpec\Iterator; | |
use PhpSpec\Runner\Maintainer\MaintainerInterface; | |
use PhpSpec\Loader\Node\ExampleNode; | |
use PhpSpec\SpecificationInterface; | |
use PhpSpec\Runner\MatcherManager; | |
use PhpSpec\Runner\CollaboratorManager; | |
use PhpSpec\Wrapper\Unwrapper; | |
use PhpSpec\Iterator\Collaborator; | |
use ReflectionClass; | |
use ReflectionException; | |
use Prophecy\Prophet; | |
class Maintainer implements MaintainerInterface | |
{ | |
private $unwrapper; | |
public function __construct(Unwrapper $unwrapper) | |
{ | |
$this->unwrapper = $unwrapper; | |
} | |
public function supports(ExampleNode $example) | |
{ | |
return true; | |
return $this->hasAnyIterator($example); | |
} | |
public function prepare(ExampleNode $example, SpecificationInterface $context, MatcherManager $matchers, CollaboratorManager $collaborators) | |
{ | |
$this->prophet = new Prophet(null, $this->unwrapper, null); | |
foreach ($this->getIterators($example) as $name => $class) { | |
$collaborators->set($name, new Collaborator($this->prophet->prophesize(), $class)); | |
} | |
} | |
public function teardown(ExampleNode $example, SpecificationInterface $context, MatcherManager $matchers, CollaboratorManager $collaborators) | |
{ | |
$this->prophet->checkPredictions(); | |
} | |
public function getPriority() | |
{ | |
return 40; | |
} | |
private function hasAnyIterator(ExampleNode $example) | |
{ | |
return 0 > count($this->getIterators($example)); | |
} | |
private function getIterators(ExampleNode $example) | |
{ | |
$classRefl = $example->getSpecification()->getClassReflection(); | |
if ($classRefl->hasMethod('let')) { | |
foreach ($classRefl->getMethod('let')->getParameters() as $parameter) { | |
if ($this->isIterator($parameter->getClass())) { | |
yield $parameter->getName() => $parameter->getClass()->getName(); | |
} | |
} | |
} | |
foreach ($example->getFunctionReflection()->getParameters() as $parameter) { | |
if ($this->isIterator($parameter->getClass())) { | |
yield $parameter->getName() => $parameter->getClass()->getName(); | |
} | |
} | |
} | |
private function isIterator($class) | |
{ | |
try { | |
if (!$class instanceof ReflectionClass) { | |
$class = new ReflectionClass($class); | |
} | |
return $class->implementsInterface('Iterator'); | |
} | |
catch (ReflectionException $e) { | |
} | |
return false; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment