Failed Conditions
Pull Request — master (#33)
by Yo
04:47 queued 02:20
created

BehatStepLoggerSubscriber::extractLineAndAction()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 21
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 0
Metric Value
dl 0
loc 21
ccs 0
cts 20
cp 0
rs 9.0534
c 0
b 0
f 0
cc 4
eloc 15
nc 4
nop 1
crap 20
1
<?php
2
namespace Yoanm\Behat3SymfonyExtension\Subscriber;
3
4
use Behat\Behat\EventDispatcher\Event\BackgroundTested;
5
use Behat\Behat\EventDispatcher\Event\ExampleTested;
6
use Behat\Behat\EventDispatcher\Event\FeatureTested;
7
use Behat\Behat\EventDispatcher\Event\GherkinNodeTested;
8
use Behat\Behat\EventDispatcher\Event\OutlineTested;
9
use Behat\Behat\EventDispatcher\Event\ScenarioTested;
10
use Behat\Behat\EventDispatcher\Event\StepTested;
11
use Behat\Gherkin\Node\ExampleNode;
12
use Behat\Gherkin\Node\StepContainerInterface;
13
use Behat\Gherkin\Node\StepNode;
14
use Behat\Testwork\EventDispatcher\Event\AfterTested;
15
use Psr\Log\LoggerInterface;
16
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
17
18
/**
19
 * Class BehatStepLoggerSubscriber
20
 */
21
class BehatStepLoggerSubscriber implements EventSubscriberInterface
22
{
23
    /** @var LoggerInterface */
24
    private $logger;
25
26
    /**
27
     * @param LoggerInterface $logger
28
     */
29
    public function __construct(LoggerInterface $logger)
30
    {
31
        $this->logger = $logger;
32
    }
33
34
    /**
35
     * {@inheritdoc}
36
     */
37
    public static function getSubscribedEvents()
38
    {
39
        // Set hight priority to log it at beginning
40
        $hightPriority = 9999999999999;
41
        return [
42
            FeatureTested::BEFORE => ['logEvent', $hightPriority],
43
            BackgroundTested::BEFORE => ['logEvent', $hightPriority],
44
            ScenarioTested::BEFORE => ['logEvent', $hightPriority],
45
            OutlineTested::BEFORE => ['logEvent', $hightPriority],
46
            ExampleTested::BEFORE => ['logEvent', $hightPriority],
47
            StepTested::BEFORE => ['logEvent', $hightPriority],
48
            FeatureTested::AFTER => ['logEvent', $hightPriority],
49
            BackgroundTested::AFTER => ['logEvent', $hightPriority],
50
            ScenarioTested::AFTER => ['logEvent', $hightPriority],
51
            OutlineTested::AFTER => ['logEvent', $hightPriority],
52
            ExampleTested::AFTER => ['logEvent', $hightPriority],
53
            StepTested::AFTER => ['logEvent', $hightPriority],
54
        ];
55
    }
56
57
    /**
58
     * @param GherkinNodeTested $event
59
     */
60
    public function logEvent(GherkinNodeTested $event)
61
    {
62
        list($header, $context) = $this->getNodeContext($event);
63
        $this->logger->debug($header, $context);
64
    }
65
66
    /**
67
     * @param GherkinNodeTested $event
68
     * @return array
69
     */
70
    protected function getNodeContext(GherkinNodeTested $event)
71
    {
72
        list($action, $line) = $this->extractLineAndAction($event);
73
        list($eventId, $context) = $this->extractTypeAndContext($event, $line);
74
75
        return [
76
            sprintf('[%s][%s]', $eventId, $action),
77
            $context
78
        ];
79
    }
80
81
    /**
82
     * @param GherkinNodeTested $event
83
     * @return array
84
     */
85
    protected function extractLineAndAction(GherkinNodeTested $event)
86
    {
87
        $action = 'IN';
88
        $line = $event->getNode()->getLine();
89
        if ($event instanceof AfterTested) {
90
            $action = 'OUT';
91
            $node = $event->getNode();
92
            if ($node instanceof StepContainerInterface) {
93
                $stepList = $node->getSteps();
94
                $lastStep = array_pop($stepList);
95
                // Check if StepContainer is not empty
96
                if ($lastStep instanceof StepNode) {
97
                    $line = $lastStep->getLine();
98
                    return array($action, $line);
99
                }
100
                return array($action, $line);
101
            }
102
            return array($action, $line);
103
        }
104
        return array($action, $line);
105
    }
106
107
    /**
108
     * @param GherkinNodeTested $event
109
     * @param int            $line
110
     *
111
     * @return array
112
     */
113
    protected function extractTypeAndContext(GherkinNodeTested $event, $line)
114
    {
115
        $context = [];
116
        if ($event instanceof StepTested) {
117
            $eventId = 'STEP';
118
            $context['text'] = $event->getStep()->getText();
119
        } elseif ($event instanceof BackgroundTested) {
120
            $eventId = 'BACKGROUND';
121
            $context['title'] = $event->getBackground()->getTitle();
122
        } elseif ($event instanceof ScenarioTested) {
123
            $scenario = $event->getScenario();
124
            $eventId = 'SCENARIO';
125
            if ($scenario instanceof ExampleNode) {
126
                $eventId .= ' EXAMPLE';
127
                $context['tokens'] = $scenario->getTokens();
128
            }
129
            $context['title'] = $event->getScenario()->getTitle();
130
        } elseif ($event instanceof OutlineTested) {
131
            $eventId = 'SCENARIO OUTLINE';
132
            $context['title'] = $event->getOutline()->getTitle();
133
        } elseif ($event instanceof FeatureTested) {
134
            $eventId = 'FEATURE';
135
            $context['title'] = $event->getFeature()->getTitle();
136
            $context['file'] = $event->getFeature()->getFile();
137
        }
138
139
        if (!$event instanceof FeatureTested) {
140
            $context['line'] = $line;
141
            return array($eventId, $context);
0 ignored issues
show
Bug introduced by
The variable $eventId does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
142
        }
143
        return array($eventId, $context);
144
    }
145
}
146