Passed
Push — master ( 4ee327...62eb0a )
by Dmitry
02:50
created

TestGuyMethods::seeClass()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace PHPKitchen\CodeSpecs\Mixin;
4
5
use PHPKitchen\CodeSpecs\Contract\TestGuy;
6
use PHPKitchen\CodeSpecs\Directive\Wait;
7
use PHPKitchen\CodeSpecs\Expectation\Dispatcher\DelayedDispatcher;
8
use PHPKitchen\CodeSpecs\Expectation\Dispatcher\Dispatcher;
9
use PHPKitchen\CodeSpecs\Expectation\Internal\StepsList;
10
use PHPKitchen\CodeSpecs\Expectation\Matcher\ArrayMatcher;
11
use PHPKitchen\CodeSpecs\Expectation\Matcher\BooleanMatcher;
12
use PHPKitchen\CodeSpecs\Expectation\Matcher\ClassMatcher;
13
use PHPKitchen\CodeSpecs\Expectation\Matcher\DirectoryMatcher;
14
use PHPKitchen\CodeSpecs\Expectation\Matcher\FileMatcher;
15
use PHPKitchen\CodeSpecs\Expectation\Matcher\NumberMatcher;
16
use PHPKitchen\CodeSpecs\Expectation\Matcher\ObjectMatcher;
17
use PHPKitchen\CodeSpecs\Expectation\Matcher\StringMatcher;
18
use PHPKitchen\CodeSpecs\Expectation\Matcher\ValueMatcher;
19
20
/**
21
 * Represents common expectation methods that can be used in test guy implementation.
22
 *
23
 * @codeCoverageIgnore
24
 *
25
 * @package PHPKitchen\CodeSpecs\Mixins
26
 * @author Dmitry Kolodko <[email protected]>
27
 */
28
trait TestGuyMethods {
29
    /**
30
     * @var StepsList
31
     */
32
    private $steps;
33
    /**
34
     * @var \PHPUnit\Framework\Test
35
     */
36
    protected $context;
37
    protected $variableName = '';
38
39
    //region ----------------------- SPECIFICATION METHODS -----------------------
40
41
    /**
42
     * Specifies scenario test guy is working on.
43
     *
44
     * @param string $scenario scenario name.
45
     * Scenario should be a logical ending of "I describe ". For example: "process of user registration".
46
     * Such scenario would result in "I describe process of user registration" output in console.
47
     * @return $this
48
     */
49
    public function describe(string $scenario): TestGuy {
50
        $this->steps->add('I describe ' . $scenario);
51
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type PHPKitchen\CodeSpecs\Mixin\TestGuyMethods which is incompatible with the type-hinted return PHPKitchen\CodeSpecs\Contract\TestGuy.
Loading history...
52
    }
53
54
    /**
55
     * Specifies what test guy expects from a set of matchers that would be defined next in the
56
     * specification.
57
     *
58
     * @param string $expectation expectation text.
59
     * Expectation should be a logical ending of "I expect that ". For example: "user is added to the DB".
60
     * Such scenario would result in "I expect that user is added to the DB" output in console.
61
     * @return $this
62
     */
63
    public function expectThat(string $expectation): TestGuy {
64
        $this->steps->add('I expect that ' . $expectation);
65
66
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type PHPKitchen\CodeSpecs\Mixin\TestGuyMethods which is incompatible with the type-hinted return PHPKitchen\CodeSpecs\Contract\TestGuy.
Loading history...
67
    }
68
69
    /**
70
     * Specifies what test guy expects from a set of matchers that would be defined next in the
71
     * specification.
72
     *
73
     * @param string $expectation expectation text.
74
     * Expectation should be a logical ending of "I expect to ". For example: "see user in the DB".
75
     * Such scenario would result in "I expect to see user in the DB" output in console.
76
     * @return $this
77
     */
78
    public function expectTo(string $expectation): TestGuy {
79
        $this->steps->add('I expect to ' . $expectation);
80
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type PHPKitchen\CodeSpecs\Mixin\TestGuyMethods which is incompatible with the type-hinted return PHPKitchen\CodeSpecs\Contract\TestGuy.
Loading history...
81
    }
82
83
    /**
84
     * Specifies what test guy expects from a set of matchers that would be defined next in the
85
     * specification.
86
     *
87
     * @param string $expectation expectation text.
88
     * Expectation should be a logical ending of "I expect to ". For example: "see user in the DB".
89
     * Such scenario would result in "I expect to see user in the DB" output in console.
90
     * @param callable $verificationSteps callable function with following definition "function (TestGuy $I) { ..." that contains a group of
91
     * expectations united by one verification topic. All of the expectations would be executed once they
92
     * are defined.
93
     * @return $this
94
     */
95
    public function verifyThat(string $expectation, callable $verificationSteps = null): TestGuy {
96
        $this->steps->add('I verify that ' . $expectation);
97
        if ($verificationSteps) {
98
            $verificationSteps($this);
99
        }
100
101
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type PHPKitchen\CodeSpecs\Mixin\TestGuyMethods which is incompatible with the type-hinted return PHPKitchen\CodeSpecs\Contract\TestGuy.
Loading history...
102
    }
103
104
    /**
105
     * Specifies name of a variable test guy would check.
106
     *
107
     * @param string $variableName name of a variable to look at.
108
     * @return TestGuy
109
     */
110
    public function lookAt(string $variableName): TestGuy {
111
        $this->variableName = $variableName;
112
        return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type PHPKitchen\CodeSpecs\Mixin\TestGuyMethods which is incompatible with the type-hinted return PHPKitchen\CodeSpecs\Contract\TestGuy.
Loading history...
113
    }
114
115
    /**
116
     * Creates runtime matcher that you can use to perform typical asserts.
117
     * Runtime matcher is an object that represents a set of asserts from a typical matcher that
118
     * aren't executed at a time they were defined but would be executed every time runtime matcher object
119
     * would be called as a function with one argument - value to assert.
120
     *
121
     * For example:
122
     * <code>
123
     *  $userHasName = $I->match('user')->isArray()->isNotEmpty()->hasKey('name');
124
     *  $userHasName($admin);
125
     *  $userHasName($member);
126
     * </code>
127
     *
128
     * @param string $variableName name of a variable to look at.
129
     * @return \PHPKitchen\CodeSpecs\Expectation\Dispatcher\DelayedDispatcher
130
     */
131
    public function match(string $variableName): DelayedDispatcher {
132
        $this->variableName = $variableName;
133
        return $this->createDispatcher(DelayedDispatcher::class, null);
134
    }
135
136
    /**
137
     * Stops execution for specified number of units of time.
138
     *
139
     * @param int $numberOfTimeUnits number of units of time.
140
     * {@link Wait} specifies what unit should be used.
141
     *
142
     * @return Wait
143
     */
144
    public function wait($numberOfTimeUnits): Wait {
145
        return new Wait($numberOfTimeUnits, $this->steps);
146
    }
147
148
    /**
149
     * Starts a chain of asserts from {@link ValueMatcher}.
150
     *
151
     * @param mixed $variable variable to be tested
152
     * @return \PHPKitchen\CodeSpecs\Expectation\Matcher\ValueMatcher
153
     */
154
    public function see($variable): ValueMatcher {
155
        return $this->dispatch($variable)
156
            ->isMixed();
157
    }
158
159
    /**
160
     * Starts a chain of asserts from {@link StringMatcher}.
161
     *
162
     * @param string $variable variable to be tested
163
     * @return \PHPKitchen\CodeSpecs\Expectation\Matcher\StringMatcher
164
     */
165
    public function seeString($string): StringMatcher {
166
        return $this->dispatch($string)
167
            ->isString();
168
    }
169
170
    /**
171
     * Starts a chain of asserts from {@link ArrayMatcher}.
172
     *
173
     * @param array|\ArrayAccess $variable variable to be tested
174
     * @return \PHPKitchen\CodeSpecs\Expectation\Matcher\ArrayMatcher
175
     */
176
    public function seeArray($variable): ArrayMatcher {
177
        return $this->dispatch($variable)
178
            ->isArray();
179
    }
180
181
    /**
182
     * Starts a chain of asserts from {@link BooleanMatcher}.
183
     *
184
     * @param boolean $variable variable to be tested
185
     * @return \PHPKitchen\CodeSpecs\Expectation\Matcher\BooleanMatcher
186
     */
187
    public function seeBool($variable): BooleanMatcher {
188
        return $this->dispatch($variable)
189
            ->isBoolean();
190
    }
191
192
    /**
193
     * Starts a chain of asserts from {@link NumberMatcher}.
194
     *
195
     * @param int|float $variable variable to be tested
196
     * @return \PHPKitchen\CodeSpecs\Expectation\Matcher\NumberMatcher
197
     */
198
    public function seeNumber($variable): NumberMatcher {
199
        return $this->dispatch($variable)
200
            ->isNumber();
201
    }
202
203
    /**
204
     * Starts a chain of asserts from {@link ObjectMatcher}.
205
     *
206
     * @param object $variable variable to be tested
207
     * @return \PHPKitchen\CodeSpecs\Expectation\Matcher\ObjectMatcher
208
     */
209
    public function seeObject($variable): ObjectMatcher {
210
        return $this->dispatch($variable)
211
            ->isObject();
212
    }
213
214
    /**
215
     * Starts a chain of asserts from {@link ClassMatcher}.
216
     *
217
     * @param string $variable variable to be tested
218
     * @return \PHPKitchen\CodeSpecs\Expectation\Matcher\ClassMatcher
219
     */
220
    public function seeClass($variable): ClassMatcher {
221
        return $this->dispatch($variable)
222
            ->isClass();
223
    }
224
225
    /**
226
     * Starts a chain of asserts from {@link FileMatcher}.
227
     *
228
     * @param string $variable variable to be tested
229
     * @return \PHPKitchen\CodeSpecs\Expectation\Matcher\FileMatcher
230
     */
231
    public function seeFile($variable): FileMatcher {
232
        return $this->dispatch($variable)
233
            ->isFile();
234
    }
235
236
    /**
237
     * Starts a chain of asserts from {@link DirectoryMatcher}.
238
     *
239
     * @param string $variable variable to be tested
240
     * @return \PHPKitchen\CodeSpecs\Expectation\Matcher\DirectoryMatcher
241
     */
242
    public function seeDirectory($variable): DirectoryMatcher {
243
        return $this->dispatch($variable)
244
            ->isDirectory();
245
    }
246
    //endregion
247
248
    //region ----------------------- UTIL METHODS -----------------------
249
250
    protected function initStepsList() {
251
        $this->steps = StepsList::getInstance();
252
        $this->steps->clear();
253
    }
254
255
    private function dispatch($actualValue): Dispatcher {
256
        return $this->createDispatcher(Dispatcher::class, $actualValue);
257
    }
258
259
    private function createDispatcher($class, $actualValue): Dispatcher {
260
        $dispatcher = new $class($this->context, $actualValue, $this->variableName);
261
        $this->variableName = '';
262
        return $dispatcher;
263
    }
264
    //endregion
265
}