Merge pull request #615 from nthachus/1.11

Update to release v1.11.7
This commit is contained in:
Barry vd. Heuvel
2018-01-31 15:16:07 +01:00
committed by GitHub
17 changed files with 1451 additions and 1091 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
+6 -2
View File
@@ -11,14 +11,18 @@
],
"require": {
"php": ">=5.3.0",
"illuminate/config": "4.x",
"illuminate/support": "4.x",
"illuminate/console": "4.x",
"illuminate/filesystem": "4.x",
"barryvdh/reflection-docblock": "^2.0.4",
"illuminate/database": "4.x",
"illuminate/view": "4.x",
"phpdocumentor/reflection-docblock": "^2.0.4",
"symfony/class-loader": "~2.3"
},
"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>
+25 -3
View File
@@ -7,7 +7,7 @@
_Checkout [this Laracasts video](https://laracasts.com/series/how-to-be-awesome-in-phpstorm/episodes/15) for a quick introduction/explanation!_
This packages generates a file that your IDE can understand, so it can provide accurate autocompletion. Generation is done, based on the files in your project, so they are alway up-to-date.
This packages generates a file that your IDE can understand, so it can provide accurate autocompletion. Generation is done, based on the files in your project, so they are always up-to-date.
If you don't want to generate it, you can add a pre-generated file to the root folder of your laravel project. (But this isn't as up-to-date as self generated files)
* Generated version: https://gist.github.com/barryvdh/5227822
@@ -18,13 +18,16 @@ Note: You do need CodeIntel for Sublime Text: https://github.com/SublimeCodeInte
It's possible to generate a PhpStorm meta file, to [add support for factory design pattern](https://confluence.jetbrains.com/display/PhpStorm/PhpStorm+Advanced+Metadata). For Laravel, this means we can make PhpStorm understand what kind of object we are resolving from the IoC Container. For example, `events` will return ann `Illuminate\Events\Dispatcher` object, so with the meta file you can call `app('events')` and it will autocomplete the Dispatcher methods.
```bash
php artisan ide-helper:meta
```
```php
app('events')->fire();
\App::make('events')->fire();
/** @var \Illuminate\Foundation\Application $app */
$app->make('events')->fire();
```
Pre-generated example: https://gist.github.com/barryvdh/bb6ffc5d11e0a75dba67
@@ -34,20 +37,27 @@ Pre-generated example: https://gist.github.com/barryvdh/bb6ffc5d11e0a75dba67
Require this package with composer using the following command:
```bash
composer require barryvdh/laravel-ide-helper ~1.11
```
After updating composer, add the ServiceProvider to the providers array in `app/config/app.php`
```php
'Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider',
```
You can now re-generate the docs yourself (for future updates) in artisan
```bash
php artisan ide-helper:generate
```
Note: bootstrap/compiled.php has to be cleared first, so run `php artisan clear-compiled` before generating (and `php artisan optimize` after..)
You can configure your composer.json to do this after each commit:
```json
"scripts":{
"post-update-cmd":[
"php artisan clear-compiled",
@@ -55,10 +65,13 @@ You can configure your composer.json to do this after each commit:
"php artisan optimize"
]
},
```
You can also publish the config-file to change implementations (ie. interface to specific class) or set defaults for --helpers or --sublime.
```bash
php artisan config:publish barryvdh/laravel-ide-helper
```
The generator tries to identify the real class, but if it cannot be found, you can define it in the config file.
@@ -78,8 +91,10 @@ Please make sure to backup your models, before writing the info.
It should keep the existing comments and only append new properties/methods. The existing phpdoc is replaced, or added if not found.
With the `--reset (-R)` option, the existing phpdocs are ignored, only the newly found columns/relations are saved as phpdocs.
```bash
php artisan ide-helper:models Post
```
```php
/**
* An Eloquent Model: 'Post'
*
@@ -92,20 +107,27 @@ With the `--reset (-R)` option, the existing phpdocs are ignored, only the newly
* @property-read \User $author
* @property-read \Illuminate\Database\Eloquent\Collection|\Comment[] $comments
*/
```
By default, models in app/models are scanned. The optional argument tells what models to use (also outside app/models).
```bash
php artisan ide-helper:models Post User
```
You can also scan a different directory, using the --dir option (relative from the base path):
```bash
php artisan ide-helper:models --dir="app/workbench/name/package/models" --dir="app/src/Model"
```
You can publish the config file (`php artisan config:publish barryvdh/laravel-ide-helper`) and set the default directories.
Models can be ignored using the --ignore (-I) option
```bash
php artisan ide-helper:models --ignore="Post,User"
```
Note: With namespaces, wrap your model name in " signs: `php artisan ide-helper:models "API\User"`, or escape the slashes (`Api\\User`)
+11 -8
View File
@@ -71,7 +71,7 @@ class Alias
if (class_exists($class) || interface_exists($class)) {
$this->classes[] = $class;
} else {
echo "Class not exists: $class\r\n";
$this->error('Class not exists: ' . $class);
}
}
}
@@ -86,11 +86,11 @@ class Alias
}
/**
* Get the classtype, 'interface' or 'class'
* Get the classType, 'interface' or 'class'
*
* @return string
*/
public function getClasstype()
public function getClassType()
{
return $this->classType;
}
@@ -117,10 +117,14 @@ class Alias
/**
* Return the short name (without namespace)
*
* @return string
*/
public function getShortName(){
public function getShortName()
{
return $this->short;
}
/**
* Get the namespace from the alias
*
@@ -134,7 +138,7 @@ class Alias
/**
* Get the methods found by this Alias
*
* @return array
* @return array|Method[]
*/
public function getMethods()
{
@@ -201,10 +205,10 @@ class Alias
//When the database connection is not set, some classes will be skipped
} catch (\PDOException $e) {
$this->error(
"PDOException: " . $e->getMessage() . "\nPlease configure your database connection correctly, or use the sqlite memory driver (-M). Skipping $facade."
'PDOException: ' . $e->getMessage() . "\nPlease configure your database connection correctly, or use the sqlite memory driver (-M). Skipping $facade."
);
} catch (\Exception $e) {
$this->error("Exception: " . $e->getMessage() . "\nSkipping $facade.");
$this->error('Exception: ' . $e->getMessage() . "\nSkipping $facade.");
}
}
@@ -251,7 +255,6 @@ class Alias
*/
protected function detectMethods()
{
foreach ($this->classes as $class) {
$reflection = new \ReflectionClass($class);
+10 -24
View File
@@ -17,7 +17,6 @@ use Illuminate\Filesystem\Filesystem;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputArgument;
/**
* A command to generate autocomplete information for your IDE
*
@@ -27,16 +26,12 @@ class GeneratorCommand extends Command
{
/**
* The console command name.
*
* @var string
* {@inheritdoc}
*/
protected $name = 'ide-helper:generate';
/**
* The console command description.
*
* @var string
* {@inheritdoc}
*/
protected $description = 'Generate a new IDE Helper file.';
@@ -51,18 +46,14 @@ class GeneratorCommand extends Command
protected $onlyExtend;
/**
* {@inheritdoc}
*
* @param \Illuminate\Config\Repository $config
* @param \Illuminate\Filesystem\Filesystem $files
* @param \Illuminate\View\Factory $view
*/
public function __construct(
ConfigRepository $config,
Filesystem $files, /* Illuminate\View\Factory */
$view
) {
public function __construct(ConfigRepository $config, Filesystem $files, $view) {
$this->config = $config;
$this->files = $files;
$this->view = $view;
@@ -95,7 +86,6 @@ class GeneratorCommand extends Command
$this->useMemoryDriver();
}
$helpers = '';
if ($this->option('helpers') || ($this->config->get('laravel-ide-helper::include_helpers'))) {
foreach ($this->config->get('laravel-ide-helper::helper_files', array()) as $helper) {
@@ -133,9 +123,7 @@ class GeneratorCommand extends Command
}
/**
* Get the console command arguments.
*
* @return array
* {@inheritdoc}
*/
protected function getArguments()
{
@@ -149,19 +137,17 @@ class GeneratorCommand extends Command
}
/**
* Get the console command options.
*
* @return array
* {@inheritdoc}
*/
protected function getOptions()
{
$format = $this->config->get('laravel-ide-helper::format');
return array(
array('format', "F", InputOption::VALUE_OPTIONAL, 'The format for the IDE Helper', $format),
array('helpers', "H", InputOption::VALUE_NONE, 'Include the helper files'),
array('memory', "M", InputOption::VALUE_NONE, 'Use sqlite memory driver'),
array('sublime', "S", InputOption::VALUE_NONE, 'DEPRECATED: Use different style for SublimeText CodeIntel'),
array('format', 'F', InputOption::VALUE_OPTIONAL, 'The format for the IDE Helper', $format),
array('helpers', 'H', InputOption::VALUE_NONE, 'Include the helper files'),
array('memory', 'M', InputOption::VALUE_NONE, 'Use sqlite memory driver'),
array('sublime', 'S', InputOption::VALUE_NONE, 'DEPRECATED: Use different style for SublimeText CodeIntel'),
);
}
+37 -14
View File
@@ -17,21 +17,18 @@ use Symfony\Component\Console\Input\InputOption;
* A command to generate phpstorm meta data
*
* @author Barry vd. Heuvel <[email protected]>
* @property \Illuminate\Container\Container $laravel
*/
class MetaCommand extends Command {
/**
* The console command name.
*
* @var string
* {@inheritdoc}
*/
protected $name = 'ide-helper:meta';
protected $filename = '.phpstorm.meta.php';
/**
* The console command description.
*
* @var string
* {@inheritdoc}
*/
protected $description = 'Generate metadata for PhpStorm';
@@ -42,20 +39,23 @@ class MetaCommand extends Command {
protected $view;
protected $methods = array(
'\Illuminate\Foundation\Application::make',
//'\Illuminate\Foundation\Application::make',
'new \Illuminate\Container\Container',
'\Illuminate\Container\Container::make',
'\App::make',
'app',
);
/**
* {@inheritdoc}
*
* @param \Illuminate\Filesystem\Filesystem $files
* @param \Illuminate\View\Factory $view
* @param \Illuminate\Container\Container $app
*/
public function __construct($files, $view) {
$this->files = $files;
$this->view = $view;
public function __construct($app)
{
$this->laravel = $app;
$this->files = $app['files'];
$this->view = $app['view'];
parent::__construct();
}
@@ -66,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)) {
@@ -77,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,14 +113,28 @@ class MetaCommand extends Command {
}
/**
* Get the console command options.
* 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}
*/
protected function getOptions()
{
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")'),
);
}
}
+47 -65
View File
@@ -15,31 +15,27 @@ use Illuminate\Support\Str;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\ClassLoader\ClassMapGenerator;
use Barryvdh\Reflection\DocBlock;
use Barryvdh\Reflection\DocBlock\Context;
use Barryvdh\Reflection\DocBlock\Tag;
use Barryvdh\Reflection\DocBlock\Serializer as DocBlockSerializer;
use phpDocumentor\Reflection\DocBlock;
use phpDocumentor\Reflection\DocBlock\Context;
use phpDocumentor\Reflection\DocBlock\Tag;
/**
* A command to generate autocomplete information for your IDE
*
* @author Barry vd. Heuvel <[email protected]>
* @property \Illuminate\Container\Container $laravel
*/
class ModelsCommand extends Command
{
/**
* The console command name.
*
* @var string
* {@inheritdoc}
*/
protected $name = 'ide-helper:models';
protected $filename = '_ide_helper_models.php';
/**
* The console command description.
*
* @var string
* {@inheritdoc}
*/
protected $description = 'Generate autocompletion for models';
@@ -49,6 +45,20 @@ class ModelsCommand extends Command
protected $dirs = array();
protected $reset;
/** @var \Illuminate\Filesystem\Filesystem */
protected $files;
/**
* {@inheritdoc}
*
* @param \Illuminate\Container\Container $app
*/
public function __construct($app)
{
$this->laravel = $app;
$this->files = $app['files'];
parent::__construct();
}
/**
* Execute the console command.
@@ -69,10 +79,7 @@ class ModelsCommand extends Command
//If filename is default and Write is not specified, ask what to do
if (!$this->write && $filename === $this->filename && !$this->option('nowrite')) {
if ($this->confirm(
"Do you want to overwrite the existing model files? Choose no to write to $filename instead? (Yes/No): "
)
) {
if ($this->confirm("Do you want to overwrite the existing model files? Choose no to write to $filename instead? (Yes/No): ")) {
$this->write = true;
}
}
@@ -80,7 +87,7 @@ class ModelsCommand extends Command
$content = $this->generateDocs($model, $ignore);
if (!$this->write) {
$written = \File::put($filename, $content);
$written = $this->files->put($filename, $content);
if ($written !== false) {
$this->info("Model information was written to $filename");
} else {
@@ -89,11 +96,8 @@ class ModelsCommand extends Command
}
}
/**
* Get the console command arguments.
*
* @return array
* {@inheritdoc}
*/
protected function getArguments()
{
@@ -103,9 +107,7 @@ class ModelsCommand extends Command
}
/**
* Get the console command options.
*
* @return array
* {@inheritdoc}
*/
protected function getOptions()
{
@@ -121,8 +123,6 @@ class ModelsCommand extends Command
protected function generateDocs($loadModels, $ignore = '')
{
$output = "<?php
/**
* An helper file for your Eloquent Models
@@ -164,7 +164,7 @@ class ModelsCommand extends Command
$this->comment("Loading model '$name'");
if (!$reflectionClass->IsInstantiable()) {
if (!$reflectionClass->isInstantiable()) {
throw new \Exception($name . ' is not instantiable.');
}
@@ -177,7 +177,7 @@ class ModelsCommand extends Command
$this->getPropertiesFromMethods($model);
$output .= $this->createPhpDocs($name);
} catch (\Exception $e) {
$this->error("Exception: " . $e->getMessage() . "\nCould not analyze class $name.");
$this->error('Exception: ' . $e->getMessage() . "\nCould not analyze class $name.");
}
}
@@ -190,10 +190,8 @@ class ModelsCommand extends Command
}
return $output;
}
protected function loadModels()
{
$models = array();
@@ -259,7 +257,7 @@ class ModelsCommand extends Command
$comment = $column->getComment();
$this->setProperty($name, $type, true, true, $comment);
$this->setMethod(
Str::camel("where_" . $name),
Str::camel('where_' . $name),
'\Illuminate\Database\Query\Builder|\\' . get_class($model),
array('$value')
);
@@ -275,21 +273,13 @@ class ModelsCommand extends Command
$methods = get_class_methods($model);
if ($methods) {
foreach ($methods as $method) {
if (Str::startsWith($method, 'get') && Str::endsWith(
$method,
'Attribute'
) && $method !== 'getAttribute'
) {
if (Str::startsWith($method, 'get') && Str::endsWith($method, 'Attribute') && $method !== 'getAttribute') {
//Magic get<name>Attribute
$name = Str::snake(substr($method, 3, -9));
if (!empty($name)) {
$this->setProperty($name, null, true, null);
}
} elseif (Str::startsWith($method, 'set') && Str::endsWith(
$method,
'Attribute'
) && $method !== 'setAttribute'
) {
} elseif (Str::startsWith($method, 'set') && Str::endsWith($method, 'Attribute') && $method !== 'setAttribute') {
//Magic set<name>Attribute
$name = Str::snake(substr($method, 3, -9));
if (!empty($name)) {
@@ -321,22 +311,14 @@ class ModelsCommand extends Command
$begin = strpos($code, 'function(');
$code = substr($code, $begin, strrpos($code, '}') - $begin + 1);
foreach (array(
'hasMany',
'belongsToMany',
'hasOne',
'belongsTo',
'morphTo',
'morphMany',
'morphToMany'
) as $relation) {
foreach (array('hasMany', 'belongsToMany', 'hasOne', 'belongsTo', 'morphTo', 'morphMany', 'morphToMany') as $relation) {
$search = '$this->' . $relation . '(';
if ($pos = stripos($code, $search)) {
$code = substr($code, $pos + strlen($search));
$arguments = explode(',', substr($code, 0, strpos($code, ');')));
//Remove quotes, ensure 1 \ in front of the model
$returnModel = $this->getClassName($arguments[0], $model);
if ($relation === "belongsToMany" or $relation === 'hasMany' or $relation === 'morphMany' or $relation === 'morphToMany') {
if ($relation === 'belongsToMany' or $relation === 'hasMany' or $relation === 'morphMany' or $relation === 'morphToMany') {
//Collection or array of models (because Collection is Arrayable)
$this->setProperty(
$method,
@@ -398,10 +380,9 @@ class ModelsCommand extends Command
*/
protected function createPhpDocs($class)
{
$reflection = new \ReflectionClass($class);
$namespace = $reflection->getNamespaceName();
$classname = $reflection->getShortName();
$className = $reflection->getShortName();
$originalDoc = $reflection->getDocComment();
if ($this->reset) {
@@ -417,10 +398,11 @@ class ModelsCommand extends Command
$properties = array();
$methods = array();
foreach ($phpdoc->getTags() as $tag) {
/* @var Tag|Tag\PropertyTag|Tag\MethodTag $tag */
$name = $tag->getName();
if ($name == "property" || $name == "property-read" || $name == "property-write") {
if ($name == 'property' || $name == 'property-read' || $name == 'property-write') {
$properties[] = $tag->getVariableName();
} elseif ($name == "method") {
} elseif ($name == 'method') {
$methods[] = $tag->getMethodName();
}
}
@@ -450,47 +432,46 @@ class ModelsCommand extends Command
$phpdoc->appendTag($tag);
}
$serializer = new DocBlockSerializer();
$serializer = new DocBlock\Serializer();
$serializer->getDocComment($phpdoc);
$docComment = $serializer->getDocComment($phpdoc);
if ($this->write) {
$filename = $reflection->getFileName();
$contents = \File::get($filename);
$contents = $this->files->get($filename);
if ($originalDoc) {
$contents = str_replace($originalDoc, $docComment, $contents);
} else {
$needle = "class {$classname}";
$replace = "{$docComment}\nclass {$classname}";
$needle = "class {$className}";
$replace = "{$docComment}\nclass {$className}";
$pos = strpos($contents, $needle);
if ($pos !== false) {
$contents = substr_replace($contents, $replace, $pos, strlen($needle));
}
}
if (\File::put($filename, $contents)) {
if ($this->files->put($filename, $contents)) {
$this->info('Written new phpDocBlock to ' . $filename);
}
}
$output = "namespace {$namespace}{\n{$docComment}\n\tclass {$classname} {}\n}\n\n";
$output = "namespace {$namespace}{\n{$docComment}\n\tclass {$className} {}\n}\n\n";
return $output;
}
/**
* Get the parameters and format them correctly
*
* @param $method
* @param \ReflectionMethod $method
* @return array
*/
public function getParameters($method)
{
//Loop through the default values for paremeters, and make the correct output string
$params = array();
//Loop through the default values for parameters, and make the correct output string
$paramsWithDefault = array();
foreach ($method->getParameters() as $param) {
$paramStr = '$' . $param->getName();
$params[] = $paramStr;
if ($param->isOptional()) {
$default = $param->getDefaultValue();
if (is_bool($default)) {
@@ -508,6 +489,7 @@ class ModelsCommand extends Command
}
$paramsWithDefault[] = $paramStr;
}
return $paramsWithDefault;
}
@@ -529,6 +511,6 @@ class ModelsCommand extends Command
return substr($className, 0, $end);
}
return "\\" . ltrim(trim($className, " \"'"), "\\") ;
return '\\' . ltrim(trim($className, ' "\''), '\\');
}
}
+21 -11
View File
@@ -10,7 +10,7 @@
namespace Barryvdh\LaravelIdeHelper;
use Illuminate\Foundation\AliasLoader;
use /** @noinspection PhpUndefinedNamespaceInspection,PhpUndefinedClassInspection */Illuminate\Foundation\AliasLoader;
use Illuminate\Config\Repository as ConfigRepository;
use Symfony\Component\Console\Output\OutputInterface;
@@ -36,11 +36,8 @@ class Generator
* @param \Symfony\Component\Console\Output\OutputInterface $output
* @param string $helpers
*/
public function __construct(ConfigRepository $config,
/* Illuminate\View\Factory */ $view,
OutputInterface $output = null,
$helpers = ''
) {
public function __construct(ConfigRepository $config, $view, OutputInterface $output = null, $helpers = '')
{
$this->config = $config;
$this->view = $view;
@@ -50,6 +47,7 @@ class Generator
$this->extra = array_merge($this->extra, $this->config->get('laravel-ide-helper::extra'));
$this->magic = array_merge($this->magic, $this->config->get('laravel-ide-helper::magic'));
$this->interfaces = array_merge($this->interfaces, $this->config->get('laravel-ide-helper::interfaces'));
// Make all interface classes absolute
foreach ($this->interfaces as &$interface) {
$interface = '\\' . ltrim($interface, '\\');
@@ -115,6 +113,7 @@ class Generator
{
try {
if (class_exists('Auth') && is_a('Auth', '\Illuminate\Support\Facades\Auth', true)) {
/** @noinspection PhpUndefinedClassInspection */
$class = get_class(\Auth::driver());
$this->extra['Auth'] = array($class);
$this->interfaces['\Illuminate\Auth\UserProviderInterface'] = $class;
@@ -123,6 +122,7 @@ class Generator
try {
if (class_exists('DB') && is_a('DB', '\Illuminate\Support\Facades\DB', true)) {
/** @noinspection PhpUndefinedClassInspection */
$class = get_class(\DB::connection());
$this->extra['DB'] = array($class);
$this->interfaces['\Illuminate\Database\ConnectionInterface'] = $class;
@@ -131,7 +131,9 @@ class Generator
try {
if (class_exists('Cache') && is_a('Cache', '\Illuminate\Support\Facades\Cache', true)) {
/** @noinspection PhpUndefinedClassInspection */
$driver = get_class(\Cache::driver());
/** @noinspection PhpUndefinedClassInspection */
$store = get_class(\Cache::getStore());
$this->extra['Cache'] = array($driver, $store);
$this->interfaces['\Illuminate\Cache\StoreInterface'] = $store;
@@ -140,6 +142,7 @@ class Generator
try {
if (class_exists('Queue') && is_a('Queue', '\Illuminate\Support\Facades\Queue', true)) {
/** @noinspection PhpUndefinedClassInspection */
$class = get_class(\Queue::connection());
$this->extra['Queue'] = array($class);
$this->interfaces['\Illuminate\Queue\QueueInterface'] = $class;
@@ -148,6 +151,7 @@ class Generator
try {
if (class_exists('SSH') && is_a('SSH', '\Illuminate\Support\Facades\SSH', true)) {
/** @noinspection PhpUndefinedClassInspection */
$class = get_class(\SSH::connection());
$this->extra['SSH'] = array($class);
$this->interfaces['\Illuminate\Remote\ConnectionInterface'] = $class;
@@ -159,13 +163,14 @@ class Generator
/**
* Find all namespaces/aliases that are valid for us to render
*
* @return array
* @return array|Alias[][]
*/
protected function getNamespaces()
{
$namespaces = array();
// Get all aliases
/** @noinspection PhpUndefinedClassInspection */
foreach (AliasLoader::getInstance()->getAliases() as $name => $facade) {
$magicMethods = array_key_exists($name, $this->magic) ? $this->magic[$name] : array();
$alias = new Alias($name, $facade, $magicMethods, $this->interfaces);
@@ -197,15 +202,20 @@ class Generator
public function getDriver($alias)
{
try {
if ($alias == "Auth") {
if ($alias == 'Auth') {
/** @noinspection PhpUndefinedClassInspection */
$driver = \Auth::driver();
} elseif ($alias == "DB") {
} elseif ($alias == 'DB') {
/** @noinspection PhpUndefinedClassInspection */
$driver = \DB::connection();
} elseif ($alias == "Cache") {
} elseif ($alias == 'Cache') {
/** @noinspection PhpUndefinedClassInspection */
$driver = get_class(\Cache::driver());
/** @noinspection PhpUndefinedClassInspection */
$store = get_class(\Cache::getStore());
return array($driver, $store);
} elseif ($alias == "Queue") {
} elseif ($alias == 'Queue') {
/** @noinspection PhpUndefinedClassInspection */
$driver = \Queue::connection();
} else {
return false;
+14 -43
View File
@@ -15,20 +15,19 @@ use Barryvdh\LaravelIdeHelper\Console\MetaCommand;
use Barryvdh\LaravelIdeHelper\Console\ModelsCommand;
use Barryvdh\LaravelIdeHelper\Console\GeneratorCommand;
/**
* @property \Illuminate\Container\Container $app
*/
class IdeHelperServiceProvider extends ServiceProvider
{
/**
* Indicates if loading of the provider is deferred.
*
* @var bool
* {@inheritdoc}
*/
protected $defer = true;
/**
* Bootstrap the application events.
*
* @return void
* {@inheritdoc}
*/
public function boot()
{
@@ -36,9 +35,7 @@ class IdeHelperServiceProvider extends ServiceProvider
}
/**
* Register the service provider.
*
* @return void
* {@inheritdoc}
*/
public function register()
{
@@ -49,14 +46,14 @@ class IdeHelperServiceProvider extends ServiceProvider
);
$this->app['command.ide-helper.models'] = $this->app->share(
function () {
return new ModelsCommand();
function ($app) {
return new ModelsCommand($app);
}
);
$this->app['command.ide-helper.meta'] = $this->app->share(
function ($app) {
return new MetaCommand($app['files'], $app['view']);
return new MetaCommand($app);
}
);
@@ -64,45 +61,19 @@ class IdeHelperServiceProvider extends ServiceProvider
}
/**
* Get the services provided by the provider.
*
* @return array
* {@inheritdoc}
*/
public function provides()
{
return array('command.ide-helper.generate', 'command.ide-helper.models');
return array('command.ide-helper.generate', 'command.ide-helper.models', 'command.ide-helper.meta');
}
/**
* Register the package's component namespaces.
*
* @param string $package
* @param string $namespace
* @param string $path
* @return void
* {@inheritdoc}
*/
public function package($package, $namespace = null, $path = null)
protected function getAppViewPath($package, $namespace = null)
{
// Is it possible to register the config?
if (method_exists($this->app['config'], 'package')) {
$this->app['config']->package($package, $path.'/config', $namespace);
} else {
// Load the config for now..
$config = $this->app['files']->getRequire($path .'/config/config.php');
foreach($config as $key => $value){
$this->app['config']->set($namespace.'::'.$key, $value);
}
}
// Register view files
$appView = $this->app['path']."/views/packages/{$package}";
if ($this->app['files']->isDirectory($appView))
{
$this->app['view']->addNamespace($namespace, $appView);
}
$this->app['view']->addNamespace($namespace, $path.'/views');
return $this->app['path'] . "/views/packages/{$package}";
}
}
+110 -89
View File
@@ -10,22 +10,19 @@
namespace Barryvdh\LaravelIdeHelper;
use Barryvdh\Reflection\DocBlock;
use Barryvdh\Reflection\DocBlock\Context;
use Barryvdh\Reflection\DocBlock\Tag;
use Barryvdh\Reflection\DocBlock\Tag\ReturnTag;
use Barryvdh\Reflection\DocBlock\Tag\ParamTag;
use Barryvdh\Reflection\DocBlock\Serializer as DocBlockSerializer;
use phpDocumentor\Reflection\DocBlock;
use phpDocumentor\Reflection\DocBlock\Context;
use phpDocumentor\Reflection\DocBlock\Tag;
use phpDocumentor\Reflection\DocBlock\Tag\ReturnTag;
class Method
{
/** @var \Barryvdh\Reflection\DocBlock */
/** @var \phpDocumentor\Reflection\DocBlock */
protected $phpdoc;
/** @var \ReflectionMethod */
protected $method;
protected $output = '';
protected $name;
protected $namespace;
protected $params = array();
@@ -36,7 +33,7 @@ class Method
/**
* @param \ReflectionMethod $method
* @param string $alias
* @param string $class
* @param \ReflectionClass $class
* @param string|null $methodName
* @param array $interfaces
*/
@@ -45,15 +42,15 @@ class Method
$this->method = $method;
$this->interfaces = $interfaces;
$this->name = $methodName ?: $method->name;
$this->namespace = $method->getDeclaringClass()->getNamespaceName();
$declaringClass = $method->getDeclaringClass();
$this->namespace = $declaringClass->getNamespaceName();
//Create a DocBlock and serializer instance
$this->phpdoc = new DocBlock($method, new Context($this->namespace));
$this->phpdoc = new DocBlock($method, new Context($this->namespace, static::getUseStatements($declaringClass)));
//Normalize the description and inherit the docs from parents/interfaces
try {
$this->normalizeParams($this->phpdoc);
$this->normalizeReturn($this->phpdoc);
$this->normalizeReturnTags($this->phpdoc);
$this->normalizeDescription($this->phpdoc);
} catch (\Exception $e) {}
@@ -61,10 +58,9 @@ class Method
$this->getParameters($method);
//Make the method static
$this->phpdoc->appendTag(Tag::createInstance('@static', $this->phpdoc));
//$this->phpdoc->appendTag(Tag::createInstance('@static', $this->phpdoc));
//Reference the 'real' function in the declaringclass
$declaringClass = $method->getDeclaringClass();
//Reference the 'real' function in the declaringClass
$this->declaringClassName = '\\' . ltrim($declaringClass->name, '\\');
$this->root = '\\' . ltrim($class->getName(), '\\');
}
@@ -93,12 +89,17 @@ class Method
* Get the docblock for this method
*
* @param string $prefix
* @return mixed
* @param bool $trim
* @return string
*/
public function getDocComment($prefix = "\t\t")
public function getDocComment($prefix = "\t\t", $trim = false)
{
$serializer = new DocBlockSerializer(1, $prefix);
return $serializer->getDocComment($this->phpdoc);
$serializer = new DocBlock\Serializer(1, $prefix);
$str = $serializer->getDocComment($this->phpdoc);
if ($trim) {
$str = preg_replace(array('/\s+$/m', '#^(\s*/\*\*[\r\n])(?:\s*\*[\r\n])+#u', '#(?:[\r\n]\s*\*)+([\r\n]\s*\*/)$#u'), array('', '$1', '$1'), $str);
}
return $str;
}
/**
@@ -111,11 +112,31 @@ class Method
return $this->name;
}
/**
* Checks whether the method is deprecated
*
* @return bool
*/
public function isDeprecated()
{
return $this->phpdoc->hasTag('deprecated');
}
/**
* Get the declared parameters for this method
*
* @return array
*/
public function getDocParams()
{
return $this->phpdoc->getTagsByName('param');
}
/**
* Get the parameters for this method
*
* @param bool $implode Wether to implode the array or not
* @return string
* @param bool $implode Whether to implode the array or not
* @return string|array
*/
public function getParams($implode = true)
{
@@ -125,8 +146,8 @@ class Method
/**
* Get the parameters for this method including default values
*
* @param bool $implode Wether to implode the array or not
* @return string
* @param bool $implode Whether to implode the array or not
* @return string|array
*/
public function getParamsWithDefault($implode = true)
{
@@ -144,103 +165,90 @@ class Method
$description = $phpdoc->getText();
//Loop through parents/interfaces, to fill in {@inheritdoc}
if (strpos($description, '{@inheritdoc}') !== false) {
$inheritdoc = $this->getInheritDoc($this->method);
if (stripos($description, '{@inheritdoc}') !== false && ($inheritdoc = $this->getInheritDoc($this->method))) {
$inheritDescription = $inheritdoc->getText();
$description = str_replace('{@inheritdoc}', $inheritDescription, $description);
$description = str_ireplace('{@inheritdoc}', $inheritDescription, $description);
$phpdoc->setText($description);
$this->normalizeParams($inheritdoc);
$this->normalizeReturn($inheritdoc);
$this->normalizeReturnTags($inheritdoc);
//Add the tags that are inherited
$inheritTags = $inheritdoc->getTags();
if ($inheritTags) {
/** @var Tag $tag */
foreach ($inheritTags as $tag) {
foreach ($inheritdoc->getTags() as $tag) {
$tag->setDocBlock();
$phpdoc->appendTag($tag);
}
}
}
}
/**
* Normalize the parameters
*
* @param DocBlock $phpdoc
*/
protected function normalizeParams(DocBlock $phpdoc)
{
//Get the return type and adjust them for beter autocomplete
$paramTags = $phpdoc->getTagsByName('param');
if ($paramTags) {
/** @var ParamTag $tag */
foreach($paramTags as $tag){
// Convert the keywords
$content = $this->convertKeywords($tag->getContent());
$tag->setContent($content);
// Get the expanded type and re-set the content
$content = $tag->getType() . ' ' . $tag->getVariableName() . ' ' . $tag->getDescription();
$tag->setContent(trim($content));
}
}
}
/**
* Normalize the return tag (make full namespace, replace interfaces)
*
* @param DocBlock $phpdoc
*/
protected function normalizeReturn(DocBlock $phpdoc)
protected function normalizeReturnTags(DocBlock $phpdoc)
{
//Get the return type and adjust them for beter autocomplete
$returnTags = $phpdoc->getTagsByName('return');
if ($returnTags) {
/** @var ReturnTag $tag */
$tag = reset($returnTags);
// Get the expanded type
$returnValue = $tag->getType();
// Replace the interfaces
foreach($this->interfaces as $interface => $real){
$returnValue = str_replace($interface, $real, $returnValue);
static $typeProp;
if (!isset($typeProp)) {
$typeProp = new \ReflectionProperty('phpDocumentor\Reflection\DocBlock\Tag\ReturnTag', 'type');
$typeProp->setAccessible(true);
}
// Set the changed content
$tag->setContent($returnValue . ' ' . $tag->getDescription());
$this->return = $returnValue;
}else{
$this->return = null;
//Get the return type and adjust them for better autocomplete
foreach ($phpdoc->getTags() as $tag) {
if ($tag instanceof ReturnTag) {
// Convert the keywords
$typeValue = static::convertKeywords($typeProp->getValue($tag));
$typeProp->setValue($tag, $typeValue);
// Get the expanded type
$typeValue = $tag->getType();
// Replace the interfaces
if (preg_match('/\bReturnTag$/', get_class($tag))) {
foreach ($this->interfaces as $interface => $real) {
$typeValue = preg_replace('/(^|\|)' . preg_quote($interface, '/') . '\b/', $real, $typeValue);
}
$this->return = $typeValue;
}
// Re-set the type
$typeProp->setValue($tag, $typeValue);
$tag->setDescription($tag->getDescription());
}
}
}
/**
* Convert keywwords that are incorrect.
* Convert keywords that are incorrect.
*
* @param string $string
* @return string
*/
protected function convertKeywords($string)
protected static function convertKeywords($string)
{
$string = str_replace('\Closure', 'Closure', $string);
$string = str_replace('Closure', '\Closure', $string);
$string = str_replace('dynamic', 'mixed', $string);
return $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);
}
/**
* Should the function return a value?
*
* @return bool
* @return bool|int
*/
public function shouldReturn()
{
if($this->return !== "void" && $this->method->name !== "__construct"){
return true;
if ($this->return !== 'void' && $this->method->name !== '__construct') {
return isset($this->return) ? true : 1;
}
return false;
@@ -249,17 +257,19 @@ class Method
/**
* Get the parameters and format them correctly
*
* @param $method
* @return array
* @param \ReflectionMethod $method
* @return void
*/
public function getParameters($method)
{
//Loop through the default values for paremeters, and make the correct output string
//Loop through the default values for parameters, and make the correct output string
$params = array();
$paramsWithDefault = array();
foreach ($method->getParameters() as $param) {
$paramStr = '$' . $param->getName();
$params[] = $paramStr;
if ($param->isOptional()) {
$default = $param->isDefaultValueAvailable() ? $param->getDefaultValue() : null;
if (is_bool($default)) {
@@ -275,6 +285,7 @@ class Method
}
$paramStr .= " = $default";
}
$paramsWithDefault[] = $paramStr;
}
@@ -284,7 +295,7 @@ class Method
/**
* @param \ReflectionMethod $reflectionMethod
* @return DocBlock
* @return DocBlock|null
*/
protected function getInheritDoc($reflectionMethod)
{
@@ -298,14 +309,24 @@ class Method
}
if ($method) {
$namespace = $method->getDeclaringClass()->getNamespaceName();
$phpdoc = new DocBlock($method, new Context($namespace));
$phpdoc = new DocBlock($method, new Context($namespace, static::getUseStatements($method->getDeclaringClass())));
if (strpos($phpdoc->getText(), '{@inheritdoc}') !== false) {
if (stripos($phpdoc->getText(), '{@inheritdoc}') !== false) {
//Not at the end yet, try another parent/interface..
return $this->getInheritDoc($method);
} else {
return $phpdoc;
}
}
return null;
}
protected static function getUseStatements(\ReflectionClass $class)
{
try {
return PhpReflection::getUseStatements($class);
} catch (\Exception $e) {
return array();
}
}
}
+166
View File
@@ -0,0 +1,166 @@
<?php namespace Barryvdh\LaravelIdeHelper;
/**
* PHP reflection helpers.
*
* This file is part of the Nette Framework (https://nette.org)
* Copyright (c) 2004 David Grudl (https://davidgrudl.com)
*
* @see https://github.com/nette/di/blob/v2.4/src/DI/PhpReflection.php
*/
class PhpReflection
{
/**
* Expands class name into full name.
*
* @param string $name
* @param \ReflectionClass $rc
* @return string full name
* @throws \InvalidArgumentException
*/
public static function expandClassName($name, \ReflectionClass $rc)
{
$lower = strtolower($name);
if (empty($name)) {
throw new \InvalidArgumentException('Class name must not be empty.');
} elseif (self::isBuiltinType($lower)) {
return $lower;
} elseif ($lower === 'self' || $lower === 'static' || $lower === '$this') {
return $rc->getName();
} elseif ($name[0] === '\\') { // fully qualified name
return ltrim($name, '\\');
}
$uses = self::getUseStatements($rc);
$parts = explode('\\', $name, 2);
if (isset($uses[$parts[0]])) {
$parts[0] = $uses[$parts[0]];
return implode('\\', $parts);
} elseif ($rc->inNamespace()) {
return $rc->getNamespaceName() . '\\' . $name;
} else {
return $name;
}
}
/**
* @param \ReflectionClass
* @return array of [alias => class]
*/
public static function getUseStatements(\ReflectionClass $class)
{
static $cache = array();
if (!isset($cache[$name = $class->getName()])) {
if ($class->isInternal() || !($code = @file_get_contents($class->getFileName()))) {
$cache[$name] = array();
} else {
$cache = self::parseUseStatements($code, $name) + $cache;
}
}
return $cache[$name];
}
/**
* @param string
* @return bool
*/
public static function isBuiltinType($type)
{
return in_array(strtolower($type), array('string', 'int', 'float', 'bool', 'array', 'callable'), true);
}
/**
* Parses PHP code.
*
* @param string $code
* @param string $forClass
* @return array of [class => [alias => class, ...]]
*/
public static function parseUseStatements($code, $forClass = null)
{
$tokens = token_get_all($code);
$namespace = $class = $classLevel = $level = null;
$res = $uses = array();
while ($token = current($tokens)) {
next($tokens);
switch (is_array($token) ? $token[0] : $token) {
case T_NAMESPACE:
$namespace = ltrim(self::fetch($tokens, array(T_STRING, T_NS_SEPARATOR)) . '\\', '\\');
$uses = array();
break;
case T_CLASS:
case T_INTERFACE:
case PHP_VERSION_ID < 50400 ? -1 : T_TRAIT:
if ($name = self::fetch($tokens, T_STRING)) {
$class = $namespace . $name;
$classLevel = $level + 1;
$res[$class] = $uses;
if ($class === $forClass) {
return $res;
}
}
break;
case T_USE:
while (!$class && ($name = self::fetch($tokens, array(T_STRING, T_NS_SEPARATOR)))) {
$name = ltrim($name, '\\');
if (self::fetch($tokens, '{')) {
while ($suffix = self::fetch($tokens, array(T_STRING, T_NS_SEPARATOR))) {
if (self::fetch($tokens, T_AS)) {
$uses[self::fetch($tokens, T_STRING)] = $name . $suffix;
} else {
$tmp = explode('\\', $suffix);
$uses[end($tmp)] = $name . $suffix;
}
if (!self::fetch($tokens, ',')) {
break;
}
}
} elseif (self::fetch($tokens, T_AS)) {
$uses[self::fetch($tokens, T_STRING)] = $name;
} else {
$tmp = explode('\\', $name);
$uses[end($tmp)] = $name;
}
if (!self::fetch($tokens, ',')) {
break;
}
}
break;
case T_CURLY_OPEN:
case T_DOLLAR_OPEN_CURLY_BRACES:
case '{':
$level++;
break;
case '}':
if ($level === $classLevel) {
$class = $classLevel = null;
}
$level--;
}
}
return $res;
}
private static function fetch(&$tokens, $take)
{
$res = null;
while ($token = current($tokens)) {
list($token, $s) = is_array($token) ? $token : array($token, $token);
if (in_array($token, (array)$take, true)) {
$res .= $s;
} elseif (!in_array($token, array(T_DOC_COMMENT, T_WHITESPACE, T_COMMENT), true)) {
break;
}
next($tokens);
}
return $res;
}
}
+17 -10
View File
@@ -2,38 +2,45 @@
/**
* An helper file for Laravel 4, to provide autocomplete information to your IDE
* Generated for Laravel <?= $version ?> on <?= date("Y-m-d") ?>.
* Generated for Laravel <?= $version ?> on <?= date('Y-m-d') ?>.
*
* @author Barry vd. Heuvel <[email protected]>
* @see https://github.com/barryvdh/laravel-ide-helper
*/
<?php foreach($namespaces as $namespace => $aliases): ?>
<?php foreach ($namespaces as $namespace => $aliases/* @var \Barryvdh\LaravelIdeHelper\Alias[] $aliases */): ?>
namespace <?= $namespace == '__root' ? '' : $namespace ?>{
<?php if ($namespace == '__root'): ?>
exit("This file should not be included, only analyzed by your IDE");
exit('This file should not be included, only analyzed by your IDE');
<?= $helpers ?>
<?php endif; ?>
<?php foreach ($aliases as $alias): ?>
<?php if (($cBase = class_basename($alias->getExtends())) != $alias->getExtends() && $cBase != $alias->getShortName()): ?>
/** @noinspection PhpUnnecessaryFullyQualifiedNameInspection */
<?php endif; ?>
<?= $alias->getClassType() ?> <?= $alias->getShortName() ?> <?= $alias->getExtends() ? 'extends ' . $alias->getExtends() : '' ?>{
<?php foreach ($alias->getMethods() as $method): ?>
<?= trim($method->getDocComment(' ')) ?>
public static function <?= $method->getName() ?>(<?= $method->getParamsWithDefault() ?>){<?php if($method->getDeclaringClass() !== $method->getRoot()): ?>
//Method inherited from <?= $method->getDeclaringClass() ?>
<?php if (($nParams = count($method->getDocParams())) > count($mParams = $method->getParamsWithDefault(false))): ?>
/** @noinspection PhpDocSignatureInspection */
<?php endif; ?>
<?php if ($docComment = str_replace("/**\n\t\t */", '', trim($method->getDocComment("\t\t", true)))): ?>
<?= $docComment ?>
<?php endif; ?>
public static function <?= $method->getName() ?>(<?= ($docComment && $nParams < count($mParams)) ? '/** @noinspection PhpDocSignatureInspection */' . implode(', /** @noinspection PhpDocSignatureInspection */', $mParams) : $method->getParamsWithDefault() ?>){
<?php if ($method->getDeclaringClass() !== $method->getRoot()): ?>
//Method inherited from <?= $method->getDeclaringClass() ?>
<?php endif; ?>
/** @noinspection PhpUnnecessaryFullyQualifiedNameInspection,PhpDynamicAsStaticMethodCallInspection<?= ($method->shouldReturn() === 1 ? ',PhpVoidFunctionResultUsedInspection' : '') . ($method->isDeprecated() ? ',PhpDeprecationInspection' : '') ?> */
<?= $method->shouldReturn() ? 'return ' : '' ?><?= $method->getRoot() ?>::<?= $method->getName() ?>(<?= $method->getParams() ?>);
}
<?php endforeach; ?>
}
<?php endforeach; ?>
}
<?php endforeach; ?>
+7 -7
View File
@@ -2,21 +2,21 @@
/**
* PhpStorm Meta file, to provide autocomplete information for PhpStorm
* Generated on <?= date("Y-m-d") ?>.
* Generated on <?= date('Y-m-d') ?>.
*
* @author Barry vd. Heuvel <[email protected]>
* @see https://github.com/barryvdh/laravel-ide-helper
*/
/** @noinspection PhpIllegalArrayKeyTypeInspection */
/** @noinspection PhpUnusedLocalVariableInspection */
/** @noinspection PhpUnnecessaryFullyQualifiedNameInspection */
/** @noinspection PhpIllegalArrayKeyTypeInspection,PhpUnusedLocalVariableInspection,PhpUnnecessaryFullyQualifiedNameInspection */
$STATIC_METHOD_TYPES = array(
<?php foreach ($methods as $method): ?>
<?= $method ?>('') => array(
<?= strpos($method, 'new ') === 0 ? $method : $method . '(\'\')' ?> => array(
<?php foreach ($bindings as $abstract => $class): ?>
'<?= $abstract ?>' instanceof \<?= $class ?>,
<?php endforeach ?> ),
<?= 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();
}
}