From e687d24b8e67dfc1517f9c8906252e979a1153ff Mon Sep 17 00:00:00 2001 From: Greg Bowler Date: Mon, 27 Feb 2023 16:43:29 +0000 Subject: [PATCH] Improvements to working with lists of data (data-bind:list and nested object improvements) (#415) * build: upgrade dom requirement and loosen version range * docs: update examples * feature: trim whitespace when there are only template children closes #363 * maintenance: phpstorm analysis improvements * test: refactor test helper class * wip: add test data for big integration * test: add failing test to cover nested objects for #356 * test: add extra cases for nested object test * feature: allow nesting of object properties closes #356 * maintenance: static analysis improvement * test: nested objects with bindgetter functions * test: isolate issue #367 * test: use `data-template-parent` attribute internally instead of id closes #367 * test: isolate functionality for #368 * wip: implementation for #368 not yet completed * feature: data-bind:list closes #368 * tidy: static analysis improvements * tidy: types of reflection method improved * tidy: remove unused import * tidy: nullable reflection type * tidy: remove unused elements * docs: add nested music example --- examples/binding/13-bindList-nested-music.php | 182 ++++++++++++++++++ src/BindableCache.php | 166 +++++++++++++--- src/CommentIni.php | 5 +- src/DocumentBinder.php | 7 +- src/HTMLAttributeBinder.php | 20 ++ src/NodePathCalculator.php | 29 ++- src/TemplateElement.php | 8 +- test/phpunit/BindableCacheTest.php | 23 +++ test/phpunit/CommentIniTest.php | 14 +- test/phpunit/ComponentExpanderTest.php | 19 +- test/phpunit/DocumentBinderTest.php | 146 ++++++++------ test/phpunit/HTMLAttributeBinderTest.php | 24 +-- test/phpunit/ListBinderTest.php | 81 +++++--- test/phpunit/PartialContentTest.php | 2 +- test/phpunit/PartialExpanderTest.php | 34 ++-- test/phpunit/PlaceholderBinderTest.php | 18 +- test/phpunit/TableBinderTest.php | 32 +-- test/phpunit/TemplateCollectionTest.php | 19 +- test/phpunit/TemplateElementTest.php | 8 +- test/phpunit/TestData.php | 97 ---------- .../ExampleClass.php | 2 +- .../HTMLPageContent.php} | 92 ++++++++- test/phpunit/TestHelper/Model/Address.php | 14 ++ test/phpunit/TestHelper/Model/Country.php | 28 +++ test/phpunit/TestHelper/Model/Currency.php | 27 +++ test/phpunit/TestHelper/Model/Customer.php | 16 ++ test/phpunit/TestHelper/Model/Money.php | 33 ++++ test/phpunit/TestHelper/Model/Order.php | 31 +++ test/phpunit/TestHelper/Model/ShopItem.php | 11 ++ test/phpunit/TestHelper/TestData.php | 173 +++++++++++++++++ 30 files changed, 1052 insertions(+), 309 deletions(-) create mode 100644 examples/binding/13-bindList-nested-music.php delete mode 100644 test/phpunit/TestData.php rename test/phpunit/{TestFactory => TestHelper}/ExampleClass.php (79%) rename test/phpunit/{TestFactory/DocumentTestFactory.php => TestHelper/HTMLPageContent.php} (89%) create mode 100644 test/phpunit/TestHelper/Model/Address.php create mode 100644 test/phpunit/TestHelper/Model/Country.php create mode 100644 test/phpunit/TestHelper/Model/Currency.php create mode 100644 test/phpunit/TestHelper/Model/Customer.php create mode 100644 test/phpunit/TestHelper/Model/Money.php create mode 100644 test/phpunit/TestHelper/Model/Order.php create mode 100644 test/phpunit/TestHelper/Model/ShopItem.php create mode 100644 test/phpunit/TestHelper/TestData.php diff --git a/examples/binding/13-bindList-nested-music.php b/examples/binding/13-bindList-nested-music.php new file mode 100644 index 0000000..1aa76e0 --- /dev/null +++ b/examples/binding/13-bindList-nested-music.php @@ -0,0 +1,182 @@ + +

Music library

+ + +HTML; + +$musicData = [ + "A Band From Your Childhood" => [ + "This Album is Good" => [ + "The Best Song You‘ve Ever Heard", + "Another Cracking Tune", + "Top Notch Music Here", + "The Best Is Left ‘Til Last", + ], + "Adequate Collection" => [ + "Meh", + "‘sok", + "Sounds Like Every Other Song", + ], + ], + "Bongo and The Bronks" => [ + "Salad" => [ + "Tomatoes", + "Song About Cucumber", + "Onions Make Me Cry (but I love them)", + ], + "Meat" => [ + "Steak", + "Is Chicken Really a Meat?", + "Don‘t Look in the Sausage Factory", + "Stop Horsing Around", + ], + "SnaxX" => [ + "Crispy Potatoes With Salt", + "Pretzel Song", + "Pork Scratchings Are Skin", + "The Peanut Is Not Actually A Nut", + ], + ], + "Crayons" => [ + "Pastel Colours" => [ + "Egg Shell", + "Cotton", + "Frost", + "Periwinkle", + ], + "Different Shades of Blue" => [ + "Cobalt", + "Slate", + "Indigo", + "Teal", + ], + ] +]; + +function example(DocumentBinder $binder, array $musicData):void { + $binder->bindList($musicData); +} + +$document = new HTMLDocument($html); +$binder = new DocumentBinder($document); + +example($binder, $musicData); + +echo $document; + +/* +Output: + + +

Music library

+ + +*/ diff --git a/src/BindableCache.php b/src/BindableCache.php index 6ddc9d9..4f10e46 100644 --- a/src/BindableCache.php +++ b/src/BindableCache.php @@ -1,10 +1,14 @@ A cache of class names that are known to * NOT be bindable (to avoid having to check with reflection each time). */ - private array $nonBindableClasses; + private array $nonBindableClassMap; public function __construct() { - $this->classAttributes = []; - $this->nonBindableClasses = []; + $this->bindableClassMap = []; + $this->nonBindableClassMap = []; } public function isBindable(object $object):bool { - if(isset($this->classAttributes[$object::class])) { + $refObj = null; + + if($object instanceof ReflectionClass) { + $refObj = $object; + $classString = $refObj->getNamespaceName() . "\\" . $refObj->getShortName(); + } + else { + $classString = $object::class; + } + + if(isset($this->bindableClassMap[$classString])) { return true; } - if(isset($this->nonBindableClasses[$object::class])) { + if(isset($this->nonBindableClassMap[$classString])) { return false; } // Reflection is SLOW! The two checks above ensure that this step is only done // once per class (not object). - $refObj = new ReflectionObject($object); + if(!$refObj) { + $refObj = new ReflectionObject($object); + } $attributeCache = []; + $cacheObjectKeys = []; + foreach($refObj->getMethods() as $refMethod) { $refAttributes = $this->getBindAttributes($refMethod); $methodName = $refMethod->getName(); + /** @var ?ReflectionNamedType $refReturn */ + $refReturn = $refMethod->getReturnType(); + $refReturnName = $refReturn?->getName(); + foreach($refAttributes as $refAttr) { $bindKey = $this->getBindKey($refAttr, $refMethod); - $attributeCache[$bindKey] - = fn(object $object) => $object->$methodName(); + $attributeCache[$bindKey] = fn(object $object):null|iterable|string + => $this->nullableStringOrIterable($object->$methodName()); + if(class_exists($refReturnName)) { + $cacheObjectKeys[$bindKey] = $refReturnName; + } } } + foreach($refObj->getProperties() as $refProp) { $propName = $refProp->getName(); - if($refProp->isPublic() && $refProp->isInitialized($object)) { - if(is_null($object->$propName) || is_scalar($object->$propName) || $object->$propName instanceof Stringable) { - $bindKey = $propName; + + if($refAttributes = $this->getBindAttributes($refProp)) { + foreach($refAttributes as $refAttr) { + $bindKey = $this->getBindKey($refAttr); +// TODO: Test for object type in object property. $attributeCache[$bindKey] - = fn(object $object, $key):?string => $object->$key; + = fn(object $object, $key):null|iterable|string => $this->nullableStringOrIterable($object->$propName); } } - $refAttributes = $this->getBindAttributes($refProp); + elseif($refProp->isPublic()) { + $bindKey = $propName; - foreach($refAttributes as $refAttr) { - $bindKey = $this->getBindKey($refAttr); - $value = $object->$propName; - if(!is_null($value)) { - $value = (string)$value; - } + /** @var ?ReflectionNamedType $refType */ + $refType = $refProp->getType(); + $refTypeName = $refType?->getName(); $attributeCache[$bindKey] - = fn(object $object) => $value; + = fn(object $object, $key):null|iterable|string => isset($object->$key) ? $this->nullableStringOrIterable($object->$key) : null; + if(class_exists($refTypeName)) { + $cacheObjectKeys[$bindKey] = $refTypeName; + } } } if(empty($attributeCache)) { - $this->nonBindableClasses[$object::class] = true; + $this->nonBindableClassMap[$object::class] = true; return false; } - $this->classAttributes[$object::class] = $attributeCache; + $attributeCache = $this->expandObjects( + $attributeCache, + $cacheObjectKeys, + ); + + $this->bindableClassMap[$classString] = $attributeCache; return true; } + /** + * @param array $cache + * @param array $objectKeys + * @return array + */ + private function expandObjects(array $cache, array $objectKeys):array { + if(empty($objectKeys)) { + return $cache; + } + + foreach($cache as $key => $closure) { + if($objectType = $objectKeys[$key] ?? null) { + $refClass = new ReflectionClass($objectType); + if($this->isBindable($refClass)) { + $bindable = $this->bindableClassMap[$objectType]; + foreach($bindable as $bindableKey => $bindableClosure) { + $cache["$key.$bindableKey"] = $bindableClosure; + } + } + +// unset($cache[$key]); + } + } + + return $cache; + } + /** @return array */ public function convertToKvp(object $object):array { $kvp = []; + if($object instanceof stdClass) { + foreach(get_object_vars($object) as $key => $value) { + if(is_null($value)) { + $kvp[$key] = null; + } + elseif(is_iterable($value)) { + $kvp[$key] = $value; + } + else { + $kvp[$key] = (string)$value; + } + } + return $kvp; + } + if(!$this->isBindable($object)) { return []; } - foreach($this->classAttributes[$object::class] as $key => $closure) { - $kvp[$key] = $closure($object, $key); + $className = $object::class; + foreach($this->bindableClassMap[$className] as $key => $closure) { + $objectToExtract = $object; + $deepKey = $key; + $deepestKey = $key; + while(str_contains($deepKey, ".")) { + $propName = strtok($deepKey, "."); + $deepKey = substr($deepKey, strpos($deepKey, ".") + 1); + $deepestKey = $deepKey; +// TODO: This "get*()" function should not be hard coded here - it should load the appropriate +// Bind/BindGetter by matching the correct Attribute. + $bindFunc = "get" . ucfirst($propName); + $objectToExtract = $objectToExtract->$propName ?? $objectToExtract->$bindFunc(); + } + + $value = $closure($objectToExtract, $deepestKey); + if(is_null($value)) { + $kvp[$key] = null; + } + elseif(is_iterable($value)) { + $kvp[$key] = $value; + } + else { + $kvp[$key] = (string)$value; + } } return $kvp; @@ -123,4 +222,21 @@ private function getBindKey( return $refAttr->getArguments()[0]; } + + /** @return null|string|array */ + private function nullableStringOrIterable(mixed $value):null|iterable|string { + if(is_scalar($value)) { + return $value; + } + elseif(is_iterable($value)) { + return $value; + } + elseif(is_object($value)) { + if($value instanceof Stringable || method_exists($value, "__toString")) { + return (string)$value; + } + } + + return null; + } } diff --git a/src/CommentIni.php b/src/CommentIni.php index 32f0183..7861920 100644 --- a/src/CommentIni.php +++ b/src/CommentIni.php @@ -55,10 +55,7 @@ public function __construct( } } - if($commentNodeToRemove) { - $commentNodeToRemove->parentNode->removeChild($commentNodeToRemove); - } - + $commentNodeToRemove?->parentNode->removeChild($commentNodeToRemove); $this->iniData = $ini ?: null; } diff --git a/src/DocumentBinder.php b/src/DocumentBinder.php index 8419b0a..5015d19 100644 --- a/src/DocumentBinder.php +++ b/src/DocumentBinder.php @@ -4,7 +4,6 @@ use Gt\Dom\Attr; use Gt\Dom\Document; use Gt\Dom\Element; -use Gt\Dom\XPathResult; class DocumentBinder { private ElementBinder $elementBinder; @@ -18,7 +17,7 @@ class DocumentBinder { * @param array $config */ public function __construct( - private Document $document, + private readonly Document $document, private array $config = [], ?ElementBinder $elementBinder = null, ?PlaceholderBinder $placeholderBinder = null, @@ -106,7 +105,7 @@ public function bindTable( } /** - * @param iterable $listData + * @param iterable $listData */ public function bindList( iterable $listData, @@ -120,7 +119,7 @@ public function bindList( return $this->listBinder->bindListData($listData, $context, $templateName); } - /** @param iterable $listData */ + /** @param iterable $listData */ public function bindListCallback( iterable $listData, callable $callback, diff --git a/src/HTMLAttributeBinder.php b/src/HTMLAttributeBinder.php index f9ef8fb..39a9fa6 100644 --- a/src/HTMLAttributeBinder.php +++ b/src/HTMLAttributeBinder.php @@ -91,6 +91,23 @@ public function expandAttributes(Element $element):void { continue; } + if($attrName === "data-bind:list") { + if($attrValue === "") { + $attrValue = $element->tagName; + if(str_contains($attrValue, "-")) { + $newAttrValue = ""; + foreach(explode("-", $attrValue) as $i => $part) { + if($i > 0) { + $part = ucfirst($part); + } + $newAttrValue .= $part; + } + $attrValue = $newAttrValue; + } + $element->setAttribute($attrName, $attrValue); + } + } + if(strlen($attrValue) === 0) { continue; } @@ -199,6 +216,9 @@ private function setBindProperty( $element->value = $bindValue; break; + case "list"; + break; + default: if($modifier) { $this->handleModifier( diff --git a/src/NodePathCalculator.php b/src/NodePathCalculator.php index 4973907..7e9cb45 100644 --- a/src/NodePathCalculator.php +++ b/src/NodePathCalculator.php @@ -19,20 +19,29 @@ public function __toString():string { do { $contextPath = strtolower($context->tagName); - if($context->id || $context->className) { - $attrPath = ""; - if($id = $context->id) { - $attrPath .= "@id='$id'"; - } + $attrPath = ""; + if($dataTemplateParent = $context->getAttribute(TemplateElement::ATTRIBUTE_TEMPLATE_PARENT)) { + $attrPath .= "@" + . TemplateElement::ATTRIBUTE_TEMPLATE_PARENT + . "='$dataTemplateParent'"; + } - foreach($context->classList as $class) { - if(strlen($attrPath) !== 0) { - $attrPath .= " and "; - } + if($id = $context->id) { + if($attrPath) { + $attrPath .= " and "; + } + $attrPath .= "@id='$id'"; + } - $attrPath .= "contains(concat(' ',normalize-space(@class),' '),' $class ')"; + foreach($context->classList as $class) { + if($attrPath) { + $attrPath .= " and "; } + $attrPath .= "contains(concat(' ',normalize-space(@class),' '),' $class ')"; + } + + if($attrPath) { $contextPath .= "[$attrPath]"; } diff --git a/src/TemplateElement.php b/src/TemplateElement.php index faa5a12..bc40a0a 100644 --- a/src/TemplateElement.php +++ b/src/TemplateElement.php @@ -7,6 +7,8 @@ use Throwable; class TemplateElement { + const ATTRIBUTE_TEMPLATE_PARENT = "data-template-parent"; + private string $templateParentPath; private null|Node|Element $templateNextSibling; private int $insertCount; @@ -15,8 +17,8 @@ public function __construct( private Node|Element $originalElement ) { $parentElement = $this->originalElement->parentElement; - if(!$parentElement->id) { - $parentElement->id = uniqid("template-parent-"); + if(!$parentElement->getAttribute(self::ATTRIBUTE_TEMPLATE_PARENT)) { + $parentElement->setAttribute(self::ATTRIBUTE_TEMPLATE_PARENT, uniqid("template-parent-")); } $this->templateParentPath = new NodePathCalculator($parentElement); @@ -54,7 +56,7 @@ public function removeOriginalElement():void { } public function getClone():Node|Element { -// TODO: Bug here - the template-parent-xxx ID is being generated the same for multiple instances. +// TODO: #368 Bug here - the template-parent-xxx ID is being generated the same for multiple instances. /** @var Element $element */ $element = $this->originalElement->cloneNode(true); // foreach($this->originalElement->ownerDocument->evaluate("./*[starts-with(@id,'template-parent-')]", $element) as $existingTemplateElement) { diff --git a/test/phpunit/BindableCacheTest.php b/test/phpunit/BindableCacheTest.php index c70aed9..c557df7 100644 --- a/test/phpunit/BindableCacheTest.php +++ b/test/phpunit/BindableCacheTest.php @@ -5,6 +5,7 @@ use Gt\DomTemplate\BindGetter; use Gt\DomTemplate\BindableCache; use Gt\DomTemplate\BindGetterMethodDoesNotStartWithGetException; +use Gt\DomTemplate\Test\TestHelper\TestData; use PHPUnit\Framework\TestCase; use stdClass; @@ -93,6 +94,7 @@ public function __construct() { self::assertSame([ "id" => "test-id", "name" => "test-name", + "age" => null, ], $sut->convertToKvp($obj)); } @@ -154,4 +156,25 @@ public function __construct( "email" => null, ], $sut->convertToKvp($obj)); } + + public function testConvertToKvp_nestedObject():void { + $sut = new BindableCache(); + + $customerList = TestData::getCustomerOrderOverview1(); + $kvpList = []; + foreach($customerList as $customer) { + array_push($kvpList, $sut->convertToKvp($customer)); + } + + foreach($customerList as $i => $customer) { + self::assertSame((string)$customer->id, $kvpList[$i]["id"]); + self::assertSame($customer->name, $kvpList[$i]["name"]); + self::assertSame($customer->address->street, $kvpList[$i]["address.street"]); + self::assertSame($customer->address->line2, $kvpList[$i]["address.line2"]); + self::assertSame($customer->address->cityState, $kvpList[$i]["address.cityState"]); + self::assertSame($customer->address->postcodeZip, $kvpList[$i]["address.postcodeZip"]); + self::assertSame($customer->address->country->code, $kvpList[$i]["address.country.code"]); + self::assertSame($customer->address->country->getName(), $kvpList[$i]["address.country.name"]); + } + } } diff --git a/test/phpunit/CommentIniTest.php b/test/phpunit/CommentIniTest.php index 8999cc8..74e6783 100644 --- a/test/phpunit/CommentIniTest.php +++ b/test/phpunit/CommentIniTest.php @@ -4,43 +4,43 @@ use Gt\Dom\HTMLDocument; use Gt\DomTemplate\CommentIni; use Gt\DomTemplate\CommentIniInvalidDocumentLocationException; -use Gt\DomTemplate\Test\TestFactory\DocumentTestFactory; +use Gt\DomTemplate\Test\TestHelper\HTMLPageContent; use PHPUnit\Framework\TestCase; class CommentIniTest extends TestCase { public function testConstruct_nullWhenNoCommentBlock():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_USER_PROFILE); + $document = new HTMLDocument(HTMLPageContent::HTML_USER_PROFILE); $sut = new CommentIni($document); self::assertFalse($sut->containsIniData()); } public function testConstruct_throwsIfCommentBlockNotFirst():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_INCORRECTLY_EXTENDS_PARTIAL_VIEW); + $document = new HTMLDocument(HTMLPageContent::HTML_INCORRECTLY_EXTENDS_PARTIAL_VIEW); self::expectException(CommentIniInvalidDocumentLocationException::class); self::expectExceptionMessage("A Comment INI must only appear as the first node of the HTML."); new CommentIni($document); } public function testContainsIniData_emptyIfNoIniData():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_COMMENT_WITHOUT_INI_DATA_PARTIAL_VIEW); + $document = new HTMLDocument(HTMLPageContent::HTML_COMMENT_WITHOUT_INI_DATA_PARTIAL_VIEW); $sut = new CommentIni($document); self::assertFalse($sut->containsIniData()); } public function testGet_noMatchingData():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_EXTENDS_PARTIAL_VIEW); + $document = new HTMLDocument(HTMLPageContent::HTML_EXTENDS_PARTIAL_VIEW); $sut = new CommentIni($document); self::assertNull($sut->get("no-match")); } public function testGet():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_EXTENDS_PARTIAL_VIEW); + $document = new HTMLDocument(HTMLPageContent::HTML_EXTENDS_PARTIAL_VIEW); $sut = new CommentIni($document); self::assertEquals("base-page", $sut->get("extends")); } public function testGetNested():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_EXTENDS_PARTIAL_VIEW); + $document = new HTMLDocument(HTMLPageContent::HTML_EXTENDS_PARTIAL_VIEW); $sut = new CommentIni($document); self::assertEquals("My website, extended...", $sut->get("vars.title")); } diff --git a/test/phpunit/ComponentExpanderTest.php b/test/phpunit/ComponentExpanderTest.php index 2c6c914..9658e97 100644 --- a/test/phpunit/ComponentExpanderTest.php +++ b/test/phpunit/ComponentExpanderTest.php @@ -3,12 +3,12 @@ use Gt\Dom\HTMLDocument; use Gt\DomTemplate\ComponentExpander; -use Gt\DomTemplate\Test\TestFactory\DocumentTestFactory; +use Gt\DomTemplate\Test\TestHelper\HTMLPageContent; class ComponentExpanderTest extends PartialContentTestCase { public function testExpand_doesNothingWhenNoMatchingFiles():void { $partialContent = self::mockPartialContent("_component"); - $document = new HTMLDocument(DocumentTestFactory::HTML_COMPONENT); + $document = new HTMLDocument(HTMLPageContent::HTML_COMPONENT); $sut = new ComponentExpander($document, $partialContent); self::assertEmpty($sut->expand()); } @@ -21,7 +21,7 @@ public function testExpand_returnsArrayOfExpandedElements():void { "custom-element" => $html ] ); - $document = new HTMLDocument(DocumentTestFactory::HTML_COMPONENT); + $document = new HTMLDocument(HTMLPageContent::HTML_COMPONENT); $sut = new ComponentExpander($document, $partialContent); $expandedElements = $sut->expand(); self::assertCount(1, $expandedElements); @@ -32,11 +32,11 @@ public function testExpand_returnsArrayOfExpandedElements():void { public function testExpand_recursive():void { $partialContent = self::mockPartialContent( "_component", [ - "todo-list" => DocumentTestFactory::HTML_TODO_COMPONENT_TODO_LIST, - "todo-list-item" => DocumentTestFactory::HTML_TODO_COMPONENT_TODO_LIST_ITEM, + "todo-list" => HTMLPageContent::HTML_TODO_COMPONENT_TODO_LIST, + "todo-list-item" => HTMLPageContent::HTML_TODO_COMPONENT_TODO_LIST_ITEM, ] ); - $document = new HTMLDocument(DocumentTestFactory::HTML_TODO_CUSTOM_ELEMENT); + $document = new HTMLDocument(HTMLPageContent::HTML_TODO_CUSTOM_ELEMENT); $sut = new ComponentExpander($document, $partialContent); $expandedElements = $sut->expand(); self::assertCount(2, $expandedElements); @@ -50,6 +50,7 @@ public function testExpand_empty():void { "empty-component" => "", ] ); + /** @noinspection HtmlRequiredLangAttribute */ $document = new HTMLDocument(""); $sut = new ComponentExpander($document, $partialContent); $expandedElements = $sut->expand(); @@ -60,11 +61,11 @@ public function testExpand_empty():void { public function testExpand_nested():void { $partialContent = self::mockPartialContent( "_component", [ - "example-nested/first" => DocumentTestFactory::HTML_COMPONENT_NESTED_INNER_FIRST, - "example-nested/second" => DocumentTestFactory::HTML_COMPONENT_NESTED_INNER_SECOND, + "example-nested/first" => HTMLPageContent::HTML_COMPONENT_NESTED_INNER_FIRST, + "example-nested/second" => HTMLPageContent::HTML_COMPONENT_NESTED_INNER_SECOND, ] ); - $document = new HTMLDocument(DocumentTestFactory::HTML_COMPONENT_NESTED_OUTER); + $document = new HTMLDocument(HTMLPageContent::HTML_COMPONENT_NESTED_OUTER); $sut = new ComponentExpander($document, $partialContent); $expandedElements = $sut->expand(); self::assertCount(2, $expandedElements); diff --git a/test/phpunit/DocumentBinderTest.php b/test/phpunit/DocumentBinderTest.php index a5989ba..0271768 100644 --- a/test/phpunit/DocumentBinderTest.php +++ b/test/phpunit/DocumentBinderTest.php @@ -14,8 +14,11 @@ use Gt\DomTemplate\InvalidBindPropertyException; use Gt\DomTemplate\PlaceholderBinder; use Gt\DomTemplate\TableElementNotFoundInContextException; -use Gt\DomTemplate\Test\TestFactory\DocumentTestFactory; -use Gt\DomTemplate\Test\TestFactory\ExampleClass; +use Gt\DomTemplate\Test\TestHelper\HTMLPageContent; +use Gt\DomTemplate\Test\TestHelper\ExampleClass; +use Gt\DomTemplate\Test\TestHelper\Model\Address; +use Gt\DomTemplate\Test\TestHelper\Model\Country; +use Gt\DomTemplate\Test\TestHelper\Model\Customer; use PHPUnit\Framework\TestCase; use stdClass; @@ -26,7 +29,7 @@ class DocumentBinderTest extends TestCase { * error message. */ public function testBindValue_missingBindProperty():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_NO_BIND_PROPERTY); + $document = new HTMLDocument(HTMLPageContent::HTML_NO_BIND_PROPERTY); $sut = new DocumentBinder($document); self::expectException(InvalidBindPropertyException::class); self::expectExceptionMessage(" Element has a data-bind attribute with missing bind property - did you mean `data-bind:text`?"); @@ -34,7 +37,7 @@ public function testBindValue_missingBindProperty():void { } public function testBindValue_singleElement():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_SINGLE_ELEMENT); + $document = new HTMLDocument(HTMLPageContent::HTML_SINGLE_ELEMENT); $sut = new DocumentBinder($document); $output = $document->querySelector("output"); self::assertSame("Nothing is bound", $output->textContent); @@ -43,7 +46,7 @@ public function testBindValue_singleElement():void { } public function testBindValue_multipleElements():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_MULTIPLE_ELEMENTS); + $document = new HTMLDocument(HTMLPageContent::HTML_MULTIPLE_ELEMENTS); $sut = new DocumentBinder($document); $output1 = $document->getElementById("o1"); $output2 = $document->getElementById("o2"); @@ -55,7 +58,7 @@ public function testBindValue_multipleElements():void { } public function testBindValue_multipleNestedElements():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_MULTIPLE_NESTED_ELEMENTS); + $document = new HTMLDocument(HTMLPageContent::HTML_MULTIPLE_NESTED_ELEMENTS); $sut = new DocumentBinder($document); $container1 = $document->getElementById("container1"); $container2 = $document->getElementById("container2"); @@ -78,7 +81,7 @@ public function testBindValue_multipleNestedElements():void { } public function testBindValue_multipleNestedElements_skipsElementWithBindProperty():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_MULTIPLE_NESTED_ELEMENTS); + $document = new HTMLDocument(HTMLPageContent::HTML_MULTIPLE_NESTED_ELEMENTS); $sut = new DocumentBinder($document); $container3 = $document->getElementById("container3"); $sut->bindValue("Test!", $container3); @@ -87,7 +90,7 @@ public function testBindValue_multipleNestedElements_skipsElementWithBindPropert } public function testBindValue_synonymousProperties():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_SYNONYMOUS_BIND_PROPERTIES); + $document = new HTMLDocument(HTMLPageContent::HTML_SYNONYMOUS_BIND_PROPERTIES); $sut = new DocumentBinder($document); $sut->bindValue("updated bold"); @@ -103,7 +106,7 @@ public function testBindValue_synonymousProperties():void { } public function testBindValue_null():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_SINGLE_ELEMENT); + $document = new HTMLDocument(HTMLPageContent::HTML_SINGLE_ELEMENT); $sut = new DocumentBinder($document); $exception = null; @@ -116,14 +119,14 @@ public function testBindValue_null():void { } public function testBindKeyValue_noMatches():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_SINGLE_ELEMENT); + $document = new HTMLDocument(HTMLPageContent::HTML_SINGLE_ELEMENT); $sut = new DocumentBinder($document); $sut->bindKeyValue("missing", "example"); self::assertSame("Nothing is bound", $document->querySelector("output")->innerHTML); } public function testBindKeyValue_noMatchesInDifferentHierarchy():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_MULTIPLE_NESTED_ELEMENTS); + $document = new HTMLDocument(HTMLPageContent::HTML_MULTIPLE_NESTED_ELEMENTS); $sut = new DocumentBinder($document); // The "title" bind element is actually within the #c3 hierarchy so should not be bound. $sut->bindKeyValue("title", "This should not bind", $document->getElementById("container1")); @@ -131,7 +134,7 @@ public function testBindKeyValue_noMatchesInDifferentHierarchy():void { } public function testBindKeyValue():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_MULTIPLE_NESTED_ELEMENTS); + $document = new HTMLDocument(HTMLPageContent::HTML_MULTIPLE_NESTED_ELEMENTS); $sut = new DocumentBinder($document); $sut->bindKeyValue("title", "This should bind"); self::assertSame("This should bind", $document->querySelector("#container3 h1")->textContent); @@ -139,7 +142,7 @@ public function testBindKeyValue():void { } public function testBindKeyValue_null():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_MULTIPLE_NESTED_ELEMENTS); + $document = new HTMLDocument(HTMLPageContent::HTML_MULTIPLE_NESTED_ELEMENTS); $sut = new DocumentBinder($document); $exception = null; @@ -158,7 +161,7 @@ public function testBindData_assocArray():void { $email = uniqid() . "@example.com"; $category = uniqid("category-"); - $document = new HTMLDocument(DocumentTestFactory::HTML_USER_PROFILE); + $document = new HTMLDocument(HTMLPageContent::HTML_USER_PROFILE); $sut = new DocumentBinder($document); $sut->bindData([ "username" => $username, @@ -176,7 +179,7 @@ public function testBindData_assocArray_withNull():void { $email = null; $category = uniqid("category-"); - $document = new HTMLDocument(DocumentTestFactory::HTML_USER_PROFILE); + $document = new HTMLDocument(HTMLPageContent::HTML_USER_PROFILE); $sut = new DocumentBinder($document); $sut->bindData([ "username" => $username, @@ -190,7 +193,7 @@ public function testBindData_assocArray_withNull():void { } public function testBindData_indexedArray():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_USER_PROFILE); + $document = new HTMLDocument(HTMLPageContent::HTML_USER_PROFILE); $sut = new DocumentBinder($document); self::expectException(IncompatibleBindDataException::class); self::expectExceptionMessage("bindData is only compatible with key-value-pair data, but it was passed an indexed array."); @@ -203,7 +206,7 @@ public function testBindData_object():void { $userObject->email = "greg.bowler@g105b.com"; $userObject->category = "maintainer"; - $document = new HTMLDocument(DocumentTestFactory::HTML_USER_PROFILE); + $document = new HTMLDocument(HTMLPageContent::HTML_USER_PROFILE); $sut = new DocumentBinder($document); $sut->bindData($userObject); @@ -228,7 +231,7 @@ public function __construct( ) {} }; - $document = new HTMLDocument(DocumentTestFactory::HTML_USER_PROFILE); + $document = new HTMLDocument(HTMLPageContent::HTML_USER_PROFILE); $sut = new DocumentBinder($document); $sut->bindData($userObject); @@ -242,7 +245,7 @@ public function __construct( } public function testBindData_objectWithNonScalarProperties_stringable():void { - $email = new class() extends StdClass implements \Stringable { + $email = new class() implements \Stringable { #[BindGetter] public function getEmail():string { return "greg.bowler@g105b.com"; @@ -256,12 +259,12 @@ public function __toString():string { $userObject = new class("g105b", $email, "maintainer") { public function __construct( public readonly string $username, - public readonly StdClass $email, + public readonly object $email, public readonly string $category, ) {} }; - $document = new HTMLDocument(DocumentTestFactory::HTML_USER_PROFILE); + $document = new HTMLDocument(HTMLPageContent::HTML_USER_PROFILE); $sut = new DocumentBinder($document); $sut->bindData($userObject); @@ -280,7 +283,7 @@ public function __construct( ) {} }; - $document = new HTMLDocument(DocumentTestFactory::HTML_USER_PROFILE); + $document = new HTMLDocument(HTMLPageContent::HTML_USER_PROFILE); $sut = new DocumentBinder($document); $sut->bindData($userObject); @@ -295,7 +298,7 @@ public function testBindData_object_withNull():void { $userObject->email = "greg.bowler@g105b.com"; $userObject->category = null; - $document = new HTMLDocument(DocumentTestFactory::HTML_USER_PROFILE); + $document = new HTMLDocument(HTMLPageContent::HTML_USER_PROFILE); $sut = new DocumentBinder($document); $sut->bindData($userObject); @@ -305,7 +308,7 @@ public function testBindData_object_withNull():void { } public function testBindData_indexArray_shouldThrowException():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_USER_PROFILE); + $document = new HTMLDocument(HTMLPageContent::HTML_USER_PROFILE); $sut = new DocumentBinder($document); self::expectException(IncompatibleBindDataException::class); self::expectExceptionMessage("bindData is only compatible with key-value-pair data, but it was passed an indexed array."); @@ -313,7 +316,7 @@ public function testBindData_indexArray_shouldThrowException():void { } public function testBindData_outOfContext():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_USER_PROFILE); + $document = new HTMLDocument(HTMLPageContent::HTML_USER_PROFILE); $sut = new DocumentBinder($document); $sut->bindData([ "username" => "will-not-bind", @@ -327,7 +330,7 @@ public function testBindData_outOfContext():void { } public function testBindKeyValue_arbitraryAttributes():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_DIFFERENT_BIND_PROPERTIES); + $document = new HTMLDocument(HTMLPageContent::HTML_DIFFERENT_BIND_PROPERTIES); $sut = new DocumentBinder($document); $img = $document->getElementById("img1"); @@ -339,7 +342,7 @@ public function testBindKeyValue_arbitraryAttributes():void { } public function testBindKeyValue_classAttribute():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_DIFFERENT_BIND_PROPERTIES); + $document = new HTMLDocument(HTMLPageContent::HTML_DIFFERENT_BIND_PROPERTIES); $sut = new DocumentBinder($document); $img = $document->getElementById("img1"); @@ -352,7 +355,7 @@ public function testBindKeyValue_classAttribute():void { } public function testBindKeyValue_classToggle():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_DIFFERENT_BIND_PROPERTIES); + $document = new HTMLDocument(HTMLPageContent::HTML_DIFFERENT_BIND_PROPERTIES); $sut = new DocumentBinder($document); $img = $document->getElementById("img2"); @@ -365,7 +368,7 @@ public function testBindKeyValue_classToggle():void { } public function testBindKeyValue_classToggle_differentClassNameToBindKey():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_DIFFERENT_BIND_PROPERTIES); + $document = new HTMLDocument(HTMLPageContent::HTML_DIFFERENT_BIND_PROPERTIES); $sut = new DocumentBinder($document); $img = $document->getElementById("img3"); @@ -378,7 +381,7 @@ public function testBindKeyValue_classToggle_differentClassNameToBindKey():void } public function testBindKeyValue_toggleArbitraryAttribute():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_DIFFERENT_BIND_PROPERTIES); + $document = new HTMLDocument(HTMLPageContent::HTML_DIFFERENT_BIND_PROPERTIES); $sut = new DocumentBinder($document); $paragraph = $document->getElementById("p1"); @@ -398,7 +401,7 @@ public function testBindKeyValue_toggleArbitraryAttribute():void { * bind attribute will be toggled depending on a bound boolean value. */ public function testBindKeyValue_toggleDisabled():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_DIFFERENT_BIND_PROPERTIES); + $document = new HTMLDocument(HTMLPageContent::HTML_DIFFERENT_BIND_PROPERTIES); $sut = new DocumentBinder($document); $button = $document->getElementById("btn1"); @@ -419,7 +422,7 @@ public function testBindKeyValue_toggleDisabled():void { * HTML attribute). */ public function testBindKeyValue_toggleDisabled_inverseLogic():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_DIFFERENT_BIND_PROPERTIES); + $document = new HTMLDocument(HTMLPageContent::HTML_DIFFERENT_BIND_PROPERTIES); $sut = new DocumentBinder($document); $button = $document->getElementById("btn2"); @@ -432,14 +435,14 @@ public function testBindKeyValue_toggleDisabled_inverseLogic():void { } public function testBindKeyValue_tableData_noTable():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_NO_TABLE); + $document = new HTMLDocument(HTMLPageContent::HTML_NO_TABLE); $sut = new DocumentBinder($document); self::expectException(TableElementNotFoundInContextException::class); $sut->bindKeyValue("tableData", []); } public function testBindTable():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_TABLES); + $document = new HTMLDocument(HTMLPageContent::HTML_TABLES); $sut = new DocumentBinder($document); $tableData = [ @@ -467,7 +470,7 @@ public function testBindTable():void { } public function testBindTable_withNullData():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_TABLES); + $document = new HTMLDocument(HTMLPageContent::HTML_TABLES); $sut = new DocumentBinder($document); $tableData = [ @@ -509,7 +512,7 @@ public function testBindTable_withNullData():void { } public function testBindKeyValue_tableData():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_TABLES); + $document = new HTMLDocument(HTMLPageContent::HTML_TABLES); $sut = new DocumentBinder($document); $tableData = [ @@ -537,7 +540,7 @@ public function testBindKeyValue_tableData():void { } public function testBindList():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_LIST_TEMPLATE); + $document = new HTMLDocument(HTMLPageContent::HTML_LIST_TEMPLATE); $sut = new DocumentBinder($document); $listData = ["One", "Two", "Three"]; @@ -551,7 +554,7 @@ public function testBindList():void { } public function testBindList_nullData():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_LIST_TEMPLATE); + $document = new HTMLDocument(HTMLPageContent::HTML_LIST_TEMPLATE); $sut = new DocumentBinder($document); $listData = ["One", null, "Three"]; @@ -570,7 +573,7 @@ public function testBindList_nullData():void { } public function testBindList_emptyLeavesNoWhiteSpace():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_LIST_TEMPLATE); + $document = new HTMLDocument(HTMLPageContent::HTML_LIST_TEMPLATE); $sut = new DocumentBinder($document); $listData = []; $sut->bindList($listData); @@ -578,7 +581,7 @@ public function testBindList_emptyLeavesNoWhiteSpace():void { } public function testBindData_objectWithAttribute():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_USER_PROFILE); + $document = new HTMLDocument(HTMLPageContent::HTML_USER_PROFILE); $sut = new DocumentBinder($document); $userObject = new class { @@ -599,7 +602,7 @@ public function getEmailAddress():string { } public function testBindList_objectListWithAttributes():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_USER_ORDER_LIST); + $document = new HTMLDocument(HTMLPageContent::HTML_USER_ORDER_LIST); $sut = new DocumentBinder($document); $userObjectList = [ @@ -680,7 +683,7 @@ public function ordersCompleted():int { } public function testBindData_castToArray():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_USER_PROFILE); + $document = new HTMLDocument(HTMLPageContent::HTML_USER_PROFILE); $sut = new DocumentBinder($document); $row = new class { @@ -701,7 +704,7 @@ public function asArray():array { } public function testBindList_castToArray():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_USER_ORDER_LIST); + $document = new HTMLDocument(HTMLPageContent::HTML_USER_ORDER_LIST); $sut = new DocumentBinder($document); $row1 = new class { @@ -731,7 +734,7 @@ public function asArray():array { } public function testBindValue_callable():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_SINGLE_ELEMENT); + $document = new HTMLDocument(HTMLPageContent::HTML_SINGLE_ELEMENT); $sut = new DocumentBinder($document); $sut->bindValue(fn() => "test"); self::assertSame("test", $document->querySelector("output")->textContent); @@ -816,7 +819,7 @@ public function testBindList_complexHTML():void { ] ]; - $document = new HTMLDocument(DocumentTestFactory::HTML_TRANSPORT_ROUTES); + $document = new HTMLDocument(HTMLPageContent::HTML_TRANSPORT_ROUTES); $sut = new DocumentBinder($document); $sut->bindKeyValue("from", $from); $sut->bindKeyValue("to", $to); @@ -886,7 +889,7 @@ public function testBindListData_callback():void { return $listItem; }; - $document = new HTMLDocument(DocumentTestFactory::HTML_SALES); + $document = new HTMLDocument(HTMLPageContent::HTML_SALES); $sut = new DocumentBinder($document); $sut->bindListCallback( $salesData, @@ -907,7 +910,7 @@ public function testBindListData_callback():void { } public function testCleanDatasets_dataBind():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_USER_PROFILE); + $document = new HTMLDocument(HTMLPageContent::HTML_USER_PROFILE); $sut = new DocumentBinder($document); $sut->bindData([ "username" => "codyboy123", @@ -927,7 +930,7 @@ public function testCleanDatasets_dataBind():void { } public function testCleanDatasets_dataTemplate():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_LIST_TEMPLATE); + $document = new HTMLDocument(HTMLPageContent::HTML_LIST_TEMPLATE); $sut = new DocumentBinder($document); $sut->bindList(["One", "Two", "Three", "Four"]); $sut->cleanDatasets(); @@ -947,7 +950,7 @@ public function testCleanDatasets_dataTemplate():void { } public function testBindListData_twoListsDifferentContexts():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_TWO_LISTS_WITH_UNNAMED_TEMPLATES); + $document = new HTMLDocument(HTMLPageContent::HTML_TWO_LISTS_WITH_UNNAMED_TEMPLATES); $sut = new DocumentBinder($document); $progLangData = ["PHP", "HTML", "bash"]; @@ -965,7 +968,7 @@ public function testBindListData_twoListsDifferentContexts():void { } public function testBindListData_twoListsDifferentContexts_withHtmlParents():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_TWO_LISTS_WITH_UNNAMED_TEMPLATES_CLASS_PARENTS); + $document = new HTMLDocument(HTMLPageContent::HTML_TWO_LISTS_WITH_UNNAMED_TEMPLATES_CLASS_PARENTS); $sut = new DocumentBinder($document); $progLangData = ["PHP", "HTML", "bash"]; @@ -983,7 +986,7 @@ public function testBindListData_twoListsDifferentContexts_withHtmlParents():voi } public function testBindValue_callableString():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_SINGLE_ELEMENT); + $document = new HTMLDocument(HTMLPageContent::HTML_SINGLE_ELEMENT); $sut = new DocumentBinder($document); $value = "explode"; $sut->bindValue($value); @@ -991,7 +994,7 @@ public function testBindValue_callableString():void { } public function testBindList_twoListsWithSamePath():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_TEMPLATES_WITH_SAME_XPATH); + $document = new HTMLDocument(HTMLPageContent::HTML_TEMPLATES_WITH_SAME_XPATH); $sut = new DocumentBinder($document); $list1 = [ ["uuid" => "AAAAAAAA", "fullName" => "Test 1"], @@ -1046,7 +1049,7 @@ public function __construct( ) {} }; - $document = new HTMLDocument(DocumentTestFactory::HTML_USER_ORDER_LIST); + $document = new HTMLDocument(HTMLPageContent::HTML_USER_ORDER_LIST); $sut = new DocumentBinder($document); $sut->bindList([$userObject1, $userObject2]); @@ -1063,7 +1066,7 @@ public function testBindList_readOnlyProperties_fullClass():void { $userObject1 = new ExampleClass(1, "g105b", 3); $userObject2 = new ExampleClass(2, "codyboy", 21); - $document = new HTMLDocument(DocumentTestFactory::HTML_USER_ORDER_LIST); + $document = new HTMLDocument(HTMLPageContent::HTML_USER_ORDER_LIST); $sut = new DocumentBinder($document); $sut->bindList([$userObject1, $userObject2]); @@ -1075,7 +1078,7 @@ public function testBindList_readOnlyProperties_fullClass():void { } public function test_onlyBindOnce():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_BIND_KEY_REUSED); + $document = new HTMLDocument(HTMLPageContent::HTML_BIND_KEY_REUSED); $sut = new DocumentBinder($document); $shopList = [ @@ -1108,8 +1111,39 @@ public function testBindKeyValue_onlyBindPlaceholderOnce():void { ->method("bind") ->with("name", "Cody"); - $document = new HTMLDocument(DocumentTestFactory::HTML_PLACEHOLDER); + $document = new HTMLDocument(HTMLPageContent::HTML_PLACEHOLDER); $sut = new DocumentBinder($document, placeholderBinder: $placeholderBinder); $sut->bindKeyValue("name", "Cody", $document->getElementById("test1")); } + + public function testBindKeyValue_nestedObject():void { + $document = new HTMLDocument(HTMLPageContent::HTML_ADDRESS_NESTED_OBJECT); + $sut = new DocumentBinder($document); + + $address = new Address( + "2184 Jasper Avenue", + "Sherwood Park", + "Edmonton", + "T5J 3N2", + new Country("CA"), + ); + $customer = new Customer( + 123, + "Joy Buolamwini", + $address, + ); + + $sut->bindData($customer); + + self::assertSame("123", $document->querySelectorAll("dd")[0]->textContent); + self::assertSame("Joy Buolamwini", $document->querySelectorAll("dd")[1]->textContent); + self::assertSame($address->street, $document->querySelectorAll("dd")[2]->textContent); + self::assertSame($address->line2, $document->querySelectorAll("dd")[3]->textContent); + self::assertSame($address->cityState, $document->querySelectorAll("dd")[4]->textContent); + self::assertSame($address->postcodeZip, $document->querySelectorAll("dd")[5]->textContent); + self::assertSame( + $address->country->getName() . " (" . $address->country->code . ")", + $document->querySelectorAll("dd")[6]->textContent + ); + } } diff --git a/test/phpunit/HTMLAttributeBinderTest.php b/test/phpunit/HTMLAttributeBinderTest.php index 705ff49..e6d4c87 100644 --- a/test/phpunit/HTMLAttributeBinderTest.php +++ b/test/phpunit/HTMLAttributeBinderTest.php @@ -4,19 +4,19 @@ use DateTime; use Gt\Dom\HTMLDocument; use Gt\DomTemplate\HTMLAttributeBinder; -use Gt\DomTemplate\Test\TestFactory\DocumentTestFactory; +use Gt\DomTemplate\Test\TestHelper\HTMLPageContent; use PHPUnit\Framework\TestCase; class HTMLAttributeBinderTest extends TestCase { public function testBind_wholeDocument():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_LANGUAGE); + $document = new HTMLDocument(HTMLPageContent::HTML_LANGUAGE); $sut = new HTMLAttributeBinder(); $sut->bind("language", "en_GB", $document); self::assertSame("en_GB", $document->documentElement->getAttribute("lang")); } public function testBind_selectValue():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_SELECT_OPTIONS_WITH_VALUE); + $document = new HTMLDocument(HTMLPageContent::HTML_SELECT_OPTIONS_WITH_VALUE); $select = $document->querySelector("select[name='drink']"); $sut = new HTMLAttributeBinder(); $valueToSelect = "tea"; @@ -34,7 +34,7 @@ public function testBind_selectValue():void { } public function testBind_selectValue_noOptions():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_SELECT_OPTIONS_WITHOUT_VALUE); + $document = new HTMLDocument(HTMLPageContent::HTML_SELECT_OPTIONS_WITHOUT_VALUE); $select = $document->querySelector("select[name='drink']"); $sut = new HTMLAttributeBinder(); $valueToSelect = "Tea"; @@ -51,7 +51,7 @@ public function testBind_selectValue_noOptions():void { } public function testBind_selectValue_optionDoesNotExist():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_SELECT_OPTIONS_WITHOUT_VALUE); + $document = new HTMLDocument(HTMLPageContent::HTML_SELECT_OPTIONS_WITHOUT_VALUE); $select = $document->querySelector("select[name='drink']"); $sut = new HTMLAttributeBinder(); $valueToSelect = "Grape Juice"; @@ -64,7 +64,7 @@ public function testBind_selectValue_optionDoesNotExist():void { } public function testBind_modifierColonNamedProperty_null():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_TODO); + $document = new HTMLDocument(HTMLPageContent::HTML_TODO); $sut = new HTMLAttributeBinder(); $li = $document->querySelector("ul li"); $sut->bind("completedAt", null, $li); @@ -72,7 +72,7 @@ public function testBind_modifierColonNamedProperty_null():void { } public function testBind_modifierColonNamedProperty():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_TODO); + $document = new HTMLDocument(HTMLPageContent::HTML_TODO); $sut = new HTMLAttributeBinder(); $li = $document->querySelector("ul li"); $sut->bind("completedAt", new DateTime(), $li); @@ -80,7 +80,7 @@ public function testBind_modifierColonNamedProperty():void { } public function testBind_modifierColon():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_DIFFERENT_BIND_PROPERTIES); + $document = new HTMLDocument(HTMLPageContent::HTML_DIFFERENT_BIND_PROPERTIES); $sut = new HTMLAttributeBinder(); $img = $document->getElementById("img1"); $sut->bind("size", "size-large", $img); @@ -88,7 +88,7 @@ public function testBind_modifierColon():void { } public function testBind_modifierQuestion():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_DIFFERENT_BIND_PROPERTIES); + $document = new HTMLDocument(HTMLPageContent::HTML_DIFFERENT_BIND_PROPERTIES); $sut = new HTMLAttributeBinder(); $btn1 = $document->getElementById("btn1"); $btn2 = $document->getElementById("btn2"); @@ -102,7 +102,7 @@ public function testBind_modifierQuestion():void { } public function testBind_modifierQuestion_withNullValue():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_DIFFERENT_BIND_PROPERTIES); + $document = new HTMLDocument(HTMLPageContent::HTML_DIFFERENT_BIND_PROPERTIES); $sut = new HTMLAttributeBinder(); $img = $document->getElementById("img3"); $sut->bind("alternativeText", null, $img); @@ -110,7 +110,7 @@ public function testBind_modifierQuestion_withNullValue():void { } public function testBind_modifierQuestion_withValue():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_DIFFERENT_BIND_PROPERTIES); + $document = new HTMLDocument(HTMLPageContent::HTML_DIFFERENT_BIND_PROPERTIES); $sut = new HTMLAttributeBinder(); $img = $document->getElementById("img3"); $testMessage = "This is a test message"; @@ -121,7 +121,7 @@ public function testBind_modifierQuestion_withValue():void { public function testBind_dateTimeInterface():void { $dateTime = new DateTime("1988-04-05 17:23:00"); - $document = new HTMLDocument(DocumentTestFactory::HTML_SINGLE_ELEMENT); + $document = new HTMLDocument(HTMLPageContent::HTML_SINGLE_ELEMENT); $outputElement = $document->querySelector("output"); $sut = new HTMLAttributeBinder(); $sut->bind(null, $dateTime, $outputElement); diff --git a/test/phpunit/ListBinderTest.php b/test/phpunit/ListBinderTest.php index 4c3696c..07d6a41 100644 --- a/test/phpunit/ListBinderTest.php +++ b/test/phpunit/ListBinderTest.php @@ -12,13 +12,14 @@ use Gt\DomTemplate\TableElementNotFoundInContextException; use Gt\DomTemplate\TemplateCollection; use Gt\DomTemplate\TemplateElement; -use Gt\DomTemplate\Test\TestFactory\DocumentTestFactory; +use Gt\DomTemplate\Test\TestHelper\HTMLPageContent; +use Gt\DomTemplate\Test\TestHelper\TestData; use PHPUnit\Framework\TestCase; use Stringable; class ListBinderTest extends TestCase { public function testBindList_emptyList():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_LIST_TEMPLATE); + $document = new HTMLDocument(HTMLPageContent::HTML_LIST_TEMPLATE); $templateCollection = new TemplateCollection($document); $sut = new ListBinder($templateCollection); @@ -30,7 +31,7 @@ public function testBindList_emptyList():void { } public function testBindList_empty_shouldHaveNoWhitespace():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_LIST_TEMPLATE); + $document = new HTMLDocument(HTMLPageContent::HTML_LIST_TEMPLATE); $templateCollection = new TemplateCollection($document); $sut = new ListBinder($templateCollection); $sut->bindListData([], $document); @@ -38,7 +39,7 @@ public function testBindList_empty_shouldHaveNoWhitespace():void { } public function testBindList_emptyList_iterator():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_LIST_TEMPLATE); + $document = new HTMLDocument(HTMLPageContent::HTML_LIST_TEMPLATE); $templateParent = $document->querySelector("ul"); $templateElement = self::createMock(TemplateElement::class); @@ -57,7 +58,7 @@ public function testBindList_emptyList_iterator():void { } public function testBindList_noMatchingTemplate():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_LIST_TEMPLATE); + $document = new HTMLDocument(HTMLPageContent::HTML_LIST_TEMPLATE); $templateCollection = self::createMock(TemplateCollection::class); $templateCollection->expects(self::once()) ->method("get") @@ -76,7 +77,7 @@ public function testBindList_noMatchingTemplate():void { } public function testBindList_simpleList():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_LIST_TEMPLATE); + $document = new HTMLDocument(HTMLPageContent::HTML_LIST_TEMPLATE); $templateElement = new TemplateElement($document->querySelector("li[data-template]")); $templateCollection = self::createMock(TemplateCollection::class); @@ -114,7 +115,7 @@ public function testBindList_simpleList():void { } public function testBindListData_existingChildren():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_SELECT_OPTIONS_TEMPLATE_WITH_EXISTING_CHILDREN); + $document = new HTMLDocument(HTMLPageContent::HTML_SELECT_OPTIONS_TEMPLATE_WITH_EXISTING_CHILDREN); $templateElement = new TemplateElement($document->querySelector("[data-template]")); $templateCollection = self::createMock(TemplateCollection::class); @@ -161,7 +162,7 @@ public function testBindListData_existingChildren():void { * two template elements to have different template names. */ public function testBindListData_twoLists():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_TWO_LISTS); + $document = new HTMLDocument(HTMLPageContent::HTML_TWO_LISTS); $templateElementProgLang = new TemplateElement( $document->querySelector("#favourites li[data-template='prog-lang']") ); @@ -198,7 +199,7 @@ public function testBindListData_twoLists():void { * elements do not identify their own template name. */ public function testBindListData_twoListsDifferentContexts():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_TWO_LISTS_WITH_UNNAMED_TEMPLATES); + $document = new HTMLDocument(HTMLPageContent::HTML_TWO_LISTS_WITH_UNNAMED_TEMPLATES); $templateElementProgLang = new TemplateElement( $document->querySelector("#prog-lang-list li[data-template]") ); @@ -232,7 +233,7 @@ public function testBindListData_twoListsDifferentContexts():void { } public function testBindListData_empty_parentShouldBeEmpty():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_LIST_TEMPLATE); + $document = new HTMLDocument(HTMLPageContent::HTML_LIST_TEMPLATE); $templateElement = new TemplateElement($document->querySelector("li[data-template]")); $templateCollection = self::createMock(TemplateCollection::class); $templateCollection->method("get") @@ -251,7 +252,7 @@ public function testBindListData_kvpList_array():void { ["userId" => 559, "username" => "seafoam", "orderCount" => 30], ["userId" => 274, "username" => "hammatime", "orderCount" => 23], ]; - $document = new HTMLDocument(DocumentTestFactory::HTML_USER_ORDER_LIST); + $document = new HTMLDocument(HTMLPageContent::HTML_USER_ORDER_LIST); $orderList = $document->querySelector("ul"); $templateElement = new TemplateElement($document->querySelector("ul li[data-template]")); @@ -276,7 +277,7 @@ public function testBindListData_kvpList_object():void { (object)["userId" => 559, "username" => "seafoam", "orderCount" => 30], (object)["userId" => 274, "username" => "hammatime", "orderCount" => 23], ]; - $document = new HTMLDocument(DocumentTestFactory::HTML_USER_ORDER_LIST); + $document = new HTMLDocument(HTMLPageContent::HTML_USER_ORDER_LIST); $orderList = $document->querySelector("ul"); $templateElement = new TemplateElement($document->querySelector("ul li[data-template]")); @@ -302,7 +303,7 @@ public function testBindListData_kvpList_instanceObject():void { new class { public int $userId = 559; public string $username = "seafoam"; public int $orderCount = 30; }, new class { public int $userId = 274; public string $username = "hammatime"; public int $orderCount = 23; }, ]; - $document = new HTMLDocument(DocumentTestFactory::HTML_USER_ORDER_LIST); + $document = new HTMLDocument(HTMLPageContent::HTML_USER_ORDER_LIST); $orderList = $document->querySelector("ul"); $templateElement = new TemplateElement($document->querySelector("ul li[data-template]")); @@ -380,7 +381,7 @@ public function getTotalOrders():int { } }, ]; - $document = new HTMLDocument(DocumentTestFactory::HTML_USER_ORDER_LIST); + $document = new HTMLDocument(HTMLPageContent::HTML_USER_ORDER_LIST); $orderList = $document->querySelector("ul"); $templateElement = new TemplateElement($document->querySelector("ul li[data-template]")); @@ -436,7 +437,7 @@ public function testBindListData_kvpList_instanceObjectWithBindAttributeProperti public int $totalOrders = 23; }, ]; - $document = new HTMLDocument(DocumentTestFactory::HTML_USER_ORDER_LIST); + $document = new HTMLDocument(HTMLPageContent::HTML_USER_ORDER_LIST); $orderList = $document->querySelector("ul"); $templateElement = new TemplateElement($document->querySelector("ul li[data-template]")); @@ -456,7 +457,7 @@ public function testBindListData_kvpList_instanceObjectWithBindAttributeProperti } public function testBindListData_nestedList():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_MUSIC_NO_TEMPLATE_NAMES); + $document = new HTMLDocument(HTMLPageContent::HTML_MUSIC_NO_TEMPLATE_NAMES); $templateCollection = new TemplateCollection($document); $sut = new ListBinder($templateCollection); $sut->bindListData(TestData::MUSIC, $document); @@ -490,7 +491,7 @@ public function testBindListData_nestedList():void { } public function testBindListData_nestedList_withKvps():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_STUDENT_LIST); + $document = new HTMLDocument(HTMLPageContent::HTML_STUDENT_LIST); $templateCollection = new TemplateCollection($document); $sut = new ListBinder($templateCollection); $sut->bindListData(TestData::STUDENTS, $document); @@ -511,7 +512,7 @@ public function testBindListData_nestedList_withKvps():void { } public function testBindListData_iterativeSomething():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_SEQUENCES); + $document = new HTMLDocument(HTMLPageContent::HTML_SEQUENCES); $templateCollection = new TemplateCollection($document); $listData = [ "Primes" => new ArrayIterator([2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71]), @@ -531,7 +532,7 @@ public function testBindListData_iterativeSomething():void { } public function testBindListData_dateTime():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_DATES); + $document = new HTMLDocument(HTMLPageContent::HTML_DATES); $templateCollection = new TemplateCollection($document); $listData = []; @@ -558,7 +559,7 @@ public function __toString():string { } public function testBindListData_dateTimeAutomatic():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_DATES); + $document = new HTMLDocument(HTMLPageContent::HTML_DATES); $templateCollection = new TemplateCollection($document); /** @var array $listData */ $listData = []; @@ -581,7 +582,7 @@ public function testBindListData_dateTimeAutomatic():void { } public function testBindListData_todoList():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_TODO); + $document = new HTMLDocument(HTMLPageContent::HTML_TODO); $templateCollection = new TemplateCollection($document); $data = TestData::TODO_DATA; $sut = new ListBinder($templateCollection); @@ -599,7 +600,7 @@ public function testBindListData_todoList():void { } public function testBindListData_multipleTemplateSiblings():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_GOOD_BAD); + $document = new HTMLDocument(HTMLPageContent::HTML_GOOD_BAD); $templateCollection = new TemplateCollection($document); $sut = new ListBinder($templateCollection); $sut->bindListData(["Good news 1", "Good news 2"], $document, "good"); @@ -646,7 +647,7 @@ public function testBindListData_callback():void { return $listItem; }; - $document = new HTMLDocument(DocumentTestFactory::HTML_SALES); + $document = new HTMLDocument(HTMLPageContent::HTML_SALES); $templateCollection = new TemplateCollection($document); $sut = new ListBinder($templateCollection); $sut->bindListData( @@ -667,4 +668,38 @@ public function testBindListData_callback():void { self::assertEquals($profitValue, $li->querySelector(".profit span")->textContent); } } + + public function testBindListData_complexStructure():void { + $customerOrderData = TestData::getCustomerOrderOverview1(); + $document = new HTMLDocument(HTMLPageContent::HTML_MAP_SHOP_CUSTOMER_OVERVIEW); + $templateCollection = new TemplateCollection($document); + $sut = new ListBinder($templateCollection); + $sut->bindListData($customerOrderData, $document); + + foreach($customerOrderData as $customerIndex => $customer) { + $customerLi = $document->querySelectorAll("customer-list>ul>li")[$customerIndex]; + + self::assertSame((string)$customer->id, $customerLi->querySelectorAll("customer-details>dl>dd")[0]->textContent); + self::assertSame($customer->name, $customerLi->querySelectorAll("customer-details>dl>dd")[1]->textContent); + self::assertSame($customer->address->street, $customerLi->querySelectorAll("customer-details>dl>dd")[2]->querySelectorAll("span")[0]->textContent); + self::assertSame($customer->address->line2, $customerLi->querySelectorAll("customer-details>dl>dd")[2]->querySelectorAll("span")[1]->textContent); + self::assertSame($customer->address->cityState, $customerLi->querySelectorAll("customer-details>dl>dd")[2]->querySelectorAll("span")[2]->textContent); + self::assertSame($customer->address->postcodeZip, $customerLi->querySelectorAll("customer-details>dl>dd")[2]->querySelectorAll("span")[3]->textContent); + self::assertSame($customer->address->country->getName(), $customerLi->querySelectorAll("customer-details>dl>dd")[2]->querySelectorAll("span")[4]->textContent); + + foreach($customer->orderList as $orderIndex => $order) { + $orderLi = $customerLi->querySelectorAll("order-list>ul>li")[$orderIndex]; + self::assertSame($order->shippingAddress->cityState, $orderLi->querySelectorAll("dl dd")[0]->textContent); + self::assertSame((string)$order->getSubtotal(), $orderLi->querySelectorAll("dl dd")[1]->textContent); + self::assertSame((string)$order->shippingCost, $orderLi->querySelectorAll("dl dd")[2]->textContent); + self::assertSame((string)$order->getTotalCost(), $orderLi->querySelectorAll("dl dd")[3]->textContent); + + foreach($order->itemList as $itemIndex => $item) { + self::assertSame($item->title, $orderLi->querySelectorAll("ul>li")[$itemIndex]->querySelector("h4")->textContent); + self::assertSame("/item/$item->id", $orderLi->querySelectorAll("ul>li")[$itemIndex]->querySelector("h4 a")->href); + self::assertSame((string)$item->cost, $orderLi->querySelectorAll("ul>li")[$itemIndex]->querySelector("p")->textContent); + } + } + } + } } diff --git a/test/phpunit/PartialContentTest.php b/test/phpunit/PartialContentTest.php index d9e0011..c984888 100644 --- a/test/phpunit/PartialContentTest.php +++ b/test/phpunit/PartialContentTest.php @@ -5,7 +5,7 @@ use Gt\DomTemplate\PartialContent; use Gt\DomTemplate\PartialContentDirectoryNotFoundException; use Gt\DomTemplate\PartialContentFileNotFoundException; -use Gt\DomTemplate\Test\TestFactory\DocumentTestFactory; +use Gt\DomTemplate\Test\TestHelper\HTMLPageContent; use PHPUnit\Framework\TestCase; class PartialContentTest extends TestCase { diff --git a/test/phpunit/PartialExpanderTest.php b/test/phpunit/PartialExpanderTest.php index b65ba83..155feca 100644 --- a/test/phpunit/PartialExpanderTest.php +++ b/test/phpunit/PartialExpanderTest.php @@ -9,7 +9,7 @@ use Gt\DomTemplate\PartialExpander; use Gt\DomTemplate\PartialInjectionMultiplePointException; use Gt\DomTemplate\PartialInjectionPointNotFoundException; -use Gt\DomTemplate\Test\TestFactory\DocumentTestFactory; +use Gt\DomTemplate\Test\TestHelper\HTMLPageContent; class PartialExpanderTest extends PartialContentTestCase { public function testExpand_noMatchingPartial():void { @@ -18,7 +18,7 @@ public function testExpand_noMatchingPartial():void { "nothing" => "this doesn't exist", ] ); - $document = new HTMLDocument(DocumentTestFactory::HTML_EXTENDS_PARTIAL_VIEW); + $document = new HTMLDocument(HTMLPageContent::HTML_EXTENDS_PARTIAL_VIEW); $sut = new PartialExpander( $document, $partialContent @@ -30,10 +30,10 @@ public function testExpand_noMatchingPartial():void { public function testExpand():void { $partialContent = self::mockPartialContent( "_partial", [ - "base-page" => DocumentTestFactory::HTML_PARTIAL_VIEW + "base-page" => HTMLPageContent::HTML_PARTIAL_VIEW ] ); - $document = new HTMLDocument(DocumentTestFactory::HTML_EXTENDS_PARTIAL_VIEW); + $document = new HTMLDocument(HTMLPageContent::HTML_EXTENDS_PARTIAL_VIEW); $mainElement = $document->querySelector("body>main"); self::assertNull($mainElement); @@ -62,10 +62,10 @@ public function testExpand():void { public function testExpand_commentVarsBound():void { $partialContent = self::mockPartialContent( "_partial", [ - "base-page" => DocumentTestFactory::HTML_PARTIAL_VIEW + "base-page" => HTMLPageContent::HTML_PARTIAL_VIEW ] ); - $document = new HTMLDocument(DocumentTestFactory::HTML_EXTENDS_PARTIAL_VIEW); + $document = new HTMLDocument(HTMLPageContent::HTML_EXTENDS_PARTIAL_VIEW); $binder = self::createMock(DocumentBinder::class); $binder->expects(self::once()) ->method("bindKeyValue") @@ -87,11 +87,11 @@ public function testExpand_noExtendsSectionOfCommentIni():void { } public function testExpand_recursive():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_EXTENDS_PARTIAL_VIEW_RECURSIVE); + $document = new HTMLDocument(HTMLPageContent::HTML_EXTENDS_PARTIAL_VIEW_RECURSIVE); $partialContent = self::mockPartialContent( "_partial", [ - "extended-page" => DocumentTestFactory::HTML_EXTENDS_PARTIAL_VIEW_RECURSIVE_BASE, - "partial-base" => DocumentTestFactory::HTML_PARTIAL_VIEW, + "extended-page" => HTMLPageContent::HTML_EXTENDS_PARTIAL_VIEW_RECURSIVE_BASE, + "partial-base" => HTMLPageContent::HTML_PARTIAL_VIEW, ] ); $sut = new PartialExpander($document, $partialContent); @@ -113,11 +113,11 @@ public function testExpand_recursive():void { } public function testExpand_noDataPartialElement():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_EXTENDS_PARTIAL_VIEW); + $document = new HTMLDocument(HTMLPageContent::HTML_EXTENDS_PARTIAL_VIEW); $partialContent = self::mockPartialContent( "_partial", [ // Here, the HTML_COMPONENT isn't expected, because there is no data-partial element. - "base-page" => DocumentTestFactory::HTML_COMPONENT, + "base-page" => HTMLPageContent::HTML_COMPONENT, ] ); $sut = new PartialExpander($document, $partialContent); @@ -127,10 +127,10 @@ public function testExpand_noDataPartialElement():void { } public function testExpand_multipleDataPartialElements():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_EXTENDS_PARTIAL_VIEW); + $document = new HTMLDocument(HTMLPageContent::HTML_EXTENDS_PARTIAL_VIEW); $partialContent = self::mockPartialContent( "_partial", [ - "base-page" => DocumentTestFactory::HTML_INCORRECT_PARTIAL_VIEW, + "base-page" => HTMLPageContent::HTML_INCORRECT_PARTIAL_VIEW, ] ); $sut = new PartialExpander($document, $partialContent); @@ -140,12 +140,12 @@ public function testExpand_multipleDataPartialElements():void { } public function testExpand_detectCyclicRecursion():void { - $document = DocumentTestFactory::createHTML(DocumentTestFactory::HTML_EXTENDS_PARTIAL_CYCLIC_RECURSION); + $document = HTMLPageContent::createHTML(HTMLPageContent::HTML_EXTENDS_PARTIAL_CYCLIC_RECURSION); $partialContent = self::mockPartialContent( "_partial", [ - "extended-page-1" => DocumentTestFactory::HTML_EXTENDS_PARTIAL_CYCLIC_RECURSION_1, - "extended-page-2" => DocumentTestFactory::HTML_EXTENDS_PARTIAL_CYCLIC_RECURSION_2, - "partial-base" => DocumentTestFactory::HTML_PARTIAL_VIEW, + "extended-page-1" => HTMLPageContent::HTML_EXTENDS_PARTIAL_CYCLIC_RECURSION_1, + "extended-page-2" => HTMLPageContent::HTML_EXTENDS_PARTIAL_CYCLIC_RECURSION_2, + "partial-base" => HTMLPageContent::HTML_PARTIAL_VIEW, ] ); $sut = new PartialExpander($document, $partialContent); diff --git a/test/phpunit/PlaceholderBinderTest.php b/test/phpunit/PlaceholderBinderTest.php index a6117a2..fe051e3 100644 --- a/test/phpunit/PlaceholderBinderTest.php +++ b/test/phpunit/PlaceholderBinderTest.php @@ -3,12 +3,12 @@ use Gt\Dom\HTMLDocument; use Gt\DomTemplate\PlaceholderBinder; -use Gt\DomTemplate\Test\TestFactory\DocumentTestFactory; +use Gt\DomTemplate\Test\TestHelper\HTMLPageContent; use PHPUnit\Framework\TestCase; class PlaceholderBinderTest extends TestCase { public function testBind():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_PLACEHOLDER); + $document = new HTMLDocument(HTMLPageContent::HTML_PLACEHOLDER); $greetingElement = $document->querySelector("#test2 .greeting"); $sut = new PlaceholderBinder(); // We can now bind text to the placeholder, and the text will @@ -19,7 +19,7 @@ public function testBind():void { } public function testBind_contextDoesNotLeak():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_PLACEHOLDER); + $document = new HTMLDocument(HTMLPageContent::HTML_PLACEHOLDER); $greetingElement = $document->querySelector("#test2 .greeting"); $sut = new PlaceholderBinder(); $sut->bind("name", "Cody", $greetingElement); @@ -29,7 +29,7 @@ public function testBind_contextDoesNotLeak():void { } public function testBind_noContextBindsAll():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_PLACEHOLDER); + $document = new HTMLDocument(HTMLPageContent::HTML_PLACEHOLDER); $sut = new PlaceholderBinder(); $sut->bind("name", "Cody", $document); self::assertStringContainsString("Cody", $document->querySelector("#test1 .greeting")->textContent); @@ -38,7 +38,7 @@ public function testBind_noContextBindsAll():void { } public function testBind_attribute():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_PLACEHOLDER); + $document = new HTMLDocument(HTMLPageContent::HTML_PLACEHOLDER); $sut = new PlaceholderBinder(); $testElement = $document->getElementById("test3"); $link = $testElement->querySelector("a"); @@ -47,7 +47,7 @@ public function testBind_attribute():void { } public function testBind_nullDefault():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_PLACEHOLDER); + $document = new HTMLDocument(HTMLPageContent::HTML_PLACEHOLDER); $sut = new PlaceholderBinder(); $testElement = $document->getElementById("test2"); $greeting = $testElement->querySelector("p.greeting"); @@ -56,7 +56,7 @@ public function testBind_nullDefault():void { } public function testBind_emptyDefault():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_PLACEHOLDER); + $document = new HTMLDocument(HTMLPageContent::HTML_PLACEHOLDER); $sut = new PlaceholderBinder(); $testElement = $document->getElementById("test2"); $greeting = $testElement->querySelector("p.greeting"); @@ -65,7 +65,7 @@ public function testBind_emptyDefault():void { } public function testBind_zeroNotDefault():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_PLACEHOLDER); + $document = new HTMLDocument(HTMLPageContent::HTML_PLACEHOLDER); $sut = new PlaceholderBinder(); $testElement = $document->getElementById("test2"); $greeting = $testElement->querySelector("p.greeting"); @@ -74,7 +74,7 @@ public function testBind_zeroNotDefault():void { } public function testBind_multipleAttribute():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_PLACEHOLDER); + $document = new HTMLDocument(HTMLPageContent::HTML_PLACEHOLDER); $sut = new PlaceholderBinder(); $testElement = $document->getElementById("test5"); $link = $testElement->querySelector("a"); diff --git a/test/phpunit/TableBinderTest.php b/test/phpunit/TableBinderTest.php index 0a7c9f3..ca6d80d 100644 --- a/test/phpunit/TableBinderTest.php +++ b/test/phpunit/TableBinderTest.php @@ -5,7 +5,7 @@ use Gt\DomTemplate\IncorrectTableDataFormat; use Gt\DomTemplate\TableBinder; use Gt\DomTemplate\TableDataStructureType; -use Gt\DomTemplate\Test\TestFactory\DocumentTestFactory; +use Gt\DomTemplate\Test\TestHelper\HTMLPageContent; use PHPUnit\Framework\TestCase; class TableBinderTest extends TestCase { @@ -15,7 +15,7 @@ class TableBinderTest extends TestCase { */ public function testBindTable_emptyTable():void { $sut = new TableBinder(); - $document = new HTMLDocument(DocumentTestFactory::HTML_TABLES); + $document = new HTMLDocument(HTMLPageContent::HTML_TABLES); $table = $document->getElementById("tbl1"); @@ -45,7 +45,7 @@ public function testBindTable_emptyTable():void { */ public function testBindTable_emptyTableSpecifiedByName():void { $sut = new TableBinder(); - $document = new HTMLDocument(DocumentTestFactory::HTML_TABLES); + $document = new HTMLDocument(HTMLPageContent::HTML_TABLES); $table0 = $document->getElementById("tbl0"); $table1 = $document->getElementById("tbl1"); @@ -80,7 +80,7 @@ public function testBindTable_emptyTableSpecifiedByName():void { */ public function testBindTable_existingTHead():void { $sut = new TableBinder(); - $document = new HTMLDocument(DocumentTestFactory::HTML_TABLES); + $document = new HTMLDocument(HTMLPageContent::HTML_TABLES); $table = $document->getElementById("tbl2"); @@ -125,7 +125,7 @@ public function testBindTable_existingTHead():void { public function testBindTable_dataNormalised():void { $sut = new TableBinder(); - $document = new HTMLDocument(DocumentTestFactory::HTML_TABLES); + $document = new HTMLDocument(HTMLPageContent::HTML_TABLES); $table = $document->getElementById("tbl2"); @@ -170,7 +170,7 @@ public function testBindTable_dataNormalised():void { */ public function testBindTable_doubleHeader_shouldEmitTHElementsInRows():void { $sut = new TableBinder(); - $document = new HTMLDocument(DocumentTestFactory::HTML_TABLES); + $document = new HTMLDocument(HTMLPageContent::HTML_TABLES); $table = $document->getElementById("tbl1"); @@ -229,7 +229,7 @@ public function testBindTable_doubleHeader_shouldEmitTHElementsInRows():void { public function testBindTable_nonIterableValue():void { $sut = new TableBinder(); - $document = new HTMLDocument(DocumentTestFactory::HTML_TABLES); + $document = new HTMLDocument(HTMLPageContent::HTML_TABLES); $table = $document->getElementById("tbl1"); @@ -249,7 +249,7 @@ public function testBindTable_nonIterableValue():void { public function testBindTable_doubleHeaderNonIterableValue():void { $sut = new TableBinder(); - $document = new HTMLDocument(DocumentTestFactory::HTML_TABLES); + $document = new HTMLDocument(HTMLPageContent::HTML_TABLES); $table = $document->getElementById("tbl1"); @@ -269,7 +269,7 @@ public function testBindTable_doubleHeaderNonIterableValue():void { public function testBindTable_assocArrayWithoutIterableColumns():void { $sut = new TableBinder(); - $document = new HTMLDocument(DocumentTestFactory::HTML_TABLES); + $document = new HTMLDocument(HTMLPageContent::HTML_TABLES); $table = $document->getElementById("tbl1"); $tableData = [ @@ -294,7 +294,7 @@ public function testBindTable_multipleTables():void { "email" => ["derek@php.net", "cmbecker69@php.net", "pollita@php.net"], ]; - $document = new HTMLDocument(DocumentTestFactory::HTML_TABLES); + $document = new HTMLDocument(HTMLPageContent::HTML_TABLES); $sut->bindTableData( $tableData, $document->getElementById("multi-table-container"), @@ -333,7 +333,7 @@ public function testBindTable_keyNamesInTHead():void { "email" => ["derek@php.net", "cmbecker69@php.net", "pollita@php.net"], ]; - $document = new HTMLDocument(DocumentTestFactory::HTML_TABLES); + $document = new HTMLDocument(HTMLPageContent::HTML_TABLES); $table = $document->getElementById("tbl3"); $sut->bindTableData( $tableData, @@ -373,7 +373,7 @@ public function testBindTableData_documentContext():void { "email" => ["derek@php.net", "cmbecker69@php.net", "pollita@php.net"], ]; - $document = new HTMLDocument(DocumentTestFactory::HTML_TABLE_NO_BIND_KEY); + $document = new HTMLDocument(HTMLPageContent::HTML_TABLE_NO_BIND_KEY); $sut->bindTableData($tableData, $document); self::assertCount(4, $document->querySelectorAll("table tr")); @@ -389,7 +389,7 @@ public function testBindTableData_emptyHeader():void { array_push($tableData, [$i, $name, md5($name)]); } - $document = new HTMLDocument(DocumentTestFactory::HTML_TABLE_ID_NAME_CODE); + $document = new HTMLDocument(HTMLPageContent::HTML_TABLE_ID_NAME_CODE); $sut->bindTableData($tableData, $document); $table = $document->querySelector("table"); @@ -416,7 +416,7 @@ public function testBindTableData_existingBodyRow():void { array_push($tableData, [$i, md5($name), $name, $i % 3 === 0]); } - $document = new HTMLDocument(DocumentTestFactory::HTML_TABLE_EXISTING_CELLS); + $document = new HTMLDocument(HTMLPageContent::HTML_TABLE_EXISTING_CELLS); $sut = new TableBinder(); $sut->bindTableData($tableData, $document); @@ -466,7 +466,7 @@ public function testBindTableData_existingBodyRow_differentDataShape():void { array_push($tableData["deleted"], $i % 3 === 0); } - $document = new HTMLDocument(DocumentTestFactory::HTML_TABLE_EXISTING_CELLS); + $document = new HTMLDocument(HTMLPageContent::HTML_TABLE_EXISTING_CELLS); $sut = new TableBinder(); $sut->bindTableData($tableData, $document); @@ -524,7 +524,7 @@ public function testBindTableData_datumPerRow():void { // "Laptop" => [799_99, 60], // ] // ]; - $document = new HTMLDocument(DocumentTestFactory::HTML_TABLE_CRUD); + $document = new HTMLDocument(HTMLPageContent::HTML_TABLE_CRUD); $sut = new TableBinder(); $sut->bindTableData($tableData, $document); $tBody = $document->querySelector("table tbody"); diff --git a/test/phpunit/TemplateCollectionTest.php b/test/phpunit/TemplateCollectionTest.php index cf16f9c..13d0926 100644 --- a/test/phpunit/TemplateCollectionTest.php +++ b/test/phpunit/TemplateCollectionTest.php @@ -5,12 +5,13 @@ use Gt\DomTemplate\ElementBinder; use Gt\DomTemplate\TemplateCollection; use Gt\DomTemplate\TemplateElementNotFoundInContextException; -use Gt\DomTemplate\Test\TestFactory\DocumentTestFactory; +use Gt\DomTemplate\Test\TestHelper\HTMLPageContent; +use Gt\DomTemplate\Test\TestHelper\TestData; use PHPUnit\Framework\TestCase; class TemplateCollectionTest extends TestCase { public function testGet_noName_noMatch():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_LIST_TEMPLATE); + $document = new HTMLDocument(HTMLPageContent::HTML_LIST_TEMPLATE); $sut = new TemplateCollection($document); self::expectException(TemplateElementNotFoundInContextException::class); @@ -18,7 +19,7 @@ public function testGet_noName_noMatch():void { } public function testGet_noName():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_LIST_TEMPLATE); + $document = new HTMLDocument(HTMLPageContent::HTML_LIST_TEMPLATE); $ul = $document->querySelector("ul"); $ol = $document->querySelector("ol"); self::assertCount(1, $ul->children); @@ -34,7 +35,7 @@ public function testGet_noName():void { } public function testGet_name_noMatch():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_TWO_LISTS); + $document = new HTMLDocument(HTMLPageContent::HTML_TWO_LISTS); $sut = new TemplateCollection($document); self::expectException(TemplateElementNotFoundInContextException::class); @@ -43,7 +44,7 @@ public function testGet_name_noMatch():void { } public function testGet_name():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_TWO_LISTS); + $document = new HTMLDocument(HTMLPageContent::HTML_TWO_LISTS); $sut = new TemplateCollection($document); $templateElement = $sut->get($document, "prog-lang"); @@ -63,7 +64,7 @@ public function testGet_name():void { * ListBinderTest::testBindListData_nestedList() */ public function testBindListData_nestedList_manual():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_MUSIC_EXPLICIT_TEMPLATE_NAMES); + $document = new HTMLDocument(HTMLPageContent::HTML_MUSIC_EXPLICIT_TEMPLATE_NAMES); $templateCollection = new TemplateCollection($document); $elementBinder = new ElementBinder(); @@ -118,13 +119,13 @@ public function testBindListData_nestedList_manual():void { } public function testConstructor_removesWhitespace():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_LIST_TEMPLATE); + $document = new HTMLDocument(HTMLPageContent::HTML_LIST_TEMPLATE); new TemplateCollection($document); self::assertSame("", $document->querySelector("ul")->innerHTML); } public function testConstructor_nonTemplateChildrenArePreserved():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_LIST_WITH_TEXTNODE); + $document = new HTMLDocument(HTMLPageContent::HTML_LIST_WITH_TEXTNODE); new TemplateCollection($document); $ulChildren = $document->querySelector("ul")->children; self::assertCount(1, $ulChildren); @@ -132,7 +133,7 @@ public function testConstructor_nonTemplateChildrenArePreserved():void { } public function testConstructor_nonTemplateChildrenArePreservedInOrder():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_LIST_WITH_TEXTNODE); + $document = new HTMLDocument(HTMLPageContent::HTML_LIST_WITH_TEXTNODE); $sut = new TemplateCollection($document); $ulChildren = $document->querySelector("ul")->children; $template = $sut->get($document); diff --git a/test/phpunit/TemplateElementTest.php b/test/phpunit/TemplateElementTest.php index dad7b35..40ec989 100644 --- a/test/phpunit/TemplateElementTest.php +++ b/test/phpunit/TemplateElementTest.php @@ -4,12 +4,12 @@ use Gt\Dom\HTMLDocument; use Gt\DomTemplate\InvalidTemplateElementNameException; use Gt\DomTemplate\TemplateElement; -use Gt\DomTemplate\Test\TestFactory\DocumentTestFactory; +use Gt\DomTemplate\Test\TestHelper\HTMLPageContent; use PHPUnit\Framework\TestCase; class TemplateElementTest extends TestCase { public function testGetTemplateName_forwardSlashStarter():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_EMPTY); + $document = new HTMLDocument(HTMLPageContent::HTML_EMPTY); $originalElement = $document->createElement("div"); $originalElement->setAttribute("data-template", "/oh/dear/oh/dear"); $document->body->appendChild($originalElement); @@ -20,7 +20,7 @@ public function testGetTemplateName_forwardSlashStarter():void { } public function testNextElementSibling():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_TEMPLATE_ELEMENT_WITH_MULTIPLE_DIVS); + $document = new HTMLDocument(HTMLPageContent::HTML_TEMPLATE_ELEMENT_WITH_MULTIPLE_DIVS); $originalElement = $document->querySelector("[data-template]"); $originalElementNextElementSibling = $originalElement->nextElementSibling; @@ -30,7 +30,7 @@ public function testNextElementSibling():void { } public function testInsertTemplate():void { - $document = new HTMLDocument(DocumentTestFactory::HTML_TEMPLATE_ELEMENT_WITH_MULTIPLE_DIVS); + $document = new HTMLDocument(HTMLPageContent::HTML_TEMPLATE_ELEMENT_WITH_MULTIPLE_DIVS); $originalElement = $document->querySelector("[data-template]"); $originalElementNextElementSibling = $originalElement->nextElementSibling; diff --git a/test/phpunit/TestData.php b/test/phpunit/TestData.php deleted file mode 100644 index d3639fe..0000000 --- a/test/phpunit/TestData.php +++ /dev/null @@ -1,97 +0,0 @@ - [ - "This Album is Good" => [ - "The Best Song You‘ve Ever Heard", - "Another Cracking Tune", - "Top Notch Music Here", - "The Best Is Left ‘Til Last", - ], - "Adequate Collection" => [ - "Meh", - "‘sok", - "Sounds Like Every Other Song", - ], - ], - "Bongo and The Bronks" => [ - "Salad" => [ - "Tomatoes", - "Song About Cucumber", - "Onions Make Me Cry (but I love them)", - ], - "Meat" => [ - "Steak", - "Is Chicken Really a Meat?", - "Don‘t Look in the Sausage Factory", - "Stop Horsing Around", - ], - "SnaxX" => [ - "Crispy Potatoes With Salt", - "Pretzel Song", - "Pork Scratchings Are Skin", - "The Peanut Is Not Actually A Nut", - ], - ], - "Crayons" => [ - "Pastel Colours" => [ - "Egg Shell", - "Cotton", - "Frost", - "Periwinkle", - ], - "Different Shades of Blue" => [ - "Cobalt", - "Slate", - "Indigo", - "Teal", - ], - ] - ]; - - const STUDENTS = [ - [ - "firstName" => "Freddie", - "lastName" => "Williams", - "modules" => [ - "Programming 1", "Networking Fundamentals", "Computational Logic" - ] - ], - [ - "firstName" => "Melissa", - "lastName" => "Adams", - "modules" => [ - "Computational Mathematics", "Networks and Security", "Graphics I" - ] - ], - [ - "firstName" => "Sofia", - "lastName" => "Reid", - "modules" => [ - "Databases", "Programming 2", "Networking Fundamentals" - ] - ], - ]; - - const TODO_DATA = [ - [ - "id" => 100, - "title" => "Create DOM facade", - "completedAt" => "2021-05-18 10:03:57", - ], [ - "id" => 101, - "title" => "Bind data to the DOM", - "completedAt" => "2021-05-18 16:32:20", - ], [ - "id" => 102, - "title" => "Bundle into WebEngine", - "completedAt" => null, - ], [ - "id" => 103, - "title" => "Release WebEngine v4", - "completedAt" => null, - ] - ]; -} diff --git a/test/phpunit/TestFactory/ExampleClass.php b/test/phpunit/TestHelper/ExampleClass.php similarity index 79% rename from test/phpunit/TestFactory/ExampleClass.php rename to test/phpunit/TestHelper/ExampleClass.php index cdd6b83..1e67154 100644 --- a/test/phpunit/TestFactory/ExampleClass.php +++ b/test/phpunit/TestHelper/ExampleClass.php @@ -1,5 +1,5 @@ HTML; @@ -898,6 +898,94 @@ class DocumentTestFactory { HTML; + const HTML_ADDRESS_NESTED_OBJECT = << +

Customer information

+
+
ID
+
+ +
Name
+
+ +
Address Street
+
Address line 1
+ +
Address Line 2
+
Address line 2
+ +
City / State
+
Address city/state
+ +
Postcode / ZIP
+
Address Postcode/ZIP
+ +
Country
+
Address country (AA)
+
+HTML; + + const HTML_MAP_SHOP_CUSTOMER_OVERVIEW = << +

Customer overview

+ + +
    +
  • + +
    +
    ID
    +
    000
    + +
    Name
    +
    Customer Name!
    + +
    Address
    +
    + Address Line 1 + Address Line 2 + Address City + Address Postcode + Address Country +
    + +
    Latest orders
    + + + +
      +
    • +
      +
      City / State
      +
      + +
      Subtotal
      +
      £0.--
      + +
      Shipping
      +
      £0.--
      + +
      Total
      +
      £0.--
      +
      +

      Items in order

      + +
    • +
    +
    +
    +
    +
  • +
+
+HTML; + public static function createHTML(string $html = ""):HTMLDocument { return new HTMLDocument($html); diff --git a/test/phpunit/TestHelper/Model/Address.php b/test/phpunit/TestHelper/Model/Address.php new file mode 100644 index 0000000..8a89234 --- /dev/null +++ b/test/phpunit/TestHelper/Model/Address.php @@ -0,0 +1,14 @@ +code) { + "US" => "United States", + "CN" => "China", + "JP" => "Japan", + "DE" => "Germany", + "GB" => "United Kingdom", + "FR" => "France", + "IN" => "India", + "CA" => "Canada", + "IT" => "Italy", + "AU" => "Australia", + "KR" => "South Korea", + default => "Unknown", + }; + } +} diff --git a/test/phpunit/TestHelper/Model/Currency.php b/test/phpunit/TestHelper/Model/Currency.php new file mode 100644 index 0000000..eb8a1d0 --- /dev/null +++ b/test/phpunit/TestHelper/Model/Currency.php @@ -0,0 +1,27 @@ + "$", + self::EUR => "€", + self::JPY, self::CNH => "¥", + self::GBP => "£", + self::CHF => "fr", + self::KRW => "₩", + }; + } +} diff --git a/test/phpunit/TestHelper/Model/Customer.php b/test/phpunit/TestHelper/Model/Customer.php new file mode 100644 index 0000000..be89035 --- /dev/null +++ b/test/phpunit/TestHelper/Model/Customer.php @@ -0,0 +1,16 @@ + $orderList */ + public function __construct( + public readonly int $id, + public readonly string $name, + public readonly Address $address, + public array $orderList = [], + ) {} + + public function addOrder(Order $order):void { + array_push($this->orderList, $order); + } +} diff --git a/test/phpunit/TestHelper/Model/Money.php b/test/phpunit/TestHelper/Model/Money.php new file mode 100644 index 0000000..0d50e81 --- /dev/null +++ b/test/phpunit/TestHelper/Model/Money.php @@ -0,0 +1,33 @@ +currency) + . number_format($this->value, 2); + } + + public function withAddition(Money $add):self { + $newValue = round( + $add->value, + $this->decimalAccuracy, + ) + round( + $this->value, + $this->decimalAccuracy, + ); + return new self( + $newValue, + $this->currency, + ); + } +} diff --git a/test/phpunit/TestHelper/Model/Order.php b/test/phpunit/TestHelper/Model/Order.php new file mode 100644 index 0000000..9288ca2 --- /dev/null +++ b/test/phpunit/TestHelper/Model/Order.php @@ -0,0 +1,31 @@ + $itemList */ + public function __construct( + public readonly int $id, + public readonly Money $shippingCost, + public readonly Address $shippingAddress, + public readonly array $itemList = [], + ) { + } + + #[BindGetter] + public function getSubtotal():Money { + $subtotal = new Money(); + + foreach($this->itemList as $item) { + $subtotal = $subtotal->withAddition($item->cost); + } + + return $subtotal; + } + + #[BindGetter] + public function getTotalCost():Money { + return $this->getSubtotal()->withAddition($this->shippingCost); + } +} diff --git a/test/phpunit/TestHelper/Model/ShopItem.php b/test/phpunit/TestHelper/Model/ShopItem.php new file mode 100644 index 0000000..5f1448c --- /dev/null +++ b/test/phpunit/TestHelper/Model/ShopItem.php @@ -0,0 +1,11 @@ + [ + "This Album is Good" => [ + "The Best Song You‘ve Ever Heard", + "Another Cracking Tune", + "Top Notch Music Here", + "The Best Is Left ‘Til Last", + ], + "Adequate Collection" => [ + "Meh", + "‘sok", + "Sounds Like Every Other Song", + ], + ], + "Bongo and The Bronks" => [ + "Salad" => [ + "Tomatoes", + "Song About Cucumber", + "Onions Make Me Cry (but I love them)", + ], + "Meat" => [ + "Steak", + "Is Chicken Really a Meat?", + "Don‘t Look in the Sausage Factory", + "Stop Horsing Around", + ], + "SnaxX" => [ + "Crispy Potatoes With Salt", + "Pretzel Song", + "Pork Scratchings Are Skin", + "The Peanut Is Not Actually A Nut", + ], + ], + "Crayons" => [ + "Pastel Colours" => [ + "Egg Shell", + "Cotton", + "Frost", + "Periwinkle", + ], + "Different Shades of Blue" => [ + "Cobalt", + "Slate", + "Indigo", + "Teal", + ], + ] + ]; + + const STUDENTS = [ + [ + "firstName" => "Freddie", + "lastName" => "Williams", + "modules" => [ + "Programming 1", "Networking Fundamentals", "Computational Logic" + ] + ], + [ + "firstName" => "Melissa", + "lastName" => "Adams", + "modules" => [ + "Computational Mathematics", "Networks and Security", "Graphics I" + ] + ], + [ + "firstName" => "Sofia", + "lastName" => "Reid", + "modules" => [ + "Databases", "Programming 2", "Networking Fundamentals" + ] + ], + ]; + + const TODO_DATA = [ + [ + "id" => 100, + "title" => "Create DOM facade", + "completedAt" => "2021-05-18 10:03:57", + ], [ + "id" => 101, + "title" => "Bind data to the DOM", + "completedAt" => "2021-05-18 16:32:20", + ], [ + "id" => 102, + "title" => "Bundle into WebEngine", + "completedAt" => null, + ], [ + "id" => 103, + "title" => "Release WebEngine v4", + "completedAt" => null, + ] + ]; + + /** @return array */ + public static function getCustomerOrderOverview1():array { + $customer1 = new Customer( + 1001, + "James Hendler", + new Address( + "23 Concord Dr", + "Middletown", + "Rhode Island", + "02842", + new Country("US"), + ), + ); + $customer2 = new Customer( + 2002, + "Annie Easley", + new Address( + "63rd Hwy", + "Calera", + "Alabama", + "35040", + new Country("US") + ), + ); + + $customer1->addOrder(new Order( + 500_001_001, + new Money(55.50, Currency::USD), + $customer1->address, + [ + new ShopItem(239, "Maryland Flag", "Vexillologist's nightmare", new Money(79.99, Currency::USD)), + new ShopItem(814, "NeXTcube", "High-end workstation computer", new Money(7_995.00, Currency::USD)), + ] + )); + $customer1->addOrder(new Order( + 500_001_002, + new Money(7.50, Currency::USD), + $customer1->address, + [ + new ShopItem(330, "Getting started with DAML", "Everything you need to know about DARPA's Agent Markup Language", new Money(20.00, Currency::USD)), + ] + )); + + $customer2->addOrder(new Order( + 500_002_001, + new Money(8.00, Currency::USD), + $customer2->address, + [ + new ShopItem(241, "New Orleans Flag", "A simple and traditional gem", new Money(79.99, Currency::USD)), + ] + )); + $customer2->addOrder(new Order( + 500_002_002, + new Money(5.00, Currency::USD), + $customer2->address, + [ + new ShopItem(190, "NASA t-shirt, ladies M", "Original design used by engineers in the 1960s", new Money(25.00, Currency::USD)), + new ShopItem(921, "Bottle of fresh O-Zone", "Taken from your local stratosphere", new Money(12.50, Currency::USD)), + new ShopItem(800, "Science and Engineering Newsletter", "Backprint of issue 48", new Money(15.00, Currency::USD)), + ] + )); + + return [ + $customer1, + $customer2, + ]; + } +}