Passed
Push — master ( 22caac...32dcd9 )
by San
59s
created

JsonContext::theJsonNodeShouldMatch()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 6

Duplication

Lines 12
Ratio 100 %

Importance

Changes 0
Metric Value
dl 12
loc 12
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 6
nc 2
nop 2
1
<?php
2
3
namespace Behatch\Context;
4
5
use Behat\Gherkin\Node\PyStringNode;
6
7
use Behat\Gherkin\Node\TableNode;
8
use Behat\Mink\Exception\ExpectationException;
9
use Behatch\Json\Json;
10
use Behatch\Json\JsonSchema;
11
use Behatch\Json\JsonInspector;
12
use Behatch\HttpCall\HttpCallResultPool;
13
14
class JsonContext extends BaseContext
15
{
16
    protected $inspector;
17
18
    protected $httpCallResultPool;
19
20
    public function __construct(HttpCallResultPool $httpCallResultPool, $evaluationMode = 'javascript')
21
    {
22
        $this->inspector = new JsonInspector($evaluationMode);
23
        $this->httpCallResultPool = $httpCallResultPool;
24
    }
25
26
    /**
27
     * Checks, that the response is correct JSON
28
     *
29
     * @Then the response should be in JSON
30
     */
31
    public function theResponseShouldBeInJson()
32
    {
33
        $this->getJson();
34
    }
35
36
    /**
37
     * Checks, that the response is not correct JSON
38
     *
39
     * @Then the response should not be in JSON
40
     */
41
    public function theResponseShouldNotBeInJson()
42
    {
43
        $this->not(
44
            [$this, 'theResponseShouldBeInJson'],
45
            'The response is in JSON'
46
        );
47
    }
48
49
    /**
50
     * Checks, that given JSON node is equal to given value
51
     *
52
     * @Then the JSON node :node should be equal to :text
53
     */
54 View Code Duplication
    public function theJsonNodeShouldBeEqualTo($node, $text)
55
    {
56
        $json = $this->getJson();
57
58
        $actual = $this->inspector->evaluate($json, $node);
59
60
        if ($actual != $text) {
61
            throw new \Exception(
62
                sprintf("The node value is '%s'", json_encode($actual))
63
            );
64
        }
65
    }
66
67
    /**
68
     * Checks, that given JSON nodes are equal to givens values
69
     *
70
     * @Then the JSON nodes should be equal to:
71
     */
72
    public function theJsonNodesShouldBeEqualTo(TableNode $nodes)
73
    {
74
        foreach ($nodes->getRowsHash() as $node => $text) {
75
            $this->theJsonNodeShouldBeEqualTo($node, $text);
76
        }
77
    }
78
79
    /**
80
     * Checks, that given JSON node matches given pattern
81
     *
82
     * @Then the JSON node :node should match :pattern
83
     */
84 View Code Duplication
    public function theJsonNodeShouldMatch($node, $pattern)
85
    {
86
        $json = $this->getJson();
87
88
        $actual = $this->inspector->evaluate($json, $node);
89
90
        if (preg_match($pattern, $actual) === 0) {
91
            throw new \Exception(
92
                sprintf("The node value is '%s'", json_encode($actual))
93
            );
94
        }
95
    }
96
97
    /**
98
     * Checks, that given JSON node is null
99
     *
100
     * @Then the JSON node :node should be null
101
     */
102
    public function theJsonNodeShouldBeNull($node)
103
    {
104
        $json = $this->getJson();
105
106
        $actual = $this->inspector->evaluate($json, $node);
107
108
        if (null !== $actual) {
109
            throw new \Exception(
110
                sprintf('The node value is `%s`', json_encode($actual))
111
            );
112
        }
113
    }
114
115
    /**
116
     * Checks, that given JSON node is not null.
117
     *
118
     * @Then the JSON node :node should not be null
119
     */
120
    public function theJsonNodeShouldNotBeNull($node)
121
    {
122
        $this->not(function () use ($node) {
123
            return $this->theJsonNodeShouldBeNull($node);
124
        }, sprintf('The node %s should not be null', $node));
125
    }
126
127
    /**
128
     * Checks, that given JSON node is true
129
     *
130
     * @Then the JSON node :node should be true
131
     */
132
    public function theJsonNodeShouldBeTrue($node)
133
    {
134
        $json = $this->getJson();
135
136
        $actual = $this->inspector->evaluate($json, $node);
137
138
        if (true !== $actual) {
139
            throw new \Exception(
140
                sprintf('The node value is `%s`', json_encode($actual))
141
            );
142
        }
143
    }
144
145
    /**
146
     * Checks, that given JSON node is false
147
     *
148
     * @Then the JSON node :node should be false
149
     */
150
    public function theJsonNodeShouldBeFalse($node)
151
    {
152
        $json = $this->getJson();
153
154
        $actual = $this->inspector->evaluate($json, $node);
155
156
        if (false !== $actual) {
157
            throw new \Exception(
158
                sprintf('The node value is `%s`', json_encode($actual))
159
            );
160
        }
161
    }
162
163
    /**
164
     * Checks, that given JSON node is equal to the given string
165
     *
166
     * @Then the JSON node :node should be equal to the string :text
167
     */
168 View Code Duplication
    public function theJsonNodeShouldBeEqualToTheString($node, $text)
169
    {
170
        $json = $this->getJson();
171
172
        $actual = $this->inspector->evaluate($json, $node);
173
174
        if ($actual !== $text) {
175
            throw new \Exception(
176
                sprintf('The node value is `%s`', json_encode($actual))
177
            );
178
        }
179
    }
180
181
    /**
182
     * Checks, that given JSON node is equal to the given number
183
     *
184
     * @Then the JSON node :node should be equal to the number :number
185
     */
186 View Code Duplication
    public function theJsonNodeShouldBeEqualToTheNumber($node, $number)
187
    {
188
        $json = $this->getJson();
189
190
        $actual = $this->inspector->evaluate($json, $node);
191
192
        if ($actual !== (float) $number && $actual !== (int) $number) {
193
            throw new \Exception(
194
                sprintf('The node value is `%s`', json_encode($actual))
195
            );
196
        }
197
    }
198
199
    /**
200
     * Checks, that given JSON node has N element(s)
201
     *
202
     * @Then the JSON node :node should have :count element(s)
203
     */
204
    public function theJsonNodeShouldHaveElements($node, $count)
205
    {
206
        $json = $this->getJson();
207
208
        $actual = $this->inspector->evaluate($json, $node);
209
210
        $this->assertSame($count, sizeof((array) $actual));
211
    }
212
213
    /**
214
     * Checks, that given JSON node contains given value
215
     *
216
     * @Then the JSON node :node should contain :text
217
     */
218 View Code Duplication
    public function theJsonNodeShouldContain($node, $text)
219
    {
220
        $json = $this->getJson();
221
222
        $actual = $this->inspector->evaluate($json, $node);
223
224
        $this->assertContains($text, (string) $actual);
225
    }
226
227
    /**
228
     * Checks, that given JSON nodes contains values
229
     *
230
     * @Then the JSON nodes should contain:
231
     */
232
    public function theJsonNodesShouldContain(TableNode $nodes)
233
    {
234
        foreach ($nodes->getRowsHash() as $node => $text) {
235
            $this->theJsonNodeShouldContain($node, $text);
236
        }
237
    }
238
239
    /**
240
     * Checks, that given JSON node does not contain given value
241
     *
242
     * @Then the JSON node :node should not contain :text
243
     */
244 View Code Duplication
    public function theJsonNodeShouldNotContain($node, $text)
245
    {
246
        $json = $this->getJson();
247
248
        $actual = $this->inspector->evaluate($json, $node);
249
250
        $this->assertNotContains($text, (string) $actual);
251
    }
252
253
    /**
254
     * Checks, that given JSON nodes does not contain given value
255
     *
256
     * @Then the JSON nodes should not contain:
257
     */
258
    public function theJsonNodesShouldNotContain(TableNode $nodes)
259
    {
260
        foreach ($nodes->getRowsHash() as $node => $text) {
261
            $this->theJsonNodeShouldNotContain($node, $text);
262
        }
263
    }
264
265
    /**
266
     * Checks, that given JSON node exist
267
     *
268
     * @Given the JSON node :name should exist
269
     */
270
    public function theJsonNodeShouldExist($name)
271
    {
272
        $json = $this->getJson();
273
274
        try {
275
            $node = $this->inspector->evaluate($json, $name);
276
        }
277
        catch (\Exception $e) {
278
            throw new \Exception("The node '$name' does not exist.");
279
        }
280
        return $node;
281
    }
282
283
    /**
284
     * Checks, that given JSON node does not exist
285
     *
286
     * @Given the JSON node :name should not exist
287
     */
288
    public function theJsonNodeShouldNotExist($name)
289
    {
290
        $this->not(function () use($name) {
291
            return $this->theJsonNodeShouldExist($name);
292
        }, "The node '$name' exists.");
293
    }
294
295
    /**
296
     * @Then the JSON should be valid according to this schema:
297
     */
298
    public function theJsonShouldBeValidAccordingToThisSchema(PyStringNode $schema)
299
    {
300
        $this->inspector->validate(
301
            $this->getJson(),
302
            new JsonSchema($schema)
303
        );
304
    }
305
306
    /**
307
     * @Then the JSON should be invalid according to this schema:
308
     */
309
    public function theJsonShouldBeInvalidAccordingToThisSchema(PyStringNode $schema)
310
    {
311
        $this->not(function() use($schema) {
312
            return $this->theJsonShouldBeValidAccordingToThisSchema($schema);
313
        }, 'Expected to receive invalid json, got valid one');
314
    }
315
316
    /**
317
     * @Then the JSON should be valid according to the schema :filename
318
     */
319
    public function theJsonShouldBeValidAccordingToTheSchema($filename)
320
    {
321
        $this->checkSchemaFile($filename);
322
323
        $this->inspector->validate(
324
            $this->getJson(),
325
            new JsonSchema(
326
                file_get_contents($filename),
327
                'file://' . realpath($filename)
328
            )
329
        );
330
    }
331
332
    /**
333
     * @Then the JSON should be invalid according to the schema :filename
334
     */
335
    public function theJsonShouldBeInvalidAccordingToTheSchema($filename)
336
    {
337
        $this->checkSchemaFile($filename);
338
339
        $this->not(function () use($filename) {
340
            return $this->theJsonShouldBeValidAccordingToTheSchema($filename);
341
        }, "The schema was valid");
342
    }
343
344
    /**
345
     * @Then the JSON should be equal to:
346
     */
347
    public function theJsonShouldBeEqualTo(PyStringNode $content)
348
    {
349
        $actual = $this->getJson();
350
351
        try {
352
            $expected = new Json($content);
353
        }
354
        catch (\Exception $e) {
355
            throw new \Exception('The expected JSON is not a valid');
356
        }
357
358
        $this->assertSame(
359
            (string) $expected,
360
            (string) $actual,
361
            "The json is equal to:\n". $actual->encode()
362
        );
363
    }
364
365
    /**
366
     * @Then print last JSON response
367
     */
368
    public function printLastJsonResponse()
369
    {
370
        echo $this->getJson()
371
            ->encode();
372
    }
373
374
    protected function getJson()
375
    {
376
        return new Json($this->httpCallResultPool->getResult()->getValue());
377
    }
378
379
    private function checkSchemaFile($filename)
380
    {
381
        if (false === is_file($filename)) {
382
            throw new \RuntimeException(
383
                'The JSON schema doesn\'t exist'
384
            );
385
        }
386
    }
387
}
388