Completed
Push — master ( 835840...ce2316 )
by Pablo
02:59
created

GuardCoverageToolHandler::isLowerCurrentCoverage()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
crap 1
1
<?php
2
3
namespace PhpGitHooks\Module\PhpUnit\Contract\Command;
4
5
use Bruli\EventBusBundle\CommandBus\CommandHandlerInterface;
6
use Bruli\EventBusBundle\CommandBus\CommandInterface;
7
use PhpGitHooks\Module\Git\Service\PreCommitOutputWriter;
8
use PhpGitHooks\Module\PhpUnit\Contract\Command\GuardCoverage;
9
use PhpGitHooks\Module\PhpUnit\Model\GuardCoverageFileReaderInterface;
10
use PhpGitHooks\Module\PhpUnit\Model\GuardCoverageFileWriterInterface;
11
use PhpGitHooks\Module\PhpUnit\Model\StrictCoverageProcessorInterface;
12
use Symfony\Component\Console\Output\OutputInterface;
13
14
class GuardCoverageToolHandler implements CommandHandlerInterface
15
{
16
    const CHECKING_MESSAGE = 'Checking your current coverage';
17
    /**
18
     * @var OutputInterface
19
     */
20
    private $output;
21
    /**
22
     * @var StrictCoverageProcessorInterface
23
     */
24
    private $strictCoverageProcessor;
25
    /**
26
     * @var GuardCoverageFileReaderInterface
27
     */
28
    private $guardReader;
29
    /**
30
     * @var GuardCoverageFileWriterInterface
31
     */
32
    private $guardWriter;
33
    /**
34
     * @var float;
35
     */
36
    private $currentCoverage;
37
    /**
38
     * @var float
39
     */
40
    private $previousCoverage;
41
42
    /**
43
     * GuardCoverageTool constructor.
44
     *
45
     * @param OutputInterface $output
46
     * @param StrictCoverageProcessorInterface $strictCoverageProcessor
47
     * @param GuardCoverageFileReaderInterface $guardReader
48
     * @param GuardCoverageFileWriterInterface $guardWriter
49
     */
50 2
    public function __construct(
51
        OutputInterface $output,
52
        StrictCoverageProcessorInterface $strictCoverageProcessor,
53
        GuardCoverageFileReaderInterface $guardReader,
54
        GuardCoverageFileWriterInterface $guardWriter
55
    ) {
56 2
        $this->output = $output;
57 2
        $this->strictCoverageProcessor = $strictCoverageProcessor;
58 2
        $this->guardReader = $guardReader;
59 2
        $this->guardWriter = $guardWriter;
60 2
    }
61
62
    /**
63
     * @param string $warningMessage
64
     */
65 2
    private function run($warningMessage)
66
    {
67 2
        $outputMessage = new PreCommitOutputWriter(self::CHECKING_MESSAGE);
68 2
        $this->output->write($outputMessage->getMessage());
69
70 2
        $this->currentCoverage = $this->strictCoverageProcessor->process();
71 2
        $this->previousCoverage = $this->guardReader->read();
72
73
74 2
        true === $this->isLowerCurrentCoverage() ? $this->output->writeln(
75 1
            sprintf(
76 1
                "\n<bg=yellow;options=bold>%s Previous coverage %s, current coverage %s.</>",
77
                $warningMessage,
78 1
                $this->previousCoverage,
79 1
                $this->currentCoverage
80
            )
81 1
        ) : $this->output->writeln(
82 1
            $outputMessage->getSuccessfulMessage() . $this->printGuardCoverage()
83
        );
84
85 2
        $this->guardWriter->write($this->currentCoverage);
86 2
    }
87
88
    /**
89
     * @return bool
90
     */
91 2
    private function isLowerCurrentCoverage()
92
    {
93 2
        return $this->currentCoverage < $this->previousCoverage;
94
    }
95
96
    /**
97
     * @return string
98
     */
99 1
    private function printGuardCoverage()
100
    {
101
        return ' <comment>[' .
102 1
            round($this->currentCoverage, 0) .
103 1
            '% >= ' .
104 1
            round($this->previousCoverage, 0) .
105 1
            '%]</comment>';
106
    }
107
108
    /**
109
     * @param CommandInterface|GuardCoverage $command
110
     */
111 2
    public function handle(CommandInterface $command)
112
    {
113 2
        $this->run($command->getWarningMessage());
0 ignored issues
show
Bug introduced by
It seems like you code against a concrete implementation and not the interface Bruli\EventBusBundle\CommandBus\CommandInterface as the method getWarningMessage() does only exist in the following implementations of said interface: PhpGitHooks\Module\PhpUn...t\Command\GuardCoverage.

Let’s take a look at an example:

interface User
{
    /** @return string */
    public function getPassword();
}

class MyUser implements User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different implementation of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the interface:

    interface User
    {
        /** @return string */
        public function getPassword();
    
        /** @return string */
        public function getDisplayName();
    }
    
Loading history...
114 2
    }
115
}
116