mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-04-18 15:05:56 +00:00
Upgraded block consistency check to detect tile changes
This commit is contained in:
parent
15e8895e54
commit
2ef02a2c5e
@ -27,6 +27,7 @@ use PHPUnit\Framework\TestCase;
|
||||
use pocketmine\utils\AssumptionFailedError;
|
||||
use pocketmine\utils\Filesystem;
|
||||
use pocketmine\utils\Utils;
|
||||
use function get_debug_type;
|
||||
use function implode;
|
||||
use function is_array;
|
||||
use function is_int;
|
||||
@ -95,11 +96,12 @@ class BlockTest extends TestCase{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int[]
|
||||
* @phpstan-return array<string, int>
|
||||
* @return int[][]|string[][]
|
||||
* @phpstan-return array{array<string, int>, array<string, string>}
|
||||
*/
|
||||
public static function computeConsistencyCheckTable(RuntimeBlockStateRegistry $blockStateRegistry) : array{
|
||||
$newTable = [];
|
||||
$newTileMap = [];
|
||||
|
||||
$idNameLookup = [];
|
||||
//if we ever split up block registration into multiple registries (e.g. separating chemistry blocks),
|
||||
@ -118,36 +120,70 @@ class BlockTest extends TestCase{
|
||||
}
|
||||
$idName = $idNameLookup[$block->getTypeId()];
|
||||
$newTable[$idName] = ($newTable[$idName] ?? 0) + 1;
|
||||
}
|
||||
|
||||
return $newTable;
|
||||
$tileClass = $block->getIdInfo()->getTileClass();
|
||||
if($tileClass !== null){
|
||||
if(isset($newTileMap[$idName]) && $newTileMap[$idName] !== $tileClass){
|
||||
throw new AssumptionFailedError("Tile entity $tileClass for $idName is inconsistent");
|
||||
}
|
||||
$newTileMap[$idName] = $tileClass;
|
||||
}
|
||||
}
|
||||
return [$newTable, $newTileMap];
|
||||
}
|
||||
|
||||
/**
|
||||
* @phpstan-param array<string, int> $actual
|
||||
* @phpstan-param array<string, int> $actualStateCounts
|
||||
* @phpstan-param array<string, string> $actualTiles
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public static function computeConsistencyCheckDiff(string $expectedFile, array $actual) : array{
|
||||
$expected = json_decode(Filesystem::fileGetContents($expectedFile), true, 2, JSON_THROW_ON_ERROR);
|
||||
public static function computeConsistencyCheckDiff(string $expectedFile, array $actualStateCounts, array $actualTiles) : array{
|
||||
$expected = json_decode(Filesystem::fileGetContents($expectedFile), true, 3, JSON_THROW_ON_ERROR);
|
||||
if(!is_array($expected)){
|
||||
throw new AssumptionFailedError("Old table should be array<string, int>");
|
||||
throw new AssumptionFailedError("Old table should be array{stateCounts: array<string, int>, tiles: array<string, string>}");
|
||||
}
|
||||
$expectedStates = $expected["stateCounts"] ?? [];
|
||||
$expectedTiles = $expected["tiles"] ?? [];
|
||||
if(!is_array($expectedStates)){
|
||||
throw new AssumptionFailedError("stateCounts should be an array, but have " . get_debug_type($expectedStates));
|
||||
}
|
||||
if(!is_array($expectedTiles)){
|
||||
throw new AssumptionFailedError("tiles should be an array, but have " . get_debug_type($expectedTiles));
|
||||
}
|
||||
|
||||
$errors = [];
|
||||
foreach(Utils::promoteKeys($expected) as $typeName => $numStates){
|
||||
foreach(Utils::promoteKeys($expectedStates) as $typeName => $numStates){
|
||||
if(!is_string($typeName) || !is_int($numStates)){
|
||||
throw new AssumptionFailedError("Old table should be array<string, int>");
|
||||
}
|
||||
if(!isset($actual[$typeName])){
|
||||
if(!isset($actualStateCounts[$typeName])){
|
||||
$errors[] = "Removed block type $typeName ($numStates permutations)";
|
||||
}elseif($actual[$typeName] !== $numStates){
|
||||
$errors[] = "Block type $typeName permutation count changed: $numStates -> " . $actual[$typeName];
|
||||
}elseif($actualStateCounts[$typeName] !== $numStates){
|
||||
$errors[] = "Block type $typeName permutation count changed: $numStates -> " . $actualStateCounts[$typeName];
|
||||
}
|
||||
}
|
||||
foreach(Utils::stringifyKeys($actual) as $typeName => $numStates){
|
||||
if(!isset($expected[$typeName])){
|
||||
$errors[] = "Added block type $typeName (" . $actual[$typeName] . " permutations)";
|
||||
foreach(Utils::stringifyKeys($actualStateCounts) as $typeName => $numStates){
|
||||
if(!isset($expectedStates[$typeName])){
|
||||
$errors[] = "Added block type $typeName (" . $actualStateCounts[$typeName] . " permutations)";
|
||||
}
|
||||
}
|
||||
|
||||
foreach(Utils::promoteKeys($expectedTiles) as $typeName => $tile){
|
||||
if(!is_string($typeName) || !is_string($tile)){
|
||||
throw new AssumptionFailedError("Tile table should be array<string, string>");
|
||||
}
|
||||
if(isset($actualStateCounts[$typeName])){
|
||||
if(!isset($actualTiles[$typeName])){
|
||||
$errors[] = "$typeName no longer has a tile";
|
||||
}elseif($actualTiles[$typeName] !== $tile){
|
||||
$errors[] = "$typeName has changed tile ($tile -> " . $actualTiles[$typeName] . ")";
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach(Utils::promoteKeys($actualTiles) as $typeName => $tile){
|
||||
if(isset($expectedStates[$typeName]) && !isset($expectedTiles[$typeName])){
|
||||
$errors[] = "$typeName has a tile when it previously didn't ($tile)";
|
||||
}
|
||||
}
|
||||
|
||||
@ -155,8 +191,8 @@ class BlockTest extends TestCase{
|
||||
}
|
||||
|
||||
public function testConsistency() : void{
|
||||
$newTable = self::computeConsistencyCheckTable($this->blockFactory);
|
||||
$errors = self::computeConsistencyCheckDiff(__DIR__ . '/block_factory_consistency_check.json', $newTable);
|
||||
[$newTable, $newTileMap] = self::computeConsistencyCheckTable($this->blockFactory);
|
||||
$errors = self::computeConsistencyCheckDiff(__DIR__ . '/block_factory_consistency_check.json', $newTable, $newTileMap);
|
||||
|
||||
self::assertEmpty($errors, "Block factory consistency check failed:\n" . implode("\n", $errors));
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -28,11 +28,11 @@ require dirname(__DIR__, 3) . '/vendor/autoload.php';
|
||||
|
||||
/* This script needs to be re-run after any intentional blockfactory change (adding or removing a block state). */
|
||||
|
||||
$newTable = BlockTest::computeConsistencyCheckTable(RuntimeBlockStateRegistry::getInstance());
|
||||
[$newTable, $newTiles] = BlockTest::computeConsistencyCheckTable(RuntimeBlockStateRegistry::getInstance());
|
||||
|
||||
$oldTablePath = __DIR__ . '/block_factory_consistency_check.json';
|
||||
if(file_exists($oldTablePath)){
|
||||
$errors = BlockTest::computeConsistencyCheckDiff($oldTablePath, $newTable);
|
||||
$errors = BlockTest::computeConsistencyCheckDiff($oldTablePath, $newTable, $newTiles);
|
||||
|
||||
if(count($errors) > 0){
|
||||
echo count($errors) . " changes detected:\n";
|
||||
@ -47,5 +47,6 @@ if(file_exists($oldTablePath)){
|
||||
}
|
||||
|
||||
ksort($newTable, SORT_STRING);
|
||||
ksort($newTiles, SORT_STRING);
|
||||
|
||||
file_put_contents($oldTablePath, json_encode($newTable, JSON_THROW_ON_ERROR | JSON_PRETTY_PRINT));
|
||||
file_put_contents($oldTablePath, json_encode(["stateCounts" => $newTable, "tiles" => $newTiles], JSON_THROW_ON_ERROR | JSON_PRETTY_PRINT));
|
||||
|
Loading…
x
Reference in New Issue
Block a user