Test Failed
Push — master ( 440ce5...0cdbc1 )
by Siad
07:01
created

BuildFileTest::configureProject()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 9
nc 1
nop 1
dl 0
loc 11
rs 9.9666
c 0
b 0
f 0
1
<?php
2
/*
3
 *
4
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
5
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
6
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
7
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
8
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
9
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
10
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
11
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
12
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
13
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
14
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
15
 *
16
 * This software consists of voluntary contributions made by many individuals
17
 * and is licensed under the LGPL. For more information please see
18
 * <http://phing.info>.
19
 */
20
21
use PHPUnit\Framework\TestCase;
22
23
/**
24
 * A BuildFileTest is a TestCase which executes targets from a Phing buildfile
25
 * for testing.
26
 *
27
 * This class provides a number of utility methods for particular build file
28
 * tests which extend this class.
29
 *
30
 * @author Nico Seessle <[email protected]>
31
 * @author Conor MacNeill
32
 * @author Victor Farazdagi <[email protected]>
33
 */
34
abstract class BuildFileTest extends TestCase
35
{
36
37
    /** @var Project */
38
    protected $project;
39
40
    /**
41
     * @var array Array of log BuildEvent objects.
42
     */
43
    public $logBuffer = [];
44
45
    private $outBuffer;
46
    private $errBuffer;
47
    private $buildException;
48
49
    /**
50
     * Asserts that the log buffer contains specified message at specified priority.
51
     * @param string $expected Message subsctring
52
     * @param int $priority Message priority (default: any)
53
     * @param string $errmsg The error message to display.
54
     */
55
    protected function assertInLogs($expected, $priority = null, $errormsg = "Expected to find '%s' in logs: %s")
56
    {
57
        $found = false;
58
        foreach ($this->logBuffer as $log) {
59
            if (false !== stripos($log['message'], $expected)) {
60
                $this->assertEquals(1, 1); // increase number of positive assertions
61
                if ($priority === null) {
62
                    return;
63
                } elseif ($priority !== null) {
64
                    if ($priority >= $log['priority']) {
65
                        $found = true;
66
                    }
67
                }
68
69
            }
70
            if ($found) {
71
                return;
72
            }
73
        }
74
        $representation = [];
75
        foreach ($this->logBuffer as $log) {
76
            $representation[] = "[msg=\"{$log['message']}\",priority={$log['priority']}]";
77
        }
78
        $this->fail(sprintf($errormsg, $expected, var_export($representation, true)));
79
    }
80
81
    /**
82
     * Asserts that the log buffer contains specified message at specified priority.
83
     * @param string $expected Message subsctring
84
     * @param int $priority Message priority (default: any)
85
     * @param string $errmsg The error message to display.
86
     */
87
    protected function assertLogLineContaining(
88
        $expected,
89
        $priority = null,
90
        $errormsg = "Expected to find a log line that starts with '%s': %s"
91
    ) {
92
        $found = false;
93
        foreach ($this->logBuffer as $log) {
94
            if (false !== strpos($log['message'], $expected)) {
95
                $this->assertEquals(1, 1); // increase number of positive assertions
96
                if ($priority === null) {
97
                    return;
98
                } elseif ($priority !== null) {
99
                    if ($priority >= $log['priority']) {
100
                        $found = true;
101
                    }
102
                }
103
104
            }
105
            if ($found) {
106
                return;
107
            }
108
        }
109
        $representation = [];
110
        foreach ($this->logBuffer as $log) {
111
            $representation[] = "[msg=\"{$log['message']}\",priority={$log['priority']}]";
112
        }
113
        $this->fail(sprintf($errormsg, $expected, var_export($representation, true)));
114
    }
115
116
    /**
117
     * Asserts that the log buffer does NOT contain specified message at specified priority.
118
     * @param string $expected Message subsctring
119
     * @param int $priority Message priority (default: any)
120
     * @param string $errmsg The error message to display.
121
     */
122
    protected function assertNotInLogs(
123
        $message,
124
        $priority = null,
0 ignored issues
show
Unused Code introduced by
The parameter $priority is not used and could be removed. ( Ignorable by Annotation )

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

124
        /** @scrutinizer ignore-unused */ $priority = null,

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
125
        $errormsg = "Unexpected string '%s' found in logs: %s"
126
    ) {
127
        foreach ($this->logBuffer as $log) {
128
            if (false !== stripos($log['message'], $message)) {
129
                $representation = [];
130
                foreach ($this->logBuffer as $log) {
0 ignored issues
show
Comprehensibility Bug introduced by
$log is overwriting a variable from outer foreach loop.
Loading history...
131
                    $representation[] = "[msg=\"{$log['message']}\",priority={$log['priority']}]";
132
                }
133
                $this->fail(sprintf($errormsg, $message, var_export($representation, true)));
134
            }
135
        }
136
137
        $this->assertEquals(1, 1); // increase number of positive assertions
138
    }
139
140
    /**
141
     *  run a target, expect for any build exception
142
     *
143
     * @param string $target target to run
144
     * @param string $cause information string to reader of report
145
     */
146
    protected function expectBuildException($target, $cause)
147
    {
148
        $this->expectSpecificBuildException($target, $cause, null);
149
    }
150
151
    /**
152
     * Assert that only the given message has been logged with a
153
     * priority &gt;= INFO when running the given target.
154
     */
155
    protected function expectLog($target, $log)
156
    {
157
        $this->executeTarget($target);
158
        $this->assertInLogs($log);
159
    }
160
161
    /**
162
     * Assert that the given message has been logged with a priority
163
     * &gt;= INFO when running the given target.
164
     */
165
    protected function expectLogContaining($target, $log)
166
    {
167
        $this->executeTarget($target);
168
        $this->assertInLogs($log);
169
    }
170
171
    /**
172
     * Assert that the given message has been logged with a priority
173
     * &gt;= DEBUG when running the given target.
174
     */
175
    protected function expectDebuglog($target, $log)
176
    {
177
        $this->executeTarget($target);
178
        $this->assertInLogs($log, Project::MSG_DEBUG);
179
    }
180
181
    /**
182
     *  execute the target, verify output matches expectations
183
     *
184
     * @param string $target target to execute
185
     * @param string $output output to look for
186
     */
187
    protected function expectOutput($target, $output)
188
    {
189
        $this->executeTarget($target);
190
        $realOutput = $this->getOutput();
191
        $this->assertEquals($output, $realOutput);
192
    }
193
194
    /**
195
     *  execute the target, verify output matches expectations
196
     *  and that we got the named error at the end
197
     * @param string $target target to execute
198
     * @param string $output output to look for
199
     * @param string $error Description of Parameter
200
     */
201
202
    protected function expectOutputAndError($target, $output, $error)
203
    {
204
        $this->executeTarget($target);
205
        $realOutput = $this->getOutput();
206
        $this->assertEquals($output, $realOutput);
207
        $realError = $this->getError();
208
        $this->assertEquals($error, $realError);
209
    }
210
211
    protected function getOutput()
212
    {
213
        return $this->cleanBuffer($this->outBuffer);
214
    }
215
216
    protected function getError()
217
    {
218
        return $this->cleanBuffer($this->errBuffer);
219
    }
220
221
    protected function getBuildException()
222
    {
223
        return $this->buildException;
224
    }
225
226
    private function cleanBuffer($buffer)
227
    {
228
        $cleanedBuffer = "";
229
        $cr = false;
230
        for ($i = 0, $bufflen = strlen($buffer); $i < $bufflen; $i++) {
231
            $ch = $buffer{$i};
232
            if ($ch == "\r") {
233
                $cr = true;
234
                continue;
235
            }
236
237
            if (!$cr) {
238
                $cleanedBuffer .= $ch;
239
            } else {
240
                if ($ch == "\n") {
241
                    $cleanedBuffer .= $ch;
242
                } else {
243
                    $cleanedBuffer .= "\r" . $ch;
244
                }
245
            }
246
        }
247
248
        return $cleanedBuffer;
249
    }
250
251
    /**
252
     *  set up to run the named project
253
     *
254
     * @param string $filename name of project file to run
255
     * @throws BuildException
256
     */
257
    protected function configureProject($filename)
258
    {
259
        $this->logBuffer = [];
260
        $this->fullLogBuffer = "";
0 ignored issues
show
Bug Best Practice introduced by
The property fullLogBuffer does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
261
        $this->project = new Project();
262
        $this->project->init();
263
        $f = new PhingFile($filename);
264
        $this->project->setUserProperty("phing.file", $f->getAbsolutePath());
265
        $this->project->setUserProperty("phing.dir", dirname($f->getAbsolutePath()));
266
        $this->project->addBuildListener(new PhingTestListener($this));
267
        ProjectConfigurator::configureProject($this->project, new PhingFile($filename));
268
    }
269
270
    /**
271
     *  execute a target we have set up
272
     * @pre configureProject has been called
273
     * @param string $targetName target to run
274
     */
275
    protected function executeTarget($targetName)
276
    {
277
        if (empty($this->project)) {
278
            return;
279
        }
280
281
        $this->outBuffer = "";
282
        $this->errBuffer = "";
283
        $this->logBuffer = [];
284
        $this->fullLogBuffer = "";
0 ignored issues
show
Bug Best Practice introduced by
The property fullLogBuffer does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
285
        $this->buildException = null;
286
        $this->project->executeTarget($targetName);
287
    }
288
289
    /**
290
     * Get the project which has been configured for a test.
291
     *
292
     * @return Project the Project instance for this test.
293
     */
294
    protected function getProject()
295
    {
296
        return $this->project;
297
    }
298
299
    /**
300
     * get the directory of the project
301
     * @return PhingFile the base dir of the project
302
     */
303
    protected function getProjectDir()
304
    {
305
        return $this->project->getBasedir();
306
    }
307
308
    /**
309
     *  run a target, wait for a build exception
310
     *
311
     * @param string $target target to run
312
     * @param string $cause information string to reader of report
313
     * @param string $msg the message value of the build exception we are waiting for
314
     * set to null for any build exception to be valid
315
     */
316
    protected function expectSpecificBuildException($target, $cause, $msg)
317
    {
318
        try {
319
            $this->executeTarget($target);
320
        } catch (BuildException $ex) {
321
            $this->buildException = $ex;
322
            if (($msg !== null) && ($ex->getMessage() != $msg)) {
323
                $this->fail(
324
                    "Should throw BuildException because '" . $cause
325
                    . "' with message '" . $msg
326
                    . "' (actual message '" . $ex->getMessage() . "' instead)"
327
                );
328
            }
329
            $this->assertEquals(1, 1); // increase number of positive assertions
330
331
            return;
332
        }
333
        $this->fail("Should throw BuildException because: " . $cause);
334
    }
335
336
    /**
337
     *  run a target, expect an exception string
338
     *  containing the substring we look for (case sensitive match)
339
     *
340
     * @param string $target target to run
341
     * @param string $cause information string to reader of report
342
     * @param string $msg the message value of the build exception we are waiting for
343
     * @param string $contains substring of the build exception to look for
344
     */
345
    protected function expectBuildExceptionContaining($target, $cause, $contains)
346
    {
347
        try {
348
            $this->executeTarget($target);
349
        } catch (BuildException $ex) {
350
            $this->buildException = $ex;
351
            $found = false;
352
            while ($ex) {
353
                $msg = $ex->getMessage();
354
                if (false !== strpos($ex->getMessage(), $contains)) {
355
                    $found = true;
356
                }
357
                $ex = $ex->getPrevious();
358
            };
359
360
            if (!$found) {
361
                $this->fail(
362
                    "Should throw BuildException because '" . $cause . "' with message containing '" . $contains
363
                    . "' (actual message '" . $msg . "' instead)"
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $msg does not seem to be defined for all execution paths leading up to this point.
Loading history...
364
                );
365
            }
366
367
            $this->assertEquals(1, 1); // increase number of positive assertions
368
            return;
369
        }
370
        $this->fail("Should throw BuildException because: " . $cause);
371
    }
372
373
    /**
374
     * call a target, verify property is as expected
375
     *
376
     * @param string $target build file target
377
     * @param string $property property name
378
     * @param string $value expected value
379
     */
380
381
    protected function expectPropertySet($target, $property, $value = "true")
382
    {
383
        $this->executeTarget($target);
384
        $this->assertPropertyEquals($property, $value);
385
    }
386
387
    /**
388
     * assert that a property equals a value; comparison is case sensitive.
389
     * @param string $property property name
390
     * @param string $value expected value
391
     */
392
    protected function assertPropertyEquals($property, $value)
393
    {
394
        $result = $this->project->getProperty($property);
395
        $this->assertEquals($value, $result, "property " . $property);
396
    }
397
398
    /**
399
     * assert that a property equals &quot;true&quot;
400
     * @param string $property property name
401
     */
402
    protected function assertPropertySet($property)
403
    {
404
        $this->assertPropertyEquals($property, "true");
405
    }
406
407
    /**
408
     * assert that a property is null
409
     * @param string $property property name
410
     */
411
    protected function assertPropertyUnset($property)
412
    {
413
        $this->assertPropertyEquals($property, null);
414
    }
415
416
    /**
417
     * call a target, verify property is null
418
     * @param string $target build file target
419
     * @param string $property property name
420
     */
421
    protected function expectPropertyUnset($target, $property)
422
    {
423
        $this->expectPropertySet($target, $property, null);
424
    }
425
426
    /**
427
     * Retrieve a resource from the caller classloader to avoid
428
     * assuming a vm working directory. The resource path must be
429
     * relative to the package name or absolute from the root path.
430
     * @param resource $resource the resource to retrieve its url.
431
     * @throws BuildException if resource is not found.
432
     */
433
    protected function getResource($resource)
0 ignored issues
show
Unused Code introduced by
The parameter $resource is not used and could be removed. ( Ignorable by Annotation )

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

433
    protected function getResource(/** @scrutinizer ignore-unused */ $resource)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
434
    {
435
        throw new BuildException("getResource() not yet implemented");
436
        //$url = ggetClass().getResource(resource);
437
        //assertNotNull("Could not find resource :" + resource, url);
438
        //return url;
439
    }
440
441
    protected function rmdir($dir)
442
    {
443
        if (!file_exists($dir)) {
444
            return true;
445
        }
446
        if (!is_dir($dir)) {
447
            return unlink($dir);
448
        }
449
        foreach (scandir($dir) as $item) {
450
            if ($item === '.' || $item === '..') {
451
                continue;
452
            }
453
            if (!$this->rmdir($dir . DIRECTORY_SEPARATOR . $item)) {
454
                return false;
455
            }
456
        }
457
458
        return rmdir($dir);
459
    }
460
461
    /**
462
     * Get relative date
463
     *
464
     * @param int $timestamp Timestamp to us as pin-point
465
     * @param string $type Whether 'fulldate' or 'time'
466
     * @return string
467
     */
468
    protected function getRelativeDate($timestamp, $type = 'fulldate')
0 ignored issues
show
Unused Code introduced by
The parameter $type is not used and could be removed. ( Ignorable by Annotation )

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

468
    protected function getRelativeDate($timestamp, /** @scrutinizer ignore-unused */ $type = 'fulldate')

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
469
    {
470
        // calculate the diffrence
471
        $timediff = time() - $timestamp;
472
473
        if ($timediff < 3600) {
474
            if ($timediff < 120) {
475
                $returndate = "1 minute ago";
476
            } else {
477
                $returndate = ceil($timediff / 60) . " minutes ago";
478
            }
479
        } else {
480
            if ($timediff < 7200) {
481
                $returndate = "1 hour ago.";
482
            } else {
483
                if ($timediff < 86400) {
484
                    $returndate = ceil($timediff / 3600) . " hours ago";
485
                } else {
486
                    if ($timediff < 172800) {
487
                        $returndate = "1 day ago.";
488
                    } else {
489
                        if ($timediff < 604800) {
490
                            $returndate = ceil($timediff / 86400) . " days ago";
491
                        } else {
492
                            if ($timediff < 1209600) {
493
                                $returndate = ceil($timediff / 86400) . " days ago";
494
                            } else {
495
                                if ($timediff < 2629744) {
496
                                    $returndate = ceil($timediff / 86400) . " days ago";
497
                                } else {
498
                                    if ($timediff < 3024000) {
499
                                        $returndate = ceil($timediff / 604900) . " weeks ago";
500
                                    } else {
501
                                        if ($timediff > 5259486) {
502
                                            $returndate = ceil($timediff / 2629744) . " months ago";
503
                                        } else {
504
                                            $returndate = ceil($timediff / 604900) . " weeks ago";
505
                                        }
506
                                    }
507
                                }
508
                            }
509
                        }
510
                    }
511
                }
512
            }
513
        }
514
515
        return $returndate;
516
    }
517
518
519
520
    public function assertFileSizeAtLeast(string $filepath, int $bytes)
521
    {
522
        $actualSize = filesize($filepath);
523
524
        if (!is_int($actualSize)) {
0 ignored issues
show
introduced by
The condition is_int($actualSize) is always true.
Loading history...
525
            $this->fail("Error while reading file '$filepath'");
526
        }
527
528
        $this->assertGreaterThanOrEqual($bytes, $actualSize);
529
    }
530
}
531
532
/**
533
 * our own personal build listener
534
 */
535
class PhingTestListener implements BuildListener
536
{
537
    private $parent;
538
539
    public function __construct($parent)
540
    {
541
        $this->parent = $parent;
542
    }
543
544
    /**
545
     *  Fired before any targets are started.
546
     */
547
    public function buildStarted(BuildEvent $event)
548
    {
549
    }
550
551
    /**
552
     *  Fired after the last target has finished. This event
553
     *  will still be thrown if an error occurred during the build.
554
     *
555
     * @see BuildEvent#getException()
556
     */
557
    public function buildFinished(BuildEvent $event)
558
    {
559
    }
560
561
    /**
562
     *  Fired when a target is started.
563
     *
564
     * @see BuildEvent#getTarget()
565
     */
566
    public function targetStarted(BuildEvent $event)
567
    {
568
        //System.out.println("targetStarted " + event.getTarget().getName());
569
    }
570
571
    /**
572
     *  Fired when a target has finished. This event will
573
     *  still be thrown if an error occurred during the build.
574
     *
575
     * @see BuildEvent#getException()
576
     */
577
    public function targetFinished(BuildEvent $event)
578
    {
579
        //System.out.println("targetFinished " + event.getTarget().getName());
580
    }
581
582
    /**
583
     *  Fired when a task is started.
584
     *
585
     * @see BuildEvent#getTask()
586
     */
587
    public function taskStarted(BuildEvent $event)
588
    {
589
        //System.out.println("taskStarted " + event.getTask().getTaskName());
590
    }
591
592
    /**
593
     *  Fired when a task has finished. This event will still
594
     *  be throw if an error occurred during the build.
595
     *
596
     * @see BuildEvent#getException()
597
     */
598
    public function taskFinished(BuildEvent $event)
599
    {
600
        //System.out.println("taskFinished " + event.getTask().getTaskName());
601
    }
602
603
    /**
604
     *  Fired whenever a message is logged.
605
     *
606
     * @see BuildEvent#getMessage()
607
     * @see BuildEvent#getPriority()
608
     */
609
    public function messageLogged(BuildEvent $event)
610
    {
611
        $this->parent->logBuffer[] = [
612
            'message' => $event->getMessage(),
613
            'priority' => $event->getPriority()
614
        ];
615
    }
616
}
617