Passed
Push — master ( 1e0132...9b86f1 )
by Baptiste
02:58
created

AbstractContext::the_json_path_should_be_empty()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 1
1
<?php declare(strict_types=1);
2
namespace Behapi\Json;
3
4
use stdClass;
5
use Datetime;
6
7
use Throwable;
8
use InvalidArgumentException;
9
10
use Behat\Gherkin\Node\PyStringNode;
11
use Behat\Behat\Context\Context as BehatContext;
12
13
use Symfony\Component\PropertyAccess\PropertyAccess;
14
use Symfony\Component\PropertyAccess\PropertyAccessor;
15
16
use Webmozart\Assert\Assert;
17
18
use function preg_match;
19
use function json_last_error;
20
21
use const JSON_ERROR_NONE;
22
use const PREG_OFFSET_CAPTURE;
23
24
abstract class AbstractContext implements BehatContext
25
{
26
    /** @var PropertyAccessor */
27
    private $accessor;
28
29
    public function __construct()
30
    {
31
        $this->accessor = PropertyAccess::createPropertyAccessor();
32
    }
33
34
    abstract protected function getJson();
35
36
    protected function getValue(string $path)
37
    {
38
        return $this->accessor->getValue($this->getJson(), $path);
39
    }
40
41
    /** @Then :path should be accessible in the latest json response */
42
    final public function path_should_be_readable(string $path): void
43
    {
44
        Assert::true($this->accessor->isReadable($this->getJson(), $path), "The path $path should be a valid path");
45
    }
46
47
    /** @Then :path should not exist in the latest json response */
48
    final public function path_should_not_be_readable(string $path): void
49
    {
50
        Assert::false($this->accessor->isReadable($this->getJson(), $path), "The path $path should not be a valid path");
51
    }
52
53
    /** @Then in the json, :path should be equal to :expected */
54
    final public function the_json_path_should_be_equal_to(string $path, $expected): void
55
    {
56
        Assert::eq($this->getValue($path), $expected);
57
    }
58
59
    /** @Then in the json, :path should not be equal to :expected */
60
    final public function the_json_path_should_not_be_equal_to(string $path, $expected): void
61
    {
62
        Assert::notEq($this->getValue($path), $expected);
63
    }
64
65
    /** @Then in the json, :path should be: */
66
    final public function the_json_path_should_be_py_string(string $path, PyStringNode $expected): void
67
    {
68
        Assert::same($this->getValue($path), $expected->getRaw());
69
    }
70
71
    /** @Then /^in the json, "(?P<path>(?:[^"]|\\")*)" should be (?P<expected>true|false)$/ */
72
    final public function the_json_path_should_be(string $path, string $expected): void
73
    {
74
        Assert::same($this->getValue($path), 'true' === $expected);
75
    }
76
77
    /** @Then /^in the json, "(?P<path>(?:[^"]|\\")*)" should not be (?P<expected>true|false)$/ */
78
    final public function the_json_path_should_not_be(string $path, string $expected): void
79
    {
80
        Assert::notSame($this->getValue($path), 'true' === $expected);
81
    }
82
83
    /** @Then in the json, :path should be null */
84
    final public function the_json_path_should_be_null(string $path): void
85
    {
86
        Assert::null($this->getValue($path));
87
    }
88
89
    /** @Then in the json, :path should not be null */
90
    final public function the_json_path_should_not_be_null(string $path): void
91
    {
92
        Assert::notNull($this->getValue($path));
93
    }
94
95
    /** @Then in the json, :path should be empty */
96
    final public function the_json_path_should_be_empty(string $path): void
97
    {
98
        Assert::isEmpty($this->getValue($path));
99
    }
100
101
    /** @Then in the json, :path should not be empty */
102
    final public function the_json_path_should_not_be_empty(string $path): void
103
    {
104
        Assert::notEmpty($this->getValue($path));
105
    }
106
107
    /** @Then in the json, :path should contain :expected */
108
    final public function the_json_path_contains(string $path, $expected): void
109
    {
110
        Assert::contains($this->getValue($path), $expected);
111
    }
112
113
    /** @Then /^in the json, :path should not contain :expected */
114
    final public function the_json_path_not_contains(string $path, $expected): void
115
    {
116
        Assert::notContains($this->getValue($path), $expected);
117
    }
118
119
    /** @Then in the json, :path collection should contain an element with :value equal to :expected */
120
    final public function the_json_path_collection_contains(string $path, string $value, $expected): void
121
    {
122
        $collection = $this->accessor->getValue($this->getJson(), $path);
123
124
        foreach ($collection as $element) {
125
            if ($expected === $this->accessor->getValue($element, $value)) {
126
                return;
127
            }
128
        }
129
130
        throw new InvalidArgumentException("$path collection does not contain an element with $value equal to $expected");
131
    }
132
133
    /** @Then in the json, :path should be a valid date(time) */
134
    final public function the_json_path_should_be_a_valid_date(string $path): void
135
    {
136
        try {
137
            new Datetime($this->getValue($path));
138
        } catch (Throwable $t) {
139
            throw new InvalidArgumentException("$path does not contain a valid date");
140
        }
141
    }
142
143
    /** @Then in the json, :path should be greater than :expected */
144
    final public function the_json_path_should_be_greater_than(string $path, int $expected): void
145
    {
146
        Assert::greaterThan($this->getValue($path), $expected);
147
    }
148
149
    /** @Then in the json, :path should be greater than or equal to :expected */
150
    final public function the_json_path_should_be_greater_or_equal_than(string $path, int $expected): void
151
    {
152
        Assert::greaterThanEq($this->getValue($path), $expected);
153
    }
154
155
    /** @Then in the json, :path should be less than :expected */
156
    final public function the_json_path_should_be_less_than(string $path, int $expected): void
157
    {
158
        Assert::lessThan($this->getValue($path), $expected);
159
    }
160
161
    /** @Then in the json, :path should be less than or equal to :expected */
162
    final public function the_json_path_should_be_less_or_equal_than(string $path, int $expected): void
163
    {
164
        Assert::lessThanEq($this->getValue($path), $expected);
165
    }
166
167
    /** @Then in the json, :path should be an array */
168
    final public function should_be_an_array(string $path): void
169
    {
170
        Assert::isArray($this->getValue($path));
171
    }
172
173
    /** @Then in the json, :path should have at least :count element(s) */
174
    final public function the_json_path_should_have_at_least_elements(string $path, int $count): void
175
    {
176
        $value = $this->getValue($path);
177
178
        Assert::isArray($value);
179
        Assert::greaterThanEq(count($value), $count);
180
    }
181
182
    /** @Then in the json, :path should have :count element(s) */
183
    final public function the_json_path_should_have_elements(string $path, int $count): void
184
    {
185
        Assert::count($this->getValue($path), $count);
186
    }
187
188
    /** @Then in the json, :path should have at most :count element(s) */
189
    final public function the_json_path_should_have_at_most_elements(string $path, int $count): void
190
    {
191
        $value = $this->getValue($path);
192
193
        Assert::isArray($value);
194
        Assert::lessThanEq(count($value), $count);
195
    }
196
197
    /** @Then in the json, :path should match :pattern */
198
    final public function the_json_path_should_match(string $path, string $pattern): void
199
    {
200
        Assert::regex($this->getValue($path), $pattern);
201
    }
202
203
    /**
204
     * @Then in the json, :path should not match :pattern
205
     *
206
     * -----
207
     *
208
     * Note :: The body of this assertion should be replaced by a
209
     * `Assert::notRegex` as soon as the Assert's PR
210
     * https://github.com/webmozart/assert/pull/58 is merged and released.
211
     */
212
    final public function the_json_path_should_not_match(string $path, string $pattern): void
213
    {
214
        if (!preg_match($pattern, $this->getValue($path), $matches, PREG_OFFSET_CAPTURE)) {
215
            // it's all good, it is supposed not to match. :}
216
            return;
217
        }
218
219
        throw new InvalidArgumentException("The value matches {$pattern} at offset {$matches[0][1]}");
220
    }
221
222
    /** @Then in the json, the root should be an array */
223
    final public function root_should_be_an_array(): void
224
    {
225
        Assert::isArray($this->getJson());
226
    }
227
228
    /** @Then in the json, the root should have :count element(s) */
229
    final public function the_root_should_have_elements(int $count): void
230
    {
231
        $value = $this->getJson();
232
233
        Assert::isArray($value);
234
        Assert::count($value, $count);
235
    }
236
237
    /** @Then in the json, the root should have at most :count element(s) */
238
    final public function the_root_should_have_at_most_elements(int $count): void
239
    {
240
        $value = $this->getJson();
241
242
        Assert::isArray($value);
243
        Assert::lessThanEq($value, $count);
244
    }
245
246
    /** @Then in the json, :path should be a valid json encoded string */
247
    final public function the_json_path_should_be_a_valid_json_encoded_string(string $path): void
248
    {
249
        $value = json_decode($this->getValue($path));
250
251
        Assert::notNull($value);
252
        Assert::same(json_last_error(), JSON_ERROR_NONE);
253
    }
254
}
255