Skip to content

Commit

Permalink
Merge pull request #33 from symfony-cmf/xml_schema_test
Browse files Browse the repository at this point in the history
Xml schema testing
  • Loading branch information
wouterj committed Dec 27, 2013
2 parents d91bc86 + 0f8c2c9 commit 4d587c3
Show file tree
Hide file tree
Showing 5 changed files with 168 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
Changelog
=========

* **2013-12-27**: Added XmlSchemaTestCase to test XML schema's
* **2013-11-17**: Added DatabaseTestListener to support database testing
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?php

namespace Symfony\Cmf\Component\Testing\Unit\Constraint;

class SchemaAcceptsXml extends \PHPUnit_Framework_Constraint
{
protected $schemaFile;
protected $failingElement;
protected $errors;

public function __construct($schemaFile)
{
$this->schemaFile = $schemaFile;
}

public function matches($others)
{
foreach ($others as $id => $other) {
$configElement = $other->getElementsByTagName('config');

if (1 !== $configElement->length) {
throw new \InvalidArgumentException(sprintf('Can only test a file if it contains 1 <config> element, %d given', $configElement->length));
}

$configDom = new \DomDocument();
$configDom->appendChild($configDom->importNode($configElement->item(0), true));

libxml_use_internal_errors(true);
if (!$configDom->schemaValidate($this->schemaFile)) {
$this->errors = libxml_get_errors();
$this->failingElement = $id;
return false;
}
}

return true;
}

public function toString() { }

protected function failureDescription($others)
{
return sprintf(
'"%s" is accepted by the XML schema "%s"',
\PHPUnit_Util_Type::export($others[$this->failingElement]),
$this->schemaFile
);
}

protected function additionalFailureDescription($other)
{
$str = '';

foreach ($this->errors as $error) {
$str .= $error->message.($error->file ? ' in'.$error->file : '').' on line '.$error->line."\n";
}

return $str;
}
}
31 changes: 31 additions & 0 deletions src/Symfony/Cmf/Component/Testing/Unit/XmlSchemaTestCase.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

namespace Symfony\Cmf\Component\Testing\Unit;

class XmlSchemaTestCase extends \PHPUnit_Framework_TestCase
{
public static function assertSchemaAcceptsXml($xmlDoms, $schemaPath, $message = '')
{
if (!is_array($xmlDoms)) {
$xmlDoms = array($xmlDoms);
}

$xmlDoms = array_map(function ($dom) {
if (is_string($dom)) {
$xml = $dom;
$dom = new \DOMDocument();
$dom->load($xml);

return $dom;
}

if (!$dom instanceof \DOMDocument) {
throw new \InvalidArgumentException(sprintf('The first argument of assertSchemaAcceptsXml should be instances of \DOMDocument, "%s" given', get_class($dom)));
}

return $dom;
}, $xmlDoms);

return self::assertThat($xmlDoms, new Constraint\SchemaAcceptsXml($schemaPath), $message);
}
}
13 changes: 13 additions & 0 deletions tests/Fixtures/schema/schema1.xsd
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8" ?>

<xsd:schema xmlns="http://cmf.symfony.com/schema/dic/foo"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://cmf.symfony.com/schema/dic/foo"
elementFormDefault="qualified">

<xsd:element name="config" type="config" />

<xsd:complexType name="config">
<xsd:attribute name="required" use="required" />
</xsd:complexType>
</xsd:schema>
63 changes: 63 additions & 0 deletions tests/Unit/XmlSchemaTestCaseTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<?php

namespace Tests\Unit;

use Symfony\Cmf\Component\Testing\Unit\XmlSchemaTestCase;

class XmlSchemaTestCaseTest extends XmlSchemaTestCase
{
/**
* @dataProvider getAssertingData
*/
public function testAsserting($input, $schemaFile, $result, $message = null)
{
$failed = false;

try {
$this->assertSchemaAcceptsXml($input, $schemaFile);
} catch (\PHPUnit_Framework_ExpectationFailedException $e) {
$failed = true;
}

if ($failed) {
$this->assertFalse($result, 'schema should accept xml');
} else {
$this->assertTrue($result, 'schema should not accept xml');
if ($message) {
$this->assertEquals($message, $e->getMessage());
}
}
}

public function getAssertingData()
{
$schema1 = __DIR__.'/../Fixtures/schema/schema1.xsd';

$data = array();

$dom1 = new \DomDocument();
$dom1->loadXML('<container><config xmlns="http://cmf.symfony.com/schema/dic/foo" required="f"/></container>');
$data[] = array($dom1, $schema1, true);

$dom2 = new \DomDocument();
$dom2->loadXML('<container><config xmlns="http://cmf.symfony.com/schema/dic/foo" /></container>');
$data[] = array($dom2, $schema1, false);

$data[] = array(array($dom1, $dom1), $schema1, true);
$data[] = array(array($dom1, $dom2), $schema1, false);
$data[] = array(array($dom2, $dom1), $schema1, false);

return $data;
}

/**
* @expectedException \InvalidArgumentException
*/
public function testFailsIfNoConfigElementIsAvailable()
{
$dom = new \DomDocument();
$dom->loadXML('<container></container>');

$this->assertSchemaAcceptsXml($dom, __DIR__.'/../Fixtures/schema/schema1.xsd');
}
}

0 comments on commit 4d587c3

Please sign in to comment.