diff --git a/.github/workflows/test-suite.yml b/.github/workflows/test-suite.yml index 958028067..785fba6a2 100644 --- a/.github/workflows/test-suite.yml +++ b/.github/workflows/test-suite.yml @@ -8,6 +8,7 @@ on: - 'examples/**' - 'composer.lock' - 'composer.json' + - 'phpunit.xml.dist' push: branches: [ 1.x ] paths: @@ -18,6 +19,7 @@ on: - 'examples/**' - 'composer.lock' - 'composer.json' + - 'phpunit.xml.dist' schedule: - cron: '0 4 * * *' workflow_dispatch: @@ -50,4 +52,4 @@ jobs: uses: ./.github/workflows/job-mutation-tests.yml benchmark-tests: - uses: ./.github/workflows/job-benchmark-tests.yml \ No newline at end of file + uses: ./.github/workflows/job-benchmark-tests.yml diff --git a/phpunit.xml.dist b/phpunit.xml.dist index dc6056917..a9d0d1eb1 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -72,10 +72,10 @@ src/lib/parquet-viewer/tests/Flow/ParquetViewer/Tests/Integration - + src/lib/snappy/tests/Flow/Snappy/Tests/Integration - + src/lib/types/tests/Flow/Types/Tests/Unit diff --git a/src/lib/types/src/Flow/Types/Type/Native/String/StringTypeChecker.php b/src/lib/types/src/Flow/Types/Type/Native/String/StringTypeChecker.php index 45d305a1d..0d416a08f 100644 --- a/src/lib/types/src/Flow/Types/Type/Native/String/StringTypeChecker.php +++ b/src/lib/types/src/Flow/Types/Type/Native/String/StringTypeChecker.php @@ -119,15 +119,19 @@ public function isHTML() : bool return false; } - if (\class_exists('\Dom\HTMLDocument', false)) { - $options = \LIBXML_HTML_NOIMPLIED; + if (\preg_match('/()?(.+?)<\/html>/im', $this->string) === 1) { + if (\class_exists('\Dom\HTMLDocument', false)) { + $options = \LIBXML_HTML_NOIMPLIED; - if (defined('Dom\HTML_NO_DEFAULT_NS')) { - $options |= constant('\Dom\HTML_NO_DEFAULT_NS'); + if (defined('Dom\HTML_NO_DEFAULT_NS')) { + $options |= constant('\Dom\HTML_NO_DEFAULT_NS'); + } + + $doc = @HTMLDocument::createFromString($this->string, $options); + + return $doc->saveHtml() === $this->string; } - HTMLDocument::createFromString($this->string, $options); - } elseif (\preg_match('/()?(.+?)<\/html>/im', $this->string) === 1) { try { \libxml_use_internal_errors(true); diff --git a/src/lib/types/tests/Flow/Types/Tests/Unit/Type/Logical/HTMLTypeTest.php b/src/lib/types/tests/Flow/Types/Tests/Unit/Type/Logical/HTMLTypeTest.php index 31125ec05..fb3ed3d43 100644 --- a/src/lib/types/tests/Flow/Types/Tests/Unit/Type/Logical/HTMLTypeTest.php +++ b/src/lib/types/tests/Flow/Types/Tests/Unit/Type/Logical/HTMLTypeTest.php @@ -7,7 +7,7 @@ use function Flow\Types\DSL\{type_from_array, type_html}; use Flow\Types\Exception\{CastingException, InvalidTypeException}; use Flow\Types\Value\HTMLDocument; -use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\{DataProvider, RequiresPhp}; use PHPUnit\Framework\TestCase; final class HTMLTypeTest extends TestCase @@ -60,7 +60,7 @@ public static function assert_data_provider() : \Generator ]; } - public static function cast_data_provider() : \Generator + public static function cast_data_provider_php82() : \Generator { yield 'string to HTML' => [ 'value' => '
1
', @@ -86,6 +86,29 @@ public static function cast_data_provider() : \Generator ]; } + public static function cast_data_provider_php84() : \Generator + { + yield 'string to HTML' => [ + 'value' => '
1
', + 'expected' => '
1
', + 'exceptionClass' => null, + ]; + + yield 'incomplete string to HTML' => [ + 'value' => '
1
', + 'expected' => <<<'HTML' +
1
+HTML, + 'exceptionClass' => null, + ]; + + yield 'object to HTML' => [ + 'value' => new \stdClass(), + 'expected' => null, + 'exceptionClass' => CastingException::class, + ]; + } + public static function is_valid_data_provider() : \Generator { yield 'valid HTMLDocument' => [ @@ -120,8 +143,22 @@ public function test_assert(mixed $value, ?string $exceptionClass = null) : void } } - #[DataProvider('cast_data_provider')] - public function test_cast(mixed $value, mixed $expected, ?string $exceptionClass) : void + #[RequiresPhp('< 8.4')] + #[DataProvider('cast_data_provider_php82')] + public function test_cast_php82(mixed $value, mixed $expected, ?string $exceptionClass) : void + { + if ($exceptionClass !== null) { + $this->expectException($exceptionClass); + type_html()->cast($value); + } else { + $result = type_html()->cast($value); + self::assertSame($expected, $result->toString()); + } + } + + #[RequiresPhp('>= 8.4')] + #[DataProvider('cast_data_provider_php84')] + public function test_cast_php84(mixed $value, mixed $expected, ?string $exceptionClass) : void { if ($exceptionClass !== null) { $this->expectException($exceptionClass); diff --git a/src/lib/types/tests/Flow/Types/Tests/Unit/Value/HTMLDocumentTest.php b/src/lib/types/tests/Flow/Types/Tests/Unit/Value/HTMLDocumentTest.php index d87474c25..c24c7ca90 100644 --- a/src/lib/types/tests/Flow/Types/Tests/Unit/Value/HTMLDocumentTest.php +++ b/src/lib/types/tests/Flow/Types/Tests/Unit/Value/HTMLDocumentTest.php @@ -14,14 +14,14 @@ final class HTMLDocumentTest extends TestCase #[RequiresPhp('>= 8.4')] public function test_create_with_dom_document_html_on_newer() : void { - $doc = \Dom\HTMLDocument::createFromString('
bar
'); + $doc = \Dom\HTMLDocument::createFromString('
bar
', \LIBXML_HTML_NOIMPLIED); $document = new HTMLDocument($doc); - self::assertSame('
bar
', (string) $document); + self::assertSame('
bar
', (string) $document); } - #[RequiresPhp('<= 8.4')] + #[RequiresPhp('< 8.4')] public function test_create_with_dom_document_html_on_old() : void { $doc = new \DOMDocument(); @@ -40,7 +40,7 @@ public function test_create_with_invalid_html_on_newer() : void self::assertSame('invalid', (string) $document); } - #[RequiresPhp('<= 8.4')] + #[RequiresPhp('< 8.4')] public function test_create_with_invalid_html_on_old() : void { $document = new HTMLDocument('invalid'); @@ -57,7 +57,7 @@ public function test_create_with_proper_html_on_newer() : void self::assertSame($html, (string) $document); } - #[RequiresPhp('<= 8.4')] + #[RequiresPhp('< 8.4')] public function test_create_with_proper_html_on_old() : void { $html = '
bar
';