Skip to content

Commit

Permalink
Added tests and fixed issues with NoCandidateFoundException (#132)
Browse files Browse the repository at this point in the history
  • Loading branch information
Nyholm authored and dbu committed Jan 5, 2019
1 parent be7a6a0 commit a2a00ec
Show file tree
Hide file tree
Showing 10 changed files with 216 additions and 9 deletions.
15 changes: 11 additions & 4 deletions .travis.yml
Expand Up @@ -28,17 +28,24 @@ matrix:
- php: 7.3
fast_finish: true
include:
- php: 5.5
env: COMPOSER_FLAGS="--prefer-stable --prefer-lowest" COVERAGE=true TEST_COMMAND="composer test-ci" PULI_VERSION=1.0.0-beta9

- name: PHPSpec code coverage
php: 5.5
env: COMPOSER_FLAGS="--prefer-stable --prefer-lowest" COVERAGE=true TEST_COMMAND="composer test-ci" PULI_VERSION=1.0.0-beta9 DEPENDENCIES="henrikbjorn/phpspec-code-coverage:^2.0.2"
- name: PHPUnit tests
php: 7.2
env: TEST_COMMAND="./vendor/bin/phpunit" DEPENDENCIES="phpunit/phpunit:^7.5 nyholm/psr7:^1.0 kriswallsmith/buzz:^1.0@beta php-http/curl-client:^1.0 php-http/message"
- name: PHPUnit test with nothing installed
php: 7.2
env: TEST_COMMAND="./vendor/bin/phpunit --group=NothingInstalled" DEPENDENCIES="phpunit/phpunit:^7.5"

before_install:
- if [[ $COVERAGE != true ]]; then phpenv config-rm xdebug.ini || true; fi
- if ! [ -z "$DEPENDENCIES" ]; then composer require --no-update ${DEPENDENCIES}; fi;

install:
- wget https://github.com/puli/cli/releases/download/1.0.0-beta10/puli.phar && chmod +x puli.phar
- composer require puli/composer-plugin:${PULI_VERSION} --no-update
- travis_retry composer update ${COMPOSER_FLAGS} --prefer-dist --no-interaction
- composer update ${COMPOSER_FLAGS} --prefer-dist --no-interaction

script:
- $TEST_COMMAND
Expand Down
3 changes: 1 addition & 2 deletions composer.json
Expand Up @@ -17,8 +17,7 @@
"php-http/httplug": "^1.0 || ^2.0",
"php-http/message-factory": "^1.0",
"puli/composer-plugin": "1.0.0-beta10",
"phpspec/phpspec": "^2.4",
"henrikbjorn/phpspec-code-coverage" : "^2.0.2"
"phpspec/phpspec": "^2.4"
},
"suggest": {
"puli/composer-plugin": "Sets up Puli which is recommended for Discovery to work. Check http://docs.php-http.org/en/latest/discovery.html for more details.",
Expand Down
20 changes: 20 additions & 0 deletions phpunit.xml.dist
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>

<phpunit bootstrap="./vendor/autoload.php"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true">

<testsuites>
<testsuite name="HTTPlug unit tests">
<directory suffix="Test.php">./tests</directory>
</testsuite>
</testsuites>

<groups>
<exclude>
<group>NothingInstalled</group>
</exclude>
</groups>
</phpunit>
15 changes: 14 additions & 1 deletion src/Exception/NoCandidateFoundException.php
Expand Up @@ -27,9 +27,22 @@ function ($a) {
$message = sprintf(
'No valid candidate found using strategy "%s". We tested the following candidates: %s.',
$strategy,
implode(', ', $classes)
implode(', ', array_map([$this, 'stringify'], $classes))
);

parent::__construct($message);
}

private function stringify($mixed)
{
if (is_string($mixed)) {
return $mixed;
}

if (is_array($mixed) && 2 === count($mixed)) {
return sprintf('%s::%s', $this->stringify($mixed[0]), $mixed[1]);
}

return is_object($mixed) ? get_class($mixed) : gettype($mixed);
}
}
2 changes: 1 addition & 1 deletion src/Psr17FactoryDiscovery.php
Expand Up @@ -20,7 +20,7 @@ final class Psr17FactoryDiscovery extends ClassDiscovery
private static function createException($type, Exception $e)
{
return new \Http\Discovery\Exception\NotFoundException(
'No psr-17 '.$type.' found. Install a package from this list: https://packagist.org/providers/psr/http-factory-implementation',
'No PSR-17 '.$type.' found. Install a package from this list: https://packagist.org/providers/psr/http-factory-implementation',
0,
$e
);
Expand Down
7 changes: 6 additions & 1 deletion src/Strategy/CommonClassesStrategy.php
Expand Up @@ -81,7 +81,12 @@ final class CommonClassesStrategy implements DiscoveryStrategy
'condition' => [\Buzz\Client\FileGetContents::class, \Buzz\Message\ResponseBuilder::class],
],
],
Psr18Client::class => [],
Psr18Client::class => [
[
'class' => [self::class, 'buzzInstantiate'],
'condition' => [\Buzz\Client\FileGetContents::class, \Buzz\Message\ResponseBuilder::class],
],
],
];

/**
Expand Down
23 changes: 23 additions & 0 deletions tests/Exception/InitializeExceptionTest.php
@@ -0,0 +1,23 @@
<?php

namespace tests\Http\Discovery\Exception;

use Http\Discovery\Exception as DiscoveryException;
use PHPUnit\Framework\TestCase;

class InitializeExceptionTest extends TestCase
{
public function testInitialize()
{
$e[] = new DiscoveryException\ClassInstantiationFailedException();
$e[] = new DiscoveryException\NotFoundException();
$e[] = new DiscoveryException\PuliUnavailableException();
$e[] = new DiscoveryException\StrategyUnavailableException();
$e[] = new DiscoveryException\NoCandidateFoundException('CommonClasses', []);
$e[] = DiscoveryException\DiscoveryFailedException::create($e);

foreach ($e as $exception) {
$this->assertInstanceOf(\Http\Discovery\Exception::class, $exception);
}
}
}
67 changes: 67 additions & 0 deletions tests/Exception/NoCandidateFoundExceptionTest.php
@@ -0,0 +1,67 @@
<?php

namespace tests\Http\Discovery\Exception;

use Http\Discovery\Exception as DiscoveryException;
use PHPUnit\Framework\TestCase;

class NoCandidateFoundExceptionTest extends TestCase
{
public function testInitialize()
{
$candidates = [
['class' => 'Foo', 'condition' => true],
['class' => 'Bar', 'condition' => false],
];
$exception = new DiscoveryException\NoCandidateFoundException('Foobar', $candidates);
$this->assertInstanceOf(\Http\Discovery\Exception::class, $exception);
$this->assertStringStartsWith('No valid candidate found using strategy "Foobar".', $exception->getMessage());
}

public function testInitializeWithArrayCallable()
{
$candidates = [
['class' => ['AnyClass', 'anyFunction'], 'condition' => true],
];

$exception = new DiscoveryException\NoCandidateFoundException('Foobar', $candidates);
$this->assertInstanceOf(\Http\Discovery\Exception::class, $exception);
}

public function testInitializeWithObjectCallable()
{
$obj = new \stdClass();
$candidates = [
['class' => [$obj, 'anyFunction'], 'condition' => true],
];

$exception = new DiscoveryException\NoCandidateFoundException('Foobar', $candidates);
$this->assertInstanceOf(\Http\Discovery\Exception::class, $exception);
}

public function testInitializeWithClosure()
{
$obj = \Closure::fromCallable(function () {
$x = 2;
});
$candidates = [
['class' => $obj, 'condition' => true],
];

$exception = new DiscoveryException\NoCandidateFoundException('Foobar', $candidates);
$this->assertInstanceOf(\Http\Discovery\Exception::class, $exception);
}

public function testInitializeWithAnonymousFunction()
{
$func = function () {
$x = 2;
};
$candidates = [
['class' => $func, 'condition' => true],
];

$exception = new DiscoveryException\NoCandidateFoundException('Foobar', $candidates);
$this->assertInstanceOf(\Http\Discovery\Exception::class, $exception);
}
}
47 changes: 47 additions & 0 deletions tests/Psr17FactoryDiscoveryTest.php
@@ -0,0 +1,47 @@
<?php

namespace tests\Http\Discovery;

use Http\Discovery\Exception\NotFoundException;
use Http\Discovery\Psr17FactoryDiscovery;
use PHPUnit\Framework\TestCase;
use Psr\Http\Message\RequestFactoryInterface;
use Psr\Http\Message\ResponseFactoryInterface;
use Psr\Http\Message\ServerRequestFactoryInterface;
use Psr\Http\Message\StreamFactoryInterface;
use Psr\Http\Message\UploadedFileFactoryInterface;
use Psr\Http\Message\UriFactoryInterface;

class Psr17FactoryDiscoveryTest extends TestCase
{
/**
* @dataProvider getFactories
*/
public function testFind($method, $interface)
{
$callable = [Psr17FactoryDiscovery::class, $method];
$client = $callable();
$this->assertInstanceOf($interface, $client);
}

/**
* @group NothingInstalled
* @dataProvider getFactories
*/
public function testNotFound($method)
{
$callable = [Psr17FactoryDiscovery::class, $method];
$this->expectException(NotFoundException::class);
$callable();
}

public function getFactories()
{
yield ['findRequestFactory', RequestFactoryInterface::class];
yield ['findResponseFactory', ResponseFactoryInterface::class];
yield ['findServerRequestFactory', ServerRequestFactoryInterface::class];
yield ['findStreamFactory', StreamFactoryInterface::class];
yield ['findUploadedFileFactory', UploadedFileFactoryInterface::class];
yield ['findUrlFactory', UriFactoryInterface::class];
}
}
26 changes: 26 additions & 0 deletions tests/Psr18ClientDiscoveryTest.php
@@ -0,0 +1,26 @@
<?php

namespace tests\Http\Discovery;

use Http\Discovery\Exception\NotFoundException;
use Http\Discovery\Psr18ClientDiscovery;
use PHPUnit\Framework\TestCase;
use Psr\Http\Client\ClientInterface;

class Psr18ClientDiscoveryTest extends TestCase
{
public function testFind()
{
$client = Psr18ClientDiscovery::find();
$this->assertInstanceOf(ClientInterface::class, $client);
}

/**
* @group NothingInstalled
*/
public function testNotFound()
{
$this->expectException(NotFoundException::class);
$client = Psr18ClientDiscovery::find();
}
}

0 comments on commit a2a00ec

Please sign in to comment.