testcase-xml.php 4.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. <?php
  2. abstract class WP_Test_XML_TestCase extends WP_UnitTestCase {
  3. /**
  4. * Load XML from a string.
  5. *
  6. * @param string $xml
  7. * @param int $options Bitwise OR of the {@link https://www.php.net/manual/en/libxml.constants.php libxml option constants}.
  8. * Default is 0.
  9. * @return DOMDocument The DOMDocument object loaded from the XML.
  10. */
  11. public function loadXML( $xml, $options = 0 ) {
  12. // Suppress PHP warnings generated by DOMDocument::loadXML(), which would cause
  13. // PHPUnit to incorrectly report an error instead of a just a failure.
  14. $internal = libxml_use_internal_errors( true );
  15. libxml_clear_errors();
  16. $xml_dom = new DOMDocument();
  17. $xml_dom->loadXML( $xml, $options );
  18. $libxml_last_error = libxml_get_last_error();
  19. $this->assertFalse(
  20. isset( $libxml_last_error->message ),
  21. isset( $libxml_last_error->message ) ? sprintf( 'Non-well-formed XML: %s.', $libxml_last_error->message ) : ''
  22. );
  23. // Restore default error handler.
  24. libxml_use_internal_errors( $internal );
  25. libxml_clear_errors();
  26. return $xml_dom;
  27. }
  28. /**
  29. * Normalize an XML document to make comparing two documents easier.
  30. *
  31. * @param string $xml
  32. * @param int $options Bitwise OR of the {@link https://www.php.net/manual/en/libxml.constants.php libxml option constants}.
  33. * Default is 0.
  34. * @return string The normalized form of `$xml`.
  35. */
  36. public function normalizeXML( $xml, $options = 0 ) {
  37. if ( ! class_exists( 'XSLTProcessor' ) ) {
  38. $this->markTestSkipped( 'This test requires the XSL extension.' );
  39. }
  40. static $xslt_proc;
  41. if ( ! $xslt_proc ) {
  42. $xslt_proc = new XSLTProcessor();
  43. $xslt_proc->importStyleSheet( simplexml_load_file( __DIR__ . '/normalize-xml.xsl' ) );
  44. }
  45. return $xslt_proc->transformToXML( $this->loadXML( $xml, $options ) );
  46. }
  47. /**
  48. * Reports an error identified by `$message` if the namespace normalized form of the XML document in `$actualXml`
  49. * is equal to the namespace normalized form of the XML document in `$expectedXml`.
  50. *
  51. * This is similar to {@link https://phpunit.de/manual/6.5/en/appendixes.assertions.html#appendixes.assertions.assertXmlStringEqualsXmlString assertXmlStringEqualsXmlString()}
  52. * except that differences in namespace prefixes are normalized away, such that given
  53. * `$actualXml = "<root xmlns='urn:wordpress.org'><child/></root>";` and
  54. * `$expectedXml = "<ns0:root xmlns:ns0='urn:wordpress.org'><ns0:child></ns0:root>";`
  55. * then `$this->assertXMLEquals( $expectedXml, $actualXml )` will succeed.
  56. *
  57. * @param string $expectedXml
  58. * @param string $actualXml
  59. * @param string $message Optional. Message to display when the assertion fails.
  60. */
  61. public function assertXMLEquals( $expectedXml, $actualXml, $message = '' ) { // phpcs:ignore WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase
  62. $this->assertSame( $this->normalizeXML( $expectedXml ), $this->normalizeXML( $actualXml ), $message ); //phpcs:ignore WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase
  63. }
  64. /**
  65. * Reports an error identified by `$message` if the namespace normalized form of the XML document in `$actualXml`
  66. * is not equal to the namespace normalized form of the XML document in `$expectedXml`.
  67. *
  68. * This is similar to {@link https://phpunit.de/manual/6.5/en/appendixes.assertions.html#appendixes.assertions.assertXmlStringEqualsXmlString assertXmlStringNotEqualsXmlString()}
  69. * except that differences in namespace prefixes are normalized away, such that given
  70. * `$actualXml = "<root xmlns='urn:wordpress.org'><child></root>";` and
  71. * `$expectedXml = "<ns0:root xmlns:ns0='urn:wordpress.org'><ns0:child/></ns0:root>";`
  72. * then `$this->assertXMLNotEquals( $expectedXml, $actualXml )` will fail.
  73. *
  74. * @param string $expectedXml
  75. * @param string $actualXml
  76. * @param string $message Optional. Message to display when the assertion fails.
  77. */
  78. public function assertXMLNotEquals( $expectedXml, $actualXml, $message = '' ) { //phpcs:ignore WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase
  79. $this->assertNotEquals( $this->normalizeXML( $expectedXml ), $this->normalizeXML( $actualXml ), $message ); //phpcs:ignore WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase
  80. }
  81. }