Completed
Push — focused-specs-cli ( c4b6f1...95fde4 )
by Erin
01:39
created

AbstractTest::setFocused()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Peridot\Core;
4
5
/**
6
 * Base class for Peridot Suites and Tests
7
 *
8
 * @package Peridot\Core
9
 */
10
abstract class AbstractTest implements TestInterface
11
{
12
    use HasEventEmitterTrait;
13
14
    /**
15
     * The test definition as a callable.
16
     *
17
     * @var callable
18
     */
19
    protected $definition;
20
21
    /**
22
     * A collection of functions to run before tests execute.
23
     *
24
     * @var array
25
     */
26
    protected $setUpFns = [];
27
28
    /**
29
     * A collection of functions to run after tests execute.
30
     *
31
     * @var array
32
     */
33
    protected $tearDownFns = [];
34
35
    /**
36
     * @var string
37
     */
38
    protected $description;
39
40
    /**
41
     * @var TestInterface
42
     */
43
    protected $parent;
44
45
    /**
46
     * @var bool|null
47
     */
48
    protected $pending = null;
49
50
    /**
51
     * @var bool
52
     */
53
    protected $focused;
54
55
    /**
56
     * @var Scope
57
     */
58
    protected $scope;
59
60
    /**
61
     * @var string
62
     */
63
    protected $file;
64
65
    /**
66
     * @var array
67
     */
68
    protected $definitionArguments = [];
69
70
    /**
71
     * @param string   $description
72
     * @param callable $definition
73
     * @param bool     $focused
74
     */
75
    public function __construct($description, callable $definition, $focused = false)
76
    {
77
        $this->definition = $definition;
78
        $this->description = $description;
79
        $this->focused = $focused;
80
        $this->scope = new Scope();
81
    }
82
83
    /**
84
     * {@inheritdoc}
85
     *
86
     * @param callable $setupFn
87
     */
88
    public function addSetupFunction(callable $setupFn)
89
    {
90
        $fn = $this->getScope()->peridotBindTo($setupFn);
91
        array_push($this->setUpFns, $fn);
92
    }
93
94
    /**
95
     * {@inheritdoc}
96
     *
97
     * @param callable $tearDownFn
98
     */
99
    public function addTearDownFunction(callable $tearDownFn)
100
    {
101
        $fn = $this->getScope()->peridotBindTo($tearDownFn);
102
        array_push($this->tearDownFns, $fn);
103
    }
104
105
    /**
106
     * {@inheritdoc}
107
     *
108
     * @return string
109
     */
110
    public function getDescription()
111
    {
112
        return $this->description;
113
    }
114
115
    /**
116
     * {@inheritdoc}
117
     *
118
     * @return callable
119
     */
120
    public function getDefinition()
121
    {
122
        return $this->scope->peridotBindTo($this->definition);
123
    }
124
125
    /**
126
     * {@inheritdoc}
127
     *
128
     * @param  TestInterface $parent
129
     * @return mixed|void
130
     */
131
    public function setParent(TestInterface $parent)
132
    {
133
        $this->parent = $parent;
134
        $this->setScope($parent->getScope());
135
    }
136
137
    /**
138
     * {@inheritdoc}
139
     *
140
     * @return TestInterface
141
     */
142
    public function getParent()
143
    {
144
        return $this->parent;
145
    }
146
147
    /**
148
     * {@inheritdoc}
149
     *
150
     * @return string
151
     */
152
    public function getTitle()
153
    {
154
        $parts = [];
155
        $node = $this;
156
        while ($node != null) {
157
            array_unshift($parts, $node->getDescription());
158
            $node = $node->getParent();
159
        }
160
161
        return implode(' ', $parts);
162
    }
163
164
    /**
165
     * {@inheritdoc}
166
     *
167
     * @return bool|null
168
     */
169
    public function getPending()
170
    {
171
        return $this->pending;
172
    }
173
174
    /**
175
     * {@inheritdoc}
176
     *
177
     * @param bool $state
178
     */
179
    public function setPending($state)
180
    {
181
        $this->pending = (bool) $state;
182
    }
183
184
    /**
185
     * Set the focused status of the test and its children according to the
186
     * supplied focus pattern and/or skip pattern
187
     *
188
     * @param string|null $focusPattern
189
     * @param string|null $skipPattern
190
     */
191
    public function applyFocusPatterns($focusPattern, $skipPattern = null)
192
    {
193
        $title = $this->getTitle();
194
195
        if ($focusPattern) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $focusPattern of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
196
            $isFocused = preg_match($focusPattern, $title);
197
        } else {
198
            $isFocused = true;
199
        }
200
201
        if (!$isFocused) {
202
            $this->focused = false;
203
204
            return;
205
        }
206
207
        if ($skipPattern === null) {
208
            $this->focused = true;
209
210
            return;
211
        }
212
213
        $this->focused = !preg_match($skipPattern, $title);
214
    }
215
216
    /**
217
     * {@inheritdoc}
218
     *
219
     * @return array
220
     */
221
    public function getSetupFunctions()
222
    {
223
        return $this->setUpFns;
224
    }
225
226
    /**
227
     * {@inheritdoc}
228
     *
229
     * @return array
230
     */
231
    public function getTearDownFunctions()
232
    {
233
        return $this->tearDownFns;
234
    }
235
236
    /**
237
     * {@inheritdoc}
238
     *
239
     * @param callable $fn
240
     */
241
    public function forEachNodeBottomUp(callable $fn)
242
    {
243
        $node = $this;
244
        while ($node !== null) {
245
            $fn($node);
246
            $node = $node->getParent();
247
        }
248
    }
249
250
    /**
251
     * {@inheritdoc}
252
     *
253
     * @param callable $fn
254
     */
255
    public function forEachNodeTopDown(callable $fn)
256
    {
257
        $node = $this;
258
        $nodes = [];
259
        while ($node !== null) {
260
            array_unshift($nodes, $node);
261
            $node = $node->getParent();
262
        }
263
        foreach ($nodes as $node) {
264
            $fn($node);
265
        }
266
    }
267
268
    /**
269
     * {@inheritdoc}
270
     *
271
     * @return Scope
272
     */
273
    public function getScope()
274
    {
275
        return $this->scope;
276
    }
277
278
    /**
279
     * {@inheritdoc}
280
     *
281
     * @param Scope $scope
282
     * @return mixed
283
     */
284
    public function setScope(Scope $scope)
285
    {
286
        $this->scope = $scope;
287
        return $this;
288
    }
289
290
    /**
291
     * Get the file this test belongs to.
292
     *
293
     * @return string
294
     */
295
    public function getFile()
296
    {
297
        return $this->file;
298
    }
299
300
    /**
301
     * Set the file this test belongs to.
302
     *
303
     * @param string $file
304
     */
305
    public function setFile($file)
306
    {
307
        $this->file = $file;
308
        return $this;
309
    }
310
311
    /**
312
     * {@inheritdoc}
313
     *
314
     * @param array $args
315
     * @return $this
316
     */
317
    public function setDefinitionArguments(array $args)
318
    {
319
        $this->definitionArguments = $args;
320
    }
321
322
    /**
323
     * {@inheritdoc}
324
     *
325
     * @return array
326
     */
327
    public function getDefinitionArguments()
328
    {
329
        return $this->definitionArguments;
330
    }
331
}
332