Skip to content

Commit

Permalink
Partial exceptions (#270)
Browse files Browse the repository at this point in the history
* build: upgrade to stable dom release

* test: bind objects in arrays with bindList

* test: isolate first issue for #244

* feature: throw exception when no data-partial
for #244

* feature: throw exception when more than one data-partial
for #244
  • Loading branch information
g105b authored Oct 12, 2021
1 parent a8fc93f commit 2bb6450
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 4 deletions.
14 changes: 11 additions & 3 deletions src/PartialExpander.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public function expand(Element $context = null):array {
$context = $this->document->documentElement;
}

/** @var HTMLDocument[] $partialDocumentArray */
/** @var array<string, HTMLDocument> $partialDocumentArray */
$partialDocumentArray = [];
do {
$commentIni = new CommentIni($context);
Expand All @@ -30,7 +30,7 @@ public function expand(Element $context = null):array {
}
while(true);

foreach($partialDocumentArray as $partialDocument) {
foreach($partialDocumentArray as $extends => $partialDocument) {
if($currentTitle = $this->document->title) {
$partialDocument->title = $currentTitle;
}
Expand All @@ -40,7 +40,15 @@ public function expand(Element $context = null):array {
$partialDocument->documentElement,
true
);
$injectionPoint = $importedRoot->querySelector("[data-partial]");
$partialElementList = $importedRoot->querySelectorAll("[data-partial]");
if(count($partialElementList) > 1) {
throw new PartialInjectionMultiplePointException("The current view extends the partial \"$extends\", but there is more than one element marked with `data-partial`. For help, see https://www.php.gt/domtemplate/partials");
}
$injectionPoint = $partialElementList[0] ?? null;

if(!$injectionPoint) {
throw new PartialInjectionPointNotFoundException("The current view extends the partial \"$extends\", but there is no element marked with `data-partial`. For help, see https://www.php.gt/domtemplate/partials");
}

// Move all the current document's content into the newly-imported injection point:
while($child = $this->document->body->firstChild) {
Expand Down
4 changes: 4 additions & 0 deletions src/PartialInjectionMultiplePointException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?php
namespace Gt\DomTemplate;

class PartialInjectionMultiplePointException extends DomTemplateException {}
4 changes: 4 additions & 0 deletions src/PartialInjectionPointNotFoundException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?php
namespace Gt\DomTemplate;

class PartialInjectionPointNotFoundException extends DomTemplateException {}
29 changes: 29 additions & 0 deletions test/phpunit/PartialExpanderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
use Gt\DomTemplate\ModularContent;
use Gt\DomTemplate\ModularContentFileNotFoundException;
use Gt\DomTemplate\PartialExpander;
use Gt\DomTemplate\PartialInjectionMultiplePointException;
use Gt\DomTemplate\PartialInjectionPointNotFoundException;
use Gt\DomTemplate\Test\TestFactory\DocumentTestFactory;

class PartialExpanderTest extends ModularContentTestCase {
Expand Down Expand Up @@ -90,4 +92,31 @@ public function testExpand_recursive():void {
);
self::assertSame("This title was set in the inner partial view.", $document->title);
}

public function testExpand_noDataPartialElement():void {
$document = DocumentTestFactory::createHTML(DocumentTestFactory::HTML_EXTENDS_PARTIAL_VIEW);
$modularContent = self::mockModularContent(
"_partial", [
// Here, the HTML_COMPONENT isn't expected, because there is no data-partial element.
"base-page" => DocumentTestFactory::HTML_COMPONENT,
]
);
$sut = new PartialExpander($document, $modularContent);
self::expectException(PartialInjectionPointNotFoundException::class);
self::expectExceptionMessage("The current view extends the partial \"base-page\", but there is no element marked with `data-partial`.");
$sut->expand();
}

public function testExpand_multipleDataPartialElements():void {
$document = DocumentTestFactory::createHTML(DocumentTestFactory::HTML_EXTENDS_PARTIAL_VIEW);
$modularContent = self::mockModularContent(
"_partial", [
"base-page" => DocumentTestFactory::HTML_INCORRECT_PARTIAL_VIEW,
]
);
$sut = new PartialExpander($document, $modularContent);
self::expectException(PartialInjectionMultiplePointException::class);
self::expectExceptionMessage("The current view extends the partial \"base-page\", but there is more than one element marked with `data-partial`.");
$sut->expand();
}
}
29 changes: 28 additions & 1 deletion test/phpunit/TestFactory/DocumentTestFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,32 @@ class DocumentTestFactory {
</footer>
</body>
</html>
HTML;

const HTML_INCORRECT_PARTIAL_VIEW = <<<HTML
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<title data-bind:test="title">My website</title>
</head>
<body>
<header>
<h1>My website!</h1>
</header>
<main data-partial>
The page content will go in here.
</main>
<div>
<article data-partial>
But, there's another partial element here, so things will break.
</article>
</div>
<footer>
<p>Thank you for visiting!</p>
</footer>
</body>
</html>
HTML;

const HTML_EXTENDS_PARTIAL_VIEW = <<<HTML
Expand All @@ -433,6 +459,7 @@ class DocumentTestFactory {
</aside>
HTML;


const HTML_INCORRECTLY_EXTENDS_PARTIAL_VIEW = <<<HTML
<article>
<h1>Hello from within a sub-template!</h1>
Expand Down Expand Up @@ -485,7 +512,7 @@ class DocumentTestFactory {
<h1>Component test</h1>
<p>This test shows how a custom element can be injected into the document.</p>
<custom-element />
<p>If there's matching modular content in the _compnent directory, the above element will be filled with its content.</p>
<p>If there's matching modular content in the _component directory, the above element will be filled with its content.</p>
HTML;

const HTML_TRANSPORT_ROUTES = <<<HTML
Expand Down

0 comments on commit 2bb6450

Please sign in to comment.