mirror of
https://github.com/pestphp/pest.git
synced 2026-03-06 07:47:22 +01:00
fix: properties and methods documented
This commit is contained in:
@ -30,6 +30,7 @@ use Pest\Expectations\HigherOrderExpectation;
|
|||||||
use Pest\Expectations\OppositeExpectation;
|
use Pest\Expectations\OppositeExpectation;
|
||||||
use Pest\Matchers\Any;
|
use Pest\Matchers\Any;
|
||||||
use Pest\Support\ExpectationPipeline;
|
use Pest\Support\ExpectationPipeline;
|
||||||
|
use Pest\Support\Reflection;
|
||||||
use PHPUnit\Architecture\Elements\ObjectDescription;
|
use PHPUnit\Architecture\Elements\ObjectDescription;
|
||||||
use PHPUnit\Framework\ExpectationFailedException;
|
use PHPUnit\Framework\ExpectationFailedException;
|
||||||
use ReflectionEnum;
|
use ReflectionEnum;
|
||||||
@ -471,7 +472,7 @@ final class Expectation
|
|||||||
$this,
|
$this,
|
||||||
fn (ObjectDescription $object): bool => isset($object->reflectionClass) === false
|
fn (ObjectDescription $object): bool => isset($object->reflectionClass) === false
|
||||||
|| array_filter(
|
|| array_filter(
|
||||||
$object->reflectionClass->getMethods(),
|
Reflection::getMethodsFromReflectionClass($object->reflectionClass),
|
||||||
fn (ReflectionMethod $method): bool => (enum_exists($object->name) === false || in_array($method->name, ['from', 'tryFrom', 'cases'], true) === false)
|
fn (ReflectionMethod $method): bool => (enum_exists($object->name) === false || in_array($method->name, ['from', 'tryFrom', 'cases'], true) === false)
|
||||||
&& realpath($method->getFileName() ?: '/') === realpath($object->path) // @phpstan-ignore-line
|
&& realpath($method->getFileName() ?: '/') === realpath($object->path) // @phpstan-ignore-line
|
||||||
&& $method->getDocComment() === false,
|
&& $method->getDocComment() === false,
|
||||||
@ -490,7 +491,7 @@ final class Expectation
|
|||||||
$this,
|
$this,
|
||||||
fn (ObjectDescription $object): bool => isset($object->reflectionClass) === false
|
fn (ObjectDescription $object): bool => isset($object->reflectionClass) === false
|
||||||
|| array_filter(
|
|| array_filter(
|
||||||
$object->reflectionClass->getProperties(),
|
Reflection::getPropertiesFromReflectionClass($object->reflectionClass),
|
||||||
fn (ReflectionProperty $property): bool => (enum_exists($object->name) === false || in_array($property->name, ['value', 'name'], true) === false)
|
fn (ReflectionProperty $property): bool => (enum_exists($object->name) === false || in_array($property->name, ['value', 'name'], true) === false)
|
||||||
&& realpath($property->getDeclaringClass()->getFileName() ?: '/') === realpath($object->path) // @phpstan-ignore-line
|
&& realpath($property->getDeclaringClass()->getFileName() ?: '/') === realpath($object->path) // @phpstan-ignore-line
|
||||||
&& $property->isPromoted() === false
|
&& $property->isPromoted() === false
|
||||||
|
|||||||
@ -18,6 +18,7 @@ use Pest\Exceptions\InvalidExpectation;
|
|||||||
use Pest\Expectation;
|
use Pest\Expectation;
|
||||||
use Pest\Support\Arr;
|
use Pest\Support\Arr;
|
||||||
use Pest\Support\Exporter;
|
use Pest\Support\Exporter;
|
||||||
|
use Pest\Support\Reflection;
|
||||||
use PHPUnit\Architecture\Elements\ObjectDescription;
|
use PHPUnit\Architecture\Elements\ObjectDescription;
|
||||||
use PHPUnit\Framework\AssertionFailedError;
|
use PHPUnit\Framework\AssertionFailedError;
|
||||||
use PHPUnit\Framework\ExpectationFailedException;
|
use PHPUnit\Framework\ExpectationFailedException;
|
||||||
@ -107,7 +108,7 @@ final class OppositeExpectation
|
|||||||
$this->original,
|
$this->original,
|
||||||
fn (ObjectDescription $object): bool => isset($object->reflectionClass) === false
|
fn (ObjectDescription $object): bool => isset($object->reflectionClass) === false
|
||||||
|| array_filter(
|
|| array_filter(
|
||||||
$object->reflectionClass->getMethods(),
|
Reflection::getMethodsFromReflectionClass($object->reflectionClass),
|
||||||
fn (ReflectionMethod $method): bool => (enum_exists($object->name) === false || in_array($method->name, ['from', 'tryFrom', 'cases'], true) === false)
|
fn (ReflectionMethod $method): bool => (enum_exists($object->name) === false || in_array($method->name, ['from', 'tryFrom', 'cases'], true) === false)
|
||||||
&& realpath($method->getFileName() ?: '/') === realpath($object->path) // @phpstan-ignore-line
|
&& realpath($method->getFileName() ?: '/') === realpath($object->path) // @phpstan-ignore-line
|
||||||
&& $method->getDocComment() !== false,
|
&& $method->getDocComment() !== false,
|
||||||
@ -126,7 +127,7 @@ final class OppositeExpectation
|
|||||||
$this->original,
|
$this->original,
|
||||||
fn (ObjectDescription $object): bool => isset($object->reflectionClass) === false
|
fn (ObjectDescription $object): bool => isset($object->reflectionClass) === false
|
||||||
|| array_filter(
|
|| array_filter(
|
||||||
$object->reflectionClass->getProperties(),
|
Reflection::getPropertiesFromReflectionClass($object->reflectionClass),
|
||||||
fn (ReflectionProperty $property): bool => (enum_exists($object->name) === false || in_array($property->name, ['value', 'name'], true) === false)
|
fn (ReflectionProperty $property): bool => (enum_exists($object->name) === false || in_array($property->name, ['value', 'name'], true) === false)
|
||||||
&& realpath($property->getDeclaringClass()->getFileName() ?: '/') === realpath($object->path) // @phpstan-ignore-line
|
&& realpath($property->getDeclaringClass()->getFileName() ?: '/') === realpath($object->path) // @phpstan-ignore-line
|
||||||
&& $property->isPromoted() === false
|
&& $property->isPromoted() === false
|
||||||
|
|||||||
@ -11,6 +11,7 @@ use Pest\TestSuite;
|
|||||||
use ReflectionClass;
|
use ReflectionClass;
|
||||||
use ReflectionException;
|
use ReflectionException;
|
||||||
use ReflectionFunction;
|
use ReflectionFunction;
|
||||||
|
use ReflectionMethod;
|
||||||
use ReflectionNamedType;
|
use ReflectionNamedType;
|
||||||
use ReflectionParameter;
|
use ReflectionParameter;
|
||||||
use ReflectionProperty;
|
use ReflectionProperty;
|
||||||
@ -213,4 +214,74 @@ final class Reflection
|
|||||||
{
|
{
|
||||||
return (new ReflectionFunction($function))->getStaticVariables()[$key] ?? null;
|
return (new ReflectionFunction($function))->getStaticVariables()[$key] ?? null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the properties from the given reflection class.
|
||||||
|
*
|
||||||
|
* Used by `expect()->toHavePropertiesDocumented()`.
|
||||||
|
*
|
||||||
|
* @param ReflectionClass<object> $reflectionClass
|
||||||
|
* @return array<int, ReflectionProperty>
|
||||||
|
*/
|
||||||
|
public static function getPropertiesFromReflectionClass(ReflectionClass $reflectionClass): array
|
||||||
|
{
|
||||||
|
$getProperties = fn (ReflectionClass $reflectionClass): array => array_filter(
|
||||||
|
array_map(
|
||||||
|
fn (ReflectionProperty $property): \ReflectionProperty => $property,
|
||||||
|
$reflectionClass->getProperties(),
|
||||||
|
), fn (ReflectionProperty $property): bool => $property->getDeclaringClass()->getName() === $reflectionClass->getName(),
|
||||||
|
);
|
||||||
|
|
||||||
|
$propertiesFromTraits = [];
|
||||||
|
foreach ($reflectionClass->getTraits() as $trait) {
|
||||||
|
$propertiesFromTraits = array_merge($propertiesFromTraits, $getProperties($trait));
|
||||||
|
}
|
||||||
|
|
||||||
|
$propertiesFromTraits = array_map(
|
||||||
|
fn (ReflectionProperty $property): string => $property->getName(),
|
||||||
|
$propertiesFromTraits,
|
||||||
|
);
|
||||||
|
|
||||||
|
return array_values(
|
||||||
|
array_filter(
|
||||||
|
$getProperties($reflectionClass),
|
||||||
|
fn (ReflectionProperty $property): bool => ! in_array($property->getName(), $propertiesFromTraits, true),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the methods from the given reflection class.
|
||||||
|
*
|
||||||
|
* Used by `expect()->toHaveMethodsDocumented()`.
|
||||||
|
*
|
||||||
|
* @param ReflectionClass<object> $reflectionClass
|
||||||
|
* @return array<int, ReflectionMethod>
|
||||||
|
*/
|
||||||
|
public static function getMethodsFromReflectionClass(ReflectionClass $reflectionClass): array
|
||||||
|
{
|
||||||
|
$getMethods = fn (ReflectionClass $reflectionClass): array => array_filter(
|
||||||
|
array_map(
|
||||||
|
fn (ReflectionMethod $method): \ReflectionMethod => $method,
|
||||||
|
$reflectionClass->getMethods(),
|
||||||
|
), fn (ReflectionMethod $method): bool => $method->getDeclaringClass()->getName() === $reflectionClass->getName(),
|
||||||
|
);
|
||||||
|
|
||||||
|
$methodsFromTraits = [];
|
||||||
|
foreach ($reflectionClass->getTraits() as $trait) {
|
||||||
|
$methodsFromTraits = array_merge($methodsFromTraits, $getMethods($trait));
|
||||||
|
}
|
||||||
|
|
||||||
|
$methodsFromTraits = array_map(
|
||||||
|
fn (ReflectionMethod $method): string => $method->getName(),
|
||||||
|
$methodsFromTraits,
|
||||||
|
);
|
||||||
|
|
||||||
|
return array_values(
|
||||||
|
array_filter(
|
||||||
|
$getMethods($reflectionClass),
|
||||||
|
fn (ReflectionMethod $method): bool => ! in_array($method->getName(), $methodsFromTraits, true),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1429,6 +1429,8 @@
|
|||||||
PASS Tests\Unit\Support\Reflection
|
PASS Tests\Unit\Support\Reflection
|
||||||
✓ it gets file name from closure
|
✓ it gets file name from closure
|
||||||
✓ it gets property values
|
✓ it gets property values
|
||||||
|
✓ it gets properties from classes
|
||||||
|
✓ it gets methods from classes
|
||||||
|
|
||||||
PASS Tests\Unit\Support\Str
|
PASS Tests\Unit\Support\Str
|
||||||
✓ it evaluates the code with ('version()', '__pest_evaluable_version__')
|
✓ it evaluates the code with ('version()', '__pest_evaluable_version__')
|
||||||
@ -1535,4 +1537,4 @@
|
|||||||
WARN Tests\Visual\Version
|
WARN Tests\Visual\Version
|
||||||
- visual snapshot of help command output
|
- visual snapshot of help command output
|
||||||
|
|
||||||
Tests: 2 deprecated, 4 warnings, 5 incomplete, 2 notices, 13 todos, 24 skipped, 1074 passed (2626 assertions)
|
Tests: 2 deprecated, 4 warnings, 5 incomplete, 2 notices, 13 todos, 24 skipped, 1076 passed (2628 assertions)
|
||||||
@ -18,3 +18,59 @@ it('gets property values', function () {
|
|||||||
|
|
||||||
expect($value)->toBe('bar');
|
expect($value)->toBe('bar');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
class Asd
|
||||||
|
{
|
||||||
|
protected $foo = 'bar';
|
||||||
|
|
||||||
|
public function getFoo()
|
||||||
|
{
|
||||||
|
return $this->foo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
trait Zxc
|
||||||
|
{
|
||||||
|
protected $baz = 'qux';
|
||||||
|
|
||||||
|
public function getBaz()
|
||||||
|
{
|
||||||
|
return $this->baz;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Qwe extends Asd
|
||||||
|
{
|
||||||
|
use Zxc;
|
||||||
|
|
||||||
|
protected $bar = 'baz';
|
||||||
|
|
||||||
|
public function getBar()
|
||||||
|
{
|
||||||
|
return $this->bar;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
it('gets properties from classes', function () {
|
||||||
|
$reflectionClass = new ReflectionClass(Qwe::class);
|
||||||
|
|
||||||
|
$properties = Reflection::getPropertiesFromReflectionClass($reflectionClass);
|
||||||
|
|
||||||
|
$properties = array_map(fn ($property) => $property->getName(), $properties);
|
||||||
|
|
||||||
|
expect($properties)->toBe([
|
||||||
|
'bar',
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('gets methods from classes', function () {
|
||||||
|
$reflectionClass = new ReflectionClass(Qwe::class);
|
||||||
|
|
||||||
|
$methods = Reflection::getMethodsFromReflectionClass($reflectionClass);
|
||||||
|
|
||||||
|
$methods = array_map(fn ($method) => $method->getName(), $methods);
|
||||||
|
|
||||||
|
expect($methods)->toBe([
|
||||||
|
'getBar',
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|||||||
@ -16,7 +16,7 @@ $run = function () {
|
|||||||
|
|
||||||
test('parallel', function () use ($run) {
|
test('parallel', function () use ($run) {
|
||||||
expect($run('--exclude-group=integration'))
|
expect($run('--exclude-group=integration'))
|
||||||
->toContain('Tests: 2 deprecated, 4 warnings, 5 incomplete, 2 notices, 13 todos, 19 skipped, 1060 passed (2594 assertions)')
|
->toContain('Tests: 2 deprecated, 4 warnings, 5 incomplete, 2 notices, 13 todos, 19 skipped, 1062 passed (2596 assertions)')
|
||||||
->toContain('Parallel: 3 processes');
|
->toContain('Parallel: 3 processes');
|
||||||
})->skipOnWindows();
|
})->skipOnWindows();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user