Skip to content

Commit 6f372a6

Browse files
committed
Added XmlMatcher
1 parent d21c4d4 commit 6f372a6

File tree

5 files changed

+267
-3
lines changed

5 files changed

+267
-3
lines changed

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@
1818
"coduo/php-to-string": "~1.0",
1919
"symfony/property-access": "~2.3",
2020
"symfony/expression-language": "~2.4",
21-
"doctrine/lexer": "1.0.*"
21+
"doctrine/lexer": "1.0.*",
22+
"openlss/lib-array2xml": "0.0.9"
2223
},
2324
"require-dev": {
2425
"phpunit/phpunit": "3.7.*"

src/Coduo/PHPMatcher/Factory/SimpleFactory.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ protected function buildMatchers()
2828
return new Matcher\ChainMatcher(array(
2929
$scalarMatchers,
3030
$arrayMatcher,
31-
new Matcher\JsonMatcher($arrayMatcher)
31+
new Matcher\JsonMatcher($arrayMatcher),
32+
new Matcher\XmlMatcher($arrayMatcher)
3233
));
3334
}
3435

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
<?php
2+
3+
namespace Coduo\PHPMatcher\Matcher;
4+
5+
use LSS\XML2Array;
6+
7+
class XmlMatcher extends Matcher
8+
{
9+
/**
10+
* @var
11+
*/
12+
private $matcher;
13+
14+
/**
15+
* @param ValueMatcher $matcher
16+
*/
17+
public function __construct(ValueMatcher $matcher)
18+
{
19+
$this->matcher = $matcher;
20+
}
21+
22+
/**
23+
* {@inheritDoc}
24+
*/
25+
public function match($value, $pattern)
26+
{
27+
if (!is_string($value) || !$this->isValidXml($value) || !$this->isValidXml($pattern)) {
28+
return false;
29+
}
30+
31+
$arrayValue = XML2Array::createArray($value);
32+
$arrayPattern = XML2Array::createArray($pattern);
33+
34+
$match = $this->matcher->match($arrayValue, $arrayPattern);
35+
if (!$match) {
36+
$this->error = $this->matcher->getError();
37+
return false;
38+
}
39+
40+
return true;
41+
}
42+
43+
/**
44+
* {@inheritDoc}
45+
*/
46+
public function canMatch($pattern)
47+
{
48+
if (!is_string($pattern)) {
49+
return false;
50+
}
51+
52+
return $this->isValidXml($pattern);
53+
}
54+
55+
private function isValidXml($string)
56+
{
57+
$xml = @simplexml_load_string($string);
58+
59+
if (!$xml instanceof \SimpleXMLElement) {
60+
61+
return false;
62+
}
63+
64+
return true;
65+
}
66+
}
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
<?php
2+
3+
namespace Coduo\PHPMatcher\Tests\Matcher;
4+
5+
use Coduo\PHPMatcher\Lexer;
6+
use Coduo\PHPMatcher\Matcher;
7+
use Coduo\PHPMatcher\Parser;
8+
9+
class XmlMatcherTest extends \PHPUnit_Framework_TestCase
10+
{
11+
/**
12+
* @var Matcher\XmlMatcher
13+
*/
14+
private $matcher;
15+
16+
public function setUp()
17+
{
18+
$parser = new Parser(new Lexer());
19+
$scalarMatchers = new Matcher\ChainMatcher(array(
20+
new Matcher\CallbackMatcher(),
21+
new Matcher\ExpressionMatcher(),
22+
new Matcher\NullMatcher(),
23+
new Matcher\StringMatcher($parser),
24+
new Matcher\IntegerMatcher($parser),
25+
new Matcher\BooleanMatcher(),
26+
new Matcher\DoubleMatcher($parser),
27+
new Matcher\NumberMatcher(),
28+
new Matcher\ScalarMatcher(),
29+
new Matcher\WildcardMatcher(),
30+
));
31+
32+
$this->matcher = new Matcher\XmlMatcher(
33+
new Matcher\ChainMatcher(array(
34+
$scalarMatchers,
35+
new Matcher\ArrayMatcher($scalarMatchers, $parser)
36+
)
37+
));
38+
}
39+
40+
/**
41+
* @dataProvider positivePatterns
42+
*/
43+
public function test_positive_can_match($pattern)
44+
{
45+
$this->assertTrue($this->matcher->canMatch($pattern));
46+
}
47+
48+
/**
49+
* @dataProvider negativePatterns
50+
*/
51+
public function test_negative_can_match($pattern)
52+
{
53+
$this->assertFalse($this->matcher->canMatch($pattern));
54+
}
55+
56+
/**
57+
* @dataProvider positiveMatches
58+
*/
59+
public function test_positive_matches($value, $pattern)
60+
{
61+
$this->assertTrue($this->matcher->match($value, $pattern), $this->matcher->getError());
62+
}
63+
64+
/**
65+
* @dataProvider negativeMatches
66+
*/
67+
public function test_negative_matches($value, $pattern)
68+
{
69+
$this->assertFalse($this->matcher->match($value, $pattern), $this->matcher->getError());
70+
71+
}
72+
73+
public static function positivePatterns()
74+
{
75+
return array(
76+
array('<xml></xml>'),
77+
array('<users><user>@string@</user></users>'),
78+
);
79+
}
80+
81+
public static function negativePatterns()
82+
{
83+
return array(
84+
array('<xml '),
85+
array('asdkasdasdqwrq'),
86+
);
87+
}
88+
89+
public static function positiveMatches()
90+
{
91+
return array(
92+
array(
93+
'<users><user>Norbert</user><user>Michał</user></users>',
94+
'<users><user>@string@</user><user>@string@</user></users>'
95+
),
96+
array(
97+
'<users><user id="1">Norbert</user></users>',
98+
'<users><user id="@string@">@string@</user></users>'
99+
),
100+
array(
101+
'<users><user><name>Norbert</name><age>25</age></user></users>',
102+
'<users><user><name>Norbert</name><age>@string@</age></user></users>'
103+
),
104+
array(
105+
'<string><![CDATA[Any kid of text here]]></string>',
106+
'<string><![CDATA[@string@]]></string>'
107+
),
108+
array(
109+
<<<XML
110+
<?xml version="1.0"?>
111+
<soap:Envelope
112+
xmlns:soap="http://www.w3.org/2001/12/soap-envelope"
113+
soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">
114+
115+
<soap:Body xmlns:m="http://www.example.org/stock">
116+
<m:GetStockPrice>
117+
<m:StockName>IBM</m:StockName>
118+
<m:StockValue>Any Value</m:StockValue>
119+
</m:GetStockPrice>
120+
</soap:Body>
121+
122+
</soap:Envelope>
123+
XML
124+
,
125+
<<<XML
126+
<?xml version="1.0"?>
127+
<soap:Envelope
128+
xmlns:soap="@string@"
129+
soap:encodingStyle="@string@">
130+
131+
<soap:Body xmlns:m="@string@">
132+
<m:GetStockPrice>
133+
<m:StockName>@string@</m:StockName>
134+
<m:StockValue>@string@</m:StockValue>
135+
</m:GetStockPrice>
136+
</soap:Body>
137+
138+
</soap:Envelope>
139+
XML
140+
)
141+
);
142+
}
143+
144+
public static function negativeMatches()
145+
{
146+
return array(
147+
array(
148+
'<users><user>Norbert</user><user>Michał</user></users>',
149+
'{"users":["Michał","@string@"]}'
150+
),
151+
array(
152+
'<users><user>Norbert</user><user>Michał</user></users>',
153+
'<users><user>@integer@</user><user>@integer@</user></users>'
154+
),
155+
);
156+
}
157+
}

tests/Coduo/PHPMatcher/MatcherTest.php

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
<?php
2+
23
namespace Coduo\PHPMatcher\Tests;
34

45
use Coduo\PHPMatcher\Lexer;
@@ -39,7 +40,8 @@ public function setUp()
3940
$this->matcher = new Matcher(new Matcher\ChainMatcher(array(
4041
$scalarMatchers,
4142
$arrayMatcher,
42-
new Matcher\JsonMatcher($arrayMatcher)
43+
new Matcher\JsonMatcher($arrayMatcher),
44+
new Matcher\XmlMatcher($arrayMatcher)
4345
)));
4446
}
4547

@@ -155,6 +157,43 @@ public function test_matcher_with_json()
155157
$this->assertTrue(match($json, $jsonPattern));
156158
}
157159

160+
public function test_matcher_with_xml()
161+
{
162+
$xml = <<<XML
163+
<?xml version="1.0"?>
164+
<soap:Envelope
165+
xmlns:soap="http://www.w3.org/2001/12/soap-envelope"
166+
soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">
167+
168+
<soap:Body xmlns:m="http://www.example.org/stock">
169+
<m:GetStockPrice>
170+
<m:StockName>IBM</m:StockName>
171+
<m:StockValue>Any Value</m:StockValue>
172+
</m:GetStockPrice>
173+
</soap:Body>
174+
175+
</soap:Envelope>
176+
XML;
177+
$xmlPattern = <<<XML
178+
<?xml version="1.0"?>
179+
<soap:Envelope
180+
xmlns:soap="@string@"
181+
soap:encodingStyle="@string@">
182+
183+
<soap:Body xmlns:m="@string@">
184+
<m:GetStockPrice>
185+
<m:StockName>@string@</m:StockName>
186+
<m:StockValue>@string@</m:StockValue>
187+
</m:GetStockPrice>
188+
</soap:Body>
189+
190+
</soap:Envelope>
191+
XML;
192+
193+
$this->assertTrue($this->matcher->match($xml, $xmlPattern));
194+
$this->assertTrue(match($xml, $xmlPattern));
195+
}
196+
158197
public function test_matcher_with_captures()
159198
{
160199
$this->assertTrue($this->matcher->match(

0 commit comments

Comments
 (0)