Passed
Push — master ( 069efd...bb88de )
by Dmitry
02:27
created

TestGuyMethods::expectTo()   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
    //region ----------------------- SPECIFICATION METHODS -----------------------
39
40
    /**
41
     * Specifies scenario test guy is working on.
42
     *
43
     * @param string $scenario scenario name.
44
     * Scenario should be a logical ending of "I describe ". For example: "process of user registration".
45
     * Such scenario would result in "I describe process of user registration" output in console.
46
     * @return $this
47
     */
48
    public function describe(string $scenario): TestGuy {
49
        $this->steps->add('I describe ' . $scenario);
50
        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...
51
    }
52
53
    /**
54
     * Specifies what test guy expects from a set of matchers that would be defined next in the
55
     * specification.
56
     *
57
     * @param string $expectation expectation text.
58
     * Expectation should be a logical ending of "I expect that ". For example: "user is added to the DB".
59
     * Such scenario would result in "I expect that user is added to the DB" output in console.
60
     * @return $this
61
     */
62
    public function expectThat(string $expectation): TestGuy {
63
        $this->steps->add('I expect that ' . $expectation);
64
65
        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...
66
    }
67
68
    /**
69
     * Specifies what test guy expects from a set of matchers that would be defined next in the
70
     * specification.
71
     *
72
     * @param string $expectation expectation text.
73
     * Expectation should be a logical ending of "I expect to ". For example: "see user in the DB".
74
     * Such scenario would result in "I expect to see user in the DB" output in console.
75
     * @param callable $verificationSteps callable function with following definition "function (TestGuy $I) { ..." that contains a group of
76
     * expectations united by one verification topic. All of the expectations would be executed once they
77
     * are defined.
78
     * @return $this
79
     */
80
    public function verifyThat(string $expectation, callable $verificationSteps = null): TestGuy {
81
        $this->steps->add('I verify that ' . $expectation);
82
        if ($verificationSteps) {
83
            $verificationSteps($this);
84
        }
85
86
        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...
87
    }
88
89
    /**
90
     * Specifies name of a variable test guy would check.
91
     *
92
     * @param string $variableName name of a variable to look at.
93
     * @return TestGuy
94
     */
95
    public function lookAt(string $variableName): TestGuy {
96
        $this->variableName = $variableName;
97
        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...
98
    }
99
100
    /**
101
     * Creates runtime matcher that you can use to perform typical asserts.
102
     * Runtime matcher is an object that represents a set of asserts from a typical matcher that
103
     * aren't executed at a time they were defined but would be executed every time runtime matcher object
104
     * would be called as a function with one argument - value to assert.
105
     *
106
     * For example:
107
     * <code>
108
     *  $userHasName = $I->match('user')->isArray()->isNotEmpty()->hasKey('name');
109
     *  $userHasName($admin);
110
     *  $userHasName($member);
111
     * </code>
112
     *
113
     * @param string $variableName name of a variable to look at.
114
     * @return \PHPKitchen\CodeSpecs\Expectation\Dispatcher\DelayedDispatcher
115
     */
116
    public function match(string $variableName): DelayedDispatcher {
117
        $this->variableName = $variableName;
118
        return $this->createDispatcher(DelayedDispatcher::class, null);
119
    }
120
121
    /**
122
     * Stops execution for specified number of units of time.
123
     *
124
     * @param int $numberOfTimeUnits number of units of time.
125
     * {@link Wait} specifies what unit should be used.
126
     *
127
     * @return Wait
128
     */
129
    public function wait($numberOfTimeUnits): Wait {
130
        return new Wait($numberOfTimeUnits, $this->steps);
131
    }
132
133
    /**
134
     * Starts a chain of asserts from {@link ValueMatcher}.
135
     *
136
     * @param mixed $variable variable to be tested
137
     * @return \PHPKitchen\CodeSpecs\Expectation\Matcher\ValueMatcher
138
     */
139
    public function see($variable): ValueMatcher {
140
        return $this->dispatch($variable)
141
            ->isMixed();
142
    }
143
144
    /**
145
     * Starts a chain of asserts from {@link StringMatcher}.
146
     *
147
     * @param string $variable variable to be tested
148
     * @return \PHPKitchen\CodeSpecs\Expectation\Matcher\StringMatcher
149
     */
150
    public function seeString($string): StringMatcher {
151
        return $this->dispatch($string)
152
            ->isString();
153
    }
154
155
    /**
156
     * Starts a chain of asserts from {@link ArrayMatcher}.
157
     *
158
     * @param array|\ArrayAccess $variable variable to be tested
159
     * @return \PHPKitchen\CodeSpecs\Expectation\Matcher\ArrayMatcher
160
     */
161
    public function seeArray($variable): ArrayMatcher {
162
        return $this->dispatch($variable)
163
            ->isArray();
164
    }
165
166
    /**
167
     * Starts a chain of asserts from {@link BooleanMatcher}.
168
     *
169
     * @param boolean $variable variable to be tested
170
     * @return \PHPKitchen\CodeSpecs\Expectation\Matcher\BooleanMatcher
171
     */
172
    public function seeBool($variable): BooleanMatcher {
173
        return $this->dispatch($variable)
174
            ->isBoolean();
175
    }
176
177
    /**
178
     * Starts a chain of asserts from {@link NumberMatcher}.
179
     *
180
     * @param int|float $variable variable to be tested
181
     * @return \PHPKitchen\CodeSpecs\Expectation\Matcher\NumberMatcher
182
     */
183
    public function seeNumber($variable): NumberMatcher {
184
        return $this->dispatch($variable)
185
            ->isNumber();
186
    }
187
188
    /**
189
     * Starts a chain of asserts from {@link ObjectMatcher}.
190
     *
191
     * @param object $variable variable to be tested
192
     * @return \PHPKitchen\CodeSpecs\Expectation\Matcher\ObjectMatcher
193
     */
194
    public function seeObject($variable): ObjectMatcher {
195
        return $this->dispatch($variable)
196
            ->isObject();
197
    }
198
199
    /**
200
     * Starts a chain of asserts from {@link ClassMatcher}.
201
     *
202
     * @param string $variable variable to be tested
203
     * @return \PHPKitchen\CodeSpecs\Expectation\Matcher\ClassMatcher
204
     */
205
    public function seeClass($variable): ClassMatcher {
206
        return $this->dispatch($variable)
207
            ->isClass();
208
    }
209
210
    /**
211
     * Starts a chain of asserts from {@link FileMatcher}.
212
     *
213
     * @param string $variable variable to be tested
214
     * @return \PHPKitchen\CodeSpecs\Expectation\Matcher\FileMatcher
215
     */
216
    public function seeFile($variable): FileMatcher {
217
        return $this->dispatch($variable)
218
            ->isFile();
219
    }
220
221
    /**
222
     * Starts a chain of asserts from {@link DirectoryMatcher}.
223
     *
224
     * @param string $variable variable to be tested
225
     * @return \PHPKitchen\CodeSpecs\Expectation\Matcher\DirectoryMatcher
226
     */
227
    public function seeDirectory($variable): DirectoryMatcher {
228
        return $this->dispatch($variable)
229
            ->isDirectory();
230
    }
231
    //endregion
232
233
    //region ----------------------- UTIL METHODS -----------------------
234
235
    protected function initStepsList() {
236
        $this->steps = StepsList::getInstance();
237
        $this->steps->clear();
238
    }
239
240
    private function dispatch($actualValue): Dispatcher {
241
        return $this->createDispatcher(Dispatcher::class, $actualValue);
242
    }
243
244
    private function createDispatcher($class, $actualValue): Dispatcher {
245
        $dispatcher = new $class($this->context, $actualValue, $this->variableName);
246
        $this->variableName = '';
247
        return $dispatcher;
248
    }
249
    //endregion
250
}