Files
core/tests/Models/CharacterModelTest.php

240 lines
7.6 KiB
PHP

<?php
declare(strict_types=1);
namespace LotGD\Core\Tests\Models;
use LotGD\Core\EventHandler;
use LotGD\Core\EventManager;
use LotGD\Core\Events\EventContext;
use LotGD\Core\Exceptions\UnexpectedArrayKeyException;
use LotGD\Core\Game;
use LotGD\Core\GameBuilder;
use LotGD\Core\Models\Character;
use LotGD\Core\Models\CharacterProperty;
use LotGD\Core\Tests\CoreModelTestCase;
use LotGD\Core\Models\Repositories\CharacterRepository;
use Ramsey\Uuid\UuidInterface;
/**
* Tests the management of Characters
*/
class CharacterModelTest extends CoreModelTestCase
{
/** @var string default data set */
protected $dataset = "character";
/**
* Tests for soft deletion
*/
public function testSoftDeletion()
{
$chars = $this->getEntityManager()->getRepository(Character::class)->find("10000000-0000-0000-0000-000000000003");
$this->assertSame(null, $chars);
$allChars = $this->getEntityManager()->getRepository(Character::class)->findAll();
$this->assertSame(3, count($allChars));
$char = $this->getEntityManager()->getRepository(Character::class)->find("10000000-0000-0000-0000-000000000001");
$char->delete($this->getEntityManager());
$this->getEntityManager()->flush();
$this->getEntityManager()->clear();
$allChars = $this->getEntityManager()
->getRepository(Character::class)
->findAll();
$this->assertSame(2, count($allChars));
$allChars = $this->getEntityManager()
->getRepository(Character::class)
->findAll(CharacterRepository::INCLUDE_SOFTDELETED);
$this->assertSame(4, count($allChars));
}
/**
* Returns data to create valid characters
* @return array $futureId => $characterData
*/
public function validCharacters(): array
{
return [
[[
"name" => "Testcharacter",
"maxHealth" => 250
]],
[[
"name" => "Spamegg",
"maxHealth" => 42
]],
];
}
/**
* Returns data to create invalid characters
* @return array A list of faulty characters
*/
public function invalidCharacters(): array
{
return [
[[
"name" => 16,
"maxHealth" => 16,
]],
[[
"name" => "Faulter",
"maxHealth" => 17.8,
]],
];
}
/**
* Tests character creation
* @param array $characterData
* @dataProvider validCharacters
*/
public function testCreation(array $characterData)
{
$em = $this->getEntityManager();
$characterEntity = Character::create($characterData);
$characterEntity->setProperty("a property", 16);
$this->assertSame(16, $characterEntity->getProperty("a property"));
$characterEntity->save($em);
$em->flush();
$this->assertInstanceOf(UuidInterface::class, $characterEntity->getId());
$this->assertSame(16, $characterEntity->getProperty("a property"));
$em->flush();
}
/**
* Tests character creation with faulty data
* @param array $characterData
* @dataProvider invalidCharacters
*/
public function testFaultyCreation(array $characterData)
{
$this->expectException(\TypeError::class);
Character::create($characterData);
}
/**
* Tests if invalid array key given during Character::create throws an exception
*/
public function testUnknownArrayKey()
{
$this->expectException(UnexpectedArrayKeyException::class);
Character::create([
"name" => "Walter",
"maxHealth" => 15,
"unknownAttribute" => "helloWorld",
]);
}
/**
* Tests if Deletor does it's work
*/
public function testDeletion()
{
$em = $this->getEntityManager();
// Count rows before
$rowsBefore = count($em->getRepository(Character::class)->findAll());
// Delete one row
$character = $em->getRepository(Character::class)->find("10000000-0000-0000-0000-000000000001");
$character->delete($em);
$em->clear();
$rowsAfter = count($em->getRepository(Character::class)->findAll());
$this->assertEquals($rowsBefore - 1, $rowsAfter);
// test flushing
$em->flush();
}
/**
* Tests character properties
*/
public function testProperties()
{
$em = $this->getEntityManager();
// test default values
$firstCharacter = $em->getRepository(Character::class)->find("10000000-0000-0000-0000-000000000001");
$this->assertSame(5, $firstCharacter->getProperty("dragonkills", 5));
$this->assertNotSame(5, $firstCharacter->getProperty("dragonkills", "5"));
$this->assertSame("hanniball", $firstCharacter->getProperty("petname", "hanniball"));
// test setting variables, then getting
$firstCharacter->setProperty("dragonkills", 5);
$this->assertSame(5, $firstCharacter->getProperty("dragonkills"));
$this->assertNotSame("5", $firstCharacter->getProperty("dragonkills"));
$firstCharacter->setProperty("dragonkills", "20");
$this->assertNotSame(20, $firstCharacter->getProperty("dragonkills"));
$this->assertSame("20", $firstCharacter->getProperty("dragonkills"));
// save some other variables
$firstCharacter->setProperty("testvar1", 5);
$firstCharacter->setProperty("testvar2", [5 => 18]);
$firstCharacter->setProperty("testvar3 9 8", "spam and eggs");
$firstCharacter->setProperty("testvar4", true);
// test precreated property
$this->assertSame("hallo", $firstCharacter->getProperty("test"));
// test flushing
$em->flush();
// revisit database and retrieve properties, check if the correct number is saved
$total = intval($em->createQueryBuilder()
->from(CharacterProperty::class, "u")
->select("COUNT(u.propertyName)")
->getQuery()->getSingleScalarResult());
$this->assertSame(6, $total);
}
public function testIfAttackPublishesEvent()
{
$level = mt_rand(0, 100);
$character1 = Character::create(["name" => "Test", "maxHealth" => 10, "level" => $level]);
$character1->setGame($this->g);
$character2 = Character::create(["name" => "Test", "maxHealth" => 10, "level" => $level*2]);
$character2->setGame($this->g);
$detectionClass = new class implements EventHandler {
static $events_called = [];
public static function handleEvent(Game $g, EventContext $context): EventContext
{
$event = $context->getEvent();
$value = $context->getDataField("value");
self::$events_called[$event] = $value;
$context->setDataField("value", $value*2);
return $context;
}
};
/** @var EventManager $eventManager */
$eventManager = $this->g->getEventManager();
$eventManager->subscribe("#h/lotgd/core/getCharacterAttack#", get_class($detectionClass), "test");
$eventManager->subscribe("#h/lotgd/core/getCharacterDefense#", get_class($detectionClass), "test");
$this->getEntityManager()->flush();
$this->assertSame($level*2, $character1->getAttack());
$this->assertSame($level*4, $character2->getDefense());
$this->assertSame($level, $detectionClass::$events_called["h/lotgd/core/getCharacterAttack"]);
$this->assertSame($level*2, $detectionClass::$events_called["h/lotgd/core/getCharacterDefense"]);
}
}