Requirement, Call, ConstantRequirement, Mirror, Problem, FeatureStatus, CompatibilityMatrix, Manifest, ManifestCheck sowie Fingerprints und LineDiff liegen jetzt im divi-freien Kern. Neu: GlobalRequirement, CompatibilityMatrix::fromProblems(), ManifestCheck-Option signatures, DiviManifestCheck::create() und DiviAreas. Divi-Verhalten unverändert. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
95 lines
3.4 KiB
PHP
95 lines
3.4 KiB
PHP
<?php
|
||
|
||
declare(strict_types=1);
|
||
|
||
namespace LIT\MCP\Tests\Unit\Compatibility;
|
||
|
||
use LIT\MCP\Compatibility\Capability;
|
||
use LIT\MCP\Compatibility\Problem;
|
||
use LIT\MCP\Integrations\Divi\Release\DiviFeature;
|
||
use PHPUnit\Framework\TestCase;
|
||
|
||
final class ProblemTest extends TestCase
|
||
{
|
||
public function testOnlyCallMirrorConstantAndResolverAreHard(): void
|
||
{
|
||
$hard = [];
|
||
foreach (['call', 'signature', 'mirror', 'constant', 'reference-missing', 'resolver'] as $kind) {
|
||
$hard[$kind] = (new Problem('x', [DiviFeature::PageWrite], $kind))->isHard();
|
||
}
|
||
|
||
self::assertSame(
|
||
['call' => true, 'signature' => false, 'mirror' => true, 'constant' => true,
|
||
'reference-missing' => false, 'resolver' => true],
|
||
$hard
|
||
);
|
||
}
|
||
|
||
public function testConcernsItsFeaturesAndWithoutFeaturesEveryFeature(): void
|
||
{
|
||
$problem = new Problem('x', [DiviFeature::PageWrite, DiviFeature::ThemeBuilderWrite], Problem::CALL);
|
||
self::assertTrue($problem->concerns(DiviFeature::ThemeBuilderWrite));
|
||
self::assertFalse($problem->concerns(DiviFeature::PageRead));
|
||
|
||
$unassigned = new Problem('x', [], Problem::CALL);
|
||
foreach (DiviFeature::cases() as $feature) {
|
||
self::assertTrue($unassigned->concerns($feature), $feature->value);
|
||
}
|
||
}
|
||
|
||
public function testRoundTripsThroughTheCacheFormat(): void
|
||
{
|
||
$problem = new Problem('Seiten: Nachbau von a() – x', [DiviFeature::PageWrite], Problem::MIRROR);
|
||
|
||
self::assertSame(
|
||
['label' => 'Seiten: Nachbau von a() – x', 'kind' => 'mirror', 'features' => ['page-write']],
|
||
$problem->toArray()
|
||
);
|
||
self::assertEquals($problem, Problem::fromArray($problem->toArray(), DiviFeature::tryFrom(...)));
|
||
}
|
||
|
||
public function testFromArrayRefusesAnythingElse(): void
|
||
{
|
||
foreach ([
|
||
'no array' => 'Seiten: x()',
|
||
'no label' => ['kind' => 'call', 'features' => []],
|
||
'unknown kind' => ['label' => 'x', 'kind' => 'other', 'features' => []],
|
||
'unknown feature' => ['label' => 'x', 'kind' => 'call', 'features' => ['page-delete']],
|
||
'features no list' => ['label' => 'x', 'kind' => 'call', 'features' => 'page-write'],
|
||
] as $case => $row) {
|
||
self::assertNull(Problem::fromArray($row, DiviFeature::tryFrom(...)), $case);
|
||
}
|
||
}
|
||
|
||
public function testFromArrayResolvesFeaturesThroughTheLookupClosure(): void
|
||
{
|
||
$pods = new class implements Capability {
|
||
public function id(): string
|
||
{
|
||
return 'pods-x';
|
||
}
|
||
|
||
public function label(): string
|
||
{
|
||
return 'Pods X';
|
||
}
|
||
|
||
public function isWrite(): bool
|
||
{
|
||
return false;
|
||
}
|
||
};
|
||
$lookup = static fn (string $id): ?Capability => $id === 'pods-x' ? $pods : null;
|
||
|
||
$problem = Problem::fromArray(['label' => 'x', 'kind' => 'call', 'features' => ['pods-x']], $lookup);
|
||
self::assertNotNull($problem);
|
||
self::assertSame([$pods], $problem->features);
|
||
self::assertTrue($problem->concerns($pods));
|
||
|
||
self::assertNull(
|
||
Problem::fromArray(['label' => 'x', 'kind' => 'call', 'features' => ['pods-x', 'page-read']], $lookup),
|
||
'one unknown ID discards the problem'
|
||
);
|
||
}
|
||
}
|