定制 solidframe/archtest 二次开发

按需修改功能、优化性能、对接业务系统,提供一站式技术支持

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

solidframe/archtest

最新稳定版本:v0.1.0

Composer 安装命令:

composer require solidframe/archtest

包简介

Architecture testing with fluent API: enforce DDD, CQRS, modular rules as PHPUnit tests for SolidFrame

README 文档

README

Architecture testing with fluent API: enforce DDD, CQRS, event-driven, and modular rules as PHPUnit tests.

Write architectural constraints as tests. Break a rule, break the build.

Installation

composer require solidframe/archtest --dev

Quick Start

Fluent Assertions

use SolidFrame\Archtest\Arch;
use PHPUnit\Framework\TestCase;
use PHPUnit\Framework\Attributes\Test;

final class ArchitectureTest extends TestCase
{
    #[Test]
    public function valueObjectsAreFinalAndReadonly(): void
    {
        Arch::assertThat(__DIR__ . '/../src/Domain/ValueObject')
            ->areFinal()
            ->areReadonly();
    }

    #[Test]
    public function domainDoesNotDependOnInfrastructure(): void
    {
        Arch::assertThat(__DIR__ . '/../src/Domain')
            ->doesNotDependOn('App\Infrastructure');
    }

    #[Test]
    public function handlersHaveCorrectSuffix(): void
    {
        Arch::assertThat(__DIR__ . '/../src/Application/Handler')
            ->haveSuffix('Handler');
    }
}

Presets

Built-in presets enforce common architectural patterns with zero configuration:

#[Test]
public function dddRules(): void
{
    Arch::preset('ddd', [
        'domainDir' => __DIR__ . '/../src/Domain',
        'infrastructureDir' => __DIR__ . '/../src/Infrastructure',
        'applicationDir' => __DIR__ . '/../src/Application',
    ])->assert();
}

#[Test]
public function cqrsRules(): void
{
    Arch::preset('cqrs', [
        'commandDir' => __DIR__ . '/../src/Application/Command',
        'queryDir' => __DIR__ . '/../src/Application/Query',
        'handlerDir' => __DIR__ . '/../src/Application/Handler',
    ])->assert();
}

#[Test]
public function eventDrivenRules(): void
{
    Arch::preset('event-driven', [
        'eventDir' => __DIR__ . '/../src/Domain/Event',
    ])->assert();
}

#[Test]
public function modularRules(): void
{
    Arch::preset('modular', [
        'modulesDir' => __DIR__ . '/../modules',
        'contractSubNamespace' => 'Contract', // default
    ])->assert();
}

Available Assertions

Structural

Arch::assertThat($dir)
    ->areFinal()       // all classes must be final
    ->areReadonly()     // all classes must be readonly
    ->areAbstract()    // all classes must be abstract
    ->areInterfaces()  // all must be interfaces
    ->areEnums();      // all must be enums

Naming

Arch::assertThat($dir)
    ->haveSuffix('Handler')     // class name ends with Handler
    ->havePrefix('Abstract');   // class name starts with Abstract

Inheritance

Arch::assertThat($dir)
    ->implement(DomainEventInterface::class)   // must implement interface
    ->extend(AbstractEntity::class);           // must extend class

Dependencies

Arch::assertThat($dir)
    ->doesNotDependOn('App\Infrastructure')   // no imports from namespace
    ->onlyDependsOn([                         // whitelist allowed namespaces
        'App\Domain',
        'SolidFrame\Core',
        'SolidFrame\Ddd',
    ]);

Preset Rules

DDD Preset

Rule Description
Domain isolation Domain must not depend on Infrastructure or Application
ValueObject final All ValueObject classes must be final
ValueObject readonly All ValueObject classes must be readonly

CQRS Preset

Rule Description
Command immutability Commands must be final readonly
Query immutability Queries must be final readonly
Handler pairing Each Command/Query must have a matching Handler (optional)

Event-Driven Preset

Rule Description
Event immutability Events must be final readonly
Event interface Events must implement DomainEventInterface

Modular Preset

Rule Description
Module isolation Cross-module dependencies only allowed through Contract namespace

Custom Presets

Implement PresetInterface for your own rules:

use SolidFrame\Archtest\Preset\PresetInterface;

final readonly class MyCustomPreset implements PresetInterface
{
    public function __construct(private string $srcDir) {}

    public function evaluate(): array
    {
        $violations = [];

        // your validation logic...
        // return array of violation message strings

        return $violations;
    }
}

// Usage
Arch::presetFrom(new MyCustomPreset(__DIR__ . '/../src'))->assert();

API Reference

Class / Interface Purpose
Arch Main entry point: assertThat() and preset()
ArchExpectation Fluent assertion builder
PresetInterface Contract for custom presets
PresetResult Wraps preset with assert() method
DddPreset DDD rules (domain isolation, VO immutability)
CqrsPreset CQRS rules (message immutability, handler pairing)
EventDrivenPreset Event rules (immutability, interface)
ModularPreset Module isolation rules
ClassInfo Metadata about a PHP class
ClassFinder Discovers classes in directories
DependencyParser Extracts use-statement dependencies
ArchViolationException Thrown on rule violations

Related Packages

Contributing

This repository is a read-only split of the solidframe/solidframe monorepo, auto-synced on every push to main. Issues, pull requests, and discussions belong in the monorepo.

统计信息

  • 总下载量: 8
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 0
  • 点击次数: 7
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 0
  • Watchers: 0
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2026-04-18

承接程序开发

PHP开发

VUE

Vue开发

前端开发

小程序开发

公众号开发

系统定制

数据库设计

云部署

网站建设

安全加固