functional-php/tests/PartialApplicationTest.php

114 lines
2.9 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\_;
function subtract($a, $b) {
return $a - $b;
}
class PartialApplicationTest extends \PHPUnit\Framework\TestCase
{
public function testPartialApplicationOfOneArgument()
{
$applied = f\partial('subtract', 10);
$this->assertEquals(0, $applied(10));
$this->assertEquals(10, $applied(0));
$this->assertEquals(20, $applied(-10));
}
public function testPartialApplicationOfAllArguments()
{
$applied = f\partial('subtract', 10, 20);
$this->assertEquals(-10, $applied());
}
public function testPartialApplicationOfFewArguments()
{
$applied = f\partial('array_merge', ['a'], ['b'], ['c']);
$this->assertEquals(['a', 'b', 'c', 'd', 'e'], $applied(['d'], ['e']));
}
public function testPartialApplicationWithPlaceholders()
{
$applied = f\partial('array_merge', ['a'], _, ['c']);
$this->assertEquals(['a', 'd', 'c'], $applied(['d']));
}
public function testPartialApplicationOfAppliedFunction()
{
$applied = f\partial('array_merge', ['a'], _, ['c']);
$double = f\partial($applied, _, ['d']);
$this->assertEquals(['a', 'b', 'c', 'd', 'e'], $double(['b'], ['e']));
}
public function testDecoration()
{
$x = function() {};
$applied = f\partial($x);
$this->assertSame($applied->getDecorated(), $x);
}
public function testArgumentProviding()
{
$applied = f\partial('array_merge', ['a'], _, ['c']);
$this->assertSame(
[0 => ['a'], 2 => ['c']],
$applied->getArguments()
);
}
public function testYCombinator()
{
$applied = f\fix(function ($f) use (&$applied) {
$this->assertSame($f, $applied);
return function ($x) {
$this->assertEquals(1, $x);
};
});
$applied(1);
}
public function testYCombinatorFactorial()
{
$applied = f\fix(function ($f) {
return function ($x) use ($f) { return $x >= 2 ? $f($x-1) * $x : 1; };
});
$this->assertEquals(6, $applied(3));
$this->assertEquals(24, $applied(4));
}
public function testYCombinatorCurried()
{
$applied = f\fix(f\curry(function ($f, $x) { return $x >= 2 ? $f($x-1) * $x : 1; }));
$this->assertEquals(6, $applied(3));
$this->assertEquals(24, $applied(4));
}
public function testPartialApplicationOfAppliedFunctionWithPlaceholders()
{
$applied = f\partial('array_merge', _, _, ['c']);
$double = f\partial($applied, ['a']);
$this->assertEquals(['a', 'b', 'c', 'd'], $double(['b'], ['d']));
}
}