Skip to content
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

#5 #6 detected property/method visibility/existence change #30

Merged
merged 5 commits into from
Apr 15, 2018
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Next Next commit
#5 PropertyVisibilityReduced BC break detector
  • Loading branch information
Ocramius committed Apr 15, 2018
commit f0683e35dbe5be60c10c01e031d5384a2d1d14e5
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<?php

declare(strict_types=1);

namespace Roave\ApiCompare\Comparator\BackwardsCompatibility\ClassBased;

use Assert\Assert;
use Roave\ApiCompare\Change;
use Roave\ApiCompare\Changes;
use Roave\BetterReflection\Reflection\ReflectionClass;
use Roave\BetterReflection\Reflection\ReflectionProperty;

final class PropertyVisibilityReduced implements ClassBased
{
private const VISIBILITY_PRIVATE = 'private';

private const VISIBILITY_PROTECTED = 'protected';

private const VISIBILITY_PUBLIC = 'public';

public function compare(ReflectionClass $fromClass, ReflectionClass $toClass) : Changes
{
Assert::that($fromClass->getName())->same($toClass->getName());

$visibilitiesFrom = $this->propertyVisibilities($fromClass);
$visibilitiesTo = $this->propertyVisibilities($toClass);

$affectedVisibilities = array_filter(
array_combine(
array_keys(array_intersect_key($visibilitiesFrom, $visibilitiesTo)),
array_map(
function (string $visibilityFrom, string $visibilityTo) : array {
return [$visibilityFrom, $visibilityTo];
},
array_intersect_key($visibilitiesFrom, $visibilitiesTo),
array_intersect_key($visibilitiesTo, $visibilitiesFrom)
)
),
function (array $visibilities) : bool {
// Note: works because public, protected and private are (luckily) sortable
return $visibilities[0] > $visibilities[1];
}
);

return Changes::fromArray(array_values(array_map(function (string $propertyName, array $visibilities) use (
$fromClass
) : Change {
return Change::removed(
sprintf(
'Property %s#%s changed visibility from %s to %s',
$fromClass->getName(),
$propertyName,
$visibilities[0],
$visibilities[1]
),
true
);
}, array_keys($affectedVisibilities), $affectedVisibilities)));
}

/** @return string[] */
private function propertyVisibilities(ReflectionClass $class) : array
{
return array_map(function (ReflectionProperty $property) : string {
if ($property->isPublic()) {
return self::VISIBILITY_PUBLIC;
}

if ($property->isProtected()) {
return self::VISIBILITY_PROTECTED;
}

return self::VISIBILITY_PRIVATE;
}, $class->getProperties());
}
}
17 changes: 17 additions & 0 deletions test/asset/api/new/ClassWithPropertyVisibilitiesBeingChanged.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php
declare(strict_types=1);

namespace RoaveTestAsset;

class ClassWithPropertyVisibilitiesBeingChanged
{
public $publicMaintainedPublic;
protected $publicReducedToProtected;
private $publicReducedToPrivate;
protected $protectedMaintainedProtected;
private $protectedReducedToPrivate;
public $protectedIncreasedToPublic;
private $privateMaintainedPrivate;
protected $privateIncreasedToProtected;
public $privateIncreasedToPublic;
}
17 changes: 17 additions & 0 deletions test/asset/api/old/ClassWithPropertyVisibilitiesBeingChanged.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php
declare(strict_types=1);

namespace RoaveTestAsset;

class ClassWithPropertyVisibilitiesBeingChanged
{
public $publicMaintainedPublic;
public $publicReducedToProtected;
public $publicReducedToPrivate;
protected $protectedMaintainedProtected;
protected $protectedReducedToPrivate;
protected $protectedIncreasedToPublic;
private $privateMaintainedPrivate;
private $privateIncreasedToProtected;
private $privateIncreasedToPublic;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?php

declare(strict_types=1);

namespace RoaveTest\ApiCompare\Comparator\BackwardsCompatibility\ClassBased;

use PHPUnit\Framework\TestCase;
use Roave\ApiCompare\Change;
use Roave\ApiCompare\Comparator\BackwardsCompatibility\ClassBased\PropertyVisibilityReduced;
use Roave\BetterReflection\BetterReflection;
use Roave\BetterReflection\Reflection\ReflectionClass;
use Roave\BetterReflection\Reflector\ClassReflector;
use Roave\BetterReflection\SourceLocator\Type\SingleFileSourceLocator;

final class PropertyVisibilityReducedTest extends TestCase
{
/**
* @dataProvider classesToBeTested
*
* @param string[] $expectedMessages
*/
public function testDiffs(
ReflectionClass $fromClass,
ReflectionClass $toClass,
array $expectedMessages
) : void {
$changes = (new PropertyVisibilityReduced())
->compare($fromClass, $toClass);

self::assertSame(
$expectedMessages,
array_map(function (Change $change) : string {
return $change->__toString();
}, iterator_to_array($changes))
);
}

/** @return (string[]|ReflectionClass)[][] */
public function classesToBeTested() : array
{
$locator = (new BetterReflection())->astLocator();

return [
'RoaveTestAsset\\ClassWithPropertyVisibilitiesBeingChanged' => [
(new ClassReflector(new SingleFileSourceLocator(
__DIR__ . '/../../../../asset/api/old/ClassWithPropertyVisibilitiesBeingChanged.php',
$locator
)))->reflect('RoaveTestAsset\\ClassWithPropertyVisibilitiesBeingChanged'),
(new ClassReflector(new SingleFileSourceLocator(
__DIR__ . '/../../../../asset/api/new/ClassWithPropertyVisibilitiesBeingChanged.php',
$locator
)))->reflect('RoaveTestAsset\\ClassWithPropertyVisibilitiesBeingChanged'),
[
'[BC] REMOVED: Property RoaveTestAsset\ClassWithPropertyVisibilitiesBeingChanged#publicReducedToProtected changed visibility from public to protected',
'[BC] REMOVED: Property RoaveTestAsset\ClassWithPropertyVisibilitiesBeingChanged#publicReducedToPrivate changed visibility from public to private',
'[BC] REMOVED: Property RoaveTestAsset\ClassWithPropertyVisibilitiesBeingChanged#protectedReducedToPrivate changed visibility from protected to private',
],
],
];
}
}