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 |
||
13 | class ChunkRunner |
||
14 | { |
||
15 | /** |
||
16 | * @var ChunkedTests |
||
17 | */ |
||
18 | private $chunkedTests; |
||
19 | |||
20 | /** |
||
21 | * @var ChunkResults |
||
22 | */ |
||
23 | private $chunkResults; |
||
24 | |||
25 | /** |
||
26 | * @var TestRunner |
||
27 | */ |
||
28 | private $testRunner; |
||
29 | |||
30 | /** |
||
31 | * @var Processes |
||
32 | */ |
||
33 | private $processes; |
||
34 | |||
35 | /** |
||
36 | * @var InputInterface |
||
37 | */ |
||
38 | private $input; |
||
39 | |||
40 | /** |
||
41 | * @var OutputInterface |
||
42 | */ |
||
43 | private $output; |
||
44 | |||
45 | /** |
||
46 | * @var bool |
||
47 | */ |
||
48 | private $verbose = false; |
||
49 | |||
50 | /** |
||
51 | * @var bool |
||
52 | */ |
||
53 | private $parallel = false; |
||
54 | |||
55 | /** |
||
56 | * @var bool |
||
57 | */ |
||
58 | private $showProgressBar = false; |
||
59 | |||
60 | /** |
||
61 | * @var ProgressBar|null |
||
62 | */ |
||
63 | private $progressBar; |
||
64 | |||
65 | 1 | public function __construct( |
|
85 | |||
86 | /** |
||
87 | * @return null|integer |
||
88 | */ |
||
89 | 1 | public function runChunks() |
|
114 | |||
115 | private function runChunk(int $chunkNum, array $chunk) |
||
136 | |||
137 | private function getChunkProcess(array $chunk) : Process |
||
147 | |||
148 | private function createProgressCallback(int $numTests) : Closure |
||
149 | { |
||
150 | if ($this->showProgressBar) { |
||
151 | $this->progressBar = $this->createChunkProgressBar($numTests); |
||
152 | |||
153 | return $this->createProgressBarCallback($this->progressBar); |
||
154 | } |
||
155 | |||
156 | if ($this->verbose) { |
||
157 | return function($type, $out) { |
||
158 | $this->extractDataFromPhpunitOutput($out); |
||
159 | |||
160 | $this->output->write($out); |
||
161 | }; |
||
162 | } |
||
163 | |||
164 | return function($type, $out) { |
||
165 | $this->extractDataFromPhpunitOutput($out); |
||
166 | }; |
||
167 | } |
||
168 | |||
169 | private function createProgressBarCallback(ProgressBar $progressBar) |
||
170 | { |
||
171 | return function(string $type, string $buffer) use ($progressBar) { |
||
172 | $this->extractDataFromPhpunitOutput($buffer); |
||
173 | |||
174 | if ($progressBar) { |
||
175 | if (in_array($buffer, ['F', 'E'])) { |
||
176 | $progressBar->setBarCharacter('<fg=red>=</>'); |
||
177 | } |
||
178 | |||
179 | if (in_array($buffer, ['F', 'E', 'S', '.'])) { |
||
180 | $progressBar->advance(); |
||
181 | } |
||
182 | } |
||
183 | }; |
||
184 | } |
||
185 | |||
186 | private function runChunkProcessParallel( |
||
197 | |||
198 | private function runChunkProcessSerial( |
||
238 | |||
239 | private function countNumTestsInChunk(array $chunk) : int |
||
240 | { |
||
241 | return array_sum(array_map(function(array $chunkFile) { |
||
242 | return $chunkFile['numTests']; |
||
243 | }, $chunk)); |
||
244 | } |
||
245 | |||
246 | private function buildFilesFromChunk(array $chunk) : array |
||
247 | { |
||
248 | return array_map(function(array $chunkFile) { |
||
249 | return $chunkFile['file']; |
||
250 | }, $chunk); |
||
251 | } |
||
252 | |||
253 | private function extractDataFromPhpunitOutput(string $outputBuffer) : int |
||
275 | |||
276 | private function createChunkProgressBar(int $numTests) : ProgressBar |
||
284 | } |
||
285 |