Skip to content

Commit 4d587c3

Browse files
committed
Merge pull request #33 from symfony-cmf/xml_schema_test
Xml schema testing
2 parents d91bc86 + 0f8c2c9 commit 4d587c3

File tree

5 files changed

+168
-0
lines changed

5 files changed

+168
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
Changelog
22
=========
33

4+
* **2013-12-27**: Added XmlSchemaTestCase to test XML schema's
45
* **2013-11-17**: Added DatabaseTestListener to support database testing
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
<?php
2+
3+
namespace Symfony\Cmf\Component\Testing\Unit\Constraint;
4+
5+
class SchemaAcceptsXml extends \PHPUnit_Framework_Constraint
6+
{
7+
protected $schemaFile;
8+
protected $failingElement;
9+
protected $errors;
10+
11+
public function __construct($schemaFile)
12+
{
13+
$this->schemaFile = $schemaFile;
14+
}
15+
16+
public function matches($others)
17+
{
18+
foreach ($others as $id => $other) {
19+
$configElement = $other->getElementsByTagName('config');
20+
21+
if (1 !== $configElement->length) {
22+
throw new \InvalidArgumentException(sprintf('Can only test a file if it contains 1 <config> element, %d given', $configElement->length));
23+
}
24+
25+
$configDom = new \DomDocument();
26+
$configDom->appendChild($configDom->importNode($configElement->item(0), true));
27+
28+
libxml_use_internal_errors(true);
29+
if (!$configDom->schemaValidate($this->schemaFile)) {
30+
$this->errors = libxml_get_errors();
31+
$this->failingElement = $id;
32+
return false;
33+
}
34+
}
35+
36+
return true;
37+
}
38+
39+
public function toString() { }
40+
41+
protected function failureDescription($others)
42+
{
43+
return sprintf(
44+
'"%s" is accepted by the XML schema "%s"',
45+
\PHPUnit_Util_Type::export($others[$this->failingElement]),
46+
$this->schemaFile
47+
);
48+
}
49+
50+
protected function additionalFailureDescription($other)
51+
{
52+
$str = '';
53+
54+
foreach ($this->errors as $error) {
55+
$str .= $error->message.($error->file ? ' in'.$error->file : '').' on line '.$error->line."\n";
56+
}
57+
58+
return $str;
59+
}
60+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
namespace Symfony\Cmf\Component\Testing\Unit;
4+
5+
class XmlSchemaTestCase extends \PHPUnit_Framework_TestCase
6+
{
7+
public static function assertSchemaAcceptsXml($xmlDoms, $schemaPath, $message = '')
8+
{
9+
if (!is_array($xmlDoms)) {
10+
$xmlDoms = array($xmlDoms);
11+
}
12+
13+
$xmlDoms = array_map(function ($dom) {
14+
if (is_string($dom)) {
15+
$xml = $dom;
16+
$dom = new \DOMDocument();
17+
$dom->load($xml);
18+
19+
return $dom;
20+
}
21+
22+
if (!$dom instanceof \DOMDocument) {
23+
throw new \InvalidArgumentException(sprintf('The first argument of assertSchemaAcceptsXml should be instances of \DOMDocument, "%s" given', get_class($dom)));
24+
}
25+
26+
return $dom;
27+
}, $xmlDoms);
28+
29+
return self::assertThat($xmlDoms, new Constraint\SchemaAcceptsXml($schemaPath), $message);
30+
}
31+
}

tests/Fixtures/schema/schema1.xsd

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?xml version="1.0" encoding="UTF-8" ?>
2+
3+
<xsd:schema xmlns="http://cmf.symfony.com/schema/dic/foo"
4+
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
5+
targetNamespace="http://cmf.symfony.com/schema/dic/foo"
6+
elementFormDefault="qualified">
7+
8+
<xsd:element name="config" type="config" />
9+
10+
<xsd:complexType name="config">
11+
<xsd:attribute name="required" use="required" />
12+
</xsd:complexType>
13+
</xsd:schema>

tests/Unit/XmlSchemaTestCaseTest.php

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
<?php
2+
3+
namespace Tests\Unit;
4+
5+
use Symfony\Cmf\Component\Testing\Unit\XmlSchemaTestCase;
6+
7+
class XmlSchemaTestCaseTest extends XmlSchemaTestCase
8+
{
9+
/**
10+
* @dataProvider getAssertingData
11+
*/
12+
public function testAsserting($input, $schemaFile, $result, $message = null)
13+
{
14+
$failed = false;
15+
16+
try {
17+
$this->assertSchemaAcceptsXml($input, $schemaFile);
18+
} catch (\PHPUnit_Framework_ExpectationFailedException $e) {
19+
$failed = true;
20+
}
21+
22+
if ($failed) {
23+
$this->assertFalse($result, 'schema should accept xml');
24+
} else {
25+
$this->assertTrue($result, 'schema should not accept xml');
26+
if ($message) {
27+
$this->assertEquals($message, $e->getMessage());
28+
}
29+
}
30+
}
31+
32+
public function getAssertingData()
33+
{
34+
$schema1 = __DIR__.'/../Fixtures/schema/schema1.xsd';
35+
36+
$data = array();
37+
38+
$dom1 = new \DomDocument();
39+
$dom1->loadXML('<container><config xmlns="http://cmf.symfony.com/schema/dic/foo" required="f"/></container>');
40+
$data[] = array($dom1, $schema1, true);
41+
42+
$dom2 = new \DomDocument();
43+
$dom2->loadXML('<container><config xmlns="http://cmf.symfony.com/schema/dic/foo" /></container>');
44+
$data[] = array($dom2, $schema1, false);
45+
46+
$data[] = array(array($dom1, $dom1), $schema1, true);
47+
$data[] = array(array($dom1, $dom2), $schema1, false);
48+
$data[] = array(array($dom2, $dom1), $schema1, false);
49+
50+
return $data;
51+
}
52+
53+
/**
54+
* @expectedException \InvalidArgumentException
55+
*/
56+
public function testFailsIfNoConfigElementIsAvailable()
57+
{
58+
$dom = new \DomDocument();
59+
$dom->loadXML('<container></container>');
60+
61+
$this->assertSchemaAcceptsXml($dom, __DIR__.'/../Fixtures/schema/schema1.xsd');
62+
}
63+
}

0 commit comments

Comments
 (0)