Skip to content

Commit

Permalink
refactor: all domtemplate classes set their dependencies outside of t…
Browse files Browse the repository at this point in the history
…he constructor

for #470
  • Loading branch information
g105b committed Oct 27, 2023
1 parent 3b3a883 commit cbfdff3
Show file tree
Hide file tree
Showing 14 changed files with 527 additions and 185 deletions.
4 changes: 3 additions & 1 deletion src/CommentIni.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ public function __construct(
$data = trim($commentNode->data);

try {
$ini = parse_ini_string($data, true);
// We know that sometimes this data will not be correct ini format, and it might actually be a textual comment.
// Therefore, we must suppress the warning that is emitted by parse_ini_string:
$ini = @parse_ini_string($data, true);
$commentNodeToRemove = $commentNode;
}
catch(Throwable) {
Expand Down
25 changes: 4 additions & 21 deletions src/ComponentBinder.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,10 @@
use Gt\Dom\Element;

class ComponentBinder extends DocumentBinder {
public function __construct(
private Element $componentElement,
Document $document,
array $config = [],
?ElementBinder $elementBinder = null,
?PlaceholderBinder $placeholderBinder = null,
?TableBinder $tableBinder = null,
?ListBinder $listBinder = null,
?ListElementCollection $templateCollection = null,
?BindableCache $bindableCache = null,
) {
parent::__construct(
$document,
$config,
$elementBinder,
$placeholderBinder,
$tableBinder,
$listBinder,
$templateCollection,
$bindableCache,
);
private Element $componentElement;

public function setComponentBinderDependencies(Element $componentElement):void {
$this->componentElement = $componentElement;
}

public function bindList(
Expand Down
42 changes: 16 additions & 26 deletions src/DocumentBinder.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,33 +13,24 @@ class DocumentBinder extends Binder {
protected ListElementCollection $templateCollection;
protected BindableCache $bindableCache;

/**
* @param array<string, string> $config
*/
public function __construct(
protected readonly Document $document,
private array $config = [],
?ElementBinder $elementBinder = null,
?PlaceholderBinder $placeholderBinder = null,
?TableBinder $tableBinder = null,
?ListBinder $listBinder = null,
?ListElementCollection $templateCollection = null,
?BindableCache $bindableCache = null
) {
$this->templateCollection = $templateCollection ?? new ListElementCollection($document);
$this->elementBinder = $elementBinder ?? new ElementBinder();
$this->placeholderBinder = $placeholderBinder ?? new PlaceholderBinder();
$this->tableBinder = $tableBinder ?? new TableBinder($this->templateCollection);
$this->listBinder = $listBinder ?? new ListBinder($this->templateCollection);
$this->bindableCache = $bindableCache ?? new BindableCache();

// This is temporary, to suppress PHPStan's complaints for declaring a variable
// without using it. There are plans to use the config variable, but it is
// currently not yet used, and this technique prevents the constructor
// parameters from changing over time.
if(!$this->config) {
$this->config = [];
}
) {}

public function setDependencies(
ElementBinder $elementBinder,
PlaceholderBinder $placeholderBinder,
TableBinder $tableBinder,
ListBinder $listBinder,
ListElementCollection $listElementCollection,
BindableCache $bindableCache,
):void {
$this->elementBinder = $elementBinder;
$this->placeholderBinder = $placeholderBinder;
$this->tableBinder = $tableBinder;
$this->listBinder = $listBinder;
$this->templateCollection = $listElementCollection;
$this->bindableCache = $bindableCache;
}

/**
Expand Down Expand Up @@ -177,7 +168,6 @@ protected function bind(
}

$this->elementBinder->bind($key, $value, $context);
$this->placeholderBinder->bind($key, $value, $context);
}

private function isIndexedArray(mixed $data):bool {
Expand Down
14 changes: 7 additions & 7 deletions src/ElementBinder.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ class ElementBinder {
private HTMLAttributeCollection $htmlAttributeCollection;
private PlaceholderBinder $placeholderBinder;

public function __construct(
?HTMLAttributeBinder $htmlAttributeBinder = null,
?HTMLAttributeCollection $htmlAttributeCollection = null,
?PlaceholderBinder $placeholderBinder = null,
public function setDependencies(
HTMLAttributeBinder $htmlAttributeBinder,
HTMLAttributeCollection $htmlAttributeCollection,
PlaceholderBinder $placeholderBinder,
) {
$this->htmlAttributeBinder = $htmlAttributeBinder ?? new HTMLAttributeBinder();
$this->htmlAttributeCollection = $htmlAttributeCollection ?? new HTMLAttributeCollection();
$this->placeholderBinder = $placeholderBinder ?? new PlaceholderBinder();
$this->htmlAttributeBinder = $htmlAttributeBinder;
$this->htmlAttributeCollection = $htmlAttributeCollection;
$this->placeholderBinder = $placeholderBinder;
}

/**
Expand Down
10 changes: 7 additions & 3 deletions src/HTMLAttributeBinder.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,14 @@
use Gt\Dom\Element;

class HTMLAttributeBinder {
private ListBinder $listBinder;
private TableBinder $tableBinder;

public function setDependencies(ListBinder $listBinder, TableBinder $tableBinder) {
$this->listBinder = $listBinder;
$this->tableBinder = $tableBinder;
}

public function bind(
?string $key,
mixed $value,
Expand Down Expand Up @@ -202,9 +208,6 @@ private function setBindProperty(
break;

case "table":
if(!isset($this->tableBinder)) {
$this->tableBinder = new TableBinder();
}
$this->tableBinder->bindTableData(
$bindValue,
$element,
Expand All @@ -217,6 +220,7 @@ private function setBindProperty(
break;

case "list";
$this->listBinder->bindListData($bindValue, $element);
break;

default:
Expand Down
21 changes: 14 additions & 7 deletions src/ListBinder.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,21 @@
use Stringable;

class ListBinder {
private ElementBinder $elementBinder;
private ListElementCollection $listElementCollection;
private BindableCache $bindableCache;
private TableBinder $tableBinder;

/** @noinspection PhpPropertyCanBeReadonlyInspection */
public function __construct(
private ListElementCollection $listElementCollection,
?BindableCache $bindableCache = null
) {
$this->bindableCache = $bindableCache ?? new BindableCache();
public function setDependencies(
ElementBinder $elementBinder,
ListElementCollection $listElementCollection,
BindableCache $bindableCache,
TableBinder $tableBinder
):void {
$this->elementBinder = $elementBinder;
$this->listElementCollection = $listElementCollection;
$this->bindableCache = $bindableCache;
$this->tableBinder = $tableBinder;
}

/** @param iterable<int|string,mixed> $listData */
Expand Down Expand Up @@ -50,7 +57,7 @@ public function bindListData(
}
}

$elementBinder = new ElementBinder();
$elementBinder = $this->elementBinder;
$nestedCount = 0;
$i = -1;
foreach($listData as $listKey => $listValue) {
Expand Down
37 changes: 28 additions & 9 deletions src/TableBinder.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,28 @@
use Traversable;

class TableBinder {
/** @noinspection PhpPropertyCanBeReadonlyInspection */
public function __construct(
private ?ListElementCollection $templateCollection = null,
private ?ElementBinder $elementBinder = null,
private ?HTMLAttributeBinder $htmlAttributeBinder = null,
private ?HTMLAttributeCollection $htmlAttributeCollection = null,
private ?PlaceholderBinder $placeholderBinder = null
) {}
private ListBinder $listBinder;
private ListElementCollection $templateCollection;
private ElementBinder $elementBinder;
private HTMLAttributeBinder $htmlAttributeBinder;
private HTMLAttributeCollection $htmlAttributeCollection;
private PlaceholderBinder $placeholderBinder;

public function setDependencies(
ListBinder $listBinder,
ListElementCollection $listElementCollection,
ElementBinder $elementBinder,
HTMLAttributeBinder $htmlAttributeBinder,
HTMLAttributeCollection $htmlAttributeCollection,
PlaceholderBinder $placeholderBinder,
) {
$this->listBinder = $listBinder;
$this->templateCollection = $listElementCollection;
$this->elementBinder = $elementBinder;
$this->htmlAttributeBinder = $htmlAttributeBinder;
$this->htmlAttributeCollection = $htmlAttributeCollection;
$this->placeholderBinder = $placeholderBinder;
}

/**
* @param array<int, array<int, string>>|array<int, array<int|string, string|array<int, mixed>>> $tableData
Expand Down Expand Up @@ -330,7 +344,10 @@ private function normaliseTableData(iterable $bindValue):array {

private function initBinders():void {
if(!$this->htmlAttributeBinder) {
$this->htmlAttributeBinder = new HTMLAttributeBinder();
$this->htmlAttributeBinder = new HTMLAttributeBinder(
$this->listBinder,
$this,
);
}
if(!$this->htmlAttributeCollection) {
$this->htmlAttributeCollection = new HTMLAttributeCollection();
Expand All @@ -340,6 +357,8 @@ private function initBinders():void {
}
if(!$this->elementBinder) {
$this->elementBinder = new ElementBinder(
$this->listBinder,
$this,
$this->htmlAttributeBinder,
$this->htmlAttributeCollection,
$this->placeholderBinder
Expand Down
40 changes: 34 additions & 6 deletions test/phpunit/ComponentBinderTest.php
Original file line number Diff line number Diff line change
@@ -1,17 +1,24 @@
<?php
namespace Gt\DomTemplate\Test;
use Gt\Dom\HTMLDocument;
use Gt\DomTemplate\BindableCache;
use Gt\DomTemplate\ComponentBinder;
use Gt\DomTemplate\ComponentDoesNotContainContextException;
use Gt\DomTemplate\ComponentExpander;
use Gt\DomTemplate\ElementBinder;
use Gt\DomTemplate\ListBinder;
use Gt\DomTemplate\ListElementCollection;
use Gt\DomTemplate\PlaceholderBinder;
use Gt\DomTemplate\TableBinder;
use Gt\DomTemplate\Test\TestHelper\HTMLPageContent;
use PHPUnit\Framework\TestCase;

class ComponentBinderTest extends TestCase {
public function testBindKeyValue_invalidContext():void {
$document = new HTMLDocument(HTMLPageContent::HTML_TODO_CUSTOM_ELEMENT_ALREADY_EXPANDED);
$componentElement = $document->querySelector("todo-list");
$sut = new ComponentBinder($componentElement, $document);
$sut = new ComponentBinder($document);
$sut->setComponentBinderDependencies($componentElement);
self::expectException(ComponentDoesNotContainContextException::class);
self::expectExceptionMessage("<todo-list> does not contain requested <body>");
$sut->bindKeyValue("example-key", "example-value", $document->querySelector("body"));
Expand All @@ -20,7 +27,8 @@ public function testBindKeyValue_invalidContext():void {
public function testBindList_invalidContext():void {
$document = new HTMLDocument(HTMLPageContent::HTML_TODO_CUSTOM_ELEMENT_ALREADY_EXPANDED);
$componentElement = $document->querySelector("todo-list");
$sut = new ComponentBinder($componentElement, $document);
$sut = new ComponentBinder($document);
$sut->setComponentBinderDependencies($componentElement);
self::expectException(ComponentDoesNotContainContextException::class);
self::expectExceptionMessage("<todo-list> does not contain requested <body>");
$sut->bindList([], $document->querySelector("body"));
Expand All @@ -29,18 +37,38 @@ public function testBindList_invalidContext():void {
public function testBindKeyValue_notInContext():void {
$document = new HTMLDocument(HTMLPageContent::HTML_TODO_CUSTOM_ELEMENT_ALREADY_EXPANDED);
$componentElement = $document->querySelector("todo-list");
$sut = new ComponentBinder($componentElement, $document);

$sut = new ComponentBinder($document);
$sut->setDependencies(
self::createMock(ElementBinder::class),
self::createMock(PlaceholderBinder::class),
self::createMock(TableBinder::class),
self::createMock(ListBinder::class),
self::createMock(ListElementCollection::class),
self::createMock(BindableCache::class),
);
$sut->setComponentBinderDependencies($componentElement);
$sut->bindKeyValue("subtitle", "This should not change!");
self::assertSame("Subtitle here", $document->querySelector("h2")->innerText);
}

public function testBindKeyValue():void {
$document = new HTMLDocument(HTMLPageContent::HTML_TODO_CUSTOM_ELEMENT_ALREADY_EXPANDED);
$componentElement = $document->querySelector("todo-list");
$sut = new ComponentBinder($componentElement, $document);
$elementBinder = self::createMock(ElementBinder::class);
$elementBinder->expects(self::once())
->method("bind")
->with("listTitle", "This should change!", $componentElement);

$sut = new ComponentBinder($document);
$sut->setDependencies(
$elementBinder,
self::createMock(PlaceholderBinder::class),
self::createMock(TableBinder::class),
self::createMock(ListBinder::class),
self::createMock(ListElementCollection::class),
self::createMock(BindableCache::class),
);
$sut->setComponentBinderDependencies($componentElement);
$sut->bindKeyValue("listTitle", "This should change!");
self::assertSame("This should change!", $document->querySelector("h3")->innerText);
}
}
Loading

0 comments on commit cbfdff3

Please sign in to comment.