PageRenderTime 29ms CodeModel.GetById 9ms RepoModel.GetById 0ms app.codeStats 0ms

/test/Tests/QueryPath/CSS/DOMTraverserTest.php

https://bitbucket.org/mkalkbrenner/querypath
PHP | 357 lines | 233 code | 88 blank | 36 comment | 0 complexity | 825cbec5d9ceeb8bd056aa22a9a54924 MD5 | raw file
  1. <?php
  2. /**
  3. * @file
  4. * CSS Event handling tests
  5. */
  6. namespace QueryPath\Tests;
  7. require_once __DIR__ . '/../TestCase.php';
  8. use \QueryPath\CSS\Token;
  9. use \QueryPath\CSS\DOMTraverser;
  10. use \QueryPath\CSS\Parser;
  11. use \QueryPath\CSS\EventHandler;
  12. define('TRAVERSER_XML', __DIR__ . '/../../../DOMTraverserTest.xml');
  13. /**
  14. * @ingroup querypath_tests
  15. * @group CSS
  16. */
  17. class DOMTraverserTest extends TestCase {
  18. protected $xml_file = TRAVERSER_XML;
  19. public function debug($msg) {
  20. fwrite(STDOUT, PHP_EOL . $msg);
  21. }
  22. public function testConstructor() {
  23. $dom = new \DOMDocument('1.0');
  24. $dom->load($this->xml_file);
  25. $splos = new \SPLObjectStorage();
  26. $splos->attach($dom);
  27. $traverser = new DOMTraverser($splos);
  28. $this->assertInstanceOf('\QueryPath\CSS\Traverser', $traverser);
  29. $this->assertInstanceOf('\QueryPath\CSS\DOMTraverser', $traverser);
  30. }
  31. protected function traverser() {
  32. $dom = new \DOMDocument('1.0');
  33. $dom->load($this->xml_file);
  34. $splos = new \SPLObjectStorage();
  35. $splos->attach($dom->documentElement);
  36. $traverser = new DOMTraverser($splos);
  37. return $traverser;
  38. }
  39. protected function find($selector) {
  40. return $this->traverser()->find($selector)->matches();
  41. }
  42. public function testFind() {
  43. $res = $this->traverser()->find('root');
  44. // Ensure that return contract is not violated.
  45. $this->assertInstanceOf('\QueryPath\CSS\Traverser', $res);
  46. }
  47. public function testMatches() {
  48. $res = $this->traverser()->matches();
  49. $this->assertEquals(1, count($res));
  50. }
  51. public function testMatchElement() {
  52. // Canary: If element does not exist, must return FALSE.
  53. $matches = $this->find('NO_SUCH_ELEMENT');
  54. $this->assertEquals(0, count($matches));
  55. // Test without namespace
  56. $matches = $this->find('root');
  57. $this->assertEquals(1, count($matches));
  58. $matches = $this->find('crowded');
  59. $this->assertEquals(1, count($matches));
  60. $matches = $this->find('outside');
  61. $this->assertEquals(3, count($matches));
  62. // Check nested elements.
  63. $matches = $this->find('a');
  64. $this->assertEquals(3, count($matches));
  65. // Test wildcard.
  66. $traverser = $this->traverser();
  67. $matches = $traverser->find('*')->matches();
  68. $actual= $traverser->getDocument()->getElementsByTagName('*');
  69. $this->assertEquals($actual->length, count($matches));
  70. // Test with namespace
  71. //$this->markTestIncomplete();
  72. $matches = $this->find('ns_test');
  73. $this->assertEquals(3, count($matches));
  74. $matches = $this->find('test|ns_test');
  75. $this->assertEquals(1, count($matches));
  76. $matches = $this->find('test|ns_test>ns_attr');
  77. $this->assertEquals(1, count($matches));
  78. $matches = $this->find('*|ns_test');
  79. $this->assertEquals(3, count($matches));
  80. $matches = $this->find('test|*');
  81. $this->assertEquals(1, count($matches));
  82. // Test where namespace is declared on the element.
  83. $matches = $this->find('newns|my_element');
  84. $this->assertEquals(1, count($matches));
  85. $matches = $this->find('test|ns_test>newns|my_element');
  86. $this->assertEquals(1, count($matches));
  87. $matches = $this->find('test|*>newns|my_element');
  88. $this->assertEquals(1, count($matches));
  89. $matches = $this->find('*|ns_test>newns|my_element');
  90. $this->assertEquals(1, count($matches));
  91. $matches = $this->find('*|*>newns|my_element');
  92. $this->assertEquals(1, count($matches));
  93. $matches = $this->find('*>newns|my_element');
  94. $this->assertEquals(1, count($matches));
  95. }
  96. public function testMatchAttributes() {
  97. $matches = $this->find('crowded[attr1]');
  98. $this->assertEquals(1, count($matches));
  99. $matches = $this->find('crowded[attr1=one]');
  100. $this->assertEquals(1, count($matches));
  101. $matches = $this->find('crowded[attr2^=tw]');
  102. $this->assertEquals(1, count($matches));
  103. $matches = $this->find('classtest[class~=two]');
  104. $this->assertEquals(1, count($matches));
  105. $matches = $this->find('classtest[class~=one]');
  106. $this->assertEquals(1, count($matches));
  107. $matches = $this->find('classtest[class~=seven]');
  108. $this->assertEquals(1, count($matches));
  109. $matches = $this->find('crowded[attr0]');
  110. $this->assertEquals(0, count($matches));
  111. $matches = $this->find('[level=1]');
  112. $this->assertEquals(3, count($matches));
  113. $matches = $this->find('[attr1]');
  114. $this->assertEquals(1, count($matches));
  115. $matches = $this->find('[test|myattr]');
  116. $this->assertEquals(1, count($matches));
  117. $matches = $this->find('[test|myattr=foo]');
  118. $this->assertEquals(1, count($matches));
  119. $matches = $this->find('[*|myattr=foo]');
  120. $this->assertEquals(1, count($matches));
  121. $matches = $this->find('[|myattr=foo]');
  122. $this->assertEquals(0, count($matches));
  123. $matches = $this->find('[|level=1]');
  124. $this->assertEquals(3, count($matches));
  125. $matches = $this->find('[*|level=1]');
  126. $this->assertEquals(4, count($matches));
  127. // Test namespace on attr where namespace
  128. // is declared on that element
  129. $matches = $this->find('[nuther|ping]');
  130. $this->assertEquals(1, count($matches));
  131. // Test multiple namespaces on an element.
  132. $matches = $this->find('[*|ping=3]');
  133. $this->assertEquals(1, count($matches));
  134. // Test multiple namespaces on an element.
  135. $matches = $this->find('[*|ping]');
  136. $this->assertEquals(1, count($matches));
  137. }
  138. public function testMatchId() {
  139. $matches = $this->find('idtest#idtest-one');
  140. $this->assertEquals(1, count($matches));
  141. $matches = $this->find('#idtest-one');
  142. $this->assertEquals(1, count($matches));
  143. $matches = $this->find('outter#fake');
  144. $this->assertEquals(0, count($matches));
  145. $matches = $this->find('#fake');
  146. $this->assertEquals(0, count($matches));
  147. }
  148. public function testMatchClasses() {
  149. // Basic test.
  150. $matches = $this->find('a.a1');
  151. $this->assertEquals(1, count($matches));
  152. // Count multiple.
  153. $matches = $this->find('.first');
  154. $this->assertEquals(2, count($matches));
  155. // Grab one in the middle of a list.
  156. $matches = $this->find('.four');
  157. $this->assertEquals(1, count($matches));
  158. // One element with two classes.
  159. $matches = $this->find('.three.four');
  160. $this->assertEquals(1, count($matches));
  161. }
  162. public function testMatchPseudoClasses() {
  163. $matches = $this->find('ul>li:first');
  164. $this->assertEquals(1, count($matches));
  165. $matches = $this->find('ul>li:not(.first)');
  166. $this->assertEquals(5, count($matches));
  167. }
  168. public function testMatchPseudoElements() {
  169. $matches = $this->find('p::first-line');
  170. $this->assertEquals(1, count($matches));
  171. $matches = $this->find('p::first-letter');
  172. $this->assertEquals(1, count($matches));
  173. $matches = $this->find('p::before');
  174. $this->assertEquals(1, count($matches));
  175. $matches = $this->find('p::after');
  176. $this->assertEquals(1, count($matches));
  177. $matches = $this->find('bottom::after');
  178. $this->assertEquals(0, count($matches));
  179. }
  180. public function testCombineAdjacent() {
  181. // Simple test
  182. $matches = $this->find('idtest + p');
  183. $this->assertEquals(1, count($matches));
  184. foreach ($matches as $m) {
  185. $this->assertEquals('p', $m->tagName);
  186. }
  187. // Test ignoring PCDATA
  188. $matches = $this->find('p + one');
  189. $this->assertEquals(1, count($matches));
  190. foreach ($matches as $m) {
  191. $this->assertEquals('one', $m->tagName);
  192. }
  193. // Test that non-adjacent elements don't match.
  194. $matches = $this->find('idtest + one');
  195. foreach ($matches as $m) {
  196. $this->assertEquals('one', $m->tagName);
  197. }
  198. $this->assertEquals(0, count($matches), 'Non-adjacents should not match.');
  199. // Test that elements BEFORE don't match
  200. $matches = $this->find('one + p');
  201. foreach ($matches as $m) {
  202. $this->assertEquals('one', $m->tagName);
  203. }
  204. $this->assertEquals(0, count($matches), 'Match only if b is after a');
  205. }
  206. public function testCombineSibling() {
  207. // Canary:
  208. $matches = $this->find('one ~ two');
  209. $this->assertEquals(0, count($matches));
  210. // Canary 2:
  211. $matches = $this->find('NO_SUCH_ELEMENT ~ two');
  212. $this->assertEquals(0, count($matches));
  213. // Simple test
  214. $matches = $this->find('idtest ~ p');
  215. $this->assertEquals(1, count($matches));
  216. foreach ($matches as $m) {
  217. $this->assertEquals('p', $m->tagName);
  218. }
  219. // Simple test
  220. $matches = $this->find('outside ~ p');
  221. $this->assertEquals(1, count($matches));
  222. foreach ($matches as $m) {
  223. $this->assertEquals('p', $m->tagName);
  224. }
  225. // Matches only go left, not right.
  226. $matches = $this->find('p ~ outside');
  227. $this->assertEquals(0, count($matches));
  228. }
  229. public function testCombineDirectDescendant() {
  230. // Canary:
  231. $matches = $this->find('one > four');
  232. $this->assertEquals(0, count($matches));
  233. $matches = $this->find('two>three');
  234. $this->assertEquals(1, count($matches));
  235. foreach ($matches as $m) {
  236. $this->assertEquals('three', $m->tagName);
  237. }
  238. $matches = $this->find('one > two > three');
  239. $this->assertEquals(1, count($matches));
  240. foreach ($matches as $m) {
  241. $this->assertEquals('three', $m->tagName);
  242. }
  243. $matches = $this->find('a>a>a');
  244. $this->assertEquals(1, count($matches));
  245. $matches = $this->find('a>a');
  246. $this->assertEquals(2, count($matches));
  247. }
  248. public function testCombineAnyDescendant() {
  249. // Canary
  250. $matches = $this->find('four one');
  251. $this->assertEquals(0, count($matches));
  252. $matches = $this->find('one two');
  253. $this->assertEquals(1, count($matches));
  254. foreach ($matches as $m) {
  255. $this->assertEquals('two', $m->tagName);
  256. }
  257. $matches = $this->find('one four');
  258. $this->assertEquals(1, count($matches));
  259. $matches = $this->find('a a');
  260. $this->assertEquals(2, count($matches));
  261. $matches = $this->find('root two four');
  262. $this->assertEquals(1, count($matches));
  263. }
  264. public function testMultipleSelectors() {
  265. // fprintf(STDOUT, "=========TEST=========\n\n");
  266. $matches = $this->find('one, two');
  267. $this->assertEquals(2, count($matches));
  268. }
  269. }