final protected function assertClassyConstructsSatisfySpecification(callable $specification, string $directory, array $excludeClassyNames = [], string $message = ''): void
    {
        if (!\is_dir($directory)) {
            throw Exception\NonExistentDirectory::fromDirectory($directory);
        }

        \array_walk($excludeClassyNames, static function ($excludeClassyName): void {
            if (!\is_string($excludeClassyName)) {
                throw Exception\InvalidExcludeClassName::fromClassName($excludeClassyName);
            }

            if (!\class_exists($excludeClassyName)) {
                throw Exception\NonExistentExcludeClass::fromClassName($excludeClassyName);
            }
        });

        $constructs = Classy\Constructs::fromDirectory($directory);

        $classyNames = \array_diff(
            $constructs,
            $excludeClassyNames
        );

        $classyNamesNotSatisfyingSpecification = \array_filter($classyNames, static function (string $className) use ($specification) {
            return false === $specification($className);
        });

        self::assertEmpty($classyNamesNotSatisfyingSpecification, \sprintf(
            '' !== $message ? $message : "Failed asserting that the classy constructs\n\n%s\n\nsatisfy a specification.",
            ' - ' . \implode("\n - ", $classyNamesNotSatisfyingSpecification)
        ));
    }
final protected function assertClassyConstructsSatisfySpecification(callable $specification, string $directory, array $excludeClassyNames = [], string $message = ''): void
    {
        if (!\is_dir($directory)) {
            throw Exception\NonExistentDirectory::fromDirectory($directory);
        }

        \array_walk($excludeClassyNames, static function ($excludeClassyName): void {
            if (!\is_string($excludeClassyName)) {
                throw Exception\InvalidExcludeClassName::fromClassName($excludeClassyName);
            }

            if (!\class_exists($excludeClassyName)) {
                throw Exception\NonExistentExcludeClass::fromClassName($excludeClassyName);
            }
        });

        $constructs = Classy\Constructs::fromDirectory($directory);

        $classyNames = \array_diff(
            $constructs,
            $excludeClassyNames
        );

        $classyNamesNotSatisfyingSpecification = \array_filter($classyNames, static function (string $className) use ($specification) {
            return false === $specification($className);
        });

        self::assertEmpty($classyNamesNotSatisfyingSpecification, \sprintf(
            '' !== $message ? $message : "Failed asserting that the classy constructs\n\n%s\n\nsatisfy a specification.",
            ' - ' . \implode("\n - ", $classyNamesNotSatisfyingSpecification)
        ));
    }
final protected function assertClassyConstructsSatisfySpecification ( callable $ specification , string $ directory , array $ excludeClassyNames = [ ] , string $ message = '' ) : void { if ( ! \ is_dir ( $ directory ) ) { throw Exception \ NonExistentDirectory :: fromDirectory ( $ directory ) ; } \ array_walk ( $ excludeClassyNames , static function ( $ excludeClassyName ) : void { if ( ! \ is_string ( $ excludeClassyName ) ) { throw Exception \ InvalidExcludeClassName :: fromClassName ( $ excludeClassyName ) ; } if ( ! \ class_exists ( $ excludeClassyName ) ) { throw Exception \ NonExistentExcludeClass :: fromClassName ( $ excludeClassyName ) ; } } ) ; $ constructs = Classy \ Constructs :: fromDirectory ( $ directory ) ; $ classyNames = \ array_diff ( $ constructs , $ excludeClassyNames ) ; $ classyNamesNotSatisfyingSpecification = \ array_filter ( $ classyNames , static function ( string $ className ) use ( $ specification ) { return false === $ specification ( $ className ) ; } ) ; self :: assertEmpty ( $ classyNamesNotSatisfyingSpecification , \ sprintf ( '' !== $ message ? $ message : "Failed asserting that the classy constructs\n\n%s\n\nsatisfy a specification." , ' - ' . \ implode ( "\n - " , $ classyNamesNotSatisfyingSpecification ) ) ) ; }
Asserts that all classes, interfaces, and traits found in a directory satisfy a specification.

Useful for asserting that production and test code conforms to certain requirements.

The specification will be invoked with a single argument, the class name, and should return true or false.

@param callable $specification
@param string   $directory
@param string[] $excludeClassyNames
@param string   $message

@throws Exception\NonExistentDirectory
@throws Exception\InvalidExcludeClassName
@throws Exception\NonExistentExcludeClass
@throws Classy\Exception\MultipleDefinitionsFound
Asserts that all classes interfaces and traits found in a directory satisfy a specification .