Passed
Push — master ( c649ab...71b580 )
by Harry
02:19
created

RunTest::testOnFailure()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 23
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 23
rs 9.0856
c 0
b 0
f 0
cc 1
eloc 15
nc 1
nop 0
1
<?php
2
3
namespace Graze\ParallelProcess\Test\Unit;
4
5
use Graze\ParallelProcess\Run;
6
use Graze\ParallelProcess\RunInterface;
7
use Graze\ParallelProcess\Test\TestCase;
8
use Mockery;
9
use Symfony\Component\Process\Process;
10
11
class RunTest extends TestCase
12
{
13
    public function testRunImplementsRunInterface()
14
    {
15
        $process = Mockery::mock(Process::class);
16
        $process->shouldReceive('stop');
17
        $run = new Run($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\Run::__construct(). ( Ignorable by Annotation )

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

17
        $run = new Run(/** @scrutinizer ignore-type */ $process);
Loading history...
18
        $this->assertInstanceOf(RunInterface::class, $run);
19
    }
20
21
    public function testInitialState()
22
    {
23
        $process = Mockery::mock(Process::class);
24
        $process->shouldReceive('stop');
25
26
        $run = new Run($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\Run::__construct(). ( Ignorable by Annotation )

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

26
        $run = new Run(/** @scrutinizer ignore-type */ $process);
Loading history...
27
28
        $this->assertSame($process, $run->getProcess());
29
30
        $process->shouldReceive('isRunning')
31
                ->andReturn(false);
32
        $process->shouldReceive('isStarted')
33
                ->andReturn(false);
34
        $process->shouldReceive('isSuccessful')
35
                ->andReturn(false);
36
37
        $this->assertFalse($run->isRunning(), 'should not be running');
38
        $this->assertFalse($run->hasStarted(), 'should not have started');
39
        $this->assertFalse($run->isSuccessful(), 'should not be successful');
40
        $this->assertTrue($run->isUpdateOnPoll(), 'update on poll should be on by deafult');
41
        $this->assertTrue($run->isUpdateOnProcessOutput(), 'update on poll should be on by deafult');
42
    }
43
44
    public function testUpdateOnPoll()
45
    {
46
        $process = Mockery::mock(Process::class);
47
        $process->shouldReceive('stop');
48
49
        $run = new Run($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\Run::__construct(). ( Ignorable by Annotation )

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

49
        $run = new Run(/** @scrutinizer ignore-type */ $process);
Loading history...
50
51
        $this->assertTrue($run->isUpdateOnPoll());
52
        $this->assertSame($run, $run->setUpdateOnPoll(false));
53
        $this->assertFalse($run->isUpdateOnPoll());
54
    }
55
56
    public function testUpdateOnProcessOutput()
57
    {
58
        $process = Mockery::mock(Process::class);
59
        $process->shouldReceive('stop');
60
61
        $run = new Run($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\Run::__construct(). ( Ignorable by Annotation )

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

61
        $run = new Run(/** @scrutinizer ignore-type */ $process);
Loading history...
62
63
        $this->assertTrue($run->isUpdateOnProcessOutput());
64
        $this->assertSame($run, $run->setUpdateOnProcessOutput(false));
65
        $this->assertFalse($run->isUpdateOnProcessOutput());
66
    }
67
68
    public function testProcessRunning()
69
    {
70
        $process = Mockery::mock(Process::class);
71
        $process->shouldReceive('stop');
72
73
        $run = new Run($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\Run::__construct(). ( Ignorable by Annotation )

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

73
        $run = new Run(/** @scrutinizer ignore-type */ $process);
Loading history...
74
75
        $process->shouldReceive('isRunning')
76
                ->andReturn(false, true);
77
        $process->shouldReceive('start');
78
79
        $run->start();
80
81
        $process->shouldReceive('isStarted')
82
                ->andReturn(true);
83
84
        $this->assertTrue($run->isRunning());
85
        $this->assertTrue($run->hasStarted());
86
        $this->assertFalse($run->isSuccessful());
87
    }
88
89
    public function testRun()
90
    {
91
        $process = Mockery::mock(Process::class);
92
        $process->shouldReceive('stop');
93
94
        $run = new Run($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\Run::__construct(). ( Ignorable by Annotation )

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

94
        $run = new Run(/** @scrutinizer ignore-type */ $process);
Loading history...
95
96
        $process->shouldReceive('isRunning')
97
                ->andReturn(false, true, false);
98
99
        $process->shouldReceive('start');
100
        $run->start();
101
102
        $process->shouldReceive('isStarted')
103
                ->andReturn(true);
104
        $process->shouldReceive('isSuccessful')
105
                ->andReturn(true);
106
107
        $this->assertTrue($run->poll());
108
        $this->assertFalse($run->poll());
109
        $this->assertTrue($run->isSuccessful());
110
        $this->assertTrue($run->hasStarted());
111
    }
112
113
    public function testOnSuccess()
114
    {
115
        $process = Mockery::mock(Process::class);
116
        $process->shouldReceive('stop');
117
118
        $hit = false;
119
120
        $run = new Run(
121
            $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\Run::__construct(). ( Ignorable by Annotation )

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

121
            /** @scrutinizer ignore-type */ $process,
Loading history...
122
            function ($proc) use ($process, &$hit) {
123
                $this->assertSame($proc, $process);
124
                $hit = true;
125
            }
126
        );
127
128
        $process->shouldReceive('start')->once();
129
        $process->shouldReceive('isStarted')->andReturn(true);
130
        $process->shouldReceive('isRunning')->andReturn(false);
131
        $process->shouldReceive('isSuccessful')->once()->andReturn(true);
132
133
        $run->start();
134
        $this->assertFalse($run->poll());
135
    }
136
137
    public function testOnFailure()
138
    {
139
        $process = Mockery::mock(Process::class);
140
        $process->shouldReceive('stop');
141
142
        $hit = false;
143
144
        $run = new Run(
145
            $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\Run::__construct(). ( Ignorable by Annotation )

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

145
            /** @scrutinizer ignore-type */ $process,
Loading history...
146
            null,
147
            function ($proc) use ($process, &$hit) {
148
                $this->assertSame($proc, $process);
149
                $hit = true;
150
            }
151
        );
152
153
        $process->shouldReceive('start')->once();
154
        $process->shouldReceive('isStarted')->andReturn(true);
155
        $process->shouldReceive('isRunning')->andReturn(false);
156
        $process->shouldReceive('isSuccessful')->once()->andReturn(false);
157
158
        $run->start();
159
        $this->assertFalse($run->poll());
160
    }
161
162
    public function testOnProgress()
163
    {
164
        $process = Mockery::mock(Process::class);
165
        $process->shouldReceive('stop');
166
167
        $hit = false;
168
169
        $run = new Run(
170
            $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\Run::__construct(). ( Ignorable by Annotation )

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

170
            /** @scrutinizer ignore-type */ $process,
Loading history...
171
            null,
172
            null,
173
            function ($proc) use ($process, &$hit) {
174
                $this->assertSame($proc, $process);
175
                $hit = true;
176
            }
177
        );
178
179
        $process->shouldReceive('start')->once();
180
        $process->shouldReceive('isStarted')->andReturn(true);
181
        $process->shouldReceive('isRunning')->andReturn(false, true, false);
182
        $process->shouldReceive('isSuccessful')->once()->andReturn(true);
183
184
        $run->start();
185
        $this->assertTrue($run->poll());
186
        $this->assertFalse($run->poll());
187
    }
188
189
    public function testStartingAfterStartedWillDoNothing()
190
    {
191
        $process = Mockery::mock(Process::class);
192
        $process->shouldReceive('stop');
193
194
        $run = new Run($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\Run::__construct(). ( Ignorable by Annotation )

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

194
        $run = new Run(/** @scrutinizer ignore-type */ $process);
Loading history...
195
196
        $process->shouldReceive('isRunning')
197
                ->andReturn(true);
198
199
        $this->assertSame($run, $run->start());
200
    }
201
202
    public function testEventsProvideDurationAndLastMessage()
203
    {
204
        $process = Mockery::mock(Process::class);
205
        $process->shouldReceive('stop');
206
207
        $process->shouldReceive('start')
208
                ->with(
209
                    Mockery::on(
210
                        function (callable $fn) {
211
                            $this->assertNotNull($fn);
212
                            $fn(Process::OUT, 'some text');
213
                            return true;
214
                        }
215
                    )
216
                )
217
                ->once();
218
219
        $run = new Run(
220
            $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\Run::__construct(). ( Ignorable by Annotation )

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

220
            /** @scrutinizer ignore-type */ $process,
Loading history...
221
            function ($proc, $dur, $last, $lastType) use ($process) {
222
                $this->assertSame($process, $proc);
223
                $this->assertInternalType('float', $dur);
224
                $this->assertEquals('some text', $last);
225
                $this->assertEquals(Process::OUT, $lastType);
226
            }
227
        );
228
229
        $process->shouldReceive('isStarted')->andReturn(true);
230
        $process->shouldReceive('isRunning')->andReturn(false);
231
        $process->shouldReceive('isSuccessful')->once()->andReturn(true);
232
233
        $run->start();
234
        $this->assertFalse($run->poll());
235
    }
236
237
    public function testLastMessageHavingMultipleLinesReturnsOnePerLine()
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, "line 1\n\nline 2");
248
                            return true;
249
                        }
250
                    )
251
                )
252
                ->once();
253
254
        $hits = 0;
255
        $run = new Run(
256
            $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\Run::__construct(). ( Ignorable by Annotation )

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

256
            /** @scrutinizer ignore-type */ $process,
Loading history...
257
            null,
258
            null,
259
            function ($proc, $dur, $last, $lastType) use ($process, &$hits) {
260
                $this->assertSame($process, $proc);
261
                $this->assertInternalType('float', $dur);
262
                $this->assertContains($last, ['line 1', 'line 2']);
263
                $this->assertEquals(Process::OUT, $lastType);
264
                $hits++;
265
            }
266
        );
267
268
        $process->shouldReceive('isStarted')->andReturn(true);
269
        $process->shouldReceive('isRunning')->andReturn(false);
270
        $process->shouldReceive('isSuccessful')->once()->andReturn(true);
271
272
        $run->start();
273
        $this->assertFalse($run->poll());
274
        $this->assertEquals(2, $hits);
275
    }
276
277
    public function testUpdateOnPollOffDoesNotUpdateOnPoll()
278
    {
279
        $process = Mockery::mock(Process::class);
280
        $process->shouldReceive('stop');
281
282
        $process->shouldReceive('start')->once();
283
284
        $run = new Run(
285
            $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\Run::__construct(). ( Ignorable by Annotation )

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

285
            /** @scrutinizer ignore-type */ $process,
Loading history...
286
            null,
287
            null,
288
            function () {
289
                $this->fail('onProgress should not be called');
290
            }
291
        );
292
        $run->setUpdateOnPoll(false);
293
294
        $process->shouldReceive('isStarted')->andReturn(true);
295
        $process->shouldReceive('isRunning')->andReturn(false, true, false);
296
        $process->shouldReceive('isSuccessful')->once()->andReturn(true);
297
298
        $run->start();
299
        $this->assertTrue($run->poll());
300
        $this->assertFalse($run->poll());
301
    }
302
303
    public function testUpdateOnOutputOffDoesNotCallUpdateOnOutput()
304
    {
305
        $process = Mockery::mock(Process::class);
306
        $process->shouldReceive('stop');
307
308
        $process->shouldReceive('start')
309
                ->with(
310
                    Mockery::on(
311
                        function (callable $fn) {
312
                            $this->assertNotNull($fn);
313
                            $fn(Process::STDOUT, 'some text');
314
                            return true;
315
                        }
316
                    )
317
                )
318
                ->once();
319
320
        $run = new Run(
321
            $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\Run::__construct(). ( Ignorable by Annotation )

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

321
            /** @scrutinizer ignore-type */ $process,
Loading history...
322
            null,
323
            null,
324
            function () {
325
                $this->fail('onProgress should not be called');
326
            }
327
        );
328
        $run->setUpdateOnProcessOutput(false);
329
330
        $process->shouldReceive('isStarted')->andReturn(true);
331
        $process->shouldReceive('isRunning')->andReturn(false);
332
        $process->shouldReceive('isSuccessful')->once()->andReturn(true);
333
334
        $run->start();
335
        $this->assertFalse($run->poll());
336
    }
337
}
338