Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
1 | <?php |
||
4 | class ExecTaskTest extends \Codeception\TestCase\Test |
||
5 | { |
||
6 | /** |
||
7 | * @var \AspectMock\Proxy\ClassProxy |
||
8 | */ |
||
9 | protected $process; |
||
10 | |||
11 | View Code Duplication | protected function _before() |
|
12 | { |
||
13 | $this->process = test::double('Symfony\Component\Process\Process', [ |
||
14 | 'run' => false, |
||
15 | 'start' => false, |
||
16 | 'getOutput' => 'Hello world', |
||
17 | 'getExitCode' => 0, |
||
18 | 'logger' => new \Psr\Log\NullLogger(), |
||
19 | ]); |
||
20 | test::double('Robo\Task\Base\Exec', ['output' => new \Symfony\Component\Console\Output\NullOutput()]); |
||
21 | } |
||
22 | |||
23 | View Code Duplication | public function testExec() |
|
24 | { |
||
25 | $task = new \Robo\Task\Base\Exec('ls'); |
||
26 | $task->setLogger(new \Psr\Log\NullLogger()); |
||
27 | |||
28 | $result = $task->run(); |
||
29 | $this->process->verifyInvoked('run'); |
||
30 | $this->assertEquals( |
||
31 | 'Hello world', |
||
32 | $result->getMessage()); |
||
33 | $this->assertEquals(0, $result->getExitCode()); |
||
34 | } |
||
35 | |||
36 | View Code Duplication | public function testExecInBackground() |
|
37 | { |
||
38 | $task = new \Robo\Task\Base\Exec('ls'); |
||
39 | $task->setLogger(new \Psr\Log\NullLogger()); |
||
40 | |||
41 | $result = $task->background()->run(); |
||
42 | $this->process->verifyInvoked('start'); |
||
43 | $this->process->verifyNeverInvoked('run'); |
||
44 | $this->assertNotEquals(100, $result->getExitCode()); |
||
45 | } |
||
46 | |||
47 | public function testGetCommand() |
||
48 | { |
||
49 | $this->assertEquals( |
||
50 | 'ls', |
||
51 | (new \Robo\Task\Base\Exec('ls'))->getCommand()); |
||
52 | } |
||
53 | |||
54 | public function testExecStack() |
||
55 | { |
||
56 | $task = new \Robo\Task\Base\ExecStack(); |
||
57 | $task->setLogger(new \Psr\Log\NullLogger()); |
||
58 | |||
59 | $task |
||
60 | ->exec('ls') |
||
61 | ->exec('cd /') |
||
62 | ->exec('cd home') |
||
63 | ->run(); |
||
64 | $this->process->verifyInvoked('run', 3); |
||
65 | } |
||
66 | |||
67 | public function testExecStackCommand() |
||
68 | { |
||
69 | $this->assertEquals( |
||
70 | 'ls && cd / && cd home', |
||
71 | (new \Robo\Task\Base\ExecStack()) |
||
72 | ->exec('ls') |
||
73 | ->exec('cd /') |
||
74 | ->exec('cd home') |
||
75 | ->getCommand() |
||
76 | ); |
||
77 | } |
||
78 | |||
79 | public function testExecStackCommandInterface() |
||
89 | }; |
||
90 |
Let’s assume that you have a directory layout like this:
and let’s assume the following content of
Bar.php
:If both files
OtherDir/Foo.php
andSomeDir/Foo.php
are loaded in the same runtime, you will see a PHP error such as the following:PHP Fatal error: Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php
However, as
OtherDir/Foo.php
does not necessarily have to be loaded and the error is only triggered if it is loaded beforeOtherDir/Bar.php
, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias: