Skip to content

Commit a671b96

Browse files
coopryansolcloud
authored andcommitted
qa: mutation testing with phsptan
1 parent 99fe009 commit a671b96

26 files changed

Lines changed: 109 additions & 48 deletions

.github/workflows/test.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name: "Tests"
22
on:
33
push:
4-
branches: [master]
4+
branches: ['*']
55
paths-ignore:
66
- '**.md'
77
- 'cli/'
@@ -24,7 +24,7 @@ jobs:
2424
persist-credentials: false
2525

2626
- name: "Install Linux dependencies"
27-
timeout-minutes: 2
27+
timeout-minutes: 4
2828
run: |
2929
sudo apt-get update && sudo apt-get install -y \
3030
composer
@@ -36,7 +36,7 @@ jobs:
3636
composer install
3737
3838
- name: "Run Composer check-full"
39-
timeout-minutes: 10
39+
timeout-minutes: 20
4040
run: |
4141
grep '"timeout": 20,' infection.json5
4242
sed -i 's/"timeout": 20,/"timeout": 40,/' infection.json5

cli/server.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
$port = (int)($argv[2] ?? 8080);
1515
$debug = in_array('--debug', $argv);
1616
$bindAddress = "udp://0.0.0.0:$port";
17+
$map = new Maps\DefaultMap();
1718
/////
1819

1920
$settings = new ServerSetting($playersMax); // must be first for correctly setting the global tickRate (Util::$TICK_RATE)
@@ -22,7 +23,7 @@
2223
$logger->info("Preparing game for launch, please wait...");
2324

2425
$game = ($debug ? GameFactory::createDebug() : GameFactory::createDefaultCompetitive());
25-
$game->loadMap(new Maps\DefaultMap());
26+
$game->loadMap($map);
2627

2728
$logger->info("Starting server on '{$bindAddress}', waiting maximum of '{$settings->warmupWaitSec}' sec for '{$playersMax}' player" . ($playersMax > 1 ? 's' : '') . " to connect.");
2829
$net = new ClueSocket($bindAddress);

composer.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
"scripts": {
33
"post-install-cmd": "@php -d memory_limit=200M cli/generateNavmesh.php",
44
"stan": "@php vendor/bin/phpstan --memory-limit=300M analyze",
5-
"unit": "@php vendor/bin/phpunit -d memory_limit=70M",
6-
"infection": "@php -d memory_limit=180M vendor/bin/infection --show-mutations --only-covered --threads=max --min-covered-msi=100",
5+
"unit": "@php vendor/bin/phpunit -d memory_limit=200M",
6+
"infection": "@php -d memory_limit=300M vendor/bin/infection --show-mutations --threads=max --min-covered-msi=100",
77
"dev": "php cli/server.php 1 8080 --debug & php cli/udp-ws-bridge.php",
88
"dev2": "php cli/server.php 2 8080 --debug & php cli/udp-ws-bridge.php & php cli/udp-ws-bridge.php 8082",
99
"dev2c": "php cli/server.php 2 8080 --debug & php cli/udp-ws-bridge.php & sleep 2 && php cli/client.php acode 8080",
@@ -28,7 +28,7 @@
2828
"check-full": [
2929
"@check",
3030
"@coverage",
31-
"@infection-cache"
31+
"@infection-cache --skip-initial-tests"
3232
]
3333
},
3434
"require": {
@@ -60,7 +60,7 @@
6060
"platform": {
6161
"php": "8.3"
6262
},
63-
"process-timeout": 720,
63+
"process-timeout": 0,
6464
"allow-plugins": {
6565
"infection/extension-installer": false
6666
}

infection.json5

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,33 +7,31 @@
77
},
88
"timeout": 20,
99
"testFramework": "phpunit",
10+
"staticAnalysisTool": "phpstan",
11+
"staticAnalysisToolOptions": "--memory-limit=300M",
1012
"mutators": {
1113
"global-ignoreSourceCodeByRegex": [
1214
"\\$this->log\\(.*\\);",
1315
"throw new GameException\\(.+\\);",
1416
"GameException::invalid\\(.*\\);",
1517
"GameException::notImplementedYet\\(.*\\);",
1618
"assert\\(.+?\\);",
19+
"if\\s*\\(\\$count > 10 && \\$count % 2 === 0\\)\\s\\{",
1720
],
1821
"@default": true,
1922
"@conditional_boundary": false,
2023
"@conditional_negotiation": false,
21-
"CastInt": false,
2224
"Continue_": false,
2325
"DecrementInteger": false,
2426
"FalseValue": false,
25-
"IfNegation": false,
2627
"Increment": false,
2728
"IncrementInteger": false,
28-
"LogicalAnd": false,
2929
"LogicalAndAllSubExprNegation": false,
3030
"LogicalOr": false,
31-
"LogicalOrAllSubExprNegation": false,
3231
"Minus": false,
33-
"Modulus": false,
3432
"Multiplication": false,
35-
"NullSafeMethodCall": false,
3633
"Plus": false,
34+
"ReturnRemoval": false,
3735
"RoundingFamily": false,
3836
"TrueValue": false,
3937
"ArrayItem": {
@@ -69,11 +67,6 @@
6967
"if\\s*\\(\\$this->ball->getResolutionAngleVertical\\(\\) > 0 && \\(.+",
7068
],
7169
},
72-
"LogicalAndNegation": {
73-
"ignoreSourceCodeByRegex": [
74-
"if\\s*\\(\\$count > 10 && \\$count % 2 === 0\\)\\s\\{",
75-
],
76-
},
7770
"LogicalNot": {
7871
"ignoreSourceCodeByRegex": [
7972
".+\\$this->lastMoveX === -\\$moveX.+",
@@ -85,6 +78,9 @@
8578
],
8679
},
8780
"MethodCallRemoval": {
81+
"ignore": [
82+
"cs\\Equipment\\Bomb::unEquip",
83+
],
8884
"ignoreSourceCodeByRegex": [
8985
"\\$this->setActiveFloor\\(.+\\);",
9086
"\\$prevPos->setFrom\\(\\$candidate\\);",

phpunit.xml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
<directory>server/src/</directory>
2626
</include>
2727
<exclude>
28-
<directory>server/src/Equipment/</directory>
2928
<directory>server/src/Map/</directory>
3029
<directory>server/src/Weapon/</directory>
3130
</exclude>

server/src/Core/BuyMenu.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public function reset(bool $forAttackerStore, array $alreadyHaveItems): void
2929

3030
foreach ($alreadyHaveItems as $item) {
3131
if ($item->getType() === ItemType::TYPE_GRENADE) {
32-
$this->grenadeCount++;
32+
$this->grenadeCount += $item->getQuantity();
3333
}
3434

3535
if (!isset($this->itemBuyCount[$item->getId()])) {

server/src/Core/HitBox.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ public function reset(): void
3434
$this->damage = 0;
3535
}
3636

37+
/** @infection-ignore-all */
3738
public function getHitAntiForce(Point $point): int
3839
{
3940
if ($this->type === HitBoxType::HEAD) {
@@ -84,6 +85,7 @@ public function registerHit(Bullet $bullet): void
8485
}
8586
}
8687

88+
/** @infection-ignore-all */
8789
private function calculateArmorDamage(BaseWeapon $shootItem, ArmorType $armorType, HitBoxType $hitBoxType): int
8890
{
8991
if ($armorType->hasNoArmor() || $hitBoxType === HitBoxType::LEG) {

server/src/Core/PathFinder.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
final class PathFinder
1010
{
1111
private Graph $graph;
12-
/** @var array<string,bool> */
12+
/** @var array<string,null> */
1313
private array $visited = [];
1414
private readonly int $obstacleOvercomeHeight;
1515
/** @var array<int,array{int,int,int}> */
@@ -105,8 +105,8 @@ public function findTile(Point $pointOnFloor, int $radius): ?Point
105105
return $floorNavmeshPoint;
106106
}
107107

108-
$maxDistance = $this->navigationMesh->tileSize * 2;
109-
$maxY = $this->obstacleOvercomeHeight * 2;
108+
$maxDistance = $this->navigationMesh->tileSize + $this->navigationMesh->tileSize;
109+
$maxY = $this->obstacleOvercomeHeight + $this->obstacleOvercomeHeight;
110110
$checkAbove = function (Point $start, int $maxY, int $radius): ?Point {
111111
$yCandidate = $start->clone();
112112
$navMeshCenter = $yCandidate->clone();
@@ -188,7 +188,7 @@ public function buildNavigationMesh(Point $start, int $objectHeight, int $maxNod
188188
continue;
189189
}
190190

191-
$this->visited[$currentKey] = true;
191+
$this->visited[$currentKey] = null;
192192
$currentNode = $this->graph->getNodeById($currentKey);
193193
if ($currentNode === null) {
194194
$currentNode = new Node($currentKey, $current);
@@ -210,7 +210,7 @@ public function buildNavigationMesh(Point $start, int $objectHeight, int $maxNod
210210
$this->graph->addEdge(new DirectedEdge($currentNode, $newNode, 1));
211211
$queue->enqueue($newNeighbour);
212212
}
213-
if (++$nodeCount === $maxNodeCount) {
213+
if (++$nodeCount === $maxNodeCount) { // @codeCoverageIgnore
214214
GameException::notImplementedYet('MaxNodeCount hit - new map, tileSize or bad test (no boundary box, bad starting point)?'); // @codeCoverageIgnore
215215
}
216216
}

server/src/Core/PlayerStat.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,11 @@ public function getKills(): int
4141
return $this->kills;
4242
}
4343

44+
public function getHeadshotKills(): int
45+
{
46+
return $this->killsHeadshot;
47+
}
48+
4449
public function getDeaths(): int
4550
{
4651
return $this->deaths;

server/src/Core/Score.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ public function roundEnd(RoundEndEvent $event): void
7373
}
7474

7575
if ($this->secondHalfScore !== []) {
76-
$this->secondHalfScore[(int)$attackersWins]++;
76+
$this->secondHalfScore[$attackersWins ? 1 : 0]++;
7777
}
7878
$this->lastRoundAttackerWins = $attackersWins;
7979
$this->roundsHistory[$this->roundNumber] = [
@@ -145,7 +145,7 @@ public function toArray(): array
145145
$scoreboard = [[], []];
146146
foreach ($this->playerStats as $playerId => $playerStat) {
147147
$key = sprintf('%d-%d-%d', $playerStat->getKills(), $playerStat->getDamage(), $playerId);
148-
$scoreboard[(int)$playerStat->isAttacker()][$key] = $playerStat->toArray();
148+
$scoreboard[$playerStat->isAttacker() ? 1 : 0][$key] = $playerStat->toArray();
149149
}
150150
$teamDefenders = $scoreboard[0];
151151
$teamAttackers = $scoreboard[1];

0 commit comments

Comments
 (0)