diff --git a/images/class_images/eq2_unknown.png b/images/class_images/eq2_unknown.png new file mode 100644 index 0000000..2d3996d Binary files /dev/null and b/images/class_images/eq2_unknown.png differ diff --git a/tests/game/eq2_icon_coverage_test.php b/tests/game/eq2_icon_coverage_test.php new file mode 100644 index 0000000..dc0d77a --- /dev/null +++ b/tests/game/eq2_icon_coverage_test.php @@ -0,0 +1,88 @@ +.png for character rows and + * roster_classes/.png for the grid, so a seeded class with no + * file behind it has no icon. avathar/bbguild#389 makes that degrade + * instead of rendering broken, but the asset is still missing. + */ +class eq2_icon_coverage_test extends TestCase +{ + /** Gaps that are known and tracked; see #7 */ + private const KNOWN_GAPS = array( + // none — fully covered + ); + + /** Same, for the grid's artwork directory */ + private const KNOWN_ROSTER_GAPS = array( + 'eq2_beastlord', + 'eq2_channeler', + 'eq2_unknown', + ); + + /** + * @return list Every imagename the installer seeds + */ + private function seeded_imagenames(): array + { + $files = glob(dirname(__DIR__, 2) . '/game/*_installer.php'); + $src = file_get_contents($files[0]); + + preg_match_all("/'imagename'\s*=>\s*'([^']+)'/", $src, $m); + + $names = array_values(array_unique(array_filter(array_map('trim', $m[1])))); + sort($names); + + return $names; + } + + private function assertNoUnexpectedGaps(string $dir, array $known): void + { + $base = dirname(__DIR__, 2) . '/images/' . $dir . '/'; + $missing = array(); + + foreach ($this->seeded_imagenames() as $name) + { + if (!file_exists($base . $name . '.png')) + { + $missing[] = $name; + } + } + + $unexpected = array_values(array_diff($missing, $known)); + + $this->assertSame( + array(), + $unexpected, + $dir . ' is missing icons that are not tracked as known gaps: ' . implode(', ', $unexpected) + ); + } + + public function test_class_images_cover_every_seeded_class(): void + { + $this->assertNoUnexpectedGaps('class_images', self::KNOWN_GAPS); + } + + public function test_roster_classes_cover_every_seeded_class(): void + { + $this->assertNoUnexpectedGaps('roster_classes', self::KNOWN_ROSTER_GAPS); + } + + public function test_the_installer_seeds_the_expected_class_count(): void + { + // Guards the parser: if the installer's array syntax changes, the + // coverage assertions must not silently pass on an empty list. + $this->assertCount(27, $this->seeded_imagenames()); + } +}