whitedigital-eu/config-pack

用于其他组织仓库的PhpCsFixer配置

2.1.0 2023-03-06 14:54 UTC

This package is auto-updated.

Last update: 2024-09-10 15:49:38 UTC


README

警告
当从v1升级到v2时,最好在不包含脚本和插件的模式下运行composer update,因为v2不再需要symfony/phpunit-bridge,卸载它可能会更改或删除测试相关文件,如.env.testphpunit.xml.dist

composer update -nW --no-scripts --no-plugins whitedigital-eu/config-pack

安装

composer require --dev whitedigital-eu/config-pack

用法

PhpCsFixer

vendor/bin/php-cs-fixer --config=vendor/whitedigital-eu/config-pack/.php-cs-fixer.php fix

在PhpStorm中

  • 在PHP CS Fixer的设置中指向相同的配置文件
  • 勾选“允许风险规则”复选框
  • 选择自定义规则集
  • 指向php-cs-fixer可执行文件

PhpUnit

vendor/bin/phpunit --log-junit report.xml --configuration vendor/whitedigital-eu/config-pack/phpunit.xml.dist tests

或者如果tests/bootstrap.php与whitedigital-eu/config-pack中的不同

vendor/bin/phpunit --log-junit report.xml --configuration vendor/whitedigital-eu/config-pack/phpunit.xml.dist --bootstrap=tests/bootstrap.php tests

PhpStan

vendor/bin/phpstan --configuration=vendor/whitedigital-eu/config-pack/phpstan.neon.dist analyse src

在PhpStorm中

  • 在PHPStan的设置中指向相同的配置文件
  • 指向项目的autoload,通常是vendor/autoload.php
  • 指向phpstan可执行文件

功能用法(自v2.2起)

ConfigPack仅适用于开发和测试环境,确保您只为此配置设置此配置。

/** config/bundles.php */
WhiteDigital\Config\ConfigPack::class => ['dev' => true, 'test' => true]

Faker

此软件包现在包含fakerphp/faker作为依赖项,因此使用假数据生成更容易。如果不使用AbstractTestCaseAbstractFixture,您可以使用FakerTrait轻松使用faker。

use WhiteDigital\Config\Faker;
use WhiteDigital\Config\Traits\FakerTrait;

class Test 
{
    use FakerTrait;
    
    public function __construct(Faker $faker) 
    {
        self::setFaker($faker);
    }
    
    public function test(): string 
    {
        return self::text();
    }
}

由于Faker与该库的配置一起使用,因此在使用任何faker功能之前必须调用setFaker函数。
Faker会自动注入。 FakerTrait主要传递来自faker工厂的函数,最有用的方法已定义为注释中的方法,以便IDE可以查看它们。
默认情况下,Faker使用lv_LV作为区域设置,使用2022作为种子。如果需要不同的值,您可以进行配置。

config_pack:
    seed: 123
    locale: en_US
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
use Symfony\Config\ConfigPackConfig;

return static function (ConfigPackConfig $config, ContainerConfigurator $container): void {
    if (in_array($container->env(), ['dev', 'test', ], true)) {
        $config
            ->seed(123)
            ->locale('en_US');
    }
};

AbstractTestCase

由于大多数用于测试api-platform api的测试都有些类似,AbstractTestCase定义了许多有用的函数,以便测试api更加容易。
总的来说,使用AbstractTestCase,通常的api测试应如下所示

use WhiteDigital\Config\Test\AbstractTestCase;
use WhiteDigital\Config\Test\Traits;

class CustomerTest extends AbstractTestCase 
{
    use Traits\DeleteItem;
    use Traits\GetCollection;
    use Traits\GetItem;
    use Traits\GetItemNotFound;

    protected static string $iri = '/api/customers';
    
    public function testPostItem(): int
    {
        return self::post([
            'key1' => self::words(),
            'key2' => self::text(),
            'key3' => self::randomDecimal(),
        ])->id;
    }

    #[Depends('testPostItem')]
    public function testPatchItem(int $id): int
    {
        return self::patch($id, [
            'key3' => self::randomDigit(),
        ])->id;
    }
}

此测试
GET: /api/customers/{id}
GET: /api/customer/{not_existing_id}
GET: /api/customers
POST: /api/customers
PATCH: /api/customers/{id}
DELETE: /api/customers/{id}

默认情况下,测试使用身份验证,您可以在config_pack配置中配置login_emaillogin_password

config_pack:
    login_email: test@test.com
    login_password: test
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
use Symfony\Config\ConfigPackConfig;

return static function (ConfigPackConfig $config, ContainerConfigurator $container): void {
    if (in_array($container->env(), ['dev', 'test', ], true)) {
        $config
            ->loginEmail('test@test.com')
            ->loginPassword('test');
    }
};

AbstractFixture

类似于AbstractTestCaseAbstractFixture为doctrine fixtures定义了基本函数。它还使用FakerTrait来简化数据生成。

use Doctrine\Persistence\ObjectManager;
use WhiteDigital\Config\DataFixture\AbstractFixture;

class OneFixture extends AbstractFixture
{
    public function load(ObjectManager $manager): void
    {
        $fixture = (new One())
            ->setKey1(self::words())
            ->setKey2(self::rnadomDecimal());
            
        $manager->persist($fixture);
        $manager->flush();
        
        $this->reference($fixture);
    }
}

class TwoFixture extends AbstractFixture
{
    public function load(ObjectManager $manager): void
    {
        for($i = 0; $i < 10; $i++){
            $fixture = (new Two())
                ->setKey1(self::words())
                ->setKey2($this->getEntity(One::class));
                
            $manager->persist($fixture);
            $manager->flush();
            
            $this->reference($fixture, $i);
        }
    }
    
    public function getDependencies() : array
    {
        $dependencies = parent::getDependencies();
        $dependencies[] = OneFixture::class;
        
        return $dependencies;
    }
}

AbstractFixture定义了一些有用的函数

getEntity -> getEntity(Entity::class):如果fixture中包含此类的对象,则返回实体对象,如果此类是在创建此fixture时添加到依赖项中,并且相关fixture定义了引用。

getImagegetFile:与whitedigital-eu/storage-item-resource库配对,这些函数根据需要返回基于StorageItem的实体 -> 图像或文本文件。

reference:将当前fixture设置为其他地方使用的引用,其中此fixture是依赖项

getClassifier:如果项目包含任何分类器,并且项目分类器组件扩展了 BaseClassifierFixture,则显式返回分类器。

BaseClassifierFixture

如果你的项目有任何分类器逻辑,可以扩展 BaseClassifierFixture,这将使分类器创建更加容易。
你需要有一个至少具有以下结构的实体才能使其工作

use Doctrine\ORM\Mapping\Entity;

#[Entity]
class Classifier
{
    private ?int $id = null;
    private ?string $value = null;
    private ?array $data = [];
    private ?ClassifierType $type = null;
}

并且你需要有一个支持枚举(这里称为 ClassifierType)。
ClassifierType 的例子可能如下所示

enum ClassifierType: string
{
    case ONE = 'ONE';
    case TWO = 'TWO';
}

使用 BaseClassifierFixture,分类器可以通过两种方式创建
简单

use WhiteDigital\Config\DataFixture\BaseClassifierFixture;

class ClassifierFixture extends BaseClassifierFixture
{
    public function __construct() 
    {
        parent::__construct(Classifier::class);
    }
    
    public function load(ObjectManager $manager): void
    {
        $classifiers = [
            'ONE' => ClassifierType::ONE,
            'TWO' => ClassifierType::TWO;
        ];

        $this->loadFixtures($manager, $classifiers);
    }
}

带数据

use WhiteDigital\Config\DataFixture\BaseClassifierFixture;

class ClassifierFixture extends BaseClassifierFixture
{
    public function __construct() 
    {
        parent::__construct(Classifier::class);
    }
    
    public function load(ObjectManager $manager): void
    {
        $classifiers = [
            'ONE' => ['classifier' => ClassifierType::ONE, 'data' => ['data' => 'one']],
            'TWO' => ['classifier' => ClassifierType::TWO, 'data' => ['data' => 'two']],
        ];

        $this->loadFixtures($manager, $classifiers);
    }
}

依赖

use WhiteDigital\Config\DataFixture\BaseClassifierFixture;

class ClassifierFixture extends BaseClassifierFixture
{
    public function __construct() 
    {
        parent::__construct(Classifier::class);
    }
    
    public function load(ObjectManager $manager): void
    {
        $classifiers = [
            'ONE' => ClassifierType::ONE,
        ];

        $this->loadFixtures($manager, $classifiers);

        $dependants = [
            'TWO' => ['classifier' => ClassifierType::TWO, 'data' => ['one_iri' => '/api/classifiers/' . $this->getClassifier(ClassifierType::ONE)->getId(), ], ],
        ];

        $this->loadFixtures($manager, $dependants);
    }
}