Failed Conditions
Pull Request — master (#1)
by Yo
04:28 queued 02:15
created

TestsStrategyListener   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 79
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 5

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 15
c 1
b 0
f 0
lcom 0
cbo 5
dl 0
loc 79
ccs 55
cts 55
cp 1
rs 10

2 Methods

Rating   Name   Duplication   Size   Complexity  
C addRiskyTest() 0 47 8
B removeCoverageFor() 0 20 7
1
<?php
2
namespace Yoanm\PhpUnitExtended\Listener;
3
4
/**
5
 * @see https://github.com/yoanm/Readme/blob/master/TESTS_STRATEGY.md#rules-strict-mode-fails-if-risky-tests
6
 * Will convert a risky test regarding following option to failure
7
 *  =>phpunit process will return a failed result at end
8
 *
9
 * List of managed options :
10
 * - beStrictAboutOutputDuringTests="true" / --report-useless-tests
11
 * - checkForUnintentionallyCoveredCode="true" / --strict-coverage
12
 *      => in case forceCoversAnnotation is used, and the test execute code that are not listed by
13
 *          a @covers or @uses annotations
14
 * - beStrictAboutTestsThatDoNotTestAnything="true" / --disallow-test-output
15
 * - beStrictAboutChangesToGlobalState="true" / --strict-global-state
16
 *
17
 * @see https://github.com/yoanm/Readme/blob/master/strategy/tests/README.md#rules-real-coverage-risky-tests
18
 * Risky tests will be managed as not executed tests and so, code coverage generated by them will be removed
19
 *  => Allow failure based on coverage
20
 */
21
class TestsStrategyListener extends \PHPUnit_Framework_BaseTestListener
22
{
23
    /**
24
     * @param \PHPUnit_Framework_Test $test
25
     * @param \Exception              $e
26
     * @param float                   $time
27
     */
28 9
    public function addRiskyTest(\PHPUnit_Framework_Test $test, \Exception $e, $time)
29
    {
30
        /* Must be PHPUnit_Framework_TestCase instance to have access to "getTestResultObject" method */
31 9
        if ($test instanceof \PHPUnit_Framework_TestCase) {
32 9
            $testResult = $test->getTestResultObject();
33 9
            $reason = null;
34 9
            switch (true) {
35
                /* beStrictAboutOutputDuringTests="true" */
36 9
                case $e instanceof \PHPUnit_Framework_OutputError:
37 4
                    $reason = 'No output during test';
38
                    /** Ack - remove coverage */
39 4
                    $this->removeCoverageFor($test);
40
                    /** END Ack */
41 4
                    break;
42
                /* checkForUnintentionallyCoveredCode="true" */
43 5
                case $e instanceof \PHPUnit_Framework_UnintentionallyCoveredCodeError:
44 1
                    $reason = 'Executed code must be defined with @covers and @uses annotations';
45 1
                    break;
46 4
                default:
47 4
                    if (preg_match('#\-\-\- Global variables before the test#', $e->getMessage())) {
48
                        /* beStrictAboutChangesToGlobalState="true" (no specific exception) for globals */
49 1
                        $reason = 'Global variable manipulation during test';
50 4
                    } elseif (preg_match('#\-\-\- Static attributes before the test#', $e->getMessage())) {
51
                        /* beStrictAboutChangesToGlobalState="true" (no specific exception) for static var */
52
                        /* Only when beStrictAboutChangesToGlobalState="true" */
53 1
                        $reason = 'Static attribute manipulation during test';
54 3
                    } elseif (preg_match('#This test did not perform any assertions#', $e->getMessage())) {
55
                        /* beStrictAboutTestsThatDoNotTestAnything="true" (no specific exception) */
56 1
                        $reason = 'Test that do not test anything';
57 1
                    }
58 4
                    break;
59 4
            }
60 9
            if (null !== $reason) {
61 8
                $testResult->addFailure(
62 8
                    $test,
63 8
                    new \PHPUnit_Framework_AssertionFailedError(
64 8
                        sprintf(
65 8
                            "Strict mode - %s :\n%s",
66 8
                            $reason,
67 8
                            $e->getMessage()
68 8
                        )
69 8
                    ),
70
                    $time
71 8
                );
72 8
            }
73 9
        }
74 9
    }
75
76
    /**
77
     * @param \PHPUnit_Framework_TestCase $test
78
     */
79 4
    protected function removeCoverageFor(\PHPUnit_Framework_TestCase $test)
80
    {
81 4
        $coverage = $test->getTestResultObject()->getCodeCoverage();
82 4
        if (null !== $coverage) {
83 3
            $id = sprintf('%s::%s', get_class($test), $test->getName());
84 3
            $data = $coverage->getData();
85 3
            foreach ($data as $fileName => $lineData) {
86 3
                foreach ($lineData as $lineNumber => $testIdList) {
87 3
                    if (is_array($testIdList)) {
88 3
                        foreach ($testIdList as $testIdKey => $testId) {
89 3
                            if ($id === $testId) {
90 3
                                unset($data[$fileName][$lineNumber][$testIdKey]);
91 3
                            }
92 3
                        }
93 3
                    }
94 3
                }
95 3
            }
96 3
            $coverage->setData($data);
97 3
        }
98 4
    }
99
}
100