Files
ik-codex/test/tests/Games/ProjectZomboid/Analyser/PerkLogAnalysisTest.php
indifferentketchup 0c90e40a28
Some checks failed
Tests / Run tests on PHP v8.4 (push) Failing after 1s
Tests / Run tests on PHP v8.5 (push) Failing after 0s
Add SkillProgressionAnomalyAnalyser
Compares consecutive perks-snapshot rows per Steam ID and emits a
SkillProgressionAnomalyProblem for any single skill whose level gained
more than THRESHOLD_DELTA between two snapshots. Login/Logout/LevelUp
event rows are skipped via a perk-pair regex check on the bracketed
event field.

Threshold of 3 reflects PZ's slow leveling pace: typical session bridges
should not produce four-or-more level jumps in a single skill. The
constant is documented inline so operators can tune for modded XP
servers without touching analysis logic.

Synthetic fixture extended with a PlayerSuspect Steam ID carrying two
snapshots: Strength jumps 2 -> 10 (delta +8, triggers), Fitness jumps
2 -> 8 (+6, triggers), Maintenance jumps 0 -> 3 (+3, exactly at
threshold, does NOT trigger). The existing single-snapshot players
remain noise-free.
2026-04-30 22:43:44 +00:00

67 lines
2.4 KiB
PHP

<?php
namespace IndifferentKetchup\Codex\Test\Tests\Games\ProjectZomboid\Analyser;
use IndifferentKetchup\Codex\Analyser\ProjectZomboid\SkillProgressionAnomalyAnalyser;
use IndifferentKetchup\Codex\Analysis\ProjectZomboid\SkillProgressionAnomalyProblem;
use IndifferentKetchup\Codex\Log\File\PathLogFile;
use IndifferentKetchup\Codex\Log\ProjectZomboid\ProjectZomboidPerkLog;
use PHPUnit\Framework\TestCase;
class PerkLogAnalysisTest extends TestCase
{
private function fixturePath(): string
{
return __DIR__ . '/../../../../src/Games/ProjectZomboid/fixtures/perk-minimal.txt';
}
public function testFlagsSkillsThatExceedDeltaThreshold(): void
{
$log = (new ProjectZomboidPerkLog())->setLogFile(new PathLogFile($this->fixturePath()));
$log->parse();
$analysis = $log->analyse();
$problems = $analysis->getFilteredInsights(SkillProgressionAnomalyProblem::class);
$skills = array_map(fn($p) => $p->getSkill(), $problems);
sort($skills);
$this->assertSame(['Fitness', 'Strength'], $skills);
foreach ($problems as $problem) {
$this->assertSame('76561198000000004', $problem->getSteamId());
$this->assertSame('PlayerSuspect', $problem->getPlayer());
}
}
public function testDeltaAtThresholdDoesNotTrigger(): void
{
$log = (new ProjectZomboidPerkLog())->setLogFile(new PathLogFile($this->fixturePath()));
$log->parse();
$analysis = $log->analyse();
$problems = $analysis->getFilteredInsights(SkillProgressionAnomalyProblem::class);
foreach ($problems as $problem) {
$this->assertNotSame('Maintenance', $problem->getSkill());
}
}
public function testSinglePlayerWithOneSnapshotProducesNoProblem(): void
{
$log = (new ProjectZomboidPerkLog())->setLogFile(new PathLogFile($this->fixturePath()));
$log->parse();
$analysis = $log->analyse();
$problems = $analysis->getFilteredInsights(SkillProgressionAnomalyProblem::class);
foreach ($problems as $problem) {
$this->assertNotSame('76561198000000001', $problem->getSteamId());
$this->assertNotSame('76561198000000002', $problem->getSteamId());
}
}
public function testThresholdConstantIsDocumentedAndPositive(): void
{
$this->assertGreaterThan(0, SkillProgressionAnomalyAnalyser::THRESHOLD_DELTA);
}
}