Skip to content

Commit

Permalink
DomQuery: searchs from current node
Browse files Browse the repository at this point in the history
  • Loading branch information
dg committed Dec 5, 2023
1 parent c5eff68 commit 0d70858
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 29 deletions.
2 changes: 1 addition & 1 deletion src/Framework/DomQuery.php
Expand Up @@ -78,7 +78,7 @@ public function has(string $selector): bool
*/
public static function css2xpath(string $css): string
{
$xpath = '//*';
$xpath = './/*';
preg_match_all('/
([#.:]?)([a-z][a-z0-9_-]*)| # id, class, pseudoclass (1,2)
\[
Expand Down
56 changes: 28 additions & 28 deletions tests/Framework/DomQuery.css2Xpath.phpt
Expand Up @@ -8,73 +8,73 @@ use Tester\DomQuery;
require __DIR__ . '/../bootstrap.php';

test('type selectors', function () {
Assert::same('//*', DomQuery::css2xpath('*'));
Assert::same('//foo', DomQuery::css2xpath('foo'));
Assert::same('.//*', DomQuery::css2xpath('*'));
Assert::same('.//foo', DomQuery::css2xpath('foo'));
});


test('#ID', function () {
Assert::same("//*[@id='foo']", DomQuery::css2xpath('#foo'));
Assert::same("//*[@id='id']", DomQuery::css2xpath('*#id'));
Assert::same(".//*[@id='foo']", DomQuery::css2xpath('#foo'));
Assert::same(".//*[@id='id']", DomQuery::css2xpath('*#id'));
});


test('class', function () {
Assert::same("//*[contains(concat(' ', normalize-space(@class), ' '), ' foo ')]", DomQuery::css2xpath('.foo'));
Assert::same("//*[contains(concat(' ', normalize-space(@class), ' '), ' foo ')]", DomQuery::css2xpath('*.foo'));
Assert::same("//*[contains(concat(' ', normalize-space(@class), ' '), ' foo ')][contains(concat(' ', normalize-space(@class), ' '), ' bar ')]", DomQuery::css2xpath('.foo.bar'));
Assert::same(".//*[contains(concat(' ', normalize-space(@class), ' '), ' foo ')]", DomQuery::css2xpath('.foo'));
Assert::same(".//*[contains(concat(' ', normalize-space(@class), ' '), ' foo ')]", DomQuery::css2xpath('*.foo'));
Assert::same(".//*[contains(concat(' ', normalize-space(@class), ' '), ' foo ')][contains(concat(' ', normalize-space(@class), ' '), ' bar ')]", DomQuery::css2xpath('.foo.bar'));
});


test('attribute selectors', function () {
Assert::same('//div[@foo]', DomQuery::css2xpath('div[foo]'));
Assert::same("//div[@foo='bar']", DomQuery::css2xpath('div[foo=bar]'));
Assert::same("//*[@foo='bar']", DomQuery::css2xpath('[foo="bar"]'));
Assert::same("//div[@foo='bar']", DomQuery::css2xpath('div[foo="bar"]'));
Assert::same("//div[@foo='bar']", DomQuery::css2xpath("div[foo='bar']"));
Assert::same("//div[@foo='bar']", DomQuery::css2xpath('div[Foo="bar"]'));
Assert::same("//div[contains(concat(' ', normalize-space(@foo), ' '), ' bar ')]", DomQuery::css2xpath('div[foo~="bar"]'));
Assert::same("//div[contains(@foo, 'bar')]", DomQuery::css2xpath('div[foo*="bar"]'));
Assert::same("//div[starts-with(@foo, 'bar')]", DomQuery::css2xpath('div[foo^="bar"]'));
Assert::same("//div[substring(@foo, string-length(@foo)-0)='bar']", DomQuery::css2xpath('div[foo$="bar"]'));
Assert::same("//div[@foo='bar[]']", DomQuery::css2xpath("div[foo='bar[]']"));
Assert::same("//div[@foo='bar[]']", DomQuery::css2xpath('div[foo="bar[]"]'));
Assert::same('.//div[@foo]', DomQuery::css2xpath('div[foo]'));
Assert::same(".//div[@foo='bar']", DomQuery::css2xpath('div[foo=bar]'));
Assert::same(".//*[@foo='bar']", DomQuery::css2xpath('[foo="bar"]'));
Assert::same(".//div[@foo='bar']", DomQuery::css2xpath('div[foo="bar"]'));
Assert::same(".//div[@foo='bar']", DomQuery::css2xpath("div[foo='bar']"));
Assert::same(".//div[@foo='bar']", DomQuery::css2xpath('div[Foo="bar"]'));
Assert::same(".//div[contains(concat(' ', normalize-space(@foo), ' '), ' bar ')]", DomQuery::css2xpath('div[foo~="bar"]'));
Assert::same(".//div[contains(@foo, 'bar')]", DomQuery::css2xpath('div[foo*="bar"]'));
Assert::same(".//div[starts-with(@foo, 'bar')]", DomQuery::css2xpath('div[foo^="bar"]'));
Assert::same(".//div[substring(@foo, string-length(@foo)-0)='bar']", DomQuery::css2xpath('div[foo$="bar"]'));
Assert::same(".//div[@foo='bar[]']", DomQuery::css2xpath("div[foo='bar[]']"));
Assert::same(".//div[@foo='bar[]']", DomQuery::css2xpath('div[foo="bar[]"]'));
});


test('variants', function () {
Assert::same("//*[@id='foo']|//*[@id='bar']", DomQuery::css2xpath('#foo, #bar'));
Assert::same("//*[@id='foo']|//*[@id='bar']", DomQuery::css2xpath('#foo,#bar'));
Assert::same("//*[@id='foo']|//*[@id='bar']", DomQuery::css2xpath('#foo ,#bar'));
Assert::same(".//*[@id='foo']|//*[@id='bar']", DomQuery::css2xpath('#foo, #bar'));
Assert::same(".//*[@id='foo']|//*[@id='bar']", DomQuery::css2xpath('#foo,#bar'));
Assert::same(".//*[@id='foo']|//*[@id='bar']", DomQuery::css2xpath('#foo ,#bar'));
});


test('descendant combinator', function () {
Assert::same(
"//div[@id='foo']//*[contains(concat(' ', normalize-space(@class), ' '), ' bar ')]",
".//div[@id='foo']//*[contains(concat(' ', normalize-space(@class), ' '), ' bar ')]",
DomQuery::css2xpath('div#foo .bar'),
);
Assert::same(
'//div//*//p',
'.//div//*//p',
DomQuery::css2xpath('div * p'),
);
});


test('child combinator', function () {
Assert::same("//div[@id='foo']/span", DomQuery::css2xpath('div#foo>span'));
Assert::same("//div[@id='foo']/span", DomQuery::css2xpath('div#foo > span'));
Assert::same(".//div[@id='foo']/span", DomQuery::css2xpath('div#foo>span'));
Assert::same(".//div[@id='foo']/span", DomQuery::css2xpath('div#foo > span'));
});


test('general sibling combinator', function () {
Assert::same('//div/following-sibling::span', DomQuery::css2xpath('div ~ span'));
Assert::same('.//div/following-sibling::span', DomQuery::css2xpath('div ~ span'));
});


test('complex', function () {
Assert::same(
"//div[@id='foo']//span[contains(concat(' ', normalize-space(@class), ' '), ' bar ')]"
".//div[@id='foo']//span[contains(concat(' ', normalize-space(@class), ' '), ' bar ')]"
. "|//*[@id='bar']//li[contains(concat(' ', normalize-space(@class), ' '), ' baz ')]//a",
DomQuery::css2xpath('div#foo span.bar, #bar li.baz a'),
);
Expand Down
4 changes: 4 additions & 0 deletions tests/Framework/DomQuery.fromHtml.phpt
Expand Up @@ -26,6 +26,10 @@ Assert::false($q->has('track footer'));
$q = DomQuery::fromHtml('<audio controls><source src="horse.mp3" type="audio/mpeg"></audio>');
Assert::true($q->has('source'));

Assert::count(1, $q->find('audio'));
Assert::count(1, $q->find('audio')[0]->find('source'));
Assert::count(0, $q->find('audio')[0]->find('audio'));


$q = DomQuery::fromHtml("<script>\nvar s = '</div>';</script> <br> <script type='text/javascript'>var s = '</div>';\n</script>");
Assert::true($q->has('script'));
Expand Down

0 comments on commit 0d70858

Please sign in to comment.