2019-12-24 01:52:07 +01:00
|
|
|
<?php
|
|
|
|
|
|
|
|
declare(strict_types=1);
|
|
|
|
|
|
|
|
namespace Psl\Tests\Collection;
|
|
|
|
|
|
|
|
use PHPUnit\Framework\TestCase;
|
2019-12-25 22:45:52 +01:00
|
|
|
use Psl\Collection;
|
|
|
|
use Psl\Exception;
|
|
|
|
use Psl\Iter;
|
|
|
|
use Psl\Str;
|
2019-12-24 01:52:07 +01:00
|
|
|
|
|
|
|
class MapTest extends TestCase
|
|
|
|
{
|
|
|
|
public function testAdd(): void
|
|
|
|
{
|
2019-12-25 22:45:52 +01:00
|
|
|
$map = new Collection\Map(['foo' => 1, 'bar' => 2]);
|
|
|
|
self::assertCount(2, $map);
|
|
|
|
|
|
|
|
$map->add(new Collection\Pair('baz', 3));
|
|
|
|
self::assertCount(3, $map);
|
|
|
|
self::assertTrue($map->contains('baz'));
|
|
|
|
|
|
|
|
$map->add(new Collection\Pair('qux', 4));
|
|
|
|
self::assertCount(4, $map);
|
|
|
|
self::assertTrue($map->contains('qux'));
|
2019-12-24 01:52:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public function testAddAll(): void
|
|
|
|
{
|
2019-12-25 22:45:52 +01:00
|
|
|
$map = new Collection\Map(['foo' => 1, 'bar' => 2]);
|
|
|
|
self::assertCount(2, $map);
|
|
|
|
|
|
|
|
$map->addAll([
|
|
|
|
new Collection\Pair('baz', 3),
|
|
|
|
new Collection\Pair('qux', 4)
|
|
|
|
]);
|
|
|
|
|
|
|
|
self::assertCount(4, $map);
|
|
|
|
self::assertTrue($map->contains('baz'));
|
|
|
|
self::assertTrue($map->contains('qux'));
|
2019-12-24 01:52:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public function testClear(): void
|
|
|
|
{
|
2019-12-25 22:45:52 +01:00
|
|
|
$map = new Collection\Map(['foo' => 1, 'bar' => 2]);
|
|
|
|
$map->clear();
|
|
|
|
|
|
|
|
self::assertCount(0, $map);
|
|
|
|
|
|
|
|
$map = new Collection\Map([]);
|
|
|
|
$map->clear();
|
|
|
|
self::assertCount(0, $map);
|
2019-12-24 01:52:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public function testItems(): void
|
|
|
|
{
|
2019-12-25 22:45:52 +01:00
|
|
|
$map = new Collection\Map(['foo' => 1, 'bar' => 2]);
|
|
|
|
|
|
|
|
$items = $map->items();
|
|
|
|
|
|
|
|
self::assertSame(2, $items->count());
|
|
|
|
|
|
|
|
self::assertSame('foo', $items->at(0)->first());
|
|
|
|
self::assertSame(1, $items->at(0)->last());
|
|
|
|
|
|
|
|
self::assertSame('bar', $items->at(1)->first());
|
|
|
|
self::assertSame(2, $items->at(1)->last());
|
2019-12-24 01:52:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public function testIsEmpty(): void
|
|
|
|
{
|
2019-12-25 22:45:52 +01:00
|
|
|
$map = new Collection\Map(['foo' => 1, 'bar' => 2]);
|
|
|
|
|
|
|
|
self::assertFalse($map->isEmpty());
|
|
|
|
|
|
|
|
$map = $map->filter(fn ($v) => false);
|
|
|
|
|
|
|
|
self::assertTrue($map->isEmpty());
|
2019-12-24 01:52:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public function testCount(): void
|
|
|
|
{
|
2019-12-25 22:45:52 +01:00
|
|
|
$map = new Collection\Map(['foo' => 1, 'bar' => 2]);
|
|
|
|
self::assertCount(2, $map);
|
|
|
|
|
|
|
|
$map = $map->filter(fn ($v) => 1 === $v);
|
|
|
|
self::assertCount(1, $map);
|
|
|
|
|
|
|
|
$map = $map->filter(fn ($v) => false);
|
|
|
|
self::assertCount(0, $map);
|
2019-12-24 01:52:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public function testToArray(): void
|
|
|
|
{
|
2019-12-25 22:45:52 +01:00
|
|
|
$map = new Collection\Map(['foo' => 1, 'bar' => 2]);
|
|
|
|
$array = $map->toArray();
|
|
|
|
|
|
|
|
self::assertArrayHasKey('foo', $array);
|
|
|
|
self::assertArrayHasKey('bar', $array);
|
|
|
|
|
|
|
|
self::assertSame(1, $array['foo']);
|
|
|
|
self::assertSame(2, $array['bar']);
|
|
|
|
|
|
|
|
$map = $map->filter(fn ($v) => false);
|
|
|
|
$array = $map->toArray();
|
|
|
|
|
|
|
|
self::assertEmpty($array);
|
2019-12-24 01:52:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public function testAt(): void
|
|
|
|
{
|
2019-12-25 22:45:52 +01:00
|
|
|
$map = new Collection\Map(['foo' => 1, 'bar' => 2]);
|
|
|
|
|
|
|
|
self::assertSame(1, $map->at('foo'));
|
|
|
|
self::assertSame(2, $map->at('bar'));
|
|
|
|
|
|
|
|
$this->expectException(Exception\InvariantViolationException::class);
|
|
|
|
$this->expectExceptionMessage('Key (baz) is out-of-bound.');
|
|
|
|
|
|
|
|
$map->at('baz');
|
2019-12-24 01:52:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public function testContainsKey(): void
|
|
|
|
{
|
2019-12-25 22:45:52 +01:00
|
|
|
$map = new Collection\Map(['foo' => 1, 'bar' => 2, 'baz' => null]);
|
|
|
|
|
|
|
|
self::assertTrue($map->containsKey('foo'));
|
|
|
|
self::assertTrue($map->containsKey('bar'));
|
|
|
|
self::assertTrue($map->containsKey('baz'));
|
|
|
|
self::assertFalse($map->containsKey('qux'));
|
2019-12-24 01:52:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public function testGet(): void
|
|
|
|
{
|
2019-12-25 22:45:52 +01:00
|
|
|
$map = new Collection\Map(['foo' => 1, 'bar' => 2]);
|
|
|
|
|
|
|
|
self::assertSame(1, $map->get('foo'));
|
|
|
|
self::assertSame(2, $map->get('bar'));
|
|
|
|
self::assertNull($map->get('baz'));
|
2019-12-24 01:52:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public function testContains(): void
|
|
|
|
{
|
2019-12-25 22:45:52 +01:00
|
|
|
$map = new Collection\Map(['foo' => 1, 'bar' => 2, 'baz' => null]);
|
|
|
|
|
|
|
|
self::assertTrue($map->contains('foo'));
|
|
|
|
self::assertTrue($map->contains('bar'));
|
|
|
|
self::assertTrue($map->contains('baz'));
|
|
|
|
self::assertFalse($map->contains('qux'));
|
2019-12-24 01:52:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public function testValues(): void
|
|
|
|
{
|
2019-12-25 22:45:52 +01:00
|
|
|
$map = new Collection\Map(['foo' => 1, 'bar' => 2, 'baz' => null]);
|
|
|
|
$values = $map->values();
|
|
|
|
|
|
|
|
self::assertCount(3, $values);
|
|
|
|
self::assertSame(1, $values->at(0));
|
|
|
|
self::assertSame(2, $values->at(1));
|
|
|
|
self::assertNull($values->at(2));
|
2019-12-24 01:52:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public function testKeys(): void
|
|
|
|
{
|
2019-12-25 22:45:52 +01:00
|
|
|
$map = new Collection\Map(['foo' => 1, 'bar' => 2, 'baz' => null]);
|
|
|
|
$keys = $map->keys();
|
|
|
|
|
|
|
|
self::assertCount(3, $keys);
|
|
|
|
self::assertSame('foo', $keys->at(0));
|
|
|
|
self::assertSame('bar', $keys->at(1));
|
|
|
|
self::assertSame('baz', $keys->at(2));
|
2019-12-24 01:52:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public function testMap(): void
|
|
|
|
{
|
2019-12-25 22:45:52 +01:00
|
|
|
$map = new Collection\Map(['foo' => 1, 'bar' => 2, 'baz' => 3]);
|
|
|
|
|
|
|
|
$map = $map->map(fn ($value) => $value * 2);
|
|
|
|
self::assertSame(2, $map->at('foo'));
|
|
|
|
self::assertSame(4, $map->at('bar'));
|
|
|
|
self::assertSame(6, $map->at('baz'));
|
2019-12-24 01:52:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public function testMapWithKey(): void
|
|
|
|
{
|
2019-12-25 22:45:52 +01:00
|
|
|
$map = new Collection\Map(['foo' => 1, 'bar' => 2, 'baz' => 3]);
|
|
|
|
|
|
|
|
$map = $map->mapWithKey(fn ($key, $value) => Str\format('%s (%d)', $key, $value));
|
|
|
|
self::assertSame('foo (1)', $map->at('foo'));
|
|
|
|
self::assertSame('bar (2)', $map->at('bar'));
|
|
|
|
self::assertSame('baz (3)', $map->at('baz'));
|
2019-12-24 01:52:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public function testFilter(): void
|
|
|
|
{
|
2019-12-25 22:45:52 +01:00
|
|
|
$map = new Collection\Map(['foo' => 1, 'bar' => 2, 'baz' => 3]);
|
|
|
|
|
|
|
|
$map = $map->filter(fn ($value) => $value >= 2);
|
|
|
|
self::assertCount(2, $map);
|
|
|
|
|
|
|
|
self::assertFalse($map->contains('foo'));
|
|
|
|
self::assertTrue($map->contains('bar'));
|
|
|
|
self::assertTrue($map->contains('baz'));
|
2019-12-24 01:52:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public function testFilterWithKey(): void
|
|
|
|
{
|
2019-12-25 22:45:52 +01:00
|
|
|
$map = new Collection\Map(['foo' => 1, 'bar' => 2, 'baz' => 3]);
|
|
|
|
|
|
|
|
$map = $map->filterWithKey(fn ($key, $value) => $value >= 2 && 'baz' !== $key);
|
|
|
|
self::assertCount(1, $map);
|
|
|
|
|
|
|
|
self::assertFalse($map->contains('foo'));
|
|
|
|
self::assertTrue($map->contains('bar'));
|
|
|
|
self::assertFalse($map->contains('baz'));
|
2019-12-24 01:52:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public function testZip(): void
|
|
|
|
{
|
2019-12-25 22:45:52 +01:00
|
|
|
$map = new Collection\Map(['foo' => 1, 'bar' => 2, 'baz' => 3, 'qux' => 4]);
|
|
|
|
|
|
|
|
$map = $map->zip(['one', 'two', 'three']);
|
|
|
|
|
|
|
|
/** @var Collection\Pair $foo */
|
|
|
|
$foo = $map->at('foo');
|
|
|
|
self::assertInstanceOf(Collection\Pair::class, $foo);
|
|
|
|
self::assertSame(1, $foo->first());
|
|
|
|
self::assertSame('one', $foo->last());
|
|
|
|
|
|
|
|
/** @var Collection\Pair $bar */
|
|
|
|
$bar = $map->at('bar');
|
|
|
|
self::assertInstanceOf(Collection\Pair::class, $bar);
|
|
|
|
self::assertSame(2, $bar->first());
|
|
|
|
self::assertSame('two', $bar->last());
|
|
|
|
|
|
|
|
/** @var Collection\Pair $baz */
|
|
|
|
$baz = $map->at('baz');
|
|
|
|
self::assertInstanceOf(Collection\Pair::class, $baz);
|
|
|
|
self::assertSame(3, $baz->first());
|
|
|
|
self::assertSame('three', $baz->last());
|
2019-12-24 01:52:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public function testTake(): void
|
|
|
|
{
|
2019-12-25 22:45:52 +01:00
|
|
|
$map = new Collection\Map(['foo' => 1, 'bar' => 2, 'baz' => 3]);
|
|
|
|
|
|
|
|
$map = $map->take(2);
|
|
|
|
|
|
|
|
self::assertCount(2, $map);
|
|
|
|
self::assertTrue($map->contains('foo'));
|
|
|
|
self::assertTrue($map->contains('bar'));
|
|
|
|
self::assertFalse($map->contains('baz'));
|
2019-12-24 01:52:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public function testTakeWhile(): void
|
|
|
|
{
|
2019-12-25 22:45:52 +01:00
|
|
|
$map = new Collection\Map(['foo' => 1, 'bar' => 2, 'baz' => 3]);
|
|
|
|
|
|
|
|
$map = $map->takeWhile(fn ($v) => 2 !== $v);
|
|
|
|
|
|
|
|
self::assertCount(1, $map);
|
|
|
|
self::assertTrue($map->contains('foo'));
|
|
|
|
self::assertFalse($map->contains('bar'));
|
|
|
|
self::assertFalse($map->contains('baz'));
|
2019-12-24 01:52:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public function testDrop(): void
|
|
|
|
{
|
2019-12-25 22:45:52 +01:00
|
|
|
$map = new Collection\Map(['foo' => 1, 'bar' => 2, 'baz' => 3]);
|
|
|
|
|
|
|
|
$map = $map->drop(1);
|
|
|
|
|
|
|
|
self::assertCount(2, $map);
|
|
|
|
self::assertFalse($map->contains('foo'));
|
|
|
|
self::assertTrue($map->contains('bar'));
|
|
|
|
self::assertTrue($map->contains('baz'));
|
2019-12-24 01:52:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public function testDropWhile(): void
|
|
|
|
{
|
2019-12-25 22:45:52 +01:00
|
|
|
$map = new Collection\Map(['foo' => 1, 'bar' => 2, 'baz' => 3]);
|
|
|
|
|
|
|
|
$map = $map->dropWhile(fn ($value) => 3 !== $value);
|
|
|
|
|
|
|
|
self::assertCount(1, $map);
|
|
|
|
self::assertFalse($map->contains('foo'));
|
|
|
|
self::assertFalse($map->contains('bar'));
|
|
|
|
self::assertTrue($map->contains('baz'));
|
2019-12-24 01:52:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public function testSlice(): void
|
|
|
|
{
|
2019-12-25 22:45:52 +01:00
|
|
|
$map = new Collection\Map(['foo' => 1, 'bar' => 2, 'baz' => 3, 'qux' => 4]);
|
|
|
|
|
|
|
|
$map = $map->slice(2, 1);
|
|
|
|
|
|
|
|
self::assertCount(1, $map);
|
|
|
|
self::assertFalse($map->contains('foo'));
|
|
|
|
self::assertFalse($map->contains('bar'));
|
|
|
|
self::assertTrue($map->contains('baz'));
|
|
|
|
self::assertFalse($map->contains('qux'));
|
|
|
|
|
|
|
|
$map = $map->slice(0, 0);
|
|
|
|
|
|
|
|
self::assertCount(0, $map);
|
2019-12-24 01:52:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public function testConcat(): void
|
|
|
|
{
|
2019-12-25 22:45:52 +01:00
|
|
|
$map = new Collection\Map(['foo' => 1, 'bar' => 2, 'baz' => 3, 'qux' => 4]);
|
|
|
|
$vector = $map->concat([5, 6, 7, 8, 9, 10]);
|
|
|
|
|
|
|
|
self::assertCount(10, $vector);
|
|
|
|
self::assertSame([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], $vector->toArray());
|
2019-12-24 01:52:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public function testFirst(): void
|
|
|
|
{
|
2019-12-25 22:45:52 +01:00
|
|
|
$map = new Collection\Map(['foo' => 1, 'bar' => 2, 'baz' => 3, 'qux' => 4]);
|
|
|
|
|
|
|
|
self::assertSame(1, $map->first());
|
|
|
|
|
|
|
|
$map = new Collection\Map([]);
|
|
|
|
|
|
|
|
self::assertNull($map->first());
|
2019-12-24 01:52:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public function testFirstKey(): void
|
|
|
|
{
|
2019-12-25 22:45:52 +01:00
|
|
|
$map = new Collection\Map(['foo' => 1, 'bar' => 2, 'baz' => 3, 'qux' => 4]);
|
|
|
|
|
|
|
|
self::assertSame('foo', $map->firstKey());
|
|
|
|
|
|
|
|
$map = new Collection\Map([]);
|
|
|
|
|
|
|
|
self::assertNull($map->firstKey());
|
2019-12-24 01:52:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public function testLast(): void
|
|
|
|
{
|
2019-12-25 22:45:52 +01:00
|
|
|
$map = new Collection\Map(['foo' => 1, 'bar' => 2, 'baz' => 3, 'qux' => 4]);
|
|
|
|
|
|
|
|
self::assertSame(4, $map->last());
|
|
|
|
|
|
|
|
$map = new Collection\Map([]);
|
|
|
|
|
|
|
|
self::assertNull($map->last());
|
2019-12-24 01:52:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public function testLastKey(): void
|
|
|
|
{
|
2019-12-25 22:45:52 +01:00
|
|
|
$map = new Collection\Map(['foo' => 1, 'bar' => 2, 'baz' => 3, 'qux' => 4]);
|
2019-12-24 01:52:07 +01:00
|
|
|
|
2019-12-25 22:45:52 +01:00
|
|
|
self::assertSame('qux', $map->lastKey());
|
|
|
|
|
|
|
|
$map = new Collection\Map([]);
|
|
|
|
|
|
|
|
self::assertNull($map->lastKey());
|
2019-12-24 01:52:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public function testDifferenceByKey(): void
|
|
|
|
{
|
2019-12-25 22:45:52 +01:00
|
|
|
$map = new Collection\Map(['foo' => 1, 'bar' => 2, 'baz' => 3, 'qux' => 4]);
|
|
|
|
|
|
|
|
$map = $map->differenceByKey(['foo' => 5, 'baz' => 6]);
|
|
|
|
|
|
|
|
self::assertFalse($map->contains('foo'));
|
|
|
|
self::assertTrue($map->contains('bar'));
|
|
|
|
self::assertFalse($map->contains('baz'));
|
|
|
|
self::assertTrue($map->contains('qux'));
|
2019-12-24 01:52:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public function testImmutable(): void
|
|
|
|
{
|
2019-12-25 22:45:52 +01:00
|
|
|
$map = new Collection\Map(['foo' => 1, 'bar' => 2, 'baz' => 3, 'qux' => 4]);
|
|
|
|
$immutable = $map->immutable();
|
|
|
|
|
|
|
|
self::assertSame($map->toArray(), $immutable->toArray());
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testGetIterator(): void
|
|
|
|
{
|
|
|
|
$map = new Collection\Map(['foo' => 1, 'bar' => 2, 'baz' => 3, 'qux' => 4]);
|
|
|
|
|
|
|
|
$iterator = $map->getIterator();
|
|
|
|
self::assertInstanceOf(Iter\Iterator::class, $iterator);
|
|
|
|
|
|
|
|
$array = \iterator_to_array($iterator);
|
|
|
|
self::assertSame(['foo' => 1, 'bar' => 2, 'baz' => 3, 'qux' => 4], $array);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testRemove(): void
|
|
|
|
{
|
|
|
|
$map = new Collection\Map(['foo' => 1, 'bar' => 2, 'baz' => 3, 'qux' => 4]);
|
|
|
|
|
|
|
|
$map->remove('foo');
|
|
|
|
|
|
|
|
self::assertFalse($map->contains('foo'));
|
2019-12-24 01:52:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public function testSet(): void
|
|
|
|
{
|
2019-12-25 22:45:52 +01:00
|
|
|
$map = new Collection\Map(['foo' => 1, 'bar' => 2, 'baz' => 3]);
|
|
|
|
|
|
|
|
$map->set('foo', 5);
|
|
|
|
|
|
|
|
self::assertSame(5, $map->get('foo'));
|
|
|
|
|
|
|
|
$map->set('qux', 4);
|
|
|
|
self::assertTrue($map->contains('qux'));
|
|
|
|
self::assertSame(4, $map->get('qux'));
|
2019-12-24 01:52:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public function testSetAll(): void
|
|
|
|
{
|
2019-12-25 22:45:52 +01:00
|
|
|
$map = new Collection\Map(['foo' => 1, 'bar' => 2, 'baz' => 3]);
|
|
|
|
|
|
|
|
$map->setAll(['foo' => 5, 'qux' => 4]);
|
|
|
|
|
|
|
|
self::assertSame(5, $map->get('foo'));
|
|
|
|
self::assertTrue($map->contains('qux'));
|
|
|
|
self::assertSame(4, $map->get('qux'));
|
2019-12-24 01:52:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public function testRemoveKey(): void
|
|
|
|
{
|
2019-12-25 22:45:52 +01:00
|
|
|
$map = new Collection\Map(['foo' => 1, 'bar' => 2, 'baz' => 3, 'qux' => 4]);
|
2019-12-24 01:52:07 +01:00
|
|
|
|
2019-12-25 22:45:52 +01:00
|
|
|
$map->removeKey('foo');
|
|
|
|
|
|
|
|
self::assertFalse($map->contains('foo'));
|
2019-12-24 01:52:07 +01:00
|
|
|
}
|
|
|
|
}
|