EloRankingTest::providerEloChanges()   B
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 99

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
loc 99
rs 8.0218
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
declare(strict_types=1);
3
/**
4
 * Created by PhpStorm.
5
 * User: benedikt
6
 * Date: 1/3/18
7
 * Time: 3:53 PM
8
 */
9
10
namespace Tfboe\FmLib\Tests\Unit\Service\RankingSystem;
11
12
use Doctrine\Common\Collections\ArrayCollection;
13
use Doctrine\Common\Persistence\ObjectRepository;
14
use Doctrine\ORM\EntityManagerInterface;
15
use Tfboe\FmLib\Entity\Helpers\Result;
16
use Tfboe\FmLib\Entity\Helpers\TournamentHierarchyEntity;
17
use Tfboe\FmLib\Entity\RankingSystemChangeInterface;
18
use Tfboe\FmLib\Entity\RankingSystemListEntryInterface;
19
use Tfboe\FmLib\Entity\RankingSystemListInterface;
20
use Tfboe\FmLib\Service\ObjectCreatorServiceInterface;
21
use Tfboe\FmLib\Service\RankingSystem\EloRanking;
22
use Tfboe\FmLib\Service\RankingSystem\EntityComparerInterface;
23
use Tfboe\FmLib\Service\RankingSystem\TimeServiceInterface;
24
use Tfboe\FmLib\Tests\Entity\Game;
25
use Tfboe\FmLib\Tests\Entity\Player;
26
use Tfboe\FmLib\Tests\Entity\RankingSystemList;
27
use Tfboe\FmLib\Tests\Entity\RankingSystemListEntry;
28
use Tfboe\FmLib\Tests\Helpers\UnitTestCase;
29
30
/**
31
 * Class EloRankingTest
32
 * @packageTfboe\FmLib\Tests\Unit\Service\RankingSystemService
33
 * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
34
 */
35
class EloRankingTest extends UnitTestCase
36
{
37
//<editor-fold desc="Public Methods">
38
  /**
39
   * Provides data for all elo changes tests
40
   * @return array
41
   */
42
  public function providerEloChanges()
43
  {
44
    return [
45
      [false, Result::TEAM_A_WINS, [
46
        ["points" => 1501.0, "rated" => 53, "played" => 74, "ranked" => 102, "pointChange" => 0.0,
47
          "ratedGamesChange" => 0, "playedChange" => 0],
48
        ["points" => 1300.0, "rated" => 20, "played" => 32, "ranked" => 26, "pointChange" => 0.0,
49
          "ratedGamesChange" => 0, "playedChange" => 0],
50
        ["points" => 1450.0, "rated" => 100, "played" => 100, "ranked" => 100, "pointChange" => 0.0,
51
          "ratedGamesChange" => 0, "playedChange" => 0],
52
        ["points" => 1200.0, "rated" => 60, "played" => 70, "ranked" => 75, "pointChange" => 0.0,
53
          "ratedGamesChange" => 0, "playedChange" => 0],
54
      ]],
55
      [true, Result::TEAM_A_WINS, [
56
        ["points" => 1501.0, "rated" => 53, "played" => 74, "ranked" => 102, "pointChange" => 7.8605068927035,
57
          "ratedGamesChange" => 1, "playedChange" => 1],
58
        ["points" => 1300.0, "rated" => 20, "played" => 32, "ranked" => 26, "pointChange" => 7.8605068927035,
59
          "ratedGamesChange" => 1, "playedChange" => 1],
60
        ["points" => 1450.0, "rated" => 100, "played" => 100, "ranked" => 100, "pointChange" => -7.8605068927035,
61
          "ratedGamesChange" => 1, "playedChange" => 1],
62
        ["points" => 1200.0, "rated" => 60, "played" => 70, "ranked" => 75, "pointChange" => 0.0,
63
          "ratedGamesChange" => 1, "playedChange" => 1],
64
      ]],
65
      [true, Result::TEAM_B_WINS, [
66
        ["points" => 1501.0, "rated" => 53, "played" => 74, "ranked" => 102, "pointChange" => -12.139493107296,
67
          "ratedGamesChange" => 1, "playedChange" => 1],
68
        ["points" => 1300.0, "rated" => 20, "played" => 32, "ranked" => 26, "pointChange" => -12.139493107296,
69
          "ratedGamesChange" => 1, "playedChange" => 1],
70
        ["points" => 1450.0, "rated" => 100, "played" => 100, "ranked" => 100, "pointChange" => 12.139493107296,
71
          "ratedGamesChange" => 1, "playedChange" => 1],
72
        ["points" => 1200.0, "rated" => 60, "played" => 70, "ranked" => 75, "pointChange" => 12.139493107296,
73
          "ratedGamesChange" => 1, "playedChange" => 1],
74
      ]],
75
      [true, Result::DRAW, [
76
        ["points" => 1501.0, "rated" => 53, "played" => 74, "ranked" => 102, "pointChange" => -2.1394931072965,
77
          "ratedGamesChange" => 1, "playedChange" => 1],
78
        ["points" => 1300.0, "rated" => 20, "played" => 32, "ranked" => 26, "pointChange" => -2.1394931072965,
79
          "ratedGamesChange" => 1, "playedChange" => 1],
80
        ["points" => 1450.0, "rated" => 100, "played" => 100, "ranked" => 100, "pointChange" => 2.1394931072965,
81
          "ratedGamesChange" => 1, "playedChange" => 1],
82
        ["points" => 1200.0, "rated" => 60, "played" => 70, "ranked" => 75, "pointChange" => 2.1394931072965,
83
          "ratedGamesChange" => 1, "playedChange" => 1],
84
      ]],
85
      [true, Result::NULLED, [
86
        ["points" => 1501.0, "rated" => 53, "played" => 74, "ranked" => 102, "pointChange" => 0.0,
87
          "ratedGamesChange" => 0, "playedChange" => 0],
88
        ["points" => 1300.0, "rated" => 20, "played" => 32, "ranked" => 26, "pointChange" => 0.0,
89
          "ratedGamesChange" => 0, "playedChange" => 0],
90
        ["points" => 1450.0, "rated" => 100, "played" => 100, "ranked" => 100, "pointChange" => 0.0,
91
          "ratedGamesChange" => 0, "playedChange" => 0],
92
        ["points" => 1200.0, "rated" => 60, "played" => 70, "ranked" => 75, "pointChange" => 0.0,
93
          "ratedGamesChange" => 0, "playedChange" => 0],
94
      ]],
95
      [true, Result::NOT_YET_FINISHED, [
96
        ["points" => 1501.0, "rated" => 53, "played" => 74, "ranked" => 102, "pointChange" => 0.0,
97
          "ratedGamesChange" => 0, "playedChange" => 0],
98
        ["points" => 1300.0, "rated" => 20, "played" => 32, "ranked" => 26, "pointChange" => 0.0,
99
          "ratedGamesChange" => 0, "playedChange" => 0],
100
        ["points" => 1450.0, "rated" => 100, "played" => 100, "ranked" => 100, "pointChange" => 0.0,
101
          "ratedGamesChange" => 0, "playedChange" => 0],
102
        ["points" => 1200.0, "rated" => 60, "played" => 70, "ranked" => 75, "pointChange" => 0.0,
103
          "ratedGamesChange" => 0, "playedChange" => 0],
104
      ]],
105
      [true, Result::TEAM_A_WINS, [
106
        ["points" => 0.0, "rated" => 15, "played" => 19, "ranked" => 20, "pointChange" => 1515.78125,
107
          "ratedGamesChange" => 1, "playedChange" => 1, "provisoryRanking" => 1501.0, "provisoryChange" => 14.78125],
108
        ["points" => 1300.0, "rated" => 20, "played" => 20, "ranked" => 26, "pointChange" => 0.0,
109
          "ratedGamesChange" => 0, "playedChange" => 1],
110
        ["points" => 1450.0, "rated" => 100, "played" => 100, "ranked" => 100, "pointChange" => 0.0,
111
          "ratedGamesChange" => 0, "playedChange" => 1],
112
        ["points" => 0.0, "rated" => 10, "played" => 10, "ranked" => 15, "pointChange" => 0.0,
113
          "ratedGamesChange" => 1, "playedChange" => 1, "provisoryRanking" => 1200.0,
114
          "provisoryChange" => -20.386363636364],
115
      ]],
116
      [true, Result::TEAM_A_WINS, [
117
        ["points" => 0.0, "rated" => 15, "played" => 15, "ranked" => 20, "pointChange" => 0.0,
118
          "ratedGamesChange" => 1, "playedChange" => 1, "provisoryRanking" => 1501.0, "provisoryChange" => 6.1875],
119
        ["points" => 2000.0, "rated" => 20, "played" => 20, "ranked" => 26, "pointChange" => 0.0,
120
          "ratedGamesChange" => 0, "playedChange" => 1],
121
        ["points" => 1200.0, "rated" => 100, "played" => 100, "ranked" => 100, "pointChange" => 0.0,
122
          "ratedGamesChange" => 0, "playedChange" => 1],
123
        ["points" => 0.0, "rated" => 10, "played" => 10, "ranked" => 15, "pointChange" => 0.0,
124
          "ratedGamesChange" => 1, "playedChange" => 1, "provisoryRanking" => 1200.0,
125
          "provisoryChange" => 31.863636363636],
126
      ]],
127
      [true, Result::TEAM_A_WINS, [
128
        ["points" => 1501.0, "rated" => 53, "played" => 74, "ranked" => 102, "pointChange" => 4.7840781802172,
129
          "ratedGamesChange" => 1, "playedChange" => 1],
130
        ["points" => 1300.0, "rated" => 20, "played" => 32, "ranked" => 26, "pointChange" => -4.7840781802172,
131
          "ratedGamesChange" => 1, "playedChange" => 1],
132
      ]],
133
      [true, Result::TEAM_A_WINS, [
134
        ["points" => 0.0, "rated" => 15, "played" => 15, "ranked" => 20, "pointChange" => 0.0,
135
          "ratedGamesChange" => 1, "playedChange" => 1, "provisoryRanking" => 1501.0, "provisoryChange" => 12.4375],
136
        ["points" => 1300.0, "rated" => 20, "played" => 20, "ranked" => 26, "pointChange" => 0.0,
137
          "ratedGamesChange" => 0, "playedChange" => 1],
138
      ]],
139
    ];
140
  }
141
142
  /**
143
   * @covers \Tfboe\FmLib\Service\RankingSystem\EloRanking::getAdditionalFields
144
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::__construct
145
   */
146
  public function testGetAdditionalFields()
147
  {
148
    $service = $this->service();
149
    $additionalFields = static::callProtectedMethod($service, 'getAdditionalFields', []);
150
    self::assertEquals(['playedGames' => 0, 'ratedGames' => 0, 'provisoryRanking' => 1200.0], $additionalFields);
151
  }
152
153
  /**
154
   * @dataProvider providerEloChanges
155
   * @covers       \Tfboe\FmLib\Service\RankingSystem\EloRanking::getChanges
156
   * @covers       \Tfboe\FmLib\Service\RankingSystem\EloRanking::computeChanges
157
   * @covers       \Tfboe\FmLib\Service\RankingSystem\EloRanking::getEloAverage
158
   * @covers       \Tfboe\FmLib\Service\RankingSystem\EloRanking::hasProvisoryEntry
159
   * @covers       \Tfboe\FmLib\Service\RankingSystem\EloRanking::addNotRatedChanges
160
   * @uses         \Tfboe\FmLib\Entity\Helpers\SubClassData::__call
161
   * @uses         \Tfboe\FmLib\Entity\Helpers\SubClassData::getProperty
162
   * @uses         \Tfboe\FmLib\Entity\Helpers\SubClassData::initSubClassData
163
   * @uses         \Tfboe\FmLib\Entity\Helpers\SubClassData::setProperty
164
   * @uses         \Tfboe\FmLib\Entity\Traits\RankingSystemChange
165
   * @uses         \Tfboe\FmLib\Entity\Traits\RankingSystemListEntry
166
   * @uses         \Tfboe\FmLib\Service\RankingSystem\EloRanking::getAdditionalFields
167
   * @uses         \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::__construct
168
   * @uses         \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getOrCreateChange
169
   * @uses         \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getEntriesOfPlayers
170
   * @uses         \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::getOrCreateRankingSystemListEntry
171
   * @uses         \Tfboe\FmLib\Service\RankingSystem\EloRanking::getAdditionalChangeFields()
172
   * @SuppressWarnings(PHPMD.CyclomaticComplexity)
173
   * @param bool $isPlayed if game was played
174
   * @param int $gameResult the game result
175
   * @param array $playerInfos all infos about each player and its expected changes
176
   */
177
  public function testGetChanges(bool $isPlayed, int $gameResult, array $playerInfos)
178
  {
179
    $repository = $this->createStub(ObjectRepository::class, ['findBy' => []]);
180
    $entityManager = $this->createStub(EntityManagerInterface::class, ['getRepository' => $repository]);
181
    $service = $this->service($entityManager, $this->getObjectCreator());
0 ignored issues
show
Documentation introduced by
$entityManager is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Doctrine\ORM\EntityManagerInterface>|null.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
182
    /** @var EloRanking $player1 */
183
184
    /** @var Player[] $players */
185
    $players = [];
186
    $playersAArray = [];
187
    $playersBArray = [];
188
    for ($i = 0; $i < count($playerInfos); $i++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
189
      $players[$i] = $this->createStub(Player::class, ['getId' => $i]);
190
      if ($i < count($playerInfos) / 2) {
191
        $playersAArray[] = $players[$i];
192
      } else {
193
        $playersBArray[] = $players[$i];
194
      }
195
    }
196
197
    $playersA = new ArrayCollection($playersAArray);
198
    $playersB = new ArrayCollection($playersBArray);
199
    $game = $this->createStub(Game::class, [
200
      'getPlayersA' => $playersA,
201
      'getPlayersB' => $playersB,
202
    ]);
203
204
    $entriesArray = [];
205
    for ($i = 0; $i < count($playerInfos); $i++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
206
      $entriesArray[$i] = $this->getRankingSystemListEntry($service, $players[$i]);
0 ignored issues
show
Bug introduced by
It seems like $players[$i] can also be of type object<PHPUnit\Framework\MockObject\MockObject>; however, Tfboe\FmLib\Tests\Unit\S...ankingSystemListEntry() does only seem to accept object<Tfboe\FmLib\Tests\Entity\Player>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
207
    }
208
    $entries = new ArrayCollection($entriesArray);
209
    $list = $this->createStub(RankingSystemList::class, ['getEntries' => $entries]);
210
    /** @var $list RankingSystemListInterface */
211
    foreach ($entries as $entry) {
212
      /** @var $entry RankingSystemListEntryInterface */
213
      $entry->setRankingSystemList($list);
214
    }
215
    for ($i = 0; $i < count($playerInfos); $i++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
216
      $info = $playerInfos[$i];
217
      $entry = $list->getEntries()[$i];
218
      $entry->setPoints($info['points']);
219
      $entry->setPlayedGames($info['played']);
220
      $entry->setNumberRankedEntities($info['ranked']);
221
      $entry->setRatedGames($info['rated']);
222
      if (array_key_exists('provisoryRanking', $info)) {
223
        $list->getEntries()[$i]->setProvisoryRanking($info['provisoryRanking']);
224
      }
225
    }
226
    $game->method('isPlayed')->willReturn($isPlayed);
0 ignored issues
show
Bug introduced by
The method method() does not seem to exist on object<PHPUnit\Framework\MockObject\MockObject>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
227
    $game->method('getResult')->willReturn($gameResult);
0 ignored issues
show
Bug introduced by
The method method() does not seem to exist on object<PHPUnit\Framework\MockObject\MockObject>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
228
229
    /** @var RankingSystemChangeInterface[] $changes */
230
    $changes = static::callProtectedMethod($service, 'getChanges', [$game, $list]);
231
    self::assertEquals(count($playerInfos), count($changes));
232
    foreach ($players as $player) {
233
      $exists = false;
234
      foreach ($changes as $change) {
235
        if ($change->getPlayer() === $player) {
236
          $exists = true;
237
          break;
238
        }
239
      }
240
      self::assertTrue($exists);
241
    }
242
    /** @var Game $game */
243
    $this->assertChanges($changes, $playerInfos, $game);
244
  }
245
246
  /**
247
   * @covers \Tfboe\FmLib\Service\RankingSystem\EloRanking::startPoints
248
   * @uses   \Tfboe\FmLib\Service\RankingSystem\RankingSystemService::__construct
249
   */
250
  public function testStartPoints()
251
  {
252
    $service = $this->service();
253
    $startPoints = static::callProtectedMethod($service, 'startPoints', []);
254
    self::assertEquals(0.0, $startPoints);
255
  }
256
//</editor-fold desc="Public Methods">
257
258
//<editor-fold desc="Private Methods">
259
  /**
260
   * @param RankingSystemChangeInterface[] $changes
261
   * @param array $playerInfos
262
   * @param TournamentHierarchyEntity $entity
263
   */
264
  private function assertChanges(array $changes, array $playerInfos, TournamentHierarchyEntity $entity)
265
  {
266
    for ($i = 0; $i < count($changes); $i++) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
267
      $change = $changes[$i];
268
      self::assertEquals($entity, $change->getHierarchyEntity());
269
      self::assertEquals($playerInfos[$i]["pointChange"], $change->getPointsChange(), '', 0.01);
270
      self::assertEquals($playerInfos[$i]["ratedGamesChange"], $change->getRatedGames());
271
      self::assertEquals($playerInfos[$i]["playedChange"], $change->getPlayedGames());
272
      self::assertEquals(
273
        array_key_exists('provisoryChange', $playerInfos[$i]) ? $playerInfos[$i]['provisoryChange'] : 0,
274
        $change->getProvisoryRanking(), '', 0.01);
275
    }
276
  }
277
278
  /**
279
   * Creates a new ranking system list entry
280
   * @param EloRanking $service the elo ranking service to get additional fields
281
   * @param Player $player the player to use for the entry
282
   * @return RankingSystemListEntryInterface the created ranking system list entry
283
   */
284
  private function getRankingSystemListEntry(EloRanking $service, Player $player)
285
  {
286
    $entry = new RankingSystemListEntry(array_keys(static::callProtectedMethod($service, 'getAdditionalFields')));
287
    $entry->setPlayer($player);
288
    return $entry;
289
  }
290
291
  /**
292
   * Gets an elo ranking service
293
   * @param EntityManagerInterface|null $entityManager
294
   * @param null|ObjectCreatorServiceInterface $objectCreatorService
295
   * @return EloRanking
296
   */
297
  private function service(?EntityManagerInterface $entityManager = null,
298
                           ?ObjectCreatorServiceInterface $objectCreatorService = null)
299
  {
300
    if ($entityManager === null) {
301
      $entityManager = $this->createMock(EntityManagerInterface::class);
302
    }
303
    if ($objectCreatorService === null) {
304
      $objectCreatorService = $this->createMock(ObjectCreatorServiceInterface::class);
305
    }
306
    /** @noinspection PhpParamsInspection */
307
    return new EloRanking(
308
      $entityManager, $this->createMock(TimeServiceInterface::class),
0 ignored issues
show
Bug introduced by
It seems like $entityManager can also be of type object<PHPUnit\Framework\MockObject\MockObject>; however, Tfboe\FmLib\Service\Rank...mService::__construct() does only seem to accept object<Doctrine\ORM\EntityManagerInterface>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
Documentation introduced by
$this->createMock(\Tfboe...erviceInterface::class) is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Tfboe\FmLib\Servi...m\TimeServiceInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
309
      $this->createMock(EntityComparerInterface::class), $objectCreatorService
0 ignored issues
show
Documentation introduced by
$this->createMock(\Tfboe...mparerInterface::class) is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a object<Tfboe\FmLib\Servi...ntityComparerInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
Bug introduced by
It seems like $objectCreatorService can also be of type object<PHPUnit\Framework\MockObject\MockObject>; however, Tfboe\FmLib\Service\Rank...mService::__construct() does only seem to accept object<Tfboe\FmLib\Servi...reatorServiceInterface>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
310
    );
311
  }
312
//</editor-fold desc="Private Methods">
313
}