From b89212a8c7a4a4220050d51a50119cced4f26239 Mon Sep 17 00:00:00 2001 From: Caen De Silva Date: Sun, 17 Mar 2024 20:15:16 +0100 Subject: [PATCH 01/15] Rename testing helper method to view --- .../tests/Feature/Views/SidebarBrandViewTest.php | 10 +++++----- .../tests/Feature/Views/SidebarFooterTextViewTest.php | 6 +++--- packages/testing/src/TestsBladeViews.php | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/framework/tests/Feature/Views/SidebarBrandViewTest.php b/packages/framework/tests/Feature/Views/SidebarBrandViewTest.php index 10b840bf5e4..03670822588 100644 --- a/packages/framework/tests/Feature/Views/SidebarBrandViewTest.php +++ b/packages/framework/tests/Feature/Views/SidebarBrandViewTest.php @@ -16,7 +16,7 @@ class SidebarBrandViewTest extends TestCase public function testSidebarBrandView() { - $view = $this->test(view('hyde::components.docs.sidebar-brand')); + $view = $this->view(view('hyde::components.docs.sidebar-brand')); $view->assertSee('HydePHP Docs'); $view->assertSee('theme-toggle-button'); @@ -27,7 +27,7 @@ public function testSidebarBrandViewWithHomeRoute() { Hyde::routes()->addRoute((new DocumentationPage('index'))->getRoute()); - $view = $this->test(view('hyde::components.docs.sidebar-brand')); + $view = $this->view(view('hyde::components.docs.sidebar-brand')); $view->assertSee('HydePHP Docs'); $view->assertSee('theme-toggle-button'); @@ -38,7 +38,7 @@ public function testSidebarBrandViewWithDefaultHeaderText() { config(['docs.sidebar' => []]); - $view = $this->test(view('hyde::components.docs.sidebar-brand')); + $view = $this->view(view('hyde::components.docs.sidebar-brand')); $view->assertSee('Documentation'); $view->assertDontSee('HydePHP Docs'); @@ -50,7 +50,7 @@ public function testSidebarBrandViewWithDefaultHeaderTextAndHomeRoute() config(['docs.sidebar' => []]); - $view = $this->test(view('hyde::components.docs.sidebar-brand')); + $view = $this->view(view('hyde::components.docs.sidebar-brand')); $view->assertSee('Documentation'); $view->assertSeeHtml('Documentation', true); @@ -63,7 +63,7 @@ public function testSidebarBrandViewWithoutDarkmodeFeature() $mock->shouldReceive('hasFeature')->with('darkmode')->andReturn(false); HydeKernel::setInstance($mock); - $view = $this->test(view('hyde::components.docs.sidebar-brand')); + $view = $this->view(view('hyde::components.docs.sidebar-brand')); $view->assertSee('HydePHP Docs'); $view->assertDontSee('theme-toggle-button'); diff --git a/packages/framework/tests/Feature/Views/SidebarFooterTextViewTest.php b/packages/framework/tests/Feature/Views/SidebarFooterTextViewTest.php index e4d5c21e9a3..0b27fa6f467 100644 --- a/packages/framework/tests/Feature/Views/SidebarFooterTextViewTest.php +++ b/packages/framework/tests/Feature/Views/SidebarFooterTextViewTest.php @@ -14,7 +14,7 @@ class SidebarFooterTextViewTest extends TestCase public function testSidebarFooterTextViewWithDefaultConfig() { - $view = $this->test(view('hyde::components.docs.sidebar-footer-text')); + $view = $this->view(view('hyde::components.docs.sidebar-footer-text')); $view->assertSeeHtml('Back to home page'); } @@ -23,7 +23,7 @@ public function testSidebarFooterTextViewWhenConfigOptionIsTrue() { Config::set('docs.sidebar.footer', true); - $view = $this->test(view('hyde::components.docs.sidebar-footer-text')); + $view = $this->view(view('hyde::components.docs.sidebar-footer-text')); $view->assertSeeHtml('Back to home page'); } @@ -32,7 +32,7 @@ public function testSidebarFooterTextViewWhenConfigOptionIsMarkdownString() { Config::set('docs.sidebar.footer', 'Your Markdown String Here'); - $view = $this->test(view('hyde::components.docs.sidebar-footer-text')); + $view = $this->view(view('hyde::components.docs.sidebar-footer-text')); $view->assertSeeText('Your Markdown String Here'); } diff --git a/packages/testing/src/TestsBladeViews.php b/packages/testing/src/TestsBladeViews.php index 01366963558..267932fa516 100644 --- a/packages/testing/src/TestsBladeViews.php +++ b/packages/testing/src/TestsBladeViews.php @@ -16,7 +16,7 @@ trait TestsBladeViews /** * Test a Blade view. */ - protected function test(string|View $view, $data = []): TestView + protected function view(string|View $view, $data = []): TestView { $data = array_merge($this->testViewData(), $data); From a5dbce40ce4395c1f73bf2db3cce2b1967ac2aee Mon Sep 17 00:00:00 2001 From: Caen De Silva Date: Mon, 18 Mar 2024 10:09:36 +0100 Subject: [PATCH 02/15] Move repeated noinspection annotation to test class --- packages/framework/tests/Unit/HtmlTestingSupportMetaTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/framework/tests/Unit/HtmlTestingSupportMetaTest.php b/packages/framework/tests/Unit/HtmlTestingSupportMetaTest.php index 4d7a92a5cc7..c796892f55c 100644 --- a/packages/framework/tests/Unit/HtmlTestingSupportMetaTest.php +++ b/packages/framework/tests/Unit/HtmlTestingSupportMetaTest.php @@ -19,6 +19,8 @@ * @see \Hyde\Testing\Support\HtmlTesting * * @coversNothing + * + * @noinspection HtmlUnknownAttribute */ class HtmlTestingSupportMetaTest extends UnitTestCase { @@ -369,7 +371,6 @@ public function testElementAttributes() { $this->assertSame([], $this->html('
Foo
')->getRootElement()->attributes); - /** @noinspection HtmlUnknownAttribute */ $this->assertSame([ 'name' => 'test', 'foo' => 'bar', @@ -429,7 +430,6 @@ public function testToArrayWithChildren() public function testToArrayWithAttributes() { - /** @noinspection HtmlUnknownAttribute */ $this->assertSame( ['id' => 'id', 'tag' => 'div', 'text' => 'Bar', 'classes' => ['class'], 'attributes' => ['name' => 'name']], $this->html('
Bar
')->getRootElement()->toArray() From 6883c15a9b39ada8097be982e99989a47af1f5aa Mon Sep 17 00:00:00 2001 From: Caen De Silva Date: Mon, 18 Mar 2024 11:52:32 +0100 Subject: [PATCH 03/15] Move repeated noinspection annotation to top of file --- packages/framework/tests/Unit/HtmlTestingSupportMetaTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/framework/tests/Unit/HtmlTestingSupportMetaTest.php b/packages/framework/tests/Unit/HtmlTestingSupportMetaTest.php index c796892f55c..ff07db2f553 100644 --- a/packages/framework/tests/Unit/HtmlTestingSupportMetaTest.php +++ b/packages/framework/tests/Unit/HtmlTestingSupportMetaTest.php @@ -1,5 +1,7 @@ Date: Mon, 18 Mar 2024 12:04:40 +0100 Subject: [PATCH 04/15] Add testing helpers to assert attribute state --- .../tests/Unit/HtmlTestingSupportMetaTest.php | 25 +++++++++++++++++++ .../HtmlTesting/TestableHtmlElement.php | 16 ++++++++++++ 2 files changed, 41 insertions(+) diff --git a/packages/framework/tests/Unit/HtmlTestingSupportMetaTest.php b/packages/framework/tests/Unit/HtmlTestingSupportMetaTest.php index ff07db2f553..d9992da590d 100644 --- a/packages/framework/tests/Unit/HtmlTestingSupportMetaTest.php +++ b/packages/framework/tests/Unit/HtmlTestingSupportMetaTest.php @@ -11,6 +11,7 @@ use Hyde\Testing\UnitTestCase; use Hyde\Testing\TestsBladeViews; use Illuminate\Support\Collection; +use PHPUnit\Framework\ExpectationFailedException; use Hyde\Testing\Support\HtmlTesting\TestableHtmlElement; use Hyde\Testing\Support\HtmlTesting\TestableHtmlDocument; @@ -446,6 +447,30 @@ public function testElementAssertDoesNotHaveClass() $this->html('
Foo
')->getRootElement()->doesNotHaveClass('bar'); } + public function testElementAssertHasAttribute() + { + $this->html('
Foo
')->getRootElement()->hasAttribute('name'); + } + + public function testElementAssertDoesNotHaveAttribute() + { + $this->html('
Foo
')->getRootElement()->doesNotHaveAttribute('href'); + } + + public function testElementAssertHasAttributeWithValue() + { + $this->html('
Foo
')->getRootElement()->hasAttribute('name', 'foo'); + } + + public function testElementAssertHasAttributeWithWrongValue() + { + try { + $this->html('
Foo
')->getRootElement()->hasAttribute('name', 'bar'); + } catch (ExpectationFailedException $exception) { + $this->assertSame("The attribute 'name' did not have the expected value.\nFailed asserting that two strings are identical.", $exception->getMessage()); + } + } + protected function exampleElement(): TestableHtmlElement { return $this->html('
Foo
')->getElementById('foo'); diff --git a/packages/testing/src/Support/HtmlTesting/TestableHtmlElement.php b/packages/testing/src/Support/HtmlTesting/TestableHtmlElement.php index fd65429518c..4dda16aa454 100644 --- a/packages/testing/src/Support/HtmlTesting/TestableHtmlElement.php +++ b/packages/testing/src/Support/HtmlTesting/TestableHtmlElement.php @@ -84,6 +84,22 @@ public function doesNotHaveClass(string $class): static return $this->doAssert(fn () => PHPUnit::assertNotContains($class, $this->classes, "The class '$class' was found in the element.")); } + public function hasAttribute(string $attribute, ?string $value = null): static + { + $this->doAssert(fn () => PHPUnit::assertArrayHasKey($attribute, $this->attributes, "The attribute '$attribute' was not found in the element.")); + + if ($value) { + return $this->doAssert(fn () => PHPUnit::assertSame($value, $this->attributes[$attribute], "The attribute '$attribute' did not have the expected value.")); + } + + return $this; + } + + public function doesNotHaveAttribute(string $attribute): static + { + return $this->doAssert(fn () => PHPUnit::assertArrayNotHasKey($attribute, $this->attributes, "The attribute '$attribute' was found in the element.")); + } + protected function parseTag(string $html): string { preg_match('/^<([a-z0-9-]+)/i', $html, $matches); From 58e75d52ca14984c7976157d4e4226b171db6af2 Mon Sep 17 00:00:00 2001 From: Caen De Silva Date: Mon, 18 Mar 2024 12:08:24 +0100 Subject: [PATCH 05/15] Add testing helpers to assert element identifiers --- .../tests/Unit/HtmlTestingSupportMetaTest.php | 10 ++++++++++ .../src/Support/HtmlTesting/TestableHtmlElement.php | 10 ++++++++++ 2 files changed, 20 insertions(+) diff --git a/packages/framework/tests/Unit/HtmlTestingSupportMetaTest.php b/packages/framework/tests/Unit/HtmlTestingSupportMetaTest.php index d9992da590d..ef714e74eaa 100644 --- a/packages/framework/tests/Unit/HtmlTestingSupportMetaTest.php +++ b/packages/framework/tests/Unit/HtmlTestingSupportMetaTest.php @@ -437,6 +437,16 @@ public function testToArrayWithAttributes() ); } + public function testElementHasId() + { + $this->html('
Foo
')->getRootElement()->hasId('foo'); + } + + public function testElementDoesNotHaveId() + { + $this->html('
Foo
')->getRootElement()->doesNotHaveId('foo'); + } + public function testElementAssertHasClass() { $this->html('
Foo
')->getRootElement()->hasClass('foo'); diff --git a/packages/testing/src/Support/HtmlTesting/TestableHtmlElement.php b/packages/testing/src/Support/HtmlTesting/TestableHtmlElement.php index 4dda16aa454..24c0aaabaf3 100644 --- a/packages/testing/src/Support/HtmlTesting/TestableHtmlElement.php +++ b/packages/testing/src/Support/HtmlTesting/TestableHtmlElement.php @@ -74,6 +74,16 @@ public function toArray(): array ], fn ($value): bool => filled($value)); } + public function hasId(string $id): static + { + return $this->doAssert(fn () => PHPUnit::assertSame($id, $this->id, 'The id attribute did not have the expected value.')); + } + + public function doesNotHaveId(string $id): static + { + return $this->doAssert(fn () => PHPUnit::assertNotSame($id, $this->id, 'The id attribute had the unexpected value.')); + } + public function hasClass(string $class): static { return $this->doAssert(fn () => PHPUnit::assertContains($class, $this->classes, "The class '$class' was not found in the element.")); From d9c4a5fc19314dc247bdf647037422dd758124c2 Mon Sep 17 00:00:00 2001 From: Caen De Silva Date: Mon, 18 Mar 2024 12:10:01 +0100 Subject: [PATCH 06/15] Forward element attribute calls for standalone properties --- .../tests/Unit/HtmlTestingSupportMetaTest.php | 10 ++++++++++ .../src/Support/HtmlTesting/TestableHtmlElement.php | 8 ++++++++ 2 files changed, 18 insertions(+) diff --git a/packages/framework/tests/Unit/HtmlTestingSupportMetaTest.php b/packages/framework/tests/Unit/HtmlTestingSupportMetaTest.php index ef714e74eaa..335f86eb13a 100644 --- a/packages/framework/tests/Unit/HtmlTestingSupportMetaTest.php +++ b/packages/framework/tests/Unit/HtmlTestingSupportMetaTest.php @@ -481,6 +481,16 @@ public function testElementAssertHasAttributeWithWrongValue() } } + public function testElementAssertHasAttributeForwardsIdAssertions() + { + $this->html('
Foo
')->getRootElement()->hasAttribute('id', 'foo'); + } + + public function testElementAssertHasAttributeForwardsClassAssertions() + { + $this->html('
Foo
')->getRootElement()->hasAttribute('class', 'foo'); + } + protected function exampleElement(): TestableHtmlElement { return $this->html('
Foo
')->getElementById('foo'); diff --git a/packages/testing/src/Support/HtmlTesting/TestableHtmlElement.php b/packages/testing/src/Support/HtmlTesting/TestableHtmlElement.php index 24c0aaabaf3..be8d81f5175 100644 --- a/packages/testing/src/Support/HtmlTesting/TestableHtmlElement.php +++ b/packages/testing/src/Support/HtmlTesting/TestableHtmlElement.php @@ -96,6 +96,14 @@ public function doesNotHaveClass(string $class): static public function hasAttribute(string $attribute, ?string $value = null): static { + if ($attribute === 'id') { + return $this->hasId($value); + } + + if ($attribute === 'class') { + return $this->hasClass($value); + } + $this->doAssert(fn () => PHPUnit::assertArrayHasKey($attribute, $this->attributes, "The attribute '$attribute' was not found in the element.")); if ($value) { From 57dd5183279e9cc88d401b62ab8bacd3105cc489 Mon Sep 17 00:00:00 2001 From: Caen De Silva Date: Mon, 18 Mar 2024 12:14:19 +0100 Subject: [PATCH 07/15] Create alias method for element assertion helper --- .../Support/HtmlTesting/HtmlTestingAssertions.php | 5 +++++ .../Support/HtmlTesting/TestableHtmlElement.php | 14 +++++++------- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/packages/testing/src/Support/HtmlTesting/HtmlTestingAssertions.php b/packages/testing/src/Support/HtmlTesting/HtmlTestingAssertions.php index 351be0cf0c5..e8e48e2b384 100644 --- a/packages/testing/src/Support/HtmlTesting/HtmlTestingAssertions.php +++ b/packages/testing/src/Support/HtmlTesting/HtmlTestingAssertions.php @@ -39,4 +39,9 @@ protected function doAssert(callable $assertion): static return $this; } + + protected function doElementAssert(callable $assertion): static + { + return $this->doAssert($assertion); + } } diff --git a/packages/testing/src/Support/HtmlTesting/TestableHtmlElement.php b/packages/testing/src/Support/HtmlTesting/TestableHtmlElement.php index be8d81f5175..2607d8d19a5 100644 --- a/packages/testing/src/Support/HtmlTesting/TestableHtmlElement.php +++ b/packages/testing/src/Support/HtmlTesting/TestableHtmlElement.php @@ -76,22 +76,22 @@ public function toArray(): array public function hasId(string $id): static { - return $this->doAssert(fn () => PHPUnit::assertSame($id, $this->id, 'The id attribute did not have the expected value.')); + return $this->doElementAssert(fn () => PHPUnit::assertSame($id, $this->id, 'The id attribute did not have the expected value.')); } public function doesNotHaveId(string $id): static { - return $this->doAssert(fn () => PHPUnit::assertNotSame($id, $this->id, 'The id attribute had the unexpected value.')); + return $this->doElementAssert(fn () => PHPUnit::assertNotSame($id, $this->id, 'The id attribute had the unexpected value.')); } public function hasClass(string $class): static { - return $this->doAssert(fn () => PHPUnit::assertContains($class, $this->classes, "The class '$class' was not found in the element.")); + return $this->doElementAssert(fn () => PHPUnit::assertContains($class, $this->classes, "The class '$class' was not found in the element.")); } public function doesNotHaveClass(string $class): static { - return $this->doAssert(fn () => PHPUnit::assertNotContains($class, $this->classes, "The class '$class' was found in the element.")); + return $this->doElementAssert(fn () => PHPUnit::assertNotContains($class, $this->classes, "The class '$class' was found in the element.")); } public function hasAttribute(string $attribute, ?string $value = null): static @@ -104,10 +104,10 @@ public function hasAttribute(string $attribute, ?string $value = null): static return $this->hasClass($value); } - $this->doAssert(fn () => PHPUnit::assertArrayHasKey($attribute, $this->attributes, "The attribute '$attribute' was not found in the element.")); + $this->doElementAssert(fn () => PHPUnit::assertArrayHasKey($attribute, $this->attributes, "The attribute '$attribute' was not found in the element.")); if ($value) { - return $this->doAssert(fn () => PHPUnit::assertSame($value, $this->attributes[$attribute], "The attribute '$attribute' did not have the expected value.")); + return $this->doElementAssert(fn () => PHPUnit::assertSame($value, $this->attributes[$attribute], "The attribute '$attribute' did not have the expected value.")); } return $this; @@ -115,7 +115,7 @@ public function hasAttribute(string $attribute, ?string $value = null): static public function doesNotHaveAttribute(string $attribute): static { - return $this->doAssert(fn () => PHPUnit::assertArrayNotHasKey($attribute, $this->attributes, "The attribute '$attribute' was found in the element.")); + return $this->doElementAssert(fn () => PHPUnit::assertArrayNotHasKey($attribute, $this->attributes, "The attribute '$attribute' was found in the element.")); } protected function parseTag(string $html): string From 814644ef8ea735f46e93e8992c09e43a2984ebd6 Mon Sep 17 00:00:00 2001 From: Caen De Silva Date: Mon, 18 Mar 2024 12:14:57 +0100 Subject: [PATCH 08/15] Move element assertion methods to trait --- .../HtmlTesting/HtmlTestingAssertions.php | 44 ++++++++++++++++++ .../HtmlTesting/TestableHtmlElement.php | 45 ------------------- 2 files changed, 44 insertions(+), 45 deletions(-) diff --git a/packages/testing/src/Support/HtmlTesting/HtmlTestingAssertions.php b/packages/testing/src/Support/HtmlTesting/HtmlTestingAssertions.php index e8e48e2b384..c6dee5b2e48 100644 --- a/packages/testing/src/Support/HtmlTesting/HtmlTestingAssertions.php +++ b/packages/testing/src/Support/HtmlTesting/HtmlTestingAssertions.php @@ -33,6 +33,50 @@ public function assertDontSeeEscaped(string $value): static return $this->doAssert(fn () => PHPUnit::assertStringNotContainsString(e($value), $this->html, "The escaped string '$value' was found in the HTML.")); } + public function hasId(string $id): static + { + return $this->doElementAssert(fn () => PHPUnit::assertSame($id, $this->id, 'The id attribute did not have the expected value.')); + } + + public function doesNotHaveId(string $id): static + { + return $this->doElementAssert(fn () => PHPUnit::assertNotSame($id, $this->id, 'The id attribute had the unexpected value.')); + } + + public function hasClass(string $class): static + { + return $this->doElementAssert(fn () => PHPUnit::assertContains($class, $this->classes, "The class '$class' was not found in the element.")); + } + + public function doesNotHaveClass(string $class): static + { + return $this->doElementAssert(fn () => PHPUnit::assertNotContains($class, $this->classes, "The class '$class' was found in the element.")); + } + + public function hasAttribute(string $attribute, ?string $value = null): static + { + if ($attribute === 'id') { + return $this->hasId($value); + } + + if ($attribute === 'class') { + return $this->hasClass($value); + } + + $this->doElementAssert(fn () => PHPUnit::assertArrayHasKey($attribute, $this->attributes, "The attribute '$attribute' was not found in the element.")); + + if ($value) { + return $this->doElementAssert(fn () => PHPUnit::assertSame($value, $this->attributes[$attribute], "The attribute '$attribute' did not have the expected value.")); + } + + return $this; + } + + public function doesNotHaveAttribute(string $attribute): static + { + return $this->doElementAssert(fn () => PHPUnit::assertArrayNotHasKey($attribute, $this->attributes, "The attribute '$attribute' was found in the element.")); + } + protected function doAssert(callable $assertion): static { $assertion(); diff --git a/packages/testing/src/Support/HtmlTesting/TestableHtmlElement.php b/packages/testing/src/Support/HtmlTesting/TestableHtmlElement.php index 2607d8d19a5..7bdb6ed9068 100644 --- a/packages/testing/src/Support/HtmlTesting/TestableHtmlElement.php +++ b/packages/testing/src/Support/HtmlTesting/TestableHtmlElement.php @@ -8,7 +8,6 @@ use Illuminate\Support\Arr; use Illuminate\Support\Collection; use Illuminate\Contracts\Support\Arrayable; -use Illuminate\Testing\Assert as PHPUnit; use function trim; use function filled; @@ -74,50 +73,6 @@ public function toArray(): array ], fn ($value): bool => filled($value)); } - public function hasId(string $id): static - { - return $this->doElementAssert(fn () => PHPUnit::assertSame($id, $this->id, 'The id attribute did not have the expected value.')); - } - - public function doesNotHaveId(string $id): static - { - return $this->doElementAssert(fn () => PHPUnit::assertNotSame($id, $this->id, 'The id attribute had the unexpected value.')); - } - - public function hasClass(string $class): static - { - return $this->doElementAssert(fn () => PHPUnit::assertContains($class, $this->classes, "The class '$class' was not found in the element.")); - } - - public function doesNotHaveClass(string $class): static - { - return $this->doElementAssert(fn () => PHPUnit::assertNotContains($class, $this->classes, "The class '$class' was found in the element.")); - } - - public function hasAttribute(string $attribute, ?string $value = null): static - { - if ($attribute === 'id') { - return $this->hasId($value); - } - - if ($attribute === 'class') { - return $this->hasClass($value); - } - - $this->doElementAssert(fn () => PHPUnit::assertArrayHasKey($attribute, $this->attributes, "The attribute '$attribute' was not found in the element.")); - - if ($value) { - return $this->doElementAssert(fn () => PHPUnit::assertSame($value, $this->attributes[$attribute], "The attribute '$attribute' did not have the expected value.")); - } - - return $this; - } - - public function doesNotHaveAttribute(string $attribute): static - { - return $this->doElementAssert(fn () => PHPUnit::assertArrayNotHasKey($attribute, $this->attributes, "The attribute '$attribute' was found in the element.")); - } - protected function parseTag(string $html): string { preg_match('/^<([a-z0-9-]+)/i', $html, $matches); From f69c3bdb75788308e4ac56293d7336fcfe0de5a0 Mon Sep 17 00:00:00 2001 From: Caen De Silva Date: Mon, 18 Mar 2024 12:17:19 +0100 Subject: [PATCH 09/15] Make protected helper method public internal --- .../testing/src/Support/HtmlTesting/HtmlTestingAssertions.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/testing/src/Support/HtmlTesting/HtmlTestingAssertions.php b/packages/testing/src/Support/HtmlTesting/HtmlTestingAssertions.php index c6dee5b2e48..83655474e9f 100644 --- a/packages/testing/src/Support/HtmlTesting/HtmlTestingAssertions.php +++ b/packages/testing/src/Support/HtmlTesting/HtmlTestingAssertions.php @@ -77,7 +77,8 @@ public function doesNotHaveAttribute(string $attribute): static return $this->doElementAssert(fn () => PHPUnit::assertArrayNotHasKey($attribute, $this->attributes, "The attribute '$attribute' was found in the element.")); } - protected function doAssert(callable $assertion): static + /** @internal */ + public function doAssert(callable $assertion): static { $assertion(); From 7bb22582a7172d93eaea872c6c7342f00d9a47e0 Mon Sep 17 00:00:00 2001 From: Caen De Silva Date: Mon, 18 Mar 2024 12:18:43 +0100 Subject: [PATCH 10/15] Change callable type to closure --- .../src/Support/HtmlTesting/HtmlTestingAssertions.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/testing/src/Support/HtmlTesting/HtmlTestingAssertions.php b/packages/testing/src/Support/HtmlTesting/HtmlTestingAssertions.php index 83655474e9f..bb3ddbe91a4 100644 --- a/packages/testing/src/Support/HtmlTesting/HtmlTestingAssertions.php +++ b/packages/testing/src/Support/HtmlTesting/HtmlTestingAssertions.php @@ -4,6 +4,7 @@ namespace Hyde\Testing\Support\HtmlTesting; +use Closure; use Illuminate\Testing\Assert as PHPUnit; trait HtmlTestingAssertions @@ -78,14 +79,14 @@ public function doesNotHaveAttribute(string $attribute): static } /** @internal */ - public function doAssert(callable $assertion): static + public function doAssert(Closure $assertion): static { $assertion(); return $this; } - protected function doElementAssert(callable $assertion): static + protected function doElementAssert(Closure $assertion): static { return $this->doAssert($assertion); } From 4cd2c424a182055f8a332c7bf8c377908a2cfa13 Mon Sep 17 00:00:00 2001 From: Caen De Silva Date: Mon, 18 Mar 2024 12:20:41 +0100 Subject: [PATCH 11/15] Change static return types to element type --- .../Support/HtmlTesting/HtmlTestingAssertions.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/testing/src/Support/HtmlTesting/HtmlTestingAssertions.php b/packages/testing/src/Support/HtmlTesting/HtmlTestingAssertions.php index bb3ddbe91a4..db6e7417d58 100644 --- a/packages/testing/src/Support/HtmlTesting/HtmlTestingAssertions.php +++ b/packages/testing/src/Support/HtmlTesting/HtmlTestingAssertions.php @@ -34,27 +34,27 @@ public function assertDontSeeEscaped(string $value): static return $this->doAssert(fn () => PHPUnit::assertStringNotContainsString(e($value), $this->html, "The escaped string '$value' was found in the HTML.")); } - public function hasId(string $id): static + public function hasId(string $id): TestableHtmlElement { return $this->doElementAssert(fn () => PHPUnit::assertSame($id, $this->id, 'The id attribute did not have the expected value.')); } - public function doesNotHaveId(string $id): static + public function doesNotHaveId(string $id): TestableHtmlElement { return $this->doElementAssert(fn () => PHPUnit::assertNotSame($id, $this->id, 'The id attribute had the unexpected value.')); } - public function hasClass(string $class): static + public function hasClass(string $class): TestableHtmlElement { return $this->doElementAssert(fn () => PHPUnit::assertContains($class, $this->classes, "The class '$class' was not found in the element.")); } - public function doesNotHaveClass(string $class): static + public function doesNotHaveClass(string $class): TestableHtmlElement { return $this->doElementAssert(fn () => PHPUnit::assertNotContains($class, $this->classes, "The class '$class' was found in the element.")); } - public function hasAttribute(string $attribute, ?string $value = null): static + public function hasAttribute(string $attribute, ?string $value = null): TestableHtmlElement { if ($attribute === 'id') { return $this->hasId($value); @@ -73,7 +73,7 @@ public function hasAttribute(string $attribute, ?string $value = null): static return $this; } - public function doesNotHaveAttribute(string $attribute): static + public function doesNotHaveAttribute(string $attribute): TestableHtmlElement { return $this->doElementAssert(fn () => PHPUnit::assertArrayNotHasKey($attribute, $this->attributes, "The attribute '$attribute' was found in the element.")); } From 4f3880c9110cb3ed911d6fb424527af486e56fcc Mon Sep 17 00:00:00 2001 From: Caen De Silva Date: Mon, 18 Mar 2024 12:24:20 +0100 Subject: [PATCH 12/15] Proxy document element assertions to the root element --- .../tests/Unit/HtmlTestingSupportMetaTest.php | 15 +++++++++++++++ .../Support/HtmlTesting/HtmlTestingAssertions.php | 12 +++++++++++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/packages/framework/tests/Unit/HtmlTestingSupportMetaTest.php b/packages/framework/tests/Unit/HtmlTestingSupportMetaTest.php index 335f86eb13a..1a97ee2ec9f 100644 --- a/packages/framework/tests/Unit/HtmlTestingSupportMetaTest.php +++ b/packages/framework/tests/Unit/HtmlTestingSupportMetaTest.php @@ -491,6 +491,21 @@ public function testElementAssertHasAttributeForwardsClassAssertions() $this->html('
Foo
')->getRootElement()->hasAttribute('class', 'foo'); } + public function testAssertionCallsOnDocumentAreForwardedToRootElement() + { + $this->assertInstanceOf(TestableHtmlElement::class, + $this->html('
Foo
') + ->assertSee('Foo') + ->hasId('foo') + ->doesNotHaveId('bar') + ->hasClass('bar') + ->doesNotHaveClass('baz') + ->hasAttribute('class', 'bar') + ->doesNotHaveAttribute('href') + ->assertSee('Foo') + ); + } + protected function exampleElement(): TestableHtmlElement { return $this->html('
Foo
')->getElementById('foo'); diff --git a/packages/testing/src/Support/HtmlTesting/HtmlTestingAssertions.php b/packages/testing/src/Support/HtmlTesting/HtmlTestingAssertions.php index db6e7417d58..3007a6e7764 100644 --- a/packages/testing/src/Support/HtmlTesting/HtmlTestingAssertions.php +++ b/packages/testing/src/Support/HtmlTesting/HtmlTestingAssertions.php @@ -86,8 +86,18 @@ public function doAssert(Closure $assertion): static return $this; } - protected function doElementAssert(Closure $assertion): static + protected function doElementAssert(Closure $assertion): TestableHtmlElement { + // Proxy to the root element if we're a TestableHtmlDocument. + if ($this instanceof TestableHtmlDocument) { + $rootElement = $this->getRootElement(); + + // Bind closure to the root element. + $assertion = $assertion->bindTo($rootElement); + + return $rootElement->doAssert($assertion); + } + return $this->doAssert($assertion); } } From a715ae2454989d7db5e5a8e4c320c5fe39462d97 Mon Sep 17 00:00:00 2001 From: Caen De Silva Date: Mon, 18 Mar 2024 12:41:03 +0100 Subject: [PATCH 13/15] Replace custom array filter with ternary return --- .../testing/src/Support/HtmlTesting/TestableHtmlElement.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/testing/src/Support/HtmlTesting/TestableHtmlElement.php b/packages/testing/src/Support/HtmlTesting/TestableHtmlElement.php index 7bdb6ed9068..77f67fd721c 100644 --- a/packages/testing/src/Support/HtmlTesting/TestableHtmlElement.php +++ b/packages/testing/src/Support/HtmlTesting/TestableHtmlElement.php @@ -10,7 +10,6 @@ use Illuminate\Contracts\Support\Arrayable; use function trim; -use function filled; use function strlen; use function explode; use function preg_match; @@ -69,8 +68,8 @@ public function toArray(): array 'text' => $this->text, 'classes' => $this->classes, 'attributes' => $this->attributes, - 'nodes' => $this->nodes, - ], fn ($value): bool => filled($value)); + 'nodes' => $this->nodes->count() ? $this->nodes : null, + ]); } protected function parseTag(string $html): string From a0d55c4846c9a78552f0c607ceb6211fa0a6c2ab Mon Sep 17 00:00:00 2001 From: Caen De Silva Date: Mon, 18 Mar 2024 12:54:41 +0100 Subject: [PATCH 14/15] Add missing assertion prefixes to testing helpers --- .../tests/Unit/HtmlTestingSupportMetaTest.php | 36 +++++++++---------- .../HtmlTesting/HtmlTestingAssertions.php | 16 ++++----- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/packages/framework/tests/Unit/HtmlTestingSupportMetaTest.php b/packages/framework/tests/Unit/HtmlTestingSupportMetaTest.php index 1a97ee2ec9f..5b6ec6f42da 100644 --- a/packages/framework/tests/Unit/HtmlTestingSupportMetaTest.php +++ b/packages/framework/tests/Unit/HtmlTestingSupportMetaTest.php @@ -437,45 +437,45 @@ public function testToArrayWithAttributes() ); } - public function testElementHasId() + public function testElementAssertHasId() { - $this->html('
Foo
')->getRootElement()->hasId('foo'); + $this->html('
Foo
')->getRootElement()->assertHasId('foo'); } - public function testElementDoesNotHaveId() + public function testElementAssertDoesNotHaveId() { - $this->html('
Foo
')->getRootElement()->doesNotHaveId('foo'); + $this->html('
Foo
')->getRootElement()->assertDoesNotHaveId('foo'); } public function testElementAssertHasClass() { - $this->html('
Foo
')->getRootElement()->hasClass('foo'); + $this->html('
Foo
')->getRootElement()->assertHasClass('foo'); } public function testElementAssertDoesNotHaveClass() { - $this->html('
Foo
')->getRootElement()->doesNotHaveClass('bar'); + $this->html('
Foo
')->getRootElement()->assertDoesNotHaveClass('bar'); } public function testElementAssertHasAttribute() { - $this->html('
Foo
')->getRootElement()->hasAttribute('name'); + $this->html('
Foo
')->getRootElement()->assertHasAttribute('name'); } public function testElementAssertDoesNotHaveAttribute() { - $this->html('
Foo
')->getRootElement()->doesNotHaveAttribute('href'); + $this->html('
Foo
')->getRootElement()->assertDoesNotHaveAttribute('href'); } public function testElementAssertHasAttributeWithValue() { - $this->html('
Foo
')->getRootElement()->hasAttribute('name', 'foo'); + $this->html('
Foo
')->getRootElement()->assertHasAttribute('name', 'foo'); } public function testElementAssertHasAttributeWithWrongValue() { try { - $this->html('
Foo
')->getRootElement()->hasAttribute('name', 'bar'); + $this->html('
Foo
')->getRootElement()->assertHasAttribute('name', 'bar'); } catch (ExpectationFailedException $exception) { $this->assertSame("The attribute 'name' did not have the expected value.\nFailed asserting that two strings are identical.", $exception->getMessage()); } @@ -483,12 +483,12 @@ public function testElementAssertHasAttributeWithWrongValue() public function testElementAssertHasAttributeForwardsIdAssertions() { - $this->html('
Foo
')->getRootElement()->hasAttribute('id', 'foo'); + $this->html('
Foo
')->getRootElement()->assertHasAttribute('id', 'foo'); } public function testElementAssertHasAttributeForwardsClassAssertions() { - $this->html('
Foo
')->getRootElement()->hasAttribute('class', 'foo'); + $this->html('
Foo
')->getRootElement()->assertHasAttribute('class', 'foo'); } public function testAssertionCallsOnDocumentAreForwardedToRootElement() @@ -496,12 +496,12 @@ public function testAssertionCallsOnDocumentAreForwardedToRootElement() $this->assertInstanceOf(TestableHtmlElement::class, $this->html('
Foo
') ->assertSee('Foo') - ->hasId('foo') - ->doesNotHaveId('bar') - ->hasClass('bar') - ->doesNotHaveClass('baz') - ->hasAttribute('class', 'bar') - ->doesNotHaveAttribute('href') + ->assertHasId('foo') + ->assertDoesNotHaveId('bar') + ->assertHasClass('bar') + ->assertDoesNotHaveClass('baz') + ->assertHasAttribute('class', 'bar') + ->assertDoesNotHaveAttribute('href') ->assertSee('Foo') ); } diff --git a/packages/testing/src/Support/HtmlTesting/HtmlTestingAssertions.php b/packages/testing/src/Support/HtmlTesting/HtmlTestingAssertions.php index 3007a6e7764..4b9da2ff53e 100644 --- a/packages/testing/src/Support/HtmlTesting/HtmlTestingAssertions.php +++ b/packages/testing/src/Support/HtmlTesting/HtmlTestingAssertions.php @@ -34,34 +34,34 @@ public function assertDontSeeEscaped(string $value): static return $this->doAssert(fn () => PHPUnit::assertStringNotContainsString(e($value), $this->html, "The escaped string '$value' was found in the HTML.")); } - public function hasId(string $id): TestableHtmlElement + public function assertHasId(string $id): TestableHtmlElement { return $this->doElementAssert(fn () => PHPUnit::assertSame($id, $this->id, 'The id attribute did not have the expected value.')); } - public function doesNotHaveId(string $id): TestableHtmlElement + public function assertDoesNotHaveId(string $id): TestableHtmlElement { return $this->doElementAssert(fn () => PHPUnit::assertNotSame($id, $this->id, 'The id attribute had the unexpected value.')); } - public function hasClass(string $class): TestableHtmlElement + public function assertHasClass(string $class): TestableHtmlElement { return $this->doElementAssert(fn () => PHPUnit::assertContains($class, $this->classes, "The class '$class' was not found in the element.")); } - public function doesNotHaveClass(string $class): TestableHtmlElement + public function assertDoesNotHaveClass(string $class): TestableHtmlElement { return $this->doElementAssert(fn () => PHPUnit::assertNotContains($class, $this->classes, "The class '$class' was found in the element.")); } - public function hasAttribute(string $attribute, ?string $value = null): TestableHtmlElement + public function assertHasAttribute(string $attribute, ?string $value = null): TestableHtmlElement { if ($attribute === 'id') { - return $this->hasId($value); + return $this->assertHasId($value); } if ($attribute === 'class') { - return $this->hasClass($value); + return $this->assertHasClass($value); } $this->doElementAssert(fn () => PHPUnit::assertArrayHasKey($attribute, $this->attributes, "The attribute '$attribute' was not found in the element.")); @@ -73,7 +73,7 @@ public function hasAttribute(string $attribute, ?string $value = null): Testable return $this; } - public function doesNotHaveAttribute(string $attribute): TestableHtmlElement + public function assertDoesNotHaveAttribute(string $attribute): TestableHtmlElement { return $this->doElementAssert(fn () => PHPUnit::assertArrayNotHasKey($attribute, $this->attributes, "The attribute '$attribute' was found in the element.")); } From 1af32f6d19ca79069332be0dfce597dcc693cacc Mon Sep 17 00:00:00 2001 From: Caen De Silva Date: Mon, 18 Mar 2024 15:41:53 +0100 Subject: [PATCH 15/15] Annotate nullable array key type --- .../testing/src/Support/HtmlTesting/TestableHtmlElement.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/testing/src/Support/HtmlTesting/TestableHtmlElement.php b/packages/testing/src/Support/HtmlTesting/TestableHtmlElement.php index 77f67fd721c..cb647ec0ff9 100644 --- a/packages/testing/src/Support/HtmlTesting/TestableHtmlElement.php +++ b/packages/testing/src/Support/HtmlTesting/TestableHtmlElement.php @@ -59,7 +59,7 @@ public function __construct(string $html, DOMElement $element, ?TestableHtmlElem $this->attributes = $this->parseAttributes($element); } - /** @return array{id: ?string, tag: string, text: string, classes: ?array, attributes: ?array, nodes: \Illuminate\Support\Collection<\Hyde\Testing\Support\HtmlTesting\TestableHtmlElement>} */ + /** @return array{id: ?string, tag: string, text: string, classes: ?array, attributes: ?array, nodes: ?\Illuminate\Support\Collection<\Hyde\Testing\Support\HtmlTesting\TestableHtmlElement>} */ public function toArray(): array { return array_filter([