Passed
Pull Request — master (#16)
by Harry
07:40 queued 02:51
created

TableTest::testProgressBar()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 118
Code Lines 104

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 104
dl 0
loc 118
rs 8
c 0
b 0
f 0
cc 1
nc 1
nop 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
/**
3
 * This file is part of graze/parallel-process.
4
 *
5
 * Copyright © 2018 Nature Delivered Ltd. <https://www.graze.com>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 *
10
 * @license https://github.com/graze/parallel-process/blob/master/LICENSE.md
11
 * @link    https://github.com/graze/parallel-process
12
 */
13
14
namespace Graze\ParallelProcess\Test\Unit;
15
16
use Graze\ParallelProcess\Pool;
17
use Graze\ParallelProcess\Run;
18
use Graze\ParallelProcess\Table;
19
use Graze\ParallelProcess\Test\BufferDiffOutput;
20
use Graze\ParallelProcess\Test\TestCase;
21
use Mockery;
22
use Symfony\Component\Console\Output\ConsoleOutputInterface;
23
use Symfony\Component\Console\Output\OutputInterface;
24
use Symfony\Component\Process\Exception\ProcessFailedException;
25
use Symfony\Component\Process\Process;
26
27
class TableTest extends TestCase
28
{
29
    /** @var BufferDiffOutput */
30
    private $bufferOutput;
31
    /** @var mixed */
32
    private $pool;
33
    /** @var Table */
34
    private $table;
35
36
    public function setUp()
37
    {
38
        mb_internal_encoding("UTF-8");
39
        $this->bufferOutput = new BufferDiffOutput();
40
        $this->pool = Mockery::mock(Pool::class)->makePartial();
41
        $this->table = new Table($this->bufferOutput, $this->pool);
0 ignored issues
show
Bug introduced by
$this->pool of type Mockery\Mock is incompatible with the type null|Graze\ParallelProcess\Pool expected by parameter $pool of Graze\ParallelProcess\Table::__construct(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

41
        $this->table = new Table($this->bufferOutput, /** @scrutinizer ignore-type */ $this->pool);
Loading history...
42
    }
43
44
    public function testConstructWithNonBufferedOutput()
45
    {
46
        $output = Mockery::mock(ConsoleOutputInterface::class);
47
        $table = new Table($output);
0 ignored issues
show
Bug introduced by
$output of type Mockery\MockInterface is incompatible with the type Symfony\Component\Console\Output\OutputInterface expected by parameter $output of Graze\ParallelProcess\Table::__construct(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

47
        $table = new Table(/** @scrutinizer ignore-type */ $output);
Loading history...
48
49
        $this->assertInstanceOf(Table::class, $table);
50
    }
51
52
    public function testShowOutput()
53
    {
54
        $output = Mockery::mock(ConsoleOutputInterface::class);
55
        $table = new Table($output);
0 ignored issues
show
Bug introduced by
$output of type Mockery\MockInterface is incompatible with the type Symfony\Component\Console\Output\OutputInterface expected by parameter $output of Graze\ParallelProcess\Table::__construct(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

55
        $table = new Table(/** @scrutinizer ignore-type */ $output);
Loading history...
56
57
        $this->assertTrue($table->isShowOutput());
58
59
        $this->assertSame($table, $table->setShowOutput(false));
60
61
        $this->assertFalse($table->isShowOutput());
62
    }
63
64
    public function testShowSummary()
65
    {
66
        $output = Mockery::mock(ConsoleOutputInterface::class);
67
        $table = new Table($output);
0 ignored issues
show
Bug introduced by
$output of type Mockery\MockInterface is incompatible with the type Symfony\Component\Console\Output\OutputInterface expected by parameter $output of Graze\ParallelProcess\Table::__construct(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

67
        $table = new Table(/** @scrutinizer ignore-type */ $output);
Loading history...
68
69
        $this->assertTrue($table->isShowSummary());
70
71
        $this->assertSame($table, $table->setShowSummary(false));
72
73
        $this->assertFalse($table->isShowSummary());
74
    }
75
76
    public function testSpinnerLoop()
77
    {
78
        $this->table->setShowSummary(false);
79
        $this->bufferOutput->setVerbosity(OutputInterface::VERBOSITY_VERBOSE);
80
81
        $process = Mockery::mock(Process::class);
82
        $process->shouldReceive('stop');
83
        $process->shouldReceive('start')->once();
84
        $process->shouldReceive('isStarted')->andReturn(true);
85
        $process->shouldReceive('isRunning')->andReturn(
86
            false, // add
87
            false, // start
88
            true,  // check
89
            true,  // ...
90
            true,
91
            true,
92
            true,
93
            true,
94
            true,
95
            true,
96
            true,
97
            true,
98
            true,
99
            false // complete
100
        );
101
        $process->shouldReceive('isSuccessful')->atLeast()->once()->andReturn(true);
102
103
        $this->pool->add($process, ['key' => 'value']);
104
105
        $this->table->run(0);
106
107
        $expected = [
108
            ['%<info>key</info>: value \(<comment>[ 0-9\.s]+</comment>\) %'],
109
            ['%<info>key</info>: value \(<comment>[ 0-9\.s]+</comment>\) ⠋%'],
110
            ['%<info>key</info>: value \(<comment>[ 0-9\.s]+</comment>\) ⠙%'],
111
            ['%<info>key</info>: value \(<comment>[ 0-9\.s]+</comment>\) ⠹%'],
112
            ['%<info>key</info>: value \(<comment>[ 0-9\.s]+</comment>\) ⠸%'],
113
            ['%<info>key</info>: value \(<comment>[ 0-9\.s]+</comment>\) ⠼%'],
114
            ['%<info>key</info>: value \(<comment>[ 0-9\.s]+</comment>\) ⠴%'],
115
            ['%<info>key</info>: value \(<comment>[ 0-9\.s]+</comment>\) ⠦%'],
116
            ['%<info>key</info>: value \(<comment>[ 0-9\.s]+</comment>\) ⠧%'],
117
            ['%<info>key</info>: value \(<comment>[ 0-9\.s]+</comment>\) ⠇%'],
118
            ['%<info>key</info>: value \(<comment>[ 0-9\.s]+</comment>\) ⠏%'],
119
            ['%<info>key</info>: value \(<comment>[ 0-9\.s]+</comment>\) ⠋%'],
120
            ['%<info>key</info>: value \(<comment>[ 0-9\.s]+</comment>\) <info>✓</info>%'],
121
        ];
122
123
        $this->compareOutputs($expected, $this->bufferOutput->getWritten());
124
    }
125
126
    public function testProgressBar()
127
    {
128
        $this->table->setShowSummary(false);
129
        $this->bufferOutput->setVerbosity(OutputInterface::VERBOSITY_VERBOSE);
130
131
        $process = Mockery::mock(Process::class);
132
        $process->shouldReceive('stop');
133
        $process->shouldReceive('start')->once();
134
        $process->shouldReceive('isStarted')->andReturn(true);
135
        $process->shouldReceive('isRunning')->andReturn(
136
            false, // add
137
            false, // start
138
            true,  // check
139
            true,  // ...
140
            true,
141
            true,
142
            true,
143
            true,
144
            true,
145
            true,
146
            true,
147
            true,
148
            true,
149
            true,
150
            true,
151
            true,
152
            true,
153
            true,
154
            true,
155
            true,
156
            true,
157
            true,
158
            false // complete
159
        );
160
        $process->shouldReceive('isSuccessful')->atLeast()->once()->andReturn(true);
161
162
        $run = Mockery::mock(Run::class, [$process, ['key' => 'value']])->makePartial();
163
        $this->pool->add($run);
164
165
        $run->allows()
166
            ->getProgress()
167
            ->andReturns(
168
                [0, 100, 0],
169
                [5, 100, 0.05],
170
                [10, 100, 0.1],
171
                [15, 100, 0.15],
172
                [20, 100, 0.2],
173
                [25, 100, 0.25],
174
                [30, 100, 0.3],
175
                [35, 100, 0.35],
176
                [40, 100, 0.4],
177
                [45, 100, 0.45],
178
                [50, 100, 0.5],
179
                [55, 100, 0.55],
180
                [60, 100, 0.6],
181
                [65, 100, 0.65],
182
                [70, 100, 0.7],
183
                [75, 100, 0.75],
184
                [80, 100, 0.8],
185
                [85, 100, 0.85],
186
                [90, 100, 0.9],
187
                [95, 100, 0.95],
188
                [100, 100, 1]
189
            );
190
        $run->allows()
191
            ->getDuration()
192
            ->andReturns(
193
                0,
194
                0.05,
195
                0.1,
196
                0.15,
197
                0.2,
198
                0.25,
199
                0.3,
200
                0.35,
201
                0.4,
202
                0.45,
203
                0.5,
204
                0.55,
205
                0.6,
206
                0.65,
207
                0.7,
208
                0.75,
209
                0.8,
210
                0.85,
211
                0.9,
212
                0.95,
213
                1
214
            );
215
216
        $this->table->run(0);
217
218
        $expected = [
219
            ['/<info>key<\/info>: value \(<comment>  0.00s<\/comment>\) /'],
220
            ['/<info>key<\/info>: value \(<comment>  0.00s<\/comment>\) ▕<comment>  <\/comment>▏<info>  0%<\/info>/'],
221
            ['/<info>key<\/info>: value \(<comment>  0.05s<\/comment>\) ▕<comment>▏ <\/comment>▏<info>  5%<\/info>/'],
222
            ['/<info>key<\/info>: value \(<comment>  0.10s<\/comment>\) ▕<comment>▎ <\/comment>▏<info> 10%<\/info>/'],
223
            ['/<info>key<\/info>: value \(<comment>  0.15s<\/comment>\) ▕<comment>▍ <\/comment>▏<info> 15%<\/info>/'],
224
            ['/<info>key<\/info>: value \(<comment>  0.20s<\/comment>\) ▕<comment>▍ <\/comment>▏<info> 20%<\/info>/'],
225
            ['/<info>key<\/info>: value \(<comment>  0.25s<\/comment>\) ▕<comment>▌ <\/comment>▏<info> 25%<\/info>/'],
226
            ['/<info>key<\/info>: value \(<comment>  0.30s<\/comment>\) ▕<comment>▋ <\/comment>▏<info> 30%<\/info>/'],
227
            ['/<info>key<\/info>: value \(<comment>  0.35s<\/comment>\) ▕<comment>▋ <\/comment>▏<info> 35%<\/info>/'],
228
            ['/<info>key<\/info>: value \(<comment>  0.40s<\/comment>\) ▕<comment>▊ <\/comment>▏<info> 40%<\/info>/'],
229
            ['/<info>key<\/info>: value \(<comment>  0.45s<\/comment>\) ▕<comment>▉ <\/comment>▏<info> 45%<\/info>/'],
230
            ['/<info>key<\/info>: value \(<comment>  0.50s<\/comment>\) ▕<comment>█ <\/comment>▏<info> 50%<\/info>/'],
231
            ['/<info>key<\/info>: value \(<comment>  0.55s<\/comment>\) ▕<comment>█▏<\/comment>▏<info> 55%<\/info>/'],
232
            ['/<info>key<\/info>: value \(<comment>  0.60s<\/comment>\) ▕<comment>█▎<\/comment>▏<info> 60%<\/info>/'],
233
            ['/<info>key<\/info>: value \(<comment>  0.65s<\/comment>\) ▕<comment>█▍<\/comment>▏<info> 65%<\/info>/'],
234
            ['/<info>key<\/info>: value \(<comment>  0.70s<\/comment>\) ▕<comment>█▍<\/comment>▏<info> 70%<\/info>/'],
235
            ['/<info>key<\/info>: value \(<comment>  0.75s<\/comment>\) ▕<comment>█▌<\/comment>▏<info> 75%<\/info>/'],
236
            ['/<info>key<\/info>: value \(<comment>  0.80s<\/comment>\) ▕<comment>█▋<\/comment>▏<info> 80%<\/info>/'],
237
            ['/<info>key<\/info>: value \(<comment>  0.85s<\/comment>\) ▕<comment>█▋<\/comment>▏<info> 85%<\/info>/'],
238
            ['/<info>key<\/info>: value \(<comment>  0.90s<\/comment>\) ▕<comment>█▊<\/comment>▏<info> 90%<\/info>/'],
239
            ['/<info>key<\/info>: value \(<comment>  0.95s<\/comment>\) ▕<comment>█▉<\/comment>▏<info> 95%<\/info>/'],
240
            ['/<info>key<\/info>: value \(<comment>  1.00s<\/comment>\) <info>✓<\/info>/'],
241
        ];
242
243
        $this->compareOutputs($expected, $this->bufferOutput->getWritten());
244
    }
245
246
    public function testValueDataArrayDoesNotShowTheKey()
247
    {
248
        $this->table->setShowSummary(false);
249
        $this->bufferOutput->setVerbosity(OutputInterface::VERBOSITY_VERBOSE);
250
251
        $process = Mockery::mock(Process::class);
252
        $process->shouldReceive('stop');
253
        $process->shouldReceive('start')->once();
254
        $process->shouldReceive('isStarted')->andReturn(true);
255
        $process->shouldReceive('isRunning')->andReturn(
256
            false, // add
257
            false, // start
258
            true,  // check
259
            false // complete
260
        );
261
        $process->shouldReceive('isSuccessful')->atLeast()->once()->andReturn(true);
262
263
        $this->pool->add($process, ['value', 'value2']);
264
265
        $this->table->run(0);
266
267
        $expected = [
268
            ['%value value2 \(<comment>[ 0-9\.s]+</comment>\) %'],
269
            ['%value value2 \(<comment>[ 0-9\.s]+</comment>\) ⠋%'],
270
            ['%value value2 \(<comment>[ 0-9\.s]+</comment>\) <info>✓</info>%'],
271
        ];
272
273
        $this->compareOutputs($expected, $this->bufferOutput->getWritten());
274
    }
275
276
    public function testSummaryIsWaitingBeforeTheProcessStarts()
277
    {
278
        $this->bufferOutput->setVerbosity(OutputInterface::VERBOSITY_VERBOSE);
279
        $this->table->setShowOutput(true);
280
        $this->table->setShowSummary(true);
281
282
        $oneFails = false;
283
284
        $process = Mockery::mock(Process::class);
285
        $process->shouldReceive('stop');
286
        $process->shouldReceive('start')->with(Mockery::on(function ($closure) {
287
            call_user_func($closure, Process::OUT, 'some text');
288
            return true;
289
        }))->once();
290
        $process->shouldReceive('isStarted')->andReturn(false, true);
291
        $process->shouldReceive('isRunning')->andReturn(false, false, true, false); // add, start, check, check
292
        $process->shouldReceive('isSuccessful')->atLeast()->once()->andReturn(true);
293
        $process->shouldReceive('getOutput')->andReturn('some text');
294
295
        $this->pool->add($process, ['key' => 'value']);
296
297
        try {
298
            $this->table->run(0);
299
        } catch (\Exception $e) {
300
            if (!$oneFails || !$e instanceof ProcessFailedException) {
0 ignored issues
show
introduced by
The condition $oneFails is always false.
Loading history...
301
                throw $e;
302
            }
303
        }
304
305
        $expected = [
306
            [
307
                '%<info>key</info>: value \(<comment>[ 0-9\.s]+</comment>\) %',
308
                '%waiting...%',
309
            ],
310
            [
311
                '%<info>key</info>: value \(<comment>[ 0-9\.s]+</comment>\) %',
312
                '%<comment>Total</comment>:  1, <comment>Running</comment>:  1, <comment>Waiting</comment>:  0%',
313
            ],
314
            [
315
                '%<info>key</info>: value \(<comment>[ 0-9\.s]+</comment>\) <info>✓</info>%',
316
                '%<comment>Total</comment>:  1, <comment>Running</comment>:  1, <comment>Waiting</comment>:  0%',
317
            ],
318
            [
319
                '%<info>key</info>: value \(<comment>[ 0-9\.s]+</comment>\) <info>✓</info>%',
320
                '%^$%',
321
            ],
322
        ];
323
324
        $this->compareOutputs($expected, $this->bufferOutput->getWritten());
325
    }
326
327
    /**
328
     * Runs a series of processes, each doing initial state, single on progress run, single complete entry
329
     *
330
     * @dataProvider outputData
331
     *
332
     * @param int        $verbosity     OutputInterface::VERBOSITY_*
333
     * @param bool       $showOutput    Should it display some output text
334
     * @param bool       $showSummary   Should we show a summary
335
     * @param bool[]     $processStates an entry for each process to run, true = success, false = failure
336
     * @param string[][] $outputs       Regex patterns for the output string
337
     *
338
     * @throws \Exception
339
     */
340
    public function testOutput($verbosity, $showOutput, $showSummary, array $processStates, array $outputs)
341
    {
342
        $this->bufferOutput->setVerbosity($verbosity);
343
        $this->table->setShowOutput($showOutput);
344
        $this->table->setShowSummary($showSummary);
345
346
        $oneFails = false;
347
348
        for ($i = 0; $i < count($processStates); $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...
349
            $process = Mockery::mock(Process::class);
350
            $process->shouldReceive('stop');
351
            $process->shouldReceive('start')->with(Mockery::on(function ($closure) {
352
                call_user_func($closure, Process::OUT, 'some text');
353
                return true;
354
            }))->once();
355
            $process->shouldReceive('isStarted')->andReturn(true);
356
            $process->shouldReceive('isRunning')->andReturn(false, false, true, false); // add, start, check, check
357
            $process->shouldReceive('isSuccessful')->atLeast()->once()->andReturn($processStates[$i]);
358
            $process->shouldReceive('getOutput')->andReturn('some text');
359
360
            if (!$processStates[$i]) {
361
                $process->shouldReceive('getCommandLine')->andReturn('test');
362
                $process->shouldReceive('getExitCode')->andReturn(1);
363
                $process->shouldReceive('getExitCodeText')->andReturn('failed');
364
                $process->shouldReceive('getWorkingDirectory')->andReturn('/tmp');
365
                $process->shouldReceive('isOutputDisabled')->andReturn(false);
366
                $process->shouldReceive('getErrorOutput')->andReturn('some error text');
367
                $oneFails = true;
368
            }
369
370
            $this->pool->add($process, ['key' => 'value', 'run' => $i]);
371
        }
372
373
        try {
374
            $this->table->run(0);
375
        } catch (\Exception $e) {
376
            if (!$oneFails || !$e instanceof ProcessFailedException) {
377
                throw $e;
378
            }
379
        }
380
381
        $this->compareOutputs($outputs, $this->bufferOutput->getWritten());
382
    }
383
384
    /**
385
     * @return array
386
     */
387
    public function outputData()
388
    {
389
        return [
390
            [ // verbose with single valid run
391
              OutputInterface::VERBOSITY_VERBOSE,
392
              false,
393
              false,
394
              [true],
395
              [
396
                  ['%<info>key</info>: value <info>run</info>: 0 \(<comment>[ 0-9\.s]+</comment>\) %'],
397
                  ['%<info>key</info>: value <info>run</info>: 0 \(<comment>[ 0-9\.s]+</comment>\) [⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏]%'],
398
                  ['%<info>key</info>: value <info>run</info>: 0 \(<comment>[ 0-9\.s]+</comment>\) <info>✓</info>%'],
399
              ],
400
            ],
401
            [ // normal verbosity only writes a single line
402
              OutputInterface::VERBOSITY_NORMAL,
403
              false,
404
              false,
405
              [true],
406
              [
407
                  ['%<info>key</info>: value <info>run</info>: 0 \(<comment>[ 0-9\.s]+</comment>\) <info>✓</info>%'],
408
              ],
409
            ],
410
            [
411
                OutputInterface::VERBOSITY_NORMAL,
412
                false,
413
                false,
414
                [true, true],
415
                [
416
                    ['%<info>key</info>: value <info>run</info>: 0 \(<comment>[ 0-9\.s]+</comment>\) <info>✓</info>%'],
417
                    ['%<info>key</info>: value <info>run</info>: 1 \(<comment>[ 0-9\.s]+</comment>\) <info>✓</info>%'],
418
                ],
419
            ],
420
            [ // multiple runs with verbosity will update each item one at a time
421
              OutputInterface::VERBOSITY_VERBOSE,
422
              false,
423
              false,
424
              [true, true],
425
              [
426
                  [
427
                      '%<info>key</info>: value <info>run</info>: 0 \(<comment>[ 0-9\.s]+</comment>\) %',
428
                      '%<info>key</info>: value <info>run</info>: 1 \(<comment>[ 0-9\.s]+</comment>\) %',
429
                  ],
430
                  [
431
                      '%<info>key</info>: value <info>run</info>: 0 \(<comment>[ 0-9\.s]+</comment>\) [⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏]%',
432
                      '%<info>key</info>: value <info>run</info>: 1 \(<comment>[ 0-9\.s]+</comment>\) %',
433
                  ],
434
                  [
435
                      '%<info>key</info>: value <info>run</info>: 0 \(<comment>[ 0-9\.s]+</comment>\) [⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏]%',
436
                      '%<info>key</info>: value <info>run</info>: 1 \(<comment>[ 0-9\.s]+</comment>\) [⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏]%',
437
                  ],
438
                  [
439
                      '%<info>key</info>: value <info>run</info>: 0 \(<comment>[ 0-9\.s]+</comment>\) <info>✓</info>%',
440
                      '%<info>key</info>: value <info>run</info>: 1 \(<comment>[ 0-9\.s]+</comment>\) [⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏]%',
441
                  ],
442
                  [
443
                      '%<info>key</info>: value <info>run</info>: 0 \(<comment>[ 0-9\.s]+</comment>\) <info>✓</info>%',
444
                      '%<info>key</info>: value <info>run</info>: 1 \(<comment>[ 0-9\.s]+</comment>\) <info>✓</info>%',
445
                  ],
446
              ],
447
            ],
448
            [ // errors will display an error
449
              OutputInterface::VERBOSITY_VERBOSE,
450
              false,
451
              false,
452
              [false],
453
              [
454
                  ['%<info>key</info>: value <info>run</info>: 0 \(<comment>[ 0-9\.s]+</comment>\) %'],
455
                  ['%<info>key</info>: value <info>run</info>: 0 \(<comment>[ 0-9\.s]+</comment>\) [⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏]%'],
456
                  ['%<info>key</info>: value <info>run</info>: 0 \(<comment>[ 0-9\.s]+</comment>\) <error>x</error>%'],
457
                  [
458
                      <<<DOC
459
%The command "test" failed.
460
461
Exit Code: 1\(failed\)
462
463
Working directory: /tmp
464
465
Output:
466
================
467
some text
468
469
Error Output:
470
================
471
some error text%
472
DOC
473
                      ,
474
                  ],
475
              ],
476
            ],
477
            [ // errors will display an error
478
              OutputInterface::VERBOSITY_NORMAL,
479
              false,
480
              false,
481
              [false],
482
              [
483
                  ['%<info>key</info>: value <info>run</info>: 0 \(<comment>[ 0-9\.s]+</comment>\) <error>x</error>%'],
484
                  [
485
                      <<<DOC
486
%The command "test" failed.
487
488
Exit Code: 1\(failed\)
489
490
Working directory: /tmp
491
492
Output:
493
================
494
some text
495
496
Error Output:
497
================
498
some error text%
499
DOC
500
                      ,
501
                  ],
502
              ],
503
            ],
504
            [ // multiple runs with verbosity will update each item one at a time
505
              OutputInterface::VERBOSITY_VERBOSE,
506
              false,
507
              false,
508
              [true, false],
509
              [
510
                  [
511
                      '%<info>key</info>: value <info>run</info>: 0 \(<comment>[ 0-9\.s]+</comment>\) %',
512
                      '%<info>key</info>: value <info>run</info>: 1 \(<comment>[ 0-9\.s]+</comment>\) %',
513
                  ],
514
                  [
515
                      '%<info>key</info>: value <info>run</info>: 0 \(<comment>[ 0-9\.s]+</comment>\) [⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏]%',
516
                      '%<info>key</info>: value <info>run</info>: 1 \(<comment>[ 0-9\.s]+</comment>\) %',
517
                  ],
518
                  [
519
                      '%<info>key</info>: value <info>run</info>: 0 \(<comment>[ 0-9\.s]+</comment>\) [⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏]%',
520
                      '%<info>key</info>: value <info>run</info>: 1 \(<comment>[ 0-9\.s]+</comment>\) [⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏]%',
521
                  ],
522
                  [
523
                      '%<info>key</info>: value <info>run</info>: 0 \(<comment>[ 0-9\.s]+</comment>\) <info>✓</info>%',
524
                      '%<info>key</info>: value <info>run</info>: 1 \(<comment>[ 0-9\.s]+</comment>\) [⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏]%',
525
                  ],
526
                  [
527
                      '%<info>key</info>: value <info>run</info>: 0 \(<comment>[ 0-9\.s]+</comment>\) <info>✓</info>%',
528
                      '%<info>key</info>: value <info>run</info>: 1 \(<comment>[ 0-9\.s]+</comment>\) <error>x</error>%',
529
                  ],
530
                  [
531
                      <<<DOC
532
%The command "test" failed.
533
534
Exit Code: 1\(failed\)
535
536
Working directory: /tmp
537
538
Output:
539
================
540
some text
541
542
Error Output:
543
================
544
some error text%
545
DOC
546
                      ,
547
                  ],
548
              ],
549
            ],
550
            [ // include output
551
              OutputInterface::VERBOSITY_VERBOSE,
552
              true,
553
              false,
554
              [true],
555
              [
556
                  ['%(*UTF8)<info>key</info>: value <info>run</info>: 0 \(<comment>[ 0-9\.s]+</comment>\) %'],
557
                  ['%(*UTF8)<info>key</info>: value <info>run</info>: 0 \(<comment>[ 0-9\.s]+</comment>\) [⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏]  some text%'],
558
                  ['%(*UTF8)<info>key</info>: value <info>run</info>: 0 \(<comment>[ 0-9\.s]+</comment>\) <info>✓</info>  some text%'],
559
              ],
560
            ],
561
            [ // include a summary
562
              OutputInterface::VERBOSITY_VERBOSE,
563
              false,
564
              true,
565
              [true, true],
566
              [
567
                  [
568
                      '%<info>key</info>: value <info>run</info>: 0 \(<comment>[ 0-9\.s]+</comment>\) %',
569
                      '%<info>key</info>: value <info>run</info>: 1 \(<comment>[ 0-9\.s]+</comment>\) %',
570
                      '%^$%',
571
                  ],
572
                  [
573
                      '%<info>key</info>: value <info>run</info>: 0 \(<comment>[ 0-9\.s]+</comment>\) [⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏]%',
574
                      '%<info>key</info>: value <info>run</info>: 1 \(<comment>[ 0-9\.s]+</comment>\) %',
575
                      '%<comment>Total</comment>:  2, <comment>Running</comment>:  2, <comment>Waiting</comment>:  0%',
576
                  ],
577
                  [
578
                      '%<info>key</info>: value <info>run</info>: 0 \(<comment>[ 0-9\.s]+</comment>\) [⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏]%',
579
                      '%<info>key</info>: value <info>run</info>: 1 \(<comment>[ 0-9\.s]+</comment>\) [⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏]%',
580
                      '%<comment>Total</comment>:  2, <comment>Running</comment>:  2, <comment>Waiting</comment>:  0%',
581
                  ],
582
                  [
583
                      '%<info>key</info>: value <info>run</info>: 0 \(<comment>[ 0-9\.s]+</comment>\) <info>✓</info>%',
584
                      '%<info>key</info>: value <info>run</info>: 1 \(<comment>[ 0-9\.s]+</comment>\) [⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏]%',
585
                      '%<comment>Total</comment>:  2, <comment>Running</comment>:  2, <comment>Waiting</comment>:  0%',
586
                  ],
587
                  [
588
                      '%<info>key</info>: value <info>run</info>: 0 \(<comment>[ 0-9\.s]+</comment>\) <info>✓</info>%',
589
                      '%<info>key</info>: value <info>run</info>: 1 \(<comment>[ 0-9\.s]+</comment>\) <info>✓</info>%',
590
                      '%<comment>Total</comment>:  2, <comment>Running</comment>:  2, <comment>Waiting</comment>:  0%',
591
                  ],
592
                  [
593
                      '%<info>key</info>: value <info>run</info>: 0 \(<comment>[ 0-9\.s]+</comment>\) <info>✓</info>%',
594
                      '%<info>key</info>: value <info>run</info>: 1 \(<comment>[ 0-9\.s]+</comment>\) <info>✓</info>%',
595
                      '%^$%',
596
                  ],
597
              ],
598
            ],
599
        ];
600
    }
601
}
602