updated packages

This commit is contained in:
2019-05-18 09:06:43 +00:00
parent 901d16349e
commit e9487fa58a
2025 changed files with 30366 additions and 49653 deletions
@@ -0,0 +1,63 @@
<?php
namespace PhpOption\Tests;
use PhpOption\None;
use PhpOption\Option;
use PhpOption\Some;
/**
* Tests for Option::ensure() method
*
* @covers Option::ensure
*/
class EnsureTest extends \PHPUnit_Framework_TestCase
{
protected function ensure($value, $noneValue = null)
{
$option = Option::ensure($value, $noneValue);
$this->assertInstanceOf('PhpOption\Option', $option);
return $option;
}
public function testMixedValue()
{
$option = $this->ensure(1);
$this->assertTrue($option->isDefined());
$this->assertSame(1, $option->get());
$this->assertFalse($this->ensure(null)->isDefined());
$this->assertFalse($this->ensure(1,1)->isDefined());
}
public function testReturnValue()
{
$option = $this->ensure(function() { return 1; });
$this->assertTrue($option->isDefined());
$this->assertSame(1, $option->get());
$this->assertFalse($this->ensure(function() { return null; })->isDefined());
$this->assertFalse($this->ensure(function() { return 1; }, 1)->isDefined());
}
public function testOptionReturnsAsSameInstance()
{
$option = $this->ensure(1);
$this->assertSame($option, $this->ensure($option));
}
public function testOptionReturnedFromClosure()
{
$option = $this->ensure(function() { return Some::create(1); });
$this->assertTrue($option->isDefined());
$this->assertSame(1, $option->get());
$option = $this->ensure(function() { return None::create(); });
$this->assertFalse($option->isDefined());
}
public function testClosureReturnedFromClosure()
{
$option = $this->ensure(function() { return function() {}; });
$this->assertTrue($option->isDefined());
$this->assertInstanceOf('Closure', $option->get());
}
}
@@ -0,0 +1,190 @@
<?php
namespace PhpOption\Tests;
use PhpOption\LazyOption;
class LazyOptionTest extends \PHPUnit_Framework_TestCase
{
private $subject;
public function setUp()
{
$this->subject = $this
->getMockBuilder('Subject')
->setMethods(array('execute'))
->getMock();
}
public function testGetWithArgumentsAndConstructor()
{
$some = \PhpOption\LazyOption::create(array($this->subject, 'execute'), array('foo'));
$this->subject
->expects($this->once())
->method('execute')
->with('foo')
->will($this->returnValue(\PhpOption\Some::create('foo')));
$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->assertFalse($some->isEmpty());
}
public function testGetWithArgumentsAndCreate()
{
$some = new \PhpOption\LazyOption(array($this->subject, 'execute'), array('foo'));
$this->subject
->expects($this->once())
->method('execute')
->with('foo')
->will($this->returnValue(\PhpOption\Some::create('foo')));
$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->assertFalse($some->isEmpty());
}
public function testGetWithoutArgumentsAndConstructor()
{
$some = new \PhpOption\LazyOption(array($this->subject, 'execute'));
$this->subject
->expects($this->once())
->method('execute')
->will($this->returnValue(\PhpOption\Some::create('foo')));
$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->assertFalse($some->isEmpty());
}
public function testGetWithoutArgumentsAndCreate()
{
$option = \PhpOption\LazyOption::create(array($this->subject, 'execute'));
$this->subject
->expects($this->once())
->method('execute')
->will($this->returnValue(\PhpOption\Some::create('foo')));
$this->assertTrue($option->isDefined());
$this->assertFalse($option->isEmpty());
$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')));
}
/**
* @expectedException \RuntimeException
* @expectedExceptionMessage None has no value
*/
public function testCallbackReturnsNull()
{
$option = \PhpOption\LazyOption::create(array($this->subject, 'execute'));
$this->subject
->expects($this->once())
->method('execute')
->will($this->returnValue(\PhpOption\None::create()));
$this->assertFalse($option->isDefined());
$this->assertTrue($option->isEmpty());
$this->assertEquals('alt', $option->getOrElse('alt'));
$this->assertEquals('alt', $option->getOrCall(function(){return 'alt';}));
$option->get();
}
/**
* @expectedException \RuntimeException
* @expectedExceptionMessage Expected instance of \PhpOption\Option
*/
public function testExceptionIsThrownIfCallbackReturnsNonOption()
{
$option = \PhpOption\LazyOption::create(array($this->subject, 'execute'));
$this->subject
->expects($this->once())
->method('execute')
->will($this->returnValue(null));
$this->assertFalse($option->isDefined());
}
/**
* @expectedException InvalidArgumentException
* @expectedExceptionMessage Invalid callback given
*/
public function testInvalidCallbackAndConstructor()
{
new \PhpOption\LazyOption('invalidCallback');
}
/**
* @expectedException InvalidArgumentException
* @expectedExceptionMessage Invalid callback given
*/
public function testInvalidCallbackAndCreate()
{
\PhpOption\LazyOption::create('invalidCallback');
}
public function testifDefined()
{
$called = false;
$self = $this;
$this->assertNull(LazyOption::fromValue('foo')->ifDefined(function($v) use (&$called, $self) {
$called = true;
$self->assertEquals('foo', $v);
}));
$this->assertTrue($called);
}
public function testForAll()
{
$called = false;
$self = $this;
$this->assertInstanceOf('PhpOption\Some', LazyOption::fromValue('foo')->forAll(function($v) use (&$called, $self) {
$called = true;
$self->assertEquals('foo', $v);
}));
$this->assertTrue($called);
}
public function testOrElse()
{
$some = \PhpOption\Some::create('foo');
$lazy = \PhpOption\LazyOption::create(function() use ($some) {return $some;});
$this->assertSame($some, $lazy->orElse(\PhpOption\None::create()));
$this->assertSame($some, $lazy->orElse(\PhpOption\Some::create('bar')));
}
public function testFoldLeftRight()
{
$callback = function() { };
$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));
}
}
@@ -0,0 +1,127 @@
<?php
namespace PhpOption\Tests;
use PhpOption\None;
class NoneTest extends \PHPUnit_Framework_TestCase
{
private $none;
/**
* @expectedException \RuntimeException
*/
public function testGet()
{
$none = \PhpOption\None::create();
$none->get();
}
public function testGetOrElse()
{
$none = \PhpOption\None::create();
$this->assertEquals('foo', $none->getOrElse('foo'));
}
public function testGetOrCall()
{
$none = \PhpOption\None::create();
$this->assertEquals('foo', $none->getOrCall(function() { return 'foo'; }));
}
/**
* @expectedException \RuntimeException
* @expectedExceptionMessage Not Found!
*/
public function testGetOrThrow()
{
None::create()->getOrThrow(new \RuntimeException('Not Found!'));
}
public function testIsEmpty()
{
$none = \PhpOption\None::create();
$this->assertTrue($none->isEmpty());
}
public function testOrElse()
{
$option = \PhpOption\Some::create('foo');
$this->assertSame($option, \PhpOption\None::create()->orElse($option));
}
public function testifDefined()
{
$this->assertNull($this->none->ifDefined(function() {
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.');
}));
}
public function testMap()
{
$this->assertSame($this->none, $this->none->map(function() {
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.');
}));
}
public function testFilter()
{
$this->assertSame($this->none, $this->none->filter(function() {
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.');
}));
}
public function testSelect()
{
$this->assertSame($this->none, $this->none->select(null));
}
public function testReject()
{
$this->assertSame($this->none, $this->none->reject(null));
}
public function testForeach()
{
$none = \PhpOption\None::create();
$called = 0;
foreach ($none as $value) {
$called++;
}
$this->assertEquals(0, $called);
}
public function testFoldLeftRight()
{
$this->assertSame(1, $this->none->foldLeft(1, function() { $this->fail(); }));
$this->assertSame(1, $this->none->foldRight(1, function() { $this->fail(); }));
}
protected function setUp()
{
$this->none = None::create();
}
}
@@ -0,0 +1,81 @@
<?php
namespace PhpOption\Tests;
use PhpOption\None;
use PhpOption\Option;
use PhpOption\Some;
class OptionTest extends \PHPUnit_Framework_TestCase
{
public function testfromValueWithDefaultNoneValue()
{
$this->assertInstanceOf('PhpOption\None', \PhpOption\Option::fromValue(null));
$this->assertInstanceOf('PhpOption\Some', \PhpOption\Option::fromValue('value'));
}
public function testFromValueWithFalseNoneValue()
{
$this->assertInstanceOf('PhpOption\None', \PhpOption\Option::fromValue(false, false));
$this->assertInstanceOf('PhpOption\Some', \PhpOption\Option::fromValue('value', false));
$this->assertInstanceOf('PhpOption\Some', \PhpOption\Option::fromValue(null, false));
}
public function testFromArraysValue()
{
$this->assertEquals(None::create(), Option::fromArraysValue('foo', 'bar'));
$this->assertEquals(None::create(), Option::fromArraysValue(null, 'bar'));
$this->assertEquals(None::create(), Option::fromArraysValue(array('foo' => 'bar'), 'baz'));
$this->assertEquals(None::create(), Option::fromArraysValue(array('foo' => null), 'foo'));
$this->assertEquals(new Some('foo'), Option::fromArraysValue(array('foo' => 'foo'), 'foo'));
}
public function testFromReturn()
{
$null = function() { return null; };
$false = function() { return false; };
$some = function() { return 'foo'; };
$this->assertTrue(\PhpOption\Option::fromReturn($null)->isEmpty());
$this->assertFalse(\PhpOption\Option::fromReturn($false)->isEmpty());
$this->assertTrue(\PhpOption\Option::fromReturn($false, array(), false)->isEmpty());
$this->assertTrue(\PhpOption\Option::fromReturn($some)->isDefined());
$this->assertFalse(\PhpOption\Option::fromReturn($some, array(), 'foo')->isDefined());
}
public function testOrElse()
{
$a = new \PhpOption\Some('a');
$b = new \PhpOption\Some('b');
$this->assertEquals('a', $a->orElse($b)->get());
}
public function testOrElseWithNoneAsFirst()
{
$a = \PhpOption\None::create();
$b = new \PhpOption\Some('b');
$this->assertEquals('b', $a->orElse($b)->get());
}
public function testOrElseWithLazyOptions()
{
$throws = function() { throw new \LogicException('Should never be called.'); };
$a = new \PhpOption\Some('a');
$b = new \PhpOption\LazyOption($throws);
$this->assertEquals('a', $a->orElse($b)->get());
}
public function testOrElseWithMultipleAlternatives()
{
$throws = new \PhpOption\LazyOption(function() { throw new \LogicException('Should never be called.'); });
$returns = new \PhpOption\LazyOption(function() { return new \PhpOption\Some('foo'); });
$a = \PhpOption\None::create();
$this->assertEquals('foo', $a->orElse($returns)->orElse($throws)->get());
}
}
@@ -0,0 +1,82 @@
<?php
namespace PhpOption\Tests;
/**
* @group performance
*/
class PerformanceTest extends \PHPUnit_Framework_TestCase
{
private $traditionalRepo;
private $phpOptionRepo;
public function testSomeCase()
{
$traditionalTime = microtime(true);
for ($i=0; $i<10000; $i++) {
if (null === $rs = $this->traditionalRepo->findMaybe(true)) {
$rs = new \stdClass();
}
}
$traditionalTime = microtime(true) - $traditionalTime;
$phpOptionTime = microtime(true);
for ($i=0; $i<10000; $i++) {
$rs = $this->phpOptionRepo->findMaybe(true)->getOrElse(new \stdClass);
}
$phpOptionTime = microtime(true) - $phpOptionTime;
$overheadPerInvocation = ($phpOptionTime - $traditionalTime) / 10000;
printf("Overhead per invocation (some case): %.9fs\n", $overheadPerInvocation);
}
public function testNoneCase()
{
$traditionalTime = microtime(true);
for ($i=0; $i<10000; $i++) {
if (null === $rs = $this->traditionalRepo->findMaybe(false)) {
$rs = new \stdClass();
}
}
$traditionalTime = microtime(true) - $traditionalTime;
$phpOptionTime = microtime(true);
for ($i=0; $i<10000; $i++) {
$rs = $this->phpOptionRepo->findMaybe(false)->getOrElse(new \stdClass);
}
$phpOptionTime = microtime(true) - $phpOptionTime;
$overheadPerInvocation = ($phpOptionTime - $traditionalTime) / 10000;
printf("Overhead per invocation (none case): %.9fs\n", $overheadPerInvocation);
}
protected function setUp()
{
$this->traditionalRepo = new TraditionalRepo();
$this->phpOptionRepo = new PhpOptionRepo();
}
}
class TraditionalRepo
{
public function findMaybe($success)
{
if ($success) {
return new \stdClass;
}
return null;
}
}
class PhpOptionRepo
{
public function findMaybe($success)
{
if ($success) {
return new \PhpOption\Some(new \stdClass);
}
return \PhpOption\None::create();
}
}
@@ -0,0 +1,180 @@
<?php
namespace PhpOption\Tests;
use PhpOption\Some;
class SomeTest extends \PHPUnit_Framework_TestCase
{
public function testGet()
{
$some = new \PhpOption\Some('foo');
$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('Not found')));
$this->assertFalse($some->isEmpty());
}
public function testCreate()
{
$some = \PhpOption\Some::create('foo');
$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('Not found')));
$this->assertFalse($some->isEmpty());
}
public function testOrElse()
{
$some = \PhpOption\Some::create('foo');
$this->assertSame($some, $some->orElse(\PhpOption\None::create()));
$this->assertSame($some, $some->orElse(\PhpOption\Some::create('bar')));
}
public function testifDefined()
{
$called = false;
$self = $this;
$some = new Some('foo');
$this->assertNull($some->ifDefined(function($v) use (&$called, $self) {
$called = true;
$self->assertEquals('foo', $v);
}));
$this->assertTrue($called);
}
public function testForAll()
{
$called = false;
$self = $this;
$some = new Some('foo');
$this->assertSame($some, $some->forAll(function($v) use (&$called, $self) {
$called = true;
$self->assertEquals('foo', $v);
}));
$this->assertTrue($called);
}
public function testMap()
{
$some = new Some('foo');
$this->assertEquals('o', $some->map(function($v) { return substr($v, 1, 1); })->get());
}
public function testFlatMap()
{
$repo = new Repository(array('foo'));
$this->assertEquals(array('name' => 'foo'), $repo->getLastRegisteredUsername()
->flatMap(array($repo, 'getUser'))
->getOrCall(array($repo, 'getDefaultUser')));
}
public function testFilter()
{
$some = new Some('foo');
$this->assertInstanceOf('PhpOption\None', $some->filter(function($v) { return 0 === strlen($v); }));
$this->assertSame($some, $some->filter(function($v) { return strlen($v) > 0; }));
}
public function testFilterNot()
{
$some = new Some('foo');
$this->assertInstanceOf('PhpOption\None', $some->filterNot(function($v) { return strlen($v) > 0; }));
$this->assertSame($some, $some->filterNot(function($v) { return strlen($v) === 0; }));
}
public function testSelect()
{
$some = new Some('foo');
$this->assertSame($some, $some->select('foo'));
$this->assertInstanceOf('PhpOption\None', $some->select('bar'));
$this->assertInstanceOf('PhpOption\None', $some->select(true));
}
public function testReject()
{
$some = new Some('foo');
$this->assertSame($some, $some->reject(null));
$this->assertSame($some, $some->reject(true));
$this->assertInstanceOf('PhpOption\None', $some->reject('foo'));
}
public function testFoldLeftRight()
{
$some = new Some(5);
$this->assertSame(6, $some->foldLeft(1, function($a, $b) {
$this->assertEquals(1, $a);
$this->assertEquals(5, $b);
return $a + $b;
}));
$this->assertSame(6, $some->foldRight(1, function($a, $b) {
$this->assertEquals(1, $b);
$this->assertEquals(5, $a);
return $a + $b;
}));
}
public function testForeach()
{
$some = new Some('foo');
$called = 0;
$extractedValue = null;
foreach ($some as $value) {
$extractedValue = $value;
$called++;
}
$this->assertEquals('foo', $extractedValue);
$this->assertEquals(1, $called);
}
}
// For the interested reader of these tests, we have gone some great lengths
// to come up with a non-contrived example that might also be used in the
// real-world, and not only for testing purposes :)
class Repository
{
private $users;
public function __construct(array $users = array())
{
$this->users = $users;
}
// A fast ID lookup, probably cached, sometimes we might not need the entire user.
public function getLastRegisteredUsername()
{
if (empty($this->users)) {
return \PhpOption\None::create();
}
return new Some(end($this->users));
}
// Returns a user object (we will live with an array here).
public function getUser($name)
{
if (in_array($name, $this->users, true)) {
return new Some(array('name' => $name));
}
return \PhpOption\None::create();
}
public function getDefaultUser()
{
return array('name' => 'muhuhu');
}
}
+8
View File
@@ -0,0 +1,8 @@
<?php
if ( ! is_file($autoloadFile = __DIR__.'/../vendor/autoload.php')) {
echo 'Could not find "vendor/autoload.php". Did you forget to run "composer install --dev"?'.PHP_EOL;
exit(1);
}
require_once $autoloadFile;