Skip to content

Commit

Permalink
Scope PHP binaries (#69)
Browse files Browse the repository at this point in the history
  • Loading branch information
theofidry authored Jul 5, 2017
1 parent fd91f4f commit d6930c6
Show file tree
Hide file tree
Showing 2 changed files with 123 additions and 9 deletions.
23 changes: 21 additions & 2 deletions src/Scoper/PhpScoper.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,11 @@
final class PhpScoper implements Scoper
{
/** @internal */
const FILE_PATTERN = '/.*\.php$/';
const FILE_PATH_PATTERN = '/.*\.php$/';
/** @internal */
const NOT_FILE_BINARY = '/\..+?$/';
/** @internal */
const PHP_BINARY = '/^#!.+?php.*\n{1,}<\?php/';

private $parser;
private $decoratedScoper;
Expand All @@ -51,7 +55,7 @@ public function __construct(Parser $parser, Scoper $decoratedScoper)
*/
public function scope(string $filePath, string $prefix): string
{
if (1 !== preg_match(self::FILE_PATTERN, $filePath)) {
if (false === $this->isPhpFile($filePath)) {
return $this->decoratedScoper->scope($filePath, $prefix);
}

Expand All @@ -67,6 +71,21 @@ public function scope(string $filePath, string $prefix): string
return $prettyPrinter->prettyPrintFile($statements)."\n";
}

private function isPhpFile(string $filePath): bool
{
if (1 === preg_match(self::FILE_PATH_PATTERN, $filePath)) {
return true;
}

if (1 === preg_match(self::NOT_FILE_BINARY, basename($filePath))) {
return false;
}

$content = file_get_contents($filePath);

return 1 === preg_match(self::PHP_BINARY, $content);
}

private function createTraverser(string $prefix): NodeTraverserInterface
{
$traverser = new NodeTraverser();
Expand Down
109 changes: 102 additions & 7 deletions tests/Scoper/PhpScoperTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,16 @@ class PhpScoperTest extends TestCase
*/
private $tmp;

/**
* @var Scoper|ObjectProphecy
*/
private $decoratedScoperProphecy;

/**
* @var Scoper
*/
private $decoratedScoper;

/**
* @inheritdoc
*/
Expand All @@ -60,6 +70,9 @@ public function setUp()
$this->tmp = make_tmp_dir('scoper', __CLASS__);
}

$this->decoratedScoperProphecy = $this->prophesize(Scoper::class);
$this->decoratedScoper = $this->decoratedScoperProphecy->reveal();

chdir($this->tmp);
}

Expand All @@ -78,32 +91,114 @@ public function test_is_a_Scoper()
$this->assertTrue(is_a(PhpScoper::class, Scoper::class, true));
}

public function test_can_scope_a_PHP_file()
{
$prefix = 'Humbug';

$filePath = escape_path($this->tmp.'/file.php');

$content = <<<'PHP'
echo "Humbug!";
PHP;

touch($filePath);
file_put_contents($filePath, $content);

$expected = <<<'PHP'
echo "Humbug!";

PHP;

$actual = $this->scoper->scope($filePath, $prefix);

$this->assertSame($expected, $actual);
}

public function test_does_not_scope_file_if_is_not_a_PHP_file()
{
$filePath = 'file.yaml';
$prefix = 'Humbug';

/** @var Scoper|ObjectProphecy $decoratedScoperProphecy */
$decoratedScoperProphecy = $this->prophesize(Scoper::class);
$decoratedScoperProphecy
$this->decoratedScoperProphecy
->scope($filePath, $prefix)
->willReturn(
$expected = 'Scoped content'
)
;

$scoper = new PhpScoper(
new FakeParser(),
$this->decoratedScoper
);

$actual = $scoper->scope($filePath, $prefix);

$this->assertSame($expected, $actual);

$this->decoratedScoperProphecy->scope(Argument::cetera())->shouldHaveBeenCalledTimes(1);
}

public function test_can_scope_PHP_binary_files()
{
$prefix = 'Humbug';

$filePath = escape_path($this->tmp.'/hello');

$content = <<<'PHP'
#!/usr/bin/env php
<?php
echo "Hello world";
PHP;

touch($filePath);
file_put_contents($filePath, $content);

$expected = <<<'PHP'
#!/usr/bin/env php
<?php
echo "Hello world";

PHP;

$actual = $this->scoper->scope($filePath, $prefix);

$this->assertSame($expected, $actual);
}

public function test_does_not_scope_a_non_PHP_binary_files()
{
$prefix = 'Humbug';

$filePath = escape_path($this->tmp.'/hello');

$content = <<<'PHP'
#!/usr/bin/env bash
<?php
echo "Hello world";
PHP;

touch($filePath);
file_put_contents($filePath, $content);

$this->decoratedScoperProphecy
->scope($filePath, $prefix)
->willReturn(
$expected = 'Scoped content'
)
;
/** @var Scoper $decoratedScoper */
$decoratedScoper = $decoratedScoperProphecy->reveal();

$scoper = new PhpScoper(
new FakeParser(),
$decoratedScoper
$this->decoratedScoper
);

$actual = $scoper->scope($filePath, $prefix);

$this->assertSame($expected, $actual);

$decoratedScoperProphecy->scope(Argument::cetera())->shouldHaveBeenCalledTimes(1);
$this->decoratedScoperProphecy->scope(Argument::cetera())->shouldHaveBeenCalledTimes(1);
}

public function test_cannot_scope_an_invalid_PHP_file()
Expand Down

0 comments on commit d6930c6

Please sign in to comment.