Skip to content

Commit

Permalink
Merge pull request #3 from mister-spock/feature/add-to-string-method
Browse files Browse the repository at this point in the history
Update PHPUnit, add '__toString()' method implementation, add tests
  • Loading branch information
ekatocd authored Jan 19, 2021
2 parents eeb6027 + 755c73a commit a94188b
Show file tree
Hide file tree
Showing 10 changed files with 122 additions and 68 deletions.
4 changes: 2 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
language: php
php:
- 5.6
- 7.0
- 7.4

before_script:
- wget http://getcomposer.org/composer.phar
- php composer.phar install --dev
- php composer.phar install

script:
- phpunit
Expand Down
7 changes: 6 additions & 1 deletion src/PhpOption/LazyOption.php
Original file line number Diff line number Diff line change
Expand Up @@ -161,14 +161,19 @@ public function foldRight($initialValue, $callable)
return $this->option()->foldRight($initialValue, $callable);
}

public function __toString()
{
return is_null($this->option) ? 'LazyOption(...not evaluated...)' : "LazyOption({$this->option})";
}

/**
* @return Option
*/
private function option()
{
if (null === $this->option) {
$this->option = call_user_func_array($this->callback, $this->arguments);
if (!$this->option instanceof Option) {
if (!($this->option instanceof Option)) {
$this->option = null;
throw new \RuntimeException('Expected instance of \PhpOption\Option');
}
Expand Down
4 changes: 4 additions & 0 deletions src/PhpOption/None.php
Original file line number Diff line number Diff line change
Expand Up @@ -136,5 +136,9 @@ public function foldRight($initialValue, $callable)
return $initialValue;
}

public function __toString() {
return "None()";
}

private function __construct() { }
}
6 changes: 6 additions & 0 deletions src/PhpOption/Option.php
Original file line number Diff line number Diff line change
Expand Up @@ -380,4 +380,10 @@ abstract public function foldLeft($initialValue, $callable);
* @return mixed
*/
abstract public function foldRight($initialValue, $callable);

/**
* String representation of the value.
* @return string
*/
abstract public function __toString();
}
10 changes: 10 additions & 0 deletions src/PhpOption/Some.php
Original file line number Diff line number Diff line change
Expand Up @@ -179,4 +179,14 @@ public function foldRight($initialValue, $callable)
{
return call_user_func($callable, $this->value, $initialValue);
}

public function __toString()
{
if (!is_object($this->value)) {
return "Some($this->value)";
}

$object_class = get_class($this->value);
return method_exists($this->value, '__toString') ? "Some({$this->value})" : "Some($object_class(...))";
}
}
64 changes: 31 additions & 33 deletions tests/PhpOption/Tests/LazyOptionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@

namespace PhpOption\Tests;

use stdClass;
use ArrayIterator;
use PhpOption\Some;
use PhpOption\None;
use InvalidArgumentException;
use PhpOption\LazyOption;
use PhpOption\None;
use PhpOption\Option;
use PhpOption\Some;
use RuntimeException;
use stdClass;

class LazyOptionTest extends \PHPUnit_Framework_TestCase
{
Expand All @@ -33,7 +36,7 @@ public function testGetWithArgumentsAndConstructor()
$this->assertEquals('foo', $some->get());
$this->assertEquals('foo', $some->getOrElse(null));
$this->assertEquals('foo', $some->getOrCall('does_not_exist'));
$this->assertEquals('foo', $some->getOrThrow(new \RuntimeException('does_not_exist')));
$this->assertEquals('foo', $some->getOrThrow(new RuntimeException('does_not_exist')));
$this->assertFalse($some->isEmpty());
}

Expand All @@ -50,7 +53,7 @@ public function testGetWithArgumentsAndCreate()
$this->assertEquals('foo', $some->get());
$this->assertEquals('foo', $some->getOrElse(null));
$this->assertEquals('foo', $some->getOrCall('does_not_exist'));
$this->assertEquals('foo', $some->getOrThrow(new \RuntimeException('does_not_exist')));
$this->assertEquals('foo', $some->getOrThrow(new RuntimeException('does_not_exist')));
$this->assertFalse($some->isEmpty());
}

Expand All @@ -66,7 +69,7 @@ public function testGetWithoutArgumentsAndConstructor()
$this->assertEquals('foo', $some->get());
$this->assertEquals('foo', $some->getOrElse(null));
$this->assertEquals('foo', $some->getOrCall('does_not_exist'));
$this->assertEquals('foo', $some->getOrThrow(new \RuntimeException('does_not_exist')));
$this->assertEquals('foo', $some->getOrThrow(new RuntimeException('does_not_exist')));
$this->assertFalse($some->isEmpty());
}

Expand All @@ -84,13 +87,9 @@ public function testGetWithoutArgumentsAndCreate()
$this->assertEquals('foo', $option->get());
$this->assertEquals('foo', $option->getOrElse(null));
$this->assertEquals('foo', $option->getOrCall('does_not_exist'));
$this->assertEquals('foo', $option->getOrThrow(new \RuntimeException('does_not_exist')));
$this->assertEquals('foo', $option->getOrThrow(new RuntimeException('does_not_exist')));
}

/**
* @expectedException \RuntimeException
* @expectedExceptionMessage None has no value
*/
public function testCallbackReturnsNull()
{
$option = LazyOption::create(array($this->subject, 'execute'));
Expand All @@ -105,13 +104,12 @@ public function testCallbackReturnsNull()
$this->assertEquals('alt', $option->getOrElse('alt'));
$this->assertEquals('alt', $option->getOrCall(function(){return 'alt';}));

$this->expectException(RuntimeException::class);
$this->expectExceptionMessage("None has no value");

$option->get();
}

/**
* @expectedException \RuntimeException
* @expectedExceptionMessage Expected instance of \PhpOption\Option
*/
public function testExceptionIsThrownIfCallbackReturnsNonOption()
{
$option = LazyOption::create(array($this->subject, 'execute'));
Expand All @@ -121,24 +119,23 @@ public function testExceptionIsThrownIfCallbackReturnsNonOption()
->method('execute')
->will($this->returnValue(null));

$this->expectException(RuntimeException::class);
$this->expectExceptionMessage("Expected instance of \PhpOption\Option");

$this->assertFalse($option->isDefined());
}

/**
* @expectedException \InvalidArgumentException
* @expectedExceptionMessage Invalid callback given
*/
public function testInvalidCallbackAndConstructor()
{
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage("Invalid callback given");
new LazyOption('invalidCallback');
}

/**
* @expectedException \InvalidArgumentException
* @expectedExceptionMessage Invalid callback given
*/
public function testInvalidCallbackAndCreate()
{
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage("Invalid callback given");
LazyOption::create('invalidCallback');
}

Expand Down Expand Up @@ -174,20 +171,12 @@ public function testOrElse()

public function testFoldLeftRight()
{
$callback = function() { };
$option = Option::fromValue(5);
$callback = function($i) { return $i + 1; };

$option = $this->getMockForAbstractClass('PhpOption\Option');
$option->expects($this->once())
->method('foldLeft')
->with(5, $callback)
->will($this->returnValue(6));
$lazyOption = new LazyOption(function() use ($option) { return $option; });
$this->assertSame(6, $lazyOption->foldLeft(5, $callback));

$option->expects($this->once())
->method('foldRight')
->with(5, $callback)
->will($this->returnValue(6));
$lazyOption = new LazyOption(function() use ($option) { return $option; });
$this->assertSame(6, $lazyOption->foldRight(5, $callback));
}
Expand All @@ -204,4 +193,13 @@ public function testFilterIsOneOf()
$this->assertSame($some, $lazy_opt->filterIsOneOf([stdClass::class, 'unknown']));
$this->assertSame($some, $lazy_opt->filterIsOneOf(new ArrayIterator([stdClass::class, 'unknown'])));
}

public function testToString()
{
$lazy_opt = LazyOption::create(function() { return Option::fromValue(1); });

$this->assertEquals('LazyOption(...not evaluated...)', $lazy_opt->__toString());
$lazy_opt->getOrElse(0);
$this->assertEquals('LazyOption(Some(1))', $lazy_opt->__toString());
}
}
28 changes: 13 additions & 15 deletions tests/PhpOption/Tests/NoneTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,19 @@

namespace PhpOption\Tests;

use stdClass;
use LogicException;
use PhpOption\None;
use PhpOption\Some;
use RuntimeException;
use stdClass;

class NoneTest extends \PHPUnit_Framework_TestCase
{
private $none;

/**
* @expectedException \RuntimeException
*/
public function testGet()
{
$this->expectException(RuntimeException::class);
$none = None::create();
$none->get();
}
Expand All @@ -31,13 +31,11 @@ public function testGetOrCall()
$this->assertEquals('foo', $none->getOrCall(function() { return 'foo'; }));
}

/**
* @expectedException \RuntimeException
* @expectedExceptionMessage Not Found!
*/
public function testGetOrThrow()
{
None::create()->getOrThrow(new \RuntimeException('Not Found!'));
$this->expectException(RuntimeException::class);
$this->expectExceptionMessage("Not Found!");
None::create()->getOrThrow(new RuntimeException('Not Found!'));
}

public function testIsEmpty()
Expand All @@ -55,42 +53,42 @@ public function testOrElse()
public function testifDefined()
{
$this->assertNull($this->none->ifDefined(function() {
throw new \LogicException('Should never be called.');
throw new LogicException('Should never be called.');
}));
}

public function testForAll()
{
$this->assertSame($this->none, $this->none->forAll(function() {
throw new \LogicException('Should never be called.');
throw new LogicException('Should never be called.');
}));
}

public function testMap()
{
$this->assertSame($this->none, $this->none->map(function() {
throw new \LogicException('Should not be called.');
throw new LogicException('Should not be called.');
}));
}

public function testFlatMap()
{
$this->assertSame($this->none, $this->none->flatMap(function() {
throw new \LogicException('Should not be called.');
throw new LogicException('Should not be called.');
}));
}

public function testFilter()
{
$this->assertSame($this->none, $this->none->filter(function() {
throw new \LogicException('Should not be called.');
throw new LogicException('Should not be called.');
}));
}

public function testFilterNot()
{
$this->assertSame($this->none, $this->none->filterNot(function() {
throw new \LogicException('Should not be called.');
throw new LogicException('Should not be called.');
}));
}

Expand Down
11 changes: 6 additions & 5 deletions tests/PhpOption/Tests/OptionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@

namespace PhpOption\Tests;

use LogicException;
use PhpOption\LazyOption;
use PhpOption\None;
use PhpOption\Some;
use PhpOption\Option;
use PhpOption\LazyOption;
use PhpOption\Some;

class OptionTest extends \PHPUnit_Framework_TestCase
{
Expand Down Expand Up @@ -62,7 +63,7 @@ public function testOrElseWithNoneAsFirst()

public function testOrElseWithLazyOptions()
{
$throws = function() { throw new \LogicException('Should never be called.'); };
$throws = function() { throw new LogicException('Should never be called.'); };

$a = new Some('a');
$b = new LazyOption($throws);
Expand All @@ -72,11 +73,11 @@ public function testOrElseWithLazyOptions()

public function testOrElseWithMultipleAlternatives()
{
$throws = new LazyOption(function() { throw new \LogicException('Should never be called.'); });
$throws = new LazyOption(function() { throw new LogicException('Should never be called.'); });
$returns = new LazyOption(function() { return new Some('foo'); });

$a = None::create();

$this->assertEquals('foo', $a->orElse($returns)->orElse($throws)->get());
}
}
}
Loading

0 comments on commit a94188b

Please sign in to comment.