* * 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()); } }