Skip to content

Commit 9145666

Browse files
authored
Add support for testing Blade components (#27)
* Add support for testing Blade components
1 parent 3896ba2 commit 9145666

14 files changed

+673
-4
lines changed

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,16 @@ $this->view('navigation')
382382
});
383383
```
384384

385+
### Usage with Blade components
386+
```php
387+
$this->component(Navigation::class)
388+
->assertElementExists('nav > ul', function(AssertElement $ul) {
389+
$ul->contains('li', [
390+
'class' => 'active',
391+
]);
392+
});
393+
```
394+
385395
## Overview of methods
386396
| Base methods | Description |
387397
|------------------------------------------------|--------------------------------------------------------------------------------------|

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@
2424
},
2525
"autoload-dev": {
2626
"psr-4": {
27-
"Tests\\": "tests/"
27+
"Tests\\": "tests/",
28+
"Tests\\Views\\Components\\": "tests/views/components"
2829
}
2930
},
3031
"extra": {

src/DomAssertionsServiceProvider.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
namespace Sinnbeck\DomAssertions;
44

55
use Illuminate\Support\ServiceProvider;
6+
use Illuminate\Support\Traits\Macroable;
7+
use Illuminate\Testing\TestComponent;
68
use Illuminate\Testing\TestResponse;
79
use Illuminate\Testing\TestView;
810

@@ -13,6 +15,11 @@ public function boot()
1315
if ($this->app->runningUnitTests()) {
1416
TestResponse::mixin(new TestResponseMacros);
1517
TestView::mixin(new TestViewMacros);
18+
19+
// https://github.com/laravel/framework/pull/54359
20+
if (in_array(Macroable::class, class_uses(TestComponent::class) ?? [])) {
21+
TestComponent::mixin(new TestComponentMacros);
22+
}
1623
}
1724
}
1825
}

src/TestComponentMacros.php

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Sinnbeck\DomAssertions;
6+
7+
use Closure;
8+
use DOMException;
9+
use Illuminate\Testing\TestComponent;
10+
use PHPUnit\Framework\Assert;
11+
use Sinnbeck\DomAssertions\Asserts\AssertElement;
12+
use Sinnbeck\DomAssertions\Asserts\AssertForm;
13+
use Sinnbeck\DomAssertions\Support\DomParser;
14+
15+
/**
16+
* @internal
17+
*
18+
* @mixin TestComponent
19+
*/
20+
class TestComponentMacros
21+
{
22+
public function assertHtml5(): Closure
23+
{
24+
return function () {
25+
/** @var TestComponent $this */
26+
Assert::assertNotEmpty(
27+
(string) $this->rendered,
28+
'The component is empty!'
29+
);
30+
31+
try {
32+
$parser = DomParser::new((string) $this->rendered);
33+
} catch (DOMException $exception) {
34+
Assert::fail($exception->getMessage());
35+
}
36+
37+
Assert::assertEquals(
38+
'html',
39+
$parser->getDocType(),
40+
'Not a html5 doctype!'
41+
);
42+
43+
return $this;
44+
};
45+
}
46+
47+
public function assertElementExists(): Closure
48+
{
49+
return function ($selector = 'body', $callback = null): TestComponent {
50+
/** @var TestComponent $this */
51+
Assert::assertNotEmpty(
52+
(string) $this->rendered,
53+
'The component is empty!'
54+
);
55+
56+
try {
57+
$parser = DomParser::new((string) $this->rendered);
58+
} catch (DOMException $exception) {
59+
Assert::fail($exception->getMessage());
60+
}
61+
62+
if ($selector instanceof Closure) {
63+
$callback = $selector;
64+
$selector = 'body';
65+
}
66+
67+
if (is_string($selector)) {
68+
$element = $parser->query($selector);
69+
} else {
70+
Assert::fail('Invalid selector!');
71+
}
72+
73+
Assert::assertNotNull($element, sprintf('No element found with selector: %s', $selector));
74+
75+
if ($callback) {
76+
$callback(new AssertElement((string) $this->rendered, $element));
77+
}
78+
79+
return $this;
80+
};
81+
}
82+
83+
public function assertFormExists(): Closure
84+
{
85+
return function ($selector = 'form', $callback = null): TestComponent {
86+
/** @var TestComponent $this */
87+
Assert::assertNotEmpty(
88+
(string) $this->rendered,
89+
'The component is empty!'
90+
);
91+
92+
try {
93+
$parser = DomParser::new((string) $this->rendered);
94+
} catch (DOMException $exception) {
95+
Assert::fail($exception->getMessage());
96+
}
97+
98+
if ($selector instanceof Closure) {
99+
$callback = $selector;
100+
$selector = 'form';
101+
}
102+
103+
if (is_string($selector)) {
104+
$form = $parser->query($selector);
105+
} else {
106+
Assert::fail('Invalid selector!');
107+
}
108+
109+
Assert::assertNotNull(
110+
$form,
111+
sprintf('No form was found with selector "%s"', $selector)
112+
);
113+
Assert::assertEquals(
114+
'form',
115+
$form->nodeName,
116+
'Element is not of type form!');
117+
118+
if ($callback) {
119+
$callback(new AssertForm((string) $this->rendered, $form));
120+
}
121+
122+
return $this;
123+
};
124+
}
125+
}

src/TestResponseMacros.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
*/
2020
class TestResponseMacros
2121
{
22-
public function assertHtml5()
22+
public function assertHtml5(): Closure
2323
{
2424
return function () {
2525
/** @var TestResponse $this */

src/TestViewMacros.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
*/
2020
class TestViewMacros
2121
{
22-
public function assertHtml5()
22+
public function assertHtml5(): Closure
2323
{
2424
return function () {
2525
/** @var TestView $this */

0 commit comments

Comments
 (0)