Passed
Push — master ( 4ee9ec...849354 )
by San
04:18 queued 03:37
created

XmlContext   B

Complexity

Total Complexity 38

Size/Duplication

Total Lines 322
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 5

Importance

Changes 0
Metric Value
wmc 38
lcom 1
cbo 5
dl 0
loc 322
rs 8.3999
c 0
b 0
f 0

25 Methods

Rating   Name   Duplication   Size   Complexity  
A theResponseShouldBeInXml() 0 4 1
A theResponseShouldNotBeInXml() 0 7 1
A theXmlElementShouldExist() 0 11 2
A theXmlElementShouldNotExist() 0 6 1
A theXmlElementShouldBeEqualTo() 0 10 2
A theXmlElementShouldNotBeEqualTo() 0 6 1
A theXmlAttributeShouldExist() 0 12 2
A theXmlAttributeShouldNotExist() 0 4 1
A theXmlAttributeShouldBeEqualTo() 0 8 2
A theXmlAttributeShouldNotBeEqualTo() 0 8 2
A theXmlElementShouldHaveNChildElements() 0 13 4
A theXmlElementShouldContain() 0 6 1
A theXmlElementShouldNotContain() 0 6 1
A theXmlShouldUseTheNamespace() 0 9 2
A theXmlShouldNotUseTheNamespace() 0 9 2
A printLastXmlResponse() 0 4 1
A beforeScenario() 0 5 1
A theXmlFeedShouldBeValidAccordingToItsDtd() 0 9 2
A theXmlFeedShouldBeValidAccordingToTheXsd() 0 11 2
A theXmlFeedShouldBeValidAccordingToThisXsd() 0 5 1
A theXmlFeedShouldBeValidAccordingToTheRelaxNgSchema() 0 11 2
A theXmlFeedShouldBeValidAccordingToThisRelaxNgSchema() 0 5 1
A theAtomFeedShouldBeValid() 0 6 1
A theRss2FeedShouldBeValid() 0 6 1
A getDom() 0 6 1
1
<?php
2
3
namespace Behatch\Context;
4
5
use Behatch\Xml\Dom;
6
use Behat\Gherkin\Node\PyStringNode;
7
8
class XmlContext extends BaseContext
9
{
10
    /**
11
     * Checks that the response is correct XML
12
     *
13
     * @Then the response should be in XML
14
     */
15
    public function theResponseShouldBeInXml()
16
    {
17
        $this->getDom();
18
    }
19
20
    /**
21
     * Checks that the response is not correct XML
22
     *
23
     * @Then the response should not be in XML
24
     */
25
    public function theResponseShouldNotBeInXml()
26
    {
27
        $this->not(
28
            [$this, 'theResponseShouldBeInXml'],
29
            'The response is in XML'
30
        );
31
    }
32
33
    /**
34
     * Checks that the specified XML element exists
35
     *
36
     * @param string $element
37
     * @throws \Exception
38
     * @return \DomNodeList
39
     *
40
     * @Then the XML element :element should exist(s)
41
     */
42
    public function theXmlElementShouldExist($element)
43
    {
44
        $elements = $this->getDom()
45
            ->xpath($element);
46
47
        if ($elements->length == 0) {
48
            throw new \Exception("The element '$element' does not exist.");
49
        }
50
51
        return $elements;
52
    }
53
54
    /**
55
     * Checks that the specified XML element does not exist
56
     *
57
     * @Then the XML element :element should not exist(s)
58
     */
59
    public function theXmlElementShouldNotExist($element)
60
    {
61
        $this->not(function () use($element) {
62
            $this->theXmlElementShouldExist($element);
63
        }, "The element '$element' exists.");
64
    }
65
66
    /**
67
     * Checks that the specified XML element is equal to the given value
68
     *
69
     * @Then the XML element :element should be equal to :text
70
     */
71
    public function theXmlElementShouldBeEqualTo($element, $text)
72
    {
73
        $elements = $this->theXmlElementShouldExist($element);
74
75
        $actual = $elements->item(0)->nodeValue;
76
77
        if ($text != $actual) {
78
            throw new \Exception("The element value is '$actual'");
79
        }
80
    }
81
82
    /**
83
     * Checks that the specified XML element is not equal to the given value
84
     *
85
     * @Then the XML element :element should not be equal to :text
86
     */
87
    public function theXmlElementShouldNotBeEqualTo($element, $text)
88
    {
89
        $this->not(function () use($element, $text) {
90
            $this->theXmlElementShouldBeEqualTo($element, $text);
91
        }, "The element '$element' value is not '$text'");
92
    }
93
94
    /**
95
     * Checks that the XML attribute on the specified element exists
96
     *
97
     * @Then the XML attribute :attribute on element :element should exist(s)
98
     */
99
    public function theXmlAttributeShouldExist($attribute, $element)
100
    {
101
        $elements = $this->theXmlElementShouldExist("{$element}[@{$attribute}]");
102
103
        $actual = $elements->item(0)->getAttribute($attribute);
104
105
        if (empty($actual)) {
106
            throw new \Exception("The attribute value is '$actual'");
107
        }
108
109
        return $actual;
110
    }
111
112
    /**
113
     * Checks that the XML attribute on the specified element does not exist
114
     *
115
     * @Then the XML attribute :attribute on element :element should not exist(s)
116
     */
117
    public function theXmlAttributeShouldNotExist($attribute, $element)
118
    {
119
        $this->theXmlElementShouldNotExist("{$element}[@{$attribute}]");
120
    }
121
122
    /**
123
     * Checks that the XML attribute on the specified element is equal to the given value
124
     *
125
     * @Then the XML attribute :attribute on element :element should be equal to :text
126
     */
127
    public function theXmlAttributeShouldBeEqualTo($attribute, $element, $text)
128
    {
129
        $actual = $this->theXmlAttributeShouldExist($attribute, $element);
130
131
        if ($text != $actual) {
132
            throw new \Exception("The attribute value is '$actual'");
133
        }
134
    }
135
136
    /**
137
     * Checks that the XML attribute on the specified element is not equal to the given value
138
     *
139
     * @Then the XML attribute :attribute on element :element should not be equal to :text
140
     */
141
    public function theXmlAttributeShouldNotBeEqualTo($attribute, $element, $text)
142
    {
143
        $actual = $this->theXmlAttributeShouldExist($attribute, $element);
144
145
        if ($text === $actual) {
146
            throw new \Exception("The attribute value is '$actual'");
147
        }
148
    }
149
150
    /**
151
     * Checks that the given XML element has N child element(s)
152
     *
153
     * @Then the XML element :element should have :count element(s)
154
     */
155
    public function theXmlElementShouldHaveNChildElements($element, $count)
156
    {
157
        $elements = $this->theXmlElementShouldExist($element);
158
159
        $length = 0;
160
        foreach ($elements->item(0)->childNodes as $node) {
161
            if ($node->hasAttributes() || (trim($node->nodeValue) != '')) {
162
                ++$length;
163
            }
164
        }
165
166
        $this->assertEquals($count, $length);
167
    }
168
169
    /**
170
     * Checks that the given XML element contains the given value
171
     *
172
     * @Then the XML element :element should contain :text
173
     */
174
    public function theXmlElementShouldContain($element, $text)
175
    {
176
        $elements = $this->theXmlElementShouldExist($element);
177
178
        $this->assertContains($text, $elements->item(0)->nodeValue);
179
    }
180
181
    /**
182
     * Checks that the given XML element does not contain the given value
183
     *
184
     * @Then the XML element :element should not contain :text
185
     */
186
    public function theXmlElementShouldNotContain($element, $text)
187
    {
188
        $elements = $this->theXmlElementShouldExist($element);
189
190
        $this->assertNotContains($text, $elements->item(0)->nodeValue);
191
    }
192
193
    /**
194
     * Checks that the XML uses the specified namespace
195
     *
196
     * @Then the XML should use the namespace :namespace
197
     */
198
    public function theXmlShouldUseTheNamespace($namespace)
199
    {
200
        $namespaces = $this->getDom()
201
            ->getNamespaces();
202
203
        if (!in_array($namespace, $namespaces)) {
204
            throw new \Exception("The namespace '$namespace' is not used");
205
        }
206
    }
207
208
    /**
209
     * Checks that the XML does not use the specified namespace
210
     *
211
     * @Then the XML should not use the namespace :namespace
212
     */
213
    public function theXmlShouldNotUseTheNamespace($namespace)
214
    {
215
        $namespaces = $this->getDom()
216
            ->getNamespaces();
217
218
        if (in_array($namespace, $namespaces)) {
219
            throw new \Exception("The namespace '$namespace' is used");
220
        }
221
    }
222
223
    /**
224
     * Optimistically (ignoring errors) attempt to pretty-print the last XML response
225
     *
226
     * @Then print last XML response
227
     */
228
    public function printLastXmlResponse()
229
    {
230
        echo (string)$this->getDom();
231
    }
232
233
    /**
234
     * @BeforeScenario
235
     */
236
    public function beforeScenario()
237
    {
238
        libxml_clear_errors();
239
        libxml_use_internal_errors(true);
240
    }
241
242
    /**
243
     * @Then the XML feed should be valid according to its DTD
244
     */
245
    public function theXmlFeedShouldBeValidAccordingToItsDtd()
246
    {
247
        try {
248
            $this->getDom();
249
        }
250
        catch(\DOMException $e) {
251
            throw new \RuntimeException($e->getMessage());
252
        }
253
    }
254
255
    /**
256
     * @Then the XML feed should be valid according to the XSD :filename
257
     */
258
    public function theXmlFeedShouldBeValidAccordingToTheXsd($filename)
259
    {
260
        if (is_file($filename)) {
261
            $xsd = file_get_contents($filename);
262
            $this->getDom()
263
                ->validateXsd($xsd);
264
        }
265
        else {
266
            throw new \RuntimeException("The xsd doesn't exist");
267
        }
268
    }
269
270
    /**
271
     * @Then the XML feed should be valid according to this XSD:
272
     */
273
    public function theXmlFeedShouldBeValidAccordingToThisXsd(PyStringNode $xsd)
274
    {
275
        $this->getDom()
276
            ->validateXsd($xsd->getRaw());
277
    }
278
279
    /**
280
     * @Then the XML feed should be valid according to the relax NG schema :filename
281
     */
282
    public function theXmlFeedShouldBeValidAccordingToTheRelaxNgSchema($filename)
283
    {
284
        if (is_file($filename)) {
285
            $ng = file_get_contents($filename);
286
            $this->getDom()
287
                ->validateNg($ng);
288
        }
289
        else {
290
            throw new \RuntimeException("The relax NG doesn't exist");
291
        }
292
    }
293
294
    /**
295
     * @Then the XML feed should be valid according to this relax NG schema:
296
     */
297
    public function theXmlFeedShouldBeValidAccordingToThisRelaxNgSchema(PyStringNode $ng)
298
    {
299
        $this->getDom()
300
            ->validateNg($ng->getRaw());
301
    }
302
303
    /**
304
     * @Then the atom feed should be valid
305
     */
306
    public function theAtomFeedShouldBeValid()
307
    {
308
        $this->theXmlFeedShouldBeValidAccordingToTheXsd(
309
            __DIR__ . '/../Resources/schemas/atom.xsd'
310
        );
311
    }
312
313
    /**
314
     * @Then the RSS2 feed should be valid
315
     */
316
    public function theRss2FeedShouldBeValid()
317
    {
318
        $this->theXmlFeedShouldBeValidAccordingToTheXsd(
319
            __DIR__ . '/../Resources/schemas/rss-2.0.xsd'
320
        );
321
    }
322
323
    private function getDom()
324
    {
325
        $content = $this->getSession()->getPage()->getContent();
326
327
        return new Dom($content);
328
    }
329
}
330