Completed
Push — master ( a7ed36...5ca62b )
by Timothée
9s
created

JsonContext   A

Complexity

Total Complexity 30

Size/Duplication

Total Lines 266
Duplicated Lines 7.89 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

Changes 0
Metric Value
wmc 30
lcom 1
cbo 4
dl 21
loc 266
rs 10
c 0
b 0
f 0

22 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 1
A iLoadJson() 0 4 1
A responseShouldBeInJson() 0 4 1
A theJsonNodeShouldBeEqualTo() 0 7 1
A theJsonNodeShouldHaveElements() 0 7 1
A theJsonArrayNodeShouldContainElements() 7 7 1
A theJsonArrayNodeShouldNotContainElements() 0 7 1
A theJsonNodeShouldContain() 7 7 1
A theJsonNodeShouldNotContain() 7 7 1
A theJsonNodeShouldExist() 0 8 2
A theJsonNodeShouldNotExist() 0 18 3
A theJsonShouldBeValidAccordingToThisSchema() 0 11 1
A theJsonShouldBeValidAccordingToTheSchema() 0 10 1
A theJsonShouldBeEqualTo() 0 14 2
A theJsonPathExpressionShouldBeEqualToJson() 0 7 1
A theJsonExpressionShouldBeEqualTo() 0 4 1
A theJsonPathExpressionShouldHaveResult() 0 5 1
A theJsonPathExpressionShouldNotHaveResult() 0 5 1
A evaluateJsonNodeValue() 0 4 1
A readJson() 0 4 1
B resolveFilename() 0 24 4
A assert() 0 8 2

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
3
namespace Rezzza\RestApiBehatExtension\Json;
4
5
use mageekguy\atoum\asserter\generator as asserter;
6
use Behat\Behat\Context\Context;
7
use Behat\Behat\Context\SnippetAcceptingContext;
8
use Behat\Gherkin\Node\PyStringNode;
9
10
class JsonContext implements Context, SnippetAcceptingContext
0 ignored issues
show
Deprecated Code introduced by
The interface Behat\Behat\Context\SnippetAcceptingContext has been deprecated with message: will be removed in 4.0. Use --snippets-for CLI option instead

This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.

Loading history...
11
{
12
    private $jsonInspector;
13
14
    private $asserter;
15
16
    private $jsonSchemaBaseUrl;
17
18
    public function __construct(JsonInspector $jsonInspector, $jsonSchemaBaseUrl = null)
19
    {
20
        $this->jsonInspector = $jsonInspector;
21
        $this->asserter = new asserter;
22
        $this->jsonSchemaBaseUrl = rtrim($jsonSchemaBaseUrl, '/');
23
    }
24
25
    /**
26
     * @When /^I load JSON:$/
27
     */
28
    public function iLoadJson(PyStringNode $jsonContent)
29
    {
30
        $this->jsonInspector->writeJson((string) $jsonContent);
31
    }
32
33
    /**
34
     * @Then /^the response should be in JSON$/
35
     */
36
    public function responseShouldBeInJson()
37
    {
38
        $this->jsonInspector->readJson();
39
    }
40
41
    /**
42
     * @Then /^the JSON node "(?P<jsonNode>[^"]*)" should be equal to "(?P<expectedValue>.*)"$/
43
     */
44
    public function theJsonNodeShouldBeEqualTo($jsonNode, $expectedValue)
45
    {
46
        $this->assert(function () use ($jsonNode, $expectedValue) {
47
            $realValue = $this->evaluateJsonNodeValue($jsonNode);
48
            $this->asserter->variable($realValue)->isEqualTo($expectedValue);
49
        });
50
    }
51
52
    /**
53
     * @Then /^the JSON node "(?P<jsonNode>[^"]*)" should have (?P<expectedNth>\d+) elements?$/
54
     * @Then /^the JSON array node "(?P<jsonNode>[^"]*)" should have (?P<expectedNth>\d+) elements?$/
55
     */
56
    public function theJsonNodeShouldHaveElements($jsonNode, $expectedNth)
57
    {
58
        $this->assert(function () use ($jsonNode, $expectedNth) {
59
            $realValue = $this->evaluateJsonNodeValue($jsonNode);
60
            $this->asserter->phpArray($realValue)->hasSize($expectedNth);
61
        });
62
    }
63
64
    /**
65
     * @Then /^the JSON array node "(?P<jsonNode>[^"]*)" should contain "(?P<expectedValue>.*)" element$/
66
     */
67 View Code Duplication
    public function theJsonArrayNodeShouldContainElements($jsonNode, $expectedValue)
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...
68
    {
69
        $this->assert(function () use ($jsonNode, $expectedValue) {
70
            $realValue = $this->evaluateJsonNodeValue($jsonNode);
71
            $this->asserter->phpArray($realValue)->contains($expectedValue);
72
        });
73
    }
74
75
    /**
76
     * @Then /^the JSON array node "(?P<jsonNode>[^"]*)" should not contain "(?P<expectedValue>.*)" element$/
77
     */
78
    public function theJsonArrayNodeShouldNotContainElements($jsonNode, $expectedValue)
79
    {
80
        $this->assert(function () use ($jsonNode, $expectedValue) {
81
            $realValue = $this->evaluateJsonNodeValue($jsonNode);
82
            $this->asserter->phpArray($realValue)->notContains($expectedValue);
83
        });
84
    }
85
86
    /**
87
     * @Then /^the JSON node "(?P<jsonNode>[^"]*)" should contain "(?P<expectedValue>.*)"$/
88
     */
89 View Code Duplication
    public function theJsonNodeShouldContain($jsonNode, $expectedValue)
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...
90
    {
91
        $this->assert(function () use ($jsonNode, $expectedValue) {
92
            $realValue = $this->evaluateJsonNodeValue($jsonNode);
93
            $this->asserter->string((string) $realValue)->contains($expectedValue);
94
        });
95
    }
96
97
    /**
98
     * Checks, that given JSON node does not contain given value
99
     *
100
     * @Then /^the JSON node "(?P<jsonNode>[^"]*)" should not contain "(?P<unexpectedValue>.*)"$/
101
     */
102 View Code Duplication
    public function theJsonNodeShouldNotContain($jsonNode, $unexpectedValue)
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...
103
    {
104
        $this->assert(function () use ($jsonNode, $unexpectedValue) {
105
            $realValue = $this->evaluateJsonNodeValue($jsonNode);
106
            $this->asserter->string((string) $realValue)->notContains($unexpectedValue);
107
        });
108
    }
109
110
    /**
111
     * Checks, that given JSON node exist
112
     *
113
     * @Given /^the JSON node "(?P<jsonNode>[^"]*)" should exist$/
114
     */
115
    public function theJsonNodeShouldExist($jsonNode)
116
    {
117
        try {
118
            $this->evaluateJsonNodeValue($jsonNode);
119
        } catch (\Exception $e) {
120
            throw new WrongJsonExpectation(sprintf("The node '%s' does not exist.", $jsonNode), $this->readJson(), $e);
121
        }
122
    }
123
124
    /**
125
     * Checks, that given JSON node does not exist
126
     *
127
     * @Given /^the JSON node "(?P<jsonNode>[^"]*)" should not exist$/
128
     */
129
    public function theJsonNodeShouldNotExist($jsonNode)
130
    {
131
        $e = null;
132
133
        try {
134
            $realValue = $this->evaluateJsonNodeValue($jsonNode);
135
        } catch (\Exception $e) {
136
            // If the node does not exist an exception should be throwed
137
        }
138
139
        if ($e === null) {
140
            throw new WrongJsonExpectation(
141
                sprintf("The node '%s' exists and contains '%s'.", $jsonNode, json_encode($realValue)),
142
                $this->readJson(),
143
                $e
144
            );
145
        }
146
    }
147
148
    /**
149
     * @Then /^the JSON should be valid according to this schema:$/
150
     */
151
    public function theJsonShouldBeValidAccordingToThisSchema(PyStringNode $jsonSchemaContent)
152
    {
153
        $tempFilename = tempnam(sys_get_temp_dir(), 'rae');
154
        file_put_contents($tempFilename, $jsonSchemaContent);
155
        $this->assert(function () use ($tempFilename) {
156
            $this->jsonInspector->validateJson(
157
                new JsonSchema($tempFilename)
158
            );
159
        });
160
        unlink($tempFilename);
161
    }
162
163
    /**
164
     * @Then /^the JSON should be valid according to the schema "(?P<filename>[^"]*)"$/
165
     */
166
    public function theJsonShouldBeValidAccordingToTheSchema($filename)
167
    {
168
        $filename = $this->resolveFilename($filename);
169
170
        $this->assert(function () use ($filename) {
171
            $this->jsonInspector->validateJson(
172
                new JsonSchema($filename)
173
            );
174
        });
175
    }
176
177
    /**
178
     * @Then /^the JSON should be equal to:$/
179
     */
180
    public function theJsonShouldBeEqualTo(PyStringNode $jsonContent)
181
    {
182
        $realJsonValue = $this->readJson();
183
184
        try {
185
            $expectedJsonValue = new Json($jsonContent);
186
        } catch (\Exception $e) {
187
            throw new \Exception('The expected JSON is not a valid');
188
        }
189
190
        $this->assert(function () use ($realJsonValue, $expectedJsonValue) {
191
            $this->asserter->castToString($realJsonValue)->isEqualTo((string) $expectedJsonValue);
192
        });
193
    }
194
195
    /**
196
     * @Then the JSON path expression :pathExpression should be equal to json :expectedJson
197
     */
198
    public function theJsonPathExpressionShouldBeEqualToJson($pathExpression, $expectedJson)
199
    {
200
        $expectedJson = new Json($expectedJson);
201
        $actualJson = Json::fromRawContent($this->jsonInspector->searchJsonPath($pathExpression));
202
203
        $this->asserter->castToString($actualJson)->isEqualTo((string) $expectedJson);
204
    }
205
206
    /**
207
     * @Then the JSON path expression :pathExpression should be equal to:
208
     */
209
    public function theJsonExpressionShouldBeEqualTo($pathExpression, PyStringNode $expectedJson)
210
    {
211
        $this->theJsonPathExpressionShouldBeEqualToJson($pathExpression, (string) $expectedJson);
212
    }
213
214
    /**
215
     * @Then the JSON path expression :pathExpression should have result
216
     */
217
    public function theJsonPathExpressionShouldHaveResult($pathExpression)
218
    {
219
        $json = $this->jsonInspector->searchJsonPath($pathExpression);
220
        $this->asserter->variable($json)->isNotNull();
221
    }
222
223
    /**
224
     * @Then the JSON path expression :pathExpression should not have result
225
     */
226
    public function theJsonPathExpressionShouldNotHaveResult($pathExpression)
227
    {
228
        $json = $this->jsonInspector->searchJsonPath($pathExpression);
229
        $this->asserter->variable($json)->isNull();
230
    }
231
232
    private function evaluateJsonNodeValue($jsonNode)
233
    {
234
        return $this->jsonInspector->readJsonNodeValue($jsonNode);
235
    }
236
237
    private function readJson()
238
    {
239
        return $this->jsonInspector->readJson();
240
    }
241
242
    private function resolveFilename($filename)
243
    {
244
        if (true === is_file($filename)) {
245
            return realpath($filename);
246
        }
247
248
        if (null === $this->jsonSchemaBaseUrl) {
249
            throw new \RuntimeException(sprintf(
250
                'The JSON schema file "%s" doesn\'t exist',
251
                $filename
252
            ));
253
        }
254
255
        $filename = $this->jsonSchemaBaseUrl . '/' . $filename;
256
257
        if (false === is_file($filename)) {
258
            throw new \RuntimeException(sprintf(
259
                'The JSON schema file "%s" doesn\'t exist',
260
                $filename
261
            ));
262
        }
263
264
        return realpath($filename);
265
    }
266
267
    private function assert(callable $assertion)
268
    {
269
        try {
270
            $assertion();
271
        } catch (\Exception $e) {
272
            throw new WrongJsonExpectation($e->getMessage(), $this->readJson(), $e);
273
        }
274
    }
275
}
276