Skip to content

Commit

Permalink
fix issue GH-268
Browse files Browse the repository at this point in the history
  • Loading branch information
llaville committed Jul 9, 2020
1 parent b2625df commit 3221451
Show file tree
Hide file tree
Showing 6 changed files with 202 additions and 1 deletion.
16 changes: 15 additions & 1 deletion src/Bartlett/CompatInfo/Analyser/CompatibilityAnalyser.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

namespace Bartlett\CompatInfo\Analyser;

use Bartlett\CompatInfo\Sniffs\PHP\DeclareSniff;
use Bartlett\CompatInfo\Util\Database;
use Bartlett\CompatInfo\Collection\ReferenceCollection;
use Bartlett\CompatInfo\PhpParser\ConditionalCodeNodeProcessor;
Expand Down Expand Up @@ -70,7 +71,7 @@ public function __construct()
$this->references = new ReferenceCollection(array(), $pdo);

$this->sniffs = [

new DeclareSniff(),
];
}

Expand Down Expand Up @@ -195,6 +196,19 @@ public function afterTraverse(array $nodes)
parent::afterTraverse($nodes);

$this->computeNamespaceVersions();

foreach ($this->metrics as $key => $values) {
if (strpos($key, '\\') === false) {
// not a sniff service result
continue;
}

foreach ($values as $value => $rawData) {
if (isset($rawData['version'])) {
$this->updateGlobalVersion($rawData['version'], '', $rawData['version']);
}
}
}
}

/**
Expand Down
67 changes: 67 additions & 0 deletions src/Bartlett/CompatInfo/Sniffs/PHP/DeclareSniff.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?php declare(strict_types=1);

namespace Bartlett\CompatInfo\Sniffs\PHP;

use Bartlett\Reflect\Sniffer\SniffAbstract;

use PhpParser\Node;

/**
* Class DeclareSniff to detect declare control structures
* @link https://www.php.net/manual/en/control-structures.declare.php
* @since Class available since Release 5.4.0
*/
class DeclareSniff extends SniffAbstract
{
private $directives;

public function enterSniff(): void
{
parent::enterSniff();
$this->directives = [];
}

public function leaveSniff(): void
{
parent::leaveSniff();

if (!empty($this->directives)) {
// inform analyser that few sniffs were found
$this->visitor->setMetrics(
array(DeclareSniff::class => $this->directives)
);
}
}

public function enterNode(Node $node)
{
parent::enterNode($node);

if (!$node instanceof Node\Stmt\Declare_) {
return;
}

foreach ($node->declares as $declare) {
$id = (string) $declare->key;

if (strcasecmp($id, 'strict_types') === 0) {
$version = '7.0.0';
} elseif (strcasecmp($id, 'ticks') === 0) {
$version = '7.0.0';
} elseif (strcasecmp($id, 'encoding') === 0) {
$version = '5.3.0';
} else {
$version = '4.0.0';
}

if (!isset($this->directives[$id])) {
$this->directives[$id] = array(
'severity' => $this->getCurrentSeverity($version),
'version' => $version,
'spots' => []
);
}
$this->directives[$id]['spots'][] = $this->getCurrentSpot($node);
}
}
}
115 changes: 115 additions & 0 deletions tests/DeclareSniffTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
<?php
/**
* Unit tests for PHP_CompatInfo package, declare sniff
*
* PHP version 7
*
* @category PHP
* @package PHP_CompatInfo
* @subpackage Tests
* @author Laurent Laville <[email protected]>
* @license https://opensource.org/licenses/BSD-3-Clause The 3-Clause BSD License
* @since Class available since Release 5.4.0
*/

namespace Bartlett\Tests\CompatInfo;

use Bartlett\CompatInfo\Analyser\CompatibilityAnalyser;
use Bartlett\Reflect\Client;

/**
* @link https://www.php.net/manual/en/control-structures.declare.php
*/
class DeclareSniffTest extends \PHPUnit\Framework\TestCase
{
protected static $fixtures;
protected static $analyserId;
protected static $api;

/**
* Sets up the shared fixture.
*
* @return void
*/
public static function setUpBeforeClass(): void
{
self::$fixtures = __DIR__ . DIRECTORY_SEPARATOR
. 'fixtures' . DIRECTORY_SEPARATOR
. 'sniffs' . DIRECTORY_SEPARATOR
;

self::$analyserId = CompatibilityAnalyser::class;

$client = new Client();

// request for a Bartlett\Reflect\Api\Analyser
self::$api = $client->api('analyser');
}

/**
* Regression test for declare control structure detection GH#268
*
* @link https://github.com/llaville/php-compat-info/issues/268
* CompatInfo 5.3.0 is detected as PHP 5.6
* @group features, regression
* @return void
*/
public function testStructureTypesDirective()
{
$dataSource = self::$fixtures . 'declare_strict_types.php';
$analysers = ['compatibility'];
$metrics = self::$api->run($dataSource, $analysers);
$versions = $metrics[self::$analyserId]['versions'];

$this->assertEquals(
[
'php.min' => '7.0.0',
'php.max' => '',
'php.all' => '7.0.0',
],
$versions
);
}

/**
* @group features
* @return void
*/
public function testTicksDirective()
{
$dataSource = self::$fixtures . 'declare_ticks.php';
$analysers = ['compatibility'];
$metrics = self::$api->run($dataSource, $analysers);
$versions = $metrics[self::$analyserId]['versions'];

$this->assertEquals(
[
'php.min' => '7.0.0',
'php.max' => '',
'php.all' => '7.0.0',
],
$versions
);
}

/**
* @group features
* @return void
*/
public function testEncodingDirective()
{
$dataSource = self::$fixtures . 'declare_encoding.php';
$analysers = ['compatibility'];
$metrics = self::$api->run($dataSource, $analysers);
$versions = $metrics[self::$analyserId]['versions'];

$this->assertEquals(
[
'php.min' => '5.3.0',
'php.max' => '',
'php.all' => '5.3.0',
],
$versions
);
}
}
2 changes: 2 additions & 0 deletions tests/fixtures/sniffs/declare_encoding.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?php
declare(encoding="utf8");
1 change: 1 addition & 0 deletions tests/fixtures/sniffs/declare_strict_types.php
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<?php declare(strict_types=1);
2 changes: 2 additions & 0 deletions tests/fixtures/sniffs/declare_ticks.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<?php
declare(ticks=1);

0 comments on commit 3221451

Please sign in to comment.