diff --git a/CHANGELOG.md b/CHANGELOG.md index 30e7b64..c979447 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,5 @@ Changelog ========= +* **2013-12-27**: Added XmlSchemaTestCase to test XML schema's * **2013-11-17**: Added DatabaseTestListener to support database testing diff --git a/src/Symfony/Cmf/Component/Testing/Unit/Constraint/SchemaAcceptsXml.php b/src/Symfony/Cmf/Component/Testing/Unit/Constraint/SchemaAcceptsXml.php new file mode 100644 index 0000000..b19c89c --- /dev/null +++ b/src/Symfony/Cmf/Component/Testing/Unit/Constraint/SchemaAcceptsXml.php @@ -0,0 +1,60 @@ +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 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; + } +} diff --git a/src/Symfony/Cmf/Component/Testing/Unit/XmlSchemaTestCase.php b/src/Symfony/Cmf/Component/Testing/Unit/XmlSchemaTestCase.php new file mode 100644 index 0000000..25cf729 --- /dev/null +++ b/src/Symfony/Cmf/Component/Testing/Unit/XmlSchemaTestCase.php @@ -0,0 +1,31 @@ +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); + } +} diff --git a/tests/Fixtures/schema/schema1.xsd b/tests/Fixtures/schema/schema1.xsd new file mode 100644 index 0000000..11ea315 --- /dev/null +++ b/tests/Fixtures/schema/schema1.xsd @@ -0,0 +1,13 @@ + + + + + + + + + + diff --git a/tests/Unit/XmlSchemaTestCaseTest.php b/tests/Unit/XmlSchemaTestCaseTest.php new file mode 100644 index 0000000..f969c3e --- /dev/null +++ b/tests/Unit/XmlSchemaTestCaseTest.php @@ -0,0 +1,63 @@ +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(''); + $data[] = array($dom1, $schema1, true); + + $dom2 = new \DomDocument(); + $dom2->loadXML(''); + $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(''); + + $this->assertSchemaAcceptsXml($dom, __DIR__.'/../Fixtures/schema/schema1.xsd'); + } +}