Skip to content

Flexible discovery #59

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 25, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Change Log

## 0.9.0 - 2016-06-25

### Changed

- Support of multiple strategies to find classes. This will make Puli optional
- Updated exceptions

## 0.8.0 - 2016-02-11

Expand Down
1 change: 1 addition & 0 deletions phpspec.yml.ci
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ extensions:
code_coverage:
format: clover
output: build/coverage.xml
bootstrap: spec/autoload.php
1 change: 1 addition & 0 deletions phpspec.yml.dist
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ suites:
namespace: Http\Discovery
psr4_prefix: Http\Discovery
formatter.name: pretty
bootstrap: spec/autoload.php
73 changes: 24 additions & 49 deletions spec/ClassDiscoverySpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,83 +3,58 @@
namespace spec\Http\Discovery;

use Http\Discovery\ClassDiscovery;
use Http\Discovery\Exception\DiscoveryFailedException;
use Http\Discovery\Exception\NotFoundException;
use Http\Discovery\Strategy\DiscoveryStrategy;
use Puli\Discovery\Binding\ClassBinding;
use Puli\GeneratedPuliFactory;
use Puli\Discovery\Api\Discovery;
use Puli\Repository\Api\ResourceRepository;
use PhpSpec\ObjectBehavior;
use spec\Http\Discovery\Helper\DiscoveryHelper;

class ClassDiscoverySpec extends ObjectBehavior
{
function let(
GeneratedPuliFactory $puliFactory,
ResourceRepository $repository,
Discovery $discovery
) {
$puliFactory->createRepository()->willReturn($repository);
$puliFactory->createDiscovery($repository)->willReturn($discovery);

function let() {
ClassDiscovery::setStrategies([DiscoveryHelper::class]);
DiscoveryHelper::clearClasses();
$this->beAnInstanceOf('spec\Http\Discovery\ClassDiscoveryStub');
$this->setPuliFactory($puliFactory);
}

function letgo()
{
$this->resetPuliFactory();
}

function it_is_initializable()
{
$this->shouldHaveType('Http\Discovery\ClassDiscovery');
}

function it_has_a_puli_factory(GeneratedPuliFactory $puliFactory)
function it_throws_an_exception_when_no_candidate_found(DiscoveryStrategy $strategy)
{
$this->getPuliFactory()->shouldReturn($puliFactory);
}
$strategy->getCandidates('NoCandidate')->willReturn([]);

function it_has_a_puli_discovery(Discovery $discovery)
{
$this->getPuliDiscovery()->shouldReturn($discovery);
$this->shouldThrow(DiscoveryFailedException::class)->duringFind('NoCandidate');
}

function it_throws_an_exception_when_binding_not_found(Discovery $discovery)
function it_returns_a_class(DiscoveryStrategy $strategy)
{
$discovery->findBindings('InvalidBinding')->willReturn([]);
$candidate = ['class' => 'ClassName', 'condition' => true];
DiscoveryHelper::setClasses('Foobar', [$candidate]);

$this->shouldThrow('Http\Discovery\NotFoundException')->duringFindOneByType('InvalidBinding');
$this->find('Foobar')->shouldReturn('ClassName');
}

function it_returns_a_class_binding(Discovery $discovery, ClassBinding $binding)
{
$binding->hasParameterValue('depends')->willReturn(false);
$binding->getClassName()->willReturn('ClassName');

$discovery->findBindings('Binding')->willReturn([$binding]);
function it_validates_conditions(DiscoveryStrategy $strategy) {
$c0 = ['class' => 'ClassName0', 'condition' => false];
$c1 = ['class' => 'ClassName1', 'condition' => true];
$c2 = ['class' => 'ClassName2', 'condition' => false];
DiscoveryHelper::setClasses('Foobar', [$c0, $c1, $c2]);

$this->findOneByType('Binding')->shouldReturn('ClassName');
}

function it_returns_a_class_binding_with_dependency(
Discovery $discovery,
ClassBinding $binding1,
ClassBinding $binding2
) {
$binding1->hasParameterValue('depends')->willReturn(true);
$binding1->getParameterValue('depends')->willReturn(false);

$binding2->hasParameterValue('depends')->willReturn(false);
$binding2->getClassName()->willReturn('ClassName');

$discovery->findBindings('Binding')->willReturn([
$binding1,
$binding2,
]);

$this->findOneByType('Binding')->shouldReturn('ClassName');
$this->find('Foobar')->shouldReturn('ClassName1');
}
}

class ClassDiscoveryStub extends ClassDiscovery
{
public static function find($type)
{
return self::findOneByType($type);
}
}
46 changes: 46 additions & 0 deletions spec/Helper/DiscoveryHelper.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php

namespace spec\Http\Discovery\Helper;

use Http\Discovery\Strategy\DiscoveryStrategy;

/**
* This is a discovery helper used in tests
*
* @author Tobias Nyholm <[email protected]>
*/
class DiscoveryHelper implements DiscoveryStrategy
{
private static $classes = [];

/**
* @param string $type
* @param array $classes
*
* @return $this
*/
public static function setClasses($type, array $classes)
{
self::$classes[$type] = $classes;
}

/**
* Clear all classes.
*/
public static function clearClasses()
{
self::$classes = [];
}

/**
* {@inheritdoc}
*/
public static function getCandidates($type)
{
if (isset(static::$classes[$type])) {
return static::$classes[$type];
}

return [];
}
}
36 changes: 16 additions & 20 deletions spec/HttpAsyncClientDiscoverySpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,24 @@

namespace spec\Http\Discovery;

use Http\Client\HttpAsyncClient;
use Http\Discovery\ClassDiscovery;
use Http\Discovery\Exception\NotFoundException;
use Http\Discovery\Strategy\DiscoveryStrategy;
use Prophecy\Argument;
use Puli\GeneratedPuliFactory;
use Puli\Discovery\Api\Discovery;
use Puli\Discovery\Binding\ClassBinding;
use Puli\Repository\Api\ResourceRepository;
use PhpSpec\ObjectBehavior;
use spec\Http\Discovery\Helper\DiscoveryHelper;

class HttpAsyncClientDiscoverySpec extends ObjectBehavior
{
function let(
GeneratedPuliFactory $puliFactory,
ResourceRepository $repository,
Discovery $discovery
) {
$puliFactory->createRepository()->willReturn($repository);
$puliFactory->createDiscovery($repository)->willReturn($discovery);

$this->setPuliFactory($puliFactory);
}

function letgo()
function let()
{
$this->resetPuliFactory();
ClassDiscovery::setStrategies([DiscoveryHelper::class]);
DiscoveryHelper::clearClasses();
}

function it_is_initializable()
Expand All @@ -36,15 +32,15 @@ function it_is_a_class_discovery()
$this->shouldHaveType('Http\Discovery\ClassDiscovery');
}

function it_finds_an_async_http_client(
Discovery $discovery,
ClassBinding $binding
) {
$binding->hasParameterValue('depends')->willReturn(false);
$binding->getClassName()->willReturn('spec\Http\Discovery\Stub\HttpAsyncClientStub');
function it_finds_an_async_http_client(DiscoveryStrategy $strategy) {

$discovery->findBindings('Http\Client\HttpAsyncClient')->willReturn([$binding]);
$candidate = ['class' => 'spec\Http\Discovery\Stub\HttpAsyncClientStub', 'condition' => true];
DiscoveryHelper::setClasses(HttpAsyncClient::class, [$candidate]);

$this->find()->shouldImplement('Http\Client\HttpAsyncClient');
}

function it_throw_exception(DiscoveryStrategy $strategy) {
$this->shouldThrow(NotFoundException::class)->duringFind();
}
}
35 changes: 15 additions & 20 deletions spec/HttpClientDiscoverySpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,23 @@

namespace spec\Http\Discovery;

use Http\Client\HttpClient;
use Http\Discovery\ClassDiscovery;
use Http\Discovery\Exception\NotFoundException;
use Http\Discovery\Strategy\DiscoveryStrategy;
use Puli\GeneratedPuliFactory;
use Puli\Discovery\Api\Discovery;
use Puli\Discovery\Binding\ClassBinding;
use Puli\Repository\Api\ResourceRepository;
use PhpSpec\ObjectBehavior;
use spec\Http\Discovery\Helper\DiscoveryHelper;

class HttpClientDiscoverySpec extends ObjectBehavior
{
function let(
GeneratedPuliFactory $puliFactory,
ResourceRepository $repository,
Discovery $discovery
) {
$puliFactory->createRepository()->willReturn($repository);
$puliFactory->createDiscovery($repository)->willReturn($discovery);

$this->setPuliFactory($puliFactory);
}

function letgo()
function let()
{
$this->resetPuliFactory();
ClassDiscovery::setStrategies([DiscoveryHelper::class]);
DiscoveryHelper::clearClasses();
}

function it_is_initializable()
Expand All @@ -36,15 +31,15 @@ function it_is_a_class_discovery()
$this->shouldHaveType('Http\Discovery\ClassDiscovery');
}

function it_finds_an_http_client(
Discovery $discovery,
ClassBinding $binding
) {
$binding->hasParameterValue('depends')->willReturn(false);
$binding->getClassName()->willReturn('spec\Http\Discovery\Stub\HttpClientStub');
function it_finds_a_http_client(DiscoveryStrategy $strategy) {

$discovery->findBindings('Http\Client\HttpClient')->willReturn([$binding]);
$candidate = ['class' => 'spec\Http\Discovery\Stub\HttpClientStub', 'condition' => true];
DiscoveryHelper::setClasses(HttpClient::class, [$candidate]);

$this->find()->shouldImplement('Http\Client\HttpClient');
}

function it_throw_exception(DiscoveryStrategy $strategy) {
$this->shouldThrow(NotFoundException::class)->duringFind();
}
}
37 changes: 17 additions & 20 deletions spec/MessageFactoryDiscoverySpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,23 @@

namespace spec\Http\Discovery;

use Http\Discovery\ClassDiscovery;
use Http\Discovery\Exception\NotFoundException;
use Http\Discovery\Strategy\DiscoveryStrategy;
use Http\Message\MessageFactory;
use Puli\GeneratedPuliFactory;
use Puli\Discovery\Api\Discovery;
use Puli\Discovery\Binding\ClassBinding;
use Puli\Repository\Api\ResourceRepository;
use PhpSpec\ObjectBehavior;
use spec\Http\Discovery\Helper\DiscoveryHelper;

class MessageFactoryDiscoverySpec extends ObjectBehavior
{
function let(
GeneratedPuliFactory $puliFactory,
ResourceRepository $repository,
Discovery $discovery
) {
$puliFactory->createRepository()->willReturn($repository);
$puliFactory->createDiscovery($repository)->willReturn($discovery);

$this->setPuliFactory($puliFactory);
}

function letgo()
function let()
{
$this->resetPuliFactory();
ClassDiscovery::setStrategies([DiscoveryHelper::class]);
DiscoveryHelper::clearClasses();
}

function it_is_initializable()
Expand All @@ -36,15 +31,17 @@ function it_is_a_class_discovery()
$this->shouldHaveType('Http\Discovery\ClassDiscovery');
}

function it_finds_a_message_factory(
Discovery $discovery,
ClassBinding $binding
) {
$binding->hasParameterValue('depends')->willReturn(false);
$binding->getClassName()->willReturn('spec\Http\Discovery\Stub\MessageFactoryStub');
function it_finds_a_message_factory(DiscoveryStrategy $strategy) {

$discovery->findBindings('Http\Message\MessageFactory')->willReturn([$binding]);
$candidate = ['class' => 'spec\Http\Discovery\Stub\MessageFactoryStub', 'condition' => true];
DiscoveryHelper::setClasses(MessageFactory::class, [$candidate]);

$this->find()->shouldImplement('Http\Message\MessageFactory');
}

function it_throw_exception(DiscoveryStrategy $strategy) {
$strategy->getCandidates('Http\Message\MessageFactory')->willReturn([]);

$this->shouldThrow(NotFoundException::class)->duringFind();
}
}
Loading