166 lines
4.6 KiB
PHP
166 lines
4.6 KiB
PHP
<?php
|
|
/**
|
|
* Copyright 2018 Kacper Donat
|
|
*
|
|
* @author Kacper "Kadet" Donat <kacper@kadet.net>
|
|
*
|
|
* Full license available in separate LICENSE file
|
|
*/
|
|
|
|
use Kadet\Functional as f;
|
|
use const Kadet\Functional\_;
|
|
|
|
class CurriedFunctionTest extends \PHPUnit\Framework\TestCase
|
|
{
|
|
/**
|
|
* @var \Kadet\Functional\Utils\CurriedFunction
|
|
*/
|
|
private $function;
|
|
private $variadic;
|
|
private $optional;
|
|
|
|
protected function setUp()
|
|
{
|
|
$this->function = function ($a, $b, $c, $d) {
|
|
return $a . $b . $c . $d;
|
|
};
|
|
|
|
$this->variadic = function (...$args) {
|
|
return implode('', $args);
|
|
};
|
|
|
|
$this->optional = function($a, $b = 'b', $c = 'c') {
|
|
return $a . $b . $c;
|
|
};
|
|
}
|
|
|
|
public function testCallAfterAllArguments()
|
|
{
|
|
$f = f\curry($this->function);
|
|
|
|
$this->assertSame('abcd', $f('a')('b')('c')('d'));
|
|
$this->assertSame('abcd', $f('a')('b', 'c')('d'));
|
|
$this->assertSame('abcd', $f('a')('b', 'c', 'd'));
|
|
$this->assertSame('abcd', $f('a', 'b')('c', 'd'));
|
|
$this->assertSame('abcd', $f('a', 'b', 'c')('d'));
|
|
$this->assertSame('abcd', $f('a', 'b', 'c', 'd'));
|
|
}
|
|
|
|
public function testPartialApplication()
|
|
{
|
|
$f = f\curry($this->function);
|
|
$g = $f('a', 'b');
|
|
|
|
$this->assertSame(['a', 'b'], $g->getArguments());
|
|
}
|
|
|
|
public function testPartialApplicationWithPlaceholder()
|
|
{
|
|
$f = f\curry($this->function);
|
|
$g = $f('a', _, 'c');
|
|
|
|
$this->assertInstanceOf(f\Utils\PartiallyAppliedFunction::class, $g);
|
|
$this->assertSame([0 => 'a', 2 => 'c'], $g->getArguments());
|
|
$this->assertSame('abcd', $g('b', 'd'));
|
|
}
|
|
|
|
public function testOptionalArgumentsCall()
|
|
{
|
|
$f = f\curry($this->optional);
|
|
|
|
$this->assertSame('abc', $f('a'));
|
|
$this->assertSame('aBc', $f('a', 'B'));
|
|
$this->assertSame('aBC', $f('a', 'B', 'C'));
|
|
}
|
|
|
|
public function testVariadicThreshold()
|
|
{
|
|
$f = f\curry($this->variadic, 3);
|
|
$g = $f('a', _, 'c');
|
|
|
|
$this->assertSame('abc', $f('a', 'b', 'c'));
|
|
|
|
$this->assertInstanceOf(f\Utils\PartiallyAppliedFunction::class, $g);
|
|
$this->assertSame([0 => 'a', 2 => 'c'], $g->getArguments());
|
|
$this->assertSame('abc', $g('b'));
|
|
}
|
|
|
|
public function testForceApply()
|
|
{
|
|
$f = f\curry($this->variadic);
|
|
$g = $f->apply('a', 'b');
|
|
|
|
$this->assertSame('', $f());
|
|
$this->assertSame('abc', $f('a', 'b', 'c'));
|
|
|
|
$this->assertInstanceOf(f\Utils\PartiallyAppliedFunction::class, $g);
|
|
$this->assertSame(['a', 'b'], $g->getArguments());
|
|
$this->assertSame('abc', $g('c'));
|
|
}
|
|
|
|
public function testForceCall()
|
|
{
|
|
$f = f\curry($this->variadic, 10);
|
|
$g = $f->apply('a', 'b');
|
|
|
|
$this->assertSame('', $f->call());
|
|
$this->assertSame('abc', $f->call('a', 'b', 'c'));
|
|
|
|
$this->assertInstanceOf(f\Utils\PartiallyAppliedFunction::class, $g);
|
|
$this->assertSame(['a', 'b'], $g->getArguments());
|
|
$this->assertSame('abc', $g->call('c'));
|
|
}
|
|
|
|
public function testForceCallIfNoArgs()
|
|
{
|
|
$f = f\curry($this->variadic, f\Utils\CurriedFunction::INF);
|
|
|
|
$this->assertSame('abcdef', $f('a', 'b', 'c')('d', 'e')('f')());
|
|
}
|
|
|
|
public function testUncurry()
|
|
{
|
|
$f = f\curry($this->variadic, 10);
|
|
$f = $f('a', 'b');
|
|
$f = $f->uncurry();
|
|
|
|
$this->assertInstanceOf(f\Utils\PartiallyAppliedFunction::class, $f);
|
|
$this->assertSame(['a', 'b'], $f->getArguments());
|
|
$this->assertSame('abc', $f('c'));
|
|
}
|
|
|
|
public function testUncurryAlias()
|
|
{
|
|
$f = f\curry($this->variadic, 10);
|
|
$f = $f('a', 'b');
|
|
$f = f\uncurry($f);
|
|
|
|
$this->assertInstanceOf(f\Utils\PartiallyAppliedFunction::class, $f);
|
|
$this->assertSame(['a', 'b'], $f->getArguments());
|
|
$this->assertSame('abc', $f('c'));
|
|
}
|
|
|
|
public function testThresholdChange()
|
|
{
|
|
$f = f\curry($this->variadic, 10);
|
|
$g = $f->apply('a', 'b')->withThreshold(4);
|
|
|
|
$this->assertSame(4, $g->getThreshold());
|
|
|
|
$this->assertInstanceOf(f\Utils\PartiallyAppliedFunction::class, $g);
|
|
$this->assertInstanceOf(f\Utils\PartiallyAppliedFunction::class, $g('c'));
|
|
$this->assertSame('abcd', $g('c', 'd'));
|
|
}
|
|
|
|
public function testThreshold()
|
|
{
|
|
$f = f\curry($this->function);
|
|
$this->assertSame(4, $f->getThreshold());
|
|
|
|
$g = f\curry($this->optional);
|
|
$this->assertSame(1, $g->getThreshold());
|
|
|
|
$h = f\curry($this->variadic);
|
|
$this->assertSame(0, $h->getThreshold());
|
|
}
|
|
} |