Passed
Push — master ( fc1073...86d0b7 )
by San
02:40
created

JsonContext::theJsonNodesShouldContain()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 6
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 3
nc 2
nop 1
1
<?php
2
3
namespace Behatch\Context;
4
5
use Behat\Gherkin\Node\PyStringNode;
6
7
use Behat\Gherkin\Node\TableNode;
8
use Behatch\Json\Json;
9
use Behatch\Json\JsonSchema;
10
use Behatch\Json\JsonInspector;
11
use 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 nodes are equal to givens values
68
     *
69
     * @Then the JSON nodes should be equal to:
70
     */
71
    public function theJsonNodesShouldBeEqualTo(TableNode $nodes)
72
    {
73
        foreach ($nodes->getRowsHash() as $node => $text) {
74
            $this->theJsonNodeShouldBeEqualTo($node, $text);
75
        }
76
    }
77
78
    public function theJsonNodesShoudBeEqualTo(TableNode $nodes)
79
    {
80
        trigger_error(
81
            sprintf('The %s function is deprecated since version 2.7 and will be removed in 3.0. Use the %s::theJsonNodesShouldBeEqualTo function instead.', __METHOD__, __CLASS__),
82
            E_USER_DEPRECATED
83
        );
84
        return $this->theJsonNodesShouldBeEqualTo($nodes);
85
    }
86
87
    /**
88
     * Checks, that given JSON node is null
89
     *
90
     * @Then the JSON node :node should be null
91
     */
92
    public function theJsonNodeShouldBeNull($node)
93
    {
94
        $json = $this->getJson();
95
96
        $actual = $this->inspector->evaluate($json, $node);
97
98
        if (null !== $actual) {
99
            throw new \Exception(
100
                sprintf('The node value is `%s`', json_encode($actual))
101
            );
102
        }
103
    }
104
105
    /**
106
     * Checks, that given JSON node is not null.
107
     *
108
     * @Then the JSON node :node should not be null
109
     */
110
    public function theJsonNodeShouldNotBeNull($name)
111
    {
112
        $this->not(function () use ($name) {
113
            return $this->theJsonNodeShouldBeNull($name);
114
        }, sprintf('The node %s should not be null', $name));
115
    }
116
117
    /**
118
     * Checks, that given JSON node is true
119
     *
120
     * @Then the JSON node :node should be true
121
     */
122
    public function theJsonNodeShouldBeTrue($node)
123
    {
124
        $json = $this->getJson();
125
126
        $actual = $this->inspector->evaluate($json, $node);
127
128
        if (true !== $actual) {
129
            throw new \Exception(
130
                sprintf('The node value is `%s`', json_encode($actual))
131
            );
132
        }
133
    }
134
135
    /**
136
     * Checks, that given JSON node is false
137
     *
138
     * @Then the JSON node :node should be false
139
     */
140
    public function theJsonNodeShouldBeFalse($node)
141
    {
142
        $json = $this->getJson();
143
144
        $actual = $this->inspector->evaluate($json, $node);
145
146
        if (false !== $actual) {
147
            throw new \Exception(
148
                sprintf('The node value is `%s`', json_encode($actual))
149
            );
150
        }
151
    }
152
153
    /**
154
     * Checks, that given JSON node is equal to the given string
155
     *
156
     * @Then the JSON node :node should be equal to the string :text
157
     */
158 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...
159
    {
160
        $json = $this->getJson();
161
162
        $actual = $this->inspector->evaluate($json, $node);
163
164
        if ($actual !== $text) {
165
            throw new \Exception(
166
                sprintf('The node value is `%s`', json_encode($actual))
167
            );
168
        }
169
    }
170
171
    /**
172
     * Checks, that given JSON node is equal to the given number
173
     *
174
     * @Then the JSON node :node should be equal to the number :number
175
     */
176 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...
177
    {
178
        $json = $this->getJson();
179
180
        $actual = $this->inspector->evaluate($json, $node);
181
182
        if ($actual !== (float) $number && $actual !== (int) $number) {
183
            throw new \Exception(
184
                sprintf('The node value is `%s`', json_encode($actual))
185
            );
186
        }
187
    }
188
189
    /**
190
     * Checks, that given JSON node has N element(s)
191
     *
192
     * @Then the JSON node :node should have :count element(s)
193
     */
194
    public function theJsonNodeShouldHaveElements($node, $count)
195
    {
196
        $json = $this->getJson();
197
198
        $actual = $this->inspector->evaluate($json, $node);
199
200
        $this->assertSame($count, sizeof((array) $actual));
201
    }
202
203
    /**
204
     * Checks, that given JSON node contains given value
205
     *
206
     * @Then the JSON node :node should contain :text
207
     */
208 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...
209
    {
210
        $json = $this->getJson();
211
212
        $actual = $this->inspector->evaluate($json, $node);
213
214
        $this->assertContains($text, (string) $actual);
215
    }
216
217
    /**
218
     * Checks, that given JSON nodes contains values
219
     *
220
     * @Then the JSON nodes should contain:
221
     */
222
    public function theJsonNodesShouldContain(TableNode $nodes)
223
    {
224
        foreach ($nodes->getRowsHash() as $node => $text) {
225
            $this->theJsonNodeShouldContain($node, $text);
226
        }
227
    }
228
229
    public function theJsonNodesShoudContain(TableNode $nodes)
230
    {
231
        trigger_error(
232
            sprintf('The %s function is deprecated since version 2.7 and will be removed in 3.0. Use the %s::theJsonNodesShouldContain function instead.', __METHOD__, __CLASS__),
233
            E_USER_DEPRECATED
234
        );
235
        return $this->theJsonNodesShouldBeEqualTo($nodes);
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 theJsonNodesShouldNotContain(TableNode $nodes)
258
    {
259
        foreach ($nodes->getRowsHash() as $node => $text) {
260
            $this->theJsonNodeShouldNotContain($node, $text);
261
        }
262
    }
263
264
    public function theJsonNodesShoudNotContain(TableNode $nodes)
265
    {
266
        trigger_error(
267
            sprintf('The %s function is deprecated since version 2.7 and will be removed in 3.0. Use the %s::theJsonNodesShouldNotContain function instead.', __METHOD__, __CLASS__),
268
            E_USER_DEPRECATED
269
        );
270
        return $this->theJsonNodesShouldBeEqualTo($nodes);
271
    }
272
273
    /**
274
     * Checks, that given JSON node exist
275
     *
276
     * @Given the JSON node :name should exist
277
     */
278
    public function theJsonNodeShouldExist($name)
279
    {
280
        $json = $this->getJson();
281
282
        try {
283
            $node = $this->inspector->evaluate($json, $name);
284
        }
285
        catch (\Exception $e) {
286
            throw new \Exception("The node '$name' does not exist.");
287
        }
288
        return $node;
289
    }
290
291
    /**
292
     * Checks, that given JSON node does not exist
293
     *
294
     * @Given the JSON node :name should not exist
295
     */
296
    public function theJsonNodeShouldNotExist($name)
297
    {
298
        $this->not(function () use($name) {
299
            return $this->theJsonNodeShouldExist($name);
300
        }, "The node '$name' exists.");
301
    }
302
303
    /**
304
     * @Then the JSON should be valid according to this schema:
305
     */
306
    public function theJsonShouldBeValidAccordingToThisSchema(PyStringNode $schema)
307
    {
308
        $this->inspector->validate(
309
            $this->getJson(),
310
            new JsonSchema($schema)
311
        );
312
    }
313
314
    /**
315
     * @Then the JSON should be valid according to the schema :filename
316
     */
317
    public function theJsonShouldBeValidAccordingToTheSchema($filename)
318
    {
319
        $this->checkSchemaFile($filename);
320
321
        $this->inspector->validate(
322
            $this->getJson(),
323
            new JsonSchema(
324
                file_get_contents($filename),
325
                'file://' . getcwd() . '/' . $filename
326
            )
327
        );
328
    }
329
330
    /**
331
     * @Then the JSON should be invalid according to the schema :filename
332
     */
333
    public function theJsonShouldBeInvalidAccordingToTheSchema($filename)
334
    {
335
        $this->checkSchemaFile($filename);
336
337
        $this->not(function () use($filename) {
338
            return $this->theJsonShouldBeValidAccordingToTheSchema($filename);
339
        }, "The schema was valid");
340
    }
341
342
    /**
343
     * @Then the JSON should be equal to:
344
     */
345
    public function theJsonShouldBeEqualTo(PyStringNode $content)
346
    {
347
        $actual = $this->getJson();
348
349
        try {
350
            $expected = new Json($content);
351
        }
352
        catch (\Exception $e) {
353
            throw new \Exception('The expected JSON is not a valid');
354
        }
355
356
        $this->assertSame(
357
            (string) $expected,
358
            (string) $actual,
359
            "The json is equal to:\n". $actual->encode()
360
        );
361
    }
362
363
    /**
364
     * @Then print last JSON response
365
     */
366
    public function printLastJsonResponse()
367
    {
368
        echo $this->getJson()
369
            ->encode();
370
    }
371
372
    protected function getJson()
373
    {
374
        return new Json($this->httpCallResultPool->getResult()->getValue());
375
    }
376
377
    private function checkSchemaFile($filename)
378
    {
379
        if (false === is_file($filename)) {
380
            throw new \RuntimeException(
381
                'The JSON schema doesn\'t exist'
382
            );
383
        }
384
    }
385
}
386