new Manifest( Manifest::PAGES, calls: [ new Call('strlen', 1), new Call('lit_mcp_missing_function', 0), new Call(ArrayObject::class . '::count', 0), new Call('Missing\Klass::run', 0), new Call('str_replace'), ], constants: ['PHP_VERSION', 'LIT_MCP_MISSING_CONSTANT'], postTypes: ['et_pb_layout'], taxonomies: ['scope'], blockTypes: ['divi/global-layout'], mirrors: [ new Mirror('same', 'a.php', 'a', null, 'gleich'), new Mirror('changed', 'b.php', 'b', null, 'geändert'), new Mirror('unreadable', 'c.php', 'c', null, 'fehlt'), new Mirror('no-expectation', 'd.php', 'd', null, 'ohne Soll'), ] ), ]; $currentHashes = ['same' => 'h1', 'changed' => 'hX', 'no-expectation' => 'h4']; return new ManifestCheck( $manifests, ['same' => 'h1', 'changed' => 'h2', 'unreadable' => 'h3'], $current ?? static fn (Mirror $mirror): ?string => $currentHashes[$mirror->id] ?? null, static fn (string $name): bool => false ); } public function testCodeChecksCoverExistenceAndArgumentCount(): void { self::assertSame( [ 'Seiten: strlen()', 'Seiten: lit_mcp_missing_function()', 'Seiten: ArrayObject::count()', 'Seiten: Klass::run()', 'Seiten: str_replace()', 'Seiten: Konstante PHP_VERSION', 'Seiten: Konstante LIT_MCP_MISSING_CONSTANT', ], array_keys($this->check()->codeChecks()) ); self::assertSame( [ 'Seiten: lit_mcp_missing_function()', 'Seiten: Klass::run()', 'Seiten: Konstante LIT_MCP_MISSING_CONSTANT', ], ManifestCheck::failed($this->check()->codeChecks()) ); } public function testAcceptsChecksTheArgumentCountTheAdapterPasses(): void { self::assertTrue(ManifestCheck::accepts(new Call('strlen', 1))); self::assertFalse(ManifestCheck::accepts(new Call('strlen', 2)), 'strlen takes one argument'); self::assertFalse(ManifestCheck::accepts(new Call('str_replace', 2)), 'str_replace needs three'); self::assertTrue(ManifestCheck::accepts(new Call('sprintf', 5)), 'variadic'); self::assertTrue(ManifestCheck::accepts(new Call('str_replace')), 'existence only'); } public function testMirrorChecksCompareWithTheExpectedFingerprints(): void { $checks = $this->check()->mirrorChecks(); self::assertSame( [ 'Seiten: Nachbau von a() – gleich', 'Seiten: Nachbau von b() – geändert', 'Seiten: Nachbau von c() – fehlt', 'Seiten: Nachbau von d() – ohne Soll', ], array_keys($checks) ); self::assertSame( [ 'Seiten: Nachbau von b() – geändert', 'Seiten: Nachbau von c() – fehlt', 'Seiten: Nachbau von d() – ohne Soll', ], ManifestCheck::failed($checks) ); } public function testUnreadableMirrorIsAFailedCheck(): void { $check = $this->check(static function (): ?string { throw new RuntimeException('Divi file gone'); }); self::assertCount(4, ManifestCheck::failed($check->mirrorChecks())); } public function testRegistrationChecksAskWordPressAndDivi(): void { Functions\when('post_type_exists')->justReturn(true); Functions\when('taxonomy_exists')->justReturn(false); $checks = $this->check()->registrationChecks(); self::assertSame( ['Seiten: Post-Typ et_pb_layout', 'Seiten: Taxonomie scope', 'Seiten: Block-Typ divi/global-layout'], array_keys($checks) ); self::assertSame( ['Seiten: Taxonomie scope', 'Seiten: Block-Typ divi/global-layout'], ManifestCheck::failed($checks) ); } }