Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.git
.phpunit.cache
vendor
tmp
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,7 @@ composer.lock
/vendor

.phpunit.cache
build/coverage.xml
coverage-priv.xml

tmp
20 changes: 20 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
FROM php:8.4-cli-bookworm

RUN apt-get update \
&& apt-get install -y --no-install-recommends curl git unzip libicu-dev $PHPIZE_DEPS \
&& docker-php-ext-install intl \
&& curl -fsSL https://github.com/krakjoe/pcov/archive/refs/tags/v1.0.12.tar.gz -o /tmp/pcov.tar.gz \
&& tar xzf /tmp/pcov.tar.gz -C /tmp \
&& cd /tmp/pcov-1.0.12 \
&& phpize \
&& ./configure \
&& make -j"$(nproc)" \
&& make install \
&& docker-php-ext-enable pcov \
&& rm -rf /tmp/pcov.tar.gz /tmp/pcov-1.0.12 \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*

COPY --from=composer:2 /usr/bin/composer /usr/bin/composer

WORKDIR /app
8 changes: 8 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
services:
php:
build: .
working_dir: /app
volumes:
- .:/app
environment:
COMPOSER_ALLOW_SUPERUSER: 1
13 changes: 13 additions & 0 deletions docker/check.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/usr/bin/env bash
set -euo pipefail

cd "$(dirname "$0")/.."
source docker/common.sh

install_dependencies

docker compose run --rm php composer validate --ansi
docker compose run --rm php vendor/bin/phpunit
docker compose run --rm php vendor/bin/phpstan analyse --memory-limit=512M --ansi
docker compose run --rm php vendor/bin/ecs check --ansi
docker compose run --rm php vendor/bin/composer-dependency-analyser
11 changes: 11 additions & 0 deletions docker/common.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/usr/bin/env bash

install_dependencies() {
if [[ ! -f vendor/bin/phpunit ]]; then
docker compose run --rm php composer update --no-interaction
return
fi

docker compose run --rm php composer install --no-interaction \
|| docker compose run --rm php composer update --no-interaction
}
8 changes: 8 additions & 0 deletions docker/coverage.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/usr/bin/env bash
set -euo pipefail

cd "$(dirname "$0")/.."
source docker/common.sh

install_dependencies
docker compose run --rm php vendor/bin/phpunit --configuration phpunit.coverage.xml "$@"
8 changes: 8 additions & 0 deletions docker/test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/usr/bin/env bash
set -euo pipefail

cd "$(dirname "$0")/.."
source docker/common.sh

install_dependencies
docker compose run --rm php vendor/bin/phpunit
10 changes: 0 additions & 10 deletions phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,6 @@ parameters:
identifier: method.alreadyNarrowedType
path: tests

# compatibility with PHPUnit 9 and 10
-
identifier: arguments.count
path: src/Testing/MockWire.php

# type from service definition
-
identifier: argument.type
path: src/Testing/MockWire.php

# magic contract
-
identifier: public.method.unused
Expand Down
27 changes: 27 additions & 0 deletions phpunit.coverage.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?xml version="1.0"?>
<phpunit
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="vendor/phpunit/phpunit/phpunit.xsd"
bootstrap="vendor/autoload.php"
colors="true"
cacheDirectory=".phpunit.cache"
>
<testsuites>
<testsuite name="unit">
<directory>tests</directory>
<exclude>tests/Testing/UnitTestFilePathsFinder/Fixture</exclude>
</testsuite>
</testsuites>

<source>
<include>
<directory suffix=".php">src</directory>
</include>
</source>

<coverage>
<report>
<text outputFile="php://stdout" showOnlySummary="false"/>
</report>
</coverage>
</phpunit>
1 change: 1 addition & 0 deletions src/DependencyInjection/ContainerFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public function create(): Container
$container = new Container();

$container->autodiscover(__DIR__ . '/../Command');
$container->autodiscover(__DIR__ . '/../Testing/Command');

$container->service(Parser::class, static function (): Parser {
$phpParserFactory = new ParserFactory();
Expand Down
18 changes: 10 additions & 8 deletions src/Finder/FilesFinder.php
Original file line number Diff line number Diff line change
Expand Up @@ -90,14 +90,16 @@ public static function findJsonFiles(array $sources): array
}
}

$jsonFileFinder = Finder::create()
->files()
->in($directories)
->name('*.json')
->sortByName();

foreach ($jsonFileFinder->getIterator() as $fileInfo) {
$jsonFileInfos[] = $fileInfo;
if ($directories !== []) {
$jsonFileFinder = Finder::create()
->files()
->in($directories)
->name('*.json')
->sortByName();

foreach ($jsonFileFinder->getIterator() as $fileInfo) {
$jsonFileInfos[] = $fileInfo;
}
}

return $jsonFileInfos;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ public function enterNode(Node $node): ?Node
}

// must be named
if (! $node->namespacedName instanceof Name) {
$namespacedName = $node->namespacedName ?? null;
if (! $namespacedName instanceof Name) {
return null;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ private function getClassName(): string
throw new ShouldNotHappenException('Class_ node is missing');
}

$namespaceName = $this->currentClass->namespacedName;
$namespaceName = $this->currentClass->namespacedName ?? null;
if (! $namespaceName instanceof Name) {
throw new ShouldNotHappenException();
}
Expand Down
3 changes: 2 additions & 1 deletion src/PhpParser/NodeVisitor/NeedForFinalizeNodeVisitor.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ public function enterNode(Node $node): ?Node
}

// we need a name to make it work
if (! $node->namespacedName instanceof Name) {
$namespacedName = $node->namespacedName ?? null;
if (! $namespacedName instanceof Name) {
return null;
}

Expand Down
16 changes: 6 additions & 10 deletions src/Testing/MockWire.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use ReflectionMethod;
use ReflectionNamedType;
use ReflectionParameter;
use Webmozart\Assert\Assert;

/**
* @api used in public
Expand Down Expand Up @@ -112,16 +113,11 @@ private static function matchPassedMockOrCreate(
}
}

// fallback to directly created mock
// support for PHPUnit 10 and 9
$testCaseReflectionClass = new ReflectionClass(TestCase::class);
$testCaseConstructor = $testCaseReflectionClass->getConstructor();
if ($testCaseConstructor instanceof ReflectionMethod && $testCaseConstructor->getNumberOfRequiredParameters() > 0) {
$phpunitMocker = new PHPUnitMocker('testName');
} else {
$phpunitMocker = new PHPUnitMocker();
}
$phpunitMocker = new PHPUnitMocker('mock');

$parameterClassName = $reflectionParameter->getType()->getName();
Assert::classExists($parameterClassName);

return $phpunitMocker->create($reflectionParameter->getType()->getName());
return $phpunitMocker->create($parameterClassName);
}
}
4 changes: 3 additions & 1 deletion stubs/Symfony/Bundle/FrameworkBundle/Test/KernelTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

namespace Symfony\Bundle\FrameworkBundle\Test;

class KernelTestCase
use PHPUnit\Framework\TestCase;

class KernelTestCase extends TestCase
{
}
50 changes: 50 additions & 0 deletions tests/CachedPhpParser/CachedPhpParserTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<?php

declare(strict_types=1);

namespace Rector\SwissKnife\Tests\CachedPhpParser;

use Nette\Utils\FileSystem;
use Override;
use PHPUnit\Framework\TestCase;
use Rector\SwissKnife\PhpParser\CachedPhpParser;
use Rector\SwissKnife\Tests\AbstractTestCase;
use RuntimeException;

final class CachedPhpParserTest extends AbstractTestCase
{
private CachedPhpParser $cachedPhpParser;

#[Override]
protected function setUp(): void
{
parent::setUp();
$this->cachedPhpParser = $this->make(CachedPhpParser::class);
}

public function testParseFileCachesResult(): void
{
$filePath = __DIR__ . '/../PhpParser/Finder/ClassConstFinder/Fixture/SomeClassWithConstants.php';

$firstParse = $this->cachedPhpParser->parseFile($filePath);
$secondParse = $this->cachedPhpParser->parseFile($filePath);

$this->assertSame($firstParse, $secondParse);
$this->assertNotEmpty($firstParse);
}

public function testParseError(): void
{
$tempFile = sys_get_temp_dir() . '/swiss-knife-parse-error-' . uniqid() . '.php';
FileSystem::write($tempFile, '<?php invalid syntax here', null);

try {
$this->expectException(RuntimeException::class);
$this->expectExceptionMessage('Could not parse file "' . $tempFile . '"');

$this->cachedPhpParser->parseFile($tempFile);
} finally {
FileSystem::delete($tempFile);
}
}
}
41 changes: 41 additions & 0 deletions tests/Command/AliceYamlFixturesToPhpCommandTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

declare(strict_types=1);

namespace Rector\SwissKnife\Tests\Command;

use Entropy\Console\Enum\ExitCode;
use Nette\Utils\FileSystem;
use Rector\SwissKnife\Command\AliceYamlFixturesToPhpCommand;
use Rector\SwissKnife\Tests\AbstractTestCase;

final class AliceYamlFixturesToPhpCommandTest extends AbstractTestCase
{
private string $tempDirectory;

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

$this->tempDirectory = sys_get_temp_dir() . '/swiss-knife-alice-' . uniqid();
FileSystem::createDir($this->tempDirectory);
}

protected function tearDown(): void
{
FileSystem::delete($this->tempDirectory);
}

public function testRun(): void
{
$yamlPath = $this->tempDirectory . '/fixture.yml';
FileSystem::write($yamlPath, "SomeEntity:\n name: test\n", null);

$command = $this->make(AliceYamlFixturesToPhpCommand::class);
$exitCode = $command->run([$this->tempDirectory]);

$this->assertSame(ExitCode::SUCCESS, $exitCode);
$this->assertFileExists($this->tempDirectory . '/fixture.php');
$this->assertFileDoesNotExist($yamlPath);
}
}
40 changes: 40 additions & 0 deletions tests/Command/AliceYamlFixturesToPhpYamlExtensionTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

declare(strict_types=1);

namespace Rector\SwissKnife\Tests\Command;

use Entropy\Console\Enum\ExitCode;
use Nette\Utils\FileSystem;
use Rector\SwissKnife\Command\AliceYamlFixturesToPhpCommand;
use Rector\SwissKnife\Tests\AbstractTestCase;

final class AliceYamlFixturesToPhpYamlExtensionTest extends AbstractTestCase
{
private string $tempDirectory;

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

$this->tempDirectory = sys_get_temp_dir() . '/swiss-knife-alice-yaml-' . uniqid();
FileSystem::createDir($this->tempDirectory);
}

protected function tearDown(): void
{
FileSystem::delete($this->tempDirectory);
}

public function testYamlExtension(): void
{
$yamlPath = $this->tempDirectory . '/fixture.yaml';
FileSystem::write($yamlPath, "SomeEntity:\n name: test\n", null);

$command = $this->make(AliceYamlFixturesToPhpCommand::class);
$exitCode = $command->run([$this->tempDirectory]);

$this->assertSame(ExitCode::SUCCESS, $exitCode);
$this->assertFileExists($this->tempDirectory . '/fixture.php');
}
}
30 changes: 30 additions & 0 deletions tests/Command/CheckCommentedCodeCommandTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

declare(strict_types=1);

namespace Rector\SwissKnife\Tests\Command;

use Entropy\Console\Enum\ExitCode;
use Rector\SwissKnife\Command\CheckCommentedCodeCommand;
use Rector\SwissKnife\Tests\AbstractTestCase;

final class CheckCommentedCodeCommandTest extends AbstractTestCase
{
public function testSuccessWhenNoCommentedCode(): void
{
$command = $this->make(CheckCommentedCodeCommand::class);

$exitCode = $command->run([__DIR__ . '/Fixture/CheckCommentedCode/Clean'], [], 4);

$this->assertSame(ExitCode::SUCCESS, $exitCode);
}

public function testErrorWhenCommentedCodeFound(): void
{
$command = $this->make(CheckCommentedCodeCommand::class);

$exitCode = $command->run([__DIR__ . '/Fixture/CheckCommentedCode/Commented'], [], 2);

$this->assertSame(ExitCode::ERROR, $exitCode);
}
}
Loading
Loading