Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@
"require-dev": {
"squizlabs/php_codesniffer": "^3.9",
"stefna/codestyle": "^1.15",
"phpstan/phpstan": "^1.10",
"phpstan/phpstan": "^2.1",
"bnf/phpstan-psr-container": "^1.0",
"phpunit/phpunit": "^10.5",
"phpstan/phpstan-phpunit": "^1.1",
"tomasvotruba/type-coverage": "^0.3 || ^1.0",
"phpstan/phpstan-phpunit": "^2.0",
"tomasvotruba/type-coverage": "^2.0",
"phpstan/extension-installer": "^1.3"
},
"autoload": {
Expand Down
1 change: 1 addition & 0 deletions phpstan.neon
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ parameters:
level: max
paths:
- src
- tests
type_coverage:
return_type: 90
param_type: 100
Expand Down
8 changes: 6 additions & 2 deletions src/AbstractListCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -191,8 +191,12 @@ public function filter(callable $filter): static

public function map(callable $callback): ListCollection
{
if ($this->data->isEmpty()) {
return new GenericListCollection($this->collectionType); // @phpstan-ignore return.type
}
$newData = $this->data->map($callback);
$collection = new GenericListCollection(get_class($newData->first()));
$collectionType = $newData->first()::class;
$collection = new GenericListCollection($collectionType);
$collection->data = $newData;
return $collection;
}
Expand All @@ -211,7 +215,7 @@ public function indexBy(callable $callback): MapCollection

public function column(callable $callback): array
{
return $this->data->map($callback)->toArray();
return array_values($this->data->map($callback)->toArray());
}

public function merge(Collection ...$collections): static
Expand Down
9 changes: 7 additions & 2 deletions src/AbstractMapCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,11 @@ public function __construct(
if (!isset($this->collectionType) && isset(static::$defaultCollectionType)) {
$this->collectionType = static::$defaultCollectionType;
}
$this->data = new Map();
$this->data = new Map(); // @phpstan-ignore assign.propertyType
// Invoke offsetSet() for each value added; in this way, sub-classes
// may provide additional logic about values added to the array object.
foreach ($data as $key => $value) {
// @phpstan-ignore function.alreadyNarrowedType
if (!is_string($key)) {
throw new \BadMethodCallException('Must specify key');
}
Expand Down Expand Up @@ -83,6 +84,7 @@ public function offsetSet(mixed $offset, mixed $value): void
if (!$value instanceof $this->collectionType) {
throw new \TypeError('Invalid type for collection. Expected: ' . $this->collectionType);
}
// @phpstan-ignore function.alreadyNarrowedType
if (!is_string($offset)) {
throw new \InvalidArgumentException('Offset must be of type string');
}
Expand All @@ -108,7 +110,7 @@ public function count(): int

public function clear(): void
{
$this->data = new Map();
$this->data = new Map(); // @phpstan-ignore assign.propertyType
}

/**
Expand Down Expand Up @@ -204,6 +206,9 @@ public function filter(callable $filter): static
*/
public function map(callable $callback): MapCollection
{
if ($this->data->isEmpty()) {
return new GenericMapCollection($this->collectionType); // @phpstan-ignore return.type
}
$newData = $this->data->map($callback);
$collection = new GenericMapCollection(get_class($newData->first()->value));
$collection->data = $newData;
Expand Down
16 changes: 14 additions & 2 deletions tests/GenericListCollectionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,18 @@ public function testMap(): void
$this->assertSame($value, $newCollection->first()?->value);
}

public function testMapOnEmptyCollection(): void
{
$collection1 = new GenericListCollection(RandomEntity::class, []);

$newCollection = $collection1->map(fn (RandomEntity $entity): ExtraEntity => new ExtraEntity((string)$entity->value));

$this->assertNotSame($collection1, $newCollection);
$this->assertCount(0, $newCollection);
// the collection type stays the same since the collection is empty and hence can't change
$this->assertSame($collection1->getType(), $newCollection->getType());
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would love to see a check to make sure the type has not changed (also for the map test):

Suggested change
}
$this->assertSame($collection1->getType(), $newCollection->getType());
}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added

Also added a comment explaining why it stays the same


public function testFilter(): void
{
$collection1 = new GenericListCollection(RandomEntity::class, [
Expand Down Expand Up @@ -226,7 +238,7 @@ public function testIndexBy(): void
$index = 1;
foreach ($mapCollection as $key => $value) {
$this->assertSame('index' . $index, $key);
$this->assertInstanceOf(ExtraEntity::class, $value);
$this->assertInstanceOf(ExtraEntity::class, $value); // @phpstan-ignore method.alreadyNarrowedType
$index++;
}
}
Expand Down Expand Up @@ -274,7 +286,7 @@ public function testColumn(): void
$values = $collection1->column(fn (RandomEntity $r) => $r->value);

$this->assertCount(5, $values);
$this->assertIsList($values);
$this->assertIsList($values); // @phpstan-ignore method.alreadyNarrowedType
$this->assertSame([1, 2, 3, 4, 5], $values);
}

Expand Down
16 changes: 14 additions & 2 deletions tests/GenericMapCollectionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,18 @@ public function testMap(): void
$this->assertSame($value, $newCollection->first()?->value);
}

public function testMapOnEmptyCollection(): void
{
$collection1 = new GenericMapCollection(RandomEntity::class, []);

$newCollection = $collection1->map(fn (string $key, RandomEntity $entity): ExtraEntity => new ExtraEntity((string)$entity->value));

$this->assertNotSame($collection1, $newCollection);
$this->assertCount(0, $newCollection);
// the collection type stays the same since the collection is empty and hence can't change
$this->assertSame($collection1->getType(), $newCollection->getType());
}

public function testFilter(): void
{
$collection1 = new GenericMapCollection(RandomEntity::class, [
Expand Down Expand Up @@ -297,7 +309,7 @@ public function testIndexBy(): void
$index = 1;
foreach ($mapCollection as $key => $value) {
$this->assertSame('index' . $index, $key);
$this->assertInstanceOf(ExtraEntity::class, $value);
$this->assertInstanceOf(ExtraEntity::class, $value); // @phpstan-ignore method.alreadyNarrowedType
$index++;
}
}
Expand All @@ -324,7 +336,7 @@ public function testColumn(): void
$values = $collection1->column(fn (RandomEntity $r) => $r->value);

$this->assertCount(5, $values);
$this->assertIsList($values);
$this->assertIsList($values); // @phpstan-ignore method.alreadyNarrowedType
$this->assertSame(['1', '2', '3', '4', '5'], $values);
}

Expand Down
8 changes: 4 additions & 4 deletions tests/ScalarMapTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public function testGetStringWithDefaultValue(): void
{
$map = $this->createMap();
$value = $map->getString('testStringNotFound', 'random');
$this->assertIsString($value);
$this->assertIsString($value); // @phpstan-ignore method.alreadyNarrowedType
$this->assertSame('random', $value);
}

Expand Down Expand Up @@ -55,7 +55,7 @@ public function testGetIntWithDefaultValue(): void
{
$map = $this->createMap();
$value = $map->getInt('testIntNotFound', 42);
$this->assertIsInt($value);
$this->assertIsInt($value); // @phpstan-ignore method.alreadyNarrowedType
$this->assertSame(42, $value);
}

Expand All @@ -76,7 +76,7 @@ public function testGetFloatWithDefaultValue(): void
{
$map = $this->createMap();
$value = $map->getFloat('testFloatNotFound', 42.1);
$this->assertIsFloat($value);
$this->assertIsFloat($value); // @phpstan-ignore method.alreadyNarrowedType
$this->assertSame(42.1, $value);
}

Expand All @@ -100,7 +100,7 @@ public function testGetBoolWithDefaultValue(): void
{
$map = $this->createMap();
$value = $map->getBool('testBoolNotFound', true);
$this->assertIsBool($value);
$this->assertIsBool($value); // @phpstan-ignore method.alreadyNarrowedType
$this->assertTrue($value);
}

Expand Down