109 lines
3.2 KiB
PHP
109 lines
3.2 KiB
PHP
<?php
|
|
/**
|
|
* Copyright 2026 Kacper Donat
|
|
*
|
|
* @author Kacper "Kadet" Donat <kacper@kadet.net>
|
|
*
|
|
* Full license available in separate LICENSE file
|
|
*/
|
|
|
|
use Ds\Map;
|
|
use Ds\Seq;
|
|
use Ds\Set;
|
|
use Kadet\Functional\Collections as c;
|
|
|
|
class CollectorsTest extends \PHPUnit\Framework\TestCase
|
|
{
|
|
private static function gen(iterable $entries): \Generator
|
|
{
|
|
foreach ($entries as $key => $value) {
|
|
yield $key => $value;
|
|
}
|
|
}
|
|
|
|
public function testKeyByLastWins()
|
|
{
|
|
$map = c\keyBy(fn ($v) => $v['id'])([['id' => 1, 'n' => 'a'], ['id' => 2, 'n' => 'b'], ['id' => 1, 'n' => 'c']]);
|
|
|
|
$this->assertInstanceOf(Map::class, $map);
|
|
$this->assertSame(2, $map->count());
|
|
$this->assertSame('c', $map->get(1)['n']);
|
|
$this->assertSame([1, 2], $map->keys()->toArray());
|
|
}
|
|
|
|
public function testKeyBySelectorReceivesKey()
|
|
{
|
|
$map = c\keyBy(fn ($v, $k) => $k . $v)(['a' => 'x']);
|
|
|
|
$this->assertSame(['ax' => 'x'], $map->toArray());
|
|
}
|
|
|
|
public function testKeyByAcceptsInternalFunction()
|
|
{
|
|
$this->assertSame(['A' => 'a'], c\keyBy(strtoupper(...))(['a'])->toArray());
|
|
}
|
|
|
|
public function testGroupByKeepsOrderAndUsesSeq()
|
|
{
|
|
$map = c\groupBy(fn ($v) => $v % 2)([1, 2, 3, 4]);
|
|
|
|
$this->assertEquals(new Map([1 => new Seq([1, 3]), 0 => new Seq([2, 4])]), $map);
|
|
$this->assertSame([1, 0], $map->keys()->toArray());
|
|
$this->assertInstanceOf(Seq::class, $map->get(1));
|
|
}
|
|
|
|
public function testToSeqDropsKeys()
|
|
{
|
|
$this->assertSame([1, 2], c\toSeq()(['a' => 1, 'b' => 2])->toArray());
|
|
}
|
|
|
|
public function testToMapPreservesGeneratorKeys()
|
|
{
|
|
$key = new \stdClass();
|
|
$map = c\toMap()((static function () use ($key) {
|
|
yield 'a' => 1;
|
|
yield 5 => 2;
|
|
yield $key => 3;
|
|
})());
|
|
|
|
$this->assertInstanceOf(Map::class, $map);
|
|
$this->assertSame(1, $map->get('a'));
|
|
$this->assertSame(2, $map->get(5));
|
|
$this->assertSame(3, $map->get($key));
|
|
}
|
|
|
|
public function testToSet()
|
|
{
|
|
$set = c\toSet()(['a' => 1, 'b' => 1, 'c' => 2]);
|
|
|
|
$this->assertInstanceOf(Set::class, $set);
|
|
$this->assertSame([1, 2], $set->toArray());
|
|
}
|
|
|
|
public function testToArrayPreservesKeys()
|
|
{
|
|
$this->assertSame(['a' => 1, 5 => 2], c\toArray()(self::gen(['a' => 1, 5 => 2])));
|
|
$this->assertSame(['a' => 1], c\toArray()(new Map(['a' => 1])));
|
|
$this->assertSame([1, 2], c\toArray()(new Seq([1, 2])));
|
|
}
|
|
|
|
public function testToArrayRejectsObjectKeys()
|
|
{
|
|
$this->expectException(\InvalidArgumentException::class);
|
|
$this->expectExceptionMessage('toArray(): key of type stdClass cannot be an array key');
|
|
|
|
$map = new Map();
|
|
$map->put(new \stdClass(), 1);
|
|
|
|
c\toArray()($map);
|
|
}
|
|
|
|
public function testCollectorsAcceptLazyInput()
|
|
{
|
|
$map = c\keyBy(fn ($v) => $v * 10)(self::gen([1, 2]));
|
|
|
|
$this->assertSame([10 => 1, 20 => 2], $map->toArray());
|
|
$this->assertSame([0 => [1, 3], 1 => [2, 4]], c\groupBy(fn ($v) => $v % 2 ? 0 : 1)(self::gen([1, 2, 3, 4]))->map(fn ($k, $v) => $v->toArray())->toArray());
|
|
}
|
|
}
|