Passed
Push — master ( 389830...ffe1a3 )
by Albin
46s
created

AbstractGeneratorTest::testSetOptions()   B

Complexity

Conditions 2
Paths 3

Size

Total Lines 39
Code Lines 25

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 0
loc 39
rs 8.8571
c 1
b 0
f 0
cc 2
eloc 25
nc 3
nop 0
1
<?php
2
3
namespace Knp\Snappy;
4
5
use Psr\Log\LoggerInterface;
6
7
class AbstractGeneratorTest extends \PHPUnit_Framework_TestCase
8
{
9
    public function testAddOption()
10
    {
11
        $media = $this->getMockForAbstractClass('Knp\Snappy\AbstractGenerator', [], '', false);
12
13
        $this->assertEquals([], $media->getOptions());
14
15
        $r = new \ReflectionMethod($media, 'addOption');
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $r. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
16
        $r->setAccessible(true);
17
        $r->invokeArgs($media, ['foo', 'bar']);
18
19
        $this->assertEquals(['foo' => 'bar'], $media->getOptions(), '->addOption() adds an option');
20
21
        $r->invokeArgs($media, ['baz', 'bat']);
22
23
        $this->assertEquals(
24
            [
25
                'foo' => 'bar',
26
                'baz' => 'bat',
27
            ],
28
            $media->getOptions(),
29
            '->addOption() appends the option to the existing ones'
30
        );
31
32
        $message = '->addOption() raises an exception when the specified option already exists';
33
34
        try {
35
            $r->invokeArgs($media, ['baz', 'bat']);
36
            $this->fail($message);
37
        } catch (\InvalidArgumentException $e) {
38
            $this->anything($message);
0 ignored issues
show
Unused Code introduced by
The call to AbstractGeneratorTest::anything() has too many arguments starting with $message.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
39
        }
40
    }
41
42
    public function testAddOptions()
43
    {
44
        $media = $this->getMockForAbstractClass('Knp\Snappy\AbstractGenerator', [], '', false);
45
46
        $this->assertEquals([], $media->getOptions());
47
48
        $r = new \ReflectionMethod($media, 'addOptions');
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $r. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
49
        $r->setAccessible(true);
50
        $r->invokeArgs($media, [['foo' => 'bar', 'baz' => 'bat']]);
51
52
        $this->assertEquals(
53
            [
54
                'foo' => 'bar',
55
                'baz' => 'bat',
56
            ],
57
            $media->getOptions(),
58
            '->addOptions() adds all the given options'
59
        );
60
61
        $r->invokeArgs($media, [['ban' => 'bag', 'bal' => 'bac']]);
62
63
        $this->assertEquals(
64
            [
65
                'foo' => 'bar',
66
                'baz' => 'bat',
67
                'ban' => 'bag',
68
                'bal' => 'bac',
69
            ],
70
            $media->getOptions(),
71
            '->addOptions() adds the given options to the existing ones'
72
        );
73
74
        $message = '->addOptions() raises an exception when one of the given options already exists';
75
76
        try {
77
            $r->invokeArgs($media, [['bak' => 'bam', 'bah' => 'bap', 'baz' => 'bat']]);
78
            $this->fail($message);
79
        } catch (\InvalidArgumentException $e) {
80
            $this->anything($message);
0 ignored issues
show
Unused Code introduced by
The call to AbstractGeneratorTest::anything() has too many arguments starting with $message.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
81
        }
82
    }
83
84
    public function testSetOption()
85
    {
86
        $media = $this
87
            ->getMockBuilder(AbstractGenerator::class)
88
            ->setConstructorArgs(['/usr/local/bin/wkhtmltopdf'])
89
            ->getMockForAbstractClass()
90
        ;
91
92
        $logger = $this
93
            ->getMockBuilder(LoggerInterface::class)
94
            ->getMock()
95
        ;
96
        $media->setLogger($logger);
97
        $logger->expects($this->once())->method('debug');
98
99
        $r = new \ReflectionMethod($media, 'addOption');
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $r. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
100
        $r->setAccessible(true);
101
        $r->invokeArgs($media, ['foo', 'bar']);
102
103
        $media->setOption('foo', 'abc');
104
105
        $this->assertEquals(
106
            [
107
                'foo' => 'abc',
108
            ],
109
            $media->getOptions(),
110
            '->setOption() defines the value of an option'
111
        );
112
113
        $message = '->setOption() raises an exception when the specified option does not exist';
114
115
        try {
116
            $media->setOption('bad', 'def');
117
            $this->fail($message);
118
        } catch (\InvalidArgumentException $e) {
119
            $this->anything($message);
0 ignored issues
show
Unused Code introduced by
The call to AbstractGeneratorTest::anything() has too many arguments starting with $message.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
120
        }
121
    }
122
123
    public function testSetOptions()
124
    {
125
        $media = $this
126
            ->getMockBuilder(AbstractGenerator::class)
127
            ->setConstructorArgs(['/usr/local/bin/wkhtmltopdf'])
128
            ->getMockForAbstractClass()
129
        ;
130
131
        $logger = $this
132
            ->getMockBuilder(LoggerInterface::class)
133
            ->getMock()
134
        ;
135
        $media->setLogger($logger);
136
        $logger->expects($this->exactly(4))->method('debug');
137
138
        $r = new \ReflectionMethod($media, 'addOptions');
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $r. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
139
        $r->setAccessible(true);
140
        $r->invokeArgs($media, [['foo' => 'bar', 'baz' => 'bat']]);
141
142
        $media->setOptions(['foo' => 'abc', 'baz' => 'def']);
143
144
        $this->assertEquals(
145
            [
146
                'foo'   => 'abc',
147
                'baz'   => 'def',
148
            ],
149
            $media->getOptions(),
150
            '->setOptions() defines the values of all the specified options'
151
        );
152
153
        $message = '->setOptions() raises an exception when one of the specified options does not exist';
154
155
        try {
156
            $media->setOptions(['foo' => 'abc', 'baz' => 'def', 'bad' => 'ghi']);
157
            $this->fail($message);
158
        } catch (\InvalidArgumentException $e) {
159
            $this->anything($message);
0 ignored issues
show
Unused Code introduced by
The call to AbstractGeneratorTest::anything() has too many arguments starting with $message.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
160
        }
161
    }
162
163
    public function testGenerate()
164
    {
165
        $media = $this->getMock(
166
            'Knp\Snappy\AbstractGenerator',
167
            [
168
                'configure',
169
                'prepareOutput',
170
                'getCommand',
171
                'executeCommand',
172
                'checkOutput',
173
                'checkProcessStatus',
174
            ],
175
            [
176
                'the_binary',
177
                [],
178
            ]
179
        );
180
181
        $logger = $this
182
            ->getMockBuilder(LoggerInterface::class)
183
            ->getMock()
184
        ;
185
        $media->setLogger($logger);
186
        $logger
187
            ->expects($this->exactly(2))
188
            ->method('info')
189
            ->with(
190
                $this->logicalOr(
191
                    'Generate from file(s) "the_input_file" to file "the_output_file".',
192
                    'File "the_output_file" has been successfully generated.'
193
                ),
194
                $this->logicalOr(
195
                    ['command' => 'the command', 'env' => null, 'timeout' => false],
196
                    ['command' => 'the command', 'stdout'  => 'stdout', 'stderr'  => 'stderr']
197
                )
198
            )
199
        ;
200
201
        $media
202
            ->expects($this->once())
203
            ->method('prepareOutput')
204
            ->with($this->equalTo('the_output_file'))
205
        ;
206
        $media
207
            ->expects($this->any())
208
            ->method('getCommand')
209
            ->with(
210
                $this->equalTo('the_input_file'),
211
                $this->equalTo('the_output_file'),
212
                $this->equalTo(['foo' => 'bar'])
213
            )
214
            ->will($this->returnValue('the command'))
215
        ;
216
        $media
217
            ->expects($this->once())
218
            ->method('executeCommand')
219
            ->with($this->equalTo('the command'))
220
            ->willReturn([0, 'stdout', 'stderr'])
221
        ;
222
        $media
223
            ->expects($this->once())
224
            ->method('checkProcessStatus')
225
            ->with(0, 'stdout', 'stderr', 'the command')
226
        ;
227
        $media
228
            ->expects($this->once())
229
            ->method('checkOutput')
230
            ->with(
231
                $this->equalTo('the_output_file'),
232
                $this->equalTo('the command')
233
            )
234
        ;
235
236
        $media->generate('the_input_file', 'the_output_file', ['foo' => 'bar']);
237
    }
238
239
    public function testFailingGenerate()
240
    {
241
        $media = $this->getMock(
242
            'Knp\Snappy\AbstractGenerator',
243
            [
244
                'configure',
245
                'prepareOutput',
246
                'getCommand',
247
                'executeCommand',
248
                'checkOutput',
249
                'checkProcessStatus',
250
            ],
251
            [
252
                'the_binary',
253
                [],
254
                ['PATH' => '/usr/bin'],
255
            ]
256
        );
257
258
        $logger = $this->getMockBuilder(LoggerInterface::class)->getMock();
259
        $media->setLogger($logger);
260
        $media->setTimeout(2000);
261
262
        $logger
263
            ->expects($this->once())
264
            ->method('info')
265
            ->with(
266
                $this->equalTo('Generate from file(s) "the_input_file" to file "the_output_file".'),
267
                $this->equalTo(['command' => 'the command', 'env' => ['PATH' => '/usr/bin'], 'timeout' => 2000])
268
            )
269
        ;
270
271
        $logger
272
            ->expects($this->once())
273
            ->method('error')
274
            ->with(
275
                $this->equalTo('An error happened while generating "the_output_file".'),
276
                $this->equalTo(['command' => 'the command', 'status' => 1, 'stdout'  => 'stdout', 'stderr'  => 'stderr'])
277
            )
278
        ;
279
280
        $media
281
            ->expects($this->once())
282
            ->method('prepareOutput')
283
            ->with($this->equalTo('the_output_file'))
284
        ;
285
        $media
286
            ->expects($this->any())
287
            ->method('getCommand')
288
            ->with(
289
                $this->equalTo('the_input_file'),
290
                $this->equalTo('the_output_file')
291
            )
292
            ->will($this->returnValue('the command'))
293
        ;
294
        $media
295
            ->expects($this->once())
296
            ->method('executeCommand')
297
            ->with($this->equalTo('the command'))
298
            ->willReturn([1, 'stdout', 'stderr'])
299
        ;
300
        $media
301
            ->expects($this->once())
302
            ->method('checkProcessStatus')
303
            ->with(1, 'stdout', 'stderr', 'the command')
304
            ->willThrowException(new \RuntimeException())
305
        ;
306
307
        $this->setExpectedException(\RuntimeException::class);
308
309
        $media->generate('the_input_file', 'the_output_file', ['foo' => 'bar']);
310
    }
311
312
    public function testGenerateFromHtml()
313
    {
314
        $media = $this->getMock(
315
            'Knp\Snappy\AbstractGenerator',
316
            [
317
                'configure',
318
                'generate',
319
                'createTemporaryFile',
320
            ],
321
            [
322
                'the_binary',
323
            ],
324
            '',
325
            false
326
        );
327
        $media
328
            ->expects($this->once())
329
            ->method('createTemporaryFile')
330
            ->with(
331
                $this->equalTo('<html>foo</html>'),
332
                $this->equalTo('html')
333
            )
334
            ->will($this->returnValue('the_temporary_file'))
335
        ;
336
        $media
337
            ->expects($this->once())
338
            ->method('generate')
339
            ->with(
340
                $this->equalTo(['the_temporary_file']),
341
                $this->equalTo('the_output_file'),
342
                $this->equalTo(['foo' => 'bar'])
343
            )
344
        ;
345
346
        $media->generateFromHtml('<html>foo</html>', 'the_output_file', ['foo' => 'bar']);
347
    }
348
349
    public function testGenerateFromHtmlWithHtmlArray()
350
    {
351
        $media = $this->getMock(
352
            'Knp\Snappy\AbstractGenerator',
353
            [
354
                'configure',
355
                'generate',
356
                'createTemporaryFile',
357
            ],
358
            [
359
                'the_binary',
360
            ],
361
            '',
362
            false
363
        );
364
        $media
365
            ->expects($this->once())
366
            ->method('createTemporaryFile')
367
            ->with(
368
                $this->equalTo('<html>foo</html>'),
369
                $this->equalTo('html')
370
            )
371
            ->will($this->returnValue('the_temporary_file'))
372
        ;
373
        $media
374
            ->expects($this->once())
375
            ->method('generate')
376
            ->with(
377
                $this->equalTo(['the_temporary_file']),
378
                $this->equalTo('the_output_file'),
379
                $this->equalTo(['foo' => 'bar'])
380
            )
381
        ;
382
383
        $media->generateFromHtml(['<html>foo</html>'], 'the_output_file', ['foo' => 'bar']);
384
    }
385
386
    public function testGetOutput()
387
    {
388
        $media = $this->getMock(
389
            'Knp\Snappy\AbstractGenerator',
390
            [
391
                'configure',
392
                'getDefaultExtension',
393
                'createTemporaryFile',
394
                'generate',
395
                'getFileContents',
396
                'unlink',
397
            ],
398
            [],
399
            '',
400
            false
401
        );
402
        $media
403
            ->expects($this->any())
404
            ->method('getDefaultExtension')
405
            ->will($this->returnValue('ext'))
406
        ;
407
        $media
408
            ->expects($this->any())
409
            ->method('createTemporaryFile')
410
            ->with(
411
                $this->equalTo(null),
412
                $this->equalTo('ext')
413
            )
414
            ->will($this->returnValue('the_temporary_file'))
415
        ;
416
        $media
417
            ->expects($this->once())
418
            ->method('generate')
419
            ->with(
420
                $this->equalTo('the_input_file'),
421
                $this->equalTo('the_temporary_file'),
422
                $this->equalTo(['foo' => 'bar'])
423
            )
424
        ;
425
        $media
426
            ->expects($this->once())
427
            ->method('getFileContents')
428
            ->will($this->returnValue('the file contents'))
429
        ;
430
431
        $media
432
            ->expects($this->any())
433
            ->method('unlink')
434
            ->with($this->equalTo('the_temporary_file'))
435
            ->will($this->returnValue(true))
436
        ;
437
438
        $this->assertEquals('the file contents', $media->getOutput('the_input_file', ['foo' => 'bar']));
439
    }
440
441
    public function testGetOutputFromHtml()
442
    {
443
        $media = $this->getMock(
444
            'Knp\Snappy\AbstractGenerator',
445
            [
446
                'configure',
447
                'getOutput',
448
                'createTemporaryFile',
449
            ],
450
            [],
451
            '',
452
            false
453
        );
454
        $media
455
            ->expects($this->once())
456
            ->method('createTemporaryFile')
457
            ->with(
458
                $this->equalTo('<html>foo</html>'),
459
                $this->equalTo('html')
460
            )
461
            ->will($this->returnValue('the_temporary_file'))
462
        ;
463
        $media
464
            ->expects($this->once())
465
            ->method('getOutput')
466
            ->with(
467
                $this->equalTo(['the_temporary_file']),
468
                $this->equalTo(['foo' => 'bar'])
469
            )
470
            ->will($this->returnValue('the output'))
471
        ;
472
473
        $this->assertEquals('the output', $media->getOutputFromHtml('<html>foo</html>', ['foo' => 'bar']));
474
    }
475
476
    public function testGetOutputFromHtmlWithHtmlArray()
477
    {
478
        $media = $this->getMock(
479
            'Knp\Snappy\AbstractGenerator',
480
            [
481
                'configure',
482
                'getOutput',
483
                'createTemporaryFile',
484
            ],
485
            [],
486
            '',
487
            false
488
        );
489
        $media
490
            ->expects($this->once())
491
            ->method('createTemporaryFile')
492
            ->with(
493
                $this->equalTo('<html>foo</html>'),
494
                $this->equalTo('html')
495
            )
496
            ->will($this->returnValue('the_temporary_file'))
497
        ;
498
        $media
499
            ->expects($this->once())
500
            ->method('getOutput')
501
            ->with(
502
                $this->equalTo(['the_temporary_file']),
503
                $this->equalTo(['foo' => 'bar'])
504
            )
505
            ->will($this->returnValue('the output'))
506
        ;
507
508
        $this->assertEquals('the output', $media->getOutputFromHtml(['<html>foo</html>'], ['foo' => 'bar']));
509
    }
510
511
    public function testMergeOptions()
512
    {
513
        $media = $this->getMockForAbstractClass('Knp\Snappy\AbstractGenerator', [], '', false);
514
515
        $originalOptions = ['foo' => 'bar', 'baz' => 'bat'];
516
517
        $addOptions = new \ReflectionMethod($media, 'addOptions');
518
        $addOptions->setAccessible(true);
519
        $addOptions->invokeArgs($media, [$originalOptions]);
520
521
        $r = new \ReflectionMethod($media, 'mergeOptions');
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $r. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
522
        $r->setAccessible(true);
523
524
        $mergedOptions = $r->invokeArgs($media, [['foo' => 'ban']]);
525
526
        $this->assertEquals(
527
            [
528
                'foo' => 'ban',
529
                'baz' => 'bat',
530
            ],
531
            $mergedOptions,
532
            '->mergeOptions() merges an option to the instance ones and returns the result options array'
533
        );
534
535
        $this->assertEquals(
536
            $originalOptions,
537
            $media->getOptions(),
538
            '->mergeOptions() does NOT change the instance options'
539
        );
540
541
        $mergedOptions = $r->invokeArgs($media, [['foo' => 'ban', 'baz' => 'bag']]);
542
543
        $this->assertEquals(
544
            [
545
                'foo' => 'ban',
546
                'baz' => 'bag',
547
            ],
548
            $mergedOptions,
549
            '->mergeOptions() merges many options to the instance ones and returns the result options array'
550
        );
551
552
        $message = '->mergeOptions() throws an InvalidArgumentException once there is an undefined option in the given array';
553
554
        try {
555
            $r->invokeArgs($media, [['foo' => 'ban', 'bad' => 'bah']]);
556
            $this->fail($message);
557
        } catch (\InvalidArgumentException $e) {
558
            $this->anything($message);
0 ignored issues
show
Unused Code introduced by
The call to AbstractGeneratorTest::anything() has too many arguments starting with $message.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
559
        }
560
    }
561
562
    /**
563
     * @dataProvider dataForBuildCommand
564
     */
565
    public function testBuildCommand($binary, $url, $path, $options, $expected)
566
    {
567
        $media = $this->getMockForAbstractClass('Knp\Snappy\AbstractGenerator', [], '', false);
568
569
        $r = new \ReflectionMethod($media, 'buildCommand');
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $r. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
570
        $r->setAccessible(true);
571
572
        $this->assertEquals($expected, $r->invokeArgs($media, [$binary, $url, $path, $options]));
573
    }
574
575
    private function getPHPExecutableFromPath()
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
Coding Style introduced by
getPHPExecutableFromPath uses the super-global variable $_SERVER which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
576
    {
577
        if (isset($_SERVER['_'])) {
578
            return $_SERVER['_'];
579
        }
580
581
        if (@defined(PHP_BINARY)) {
582
            return PHP_BINARY;
583
        }
584
585
        $paths = explode(PATH_SEPARATOR, getenv('PATH'));
586
        foreach ($paths as $path) {
587
            // we need this for XAMPP (Windows)
588
            if (strstr($path, 'php.exe') && isset($_SERVER['WINDIR']) && file_exists($path) && is_file($path)) {
589
                return $path;
590
            } else {
591
                $php_executable = $path . DIRECTORY_SEPARATOR . 'php' . (isset($_SERVER['WINDIR']) ? '.exe' : '');
592
                if (file_exists($php_executable) && is_file($php_executable)) {
593
                    return $php_executable;
594
                }
595
            }
596
        }
597
598
        return false; // not found
599
    }
600
601
    public function dataForBuildCommand()
602
    {
603
        $theBinary = $this->getPHPExecutableFromPath() . ' -v'; // i.e.: '/usr/bin/php -v'
604
605
        return [
606
            [
607
                $theBinary,
608
                'http://the.url/',
609
                '/the/path',
610
                [],
611
                $theBinary . ' ' . escapeshellarg('http://the.url/') . ' ' . escapeshellarg('/the/path'),
612
            ],
613
            [
614
                $theBinary,
615
                'http://the.url/',
616
                '/the/path',
617
                [
618
                    'foo'   => null,
619
                    'bar'   => false,
620
                    'baz'   => [],
621
                ],
622
                $theBinary . ' ' . escapeshellarg('http://the.url/') . ' ' . escapeshellarg('/the/path'),
623
            ],
624
            [
625
                $theBinary,
626
                'http://the.url/',
627
                '/the/path',
628
                [
629
                    'foo'   => 'foovalue',
630
                    'bar'   => ['barvalue1', 'barvalue2'],
631
                    'baz'   => true,
632
                ],
633
                $theBinary . ' --foo ' . escapeshellarg('foovalue') . ' --bar ' . escapeshellarg('barvalue1') . ' --bar ' . escapeshellarg('barvalue2') . ' --baz ' . escapeshellarg('http://the.url/') . ' ' . escapeshellarg('/the/path'),
634
            ],
635
            [
636
                $theBinary,
637
                'http://the.url/',
638
                '/the/path',
639
                [
640
                    'cookie'          => ['session' => 'bla', 'phpsess' => 12],
641
                    'no-background'   => '1',
642
                ],
643
                $theBinary . ' --cookie ' . escapeshellarg('session') . ' ' . escapeshellarg('bla') . ' --cookie ' . escapeshellarg('phpsess') . ' ' . escapeshellarg('12') . ' --no-background ' . escapeshellarg('1') . ' ' . escapeshellarg('http://the.url/') . ' ' . escapeshellarg('/the/path'),
644
            ],
645
            [
646
                $theBinary,
647
                'http://the.url/',
648
                '/the/path',
649
                [
650
                    'allow'           => ['/path1', '/path2'],
651
                    'no-background'   => '1',
652
                ],
653
                $theBinary . ' --allow ' . escapeshellarg('/path1') . ' --allow ' . escapeshellarg('/path2') . ' --no-background ' . escapeshellarg('1') . ' ' . escapeshellarg('http://the.url/') . ' ' . escapeshellarg('/the/path'),
654
            ],
655
            [
656
                $theBinary,
657
                'http://the.url/',
658
                '/the/path',
659
                [
660
                    'image-dpi'     => 100,
661
                    'image-quality' => 50,
662
                ],
663
                $theBinary . ' ' . '--image-dpi 100 --image-quality 50 ' . escapeshellarg('http://the.url/') . ' ' . escapeshellarg('/the/path'),
664
            ],
665
        ];
666
    }
667
668
    public function testCheckOutput()
669
    {
670
        $media = $this->getMock(
671
            'Knp\Snappy\AbstractGenerator',
672
            [
673
                'configure',
674
                'fileExists',
675
                'filesize',
676
            ],
677
            [],
678
            '',
679
            false
680
        );
681
        $media
682
            ->expects($this->once())
683
            ->method('fileExists')
684
            ->with($this->equalTo('the_output_file'))
685
            ->will($this->returnValue(true))
686
        ;
687
        $media
688
            ->expects($this->once())
689
            ->method('filesize')
690
            ->with($this->equalTo('the_output_file'))
691
            ->will($this->returnValue(123))
692
        ;
693
694
        $r = new \ReflectionMethod($media, 'checkOutput');
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $r. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
695
        $r->setAccessible(true);
696
697
        $message = '->checkOutput() checks both file existence and size';
698
699
        try {
700
            $r->invokeArgs($media, ['the_output_file', 'the command']);
701
            $this->anything($message);
0 ignored issues
show
Unused Code introduced by
The call to AbstractGeneratorTest::anything() has too many arguments starting with $message.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
702
        } catch (\RuntimeException $e) {
703
            $this->fail($message);
704
        }
705
    }
706
707
    public function testCheckOutputWhenTheFileDoesNotExist()
708
    {
709
        $media = $this->getMock(
710
            'Knp\Snappy\AbstractGenerator',
711
            [
712
                'configure',
713
                'fileExists',
714
                'filesize',
715
            ],
716
            [],
717
            '',
718
            false
719
        );
720
        $media
721
            ->expects($this->once())
722
            ->method('fileExists')
723
            ->with($this->equalTo('the_output_file'))
724
            ->will($this->returnValue(false))
725
        ;
726
727
        $r = new \ReflectionMethod($media, 'checkOutput');
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $r. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
728
        $r->setAccessible(true);
729
730
        $message = '->checkOutput() throws an InvalidArgumentException when the file does not exist';
731
732
        try {
733
            $r->invokeArgs($media, ['the_output_file', 'the command']);
734
            $this->fail($message);
735
        } catch (\RuntimeException $e) {
736
            $this->anything($message);
0 ignored issues
show
Unused Code introduced by
The call to AbstractGeneratorTest::anything() has too many arguments starting with $message.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
737
        }
738
    }
739
740
    public function testCheckOutputWhenTheFileIsEmpty()
741
    {
742
        $media = $this->getMock(
743
            'Knp\Snappy\AbstractGenerator',
744
            [
745
                'configure',
746
                'fileExists',
747
                'filesize',
748
            ],
749
            [],
750
            '',
751
            false
752
        );
753
        $media
754
            ->expects($this->once())
755
            ->method('fileExists')
756
            ->with($this->equalTo('the_output_file'))
757
            ->will($this->returnValue(true))
758
        ;
759
        $media
760
            ->expects($this->once())
761
            ->method('filesize')
762
            ->with($this->equalTo('the_output_file'))
763
            ->will($this->returnValue(0))
764
        ;
765
766
        $r = new \ReflectionMethod($media, 'checkOutput');
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $r. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
767
        $r->setAccessible(true);
768
769
        $message = '->checkOutput() throws an InvalidArgumentException when the file is empty';
770
771
        try {
772
            $r->invokeArgs($media, ['the_output_file', 'the command']);
773
            $this->fail($message);
774
        } catch (\RuntimeException $e) {
775
            $this->anything($message);
0 ignored issues
show
Unused Code introduced by
The call to AbstractGeneratorTest::anything() has too many arguments starting with $message.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
776
        }
777
    }
778
779
    public function testCheckProcessStatus()
780
    {
781
        $media = $this->getMock(
782
            'Knp\Snappy\AbstractGenerator',
783
            [
784
                'configure',
785
            ],
786
            [],
787
            '',
788
            false
789
        );
790
791
        $r = new \ReflectionMethod($media, 'checkProcessStatus');
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $r. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
792
        $r->setAccessible(true);
793
794
        try {
795
            $r->invokeArgs($media, [0, '', '', 'the command']);
796
            $this->anything('0 status means success');
0 ignored issues
show
Unused Code introduced by
The call to AbstractGeneratorTest::anything() has too many arguments starting with '0 status means success'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
797
        } catch (\RuntimeException $e) {
798
            $this->fail('0 status means success');
799
        }
800
801
        try {
802
            $r->invokeArgs($media, [1, '', '', 'the command']);
803
            $this->anything('1 status means failure, but no stderr content');
0 ignored issues
show
Unused Code introduced by
The call to AbstractGeneratorTest::anything() has too many arguments starting with '1 status means failure, but no stderr content'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
804
        } catch (\RuntimeException $e) {
805
            $this->fail('1 status means failure, but no stderr content');
806
        }
807
808
        try {
809
            $r->invokeArgs($media, [1, '', 'Could not connect to X', 'the command']);
810
            $this->fail('1 status means failure');
811
        } catch (\RuntimeException $e) {
812
            $this->anything('1 status means failure');
0 ignored issues
show
Unused Code introduced by
The call to AbstractGeneratorTest::anything() has too many arguments starting with '1 status means failure'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
813
        }
814
    }
815
816
    /**
817
     * @dataProvider dataForIsAssociativeArray
818
     */
819
    public function testIsAssociativeArray($array, $isAssociativeArray)
820
    {
821
        $generator = $this->getMockForAbstractClass('Knp\Snappy\AbstractGenerator', [], '', false);
822
823
        $r = new \ReflectionMethod($generator, 'isAssociativeArray');
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $r. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
824
        $r->setAccessible(true);
825
        $this->assertEquals($isAssociativeArray, $r->invokeArgs($generator, [$array]));
826
    }
827
828
    /**
829
     * @expectedException Knp\Snappy\Exception\FileAlreadyExistsException
830
     */
831
    public function testItThrowsTheProperExceptionWhenFileExistsAndNotOverwritting()
832
    {
833
        $media = $this->getMock(
834
            'Knp\Snappy\AbstractGenerator',
835
            [
836
                'configure',
837
                'fileExists',
838
                'isFile',
839
            ],
840
            [],
841
            '',
842
            false
843
        );
844
        $media
845
            ->expects($this->any())
846
            ->method('fileExists')
847
            ->will($this->returnValue(true))
848
        ;
849
        $media
850
            ->expects($this->any())
851
            ->method('isFile')
852
            ->will($this->returnValue(true))
853
        ;
854
        $r = new \ReflectionMethod($media, 'prepareOutput');
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $r. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
855
        $r->setAccessible(true);
856
857
        $r->invokeArgs($media, ['', false]);
858
    }
859
860
    public function dataForIsAssociativeArray()
861
    {
862
        return [
863
            [
864
                ['key' => 'value'],
865
                true,
866
            ],
867
            [
868
                ['key' => 2],
869
                true,
870
            ],
871
            [
872
                ['key' => 'value', 'key2' => 'value2'],
873
                true,
874
            ],
875
            [
876
                [0 => 'value', 1 => 'value2', 'deux' => 'value3'],
877
                true,
878
            ],
879
            [
880
                [0 => 'value'],
881
                false,
882
            ],
883
            [
884
                [0 => 'value', 1 => 'value2', 3 => 'value3'],
885
                false,
886
            ],
887
            [
888
                ['0' => 'value', '1' => 'value2', '3' => 'value3'],
889
                false,
890
            ],
891
            [
892
                [],
893
                false,
894
            ],
895
        ];
896
    }
897
898
    public function testCleanupEmptyTemporaryFiles()
899
    {
900
        $generator = $this->getMock(
901
            'Knp\Snappy\AbstractGenerator',
902
            [
903
                'configure',
904
                'unlink',
905
            ],
906
            [
907
                'the_binary',
908
            ]
909
        );
910
        $generator
911
            ->expects($this->once())
912
            ->method('unlink');
913
914
        $create = new \ReflectionMethod($generator, 'createTemporaryFile');
915
        $create->setAccessible(true);
916
        $create->invoke($generator, null, null);
917
918
        $files = new \ReflectionProperty($generator, 'temporaryFiles');
919
        $files->setAccessible(true);
920
        $this->assertCount(1, $files->getValue($generator));
921
922
        $remove = new \ReflectionMethod($generator, 'removeTemporaryFiles');
923
        $remove->setAccessible(true);
924
        $remove->invoke($generator);
925
    }
926
927
    public function testleanupTemporaryFiles()
928
    {
929
        $generator = $this->getMock(
930
            'Knp\Snappy\AbstractGenerator',
931
            [
932
                'configure',
933
                'unlink',
934
            ],
935
            [
936
                'the_binary',
937
            ]
938
        );
939
        $generator
940
            ->expects($this->once())
941
            ->method('unlink');
942
943
        $create = new \ReflectionMethod($generator, 'createTemporaryFile');
944
        $create->setAccessible(true);
945
        $create->invoke($generator, '<html/>', 'html');
946
947
        $files = new \ReflectionProperty($generator, 'temporaryFiles');
948
        $files->setAccessible(true);
949
        $this->assertCount(1, $files->getValue($generator));
950
951
        $remove = new \ReflectionMethod($generator, 'removeTemporaryFiles');
952
        $remove->setAccessible(true);
953
        $remove->invoke($generator);
954
    }
955
}
956