From 81828bd83359e20d5d0ed1f8cb7dd36651392b6f Mon Sep 17 00:00:00 2001 From: Ben Martinez-Bateman Date: Fri, 24 Jul 2020 19:57:18 -0700 Subject: [PATCH] Add is(Not)Empty helper methods --- README.adoc | 19 +++++++++++++++++ src/Brief.php | 51 +++++++++++++++++++++++++++++++++++++++++++++ tests/BriefTest.php | 33 +++++++++++++++++++++++++++++ 3 files changed, 103 insertions(+) diff --git a/README.adoc b/README.adoc index 6815606..4b365ee 100644 --- a/README.adoc +++ b/README.adoc @@ -169,6 +169,25 @@ $brief->a_rose === $brief->montague; // true ---- +=== Custom Empty Test + +Brief comes with `isEmpty()` and `isNotEmpty()` which somewhat naively test if the Brief is empty +(they examine only whether top-level items in the array are not equal to `null`). +If your use case requires a more robust test, you can pass that test to the `isEmpty` parameter at instantiation. +It accepts anything PHP considers callable. + +[source,php] +---- +$brief = Brief::make([ + ['key' => 'value'], + ['isEmpty' => function($brief) { + // some logic + }] +); + +$brief->isEmpty(); // false (hopefully) +---- + === Logging Since the basic concept for Brief is about how either your data exists or doesn't, Brief will not complain loudly if you do something it doesn't like. diff --git a/src/Brief.php b/src/Brief.php index 1c88d00..0debc76 100644 --- a/src/Brief.php +++ b/src/Brief.php @@ -141,6 +141,9 @@ public function parseSettings(array $settings) case 'logger': $this->setUpLogger($arg); break; + case 'isEmpty': + $this->setUpIsEmpty($arg); + break; } } } @@ -169,6 +172,20 @@ protected function setUpLogger($callable) } } + /** + * Attach isEmpty text to Brief, if valid. + * + * This callable will be passed a copy of the Brief to evaluate. + * + * @param $callable + */ + protected function setUpIsEmpty($callable) + { + if (is_callable($callable)) { + $this->callables['isEmpty'] = $callable; + } + } + /** * Store multiple values, as defined by an array. * @@ -839,4 +856,38 @@ public function transform(callable $callable) return $this; } + + /** + * Determines whether the Brief is empty. + * + * The default test is somewhat naive, but you can pass your own test via + * the `isEmpty` setting on instantiation. + * + * @return bool|mixed + */ + public function isEmpty() + { + $Clone = clone $this; + + if (isset($this->callables['isEmpty']) && is_callable($this->callables['isEmpty'])) { + $result = call_user_func($this->callables['isEmpty'], $Clone); + unset($Clone); + + return $result; + } + + return count(array_filter(array_column($this->store, 'value'), function ($value) { + return $value !== null; + })) < 1; + } + + /** + * If the Brief is *not* empty. + * + * @return bool + */ + public function isNotEmpty() + { + return !$this->isEmpty(); + } } diff --git a/tests/BriefTest.php b/tests/BriefTest.php index b1e6e08..27ac134 100644 --- a/tests/BriefTest.php +++ b/tests/BriefTest.php @@ -447,6 +447,39 @@ public function testSetKeyAndValueDynamically(): void $this->assertEquals('new value', $Brief->new_key); $this->assertNotEquals('new value', $Brief->any_key); } + + public function testCanDetermineEmptyBriefs(): void + { + $Brief = Brief::make([]); + $this->assertTrue($Brief->isEmpty()); + $this->assertFalse($Brief->isNotEmpty()); + + $SortOfEmpty = Brief::make([ + 'key' => null, + ]); + $this->assertTrue($SortOfEmpty->isEmpty()); + $this->assertFalse($SortOfEmpty->isNotEmpty()); + + $NotActuallyEmpty = Brief::make([ + 'key' => false, + ]); + $this->assertFalse($NotActuallyEmpty->isEmpty()); + $this->assertTrue($NotActuallyEmpty->isNotEmpty()); + } + + public function testCanUserCustomEmptyFunction(): void + { + $test = function(Brief $brief) { + return count(array_filter($brief->getKeyed())) < 1; + }; + $Brief = Brief::make([], ['isEmpty' => $test]); + $this->assertTrue($Brief->isEmpty()); + + $Brieful = Brief::make([ + 'key' => 'value', + ], ['isEmpty' => $test]); + $this->assertFalse($Brieful->isEmpty()); + } } /**