SelectorTest.php 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  1. <?php
  2. declare(strict_types=1);
  3. namespace DiDom\Tests;
  4. use DiDom\Document;
  5. class SelectorTest extends TestCase
  6. {
  7. public function testTag()
  8. {
  9. $html = '
  10. <ul id="first">
  11. <li><a href="#">Item 1</a></li>
  12. <li><a href="#">Item 2</a></li>
  13. <li><a href="#">Item 3</a></li>
  14. </ul>
  15. <ol id="second">
  16. <li><a href="#">Item 1</a></li>
  17. <li><a href="#">Item 2</a></li>
  18. <li><a href="#">Item 3</a></li>
  19. </ol>
  20. ';
  21. $document = new Document($html);
  22. $expected = ['Item 1', 'Item 2', 'Item 3', 'Item 1', 'Item 2', 'Item 3'];
  23. $result = [];
  24. foreach ($document->find('li') as $element) {
  25. $result[] = $element->text();
  26. }
  27. $this->assertEquals($expected, $result);
  28. }
  29. public function testNestedTag()
  30. {
  31. $html = '
  32. <ul id="first">
  33. <li><a href="#">Item 1</a></li>
  34. <li><a href="#">Item 2</a></li>
  35. <li><a href="#">Item 3</a></li>
  36. </ul>
  37. <ol id="second">
  38. <li><a href="#">Item 1</a></li>
  39. <li><a href="#">Item 2</a></li>
  40. <li><a href="#">Item 3</a></li>
  41. </ol>
  42. ';
  43. $document = new Document($html);
  44. $expected = ['Item 1', 'Item 2', 'Item 3'];
  45. $result = [];
  46. foreach ($document->find('ul a') as $element) {
  47. $result[] = $element->text();
  48. }
  49. $this->assertEquals($expected, $result);
  50. }
  51. public function testDirectChild()
  52. {
  53. $html = '
  54. <div>
  55. <p><span>Lorem ipsum.</span></p>
  56. <span>Lorem ipsum.</span>
  57. </div>
  58. ';
  59. $document = new Document($html);
  60. $expected = ['Lorem ipsum.'];
  61. $result = [];
  62. foreach ($document->find('div > span') as $element) {
  63. $result[] = $element->text();
  64. }
  65. $this->assertEquals($expected, $result);
  66. }
  67. public function testId()
  68. {
  69. $html = '
  70. <span>Lorem ipsum dolor.</span>
  71. <span id="second">Tenetur totam, nostrum.</span>
  72. <span>Iste, doloremque, praesentium.</span>
  73. ';
  74. $document = new Document($html);
  75. $expected = ['Tenetur totam, nostrum.'];
  76. $result = [];
  77. foreach ($document->find('#second') as $element) {
  78. $result[] = $element->text();
  79. }
  80. $this->assertEquals($expected, $result);
  81. }
  82. public function testClass()
  83. {
  84. $html = '
  85. <span class="odd first">Lorem ipsum dolor.</span>
  86. <span class="even second">Tenetur totam, nostrum.</span>
  87. <span class="odd third">Iste, doloremque, praesentium.</span>
  88. ';
  89. $document = new Document($html);
  90. $expected = ['Lorem ipsum dolor.', 'Iste, doloremque, praesentium.'];
  91. $result = [];
  92. foreach ($document->find('.odd') as $element) {
  93. $result[] = $element->text();
  94. }
  95. $this->assertEquals($expected, $result);
  96. $expected = ['Iste, doloremque, praesentium.'];
  97. $result = [];
  98. foreach ($document->find('.odd.third') as $element) {
  99. $result[] = $element->text();
  100. }
  101. $this->assertEquals($expected, $result);
  102. }
  103. public function testAttributes()
  104. {
  105. $html = '
  106. <ul class="links">
  107. <li>
  108. <a href="https://foo.com" title="Foo" target="_blank">Foo</a>
  109. <a href="http://bar.com" title="Bar" rel="noreferrer">Bar</a>
  110. <a href="https://baz.org" title="Baz" rel="nofollow noreferrer">Baz</a>
  111. <a href="http://qux.org" title="Qux" target="_blank" rel="nofollow">Qux</a>
  112. </li>
  113. </ul>
  114. ';
  115. $document = new Document($html);
  116. // has attribute
  117. $expected = ['Foo', 'Qux'];
  118. $result = [];
  119. foreach ($document->find('a[target]') as $element) {
  120. $result[] = $element->text();
  121. }
  122. $this->assertEquals($expected, $result);
  123. // has no attribute
  124. $expected = ['Bar', 'Baz'];
  125. $result = [];
  126. foreach ($document->find('a[!target]') as $element) {
  127. $result[] = $element->text();
  128. }
  129. $this->assertEquals($expected, $result);
  130. // equals
  131. $expected = ['Baz'];
  132. $result = [];
  133. foreach ($document->find('a[href="https://baz.org"]') as $element) {
  134. $result[] = $element->text();
  135. }
  136. $this->assertEquals($expected, $result);
  137. // not equals
  138. $expected = ['Foo', 'Bar', 'Qux'];
  139. $result = [];
  140. foreach ($document->find('a[href!="https://baz.org"]') as $element) {
  141. $result[] = $element->text();
  142. }
  143. $this->assertEquals($expected, $result);
  144. // starts with
  145. $expected = ['Foo', 'Baz'];
  146. $result = [];
  147. foreach ($document->find('a[href^="https"]') as $element) {
  148. $result[] = $element->text();
  149. }
  150. $this->assertEquals($expected, $result);
  151. // ends with
  152. $expected = ['Baz', 'Qux'];
  153. $result = [];
  154. foreach ($document->find('a[href$="org"]') as $element) {
  155. $result[] = $element->text();
  156. }
  157. $this->assertEquals($expected, $result);
  158. // contains word
  159. $expected = ['Bar', 'Baz'];
  160. $result = [];
  161. foreach ($document->find('a[rel~="noreferrer"]') as $element) {
  162. $result[] = $element->text();
  163. }
  164. $this->assertEquals($expected, $result);
  165. $this->assertEquals([], $document->find('a[rel~="noref"]'));
  166. // contains substring
  167. $expected = ['Bar', 'Baz'];
  168. $result = [];
  169. foreach ($document->find('a[href*="ba"]') as $element) {
  170. $result[] = $element->text();
  171. }
  172. $this->assertEquals($expected, $result);
  173. // multiple attribute conditions
  174. $expected = ['Qux'];
  175. $result = [];
  176. foreach ($document->find('a[target="_blank"][rel="nofollow"]') as $element) {
  177. $result[] = $element->text();
  178. }
  179. $this->assertEquals($expected, $result);
  180. }
  181. /**
  182. * @param $selector
  183. * @param $expectedResult
  184. *
  185. * @dataProvider containsPseudoClassTests
  186. */
  187. public function testContainsPseudoClass($selector, $expectedResult)
  188. {
  189. $html = '
  190. <ul class="links">
  191. <li>
  192. <a href="https://foo.com" title="Foo" target="_blank">Foo</a>
  193. <a href="http://bar.com" title="Bar" rel="noreferrer">Bar</a>
  194. <a href="https://baz.org" title="Baz" rel="nofollow noreferrer">Baz</a>
  195. <a href="http://qux.org" title="Qux" target="_blank" rel="nofollow">Qux</a>
  196. <a href="https://foobar.com" title="FooBar" target="_blank">FooBar</a>
  197. </li>
  198. </ul>
  199. ';
  200. $document = new Document($html);
  201. $result = [];
  202. foreach ($document->find($selector) as $element) {
  203. $result[] = $element->text();
  204. }
  205. $this->assertEquals($expectedResult, $result);
  206. }
  207. public function containsPseudoClassTests()
  208. {
  209. return [
  210. ['a:contains(Baz)', ['Baz']],
  211. ['a:contains(a)', ['Bar', 'Baz', 'FooBar']],
  212. ['a:contains(Bar)', ['Bar', 'FooBar']],
  213. ['a:contains(Bar, true, true)', ['Bar']],
  214. ['a:contains(bar)', []],
  215. ['a:contains(bar, false)', ['Bar', 'FooBar']],
  216. ['a:contains(bar, false, true)', ['Bar']],
  217. ];
  218. }
  219. public function testUnicodeSupport()
  220. {
  221. $html = '
  222. <ul class="links">
  223. <li>
  224. <a href="http://foo.com" title="Foo">Foo</a>
  225. <a href="http://example.com" title="Пример">Example</a>
  226. <a href="http://bar.com" title="Foo">Bar</a>
  227. <a href="http://example.ru" title="Example">Пример</a>
  228. </li>
  229. </ul>
  230. ';
  231. $document = new Document($html);
  232. $this->assertEquals('Example', $document->first('a[title=Пример]')->text());
  233. $this->assertEquals('Example', $document->first('a:contains(Пример)')->attr('title'));
  234. }
  235. }