phparkitect / arkitect

Put your architectural rules under test!
MIT License
703 stars 36 forks source link

Don't assume PHPARKITECT_COMPOSER_INSTALL is not defined yet #401

Open hgraca opened 1 year ago

hgraca commented 1 year ago

By default, the classmap is not loaded, so it's not possible to use functions like is_a to infer inheritance of classes under test. To solve this, the autoloader must be included in the config file, but then it will try to define this variable again, which will cause it to throw an error.

fain182 commented 1 year ago

Can you show a snippet of how you use is_a in the configuration file to better understand your needs?

codecov-commenter commented 1 year ago

Codecov Report

Merging #401 (7b82aca) into main (976c200) will not change coverage. The diff coverage is n/a.

:exclamation: Your organization is not using the GitHub App Integration. As a result you may experience degraded service beginning May 15th. Please install the Github App Integration for your organization. Read more.

@@            Coverage Diff            @@
##               main     #401   +/-   ##
=========================================
  Coverage     94.33%   94.33%           
  Complexity      571      571           
=========================================
  Files            67       67           
  Lines          1500     1500           
=========================================
  Hits           1415     1415           
  Misses           85       85           
hgraca commented 1 year ago

Like this:

<?php

declare(strict_types=1);

use Arkitect\ClassSet;
use Arkitect\CLI\Config;
use Arkitect\Expression\ForClasses\HaveNameMatching;
use Arkitect\Expression\ForClasses\IsA;
use Arkitect\Rules\Rule;
use Hgraca\SymfonyBoilerplate\Infrastructure\CommandBus\Port\CommandHandlerInterface;

require_once dirname(__DIR__) . '/../vendor/autoload_runtime.php';

return static function (Config $config): void {
    $rootPath = realpath(__DIR__ . '/../..');

    $classSet = ClassSet::fromDir("$rootPath/src", "$rootPath/tests");

    $rules[] = Rule::allClasses()
        ->except(...$this->exceptionList)
        ->that(new IsA(CommandHandlerInterface::class))
        ->should(new HaveNameMatching('*CommandHandler'))
        ->because("our command handlers must be suffixed 'CommandHandler', to differentiate from 'QueryHandler' and 'MutatorHandler'.");

    $config->add($classSet, ...$rules);
};

I need to use the IsA expression there, as opposed to Implements, because Implements only checks for direct implementation, not implementation through the inheritance tree.