Completed
Push — master ( 29ee36...92bd35 )
by Tom
03:51
created

MagerunCommandTester   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 122
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Importance

Changes 0
Metric Value
wmc 10
c 0
b 0
f 0
lcom 1
cbo 2
dl 0
loc 122
rs 10

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 9 1
A getCommand() 0 4 1
A getDisplay() 0 6 1
A getStatus() 0 6 1
A getExecutedCommandTester() 0 9 2
A getCommandTester() 0 12 2
A getCommandInternal() 0 20 2
1
<?php
2
3
namespace N98\Magento;
4
5
use N98\Magento\Command\TestCase;
6
use Symfony\Component\Console\Command\Command;
7
use Symfony\Component\Console\Tester\CommandTester;
8
9
/**
10
 * Command Tester for a Magerun Command (based on Symfony Console), for
11
 * use in Phpunit based integration tests
12
 */
13
class MagerunCommandTester
14
{
15
    /**
16
     * @var TestCase
17
     */
18
    private $testCase;
19
20
    /**
21
     * @var string
22
     */
23
    private $commandName;
24
25
    /**
26
     * @see CommandTester::execute()
27
     * @var array of command input
28
     */
29
    private $input;
30
31
    /**
32
     * @var int
33
     */
34
    private $status;
35
36
    /**
37
     * @var CommandTester
38
     */
39
    private $commandTester;
40
41
    /**
42
     * MagerunCommandTester constructor.
43
     *
44
     * @param TestCase $testCase
45
     * @param string|array $input
46
     */
47
    public function __construct(TestCase $testCase, array $input)
48
    {
49
        $this->testCase = $testCase;
50
51
        $testCase->assertArrayHasKey('command', $input);
52
        $testCase->assertInternalType('string', $input['command']);
53
        $this->commandName = $input['command'];
54
        $this->input = $input;
55
    }
56
57
    /**
58
     * @return Command
59
     */
60
    public function getCommand()
61
    {
62
        return $this->getCommandInternal();
63
    }
64
65
    /**
66
     * @return string
67
     */
68
    public function getDisplay()
69
    {
70
        $commandTester = $this->getExecutedCommandTester();
71
72
        return $commandTester->getDisplay();
73
    }
74
75
    /**
76
     * @return int
77
     */
78
    public function getStatus()
79
    {
80
        $this->getExecutedCommandTester();
81
82
        return $this->status;
83
    }
84
85
    private function getExecutedCommandTester()
86
    {
87
        $commandTester = $this->getCommandTester();
88
        if (!isset($this->status)) {
89
            $this->status = $commandTester->execute($this->input);
90
        }
91
92
        return $commandTester;
93
    }
94
95
    /**
96
     * @return CommandTester
97
     */
98
    private function getCommandTester()
99
    {
100
        if (isset($this->commandTester)) {
101
            return $this->commandTester;
102
        }
103
104
        $command = $this->getCommandInternal();
105
106
        $commandTester = new CommandTester($command);
107
108
        return $this->commandTester = $commandTester;
109
    }
110
111
    /**
112
     * @return Command
113
     */
114
    private function getCommandInternal()
115
    {
116
        $test = $this->testCase;
117
118
        $command = $test->getApplication()->find($this->commandName);
0 ignored issues
show
Bug introduced by
The method find does only exist in N98\Magento\Application, but not in PHPUnit_Framework_MockObject_MockObject.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
119
120
        $test->assertSame(
121
            $command->getName(),
122
            $this->commandName,
123
            'Verifying that test is done against main command name'
124
        );
125
126
        if (!$command instanceof Command) {
127
            throw new \InvalidArgumentException(
128
                sprintf('Command "%s" is not a console command', $this->commandName)
129
            );
130
        }
131
132
        return $command;
133
    }
134
}
135