Skip to content

Commit

Permalink
Create PhpUnitHook for bypassing final classes
Browse files Browse the repository at this point in the history
  • Loading branch information
radek-bruha committed Aug 3, 2019
1 parent 5d2ac90 commit 6245070
Show file tree
Hide file tree
Showing 16 changed files with 323 additions and 31 deletions.
8 changes: 4 additions & 4 deletions .travis.yml
Expand Up @@ -7,12 +7,12 @@ php:
before_script:
- composer install -o --no-ansi --no-suggest
- composer update -o --no-ansi --no-suggest
- export PARALLEL=PARALLEL; vendor/bin/paratest tests -p 8 --runner WrapperRunner --coverage-clover build/logs/clover.xml --coverage-xml=/tmp/coverage/coverage-xml --log-junit=/tmp/coverage/phpunit.junit.xml --whitelist src; export PARALLEL;
- export PARALLEL=PARALLEL; vendor/bin/paratest tests -p 8 --runner WrapperRunner; export PARALLEL;

script:
- vendor/bin/phpcs src tests -p --ignore=tests/*/Data/* --extensions=php --standard=ruleset.xml
- vendor/bin/phpstan analyse src tests -c ruleset.neon -l 7
- export PARALLEL=PARALLEL; vendor/bin/paratest tests -p 8 --runner WrapperRunner --coverage-clover build/logs/clover.xml --coverage-xml=/tmp/coverage/coverage-xml --log-junit=/tmp/coverage/phpunit.junit.xml --whitelist src; export PARALLEL;
- vendor/bin/phpcs bin src tests -p --ignore=tests/*/Data/* --extensions=php --standard=ruleset.xml
- vendor/bin/phpstan analyse bin src tests -c ruleset.neon -l 7
- export PARALLEL=PARALLEL; vendor/bin/paratest tests -p8 --runner WrapperRunner --coverage-clover build/logs/clover.xml --coverage-xml=/tmp/coverage/coverage-xml --log-junit=/tmp/coverage/phpunit.junit.xml --whitelist src; export PARALLEL;
- export INFECTION=INFECTION; vendor/bin/infection -j8 --coverage=/tmp/coverage --only-covered --no-ansi; export INFECTION;

after_success:
Expand Down
5 changes: 4 additions & 1 deletion composer.json
@@ -1,6 +1,8 @@
{
"name": "radek-bruha/coding-standard",
"description": "Coding Standard Enforcement Tools",
"license": "unlicense",
"type": "library",
"autoload": {
"psr-4": {
"Bruha\\CodingStandard\\": "src/"
Expand All @@ -22,6 +24,7 @@
"ext-tokenizer": "*",
"brianium/paratest": "^3.0",
"cweagans/composer-patches": "^1.6",
"dg/bypass-finals": "^1.1",
"infection/infection": "^0.13",
"php-mock/php-mock-phpunit": "^2.4",
"phpstan/phpstan": "^0.11",
Expand All @@ -30,7 +33,7 @@
"phpstan/phpstan-nette": "^0.11",
"phpstan/phpstan-phpunit": "^0.11",
"phpstan/phpstan-strict-rules": "^0.11",
"phpunit/phpunit": "^8.2",
"phpunit/phpunit": "^8.3",
"slevomat/coding-standard": "^5.0",
"squizlabs/php_codesniffer": "^3.4",
"stesie/phpcs-doctrine-annotation-rules": "^1.2"
Expand Down
3 changes: 3 additions & 0 deletions phpunit.xml
Expand Up @@ -9,4 +9,7 @@
<directory>src</directory>
</whitelist>
</filter>
<extensions>
<extension class="Bruha\CodingStandard\CustomHooks\PhpUnitHook"/>
</extensions>
</phpunit>
75 changes: 75 additions & 0 deletions src/CustomHooks/PhpUnitHook.php
@@ -0,0 +1,75 @@
<?php declare(strict_types=1);

namespace Bruha\CodingStandard\CustomHooks;

use DG\BypassFinals;
use PHPUnit\Runner\AfterLastTestHook;
use PHPUnit\Runner\AfterTestHook;
use PHPUnit\Runner\BeforeTestHook;

/**
* Class PhpUnitHook
*
* @package Bruha\CodingStandard\CustomHooks
*/
final class PhpUnitHook implements BeforeTestHook, AfterTestHook, AfterLastTestHook
{

/**
* @var array
*/
private $tests = [];

/**
* @var float
*/
private $time = 0.0;

/**
* @var int
*/
private $count = 0;

/**
* @param string $test
*/
public function executeBeforeTest(string $test): void
{
$test;

BypassFinals::enable();
}

/**
* @param string $test
* @param float $time
*/
public function executeAfterTest(string $test, float $time): void
{
$this->tests[(string) $time] = $test;
$this->time += $time;
$this->count++;
}

/**
*
*/
public function executeAfterLastTest(): void
{
krsort($this->tests, SORT_NUMERIC);

echo sprintf(
'%s%s%07.3fs (100.000%%): Time analysis of %s tests:%s',
PHP_EOL,
PHP_EOL,
$this->time,
$this->count,
PHP_EOL
);

foreach ($this->tests as $time => $name) {
echo sprintf('%07.3fs (%07.3f%%): %s%s', $time, $time / $this->time * 100, $name, PHP_EOL);
}
}

}
82 changes: 82 additions & 0 deletions tests/Integration/CustomHooks/PhpUnitHookTest.php
@@ -0,0 +1,82 @@
<?php declare(strict_types=1);

namespace Tests\Integration\CustomHooks;

use Bruha\CodingStandard\CustomHooks\PhpUnitHook;
use DG\BypassFinals;
use Tests\AbstractTestCase;
use Tests\PrivateTrait;

/**
* Class PhpUnitHookTest
*
* @package Tests\Integration\CustomHooks
*/
final class PhpUnitHookTest extends AbstractTestCase
{

use PrivateTrait;

/**
* @var PhpUnitHook
*/
private $hook;

/**
*
*/
protected function setUp(): void
{
parent::setUp();

$this->hook = new PhpUnitHook();
}

/**
* @covers PhpUnitHook::executeBeforeTest
*/
public function testExecuteBeforeTest(): void
{
$this->hook->executeBeforeTest('Test');

self::assertTrue(in_array(BypassFinals::PROTOCOL, stream_get_wrappers(), TRUE));
}

/**
* @covers PhpUnitHook::executeAfterTest
*/
public function testExecuteAfterTest(): void
{
$this->hook->executeAfterTest('Test::test', 1);

self::assertEquals(['1' => 'Test::test'], $this->getProperty($this->hook, 'tests'));
self::assertEquals(1, $this->getProperty($this->hook, 'time'));
self::assertEquals(1, $this->getProperty($this->hook, 'count'));
}

/**
* @covers PhpUnitHook::executeAfterLastTest
*/
public function testExecuteAfterLastTest(): void
{
ob_start();
$this->hook->executeAfterTest('Test::test', 1);
$this->hook->executeAfterLastTest();
$output = explode(PHP_EOL, (string) ob_get_contents());
ob_end_clean();

self::assertGreaterThan(0, count($output));
self::assertEquals('', array_pop($output));
self::assertEquals('', array_shift($output));
self::assertEquals('', array_shift($output));
self::assertRegExp(
'/\d+\.\d+s \(100\.000%\): Time analysis of \d+ tests:/',
(string) array_shift($output)
);
self::assertRegExp(
'/\d+\.\d+s \(\d+\.\d+%\): \w+::\w+/',
(string) array_shift($output)
);
}

}
12 changes: 6 additions & 6 deletions tests/Integration/CustomPatches/PatchesTest.php
Expand Up @@ -13,7 +13,7 @@ final class PatchesTest extends AbstractTestCase
{

/**
* @covers
* @coversNothing
*/
public function testPhpCodeSniffer(): void
{
Expand All @@ -22,7 +22,7 @@ public function testPhpCodeSniffer(): void
}

/**
* @covers
* @coversNothing
*/
public function testPhpStan(): void
{
Expand All @@ -31,7 +31,7 @@ public function testPhpStan(): void
}

/**
* @covers
* @coversNothing
*/
public function testPhpUnit(): void
{
Expand All @@ -40,15 +40,15 @@ public function testPhpUnit(): void
}

/**
* @covers
* @coversNothing
*/
public function testPhpParaTest(): void
{
$this->processPatch('brianium/paratest/src/Runners/PHPUnit/ResultPrinter.php', 'PHPParaTest.patch');
}

/**
* @covers
* @coversNothing
*/
public function testPhpInfection(): void
{
Expand Down Expand Up @@ -91,7 +91,7 @@ public function testPhpInfection(): void
}

/**
* @covers
* @coversNothing
*/
public function testDoctrineAnnotation(): void
{
Expand Down
4 changes: 2 additions & 2 deletions tests/Integration/CustomRules/AnalyzerTest.php
Expand Up @@ -30,7 +30,7 @@ public function testPhpCodeSniffer(): void
(string) array_shift($output)
);
self::assertRegExp(
'/.+ \(\d+\.\d+%\): .+Sniff/',
'/\d+\.\d+s \(\d+\.\d+%\): .+Sniff/',
(string) array_shift($output)
);
}
Expand All @@ -52,7 +52,7 @@ public function testPhpUnit(): void
(string) array_shift($output)
);
self::assertRegExp(
'/.+ \(\d+\.\d+%\): .+Test::test.+/',
'/\d+\.\d+s \(\d+\.\d+%\): .+::.+/',
(string) array_shift($output)
);
}
Expand Down
14 changes: 10 additions & 4 deletions tests/Integration/CustomRules/Sniffs/Commenting/ClassSniffTest.php
Expand Up @@ -19,7 +19,10 @@ final class ClassSniffTest extends AbstractTestCase
private $sniff = ClassSniff::class;

/**
* @covers
* @covers ClassSniff::register
* @covers ClassSniff::process
* @covers ClassSniff::processCommenting
* @covers ClassSniff::replacePlaceholders
*/
public function testSuccess(): void
{
Expand All @@ -29,7 +32,10 @@ public function testSuccess(): void
}

/**
* @covers
* @covers ClassSniff::register
* @covers ClassSniff::process
* @covers ClassSniff::processCommenting
* @covers ClassSniff::replacePlaceholders
*/
public function testMissing(): void
{
Expand All @@ -38,7 +44,7 @@ public function testMissing(): void
self::assertNotSuccess(
$result,
5,
13,
8,
0,
$this->sniff,
'CustomRules.Commenting.Class.Comment',
Expand All @@ -48,7 +54,7 @@ public function testMissing(): void
self::assertNotSuccess(
$result,
5,
13,
8,
1,
$this->sniff,
'CustomRules.Commenting.Class.Comment',
Expand Down
Expand Up @@ -19,7 +19,10 @@ final class ConstructorSniffTest extends AbstractTestCase
private $sniff = ConstructorSniff::class;

/**
* @covers
* @covers ConstructorSniff::register
* @covers ConstructorSniff::process
* @covers ConstructorSniff::processCommenting
* @covers ConstructorSniff::replacePlaceholders
*/
public function testSuccess(): void
{
Expand All @@ -29,7 +32,10 @@ public function testSuccess(): void
}

/**
* @covers
* @covers ConstructorSniff::register
* @covers ConstructorSniff::process
* @covers ConstructorSniff::processCommenting
* @covers ConstructorSniff::replacePlaceholders
*/
public function testMissing(): void
{
Expand Down
Expand Up @@ -19,7 +19,8 @@ final class FunctionSniffTest extends AbstractTestCase
private $sniff = FunctionSniff::class;

/**
* @covers
* @covers FunctionSniff::register
* @covers FunctionSniff::process
*/
public function testSuccess(): void
{
Expand All @@ -29,7 +30,8 @@ public function testSuccess(): void
}

/**
* @covers
* @covers FunctionSniff::register
* @covers FunctionSniff::process
*/
public function testMissing(): void
{
Expand Down
Expand Up @@ -19,7 +19,10 @@ final class InterfaceSniffTest extends AbstractTestCase
private $sniff = InterfaceSniff::class;

/**
* @covers
* @covers InterfaceSniff::register
* @covers InterfaceSniff::process
* @covers InterfaceSniff::processCommenting
* @covers InterfaceSniff::replacePlaceholders
*/
public function testSuccess(): void
{
Expand All @@ -29,7 +32,10 @@ public function testSuccess(): void
}

/**
* @covers
* @covers InterfaceSniff::register
* @covers InterfaceSniff::process
* @covers InterfaceSniff::processCommenting
* @covers InterfaceSniff::replacePlaceholders
*/
public function testMissing(): void
{
Expand Down

0 comments on commit 6245070

Please sign in to comment.