Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
128 lines
5.0 KiB
PHP
128 lines
5.0 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace LIT\MCP\Tests\Unit\Integrations\Divi\Release;
|
|
|
|
use LIT\MCP\Integrations\Divi\Release\CompatibilityMatrix;
|
|
use LIT\MCP\Integrations\Divi\Release\DiviFeature;
|
|
use LIT\MCP\Integrations\Divi\Release\FeatureStatus;
|
|
use LIT\MCP\Integrations\Divi\Release\ReleaseState;
|
|
use PHPUnit\Framework\TestCase;
|
|
|
|
final class CompatibilityMatrixTest extends TestCase
|
|
{
|
|
public function testAFeatureWithoutResultIsIncompatible(): void
|
|
{
|
|
$matrix = new CompatibilityMatrix([
|
|
'page-read' => new FeatureStatus(DiviFeature::PageRead, ReleaseState::Released, [], 'code'),
|
|
// Under the wrong key: does not count for page-write.
|
|
'page-write' => new FeatureStatus(DiviFeature::PageRead, ReleaseState::Released, [], 'code'),
|
|
]);
|
|
|
|
self::assertTrue($matrix->of(DiviFeature::PageRead)->usable());
|
|
foreach ([DiviFeature::PageWrite, DiviFeature::ThemeBuilderWrite] as $feature) {
|
|
$status = $matrix->of($feature);
|
|
self::assertSame(ReleaseState::Incompatible, $status->state);
|
|
self::assertSame([CompatibilityMatrix::MISSING], $status->problems);
|
|
}
|
|
self::assertCount(count(DiviFeature::cases()) - 1, $matrix->unusable());
|
|
}
|
|
|
|
public function testAllReleasedAndAllIncompatible(): void
|
|
{
|
|
$released = CompatibilityMatrix::allReleased('database');
|
|
$broken = CompatibilityMatrix::allIncompatible('kaputt');
|
|
|
|
foreach (DiviFeature::cases() as $feature) {
|
|
self::assertTrue($released->of($feature)->usable());
|
|
self::assertSame('database', $released->of($feature)->source);
|
|
self::assertSame(ReleaseState::Incompatible, $broken->of($feature)->state);
|
|
self::assertSame(['kaputt'], $broken->of($feature)->problems);
|
|
self::assertNull($broken->of($feature)->source);
|
|
}
|
|
self::assertSame([], $released->unusable());
|
|
self::assertSame('code', CompatibilityMatrix::allReleased()->source());
|
|
}
|
|
|
|
public function testTheStateIsTheWorstFeatureAndEveryProblemIsListedOnce(): void
|
|
{
|
|
$matrix = self::matrix([
|
|
'page-write' => [ReleaseState::Untested, ['a']],
|
|
'tb-write' => [ReleaseState::Incompatible, ['b', 'a']],
|
|
]);
|
|
|
|
self::assertSame(ReleaseState::Incompatible, $matrix->state());
|
|
self::assertSame(['a', 'b'], $matrix->problems());
|
|
self::assertNull($matrix->source());
|
|
self::assertSame(ReleaseState::Untested, self::matrix(['catalog' => [ReleaseState::Untested, []]])->state());
|
|
self::assertSame(ReleaseState::Released, self::matrix([])->state());
|
|
}
|
|
|
|
public function testTheSourceOfAReleasedMatrixIsCommonOrNull(): void
|
|
{
|
|
self::assertSame('auto', self::matrix([])->source());
|
|
|
|
$mixed = new CompatibilityMatrix(array_merge(
|
|
self::features([]),
|
|
['roles' => new FeatureStatus(DiviFeature::Roles, ReleaseState::Released, [], 'code')]
|
|
));
|
|
self::assertSame(ReleaseState::Released, $mixed->state());
|
|
self::assertNull($mixed->source());
|
|
}
|
|
|
|
public function testUsableAndUnusable(): void
|
|
{
|
|
$matrix = self::matrix(['catalog' => [ReleaseState::Untested, []]]);
|
|
|
|
self::assertTrue($matrix->usable([DiviFeature::PageWrite, DiviFeature::PageRead]));
|
|
self::assertFalse($matrix->usable([DiviFeature::PageWrite, DiviFeature::Catalog]));
|
|
self::assertTrue($matrix->usable([]));
|
|
self::assertSame(
|
|
[DiviFeature::Catalog],
|
|
array_map(static fn (FeatureStatus $status): DiviFeature => $status->feature, $matrix->unusable())
|
|
);
|
|
}
|
|
|
|
public function testToArrayListsEveryFeatureInCaseOrder(): void
|
|
{
|
|
$rows = self::matrix(['tb-write' => [ReleaseState::Incompatible, ['b']]])->toArray();
|
|
|
|
self::assertSame(
|
|
array_map(static fn (DiviFeature $feature): string => $feature->value, DiviFeature::cases()),
|
|
array_column($rows, 'id')
|
|
);
|
|
self::assertContains(
|
|
['id' => 'tb-write', 'label' => DiviFeature::ThemeBuilderWrite->label(), 'state' => 'incompatible',
|
|
'problems' => ['b'], 'source' => null],
|
|
$rows
|
|
);
|
|
}
|
|
|
|
/**
|
|
* @param array<string, array{ReleaseState, list<string>}> $locked
|
|
* @return array<string, FeatureStatus>
|
|
*/
|
|
private static function features(array $locked): array
|
|
{
|
|
$features = [];
|
|
foreach (DiviFeature::cases() as $feature) {
|
|
[$state, $problems] = $locked[$feature->value] ?? [ReleaseState::Released, []];
|
|
$features[$feature->value] = new FeatureStatus(
|
|
$feature,
|
|
$state,
|
|
$problems,
|
|
$state === ReleaseState::Released ? 'auto' : null
|
|
);
|
|
}
|
|
|
|
return $features;
|
|
}
|
|
|
|
/** @param array<string, array{ReleaseState, list<string>}> $locked */
|
|
private static function matrix(array $locked): CompatibilityMatrix
|
|
{
|
|
return new CompatibilityMatrix(self::features($locked));
|
|
}
|
|
}
|