testUpdateOnOutputOffDoesNotCallUpdateOnOutput()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 32
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 21
c 1
b 0
f 0
dl 0
loc 32
rs 9.584
cc 1
nc 1
nop 0
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\Event\RunEvent;
17
use Graze\ParallelProcess\ProcessRun;
18
use Graze\ParallelProcess\RunInterface;
19
use Graze\ParallelProcess\Test\TestCase;
20
use Mockery;
21
use Symfony\Component\Process\Process;
22
23
class ProcessRunTest extends TestCase
24
{
25
    public function testRunImplementsRunInterface()
26
    {
27
        $process = Mockery::mock(Process::class);
28
        $process->shouldReceive('stop');
29
        $run = new ProcessRun($process);
0 ignored issues
show
Bug introduced by
$process of type Mockery\MockInterface is incompatible with the type Symfony\Component\Process\Process expected by parameter $process of Graze\ParallelProcess\ProcessRun::__construct(). ( Ignorable by Annotation )

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

29
        $run = new ProcessRun(/** @scrutinizer ignore-type */ $process);
Loading history...
30
        $this->assertInstanceOf(RunInterface::class, $run);
31
    }
32
33
    public function testInitialState()
34
    {
35
        $process = Mockery::mock(Process::class);
36
        $process->shouldReceive('stop');
37
38
        $run = new ProcessRun($process);
0 ignored issues
show
Bug introduced by
$process of type Mockery\MockInterface is incompatible with the type Symfony\Component\Process\Process expected by parameter $process of Graze\ParallelProcess\ProcessRun::__construct(). ( Ignorable by Annotation )

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

38
        $run = new ProcessRun(/** @scrutinizer ignore-type */ $process);
Loading history...
39
40
        $this->assertSame($process, $run->getProcess());
41
42
        $process->shouldReceive('isRunning')
43
                ->andReturn(false);
44
        $process->shouldReceive('isStarted')
45
                ->andReturn(false);
46
        $process->shouldReceive('isSuccessful')
47
                ->andReturn(false);
48
49
        $this->assertFalse($run->isRunning(), 'should not be running');
50
        $this->assertFalse($run->hasStarted(), 'should not have started');
51
        $this->assertFalse($run->isSuccessful(), 'should not be successful');
52
        $this->assertTrue($run->isUpdateOnPoll(), 'update on poll should be on by deafult');
53
        $this->assertTrue($run->isUpdateOnProcessOutput(), 'update on poll should be on by deafult');
54
        $this->assertEquals([], $run->getExceptions(), 'no exceptions should be returned');
55
    }
56
57
    public function testUpdateOnPoll()
58
    {
59
        $process = Mockery::mock(Process::class);
60
        $process->shouldReceive('stop');
61
62
        $run = new ProcessRun($process);
0 ignored issues
show
Bug introduced by
$process of type Mockery\MockInterface is incompatible with the type Symfony\Component\Process\Process expected by parameter $process of Graze\ParallelProcess\ProcessRun::__construct(). ( Ignorable by Annotation )

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

62
        $run = new ProcessRun(/** @scrutinizer ignore-type */ $process);
Loading history...
63
64
        $this->assertTrue($run->isUpdateOnPoll());
65
        $this->assertSame($run, $run->setUpdateOnPoll(false));
66
        $this->assertFalse($run->isUpdateOnPoll());
67
    }
68
69
    public function testUpdateOnProcessOutput()
70
    {
71
        $process = Mockery::mock(Process::class);
72
        $process->shouldReceive('stop');
73
74
        $run = new ProcessRun($process);
0 ignored issues
show
Bug introduced by
$process of type Mockery\MockInterface is incompatible with the type Symfony\Component\Process\Process expected by parameter $process of Graze\ParallelProcess\ProcessRun::__construct(). ( Ignorable by Annotation )

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

74
        $run = new ProcessRun(/** @scrutinizer ignore-type */ $process);
Loading history...
75
76
        $this->assertTrue($run->isUpdateOnProcessOutput());
77
        $this->assertSame($run, $run->setUpdateOnProcessOutput(false));
78
        $this->assertFalse($run->isUpdateOnProcessOutput());
79
    }
80
81
    public function testProcessRunning()
82
    {
83
        $process = Mockery::mock(Process::class);
84
        $process->shouldReceive('stop');
85
86
        $run = new ProcessRun($process);
0 ignored issues
show
Bug introduced by
$process of type Mockery\MockInterface is incompatible with the type Symfony\Component\Process\Process expected by parameter $process of Graze\ParallelProcess\ProcessRun::__construct(). ( Ignorable by Annotation )

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

86
        $run = new ProcessRun(/** @scrutinizer ignore-type */ $process);
Loading history...
87
88
        $process->shouldReceive('isRunning')
89
                ->andReturn(true); // check
90
        $process->shouldReceive('start');
91
92
        $process->shouldReceive('isStarted')
93
                ->andReturn(false, true); // start, check
94
95
        $run->start();
96
97
        $this->assertTrue($run->isRunning());
98
        $this->assertTrue($run->hasStarted());
99
        $this->assertFalse($run->isSuccessful());
100
    }
101
102
    public function testRun()
103
    {
104
        $process = Mockery::mock(Process::class);
105
        $process->shouldReceive('stop');
106
107
        $run = new ProcessRun($process);
0 ignored issues
show
Bug introduced by
$process of type Mockery\MockInterface is incompatible with the type Symfony\Component\Process\Process expected by parameter $process of Graze\ParallelProcess\ProcessRun::__construct(). ( Ignorable by Annotation )

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

107
        $run = new ProcessRun(/** @scrutinizer ignore-type */ $process);
Loading history...
108
109
        $process->shouldReceive('isRunning')->andReturn(true, false);
110
        $process->shouldReceive('start');
111
        $process->shouldReceive('isStarted')->andReturn(false, true);
112
113
        $run->start();
114
115
        $process->shouldReceive('isSuccessful')->andReturn(true);
116
117
        $this->assertTrue($run->poll());
118
        $this->assertFalse($run->poll());
119
        $this->assertTrue($run->isSuccessful());
120
        $this->assertTrue($run->hasStarted());
121
    }
122
123
    public function testOnStart()
124
    {
125
        $process = Mockery::mock(Process::class);
126
        $process->shouldReceive('stop');
127
128
        $hit = false;
129
130
        $run = new ProcessRun($process);
0 ignored issues
show
Bug introduced by
$process of type Mockery\MockInterface is incompatible with the type Symfony\Component\Process\Process expected by parameter $process of Graze\ParallelProcess\ProcessRun::__construct(). ( Ignorable by Annotation )

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

130
        $run = new ProcessRun(/** @scrutinizer ignore-type */ $process);
Loading history...
131
        $run->addListener(
132
            RunEvent::STARTED,
133
            function (RunEvent $event) use (&$run, &$hit) {
134
                $this->assertSame($event->getRun(), $run);
135
                $hit = true;
136
            }
137
        );
138
139
        $process->shouldReceive('start')->once();
140
        $process->shouldReceive('isStarted')->andReturn(false, true);
141
        $process->shouldReceive('isRunning')->andReturn(false);
142
        $process->shouldReceive('isSuccessful')->once()->andReturn(true);
143
144
        $run->start();
145
        $this->assertFalse($run->poll());
146
    }
147
148
    public function testOnSuccess()
149
    {
150
        $process = Mockery::mock(Process::class);
151
        $process->shouldReceive('stop');
152
153
        $hit = false;
154
155
        $run = new ProcessRun($process);
0 ignored issues
show
Bug introduced by
$process of type Mockery\MockInterface is incompatible with the type Symfony\Component\Process\Process expected by parameter $process of Graze\ParallelProcess\ProcessRun::__construct(). ( Ignorable by Annotation )

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

155
        $run = new ProcessRun(/** @scrutinizer ignore-type */ $process);
Loading history...
156
        $run->addListener(
157
            RunEvent::COMPLETED,
158
            function (RunEvent $event) use (&$run, &$hit) {
159
                $this->assertSame($event->getRun(), $run);
160
                $hit = true;
161
            }
162
        );
163
164
        $process->shouldReceive('start')->once();
165
        $process->shouldReceive('isStarted')->andReturn(false, true);
166
        $process->shouldReceive('isRunning')->andReturn(false);
167
        $process->shouldReceive('isSuccessful')->once()->andReturn(true);
168
169
        $run->start();
170
        $this->assertFalse($run->poll());
171
    }
172
173
    public function testOnFailure()
174
    {
175
        $process = Mockery::mock(Process::class);
176
        $process->shouldReceive('stop');
177
178
        $hit = false;
179
180
        $run = new ProcessRun($process);
0 ignored issues
show
Bug introduced by
$process of type Mockery\MockInterface is incompatible with the type Symfony\Component\Process\Process expected by parameter $process of Graze\ParallelProcess\ProcessRun::__construct(). ( Ignorable by Annotation )

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

180
        $run = new ProcessRun(/** @scrutinizer ignore-type */ $process);
Loading history...
181
        $run->addListener(
182
            RunEvent::FAILED,
183
            function (RunEvent $event) use (&$run, &$hit) {
184
                $this->assertSame($event->getRun(), $run);
185
                $hit = true;
186
            }
187
        );
188
189
        $process->shouldReceive('start')->once();
190
        $process->shouldReceive('isStarted')->andReturn(false, true);
191
        $process->shouldReceive('isRunning')->andReturn(false);
192
        $process->shouldReceive('isSuccessful')->once()->andReturn(false);
193
194
        $run->start();
195
        $this->assertFalse($run->poll());
196
    }
197
198
    public function testOnProgress()
199
    {
200
        $process = Mockery::mock(Process::class);
201
        $process->shouldReceive('stop');
202
203
        $hit = false;
204
205
        $run = new ProcessRun($process);
0 ignored issues
show
Bug introduced by
$process of type Mockery\MockInterface is incompatible with the type Symfony\Component\Process\Process expected by parameter $process of Graze\ParallelProcess\ProcessRun::__construct(). ( Ignorable by Annotation )

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

205
        $run = new ProcessRun(/** @scrutinizer ignore-type */ $process);
Loading history...
206
        $run->addListener(
207
            RunEvent::UPDATED,
208
            function (RunEvent $event) use (&$run, &$hit) {
209
                $this->assertSame($event->getRun(), $run);
210
                $hit = true;
211
            }
212
        );
213
214
        $process->shouldReceive('start')->once();
215
        $process->shouldReceive('isStarted')->andReturn(false, true);
216
        $process->shouldReceive('isRunning')->andReturn(true, false);
217
        $process->shouldReceive('isSuccessful')->once()->andReturn(true);
218
219
        $run->start();
220
        $this->assertTrue($run->poll());
221
        $this->assertFalse($run->poll());
222
    }
223
224
    public function testStartingAfterStartedWillDoNothing()
225
    {
226
        $process = Mockery::mock(Process::class);
227
        $process->shouldReceive('stop');
228
229
        $run = new ProcessRun($process);
0 ignored issues
show
Bug introduced by
$process of type Mockery\MockInterface is incompatible with the type Symfony\Component\Process\Process expected by parameter $process of Graze\ParallelProcess\ProcessRun::__construct(). ( Ignorable by Annotation )

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

229
        $run = new ProcessRun(/** @scrutinizer ignore-type */ $process);
Loading history...
230
231
        $process->shouldReceive('isStarted')
232
                ->andReturn(true);
233
234
        $this->assertSame($run, $run->start());
235
    }
236
237
    public function testEventsProvideDurationAndLastMessage()
238
    {
239
        $process = Mockery::mock(Process::class);
240
        $process->shouldReceive('stop');
241
242
        $process->shouldReceive('start')
243
                ->with(
244
                    Mockery::on(
245
                        function (callable $fn) {
246
                            $this->assertNotNull($fn);
247
                            $fn(Process::OUT, 'some text');
248
                            return true;
249
                        }
250
                    )
251
                )
252
                ->once();
253
254
        $run = new ProcessRun($process);
0 ignored issues
show
Bug introduced by
$process of type Mockery\MockInterface is incompatible with the type Symfony\Component\Process\Process expected by parameter $process of Graze\ParallelProcess\ProcessRun::__construct(). ( Ignorable by Annotation )

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

254
        $run = new ProcessRun(/** @scrutinizer ignore-type */ $process);
Loading history...
255
        $run->addListener(
256
            RunEvent::UPDATED,
257
            function (RunEvent $event) use (&$run, &$hits) {
258
                $this->assertSame($event->getRun(), $run);
259
                $this->assertInternalType('float', $run->getDuration());
0 ignored issues
show
Deprecated Code introduced by
The function PHPUnit\Framework\Assert::assertInternalType() has been deprecated: https://github.com/sebastianbergmann/phpunit/issues/3369 ( Ignorable by Annotation )

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

259
                /** @scrutinizer ignore-deprecated */ $this->assertInternalType('float', $run->getDuration());

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
260
                $this->assertEquals('some text', $run->getLastMessage());
261
                $this->assertEquals(Process::OUT, $run->getLastMessageType());
262
                $hits++;
263
            }
264
        );
265
266
        $process->shouldReceive('isStarted')->andReturn(false, true);
267
        $process->shouldReceive('isRunning')->andReturn(false);
268
        $process->shouldReceive('isSuccessful')->once()->andReturn(true);
269
270
        $run->start();
271
        $this->assertFalse($run->poll());
272
    }
273
274
    public function testLastMessageHavingMultipleLinesReturnsOnePerLine()
275
    {
276
        $process = Mockery::mock(Process::class);
277
        $process->shouldReceive('stop');
278
279
        $process->shouldReceive('start')
280
                ->with(
281
                    Mockery::on(
282
                        function (callable $fn) {
283
                            $this->assertNotNull($fn);
284
                            $fn(Process::OUT, "line 1\n\nline 2");
285
                            return true;
286
                        }
287
                    )
288
                )
289
                ->once();
290
291
        $hits = 0;
292
        $run = new ProcessRun($process);
0 ignored issues
show
Bug introduced by
$process of type Mockery\MockInterface is incompatible with the type Symfony\Component\Process\Process expected by parameter $process of Graze\ParallelProcess\ProcessRun::__construct(). ( Ignorable by Annotation )

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

292
        $run = new ProcessRun(/** @scrutinizer ignore-type */ $process);
Loading history...
293
        $run->addListener(
294
            RunEvent::UPDATED,
295
            function (RunEvent $event) use (&$run, &$hits) {
296
                $this->assertSame($event->getRun(), $run);
297
                $this->assertInternalType('float', $run->getDuration());
0 ignored issues
show
Deprecated Code introduced by
The function PHPUnit\Framework\Assert::assertInternalType() has been deprecated: https://github.com/sebastianbergmann/phpunit/issues/3369 ( Ignorable by Annotation )

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

297
                /** @scrutinizer ignore-deprecated */ $this->assertInternalType('float', $run->getDuration());

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
298
                $this->assertContains($run->getLastMessage(), ['line 1', 'line 2']);
299
                $this->assertEquals(Process::OUT, $run->getLastMessageType());
300
                $hits++;
301
            }
302
        );
303
304
        $process->shouldReceive('isStarted')->andReturn(false, true);
305
        $process->shouldReceive('isRunning')->andReturn(false);
306
        $process->shouldReceive('isSuccessful')->once()->andReturn(true);
307
308
        $run->start();
309
        $this->assertFalse($run->poll());
310
        $this->assertEquals(2, $hits);
311
    }
312
313
    public function testUpdateOnPollOffDoesNotUpdateOnPoll()
314
    {
315
        $process = Mockery::mock(Process::class);
316
        $process->shouldReceive('stop');
317
318
        $process->shouldReceive('start')->once();
319
320
        $run = new ProcessRun($process);
0 ignored issues
show
Bug introduced by
$process of type Mockery\MockInterface is incompatible with the type Symfony\Component\Process\Process expected by parameter $process of Graze\ParallelProcess\ProcessRun::__construct(). ( Ignorable by Annotation )

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

320
        $run = new ProcessRun(/** @scrutinizer ignore-type */ $process);
Loading history...
321
        $run->addListener(
322
            RunEvent::UPDATED,
323
            function () {
324
                $this->fail('onProgress should not be called');
325
            }
326
        );
327
        $run->setUpdateOnPoll(false);
328
329
        $process->shouldReceive('isStarted')->andReturn(false, true);
330
        $process->shouldReceive('isRunning')->andReturn(true, false);
331
        $process->shouldReceive('isSuccessful')->once()->andReturn(true);
332
333
        $run->start();
334
        $this->assertTrue($run->poll());
335
        $this->assertFalse($run->poll());
336
    }
337
338
    public function testUpdateOnOutputOffDoesNotCallUpdateOnOutput()
339
    {
340
        $process = Mockery::mock(Process::class);
341
        $process->shouldReceive('stop');
342
343
        $process->shouldReceive('start')
344
                ->with(
345
                    Mockery::on(
346
                        function (callable $fn) {
347
                            $this->assertNotNull($fn);
348
                            $fn(Process::STDOUT, 'some text');
349
                            return true;
350
                        }
351
                    )
352
                )
353
                ->once();
354
355
        $run = new ProcessRun($process);
0 ignored issues
show
Bug introduced by
$process of type Mockery\MockInterface is incompatible with the type Symfony\Component\Process\Process expected by parameter $process of Graze\ParallelProcess\ProcessRun::__construct(). ( Ignorable by Annotation )

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

355
        $run = new ProcessRun(/** @scrutinizer ignore-type */ $process);
Loading history...
356
        $run->addListener(
357
            RunEvent::UPDATED,
358
            function () {
359
                $this->fail('onProgress should not be called');
360
            }
361
        );
362
        $run->setUpdateOnProcessOutput(false);
363
364
        $process->shouldReceive('isStarted')->andReturn(false, true);
365
        $process->shouldReceive('isRunning')->andReturn(false);
366
        $process->shouldReceive('isSuccessful')->once()->andReturn(true);
367
368
        $run->start();
369
        $this->assertFalse($run->poll());
370
    }
371
372
    public function testGetPriority()
373
    {
374
        $process = Mockery::mock(Process::class);
375
        $process->allows(['stop' => null, 'isStarted' => false]);
376
        $run = new ProcessRun($process, [], 1.5);
0 ignored issues
show
Bug introduced by
$process of type Mockery\MockInterface is incompatible with the type Symfony\Component\Process\Process expected by parameter $process of Graze\ParallelProcess\ProcessRun::__construct(). ( Ignorable by Annotation )

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

376
        $run = new ProcessRun(/** @scrutinizer ignore-type */ $process, [], 1.5);
Loading history...
377
378
        $this->assertEquals(1.5, $run->getPriority());
379
        $this->assertSame($run, $run->setPriority(2));
380
        $this->assertEquals(2, $run->getPriority());
381
    }
382
}
383