Skip to content

Commit e83d033

Browse files
authored
Merge pull request #28 from tonysm/replace-simplexml-with-dom-api
Replaces usage of simplexml_load_string with DOMDocument and DOMElement
2 parents ee13952 + 007eb5d commit e83d033

2 files changed

Lines changed: 28 additions & 48 deletions

File tree

src/Testing/ConvertTestResponseToTurboStreamCollection.php

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,25 @@
22

33
namespace Tonysm\TurboLaravel\Testing;
44

5+
use DOMDocument;
56
use Illuminate\Support\Collection;
67
use Illuminate\Testing\TestResponse;
78

89
class ConvertTestResponseToTurboStreamCollection
910
{
1011
public function __invoke(TestResponse $response): Collection
1112
{
12-
$parsed = simplexml_load_string(<<<XML
13-
<xml>{$response->content()}</xml>
14-
XML);
13+
libxml_use_internal_errors(true);
14+
$document = tap(new DOMDocument())->loadHTML($response->content());
15+
$elements = $document->getElementsByTagName('turbo-stream');
1516

16-
return collect(json_decode(json_encode($parsed), true)['turbo-stream']);
17+
$streams = collect();
18+
19+
/** @var \DOMElement $element */
20+
foreach ($elements as $element) {
21+
$streams->push($element);
22+
}
23+
24+
return $streams;
1725
}
1826
}

src/Testing/TurboStreamMatcher.php

Lines changed: 16 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,18 @@
33
namespace Tonysm\TurboLaravel\Testing;
44

55
use Closure;
6-
use Illuminate\Http\Response;
7-
use Illuminate\Support\Arr;
8-
use Illuminate\Testing\TestResponse;
6+
use DOMElement;
97
use Illuminate\View\ComponentAttributeBag;
8+
use PHPUnit\Framework\Assert;
109

1110
class TurboStreamMatcher
1211
{
12+
/** @var \DOMElement */
1313
private $turboStream;
1414
private array $wheres = [];
1515
private array $contents = [];
1616

17-
public function __construct($turboStream)
17+
public function __construct(DOMElement $turboStream)
1818
{
1919
$this->turboStream = $turboStream;
2020
}
@@ -70,9 +70,9 @@ public function attrs(): string
7070
private function matchesProps()
7171
{
7272
foreach ($this->wheres as $prop => $value) {
73-
$actualProp = $this->turboStream['@attributes'][$prop] ?? false;
73+
$propValue = $this->turboStream->getAttribute($prop);
7474

75-
if ($actualProp === false || $actualProp !== $value) {
75+
if (! $propValue || $propValue !== $value) {
7676
return false;
7777
}
7878
}
@@ -86,55 +86,27 @@ private function matchesContents()
8686
return true;
8787
}
8888

89-
// To assert that the Turbo Stream contains the desired text, we first need to
90-
// rebuild the markup from the response. This is because we had to parse the
91-
// HTML before getting here so we could assert each Turbo Stream separately.
92-
93-
$content = new TestResponse(new Response($this->makeElements($this->turboStream['template'] ?? [])));
94-
95-
foreach ($this->contents as $expectedContent) {
96-
$content->assertSee($expectedContent);
89+
foreach ($this->contents as $content) {
90+
Assert::assertStringContainsString($content, $this->renderElement());
9791
}
9892

9993
return true;
10094
}
10195

102-
private function makeAttributes(array $attributes): string
103-
{
104-
return (new ComponentAttributeBag($attributes))->toHtml();
105-
}
106-
107-
private function makeElements($tags)
96+
private function renderElement(): string
10897
{
109-
if (is_string($tags)) {
110-
return $tags;
111-
}
112-
113-
$content = '';
114-
115-
foreach ($tags as $tag => $contents) {
116-
$attrs = $this->makeAttributes($contents['@attributes'] ?? []);
117-
118-
$strContent = $this->makeElements(is_array($contents) ? Arr::except($contents, '@attributes') : $contents);
119-
$opening = trim(sprintf('%s %s', $tag, $attrs));
98+
$html = '';
99+
$children = $this->turboStream->childNodes;
120100

121-
if ($this->isSelfClosingTag($tag)) {
122-
$content .= "<{$opening} />";
123-
} else {
124-
$content .= "<{$opening}>{$strContent}</{$tag}>";
125-
}
101+
foreach ($children as $child) {
102+
$html .= $child->ownerDocument->saveXML($child);
126103
}
127104

128-
return $content;
105+
return $html;
129106
}
130107

131-
private function isSelfClosingTag(string $tag): bool
108+
private function makeAttributes(array $attributes): string
132109
{
133-
return in_array($tag, [
134-
'input',
135-
'img',
136-
'br',
137-
'source',
138-
]);
110+
return (new ComponentAttributeBag($attributes))->toHtml();
139111
}
140112
}

0 commit comments

Comments
 (0)