Skip to content

Commit 17ac6b1

Browse files
committed
Add HTMLQuerySelectorAll & HTMLQuerySelector scalar functions
1 parent 8b5a0fb commit 17ac6b1

6 files changed

Lines changed: 116 additions & 8 deletions

File tree

src/core/etl/src/Flow/ETL/Function/HTMLQuerySelector.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public function eval(Row $row) : mixed
2626
}
2727

2828
if (!\class_exists('\Dom\HTMLDocument')) {
29-
return null;
29+
throw new \RuntimeException('This function requires \Dom\HTMLDocument extension available in PHP 8.4+.');
3030
}
3131

3232
return HTMLDocument::createFromString($value->toString())

src/core/etl/src/Flow/ETL/Function/HTMLQuerySelectorAll.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ public function eval(Row $row) : mixed
2626
}
2727

2828
if (!\class_exists('\Dom\HTMLDocument')) {
29-
return null;
29+
throw new \RuntimeException('This function requires \Dom\HTMLDocument extension available in PHP 8.4+.');
3030
}
3131

3232
/* @phpstan-ignore-next-line */
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Flow\ETL\Tests\Integration\Function;
6+
7+
use function Flow\ETL\DSL\{df, from_rows, html_entry, ref, row, rows};
8+
use Dom\Element;
9+
use Flow\Types\Value\HTMLDocument;
10+
use PHPUnit\Framework\Attributes\RequiresPhp;
11+
use PHPUnit\Framework\TestCase;
12+
13+
final class HTMLQuerySelectorAllTest extends TestCase
14+
{
15+
private HTMLDocument $html;
16+
17+
protected function setUp() : void
18+
{
19+
$this->html = new HTMLDocument('<!DOCTYPE html><html><head></head><body><div><span>foobar</span></div></body></html>');
20+
}
21+
22+
#[RequiresPhp('<= 8.4')]
23+
public function test_fails_with_older_php() : void
24+
{
25+
$this->expectException(\RuntimeException::class);
26+
27+
df()
28+
->read(from_rows(rows(row(html_entry('html_raw', $this->html)))))
29+
->withEntry('html', ref('html_raw')->htmlQuerySelectorAll('body div span'))
30+
->fetch();
31+
}
32+
33+
#[RequiresPhp('>= 8.4')]
34+
public function test_invalid_query_all_on_html_document() : void
35+
{
36+
$rows = df()
37+
->read(from_rows(rows(row(html_entry('html_raw', $this->html)))))
38+
->withEntry('html', ref('html_raw')->htmlQuerySelectorAll('body div p'))
39+
->drop('html_raw')
40+
->fetch();
41+
42+
$results = $rows->toArray()[0]['html'] ?? [];
43+
44+
/* @phpstan-ignore-next-line */
45+
self::assertCount(0, $results);
46+
}
47+
48+
#[RequiresPhp('>= 8.4')]
49+
public function test_valid_query_all_on_html_document() : void
50+
{
51+
$rows = df()
52+
->read(from_rows(rows(row(html_entry('html_raw', $this->html)))))
53+
->withEntry('html', ref('html_raw')->htmlQuerySelectorAll('body div span'))
54+
->drop('html_raw')
55+
->fetch();
56+
57+
$results = $rows->toArray()[0]['html'] ?? [];
58+
59+
/* @phpstan-ignore-next-line */
60+
self::assertCount(1, $results);
61+
/* @phpstan-ignore-next-line */
62+
self::assertContainsOnlyInstancesOf(Element::class, $results);
63+
}
64+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Flow\ETL\Tests\Integration\Function;
6+
7+
use function Flow\ETL\DSL\{df, from_rows, html_entry, ref, row, rows};
8+
use Flow\Types\Value\HTMLDocument;
9+
use PHPUnit\Framework\Attributes\RequiresPhp;
10+
use PHPUnit\Framework\TestCase;
11+
12+
final class HTMLQuerySelectorTest extends TestCase
13+
{
14+
private HTMLDocument $html;
15+
16+
protected function setUp() : void
17+
{
18+
$this->html = new HTMLDocument('<!DOCTYPE html><html><head></head><body><div><span>foobar</span></div></body></html>');
19+
}
20+
21+
#[RequiresPhp('<= 8.4')]
22+
public function test_fails_with_older_php() : void
23+
{
24+
$this->expectException(\RuntimeException::class);
25+
26+
df()
27+
->read(from_rows(rows(row(html_entry('html_raw', $this->html)))))
28+
->withEntry('html', ref('html_raw')->htmlQuerySelector('body div span'))
29+
->fetch();
30+
}
31+
32+
#[RequiresPhp('>= 8.4')]
33+
public function test_invalid_query_on_html_document() : void
34+
{
35+
$rows = df()
36+
->read(from_rows(rows(row(html_entry('html_raw', $this->html)))))
37+
->withEntry('html', ref('html_raw')->htmlQuerySelector('body div p'))
38+
->drop('html_raw')
39+
->fetch();
40+
41+
$results = $rows->toArray()[0]['html'] ?? [];
42+
43+
/* @phpstan-ignore-next-line */
44+
self::assertCount(0, $results);
45+
}
46+
}

src/core/etl/tests/Flow/ETL/Tests/Unit/Function/HTMLQuerySelectorAllTest.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,9 @@ public function test_getting_elements_for_given_path() : void
3434
#[RequiresPhp('< 8.4')]
3535
public function test_getting_null_for_older_versions() : void
3636
{
37-
$result = ref('value')->htmlQuerySelectorAll('body div p')->eval(row(flow_context(config())->entryFactory()->create('value', $this->html)));
37+
$this->expectException(\RuntimeException::class);
3838

39-
self::assertNull($result);
39+
ref('value')->htmlQuerySelectorAll('body div p')->eval(row(flow_context(config())->entryFactory()->create('value', $this->html)));
4040
}
4141

4242
#[RequiresPhp('>= 8.4')]

src/core/etl/tests/Flow/ETL/Tests/Unit/Function/HTMLQuerySelectorTest.php

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,16 +31,14 @@ public function test_getting_elements_for_given_path() : void
3131
#[RequiresPhp('< 8.4')]
3232
public function test_getting_null_for_older_versions() : void
3333
{
34-
$result = ref('value')->htmlQuerySelector('body div p')->eval(row(flow_context(config())->entryFactory()->create('value', $this->html)));
34+
$this->expectException(\RuntimeException::class);
3535

36-
self::assertNull($result);
36+
ref('value')->htmlQuerySelector('body div p')->eval(row(flow_context(config())->entryFactory()->create('value', $this->html)));
3737
}
3838

3939
#[RequiresPhp('>= 8.4')]
4040
public function test_getting_null_when_nothing_found() : void
4141
{
42-
$html = new HTMLDocument('<!DOCTYPE html><html><head></head><body><div><span>foobar</span></div></body></html>');
43-
4442
$result = ref('value')->htmlQuerySelector('body div p')->eval(row(flow_context(config())->entryFactory()->create('value', $this->html)));
4543

4644
self::assertNull($result);

0 commit comments

Comments
 (0)