Completed
Push — master ( a33641...7233dc )
by San
02:42
created

JsonContext::theJsonNodesShoudBeEqualTo()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 8
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 5
nc 1
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 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
    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 is null
81
     *
82
     * @Then the JSON node :node should be null
83
     */
84
    public function theJsonNodeShouldBeNull($node)
85
    {
86
        $json = $this->getJson();
87
88
        $actual = $this->inspector->evaluate($json, $node);
89
90
        if (null !== $actual) {
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 not null.
99
     *
100
     * @Then the JSON node :node should not be null
101
     */
102
    public function theJsonNodeShouldNotBeNull($node)
103
    {
104
        $this->not(function () use ($node) {
105
            return $this->theJsonNodeShouldBeNull($node);
106
        }, sprintf('The node %s should not be null', $node));
107
    }
108
109
    /**
110
     * Checks, that given JSON node is true
111
     *
112
     * @Then the JSON node :node should be true
113
     */
114
    public function theJsonNodeShouldBeTrue($node)
115
    {
116
        $json = $this->getJson();
117
118
        $actual = $this->inspector->evaluate($json, $node);
119
120
        if (true !== $actual) {
121
            throw new \Exception(
122
                sprintf('The node value is `%s`', json_encode($actual))
123
            );
124
        }
125
    }
126
127
    /**
128
     * Checks, that given JSON node is false
129
     *
130
     * @Then the JSON node :node should be false
131
     */
132
    public function theJsonNodeShouldBeFalse($node)
133
    {
134
        $json = $this->getJson();
135
136
        $actual = $this->inspector->evaluate($json, $node);
137
138
        if (false !== $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 equal to the given string
147
     *
148
     * @Then the JSON node :node should be equal to the string :text
149
     */
150 View Code Duplication
    public function theJsonNodeShouldBeEqualToTheString($node, $text)
151
    {
152
        $json = $this->getJson();
153
154
        $actual = $this->inspector->evaluate($json, $node);
155
156
        if ($actual !== $text) {
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 number
165
     *
166
     * @Then the JSON node :node should be equal to the number :number
167
     */
168 View Code Duplication
    public function theJsonNodeShouldBeEqualToTheNumber($node, $number)
169
    {
170
        $json = $this->getJson();
171
172
        $actual = $this->inspector->evaluate($json, $node);
173
174
        if ($actual !== (float) $number && $actual !== (int) $number) {
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 has N element(s)
183
     *
184
     * @Then the JSON node :node should have :count element(s)
185
     */
186
    public function theJsonNodeShouldHaveElements($node, $count)
187
    {
188
        $json = $this->getJson();
189
190
        $actual = $this->inspector->evaluate($json, $node);
191
192
        $this->assertSame($count, sizeof((array) $actual));
193
    }
194
195
    /**
196
     * Checks, that given JSON node contains given value
197
     *
198
     * @Then the JSON node :node should contain :text
199
     */
200 View Code Duplication
    public function theJsonNodeShouldContain($node, $text)
201
    {
202
        $json = $this->getJson();
203
204
        $actual = $this->inspector->evaluate($json, $node);
205
206
        $this->assertContains($text, (string) $actual);
207
    }
208
209
    /**
210
     * Checks, that given JSON nodes contains values
211
     *
212
     * @Then the JSON nodes should contain:
213
     */
214
    public function theJsonNodesShouldContain(TableNode $nodes)
215
    {
216
        foreach ($nodes->getRowsHash() as $node => $text) {
217
            $this->theJsonNodeShouldContain($node, $text);
218
        }
219
    }
220
221
    /**
222
     * Checks, that given JSON node does not contain given value
223
     *
224
     * @Then the JSON node :node should not contain :text
225
     */
226 View Code Duplication
    public function theJsonNodeShouldNotContain($node, $text)
227
    {
228
        $json = $this->getJson();
229
230
        $actual = $this->inspector->evaluate($json, $node);
231
232
        $this->assertNotContains($text, (string) $actual);
233
    }
234
235
    /**
236
     * Checks, that given JSON nodes does not contain given value
237
     *
238
     * @Then the JSON nodes should not contain:
239
     */
240
    public function theJsonNodesShouldNotContain(TableNode $nodes)
241
    {
242
        foreach ($nodes->getRowsHash() as $node => $text) {
243
            $this->theJsonNodeShouldNotContain($node, $text);
244
        }
245
    }
246
247
    /**
248
     * Checks, that given JSON node exist
249
     *
250
     * @Given the JSON node :name should exist
251
     */
252
    public function theJsonNodeShouldExist($name)
253
    {
254
        $json = $this->getJson();
255
256
        try {
257
            $node = $this->inspector->evaluate($json, $name);
258
        }
259
        catch (\Exception $e) {
260
            throw new \Exception("The node '$name' does not exist.");
261
        }
262
        return $node;
263
    }
264
265
    /**
266
     * Checks, that given JSON node does not exist
267
     *
268
     * @Given the JSON node :name should not exist
269
     */
270
    public function theJsonNodeShouldNotExist($name)
271
    {
272
        $this->not(function () use($name) {
273
            return $this->theJsonNodeShouldExist($name);
274
        }, "The node '$name' exists.");
275
    }
276
277
    /**
278
     * @Then the JSON should be valid according to this schema:
279
     */
280
    public function theJsonShouldBeValidAccordingToThisSchema(PyStringNode $schema)
281
    {
282
        $this->inspector->validate(
283
            $this->getJson(),
284
            new JsonSchema($schema)
285
        );
286
    }
287
288
    /**
289
     * @Then the JSON should be invalid according to this schema:
290
     */
291
    public function theJsonShouldBeInvalidAccordingToThisSchema(PyStringNode $schema)
292
    {
293
        $this->not(function() use($schema) {
294
            return $this->theJsonShouldBeValidAccordingToThisSchema($schema);
295
        }, 'Expected to receive invalid json, got valid one');
296
    }
297
298
    /**
299
     * @Then the JSON should be valid according to the schema :filename
300
     */
301
    public function theJsonShouldBeValidAccordingToTheSchema($filename)
302
    {
303
        $this->checkSchemaFile($filename);
304
305
        $this->inspector->validate(
306
            $this->getJson(),
307
            new JsonSchema(
308
                file_get_contents($filename),
309
                'file://' . realpath($filename)
310
            )
311
        );
312
    }
313
314
    /**
315
     * @Then the JSON should be invalid according to the schema :filename
316
     */
317
    public function theJsonShouldBeInvalidAccordingToTheSchema($filename)
318
    {
319
        $this->checkSchemaFile($filename);
320
321
        $this->not(function () use($filename) {
322
            return $this->theJsonShouldBeValidAccordingToTheSchema($filename);
323
        }, "The schema was valid");
324
    }
325
326
    /**
327
     * @Then the JSON should be equal to:
328
     */
329
    public function theJsonShouldBeEqualTo(PyStringNode $content)
330
    {
331
        $actual = $this->getJson();
332
333
        try {
334
            $expected = new Json($content);
335
        }
336
        catch (\Exception $e) {
337
            throw new \Exception('The expected JSON is not a valid');
338
        }
339
340
        $this->assertSame(
341
            (string) $expected,
342
            (string) $actual,
343
            "The json is equal to:\n". $actual->encode()
344
        );
345
    }
346
347
    /**
348
     * @Then print last JSON response
349
     */
350
    public function printLastJsonResponse()
351
    {
352
        echo $this->getJson()
353
            ->encode();
354
    }
355
356
    protected function getJson()
357
    {
358
        return new Json($this->httpCallResultPool->getResult()->getValue());
359
    }
360
361
    private function checkSchemaFile($filename)
362
    {
363
        if (false === is_file($filename)) {
364
            throw new \RuntimeException(
365
                'The JSON schema doesn\'t exist'
366
            );
367
        }
368
    }
369
}
370