summaryrefslogtreecommitdiff
path: root/lib/querypath/test/Tests/QueryPath/CSS/QueryPathEventHandlerTest.php
diff options
context:
space:
mode:
Diffstat (limited to 'lib/querypath/test/Tests/QueryPath/CSS/QueryPathEventHandlerTest.php')
-rw-r--r--lib/querypath/test/Tests/QueryPath/CSS/QueryPathEventHandlerTest.php1439
1 files changed, 1439 insertions, 0 deletions
diff --git a/lib/querypath/test/Tests/QueryPath/CSS/QueryPathEventHandlerTest.php b/lib/querypath/test/Tests/QueryPath/CSS/QueryPathEventHandlerTest.php
new file mode 100644
index 0000000..01af591
--- /dev/null
+++ b/lib/querypath/test/Tests/QueryPath/CSS/QueryPathEventHandlerTest.php
@@ -0,0 +1,1439 @@
+<?php
+/** @file
+ * CSS Event handling tests
+ */
+namespace QueryPath\Tests;
+
+require_once __DIR__ . '/../TestCase.php';
+
+use \QueryPath\CSS\Token;
+use \QueryPath\CSS\QueryPathEventHandler;
+use \QueryPath\CSS\Parser;
+use \QueryPath\CSS\EventHandler;
+
+/**
+ * Tests for QueryPathEventHandler class.
+ * @ingroup querypath_tests
+ * @group deprecated
+ */
+class QueryPathEventHandlerTest extends TestCase {
+
+
+ var $xml = '<?xml version="1.0" ?>
+ <html>
+ <head>
+ <title>This is the title</title>
+ </head>
+ <body>
+ <div id="one">
+ <div id="two" class="class-one">
+ <div id="three">
+ Inner text.
+ </div>
+ </div>
+ </div>
+ <span class="class-two">Nada</span>
+ <p><p><p><p><p><p><p class="Odd"><p>8</p></p></p></p></p></p></p></p>
+ <ul>
+ <li class="Odd" id="li-one">Odd</li>
+ <li class="even" id="li-two">Even</li>
+ <li class="Odd" id="li-three">Odd</li>
+ <li class="even" id="li-four">Even</li>
+ <li class="Odd" id="li-five">Odd</li>
+ <li class="even" id="li-six">Even</li>
+ <li class="Odd" id="li-seven">Odd</li>
+ <li class="even" id="li-eight">Even</li>
+ <li class="Odd" id="li-nine">Odd</li>
+ <li class="even" id="li-ten">Even</li>
+ </ul>
+ </body>
+ </html>
+ ';
+
+ private function firstMatch($matches) {
+ $matches->rewind();
+ return $matches->current();
+ }
+ private function nthMatch($matches, $n = 0) {
+ foreach ($matches as $m) {
+ if ($matches->key() == $n) return $m;
+ }
+ }
+
+ public function testGetMatches() {
+ // Test root element:
+ $xml = '<?xml version="1.0" ?><test><inside/>Text<inside/></test>';
+ $doc = new \DomDocument();
+ $doc->loadXML($xml);
+
+ // Test handing it a DOM Document
+ $handler = new QueryPathEventHandler($doc);
+ $matches = $handler->getMatches();
+ $this->assertTrue($matches->count() == 1);
+ $match = $this->firstMatch($matches);
+ $this->assertEquals('test', $match->tagName);
+
+ // Test handling single element
+ $root = $doc->documentElement;
+ $handler = new QueryPathEventHandler($root);
+ $matches = $handler->getMatches();
+ $this->assertEquals(1, $matches->count());
+ $match = $this->firstMatch($matches);
+ $this->assertEquals('test', $match->tagName);
+
+ // Test handling a node list
+ $eles = $doc->getElementsByTagName('inside');
+ $handler = new QueryPathEventHandler($eles);
+ $matches = $handler->getMatches();
+ $this->assertEquals(2, $matches->count());
+ $match = $this->firstMatch($matches);
+ $this->assertEquals('inside', $match->tagName);
+
+ // Test handling an array of elements
+ $eles = $doc->getElementsByTagName('inside');
+ $array = array();
+ foreach ($eles as $ele) $array[] = $ele;
+ $handler = new QueryPathEventHandler($array);
+ $matches = $handler->getMatches();
+ $this->assertEquals(2, $matches->count());
+ $match = $this->firstMatch($matches);
+ $this->assertEquals('inside', $match->tagName);
+ }
+
+ /**
+ * @expectedException \QueryPath\CSS\ParseException
+ */
+ public function testEmptySelector() {
+ $xml = '<?xml version="1.0" ?><t:test xmlns:t="urn:foo/bar"><t:inside id="first"/>Text<t:inside/><inside/></t:test>';
+ $doc = new \DomDocument();
+ $doc->loadXML($xml);
+
+ // Basic test
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('');
+ $matches = $handler->getMatches();
+ $this->assertEquals(0, $matches->count());
+ }
+
+ public function testElementNS() {
+ $xml = '<?xml version="1.0" ?><t:test xmlns:t="urn:foo/bar"><t:inside id="first"/>Text<t:inside/><inside/></t:test>';
+ $doc = new \DomDocument();
+ $doc->loadXML($xml);
+
+ // Basic test
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('t|inside');
+ $matches = $handler->getMatches();
+ $this->assertEquals(2, $matches->count());
+ $match = $this->firstMatch($matches);
+ $this->assertEquals('t:inside', $match->tagName);
+
+ // Basic test
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('t|test');
+ $matches = $handler->getMatches();
+ $this->assertEquals(1, $matches->count());
+ $match = $this->firstMatch($matches);
+ $this->assertEquals('t:test', $match->tagName);
+ }
+
+
+ /**
+ * @expectedException \QueryPath\CSS\ParseException
+ */
+ public function testFailedElementNS() {
+ $xml = '<?xml version="1.0" ?><t:test xmlns:t="urn:foo/bar"><t:inside id="first"/>Text<t:inside/><inside/></t:test>';
+ $doc = new \DomDocument();
+ $doc->loadXML($xml);
+
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('myns\:mytest');
+ }
+
+ public function testElement() {
+ $xml = '<?xml version="1.0" ?><test><inside id="first"/>Text<inside/></test>';
+ $doc = new \DomDocument();
+ $doc->loadXML($xml);
+
+ // Basic test
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('inside');
+ $matches = $handler->getMatches();
+ $this->assertEquals(2, $matches->count());
+ $match = $this->firstMatch($matches);
+ $this->assertEquals('inside', $match->tagName);
+
+ $doc = new \DomDocument();
+ $doc->loadXML($this->xml);
+
+ // Test getting nested
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('div');
+ $matches = $handler->getMatches();
+ $this->assertEquals(3, $matches->count());
+ $match = $this->firstMatch($matches);
+ $this->assertEquals('div', $match->tagName);
+ $this->assertEquals('one', $match->getAttribute('id'));
+
+ // Test getting a list
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('li');
+ $matches = $handler->getMatches();
+ $this->assertEquals(10, $matches->count());
+ $match = $this->firstMatch($matches);
+ //$this->assertEquals('div', $match->tagName);
+ $this->assertEquals('li-one', $match->getAttribute('id'));
+
+ // Test getting the root element
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('html');
+ $matches = $handler->getMatches();
+ $this->assertEquals(1, $matches->count());
+ $match = $this->firstMatch($matches);
+ $this->assertEquals('html', $match->tagName);
+ }
+
+ public function testElementId() {
+ // Test root element:
+ $xml = '<?xml version="1.0" ?><test><inside id="first"/>Text<inside/></test>';
+ $doc = new \DomDocument();
+ $doc->loadXML($xml);
+
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('#first');
+ $matches = $handler->getMatches();
+ $this->assertEquals(1, $matches->count());
+ $match = $this->firstMatch($matches);
+ $this->assertEquals('inside', $match->tagName);
+
+ // Test a search with restricted scope:
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('inside#first');
+ $matches = $handler->getMatches();
+
+ $this->assertEquals(1, $matches->count());
+ $match = $this->firstMatch($matches);
+ $this->assertEquals('inside', $match->tagName);
+
+ }
+
+ public function testAnyElementInNS() {
+ $xml = '<?xml version="1.0" ?><ns1:test xmlns:ns1="urn:foo/bar"><ns1:inside/>Text<ns1:inside/></ns1:test>';
+ $doc = new \DomDocument();
+ $doc->loadXML($xml);
+
+ // Test handing it a DOM Document
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('ns1|*');
+ $matches = $handler->getMatches();
+
+ $this->assertEquals(3, $matches->count());
+ $match = $this->firstMatch($matches);
+ $this->assertEquals('ns1:test', $match->tagName);
+
+ // Test Issue #30:
+ $xml = '<?xml version="1.0" ?>
+ <ns1:test xmlns:ns1="urn:foo/bar">
+ <ns1:inside>
+ <ns1:insideInside>Test</ns1:insideInside>
+ </ns1:inside>
+ </ns1:test>';
+ $doc = new \DomDocument();
+ $doc->loadXML($xml);
+
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('ns1|test>*');
+ $matches = $handler->getMatches();
+
+ $this->assertEquals(1, $matches->count());
+ $match = $this->firstMatch($matches);
+ $this->assertEquals('ns1:inside', $match->tagName);
+ }
+
+ public function testAnyElement() {
+ $xml = '<?xml version="1.0" ?><test><inside/>Text<inside/></test>';
+ $doc = new \DomDocument();
+ $doc->loadXML($xml);
+
+ // Test handing it a DOM Document
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('*');
+ $matches = $handler->getMatches();
+
+ $this->assertEquals(3, $matches->count());
+ $match = $this->firstMatch($matches);
+ $this->assertEquals('test', $match->tagName);
+
+ $doc = new \DomDocument();
+ $doc->loadXML($this->xml);
+
+ // Test handing it a DOM Document
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('#two *');
+ $matches = $handler->getMatches();
+ $this->assertEquals(1, $matches->count());
+ $match = $this->firstMatch($matches);
+ $this->assertEquals('three', $match->getAttribute('id'));
+
+ // Regression for issue #30
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('#one>*');
+ $matches = $handler->getMatches();
+
+ $this->assertEquals(1, $matches->count(), 'Should match just top div.');
+ $match = $this->firstMatch($matches);
+ $this->assertEquals('two', $match->getAttribute('id'), 'Should match ID #two');
+ }
+
+ public function testElementClass() {
+ $xml = '<?xml version="1.0" ?><test><inside class="foo" id="one"/>Text<inside/></test>';
+ $doc = new \DomDocument();
+ $doc->loadXML($xml);
+
+ // Test basic class
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('.foo');
+ $matches = $handler->getMatches();
+ $this->assertEquals(1, $matches->count());
+ $match = $this->firstMatch($matches);
+ $this->assertEquals('one', $match->getAttribute('id'));
+
+ // Test class in element
+ $doc = new \DomDocument();
+ $doc->loadXML($this->xml);
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('li.Odd');
+ $matches = $handler->getMatches();
+ $this->assertEquals(5, $matches->count());
+ $match = $this->nthMatch($matches, 4);
+ $this->assertEquals('li-nine', $match->getAttribute('id'));
+
+ // Test ID/class combo
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('.Odd#li-nine');
+ $matches = $handler->getMatches();
+ $this->assertEquals(1, $matches->count());
+ $match = $this->firstMatch($matches);
+ $this->assertEquals('li-nine', $match->getAttribute('id'));
+
+ }
+
+ public function testDirectDescendant() {
+ $xml = '<?xml version="1.0" ?>
+ <test>
+ <inside class="foo" id="one"/>
+ Text
+ <inside id="two">
+ <inside id="inner-one"/>
+ </inside>
+ </test>';
+ $doc = new \DomDocument();
+ $doc->loadXML($xml);
+
+ // Test direct descendent
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('test > inside');
+ $matches = $handler->getMatches();
+ $this->assertEquals(2, $matches->count());
+ $match = $this->nthMatch($matches, 1);
+ $this->assertEquals('two', $match->getAttribute('id'));
+
+ }
+
+ public function testAttribute() {
+ $xml = '<?xml version="1.0" ?><test><inside id="one" name="antidisestablishmentarianism"/>Text<inside/></test>';
+ $doc = new \DomDocument();
+ $doc->loadXML($xml);
+
+ // Test match on attr name
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('inside[name]');
+ $matches = $handler->getMatches();
+ $this->assertEquals(1, $matches->count());
+ $match = $this->firstMatch($matches);
+ $this->assertEquals('one', $match->getAttribute('id'));
+
+ // Test broken form
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('inside[@name]');
+ $matches = $handler->getMatches();
+ $this->assertEquals(1, $matches->count());
+ $match = $this->firstMatch($matches);
+ $this->assertEquals('one', $match->getAttribute('id'));
+
+ // Test match on attr name and equals value
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('inside[name="antidisestablishmentarianism"]');
+ $matches = $handler->getMatches();
+ $this->assertEquals(1, $matches->count());
+ $match = $this->firstMatch($matches);
+ $this->assertEquals('one', $match->getAttribute('id'));
+
+ // Test match on containsInString
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('inside[name*="disestablish"]');
+ $matches = $handler->getMatches();
+ $this->assertEquals(1, $matches->count());
+ $match = $this->firstMatch($matches);
+ $this->assertEquals('one', $match->getAttribute('id'));
+
+ // Test match on beginsWith
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('inside[name^="anti"]');
+ $matches = $handler->getMatches();
+ $this->assertEquals(1, $matches->count());
+ $match = $this->firstMatch($matches);
+ $this->assertEquals('one', $match->getAttribute('id'));
+
+ // Test match on endsWith
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('inside[name$="ism"]');
+ $matches = $handler->getMatches();
+ $this->assertEquals(1, $matches->count());
+ $match = $this->firstMatch($matches);
+ $this->assertEquals('one', $match->getAttribute('id'));
+
+ // Test containsWithSpace
+ $xml = '<?xml version="1.0" ?><test><inside id="one" name="anti dis establishment arian ism"/>Text<inside/></test>';
+ $doc = new \DomDocument();
+ $doc->loadXML($xml);
+
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('inside[name~="dis"]');
+ $matches = $handler->getMatches();
+ $this->assertEquals(1, $matches->count());
+ $match = $this->firstMatch($matches);
+ $this->assertEquals('one', $match->getAttribute('id'));
+
+ // Test containsWithHyphen
+ $xml = '<?xml version="1.0" ?><test><inside id="one" name="en-us"/>Text<inside/></test>';
+ $doc = new \DomDocument();
+ $doc->loadXML($xml);
+
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('inside[name|="us"]');
+ $matches = $handler->getMatches();
+ $this->assertEquals(1, $matches->count());
+ $match = $this->firstMatch($matches);
+ $this->assertEquals('one', $match->getAttribute('id'));
+
+ }
+
+ public function testPseudoClassLang() {
+
+ $xml = '<?xml version="1.0" ?><test><inside lang="en-us" id="one"/>Text<inside/></test>';
+ $doc = new \DomDocument();
+ $doc->loadXML($xml);
+
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find(':lang(en-us)');
+ $matches = $handler->getMatches();
+ $this->assertEquals(1, $matches->count());
+ $match = $this->firstMatch($matches);
+ $this->assertEquals('one', $match->getAttribute('id'));
+
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('inside:lang(en)');
+ $matches = $handler->getMatches();
+ $this->assertEquals(1, $matches->count());
+ $match = $this->firstMatch($matches);
+ $this->assertEquals('one', $match->getAttribute('id'));
+
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('inside:lang(us)');
+ $matches = $handler->getMatches();
+ $this->assertEquals(1, $matches->count());
+ $match = $this->firstMatch($matches);
+ $this->assertEquals('one', $match->getAttribute('id'));
+
+ $xml = '<?xml version="1.0" ?><test><inside lang="en-us" id="one"/>Text<inside lang="us" id="two"/></test>';
+ $doc = new \DomDocument();
+ $doc->loadXML($xml);
+
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find(':lang(us)');
+ $matches = $handler->getMatches();
+ $this->assertEquals(2, $matches->count());
+ $match = $this->nthMatch($matches, 1);
+ $this->assertEquals('two', $match->getAttribute('id'));
+
+ $xml = '<?xml version="1.0" ?>
+ <test xmlns="http://aleph-null.tv/xml" xmlns:xml="http://www.w3.org/XML/1998/namespace">
+ <inside lang="en-us" id="one"/>Text
+ <inside xml:lang="en-us" id="two"/>
+ </test>';
+ $doc = new \DomDocument();
+ $doc->loadXML($xml);
+
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find(':lang(us)');
+ $matches = $handler->getMatches();
+ $this->assertEquals(2, $matches->count());
+ $match = $this->nthMatch($matches, 1);
+ $this->assertEquals('two', $match->getAttribute('id'));
+ }
+
+ public function testPseudoClassEnabledDisabledChecked() {
+ $xml = '<?xml version="1.0" ?>
+ <test>
+ <inside enabled="enabled" id="one"/>Text
+ <inside disabled="disabled" id="two"/>
+ <inside checked="FOOOOO" id="three"/>
+ </test>';
+ $doc = new \DomDocument();
+ $doc->loadXML($xml);
+
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find(':enabled');
+ $matches = $handler->getMatches();
+ $this->assertEquals(1, $matches->count());
+ $match = $this->firstMatch($matches);
+ $this->assertEquals('one', $match->getAttribute('id'));
+
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find(':disabled');
+ $matches = $handler->getMatches();
+ $this->assertEquals(1, $matches->count());
+ $match = $this->firstMatch($matches);
+ $this->assertEquals('two', $match->getAttribute('id'));
+
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find(':checked()');
+ $matches = $handler->getMatches();
+ $this->assertEquals(1, $matches->count());
+ $match = $this->firstMatch($matches);
+ $this->assertEquals('three', $match->getAttribute('id'));
+ }
+
+ public function testPseudoClassLink() {
+ $xml = '<?xml version="1.0"?><a><b href="foo"/><c href="foo"/></a>';
+ $qp = qp($xml, ':link');
+ $this->assertEquals(2, $qp->size());
+ }
+
+ public function testPseudoClassXReset() {
+ $xml = '<?xml version="1.0" ?>
+ <test>
+ <inside enabled="enabled" id="one"/>Text
+ <inside disabled="disabled" id="two"/>
+ <inside checked="FOOOOO" id="three"/>
+ </test>';
+ $doc = new \DomDocument();
+ $doc->loadXML($xml);
+
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('inside');
+ $matches = $handler->getMatches();
+ $this->assertEquals(3, $matches->count());
+ $handler->find(':x-reset');
+ $matches = $handler->getMatches();
+ $this->assertEquals(1, $matches->count());
+ $this->assertEquals('test', $this->firstMatch($matches)->tagName);
+ }
+
+ public function testPseudoClassRoot() {
+ $xml = '<?xml version="1.0" ?>
+ <test>
+ <inside enabled="enabled" id="one"/>Text
+ <inside disabled="disabled" id="two"/>
+ <inside checked="FOOOOO" id="three"/>
+ </test>';
+ $doc = new \DomDocument();
+ $doc->loadXML($xml);
+ $start = $doc->getElementsByTagName('inside');
+
+ // Start "deep in the doc" and traverse backward.
+ $handler = new QueryPathEventHandler($start);
+ $handler->find(':root');
+ $matches = $handler->getMatches();
+ $this->assertEquals(1, $matches->count());
+ $this->assertEquals('test', $this->firstMatch($matches)->tagName);
+ }
+
+ // Test removed so I can re-declare
+ // listPeerElements as private.
+ public function xtestListPeerElements() {
+ $xml = '<?xml version="1.0" ?>
+ <test>
+ <i class="odd" id="one"/>
+ <i class="even" id="two"/>
+ <i class="odd" id="three"/>
+ <i class="even" id="four"/>
+ <i class="odd" id="five"/>
+ <e class="even" id="six"/>
+ </test>';
+ $doc = new \DomDocument();
+ $doc->loadXML($xml);
+
+ // Test full list
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('#one');
+ $matches = $handler->getMatches();
+ $peers = $handler->listPeerElements($this->firstMatch($matches));
+ $this->assertEquals(6, count($peers));
+ }
+ /*
+ public function testChildAtIndex() {
+ $xml = '<?xml version="1.0" ?>
+ <test>
+ <i class="odd" id="one"/>
+ <i class="even" id="two"/>
+ <i class="odd" id="three"/>
+ <i class="even" id="four"/>
+ <i class="odd" id="five"/>
+ <e class="even" id="six"/>
+ </test>';
+ $doc = new \DomDocument();
+ $doc->loadXML($xml);
+
+ // Test full list
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('test:child-at-index(1)');
+ $matches = $handler->getMatches();
+ $this->assertEquals(1, $matches->count());
+ $this->assertEquals('one', $this->nthMatch($matches, 1)->getAttribute('id'));
+ }*/
+
+ public function testPseudoClassNthChild() {
+ $xml = '<?xml version="1.0" ?>
+ <test>
+ <i class="odd" id="one"/>
+ <i class="even" id="two"/>
+ <i class="odd" id="three"/>
+ <i class="even" id="four"/>
+ <i class="odd" id="five"/>
+ <e class="even" id="six"/>
+ </test>';
+ $doc = new \DomDocument();
+ $doc->loadXML($xml);
+
+ // Test full list
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find(':root :even');
+ $matches = $handler->getMatches();
+ $this->assertEquals(3, $matches->count());
+ $this->assertEquals('four', $this->nthMatch($matches, 1)->getAttribute('id'));
+
+ // Test restricted to specific element
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('i:even');
+ $matches = $handler->getMatches();
+ $this->assertEquals(2, $matches->count());
+ $this->assertEquals('four', $this->nthMatch($matches, 1)->getAttribute('id'));
+
+ // Test restricted to specific element, odd this time
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('i:odd');
+ $matches = $handler->getMatches();
+ $this->assertEquals(3, $matches->count());
+ $this->assertEquals('three', $this->nthMatch($matches, 1)->getAttribute('id'));
+
+ // Test nth-child(odd)
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('i:nth-child(odd)');
+ $matches = $handler->getMatches();
+ $this->assertEquals(3, $matches->count());
+ $this->assertEquals('three', $this->nthMatch($matches, 1)->getAttribute('id'));
+
+ // Test nth-child(2n+1)
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('i:nth-child(2n+1)');
+ $matches = $handler->getMatches();
+ $this->assertEquals(3, $matches->count());
+ $this->assertEquals('three', $this->nthMatch($matches, 1)->getAttribute('id'));
+
+ // Test nth-child(2n) (even)
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('i:nth-child(2n)');
+ $matches = $handler->getMatches();
+ $this->assertEquals(2, $matches->count());
+ $this->assertEquals('four', $this->nthMatch($matches, 1)->getAttribute('id'));
+
+ // Not totally sure what should be returned here
+ // Test nth-child(-2n)
+ // $handler = new QueryPathEventHandler($doc);
+ // $handler->find('i:nth-child(-2n)');
+ // $matches = $handler->getMatches();
+ // $this->assertEquals(2, $matches->count());
+ // $this->assertEquals('four', $this->nthMatch($matches, 1)->getAttribute('id'));
+
+ // Test nth-child(2n-1) (odd, equiv to 2n + 1)
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('i:nth-child(2n-1)');
+ $matches = $handler->getMatches();
+ $this->assertEquals(3, $matches->count());
+ $this->assertEquals('three', $this->nthMatch($matches, 1)->getAttribute('id'));
+
+ // Test nth-child(4n) (every fourth row)
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('i:nth-child(4n)');
+ $matches = $handler->getMatches();
+ $this->assertEquals(1, $matches->count());
+ $this->assertEquals('four', $this->nthMatch($matches, 0)->getAttribute('id'));
+
+ // Test nth-child(4n+1) (first of every four rows)
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('i:nth-child(4n+1)');
+ $matches = $handler->getMatches();
+ // Should match rows one and five
+ $this->assertEquals(2, $matches->count());
+ $this->assertEquals('five', $this->nthMatch($matches, 1)->getAttribute('id'));
+
+ // Test nth-child(1) (First row)
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('i:nth-child(1)');
+ $matches = $handler->getMatches();
+ $this->assertEquals(1, $matches->count());
+ $this->assertEquals('one', $this->firstMatch($matches)->getAttribute('id'));
+
+ // Test nth-child(0n-0) (Empty list)
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('i:nth-child(0n-0)');
+ $matches = $handler->getMatches();
+ $this->assertEquals(0, $matches->count());
+
+ // Test nth-child(-n+3) (First three lines)
+ // $handler = new QueryPathEventHandler($doc);
+ // $handler->find('i:nth-child(-n+3)');
+ // $matches = $handler->getMatches();
+ // $this->assertEquals(3, $matches->count());
+
+ $xml = '<?xml version="1.0" ?>
+ <test>
+ <i class="odd" id="one"/>
+ <i class="even" id="two"/>
+ <i class="odd" id="three">
+ <i class="odd" id="inner-one"/>
+ <i class="even" id="inner-two"/>
+ </i>
+ <i class="even" id="four"/>
+ <i class="odd" id="five"/>
+ <e class="even" id="six"/>
+ </test>';
+ $doc = new \DomDocument();
+ $doc->loadXML($xml);
+
+ // Test nested items.
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('i:nth-child(odd)');
+ $matches = $handler->getMatches();
+ $this->assertEquals(4, $matches->count());
+ $matchIDs = array();
+ foreach ($matches as $m) {
+ $matchIDs[] = $m->getAttribute('id');
+ }
+// $matchIDs = sort($matchIDs);
+ $this->assertEquals(array('one', 'three', 'inner-one', 'five'), $matchIDs);
+ //$this->assertEquals('inner-one', $matches[3]->getAttribute('id'));
+
+ }
+ public function testPseudoClassOnlyChild() {
+ $xml = '<?xml version="1.0" ?>
+ <test>
+ <i class="odd" id="one"/>
+ </test>';
+ $doc = new \DomDocument();
+ $doc->loadXML($xml);
+
+ // Test single last child.
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('i:only-child');
+ $matches = $handler->getMatches();
+ $this->assertEquals(1, $matches->count());
+ $this->assertEquals('one', $this->firstMatch($matches)->getAttribute('id'));
+
+ $xml = '<?xml version="1.0" ?>
+ <test>
+ <i class="odd" id="one"/>
+ <i class="odd" id="two"/>
+ </test>';
+ $doc = new \DomDocument();
+ $doc->loadXML($xml);
+
+ // Test single last child.
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('i:only-child');
+ $matches = $handler->getMatches();
+ $this->assertEquals(0, $matches->count());
+ //$this->assertEquals('one', $this->firstMatch($matches)->getAttribute('id'));
+ }
+
+ public function testPseudoClassOnlyOfType() {
+ // TODO: Added this late (it was missing in original test),
+ // and I'm not sure if the assumed behavior is correct.
+
+ $xml = '<?xml version="1.0" ?>
+ <test>
+ <i class="odd" id="one"/>
+ </test>';
+ $doc = new \DomDocument();
+ $doc->loadXML($xml);
+
+ // Test single last child.
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('i:only-of-type');
+ $matches = $handler->getMatches();
+ $this->assertEquals(1, $matches->count());
+ $this->assertEquals('one', $this->firstMatch($matches)->getAttribute('id'));
+
+
+ $xml = '<?xml version="1.0" ?>
+ <test>
+ <i class="odd" id="one"/>
+ <i class="odd" id="two"/>
+ </test>';
+ $doc = new \DomDocument();
+ $doc->loadXML($xml);
+
+ // Test single last child.
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('i:only-of-type');
+ $matches = $handler->getMatches();
+ $this->assertEquals(0, $matches->count());
+ }
+
+ public function testPseudoClassFirstChild() {
+ $xml = '<?xml version="1.0" ?>
+ <test>
+ <i class="odd" id="one"/>
+ <i class="even" id="two"/>
+ <i class="odd" id="three"/>
+ <i class="even" id="four">
+ <i class="odd" id="inner-one"/>
+ <i class="even" id="inner-two"/>
+ <i class="odd" id="inner-three"/>
+ <i class="even" id="inner-four"/>
+ </i>
+ <i class="odd" id="five"/>
+ <e class="even" id="six"/>
+ </test>';
+ $doc = new \DomDocument();
+ $doc->loadXML($xml);
+
+ // Test single last child.
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('#four > i:first-child');
+ $matches = $handler->getMatches();
+ $this->assertEquals(1, $matches->count());
+ $this->assertEquals('inner-one', $this->firstMatch($matches)->getAttribute('id'));
+
+ // Test for two last children
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('i:first-child');
+ $matches = $handler->getMatches();
+ $this->assertEquals(2, $matches->count());
+ $this->assertEquals('inner-one', $this->nthMatch($matches, 1)->getAttribute('id'));
+ }
+
+ public function testPseudoClassLastChild() {
+ //print '----' . PHP_EOL;
+ $xml = '<?xml version="1.0" ?>
+ <test>
+ <i class="odd" id="one"/>
+ <i class="even" id="two"/>
+ <i class="odd" id="three"/>
+ <i class="even" id="four">
+ <i class="odd" id="inner-one"/>
+ <i class="even" id="inner-two"/>
+ <i class="odd" id="inner-three"/>
+ <i class="even" id="inner-four"/>
+ </i>
+ <i class="odd" id="five"/>
+ <e class="even" id="six"/>
+ </test>';
+ $doc = new \DomDocument();
+ $doc->loadXML($xml);
+
+ // Test single last child.
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('#four > i:last-child');
+ $matches = $handler->getMatches();
+ $this->assertEquals(1, $matches->count());
+ $this->assertEquals('inner-four', $this->nthMatch($matches, 0)->getAttribute('id'));
+
+ // Test for two last children
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('i:last-child');
+ $matches = $handler->getMatches();
+ $this->assertEquals(2, $matches->count());
+ $this->assertEquals('inner-four', $this->nthMatch($matches, 0)->getAttribute('id'));
+ $this->assertEquals('five', $this->nthMatch($matches, 1)->getAttribute('id'));
+ }
+
+ public function testPseudoClassNthLastChild() {
+ $xml = '<?xml version="1.0" ?>
+ <test>
+ <i class="odd" id="one"/>
+ <i class="even" id="two"/>
+ <i class="odd" id="three"/>
+ <i class="even" id="four">
+ <i class="odd" id="inner-one"/>
+ <i class="even" id="inner-two"/>
+ <i class="odd" id="inner-three"/>
+ <i class="even" id="inner-four"/>
+ </i>
+ <i class="odd" id="five"/>
+ <e class="even" id="six"/>
+ </test>';
+ $doc = new \DomDocument();
+ $doc->loadXML($xml);
+
+ // Test alternate rows from the end.
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('#four > i:nth-last-child(odd)');
+ $matches = $handler->getMatches();
+ $this->assertEquals(2, $matches->count());
+ $this->assertEquals('inner-two', $this->nthMatch($matches, 0)->getAttribute('id'));
+ $this->assertEquals('inner-four', $this->nthMatch($matches, 1)->getAttribute('id'));
+
+ // According to spec, this should be last two elements.
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('#four > i:nth-last-child(-1n+2)');
+ $matches = $handler->getMatches();
+ //print $this->firstMatch($matches)->getAttribute('id');
+ $this->assertEquals(2, $matches->count());
+ $this->assertEquals('inner-three', $this->nthMatch($matches, 0)->getAttribute('id'));
+ $this->assertEquals('inner-four', $this->nthMatch($matches, 1)->getAttribute('id'));
+ }
+
+ public function testPseudoClassFirstOfType() {
+ $xml = '<?xml version="1.0" ?>
+ <test>
+ <n class="odd" id="one"/>
+ <i class="even" id="two"/>
+ <i class="odd" id="three"/>
+ </test>';
+ $doc = new \DomDocument();
+ $doc->loadXML($xml);
+
+ // Test alternate rows from the end.
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('i:first-of-type(odd)');
+ $matches = $handler->getMatches();
+ $this->assertEquals(1, $matches->count());
+ $this->assertEquals('two', $this->firstMatch($matches)->getAttribute('id'));
+ }
+
+ public function testPseudoClassNthFirstOfType() {
+ $xml = '<?xml version="1.0" ?>
+ <test>
+ <n class="odd" id="one"/>
+ <i class="even" id="two"/>
+ <i class="odd" id="three"/>
+ </test>';
+ $doc = new \DomDocument();
+ $doc->loadXML($xml);
+
+ // Test alternate rows from the end.
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('i:first-of-type(1)');
+ $matches = $handler->getMatches();
+ $this->assertEquals(1, $matches->count());
+ $this->assertEquals('two', $this->firstMatch($matches)->getAttribute('id'));
+ }
+
+ public function testPseudoClassLastOfType() {
+ $xml = '<?xml version="1.0" ?>
+ <test>
+ <n class="odd" id="one"/>
+ <i class="even" id="two"/>
+ <i class="odd" id="three"/>
+ </test>';
+ $doc = new \DomDocument();
+ $doc->loadXML($xml);
+
+ // Test alternate rows from the end.
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('i:last-of-type(odd)');
+ $matches = $handler->getMatches();
+ $this->assertEquals(1, $matches->count());
+ $this->assertEquals('three', $this->firstMatch($matches)->getAttribute('id'));
+ }
+
+ public function testPseudoNthClassLastOfType() {
+ $xml = '<?xml version="1.0" ?>
+ <test>
+ <n class="odd" id="one"/>
+ <i class="even" id="two"/>
+ <i class="odd" id="three"/>
+ </test>';
+ $doc = new \DomDocument();
+ $doc->loadXML($xml);
+
+ // Test alternate rows from the end.
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('i:nth-last-of-type(1)');
+ $matches = $handler->getMatches();
+ $this->assertEquals(1, $matches->count());
+ $this->assertEquals('three', $this->firstMatch($matches)->getAttribute('id'));
+
+
+ // Issue #56: an+b not working.
+ $xml = '<?xml version="1.0"?>
+ <root>
+ <div>I am the first div.</div>
+ <div>I am the second div.</div>
+ <div>I am the third div.</div>
+ <div>I am the fourth div.</div>
+ <div id="five">I am the fifth div.</div>
+ <div id="six">I am the sixth div.</div>
+ <div id="seven">I am the seventh div.</div>
+ </root>';
+ $doc = new \DomDocument();
+ $doc->loadXML($xml);
+
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('div:nth-last-of-type(-n+3)');
+ $matches = $handler->getMatches();
+
+ $this->assertEquals(3, $matches->count());
+ $this->assertEquals('five', $this->firstMatch($matches)->getAttribute('id'));
+
+ }
+
+ public function testPseudoClassEmpty() {
+ $xml = '<?xml version="1.0" ?>
+ <test>
+ <n class="odd" id="one"/>
+ <i class="even" id="two"></i>
+ </test>';
+ $doc = new \DomDocument();
+ $doc->loadXML($xml);
+
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('n:empty');
+ $matches = $handler->getMatches();
+ $this->assertEquals(1, $matches->count());
+ $this->assertEquals('one', $this->firstMatch($matches)->getAttribute('id'));
+
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('i:empty');
+ $matches = $handler->getMatches();
+ $this->assertEquals(1, $matches->count());
+ $this->assertEquals('two', $this->firstMatch($matches)->getAttribute('id'));
+ }
+
+ public function testPseudoClassFirst() {
+ $xml = '<?xml version="1.0" ?>
+ <test>
+ <i class="odd" id="one"/>
+ <i class="even" id="two"/>
+ <i class="odd" id="three"/>
+ </test>';
+ $doc = new \DomDocument();
+ $doc->loadXML($xml);
+
+ // Test alternate rows from the end.
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('i:first');
+ $matches = $handler->getMatches();
+ $this->assertEquals(1, $matches->count());
+ $this->assertEquals('one', $this->firstMatch($matches)->getAttribute('id'));
+ }
+
+ public function testPseudoClassLast() {
+ $xml = '<?xml version="1.0" ?>
+ <test>
+ <i class="odd" id="one"/>
+ <i class="even" id="two"/>
+ <i class="odd" id="three"/>
+ </test>';
+ $doc = new \DomDocument();
+ $doc->loadXML($xml);
+
+ // Test alternate rows from the end.
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('i:last');
+ $matches = $handler->getMatches();
+ $this->assertEquals(1, $matches->count());
+ $this->assertEquals('three', $this->firstMatch($matches)->getAttribute('id'));
+ }
+
+ public function testPseudoClassGT() {
+ $xml = '<?xml version="1.0" ?>
+ <test>
+ <i class="odd" id="one"/>
+ <i class="even" id="two"/>
+ <i class="odd" id="three"/>
+ </test>';
+ $doc = new \DomDocument();
+ $doc->loadXML($xml);
+
+ // Test alternate rows from the end.
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('i:gt(1)');
+ $matches = $handler->getMatches();
+ $this->assertEquals(2, $matches->count());
+ $this->assertEquals('two', $this->firstMatch($matches)->getAttribute('id'));
+ }
+ public function testPseudoClassLT() {
+ $xml = '<?xml version="1.0" ?>
+ <test>
+ <i class="odd" id="one"/>
+ <i class="even" id="two"/>
+ <i class="odd" id="three"/>
+ </test>';
+ $doc = new \DomDocument();
+ $doc->loadXML($xml);
+
+ // Test alternate rows from the end.
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('i:lt(3)');
+ $matches = $handler->getMatches();
+ $this->assertEquals(2, $matches->count());
+ $this->assertEquals('one', $this->nthMatch($matches,0)->getAttribute('id'));
+ $this->assertEquals('two', $this->nthMatch($matches,1)->getAttribute('id'));
+ }
+ public function testPseudoClassNTH() {
+ $xml = '<?xml version="1.0" ?>
+ <test>
+ <i class="odd" id="one"/>
+ <i class="even" id="two"/>
+ <i class="odd" id="three"/>
+ </test>';
+ $doc = new \DomDocument();
+ $doc->loadXML($xml);
+
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('i:nth(2)');
+ $matches = $handler->getMatches();
+ $this->assertEquals(1, $matches->count());
+ $this->assertEquals('two', $this->firstMatch($matches)->getAttribute('id'));
+
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('i:eq(2)');
+ $matches = $handler->getMatches();
+ $this->assertEquals(1, $matches->count());
+ $this->assertEquals('two', $this->firstMatch($matches)->getAttribute('id'));
+ }
+ public function testPseudoClassNthOfType() {
+ $xml = '<?xml version="1.0" ?>
+ <test>
+ <i class="odd" id="one"/>
+ <i class="even" id="two"/>
+ <i class="odd" id="three"/>
+ </test>';
+ $doc = new \DomDocument();
+ $doc->loadXML($xml);
+
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('i:nth-of-type(2)');
+ $matches = $handler->getMatches();
+ $this->assertEquals(1, $matches->count());
+ $this->assertEquals('two', $this->firstMatch($matches)->getAttribute('id'));
+ }
+
+ public function testPseudoClassFormElements() {
+ $form = array('text', 'radio', 'checkbox', 'button', 'password');
+ $xml = '<?xml version="1.0" ?>
+ <test>
+ <input type="%s" class="odd" id="one"/>
+ </test>';
+
+ foreach ($form as $item) {
+ $doc = new \DomDocument();
+ $doc->loadXML(sprintf($xml, $item));
+
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find(':' . $item);
+ $matches = $handler->getMatches();
+ $this->assertEquals(1, $matches->count());
+ $this->assertEquals('one', $this->firstMatch($matches)->getAttribute('id'));
+ }
+ }
+
+ public function testPseudoClassHeader() {
+ $xml = '<?xml version="1.0" ?>
+ <test>
+ <h1 class="odd" id="one"/>
+ <h2 class="even" id="two"/>
+ <h6 class="odd" id="three"/>
+ </test>';
+ $doc = new \DomDocument();
+ $doc->loadXML($xml);
+
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('test :header');
+ $matches = $handler->getMatches();
+ $this->assertEquals(3, $matches->count());
+ $this->assertEquals('three', $this->nthMatch($matches, 2)->getAttribute('id'));
+ }
+
+ public function testPseudoClassContains() {
+ $xml = '<?xml version="1.0" ?>
+ <test>
+ <p id="one">This is text.</p>
+ <p id="two"><i>More text</i></p>
+ </test>';
+ $doc = new \DomDocument();
+ $doc->loadXML($xml);
+
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('p:contains(This is text.)');
+ $matches = $handler->getMatches();
+ $this->assertEquals(1, $matches->count());
+ $this->assertEquals('one', $this->firstMatch($matches)->getAttribute('id'));
+
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('* :contains(More text)');
+ $matches = $handler->getMatches();
+ $this->assertEquals(2, $matches->count(), 'Matches two instance of same text?');
+ $this->assertEquals('two', $this->firstMatch($matches)->getAttribute('id'));
+
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('p:contains("This is text.")');
+ $matches = $handler->getMatches();
+ $this->assertEquals(1, $matches->count(), 'Quoted text matches unquoted pcdata');
+ $this->assertEquals('one', $this->firstMatch($matches)->getAttribute('id'));
+
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('p:contains(\\\'This is text.\\\')');
+ $matches = $handler->getMatches();
+ $this->assertEquals(1, $matches->count(), 'One match for quoted string.');
+ $this->assertEquals('one', $this->firstMatch($matches)->getAttribute('id'));
+
+ // Test for issue #32
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('p:contains(text)');
+ $matches = $handler->getMatches();
+ $this->assertEquals(2, $matches->count(), 'Two matches for fragment of string.');
+ $this->assertEquals('one', $this->firstMatch($matches)->getAttribute('id'));
+
+ }
+
+ public function testPseudoClassContainsExactly() {
+ $xml = '<?xml version="1.0" ?>
+ <test>
+ <p id="one">This is text.</p>
+ <p id="two"><i>More text</i></p>
+ </test>';
+ $doc = new \DomDocument();
+ $doc->loadXML($xml);
+
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('p:contains(This is text.)');
+ $matches = $handler->getMatches();
+ $this->assertEquals(1, $matches->count());
+ $this->assertEquals('one', $this->firstMatch($matches)->getAttribute('id'));
+
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('* :contains(More text)');
+ $matches = $handler->getMatches();
+ $this->assertEquals(2, $matches->count(), 'Matches two instance of same text.');
+ $this->assertEquals('two', $this->firstMatch($matches)->getAttribute('id'));
+
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('p:contains("This is text.")');
+ $matches = $handler->getMatches();
+ $this->assertEquals(1, $matches->count(), 'Quoted text matches unquoted pcdata');
+ $this->assertEquals('one', $this->firstMatch($matches)->getAttribute('id'));
+
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('p:contains(\\\'This is text.\\\')');
+ $matches = $handler->getMatches();
+ $this->assertEquals(1, $matches->count(), 'One match for quoted string.');
+ $this->assertEquals('one', $this->firstMatch($matches)->getAttribute('id'));
+ }
+
+ public function testPseudoClassHas() {
+ $xml = '<?xml version="1.0" ?>
+ <test>
+ <outer id="one">
+ <inner/>
+ </outer>
+ <outer id="two"/>
+ </test>';
+ $doc = new \DomDocument();
+ $doc->loadXML($xml);
+
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('outer:has(inner)');
+ $matches = $handler->getMatches();
+ $this->assertEquals(1, $matches->count());
+ $this->assertEquals('one', $this->firstMatch($matches)->getAttribute('id'));
+ }
+
+ public function testPseudoClassNot() {
+ $xml = '<?xml version="1.0" ?>
+ <test>
+ <outer id="one">
+ <inner/>
+ </outer>
+ <outer id="two" class="notMe"/>
+ </test>';
+ $doc = new \DomDocument();
+ $doc->loadXML($xml);
+
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('outer:not(#one)');
+ $matches = $handler->getMatches();
+ $this->assertEquals(1, $matches->count());
+ $this->assertEquals('two', $this->firstMatch($matches)->getAttribute('id'));
+
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('outer:not(inner)');
+ $matches = $handler->getMatches();
+ $this->assertEquals(1, $matches->count());
+ $this->assertEquals('two', $this->firstMatch($matches)->getAttribute('id'));
+
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('outer:not(.notMe)');
+ $matches = $handler->getMatches();
+ $this->assertEquals(1, $matches->count());
+ $this->assertEquals('one', $this->firstMatch($matches)->getAttribute('id'));
+ }
+
+ public function testPseudoElement() {
+ $xml = '<?xml version="1.0" ?>
+ <test>
+ <outer id="one">Texts
+
+ More text</outer>
+ <outer id="two" class="notMe"/>
+ </test>';
+ $doc = new \DomDocument();
+ $doc->loadXML($xml);
+
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('outer::first-letter');
+ $matches = $handler->getMatches();
+ $this->assertEquals(1, $matches->count());
+ $this->assertEquals('T', $this->firstMatch($matches)->textContent);
+
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('outer::first-line');
+ $matches = $handler->getMatches();
+ $this->assertEquals(1, $matches->count());
+ $this->assertEquals('Texts', $this->firstMatch($matches)->textContent);
+ }
+
+ public function testAdjacent() {
+ $xml = '<?xml version="1.0" ?>
+ <test>
+ <li id="one"/><li id="two"/><li id="three">
+ <li id="inner-one">
+ <li id="inner-inner-one"/>
+ <li id="inner-inner-one"/>
+ </li>
+ <li id="inner-two"/>
+ </li>
+ <li id="four"/>
+ <li id="five"/>
+ </test>';
+ $doc = new \DomDocument();
+ $doc->loadXML($xml);
+
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('#one + li');
+ $matches = $handler->getMatches();
+ $this->assertEquals(1, $matches->count());
+ $this->assertEquals('two', $this->firstMatch($matches)->getAttribute('id'));
+
+ // Tell it to ignore whitespace nodes.
+ $doc->loadXML($xml, LIBXML_NOBLANKS);
+
+ // Test with whitespace sensitivity weakened.
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('#four + li');
+ $matches = $handler->getMatches();
+ $this->assertEquals(1, $matches->count());
+ $this->assertEquals('five', $this->firstMatch($matches)->getAttribute('id'));
+ }
+ public function testAnotherSelector() {
+ $xml = '<?xml version="1.0" ?>
+ <test>
+ <li id="one"/><li id="two"/><li id="three">
+ <li id="inner-one">
+ <li id="inner-inner-one"/>
+ <li id="inner-inner-one"/>
+ </li>
+ <li id="inner-two"/>
+ </li>
+ <li id="four"/>
+ <li id="five"/>
+ </test>';
+ $doc = new \DomDocument();
+ $doc->loadXML($xml);
+
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('#one, #two');
+ $matches = $handler->getMatches();
+ //print $this->firstMatch($matches)->getAttribute('id') . PHP_EOL;
+ $this->assertEquals(2, $matches->count());
+ $this->assertEquals('two', $this->nthMatch($matches, 1)->getAttribute('id'));
+
+ }
+ public function testSibling() {
+ $xml = '<?xml version="1.0" ?>
+ <test>
+ <li id="one"/><li id="two"/><li id="three">
+ <li id="inner-one">
+ <li id="inner-inner-one"/>
+ <il id="inner-inner-two"/>
+ <li id="dont-match-me"/>
+ </li>
+ <li id="inner-two"/>
+ </li>
+ <li id="four"/>
+ <li id="five"/>
+ </test>';
+ $doc = new \DomDocument();
+ $doc->loadXML($xml);
+
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('#one ~ li');
+ $matches = $handler->getMatches();
+ //print $this->firstMatch($matches)->getAttribute('id') . PHP_EOL;
+ $this->assertEquals(4, $matches->count());
+ $this->assertEquals('three', $this->nthMatch($matches, 1)->getAttribute('id'));
+
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('#two ~ li');
+ $matches = $handler->getMatches();
+ //print $this->firstMatch($matches)->getAttribute('id') . PHP_EOL;
+ $this->assertEquals(3, $matches->count());
+ //$this->assertEquals('three', $this->nthMatch($matches, 1)->getAttribute('id'));
+
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('#inner-one > li ~ il');
+ $matches = $handler->getMatches();
+ //print $this->firstMatch($matches)->getAttribute('id') . PHP_EOL;
+ $this->assertEquals(1, $matches->count());
+ $this->assertEquals('inner-inner-two', $this->firstMatch($matches)->getAttribute('id'));
+ }
+
+ public function testAnyDescendant() {
+ $xml = '<?xml version="1.0" ?>
+ <test>
+ <li id="one"/><li id="two"/><li id="three">
+ <li id="inner-one" class="foo">
+ <li id="inner-inner-one" class="foo"/>
+ <il id="inner-inner-two"/>
+ <li id="dont-match-me"/>
+ </li>
+ <li id="inner-two"/>
+ </li>
+ <li id="four"/>
+ <li id="five"/>
+ </test>';
+ $doc = new \DomDocument();
+ $doc->loadXML($xml);
+
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('*');
+ $matches = $handler->getMatches();
+ $this->assertEquals(11, $matches->count());
+
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('*.foo');
+ $matches = $handler->getMatches();
+ $this->assertEquals(2, $matches->count());
+ $this->assertEquals('inner-inner-one', $this->nthMatch($matches, 1)->getAttribute('id'));
+
+ $handler = new QueryPathEventHandler($doc);
+ $handler->find('test > li *.foo');
+ $matches = $handler->getMatches();
+ $this->assertEquals(2, $matches->count());
+ $this->assertEquals('inner-inner-one', $this->nthMatch($matches, 1)->getAttribute('id'));
+ }
+}