-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #34 from mediact/issue/33-proposal-fix
1.0.8 Issue/33 proposal fix
- Loading branch information
Showing
9 changed files
with
4,984 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
<?php | ||
/** | ||
* Copyright MediaCT. All rights reserved. | ||
* https://www.mediact.nl | ||
*/ | ||
|
||
namespace Mediact\DependencyGuard\Composer\Repository; | ||
|
||
use Composer\Repository\CompositeRepository; | ||
use Composer\Repository\RepositoryInterface; | ||
|
||
class DependentsResolver implements DependentsResolverInterface | ||
{ | ||
/** @var CompositeRepository */ | ||
private $repository; | ||
|
||
/** | ||
* Constructor. | ||
* | ||
* @param RepositoryInterface $repository | ||
*/ | ||
public function __construct(RepositoryInterface $repository) | ||
{ | ||
$this->repository = new CompositeRepository([$repository]); | ||
} | ||
|
||
/** | ||
* Resolves the dependents of the package. | ||
* | ||
* @param string $packageName | ||
* | ||
* @return array | ||
*/ | ||
public function resolve(string $packageName): array | ||
{ | ||
return $this->getDependents( | ||
$packageName, | ||
false, | ||
[] | ||
); | ||
} | ||
|
||
/** | ||
* Retrieves the dependents of a package in a recursive way. | ||
* | ||
* @param string $packageName | ||
* @param bool $returnContext | ||
* @param array $context | ||
* | ||
* @return array | ||
*/ | ||
private function getDependents( | ||
string $packageName, | ||
bool $returnContext, | ||
array $context = [] | ||
): array { | ||
if (!isset($context[$packageName])) { | ||
$context[$packageName] = $this->repository->getDependents( | ||
$packageName, | ||
null, | ||
false, | ||
false | ||
); | ||
|
||
foreach ($context[$packageName] as $key => $dependent) { | ||
$dependentContext = $this->getDependents($key, true, $context); | ||
$context = array_merge( | ||
$context, | ||
$dependentContext | ||
); | ||
|
||
$context[$packageName] = array_merge( | ||
$context[$packageName], | ||
$dependentContext[$key] | ||
); | ||
} | ||
} | ||
|
||
if (!$returnContext) { | ||
return $context[$packageName]; | ||
} | ||
|
||
return $context; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
<?php | ||
/** | ||
* Copyright MediaCT. All rights reserved. | ||
* https://www.mediact.nl | ||
*/ | ||
|
||
namespace Mediact\DependencyGuard\Composer\Repository; | ||
|
||
interface DependentsResolverInterface | ||
{ | ||
/** | ||
* Resolve dependents for a package. | ||
* | ||
* @param string $package | ||
* | ||
* @return array | ||
*/ | ||
public function resolve(string $package): array; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,226 @@ | ||
<?php | ||
/** | ||
* Copyright MediaCT. All rights reserved. | ||
* https://www.mediact.nl | ||
*/ | ||
|
||
namespace Mediact\DependencyGuard\Tests\Composer\Repository; | ||
|
||
use Composer\Repository\CompositeRepository; | ||
use Composer\Repository\RepositoryInterface; | ||
use Mediact\DependencyGuard\Composer\Repository\DependentsResolver; | ||
use PHPUnit\Framework\TestCase; | ||
use Composer\Package\Link; | ||
use Composer\Package\PackageInterface; | ||
use PHPUnit\Framework\MockObject\MockObject; | ||
|
||
/** | ||
* @coversDefaultClass \Mediact\DependencyGuard\Composer\Repository\DependentsResolver | ||
*/ | ||
class DependentResolverTest extends TestCase | ||
{ | ||
/** | ||
* @return void | ||
* | ||
* @covers ::__construct | ||
*/ | ||
public function testConstruct(): void | ||
{ | ||
$this->assertInstanceOf( | ||
DependentsResolver::class, | ||
new DependentsResolver( | ||
$this->createMock(RepositoryInterface::class) | ||
) | ||
); | ||
} | ||
|
||
/** | ||
* @dataProvider repositoryProvider | ||
* | ||
* @param RepositoryInterface $repository | ||
* @param string $packageName | ||
* @param array $expected | ||
* | ||
* @return void | ||
* | ||
* @covers ::resolve | ||
* @covers ::getDependents | ||
*/ | ||
public function testResolve( | ||
RepositoryInterface $repository, | ||
string $packageName, | ||
array $expected | ||
): void { | ||
$subject = new DependentsResolver($repository); | ||
$this->assertEquals( | ||
$expected, | ||
array_keys($subject->resolve($packageName)) | ||
); | ||
} | ||
|
||
/** | ||
* @dataProvider repositoryProvider | ||
* | ||
* @param RepositoryInterface $repository | ||
* @param string $packageName | ||
* | ||
* @return void | ||
* | ||
* @covers ::getDependents | ||
*/ | ||
public function testEqualBehaviour( | ||
RepositoryInterface $repository, | ||
string $packageName | ||
): void { | ||
$subject = new DependentsResolver($repository); | ||
$legacy = new CompositeRepository([$repository]); | ||
$this->assertEquals( | ||
$legacy->getDependents($packageName), | ||
$subject->resolve($packageName) | ||
); | ||
} | ||
|
||
/** | ||
* @param PackageInterface ...$packages | ||
* | ||
* @return RepositoryInterface | ||
*/ | ||
private function createRepository( | ||
PackageInterface ...$packages | ||
): RepositoryInterface { | ||
/** @var RepositoryInterface|MockObject $repository */ | ||
$repository = $this->createMock(RepositoryInterface::class); | ||
|
||
$repository | ||
->expects(self::any()) | ||
->method('getPackages') | ||
->willReturn($packages); | ||
|
||
return $repository; | ||
} | ||
|
||
/** | ||
* @param string $name | ||
* @param string ...$requires | ||
* | ||
* @return PackageInterface | ||
*/ | ||
private function createPackage( | ||
string $name, | ||
string ...$requires | ||
): PackageInterface { | ||
/** @var PackageInterface|MockObject $package */ | ||
$package = $this->createMock(PackageInterface::class); | ||
|
||
$package | ||
->expects(self::any()) | ||
->method('getName') | ||
->willReturn($name); | ||
|
||
$package | ||
->expects(self::any()) | ||
->method('getRequires') | ||
->willReturn( | ||
array_map( | ||
function (string $target) use ($name): Link { | ||
return $this->createLink($name, $target); | ||
}, | ||
$requires | ||
) | ||
); | ||
|
||
$package | ||
->expects(self::any()) | ||
->method( | ||
self::matchesRegularExpression( | ||
'/^get(DevRequires|Replaces|Conflicts)$/' | ||
) | ||
) | ||
->willReturn([]); | ||
|
||
return $package; | ||
} | ||
|
||
/** | ||
* @param string $source | ||
* @param string $target | ||
* | ||
* @return Link | ||
*/ | ||
private function createLink(string $source, string $target): Link | ||
{ | ||
/** @var Link|MockObject $link */ | ||
$link = $this->createMock(Link::class); | ||
|
||
$link | ||
->expects(self::any()) | ||
->method('getSource') | ||
->willReturn($source); | ||
|
||
$link | ||
->expects(self::any()) | ||
->method('getTarget') | ||
->willReturn($target); | ||
|
||
return $link; | ||
} | ||
|
||
/** | ||
* @return array | ||
*/ | ||
public function repositoryProvider(): array | ||
{ | ||
return [ | ||
[ | ||
$this->createRepository(), | ||
'foo/foo', | ||
[] | ||
], | ||
[ | ||
$this->createRepository( | ||
$this->createPackage('bar/bar') | ||
), | ||
'foo/foo', | ||
[] | ||
], | ||
[ | ||
$this->createRepository( | ||
$this->createPackage( | ||
'bar/bar', | ||
'foo/foo' | ||
) | ||
), | ||
'foo/foo', | ||
['bar/bar'] | ||
], | ||
[ | ||
$this->createRepository( | ||
$this->createPackage( | ||
'bar/bar' | ||
) | ||
), | ||
'foo/foo', | ||
[] | ||
], | ||
[ | ||
$this->createRepository( | ||
$this->createPackage( | ||
'bar/bar', | ||
'foo/foo', | ||
'baz/baz' | ||
), | ||
$this->createPackage( | ||
'baz/baz', | ||
'qux/qux' | ||
), | ||
$this->createPackage( | ||
'quz/quz', | ||
'foo/foo' | ||
) | ||
), | ||
'foo/foo', | ||
['bar/bar', 'quz/quz'] | ||
] | ||
]; | ||
} | ||
} |
Oops, something went wrong.