Skip to content

Commit

Permalink
Merge pull request #36 from omitobi/feature/implement-else-if-method
Browse files Browse the repository at this point in the history
Feature/implement else if method
  • Loading branch information
omitobi authored Apr 19, 2020
2 parents fd9a590 + 43ef7e3 commit 57433c2
Show file tree
Hide file tree
Showing 3 changed files with 170 additions and 10 deletions.
34 changes: 31 additions & 3 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ or add to the require object of `composer.json` file with the version number:
```json
{
"require": {
"omitobisam/conditional": "^1.0"
"omitobisam/conditional": "^1.1"
}
}
```
Expand Down Expand Up @@ -116,11 +116,13 @@ You are also allowed to throw exception based on the condition like so:

```php
\conditional('foo' === 'bar')

->then('foo === bar')

->else(new TestException('Foo is not the same as bar')); //this exception is thrown
```

### Coming soon
### Newly released

`elseIf()` method of Conditional like so:

Expand All @@ -136,9 +138,35 @@ conditional(isset($data))
->else(2);
```

### Coming Soon
`if()` method of Conditional like so:

```php
Conditional::if(function ($value1, $value2, $value3) {
return $value1 === 1 && $value2 === 2 && $value3 == 4;
})
->then(fn() => doThis())

->else(2);
```

`If()` and `elseIf()` statement accepting a default value when no condition is met and `else()` is not called like so:

```php
Conditional::if(is_array('a'), 'ninja') //default value is ninja

->then(fn() => doThis())

->elseIf(is_int(""))

->then(fn() => doThat())

->value(); // 'ninja' is returned :scream:
```

## Caveats (or Awareness)

- As at version 1.0, Calling `if()` method returns an instance of Condtional, so do not call it twice on the same instance for example:
- As at version 1.x, Calling `if()` method returns an instance of Condtional, so do not call it twice on the same instance for example:

```php
// This is Wrong!
Expand Down
66 changes: 59 additions & 7 deletions src/Conditional.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,11 @@
use Closure;
use Conditional\Exceptions\InvalidConditionOrderException;

/**
* Class Conditional
* @package Conditional
*
*/
class Conditional
{
private static bool $truthy = false;
Expand All @@ -15,41 +20,54 @@ class Conditional

private static bool $thenCalled = false;

private static bool $elseCalled = false;

private static bool $elseIfCalled = false;

private static $finalValue;

private static $finalValueChanged = null;

public static function if($condition)
{
self::setTruthy($condition);

self::$conditionsExists = true;

self::$ifCalled = true;

return new static;
}

public static function setTruthy($condition)
{
if (!$condition instanceof Closure) {
self::$truthy = (bool)$condition;
} else {
self::$truthy = (bool)$condition();
}

return new static;
}

public function else($action)
{
self::$conditionsExists = true;

$this->toggleTruthy();

if (!self::$thenCalled) {
throw new InvalidConditionOrderException(
'then() must be called before calling else()'
);
}

$this->toggleTruthy();

self::$conditionsExists = true;

self::$elseCalled = true;

return $this->then($action);
}

public function then($action)
{
if (!self::$conditionsExists || !self::$ifCalled) {
if (!$this->allowThen()) {
throw new InvalidConditionOrderException(
'A condition must be called before calling then()'
);
Expand All @@ -66,6 +84,8 @@ public function then($action)
}

self::$finalValue = $action();

self::$finalValueChanged = true;
}

self::$thenCalled = true;
Expand All @@ -75,6 +95,30 @@ public function then($action)
return $this;
}


public function elseIf($condition)
{
if (! self::$thenCalled || self::$elseCalled || self::$elseIfCalled) {
throw new InvalidConditionOrderException(
'At least then() condition must be called before calling elseIf'
);
}

self::$conditionsExists = true;

if (self::$truthy) {
$this->toggleTruthy();

return $this;
}

self::setTruthy($condition);

self::$elseIfCalled = true;

return $this;
}

private function isExceptionClass($action)
{
return is_a($action, \Exception::class);
Expand All @@ -85,6 +129,11 @@ public function value()
return self::$finalValue;
}

private function allowThen()
{
return self::$conditionsExists && (self::$ifCalled || self::$elseIfCalled);
}

protected function canBeCalled($value)
{
return (
Expand All @@ -104,6 +153,9 @@ public function __destruct()
self::$conditionsExists = false;
self::$ifCalled = false;
self::$thenCalled = false;
self::$elseCalled = false;
self::$elseIfCalled = false;
self::$finalValue = null;
self::$finalValueChanged = null;
}
}
80 changes: 80 additions & 0 deletions tests/ConditionalTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,86 @@ public function testThenAndElseAcceptsException()
->else(new TestException('This is still wrong'));
}

public function testElseAfterElseIfConditional()
{
$value = Conditional::if('1' === true)
->then(1)
->elseIf('1' === false)
->then(3)
->else(4)
->value();

$this->assertEquals(4, $value);
}

public function testElseIfCannotBeCalledBeforeThen()
{
$condtional = new Conditional();

$this->expectException(InvalidConditionOrderException::class);

$this->expectExceptionMessage('At least then() condition must be called before calling elseIf');

$condtional->elseIf(true);
}

public function testElseIfCannotBeCalledAfterElse()
{
$this->expectException(InvalidConditionOrderException::class);

$this->expectExceptionMessage('At least then() condition must be called before calling elseIf');

Conditional::if('1' === true)
->then(1)
->elseIf('1' === false)
->then(3)
->else(5)
->elseIf(true)
->then('abc');
}

public function testElseIfBuildsUpAnotherConditional()
{
$conditional = Conditional::if(false);

$conditional2 = $conditional->then(1)
->elseIf(true);

$this->assertEquals($conditional, $conditional2);
$this->assertSame($conditional, $conditional2);

$value = $conditional2->then(3)
->value();

$this->assertEquals(3, $value);
}

public function testElseIfCannotBeChainedWithElseIf()
{
$this->expectException(InvalidConditionOrderException::class);

$this->expectExceptionMessage('At least then() condition must be called before calling elseIf');

Conditional::if('1' === true)
->then(1)
->elseIf('1' === false)
->elseIf(1 === '1')
->value();
}

// public function testIfCannotBeCalledAfterElseIf()
// {
// $this->expectException(InvalidConditionOrderException::class);
//
// $this->expectExceptionMessage('At least then() condition must be called before calling elseIf');
//
// Conditional::if('1' === true)
// ->then(1)
// ->elseIf('1' === false)
// ->if(1 === '1')
// ->value();
// }

private function dump(...$expression)
{
var_dump($expression);
Expand Down

0 comments on commit 57433c2

Please sign in to comment.