Passed
Push — master ( 1e7c7f...24f8fa )
by Baptiste
06:05
created

AbstractContext   A

Complexity

Total Complexity 35

Size/Duplication

Total Lines 231
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

Changes 0
Metric Value
wmc 35
lcom 1
cbo 4
dl 0
loc 231
c 0
b 0
f 0
rs 9

32 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
getJson() 0 1 ?
A getValue() 0 4 1
A pathShouldBeReadable() 0 4 1
A pathShouldNotBeReadable() 0 4 1
A theJsonPathShouldBeEqualTo() 0 4 1
A theJsonPathShouldNotBeEqualTo() 0 4 1
A theJsonPathShouldBePyString() 0 4 1
A theJsonPathShouldBe() 0 4 1
A theJsonPathShouldNotBe() 0 4 1
A theJsonPathShouldBeNull() 0 4 1
A theJsonPathShouldNotBeNull() 0 4 1
A theJsonPathShouldBeEmpty() 0 4 1
A theJsonPathShouldNotBeEmpty() 0 4 1
A theJsonPathContains() 0 4 1
A theJsonPathNotContains() 0 4 1
A theJsonPathCollectionContains() 0 12 3
A theJsonPathShouldBeAValidDate() 0 8 2
A theJsonPathShouldBeGreaterThan() 0 4 1
A theJsonPathShouldBeGreaterOrEqualThan() 0 4 1
A theJsonPathShouldBeLessThan() 0 4 1
A theJsonPathShouldBeLessOrEqualThan() 0 4 1
A shouldBeAnArray() 0 4 1
A theJsonPathShouldHaveAtLeastElements() 0 7 1
A theJsonPathShouldHaveElements() 0 4 1
A theJsonPathShouldHaveAtMostElements() 0 7 1
A theJsonPathShouldMatch() 0 4 1
A theJsonPathShouldNotMatch() 0 9 2
A rootShouldBeAnArray() 0 4 1
A theRootShouldHaveElements() 0 7 1
A theRootShouldHaveAtMostElements() 0 7 1
A theJsonPathShouldBeAValidJsonEncodedString() 0 7 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
    public function pathShouldBeReadable(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
    public function pathShouldNotBeReadable(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
    public function theJsonPathShouldBeEqualTo(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
    public function theJsonPathShouldNotBeEqualTo(string $path, $expected): void
61
    {
62
        Assert::notEq($this->getValue($path), $expected);
63
    }
64
65
    /** @Then in the json, :path should be: */
66
    public function theJsonPathShouldBePyString(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
    public function theJsonPathShouldBe(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
    public function theJsonPathShouldNotBe(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
    public function theJsonPathShouldBeNull(string $path): void
85
    {
86
        Assert::null($this->getValue($path));
87
    }
88
89
    /** @Then in the json, :path should not be null */
90
    public function theJsonPathShouldNotBeNull(string $path): void
91
    {
92
        Assert::notNull($this->getValue($path));
93
    }
94
95
    /** @Then in the json, :path should be empty */
96
    public function theJsonPathShouldBeEmpty(string $path): void
97
    {
98
        Assert::isEmpty($this->getValue($path));
99
    }
100
101
    /** @Then in the json, :path should not be empty */
102
    public function theJsonPathShouldNotBeEmpty(string $path): void
103
    {
104
        Assert::notEmpty($this->getValue($path));
105
    }
106
107
    /** @Then in the json, :path should contain :expected */
108
    public function theJsonPathContains(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
    public function theJsonPathNotContains(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
    public function theJsonPathCollectionContains(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
    public function theJsonPathShouldBeAValidDate(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
    public function theJsonPathShouldBeGreaterThan(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
    public function theJsonPathShouldBeGreaterOrEqualThan(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
    public function theJsonPathShouldBeLessThan(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
    public function theJsonPathShouldBeLessOrEqualThan(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
    public function shouldBeAnArray(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
    public function theJsonPathShouldHaveAtLeastElements(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
    public function theJsonPathShouldHaveElements(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
    public function theJsonPathShouldHaveAtMostElements(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
    public function theJsonPathShouldMatch(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
    public function theJsonPathShouldNotMatch(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
    public function rootShouldBeAnArray(): void
224
    {
225
        Assert::isArray($this->getJson());
226
    }
227
228
    /** @Then in the json, the root should have :count element(s) */
229
    public function theRootShouldHaveElements(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
    public function theRootShouldHaveAtMostElements(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
    public function theJsonPathShouldBeAValidJsonEncodedString(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