Skip to content

Commit

Permalink
Merge branch 'master' of github.com:/PhpGt/DomTemplate
Browse files Browse the repository at this point in the history
  • Loading branch information
g105b committed Dec 12, 2023
2 parents afc9a52 + 913b654 commit 5ab216b
Show file tree
Hide file tree
Showing 10 changed files with 280 additions and 0 deletions.
104 changes: 104 additions & 0 deletions test/phpunit/ListBinderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
use Gt\Dom\HTMLDocument;
use Gt\DomTemplate\Bind;
use Gt\DomTemplate\BindableCache;
use Gt\DomTemplate\BindGetter;
use Gt\DomTemplate\ElementBinder;
use Gt\DomTemplate\HTMLAttributeBinder;
use Gt\DomTemplate\HTMLAttributeCollection;
Expand All @@ -20,6 +21,8 @@
use Gt\DomTemplate\ListElementCollection;
use Gt\DomTemplate\ListElement;
use Gt\DomTemplate\Test\TestHelper\HTMLPageContent;
use Gt\DomTemplate\Test\TestHelper\Model\IteratorAggregate\Music\MusicFactory;
use Gt\DomTemplate\Test\TestHelper\Model\IteratorAggregate\Student\StudentFactory;
use Gt\DomTemplate\Test\TestHelper\Model\Student;
use Gt\DomTemplate\Test\TestHelper\TestData;
use PHPUnit\Framework\TestCase;
Expand Down Expand Up @@ -821,4 +824,105 @@ private function listBinderDependencies(HTMLDocument $document, mixed...$otherOb
];
}

public function testBindListData_objectWithPublicIterable():void {
$obj1 = new class("First") {
public function __construct(public string $name) {}
#[BindGetter]
public function getLettersOfName():array {
return str_split($this->name, 1);
}
};
$obj2 = new class("Second") {
public function __construct(public string $name) {}
#[BindGetter]
public function getLettersOfName():array {
return str_split($this->name, 1);
}
};

$document = new HTMLDocument(HTMLPageContent::HTML_LIST_BIND_NAME);
$sut = new ListBinder();
$sut->setDependencies(...$this->listBinderDependencies($document));
$sut->bindListData([
$obj1,
$obj2,
], $document);

$nodeList = $document->querySelectorAll("ul li");
self::assertCount(2, $nodeList);
self::assertSame("First", $nodeList[0]->textContent);
self::assertSame("Second", $nodeList[1]->textContent);
}

public function testBindListData_iteratorAggregate():void {
$testData = (new MusicFactory())->buildArtistArray(TestData::MUSIC);
$document = new HTMLDocument(HTMLPageContent::HTML_MUSIC_NO_TEMPLATE_NAMES);
$sut = new ListBinder();
$sut->setDependencies(...$this->listBinderDependencies($document));
$sut->bindListData($testData, $document);

$arrayArtistData = TestData::MUSIC;

foreach($document->querySelectorAll("body>ul>li") as $artistLi) {
$artistName = key($arrayArtistData);
$arrayAlbumData = current($arrayArtistData);

self::assertSame($artistName, $artistLi->querySelector("h2")->textContent);

foreach($artistLi->querySelectorAll("ul>li") as $albumLi) {
$albumName = key($arrayAlbumData);
$arrayTrackData = current($arrayAlbumData);

self::assertSame($albumName, $albumLi->querySelector("h3")->textContent);

foreach($albumLi->querySelectorAll("ol>li") as $trackLi) {
$trackName = current($arrayTrackData);
self::assertSame($trackName, $trackLi->textContent);
next($arrayTrackData);
}

next($arrayAlbumData);
}

next($arrayArtistData);
}
}

/**
* This test asserts that the outer element has its data bound correctly.
* We know that the nested sub-lists are bound correctly from the music examples,
* but there's a bug where the outer element (representing the Student in this case)
* does not have its data bound correctly.
*/
public function testBindListData_iteratorAggregate_outerBinds():void {
$testData = (new StudentFactory())->buildStudentArray(TestData::STUDENTS);
$document = new HTMLDocument(HTMLPageContent::HTML_STUDENT_LIST_EXPLICIT_BINDS);
$sut = new ListBinder();
$sut->setDependencies(...$this->listBinderDependencies($document));
$sut->bindListData($testData, $document);

$arrayStudentData = TestData::STUDENTS;

foreach($document->querySelectorAll("body>ul>li") as $studentLi) {
$arrayStudent = current($arrayStudentData);
$firstName = $arrayStudent["firstName"];
$lastName = $arrayStudent["lastName"];

self::assertSame(
"$firstName $lastName",
trim(preg_replace("/\s+/", " ", $studentLi->querySelector("dd.name")->textContent))
);

$arrayModuleData = $arrayStudent["modules"];
foreach($studentLi->querySelectorAll(".modules ul>li") as $moduleLi) {
$moduleTitle = current($arrayModuleData);

self::assertSame($moduleTitle, $moduleLi->textContent);

next($arrayModuleData);
}

next($arrayStudentData);
}
}
}
33 changes: 33 additions & 0 deletions test/phpunit/TestHelper/HTMLPageContent.php
Original file line number Diff line number Diff line change
Expand Up @@ -1067,6 +1067,39 @@ class HTMLPageContent {
</ul>
HTML;

const HTML_LIST_BIND_NAME = <<<HTML
<!doctype html>
<ul>
<li data-list data-bind:text="name">Template item!</li>
</ul>
<ol>
<li>This doesn't have a data template attribute</li>
</ol>
<p data-bind:text="message">Text message goes here</p>
HTML;

const HTML_STUDENT_LIST_EXPLICIT_BINDS = <<<HTML
<!doctype html>
<h1>List of students:</h1>
<ul>
<li data-list>
<dl>
<dt>Student name</dt>
<dd class="name">
<span data-bind:text="name.first">First name</span>
<span data-bind:text="name.last">Last name</span>
</dd>
<dt>Current modules</dt>
<dd class="modules">
<ul>
<li data-list data-bind:text="title">Module name</li>
</ul>
</dd>
</dl>
</li>
</ul>
HTML;

public static function createHTML(string $html = ""):HTMLDocument {
return new HTMLDocument($html);
Expand Down
18 changes: 18 additions & 0 deletions test/phpunit/TestHelper/Model/IteratorAggregate/Music/Album.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php
namespace Gt\DomTemplate\Test\TestHelper\Model\IteratorAggregate\Music;

use ArrayIterator;
use IteratorAggregate;
use Traversable;

class Album implements IteratorAggregate {
/** @param array<Track> $trackList */
public function __construct(
public readonly string $name,
public readonly array $trackList,
) {}

public function getIterator():Traversable {
return new ArrayIterator($this->trackList);
}
}
19 changes: 19 additions & 0 deletions test/phpunit/TestHelper/Model/IteratorAggregate/Music/Artist.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php
namespace Gt\DomTemplate\Test\TestHelper\Model\IteratorAggregate\Music;

use ArrayIterator;
use IteratorAggregate;
use Traversable;

class Artist implements IteratorAggregate {
/** @param array<Album> $albumList */
public function __construct(
public readonly string $name,
public readonly array $albumList,
) {
}

public function getIterator():Traversable {
return new ArrayIterator($this->albumList);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php
namespace Gt\DomTemplate\Test\TestHelper\Model\IteratorAggregate\Music;

class MusicFactory {
/**
* @param array<string, array<string, array<string>>> $input
* @return array<Artist>
*/
public function buildArtistArray(array $input):array {
$artistArray = [];

foreach($input as $artistName => $inputAlbums) {
$albumList = [];
foreach($inputAlbums as $albumName => $inputTracks) {
$trackList = [];
foreach($inputTracks as $trackName) {
$trackList[$trackName] = new Track($trackName, rand(20, 300));
}

$albumList[$albumName] = new Album($albumName, $trackList);
}

$artistArray[$artistName] = new Artist($artistName, $albumList);
}

return $artistArray;
}
}
10 changes: 10 additions & 0 deletions test/phpunit/TestHelper/Model/IteratorAggregate/Music/Track.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php
namespace Gt\DomTemplate\Test\TestHelper\Model\IteratorAggregate\Music;

class Track {
public function __construct(
public string $name,
public ?int $durationSeconds = null,
) {
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php
namespace Gt\DomTemplate\Test\TestHelper\Model\IteratorAggregate\Student;

class Module {
public function __construct(
public readonly string $title,
) {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php
namespace Gt\DomTemplate\Test\TestHelper\Model\IteratorAggregate\Student;

class Name {
public function __construct(
public readonly string $first,
public readonly string $last,
) {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php
namespace Gt\DomTemplate\Test\TestHelper\Model\IteratorAggregate\Student;

use Traversable;

class Student implements \IteratorAggregate {
/** @param array<Module> $moduleList */
public function __construct(
public readonly Name $name,
public readonly array $moduleList,
) {}

public function getIterator():Traversable {
return new \ArrayIterator($this->moduleList);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

namespace Gt\DomTemplate\Test\TestHelper\Model\IteratorAggregate\Student;

class StudentFactory {
/**
* @param array<int, array<string, string|array<string>>> $input
* @return array<Student>
*/
public function buildStudentArray(array $input):array {
$studentArray = [];

foreach($input as $inputStudent) {
$moduleList = [];
foreach($inputStudent["modules"] as $moduleName) {
array_push(
$moduleList,
new Module($moduleName),
);
}

$name = new Name($inputStudent["firstName"], $inputStudent["lastName"]);

array_push(
$studentArray,
new Student(
$name,
$moduleList,
),
);
}

return $studentArray;
}
}

0 comments on commit 5ab216b

Please sign in to comment.