Completed
Pull Request — master (#174)
by Włodzimierz
03:19
created

JsonContext::theJsonNodeShouldMatch()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 6

Duplication

Lines 12
Ratio 100 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 12
loc 12
rs 9.4285
cc 2
eloc 6
nc 2
nop 2
1
<?php
2
3
namespace Sanpi\Behatch\Context;
4
5
use Behat\Gherkin\Node\PyStringNode;
6
7
use Behat\Gherkin\Node\TableNode;
8
use Sanpi\Behatch\Json\Json;
9
use Sanpi\Behatch\Json\JsonSchema;
10
use Sanpi\Behatch\Json\JsonInspector;
11
use Sanpi\Behatch\HttpCall\HttpCallResultPool;
12
13
class JsonContext extends BaseContext
14
{
15
    protected $inspector;
16
17
    protected $httpCallResultPool;
18
19
    public function __construct(HttpCallResultPool $httpCallResultPool, $evaluationMode = 'javascript')
20
    {
21
        $this->inspector = new JsonInspector($evaluationMode);
22
        $this->httpCallResultPool = $httpCallResultPool;
23
    }
24
25
    /**
26
     * Checks, that the response is correct JSON
27
     *
28
     * @Then the response should be in JSON
29
     */
30
    public function theResponseShouldBeInJson()
31
    {
32
        $this->getJson();
33
    }
34
35
    /**
36
     * Checks, that the response is not correct JSON
37
     *
38
     * @Then the response should not be in JSON
39
     */
40
    public function theResponseShouldNotBeInJson()
41
    {
42
        $this->not(
43
            [$this, 'theResponseShouldBeInJson'],
44
            'The response is in JSON'
45
        );
46
    }
47
48
    /**
49
     * Checks, that given JSON node is equal to given value
50
     *
51
     * @Then the JSON node :node should be equal to :text
52
     */
53
    public function theJsonNodeShouldBeEqualTo($node, $text)
54
    {
55
        $json = $this->getJson();
56
57
        $actual = $this->inspector->evaluate($json, $node);
58
59
        if ($actual != $text) {
60
            throw new \Exception(
61
                sprintf("The node value is '%s'", json_encode($actual))
62
            );
63
        }
64
    }
65
66
    /**
67
     * Checks, that given JSON node matches given regexp
68
     *
69
     * @Then the JSON node :node should match :regexp
70
     */
71 View Code Duplication
    public function theJsonNodeShouldMatch($node, $regexp)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
72
    {
73
        $json = $this->getJson();
74
75
        $actual = $this->inspector->evaluate($json, $node);
76
77
        if (!preg_match($regexp, $actual)) {
78
            throw new \Exception(
79
                sprintf("The node value is '%s'", json_encode($actual))
80
            );
81
        }
82
    }
83
84
    /**
85
     * Checks, that given JSON nodes are equal to givens values
86
     *
87
     * @Then the JSON nodes should be equal to:
88
     */
89
    public function theJsonNodesShoudBeEqualTo(TableNode $nodes)
90
    {
91
        foreach ($nodes->getRowsHash() as $node => $text) {
92
            $this->theJsonNodeShouldBeEqualTo($node, $text);
93
        }
94
    }
95
96
    /**
97
     * Checks, that given JSON node is null
98
     *
99
     * @Then the JSON node :node should be null
100
     */
101
    public function theJsonNodeShouldBeNull($node)
102
    {
103
        $json = $this->getJson();
104
105
        $actual = $this->inspector->evaluate($json, $node);
106
107
        if (null !== $actual) {
108
            throw new \Exception(
109
                sprintf('The node value is `%s`', json_encode($actual))
110
            );
111
        }
112
    }
113
114
    /**
115
     * Checks, that given JSON node is not null.
116
     *
117
     * @Then the JSON node :node should not be null
118
     */
119
    public function theJsonNodeShouldNotBeNull($name)
120
    {
121
        $this->not(function () use ($name) {
122
            return $this->theJsonNodeShouldBeNull($name);
123
        }, sprintf('The node %s should not be null', $name));
124
    }
125
126
    /**
127
     * Checks, that given JSON node is true
128
     *
129
     * @Then the JSON node :node should be true
130
     */
131
    public function theJsonNodeShouldBeTrue($node)
132
    {
133
        $json = $this->getJson();
134
135
        $actual = $this->inspector->evaluate($json, $node);
136
137
        if (true !== $actual) {
138
            throw new \Exception(
139
                sprintf('The node value is `%s`', json_encode($actual))
140
            );
141
        }
142
    }
143
144
    /**
145
     * Checks, that given JSON node is false
146
     *
147
     * @Then the JSON node :node should be false
148
     */
149
    public function theJsonNodeShouldBeFalse($node)
150
    {
151
        $json = $this->getJson();
152
153
        $actual = $this->inspector->evaluate($json, $node);
154
155
        if (false !== $actual) {
156
            throw new \Exception(
157
                sprintf('The node value is `%s`', json_encode($actual))
158
            );
159
        }
160
    }
161
162
    /**
163
     * Checks, that given JSON node is equal to the given string
164
     *
165
     * @Then the JSON node :node should be equal to the string :text
166
     */
167 View Code Duplication
    public function theJsonNodeShouldBeEqualToTheString($node, $text)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
168
    {
169
        $json = $this->getJson();
170
171
        $actual = $this->inspector->evaluate($json, $node);
172
173
        if ($actual !== $text) {
174
            throw new \Exception(
175
                sprintf('The node value is `%s`', json_encode($actual))
176
            );
177
        }
178
    }
179
180
    /**
181
     * Checks, that given JSON node is equal to the given number
182
     *
183
     * @Then the JSON node :node should be equal to the number :number
184
     */
185 View Code Duplication
    public function theJsonNodeShouldBeEqualToTheNumber($node, $number)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
186
    {
187
        $json = $this->getJson();
188
189
        $actual = $this->inspector->evaluate($json, $node);
190
191
        if ($actual !== (float) $number && $actual !== (int) $number) {
192
            throw new \Exception(
193
                sprintf('The node value is `%s`', json_encode($actual))
194
            );
195
        }
196
    }
197
198
    /**
199
     * Checks, that given JSON node has N element(s)
200
     *
201
     * @Then the JSON node :node should have :count element(s)
202
     */
203
    public function theJsonNodeShouldHaveElements($node, $count)
204
    {
205
        $json = $this->getJson();
206
207
        $actual = $this->inspector->evaluate($json, $node);
208
209
        $this->assertSame($count, sizeof((array) $actual));
210
    }
211
212
    /**
213
     * Checks, that given JSON node contains given value
214
     *
215
     * @Then the JSON node :node should contain :text
216
     */
217 View Code Duplication
    public function theJsonNodeShouldContain($node, $text)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
218
    {
219
        $json = $this->getJson();
220
221
        $actual = $this->inspector->evaluate($json, $node);
222
223
        $this->assertContains($text, (string) $actual);
224
    }
225
226
    /**
227
     * Checks, that given JSON nodes contains values
228
     *
229
     * @Then the JSON nodes should contain:
230
     */
231
    public function theJsonNodesShoudContain(TableNode $nodes)
232
    {
233
        foreach ($nodes->getRowsHash() as $node => $text) {
234
            $this->theJsonNodeShouldContain($node, $text);
235
        }
236
    }
237
238
    /**
239
     * Checks, that given JSON node does not contain given value
240
     *
241
     * @Then the JSON node :node should not contain :text
242
     */
243 View Code Duplication
    public function theJsonNodeShouldNotContain($node, $text)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
244
    {
245
        $json = $this->getJson();
246
247
        $actual = $this->inspector->evaluate($json, $node);
248
249
        $this->assertNotContains($text, (string) $actual);
250
    }
251
252
    /**
253
     * Checks, that given JSON nodes does not contain given value
254
     *
255
     * @Then the JSON nodes should not contain:
256
     */
257
    public function theJsonNodesShoudNotContain(TableNode $nodes)
258
    {
259
        foreach ($nodes->getRowsHash() as $node => $text) {
260
            $this->theJsonNodeShouldNotContain($node, $text);
261
        }
262
    }
263
264
    /**
265
     * Checks, that given JSON node exist
266
     *
267
     * @Given the JSON node :name should exist
268
     */
269
    public function theJsonNodeShouldExist($name)
270
    {
271
        $json = $this->getJson();
272
273
        try {
274
            $node = $this->inspector->evaluate($json, $name);
275
        }
276
        catch (\Exception $e) {
277
            throw new \Exception("The node '$name' does not exist.");
278
        }
279
        return $node;
280
    }
281
282
    /**
283
     * Checks, that given JSON node does not exist
284
     *
285
     * @Given the JSON node :name should not exist
286
     */
287
    public function theJsonNodeShouldNotExist($name)
288
    {
289
        $this->not(function () use($name) {
290
            return $this->theJsonNodeShouldExist($name);
291
        }, "The node '$name' exists.");
292
    }
293
294
    /**
295
     * @Then the JSON should be valid according to this schema:
296
     */
297
    public function theJsonShouldBeValidAccordingToThisSchema(PyStringNode $schema)
298
    {
299
        $this->inspector->validate(
300
            $this->getJson(),
301
            new JsonSchema($schema)
302
        );
303
    }
304
305
    /**
306
     * @Then the JSON should be valid according to the schema :filename
307
     */
308
    public function theJsonShouldBeValidAccordingToTheSchema($filename)
309
    {
310
        $this->checkSchemaFile($filename);
311
312
        $this->inspector->validate(
313
            $this->getJson(),
314
            new JsonSchema(
315
                file_get_contents($filename),
316
                'file://' . getcwd() . '/' . $filename
317
            )
318
        );
319
    }
320
321
    /**
322
     * @Then the JSON should be invalid according to the schema :filename
323
     */
324
    public function theJsonShouldBeInvalidAccordingToTheSchema($filename)
325
    {
326
        $this->checkSchemaFile($filename);
327
328
        $this->not(function () use($filename) {
329
            return $this->theJsonShouldBeValidAccordingToTheSchema($filename);
330
        }, "The schema was valid");
331
    }
332
333
    /**
334
     * @Then the JSON should be equal to:
335
     */
336
    public function theJsonShouldBeEqualTo(PyStringNode $content)
337
    {
338
        $actual = $this->getJson();
339
340
        try {
341
            $expected = new Json($content);
342
        }
343
        catch (\Exception $e) {
344
            throw new \Exception('The expected JSON is not a valid');
345
        }
346
347
        $this->assertSame(
348
            (string) $expected,
349
            (string) $actual,
350
            "The json is equal to:\n". $actual->encode()
351
        );
352
    }
353
354
    /**
355
     * @Then print last JSON response
356
     */
357
    public function printLastJsonResponse()
358
    {
359
        echo $this->getJson()
360
            ->encode();
361
    }
362
363
    protected function getJson()
364
    {
365
        return new Json($this->httpCallResultPool->getResult()->getValue());
366
    }
367
368
    private function checkSchemaFile($filename)
369
    {
370
        if (false === is_file($filename)) {
371
            throw new \RuntimeException(
372
                'The JSON schema doesn\'t exist'
373
            );
374
        }
375
    }
376
}
377