tests/Codes/Armaments/MeleeWeaponCodeTest.php
<?php declare(strict_types=1);
namespace DrdPlus\Tests\Codes\Armaments;
use DrdPlus\Codes\Armaments\Exceptions\CanNotBeConvertedToRangeWeaponCode;
use DrdPlus\Codes\Armaments\MeleeWeaponCode;
use DrdPlus\Codes\Armaments\RangedWeaponCode;
use DrdPlus\Codes\Armaments\WeaponCategoryCode;
use DrdPlus\Codes\Partials\Exceptions\UnknownValueForCode;
use Granam\String\StringTools;
class MeleeWeaponCodeTest extends WeaponCodeTest
{
use MeleeWeaponlikeCodeTrait;
/**
* @test
*/
public function I_can_easily_composer_method_to_get_weapons_of_same_category()
{
foreach (WeaponCategoryCode::getMeleeWeaponCategoryValues() as $meleeWeaponCategoryValue) {
$getMeleeWeaponOfCategory = StringTools::assembleGetterForName($meleeWeaponCategoryValue . 'Values');
self::assertTrue(method_exists(self::getSutClass(), $getMeleeWeaponOfCategory));
}
}
/**
* @param string $weaponlikeCode
* @param string $interferingCodeClass
* @return bool
*/
protected function isSameCodeAllowedFor(string $weaponlikeCode, string $interferingCodeClass): bool
{
try {
return \is_a(MeleeWeaponCode::getIt($weaponlikeCode)->convertToRangedWeaponCodeEquivalent(), $interferingCodeClass);
} catch (CanNotBeConvertedToRangeWeaponCode $canNotBeConvertedToRangeWeaponCode) {
return false;
} catch (UnknownValueForCode $unknownValueForCode) {
return false;
}
}
/**
* @test
*/
public function It_is_melee_weapon_code()
{
/** @var MeleeWeaponCode $sut */
$sut = $this->getSut();
self::assertInstanceOf(MeleeWeaponCode::class, $sut);
self::assertTrue($sut->isMeleeWeapon());
}
/**
* @test
*/
public function I_can_easily_find_out_if_is_melee()
{
/** @var MeleeWeaponCode $sut */
$sut = $this->getSut();
self::assertTrue($sut->isMelee());
}
/**
* @test
*/
public function I_can_get_axe_codes()
{
self::assertSame(
[
'light_axe',
'axe',
'war_axe',
'two_handed_axe',
],
MeleeWeaponCode::getAxesValues()
);
}
/**
* @test
*/
public function I_can_get_knife_and_dagger_codes()
{
self::assertSame(
[
'knife',
'dagger',
'stabbing_dagger',
'long_knife',
'long_dagger',
],
MeleeWeaponCode::getKnivesAndDaggersValues()
);
}
/**
* @test
*/
public function I_can_get_mace_and_club_codes()
{
self::assertSame(
[
'cudgel',
'club',
'hobnailed_club',
'light_mace',
'mace',
'heavy_club',
'war_hammer',
'two_handed_club',
'heavy_sledgehammer',
],
MeleeWeaponCode::getMacesAndClubsValues()
);
}
/**
* @test
*/
public function I_can_get_morningstar_and_morgenstern_codes()
{
self::assertSame(
[
'light_morgenstern',
'morgenstern',
'heavy_morgenstern',
'flail',
'morningstar',
'hobnailed_flail',
'heavy_morningstar',
],
MeleeWeaponCode::getMorningstarsAndMorgensternsValues()
);
}
/**
* @test
*/
public function I_can_get_saber_and_bowie_knife_codes()
{
self::assertSame(
[
'machete',
'light_saber',
'bowie_knife',
'saber',
'heavy_saber',
],
MeleeWeaponCode::getSabersAndBowieKnivesValues()
);
}
/**
* @test
*/
public function I_can_get_staff_and_spear_codes()
{
self::assertSame(
[
'light_spear',
'shortened_staff',
'light_staff',
'spear',
'hobnailed_staff',
'long_spear',
'heavy_hobnailed_staff',
'pike',
'metal_staff',
],
MeleeWeaponCode::getStaffsAndSpearsValues()
);
}
/**
* @test
*/
public function I_can_get_sword_codes()
{
self::assertSame(
[
'short_sword',
'hanger',
'glaive',
'long_sword',
'one_and_half_handed_sword',
'barbarian_sword',
'two_handed_sword',
],
MeleeWeaponCode::getSwordsValues()
);
}
/**
* @test
*/
public function I_can_get_voulges_and_trident_codes()
{
self::assertSame(
[
'pitchfork',
'light_voulge',
'light_trident',
'halberd',
'heavy_voulge',
'heavy_trident',
'heavy_halberd',
],
MeleeWeaponCode::getVoulgesAndTridentsValues()
);
}
/**
* @test
*/
public function I_can_get_unarmed_codes()
{
self::assertSame(
[
'hand',
'hobnailed_glove',
'leg',
'hobnailed_boot',
],
MeleeWeaponCode::getUnarmedValues()
);
}
/**
* @test
*/
public function I_can_get_all_codes_at_once_or_by_same_named_constant()
{
self::assertSame(
$expectedValues = [
// unarmed
'hand',
'hobnailed_glove',
'leg',
'hobnailed_boot',
// axes
'light_axe',
'axe',
'war_axe',
'two_handed_axe',
// knives and daggers
'knife',
'dagger',
'stabbing_dagger',
'long_knife',
'long_dagger',
// maces and clubs
'cudgel',
'club',
'hobnailed_club',
'light_mace',
'mace',
'heavy_club',
'war_hammer',
'two_handed_club',
'heavy_sledgehammer',
// morningstars and morgensterns
'light_morgenstern',
'morgenstern',
'heavy_morgenstern',
'flail',
'morningstar',
'hobnailed_flail',
'heavy_morningstar',
// sabers and bowie knives
'machete',
'light_saber',
'bowie_knife',
'saber',
'heavy_saber',
// staffs and spears
'light_spear',
'shortened_staff',
'light_staff',
'spear',
'hobnailed_staff',
'long_spear',
'heavy_hobnailed_staff',
'pike',
'metal_staff',
// swords
'short_sword',
'hanger',
'glaive',
'long_sword',
'one_and_half_handed_sword',
'barbarian_sword',
'two_handed_sword',
// voulges and tridents
'pitchfork',
'light_voulge',
'light_trident',
'halberd',
'heavy_voulge',
'heavy_trident',
'heavy_halberd',
],
MeleeWeaponCode::getPossibleValues(),
'There are ' . (
\count($missingOrDifferent = \array_diff_assoc($expectedValues, MeleeWeaponCode::getPossibleValues())) > 0
? 'missing values or different keys in given: ' . \var_export($missingOrDifferent, true)
: 'superfluous values or different keys in given: ' . \var_export(\array_diff_assoc(MeleeWeaponCode::getPossibleValues(), $expectedValues), true)
)
);
}
/**
* @test
*/
public function I_can_ask_code_if_is_specific_weapon_type()
{
$questions = [
'isAxe', 'isKnifeOrDagger', 'isMaceOrClub', 'isMorningstarOrMorgenstern', 'isSaberOrBowieKnife',
'isStaffOrSpear', 'isSword', 'isVoulgeOrTrident', 'isUnarmed',
];
foreach (MeleeWeaponCode::getAxesValues() as $codeValue) {
$code = MeleeWeaponCode::getIt($codeValue);
self::assertTrue($code->isMelee());
self::assertFalse($code->isRanged());
self::assertTrue($code->isAxe());
foreach ($questions as $question) {
if ($question !== 'isAxe') {
self::assertFalse($code->$question());
}
}
}
foreach (MeleeWeaponCode::getKnivesAndDaggersValues() as $codeValue) {
$code = MeleeWeaponCode::getIt($codeValue);
self::assertTrue($code->isMelee());
self::assertFalse($code->isRanged());
self::assertTrue($code->isKnifeOrDagger());
foreach ($questions as $question) {
if ($question !== 'isKnifeOrDagger') {
self::assertFalse($code->$question());
}
}
}
foreach (MeleeWeaponCode::getMacesAndClubsValues() as $codeValue) {
$code = MeleeWeaponCode::getIt($codeValue);
self::assertTrue($code->isMelee());
self::assertFalse($code->isRanged());
self::assertTrue($code->isMaceOrClub());
foreach ($questions as $question) {
if ($question !== 'isMaceOrClub') {
self::assertFalse($code->$question());
}
}
}
foreach (MeleeWeaponCode::getMorningstarsAndMorgensternsValues() as $codeValue) {
$code = MeleeWeaponCode::getIt($codeValue);
self::assertTrue($code->isMelee());
self::assertFalse($code->isRanged());
self::assertTrue($code->isMorningstarOrMorgenstern());
foreach ($questions as $question) {
if ($question !== 'isMorningstarOrMorgenstern') {
self::assertFalse($code->$question());
}
}
}
foreach (MeleeWeaponCode::getSabersAndBowieKnivesValues() as $codeValue) {
$code = MeleeWeaponCode::getIt($codeValue);
self::assertTrue($code->isMelee());
self::assertFalse($code->isRanged());
self::assertTrue($code->isSaberOrBowieKnife());
foreach ($questions as $question) {
if ($question !== 'isSaberOrBowieKnife') {
self::assertFalse($code->$question());
}
}
}
foreach (MeleeWeaponCode::getStaffsAndSpearsValues() as $codeValue) {
$code = MeleeWeaponCode::getIt($codeValue);
self::assertTrue($code->isMelee());
self::assertFalse($code->isRanged());
self::assertTrue($code->isStaffOrSpear());
foreach ($questions as $question) {
if ($question !== 'isStaffOrSpear') {
if ($question !== 'isThrowingWeapon' || $codeValue !== MeleeWeaponCode::SPEAR) {
self::assertFalse($code->$question());
} else {
self::assertTrue($code->$question());
}
}
}
}
foreach (MeleeWeaponCode::getSwordsValues() as $codeValue) {
$code = MeleeWeaponCode::getIt($codeValue);
self::assertTrue($code->isMelee());
self::assertFalse($code->isRanged());
self::assertTrue($code->isSword());
foreach ($questions as $question) {
if ($question !== 'isSword') {
self::assertFalse($code->$question());
}
}
}
foreach (MeleeWeaponCode::getVoulgesAndTridentsValues() as $codeValue) {
$code = MeleeWeaponCode::getIt($codeValue);
self::assertTrue($code->isMelee());
self::assertFalse($code->isRanged());
self::assertTrue($code->isVoulgeOrTrident());
foreach ($questions as $question) {
if ($question !== 'isVoulgeOrTrident') {
self::assertFalse($code->$question());
}
}
}
foreach (MeleeWeaponCode::getUnarmedValues() as $codeValue) {
$code = MeleeWeaponCode::getIt($codeValue);
self::assertTrue($code->isMelee());
self::assertFalse($code->isRanged());
self::assertTrue($code->isUnarmed());
foreach ($questions as $question) {
if ($question !== 'isUnarmed') {
self::assertFalse($code->$question());
}
}
}
}
/**
* @test
*/
public function I_can_convert_spear_to_range_weapon_code()
{
$meleeSpear = MeleeWeaponCode::getIt(MeleeWeaponCode::SPEAR);
self::assertInstanceOf(MeleeWeaponCode::class, $meleeSpear);
self::assertSame($meleeSpear, $meleeSpear->convertToMeleeWeaponCodeEquivalent());
$rangeSpear = $meleeSpear->convertToRangedWeaponCodeEquivalent();
self::assertNotSame($meleeSpear, $rangeSpear);
self::assertInstanceOf(RangedWeaponCode::class, $rangeSpear);
self::assertSame(RangedWeaponCode::getIt(RangedWeaponCode::SPEAR), $rangeSpear);
}
/**
* @test
*/
public function I_can_not_convert_anything_to_melee_weapon_code()
{
$this->expectException(\DrdPlus\Codes\Armaments\Exceptions\CanNotBeConvertedToRangeWeaponCode::class);
$this->expectExceptionMessageMatches('~cudgel~');
$wantItRange = MeleeWeaponCode::getIt(MeleeWeaponCode::CUDGEL);
self::assertFalse($wantItRange->isRanged());
$wantItRange->convertToRangedWeaponCodeEquivalent();
}
/**
* @test
*/
public function I_get_from_melee_code_negative_answer_to_most_range_question()
{
foreach (MeleeWeaponCode::getPossibleValues() as $meleeWeaponCode) {
$meleeWeaponCode = MeleeWeaponCode::getIt($meleeWeaponCode);
self::assertTrue($meleeWeaponCode->isMelee());
self::assertFalse($meleeWeaponCode->isRanged());
self::assertFalse($meleeWeaponCode->isThrowingWeapon());
self::assertFalse($meleeWeaponCode->isShootingWeapon());
self::assertFalse($meleeWeaponCode->isProjectile());
}
}
/**
* @test
*/
public function I_can_easily_find_out_if_is_shield()
{
self::assertFalse(MeleeWeaponCode::getIt(MeleeWeaponCode::CLUB)->isShield());
}
/**
* @test
*/
public function I_can_easily_find_out_if_is_melee_weapon()
{
self::assertTrue(MeleeWeaponCode::getIt(MeleeWeaponCode::CLUB)->isMeleeWeapon());
}
/**
* @test
*/
public function I_can_easily_find_out_if_weapon_is_unarmed_in_fact()
{
foreach (MeleeWeaponCode::getPossibleValues() as $meleeWeaponCodeValue) {
$meleeWeaponCode = MeleeWeaponCode::getIt($meleeWeaponCodeValue);
self::assertSame(
\in_array($meleeWeaponCodeValue, MeleeWeaponCode::getUnarmedValues(), true),
$meleeWeaponCode->isUnarmed()
);
}
self::assertSame(
[
MeleeWeaponCode::HAND,
MeleeWeaponCode::HOBNAILED_GLOVE,
MeleeWeaponCode::LEG,
MeleeWeaponCode::HOBNAILED_BOOT,
],
MeleeWeaponCode::getUnarmedValues()
);
}
/**
* @test
*/
public function I_can_easily_find_out_if_is_ranged()
{
self::assertFalse(MeleeWeaponCode::getIt(MeleeWeaponCode::CUDGEL)->isRanged());
}
protected function getWeaponCategoryValues(): array
{
return WeaponCategoryCode::getMeleeWeaponCategoryValues();
}
/**
* @test
* @runInSeparateProcess
*/
public function I_can_not_add_new_melee_weapon_code_with_not_melee_category()
{
$this->expectException(\DrdPlus\Codes\Armaments\Exceptions\InvalidWeaponCategoryForNewMeleeWeaponCode::class);
$this->expectExceptionMessageMatches('~throwing~');
$throwingCategory = WeaponCategoryCode::getIt(WeaponCategoryCode::THROWING_WEAPONS);
self::assertFalse($throwingCategory->isMeleeWeaponCategory());
MeleeWeaponCode::addNewMeleeWeaponCode('foo', $throwingCategory, []);
}
/**
* @test
* @runInSeparateProcess
* @throws \ReflectionException
*/
public function I_can_not_extended_it_by_same_code_but_different_category()
{
$this->expectException(\DrdPlus\Codes\Armaments\Exceptions\MeleeWeaponIsAlreadyInDifferentWeaponCategory::class);
$reflectionClass = new \ReflectionClass(MeleeWeaponCode::class);
$translations = $reflectionClass->getProperty('translations');
$translations->setAccessible(true);
// to reset already initialized translations and force them to be loaded again
$translations->setValue(null);
$translations->setAccessible(false);
self::assertNotContains('corge', MeleeWeaponCode::getPossibleValues());
self::assertTrue(
MeleeWeaponCode::addNewMeleeWeaponCode('corge', $someCategory = $this->getRandomWeaponCategoryCode(), [])
);
$differentCategory = $this->getRandomWeaponCategoryCode($someCategory);
self::assertNotEquals($someCategory, $differentCategory);
MeleeWeaponCode::addNewMeleeWeaponCode('corge', $differentCategory, []);
}
/**
* @test
*/
public function I_can_get_it_with_default_value()
{
$sut = $this->findSut();
self::assertSame(MeleeWeaponCode::HAND, $sut->getValue(), 'Expected bare hands as a default value');
}
}