Skip to content

Commit

Permalink
Merge pull request #26 from mediact/issue/25
Browse files Browse the repository at this point in the history
1.0.5 - Fix issue #25 - Out of memory error
  • Loading branch information
sjokki authored Oct 12, 2018
2 parents 6a99bd2 + 8ab87a3 commit b42c529
Show file tree
Hide file tree
Showing 10 changed files with 589 additions and 38 deletions.
6 changes: 4 additions & 2 deletions src/Candidate/CandidateExtractor.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,12 @@
use Mediact\DependencyGuard\Php\SymbolInterface;
use Mediact\DependencyGuard\Php\SymbolIterator;
use Mediact\DependencyGuard\Php\SymbolIteratorInterface;
use Roave\BetterReflection\Reflection\ReflectionClass;
use Mediact\DependencyGuard\Reflection\ReflectionTrait;

class CandidateExtractor implements CandidateExtractorInterface
{
use ReflectionTrait;

/**
* Extract violation candidates from the given Composer instance and symbols.
*
Expand Down Expand Up @@ -100,7 +102,7 @@ private function extractPackage(
$name = $symbol->getName();

if (!array_key_exists($name, $packagesPerSymbol)) {
$reflection = ReflectionClass::createFromName($name);
$reflection = $this->getClassReflection($name);
$file = $reflection->getFileName();

// This happens for symbols in the current package.
Expand Down
6 changes: 4 additions & 2 deletions src/Php/Filter/UserDefinedSymbolFilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@

namespace Mediact\DependencyGuard\Php\Filter;

use Roave\BetterReflection\Reflection\ReflectionClass;
use Mediact\DependencyGuard\Reflection\ReflectionTrait;
use Throwable;

class UserDefinedSymbolFilter implements SymbolFilterInterface
{
use ReflectionTrait;

/**
* Filter the given symbol.
*
Expand All @@ -21,7 +23,7 @@ class UserDefinedSymbolFilter implements SymbolFilterInterface
public function __invoke(string $symbol): bool
{
try {
$reflection = ReflectionClass::createFromName($symbol);
$reflection = $this->getClassReflection($symbol);
} catch (Throwable $e) {
return false;
}
Expand Down
4 changes: 3 additions & 1 deletion src/Php/SymbolExtractor.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ public function extract(
$symbols = [];

foreach ($files as $file) {
$parser = clone $this->parser;

try {
$size = $file->getSize();
$handle = $file->openFile('rb');
Expand All @@ -57,7 +59,7 @@ public function extract(
continue;
}

$statements = $this->parser->parse($contents);
$statements = $parser->parse($contents);
} catch (Error $e) {
// Either not a file, file is not readable, not a PHP file or
// the broken file should be detected by other tooling entirely.
Expand Down
44 changes: 44 additions & 0 deletions src/Reflection/ReflectionTrait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php
/**
* Copyright MediaCT. All rights reserved.
* https://www.mediact.nl
*/

namespace Mediact\DependencyGuard\Reflection;

use Roave\BetterReflection\BetterReflection;
use Roave\BetterReflection\Reflection\ReflectionClass;

trait ReflectionTrait
{
/** @var BetterReflection */
private static $reflectionEnvironment;

/**
* Get the current reflection environment.
*
* @return BetterReflection
*/
private static function getReflectionEnvironment(): BetterReflection
{
if (self::$reflectionEnvironment === null) {
self::$reflectionEnvironment = new BetterReflection();
}

return self::$reflectionEnvironment;
}

/**
* Get the reflection for the given class name.
*
* @param string $className
*
* @return ReflectionClass
*/
public function getClassReflection(string $className): ReflectionClass
{
return static::getReflectionEnvironment()
->classReflector()
->reflect($className);
}
}
33 changes: 33 additions & 0 deletions tests/Reflection/ReflectionTraitTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php
/**
* Copyright MediaCT. All rights reserved.
* https://www.mediact.nl
*/

namespace Mediact\DependencyGuard\Tests\Reflection;

use PHPUnit\Framework\TestCase;
use Mediact\DependencyGuard\Reflection\ReflectionTrait;
use Roave\BetterReflection\Reflection\ReflectionClass;

/**
* @coversDefaultClass \Mediact\DependencyGuard\Reflection\ReflectionTrait
*/
class ReflectionTraitTest extends TestCase
{
/**
* @return void
* @covers ::getClassReflection
* @covers ::getReflectionEnvironment
*/
public function testGetClassReflection(): void
{
/** @var ReflectionTrait $subject */
$subject = $this->getMockForTrait(ReflectionTrait::class);

$this->assertInstanceOf(
ReflectionClass::class,
$subject->getClassReflection(__CLASS__)
);
}
}
84 changes: 84 additions & 0 deletions tests/Regression/ComposerTestEnvironmentTrait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<?php
/**
* Copyright MediaCT. All rights reserved.
* https://www.mediact.nl
*/

namespace Mediact\DependencyGuard\Tests\Regression;

use ReflectionObject;
use Symfony\Component\Process\Process;
use Composer\Util\Filesystem;

trait ComposerTestEnvironmentTrait
{
/** @var string */
private $workingDirectory;

/**
* @return string
*/
private function getWorkingDirectory(): string
{
if ($this->workingDirectory === null) {
$reflection = new ReflectionObject($this);

$this->workingDirectory = dirname($reflection->getFileName());
}

return $this->workingDirectory;
}

/**
* Create a composer process for the given command.
*
* @param string $command
* @param string ...$arguments
*
* @return Process
*/
protected function createComposerProcess(
string $command,
string ...$arguments
): Process {
return new Process(
array_merge(
[
trim(`which composer` ?? `which composer.phar`),
$command,
],
$arguments,
[
'--quiet',
'--working-dir',
$this->getWorkingDirectory()
]
)
);
}

/**
* @return void
*/
public function setUp(): void
{
$process = $this->createComposerProcess('install');

if ($process->run() !== 0) {
self::markTestSkipped(
$process->getErrorOutput()
);
}
}

/**
* @return void
*/
public function tearDown(): void
{
$filesystem = new Filesystem();
$filesystem->removeDirectory(
$this->getWorkingDirectory() . DIRECTORY_SEPARATOR . 'vendor'
);
}
}
35 changes: 2 additions & 33 deletions tests/Regression/Issue21/Issue21Test.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

namespace Mediact\DependencyGuard\Tests\Regression\Issue21;

use Composer\Util\Filesystem;
use Mediact\DependencyGuard\Tests\Regression\ComposerTestEnvironmentTrait;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Process\Process;

Expand All @@ -11,27 +11,7 @@
*/
class Issue21Test extends TestCase
{
/**
* @return void
*/
public function setUp(): void
{
$process = new Process(
[
trim(`which composer` ?? `which composer.phar`),
'install',
'--quiet',
'--working-dir',
__DIR__
]
);

if ($process->run() !== 0) {
self::markTestSkipped(
$process->getErrorOutput()
);
}
}
use ComposerTestEnvironmentTrait;

/**
* @return void
Expand All @@ -51,15 +31,4 @@ public function testNoFatalsBecauseOfConflicts(): void

self::assertNotContains('Fatal error:', $process->getErrorOutput());
}

/**
* @return void
*/
public function tearDown(): void
{
$filesystem = new Filesystem();
$filesystem->removeDirectory(
__DIR__ . DIRECTORY_SEPARATOR . 'vendor'
);
}
}
45 changes: 45 additions & 0 deletions tests/Regression/Issue25/Issue25Test.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php
/**
* Copyright MediaCT. All rights reserved.
* https://www.mediact.nl
*/

namespace Mediact\DependencyGuard\Tests\Regression\Issue25;

use Mediact\DependencyGuard\Tests\Regression\ComposerTestEnvironmentTrait;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Process\Process;

/**
* @see https://github.com/mediact/dependency-guard/issues/25
*/
class Issue25Test extends TestCase
{
use ComposerTestEnvironmentTrait;

/**
* @return void
* @coversNothing
*/
public function testNoOutOfMemoryError(): void
{
$process = new Process(
[
PHP_BINARY,
'-d',
'memory_limit=25M',
'../../../bin/dependency-guard'
],
__DIR__
);

// The exit code of the process is of no concern to the issue.
$process->run();

$this->assertNotContains(
'Allowed memory size',
$process->getErrorOutput(),
'Dependency guard ran out of memory.'
);
}
}
11 changes: 11 additions & 0 deletions tests/Regression/Issue25/composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"name": "issue25/test",
"require": {
"php-twinfield/twinfield": "dev-master#04c1b248efc9268db2ad173a9305fa9c21970df8"
},
"autoload": {
"psr-4": {
"PhpTwinfield\\": "vendor/php-twinfield/twinfield/src"
}
}
}
Loading

0 comments on commit b42c529

Please sign in to comment.