You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

198 lines
5.0 KiB

3 years ago
  1. <?php
  2. namespace Hamcrest\Xml;
  3. class HasXPathTest extends \Hamcrest\AbstractMatcherTest
  4. {
  5. protected static $xml;
  6. protected static $doc;
  7. protected static $html;
  8. public static function setUpBeforeClass()
  9. {
  10. self::$xml = <<<XML
  11. <?xml version="1.0"?>
  12. <users>
  13. <user>
  14. <id>alice</id>
  15. <name>Alice Frankel</name>
  16. <role>admin</role>
  17. </user>
  18. <user>
  19. <id>bob</id>
  20. <name>Bob Frankel</name>
  21. <role>user</role>
  22. </user>
  23. <user>
  24. <id>charlie</id>
  25. <name>Charlie Chan</name>
  26. <role>user</role>
  27. </user>
  28. </users>
  29. XML;
  30. self::$doc = new \DOMDocument();
  31. self::$doc->loadXML(self::$xml);
  32. self::$html = <<<HTML
  33. <html>
  34. <head>
  35. <title>Home Page</title>
  36. </head>
  37. <body>
  38. <h1>Heading</h1>
  39. <p>Some text</p>
  40. </body>
  41. </html>
  42. HTML;
  43. }
  44. protected function createMatcher()
  45. {
  46. return \Hamcrest\Xml\HasXPath::hasXPath('/users/user');
  47. }
  48. public function testMatchesWhenXPathIsFound()
  49. {
  50. assertThat('one match', self::$doc, hasXPath('user[id = "bob"]'));
  51. assertThat('two matches', self::$doc, hasXPath('user[role = "user"]'));
  52. }
  53. public function testDoesNotMatchWhenXPathIsNotFound()
  54. {
  55. assertThat(
  56. 'no match',
  57. self::$doc,
  58. not(hasXPath('user[contains(id, "frank")]'))
  59. );
  60. }
  61. public function testMatchesWhenExpressionWithoutMatcherEvaluatesToTrue()
  62. {
  63. assertThat(
  64. 'one match',
  65. self::$doc,
  66. hasXPath('count(user[id = "bob"])')
  67. );
  68. }
  69. public function testDoesNotMatchWhenExpressionWithoutMatcherEvaluatesToFalse()
  70. {
  71. assertThat(
  72. 'no matches',
  73. self::$doc,
  74. not(hasXPath('count(user[id = "frank"])'))
  75. );
  76. }
  77. public function testMatchesWhenExpressionIsEqual()
  78. {
  79. assertThat(
  80. 'one match',
  81. self::$doc,
  82. hasXPath('count(user[id = "bob"])', 1)
  83. );
  84. assertThat(
  85. 'two matches',
  86. self::$doc,
  87. hasXPath('count(user[role = "user"])', 2)
  88. );
  89. }
  90. public function testDoesNotMatchWhenExpressionIsNotEqual()
  91. {
  92. assertThat(
  93. 'no match',
  94. self::$doc,
  95. not(hasXPath('count(user[id = "frank"])', 2))
  96. );
  97. assertThat(
  98. 'one match',
  99. self::$doc,
  100. not(hasXPath('count(user[role = "admin"])', 2))
  101. );
  102. }
  103. public function testMatchesWhenContentMatches()
  104. {
  105. assertThat(
  106. 'one match',
  107. self::$doc,
  108. hasXPath('user/name', containsString('ice'))
  109. );
  110. assertThat(
  111. 'two matches',
  112. self::$doc,
  113. hasXPath('user/role', equalTo('user'))
  114. );
  115. }
  116. public function testDoesNotMatchWhenContentDoesNotMatch()
  117. {
  118. assertThat(
  119. 'no match',
  120. self::$doc,
  121. not(hasXPath('user/name', containsString('Bobby')))
  122. );
  123. assertThat(
  124. 'no matches',
  125. self::$doc,
  126. not(hasXPath('user/role', equalTo('owner')))
  127. );
  128. }
  129. public function testProvidesConvenientShortcutForHasXPathEqualTo()
  130. {
  131. assertThat('matches', self::$doc, hasXPath('count(user)', 3));
  132. assertThat('matches', self::$doc, hasXPath('user[2]/id', 'bob'));
  133. }
  134. public function testProvidesConvenientShortcutForHasXPathCountEqualTo()
  135. {
  136. assertThat('matches', self::$doc, hasXPath('user[id = "charlie"]', 1));
  137. }
  138. public function testMatchesAcceptsXmlString()
  139. {
  140. assertThat('accepts XML string', self::$xml, hasXPath('user'));
  141. }
  142. public function testMatchesAcceptsHtmlString()
  143. {
  144. assertThat('accepts HTML string', self::$html, hasXPath('body/h1', 'Heading'));
  145. }
  146. public function testHasAReadableDescription()
  147. {
  148. $this->assertDescription(
  149. 'XML or HTML document with XPath "/users/user"',
  150. hasXPath('/users/user')
  151. );
  152. $this->assertDescription(
  153. 'XML or HTML document with XPath "count(/users/user)" <2>',
  154. hasXPath('/users/user', 2)
  155. );
  156. $this->assertDescription(
  157. 'XML or HTML document with XPath "/users/user/name"'
  158. . ' a string starting with "Alice"',
  159. hasXPath('/users/user/name', startsWith('Alice'))
  160. );
  161. }
  162. public function testHasAReadableMismatchDescription()
  163. {
  164. $this->assertMismatchDescription(
  165. 'XPath returned no results',
  166. hasXPath('/users/name'),
  167. self::$doc
  168. );
  169. $this->assertMismatchDescription(
  170. 'XPath expression result was <3F>',
  171. hasXPath('/users/user', 2),
  172. self::$doc
  173. );
  174. $this->assertMismatchDescription(
  175. 'XPath returned ["alice", "bob", "charlie"]',
  176. hasXPath('/users/user/id', 'Frank'),
  177. self::$doc
  178. );
  179. }
  180. }