From be9ec471f4162f0dc53f756833365105ae97d693 Mon Sep 17 00:00:00 2001 From: Greg Bowler Date: Sat, 6 Jan 2018 21:16:32 +0000 Subject: [PATCH 1/2] Add failing test for #9 --- test/unit/BindableTest.php | 36 ++++++++++++++++++++++++++++++++++++ test/unit/Helper/Helper.php | 30 ++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/test/unit/BindableTest.php b/test/unit/BindableTest.php index 42f12dc..519159b 100644 --- a/test/unit/BindableTest.php +++ b/test/unit/BindableTest.php @@ -1,6 +1,7 @@ innerHTML); self::assertNotContains("Use the other template instead!", $todoListElement->innerHTML); } + + public function testBindWithNonOptionalKey() { + $document = new HTMLDocument(Helper::HTML_TODO_LIST); + $todoData = [ + ["title" => "Write tests", "complete" => true], + ["title" => "Implement features", "complete" => false], + ["title" => "Pass tests", "complete" => false], + ]; + $document->extractTemplates(); + $todoListElement = $document->getElementById("todo-list"); + + self::expectException(BoundDataNotSetException::class); + $todoListElement->bind($todoData); + } + + public function testBindWithOptionalKey() { + $document = new HTMLDocument(Helper::HTML_TODO_LIST_OPTIONAL_ID); + $todoData = [ + ["title" => "Write tests", "complete" => true], + ["title" => "Implement features", "complete" => false], + ["title" => "Pass tests", "complete" => false], + ]; + $document->extractTemplates(); + $todoListElement = $document->getElementById("todo-list"); + $items = $todoListElement->querySelectorAll("li"); + + $todoListElement->bind($todoData); + self::assertEquals( + "Implement features", + $items[1]->querySelector("input[name=title]")->innerText + ); + self::assertNull( + $items[1]->querySelector("input[name=id]")->value + ); + } } \ No newline at end of file diff --git a/test/unit/Helper/Helper.php b/test/unit/Helper/Helper.php index c4877b6..908f94e 100644 --- a/test/unit/Helper/Helper.php +++ b/test/unit/Helper/Helper.php @@ -188,5 +188,35 @@ class Helper { +HTML; + + const HTML_TODO_LIST_OPTIONAL_ID = << + +Todo list +
+ +
+HTML; + + const HTML_TODO_LIST_OPTIONAL_ID_REFERENCED = << + +Todo list +
+ +
HTML; } \ No newline at end of file From a5fa432d63b9bc1ed24870d932e35577eaec0bb8 Mon Sep 17 00:00:00 2001 From: Greg Bowler Date: Sat, 6 Jan 2018 21:29:33 +0000 Subject: [PATCH 2/2] Implement optional bind keys Closes #9 --- src/Bindable.php | 19 +++++++++++-------- src/DataKeyMatch.php | 24 ++++++++++++++++++++++++ test/unit/BindableTest.php | 6 ++++-- 3 files changed, 39 insertions(+), 10 deletions(-) create mode 100644 src/DataKeyMatch.php diff --git a/src/Bindable.php b/src/Bindable.php index 377fed2..e76d8bb 100644 --- a/src/Bindable.php +++ b/src/Bindable.php @@ -79,11 +79,8 @@ protected function setData(BaseElement $element, iterable $data):void { continue; } - $key = $this->getKeyFromAttribute($element, $attr); - if(!isset($data[$key])) { - throw new BoundDataNotSetException($key); - } - $dataValue = $data[$key]; + $dataKeyMatch = $this->getKeyFromAttribute($element, $attr); + $dataValue = $dataKeyMatch->getValue($data) ?? ""; switch($matches[1]) { case "html": @@ -104,9 +101,15 @@ protected function setData(BaseElement $element, iterable $data):void { } } - protected function getKeyFromAttribute(BaseElement $element, Attr $attr):string { + protected function getKeyFromAttribute(BaseElement $element, Attr $attr):DataKeyMatch { + $required = true; $key = $attr->value; + if($key[0] === "?") { + $required = false; + $key = substr($key, 1); + } + if($key[0] === "@") { $key = substr($key, 1); $attributeValue = $element->getAttribute($key); @@ -114,10 +117,10 @@ protected function getKeyFromAttribute(BaseElement $element, Attr $attr):string throw new BoundAttributeDoesNotExistException($attr->name); } - return $attributeValue; + $key = $attributeValue; } - return $key; + return new DataKeyMatch($key, $required); } protected function wrapData(iterable $data):iterable { diff --git a/src/DataKeyMatch.php b/src/DataKeyMatch.php new file mode 100644 index 0000000..ecf7b86 --- /dev/null +++ b/src/DataKeyMatch.php @@ -0,0 +1,24 @@ +key = $key; + $this->required = $required; + } + + public function checkDataExists(iterable $data) { + if(!$this->required) { + return; + } + + if(!isset($data[$this->key])) { + throw new BoundDataNotSetException($this->key); + } + } + + public function getValue(iterable $data):?string { + $this->checkDataExists($data); + return $data[$this->key] ?? null; + } +} \ No newline at end of file diff --git a/test/unit/BindableTest.php b/test/unit/BindableTest.php index 519159b..3bc2995 100644 --- a/test/unit/BindableTest.php +++ b/test/unit/BindableTest.php @@ -210,12 +210,14 @@ public function testBindWithOptionalKey() { ]; $document->extractTemplates(); $todoListElement = $document->getElementById("todo-list"); - $items = $todoListElement->querySelectorAll("li"); $todoListElement->bind($todoData); + $items = $todoListElement->querySelectorAll("li"); + self::assertCount(3, $items); + self::assertEquals( "Implement features", - $items[1]->querySelector("input[name=title]")->innerText + $items[1]->querySelector("input[name=title]")->value ); self::assertNull( $items[1]->querySelector("input[name=id]")->value