33namespace Tonysm \TurboLaravel \Testing ;
44
55use Closure ;
6- use Illuminate \Http \Response ;
7- use Illuminate \Support \Arr ;
8- use Illuminate \Testing \TestResponse ;
6+ use DOMElement ;
97use Illuminate \View \ComponentAttributeBag ;
8+ use PHPUnit \Framework \Assert ;
109
1110class 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