CombatBaseTest   A
last analyzed

Complexity

Total Complexity 11

Size/Duplication

Total Lines 186
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 11
eloc 132
c 1
b 0
f 0
dl 0
loc 186
rs 10

11 Methods

Rating   Name   Duplication   Size   Complexity  
A testPostCombat() 0 14 1
A testInvalidStates() 0 10 1
A generateCharacter() 0 27 1
A testActionSelector() 0 6 1
A testDecreaseEffectsDuration() 0 19 1
A testAssignPositions() 0 30 1
A testVictoryConditions() 0 6 1
A testEffectProviders() 0 24 1
A testApplyPoison() 0 15 1
A testSuccessCalculator() 0 6 1
A setUp() 0 3 1
1
<?php
2
declare(strict_types=1);
3
4
namespace HeroesofAbenez\Combat;
5
6
use Tester\Assert;
7
8
require __DIR__ . "/../../bootstrap.php";
9
10
/**
11
 * @author Jakub Konečný
12
 * @testCase
13
 */
14
final class CombatBaseTest extends \Tester\TestCase
15
{
16
    use \Testbench\TCompiledContainer;
17
18
    private CombatLogger $logger;
19
20
    public function setUp(): void
21
    {
22
        $this->logger = $this->getService(CombatLogger::class); // @phpstan-ignore assign.propertyType
23
    }
24
25
    private function generateCharacter(int $id): Character
26
    {
27
        $stats = [
28
            "id" => $id, "name" => "Player $id", "level" => 1, "initiativeFormula" => "1d2+DEX/4", "strength" => 10,
29
            "dexterity" => 10, "constitution" => 10, "intelligence" => 10, "charisma" => 10
30
        ];
31
        $petStats = [
32
            "id" => $id, "deployed" => true, "bonusStat" => "strength", "bonusValue" => 10
33
        ];
34
        $weaponStats = [
35
            "id" => 1, "name" => "Novice sword", "slot" => Equipment::SLOT_WEAPON, "type" => Weapon::TYPE_SWORD,
36
            "strength" => 1, "worn" => true,
37
        ];
38
        $attackSkillStats = [
39
            "id" => 1, "name" => "Charge", "target" => SkillAttack::TARGET_SINGLE, "levels" => 5,
40
            "baseDamage" => "110%", "damageGrowth" => "5%", "strikes" => 1, "hitRate" => null,
41
        ];
42
        $specialSkillStats = [
43
            "id" => 1, "name" => "type", "target" => SkillSpecial::TARGET_SELF, "levels" => 5,
44
            "type" => SkillSpecial::TYPE_BUFF, "stat" => Character::STAT_DEFENSE, "value" => 15, "valueGrowth" => 3,
45
            "duration" => 3,
46
        ];
47
        $skills = [
48
            new CharacterAttackSkill(new SkillAttack($attackSkillStats), 1),
49
            new CharacterSpecialSkill(new SkillSpecial($specialSkillStats), 1),
50
        ];
51
        return new Character($stats, [new Weapon($weaponStats)], [new Pet($petStats)], $skills);
52
    }
53
54
    public function testInvalidStates(): void
55
    {
56
        $combat = new CombatBase(clone $this->logger);
57
        Assert::exception(function () use ($combat) {
58
            $combat->execute();
59
        }, InvalidStateException::class);
60
        $combat->setTeams(new Team(""), new Team(""));
61
        Assert::exception(function () use ($combat) {
62
            $combat->setTeams(new Team(""), new Team(""));
63
        }, ImmutableException::class);
64
    }
65
66
    public function testVictoryConditions(): void
67
    {
68
        $combat = new CombatBase(clone $this->logger);
69
        Assert::same([VictoryConditions::class, "moreDamage"], $combat->victoryCondition);
70
        $combat->victoryCondition = [VictoryConditions::class, "eliminateSecondTeam"];
71
        Assert::same([VictoryConditions::class, "eliminateSecondTeam"], $combat->victoryCondition);
72
    }
73
74
    public function testEffectProviders(): void
75
    {
76
        $character1 = $this->generateCharacter(1);
77
        $character2 = $this->generateCharacter(2);
78
        $provider = new EffectsProvider();
79
        $character1->effectProviders[] = $provider;
80
        Assert::same(50, $character1->maxHitpointsBase);
81
        Assert::same(50, $character1->maxHitpoints);
82
        Assert::same(50, $character1->hitpoints);
83
        $combat = new CombatBase(clone $this->logger);
84
        $combat->setDuelParticipants($character1, $character2);
85
        $combat->onRoundStart($combat);
86
        Assert::same(50, $character1->maxHitpointsBase);
87
        Assert::same(60, $character1->maxHitpoints);
88
        Assert::same(60, $character1->hitpoints);
89
        $provider->value = 1;
90
        $combat->onRoundStart($combat);
91
        Assert::same(50, $character1->maxHitpointsBase);
92
        Assert::same(51, $character1->maxHitpoints);
93
        Assert::same(51, $character1->hitpoints);
94
        $combat->onCombatEnd($combat);
95
        Assert::same(50, $character1->maxHitpointsBase);
96
        Assert::same(50, $character1->maxHitpoints);
97
        Assert::same(50, $character1->hitpoints);
98
    }
99
100
    public function testSuccessCalculator(): void
101
    {
102
        $combat = new CombatBase(clone $this->logger);
103
        Assert::type(RandomSuccessCalculator::class, $combat->successCalculator);
104
        $combat->successCalculator = new StaticSuccessCalculator();
105
        Assert::type(StaticSuccessCalculator::class, $combat->successCalculator);
106
    }
107
108
    public function testActionSelector(): void
109
    {
110
        $combat = new CombatBase(clone $this->logger);
111
        Assert::type(CombatActionSelector::class, $combat->actionSelector);
112
        $combat->actionSelector = new ActionSelector();
113
        Assert::type(ActionSelector::class, $combat->actionSelector);
114
    }
115
116
    public function testAssignPositions(): void
117
    {
118
        $combat = new CombatBase(clone $this->logger);
119
        $team1 = new Team("");
120
        $team1->maxRowSize = 2;
121
        $team1[] = $this->generateCharacter(1);
122
        $team1[0]->positionRow = $team1[0]->positionColumn = 1;
123
        $team1[] = $this->generateCharacter(2);
124
        $team1[] = $this->generateCharacter(3);
125
        $team1[] = $this->generateCharacter(4);
126
        $team2 = new Team("");
127
        $team2->maxRowSize = 2;
128
        $team2[] = $this->generateCharacter(5);
129
        $team2[] = $this->generateCharacter(6);
130
        $team2[] = $this->generateCharacter(7);
131
        $team2[] = $this->generateCharacter(8);
132
        $combat->setTeams($team1, $team2);
133
        $combat->assignPositions($combat);
134
        Assert::count(2, $team1->getItems(["positionRow" => 1]));
135
        Assert::count(2, $team1->getItems(["positionRow" => 2]));
136
        Assert::count(0, $team1->getItems(["positionRow" => 3]));
137
        Assert::count(2, $team1->getItems(["positionColumn" => 1]));
138
        Assert::count(2, $team1->getItems(["positionColumn" => 2]));
139
        Assert::count(0, $team1->getItems(["positionColumn" => 3]));
140
        Assert::count(2, $team2->getItems(["positionRow" => 1]));
141
        Assert::count(2, $team2->getItems(["positionRow" => 2]));
142
        Assert::count(0, $team2->getItems(["positionRow" => 3]));
143
        Assert::count(2, $team2->getItems(["positionColumn" => 1]));
144
        Assert::count(2, $team2->getItems(["positionColumn" => 2]));
145
        Assert::count(0, $team2->getItems(["positionColumn" => 3]));
146
    }
147
148
    public function testDecreaseEffectsDuration(): void
149
    {
150
        $combat = new CombatBase(clone $this->logger);
151
        $character1 = $this->generateCharacter(1);
152
        $character2 = $this->generateCharacter(2);
153
        $combat->setDuelParticipants($character1, $character2);
154
        Assert::count(0, $character1->effects);
155
        $effect = new CharacterEffect([
156
            "id" => "skillEffect", "type" => SkillSpecial::TYPE_STUN, "valueAbsolute" => false,
157
            "value" => 0, "duration" => 1, "stat" => "",
158
        ]);
159
        $character1->effects[] = $effect;
160
        Assert::count(1, $character1->effects);
161
        Assert::true($character1->hasStatus(Character::STATUS_STUNNED));
162
        $combat->decreaseEffectsDuration($combat);
163
        Assert::same(0, $effect->duration);
164
        $character1->recalculateStats();
165
        Assert::count(0, $character1->effects);
166
        Assert::false($character1->hasStatus(Character::STATUS_STUNNED));
167
    }
168
169
    public function testApplyPoison(): void
170
    {
171
        $combat = new CombatBase(clone $this->logger);
172
        $character1 = $this->generateCharacter(1);
173
        $character2 = $this->generateCharacter(2);
174
        $combat->setDuelParticipants($character1, $character2);
175
        $effect = new CharacterEffect([
176
            "id" => "skillEffect", "type" => SkillSpecial::TYPE_POISON, "valueAbsolute" => false,
177
            "value" => 5, "duration" => 1, "stat" => "",
178
        ]);
179
        $character1->effects[] = $effect;
180
        $character1->effects[] = $effect;
181
        Assert::same(50, $character1->hitpoints);
182
        $combat->applyPoison($combat);
183
        Assert::same(40, $character1->hitpoints);
184
    }
185
186
    public function testPostCombat(): void
187
    {
188
        $combat = new CombatBase(clone $this->logger);
189
        $combat->healers = function (Team $team1, Team $team2): Team {
190
            return Team::fromArray(array_merge($team1->toArray(), $team2->toArray()), "healers");
191
        };
192
        $character1 = $this->generateCharacter(1);
193
        $character2 = $this->generateCharacter(2);
194
        $combat->setDuelParticipants($character1, $character2);
195
        $combat->execute();
196
        Assert::same(31, $combat->round);
197
        Assert::same(5000, $combat->log->round);
198
        Assert::count(1, $combat->team1->getItems(["initiative" => 0]));
199
        Assert::count(1, $combat->team2->getItems(["initiative" => 0]));
200
    }
201
}
202
203
$test = new CombatBaseTest();
204
$test->run();
205