- Improve MetaCommand to allow to ignore some abstract names

- Auto-correct `Method` FQN type name if missing first \
- Implement unit-tests
This commit is contained in:
Thach Nguyen
2018-01-31 19:53:24 +07:00
parent 647b8ff0d1
commit 1080504a78
9 changed files with 207 additions and 9 deletions
+1 -1
View File
@@ -1,3 +1,3 @@
/vendor
composer.lock
.idea
.idea/
+26
View File
@@ -0,0 +1,26 @@
language: php
php:
- 5.4
- 5.5
- 5.6
- hhvm
matrix:
include:
- php: 5.3
dist: precise
allow_failures:
- php: hhvm
fast_finish: true
cache:
directories:
- vendor
- $HOME/.composer/cache
before_script:
- travis_retry composer self-update
- travis_retry composer install --no-interaction --no-suggest --no-progress
script:
- vendor/bin/phpunit
+2 -1
View File
@@ -22,7 +22,8 @@
"kdyby/parse-use-statements": "~0.2"
},
"require-dev": {
"doctrine/dbal": "~2.3"
"doctrine/dbal": "~2.3",
"phpunit/phpunit": "~4.0"
},
"suggest": {
"doctrine/dbal": "Load information from the database about models for phpdocs (~2.3)"
+18
View File
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.0/phpunit.xsd"
backupGlobals="false"
backupStaticAttributes="false"
bootstrap="vendor/autoload.php"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false">
<testsuites>
<testsuite name="Package Test Suite">
<directory suffix=".php">./tests/</directory>
</testsuite>
</testsuites>
</phpunit>
+28 -4
View File
@@ -39,10 +39,9 @@ class MetaCommand extends Command {
protected $view;
protected $methods = array(
'\Illuminate\Foundation\Application::make',
'new \Illuminate\Foundation\Application',
'\Illuminate\Container\Container::make',
//'\Illuminate\Foundation\Application::make',
'new \Illuminate\Container\Container',
'\Illuminate\Container\Container::make',
'\App::make',
'app',
);
@@ -67,8 +66,16 @@ class MetaCommand extends Command {
*/
public function fire()
{
$bindings = array();
$bindings = array_flip($this->getAppAliases());
$exclude = $this->option('exclude');
if (!empty($exclude)) {
$exclude = '/' . str_replace('\|', '|', preg_quote($exclude, '/')) . '/';
}
foreach ($this->getAbstracts() as $abstract) {
if (!empty($exclude) && preg_match($exclude, $abstract))
continue;
try {
$concrete = $this->laravel->make($abstract);
if (is_object($concrete)) {
@@ -78,6 +85,7 @@ class MetaCommand extends Command {
$this->error("Cannot make $abstract: " . $e->getMessage());
}
}
asort($bindings);
$content = $this->view->make('laravel-ide-helper::meta', array(
'bindings' => $bindings,
@@ -104,6 +112,21 @@ class MetaCommand extends Command {
return array_keys($this->laravel->getBindings());
}
/**
* Get a list of aliases from the Laravel Application.
*
* @return array
*/
protected function getAppAliases()
{
static $aliasProp;
if (!isset($aliasProp)) {
$aliasProp = new \ReflectionProperty('Illuminate\Container\Container', 'aliases');
$aliasProp->setAccessible(true);
}
return $aliasProp->getValue($this->laravel);
}
/**
* {@inheritdoc}
*/
@@ -111,6 +134,7 @@ class MetaCommand extends Command {
{
return array(
array('filename', 'F', InputOption::VALUE_OPTIONAL, 'The path to the meta file', $this->filename),
array('exclude', 'E', InputOption::VALUE_OPTIONAL, 'Laravel bindings to exclude (e.g. "bar.|.foo")'),
);
}
}
+10 -2
View File
@@ -24,7 +24,6 @@ class Method
/** @var \ReflectionMethod */
protected $method;
protected $output = '';
protected $name;
protected $namespace;
protected $params = array();
@@ -230,7 +229,16 @@ class Method
*/
protected static function convertKeywords($string)
{
return preg_replace(array('/(^|\|)Closure(\||$)/', '/(^|\|)dynamic(\||$)/'), array('$1\Closure$2', '$1mixed$2'), $string);
$types = explode('|', $string);
foreach ($types as &$type) {
if ($type === 'Closure')
$type = '\Closure';
elseif ($type === 'dynamic')
$type = 'mixed';
elseif (strrpos($type, '\\') && $type[0] !== '\\' && (class_exists($type) || interface_exists($type)))
$type = '\\' . $type;
}
return implode('|', $types);
}
/**
+1 -1
View File
@@ -13,7 +13,7 @@
<?php foreach ($methods as $method): ?>
<?= strpos($method, 'new ') === 0 ? $method : $method . '(\'\')' ?> => array(
<?php foreach ($bindings as $abstract => $class): ?>
'<?= $abstract ?>' instanceof \<?= $class ?>,
<?= var_export($abstract, true) ?> instanceof \<?= $class ?>,
<?php endforeach ?>
),
<?php endforeach ?>
+38
View File
@@ -0,0 +1,38 @@
<?php namespace Barryvdh\LaravelIdeHelper;
class MethodTest extends \PHPUnit_Framework_TestCase
{
/**
* @expectedException \PHPUnit_Framework_Error
* @expectedExceptionMessage Argument 1 passed to
*/
public function testConstructorWithoutMethod()
{
new Method(null, null, null);
}
public function testConstructor()
{
$method = new \ReflectionMethod('PHPUnit_Framework_TestCase', 'getMock');
$object = new Method($method, null, new \ReflectionClass(get_class($this)));
$this->assertSame('\PHPUnit_Framework_TestCase', $object->getDeclaringClass());
$this->assertSame('\\' . get_class($this), $object->getRoot());
$this->assertSame('getMock', $object->getName());
$prop = new \ReflectionProperty(get_class($object), 'namespace');
$prop->setAccessible(true);
$this->assertSame('', $prop->getValue($object));
$this->assertFalse($object->isDeprecated());
$this->assertCount($method->getNumberOfParameters(), $object->getDocParams());
$doc = $object->getDocComment('', true);
$this->assertContains("\n * " . '@param array|null $methods', $doc);
$this->assertContains("\n * " . '@return \PHPUnit_Framework_MockObject_MockObject', $doc);
$this->assertContains("\n * " . '@throws \PHPUnit_Framework_Exception', $doc);
$this->assertTrue($object->shouldReturn());
}
}
+83
View File
@@ -0,0 +1,83 @@
<?php namespace Barryvdh\LaravelIdeHelper;
class ServiceProviderTest extends \PHPUnit_Framework_TestCase
{
/** @var \PHPUnit_Framework_MockObject_MockObject|\Illuminate\Container\Container */
protected $app;
/** @var IdeHelperServiceProvider */
protected $provider;
static function makeAppMock(\PHPUnit_Framework_TestCase $testCase)
{
$app = $testCase->getMock('Illuminate\Container\Container', array('make', 'bind'));
$fs = $testCase->getMock('Illuminate\Filesystem\Filesystem', null);
$config = $testCase->getMock('Illuminate\Config\Repository', array('get', 'set', 'package'), array(), '', false);
$events = $testCase->getMock('Illuminate\Events\Dispatcher', array('listen'), array($app));
$view = $testCase->getMock('Illuminate\View\Factory', array('addNamespace'), array(), '', false);
$app->expects($testCase->any())->method('make')->willReturnMap(array(
array('files', array(), $fs),
array('config', array(), $config),
array('events', array(), $events),
array('view', array(), $view),
array('path', array(), __DIR__),
));
return $app;
}
/**
* {@inheritdoc}
*/
protected function setUp()
{
$this->app = static::makeAppMock($this);
/** @noinspection PhpParamsInspection */
$this->provider = new IdeHelperServiceProvider($this->app);
}
public function testDeferred()
{
$this->assertTrue($this->provider->isDeferred());
}
public function testProvides()
{
$this->assertEquals(array('command.ide-helper.generate', 'command.ide-helper.models', 'command.ide-helper.meta'), $this->provider->provides());
}
public function testRegister()
{
$this->app->expects($this->exactly(3))->method('bind')->withConsecutive(
array('command.ide-helper.generate', $this->isType(\PHPUnit_Framework_Constraint_IsType::TYPE_CALLABLE), $this->isFalse()),
array('command.ide-helper.models', $this->isType(\PHPUnit_Framework_Constraint_IsType::TYPE_CALLABLE), $this->isFalse()),
array('command.ide-helper.meta', $this->isType(\PHPUnit_Framework_Constraint_IsType::TYPE_CALLABLE), $this->isFalse())
);
/** @var \PHPUnit_Framework_MockObject_MockObject|\Illuminate\Events\Dispatcher $events */
$events = $this->app['events'];
$events->expects($this->once())->method('listen')->with('artisan.start', $this->callback(function ($listener) {
$params = print_r(array('commands' => array('command.ide-helper.generate', 'command.ide-helper.models', 'command.ide-helper.meta')), true);
return strpos(preg_replace('/^\s+/mu', '', print_r($listener, true)), preg_replace('/^\s+/mu', '', $params));
}), 0);
$this->provider->register();
}
public function testBoot()
{
$path = realpath(__DIR__ . '/../src');
/** @var \PHPUnit_Framework_MockObject_MockObject|\Illuminate\Config\Repository $config */
$config = $this->app['config'];
$config->expects($this->once())->method('package')->with('barryvdh/laravel-ide-helper', $path . '/config', 'laravel-ide-helper');
/** @var \PHPUnit_Framework_MockObject_MockObject|\Illuminate\View\Factory $view */
$view = $this->app['view'];
$view->expects($this->once())->method('addNamespace')->with('laravel-ide-helper', $path . '/views');
$this->provider->boot();
}
}