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
51 changes: 47 additions & 4 deletions .github/workflows/continuous-integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,50 @@ env:
fail-fast: true

jobs:
checks:
runs-on: ubuntu-latest
steps:
- name: Checkout Code
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: 8.3
extensions: mbstring
coverage: none
tools: composer-dependency-analyser, composer-normalize, composer-require-checker

- name: Install Composer Dependencies
uses: ramsey/composer-install@v3
with:
dependency-versions: "highest"
composer-options: "--prefer-stable --optimize-autoloader --no-progress --no-interaction"

- name: Run Composer Dependency Analyser
run: composer-dependency-analyser

- name: Run Composer Require Checker
run: composer-require-checker

- name: Run Composer Normalize
run: composer-normalize --dry-run --indent-size 2 --indent-style space --no-check-lock --no-update-lock

- name: Run PHP CS Fixer
run: ./vendor/bin/php-cs-fixer check --using-cache=no --config ./vendor/kununu/scripts/src/PHP/CodeStandards/Scripts/php_cs src/ tests/

- name: Run Rector
run: ./vendor/bin/rector process --ansi --dry-run --config rector-ci.php src/ tests/

- name: Run PHPStan
run: ./vendor/bin/phpstan analyse --ansi

build:
needs: checks
name: PHPUnit
runs-on: ubuntu-22.04
runs-on: ubuntu-latest
strategy:
matrix:
php-version:
Expand All @@ -26,22 +67,25 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php-version }}
extensions: mbstring
coverage: pcov

- name: Install Composer Dependencies
uses: ramsey/composer-install@v3
with:
dependency-versions: ${{ matrix.dependencies }}
composer-options: "--prefer-stable"
composer-options: "--prefer-stable --optimize-autoloader --no-progress --no-interaction"

- name: Run PHPUnit
run: |
vendor/bin/phpunit --colors=always \
vendor/bin/phpunit --colors=always --testdox \
--log-junit tests/.results/tests-junit.xml \
--coverage-clover tests/.results/tests-clover.xml

Expand All @@ -58,7 +102,6 @@ jobs:
steps:
- uses: actions/checkout@v4
with:
# Disabling shallow clone is recommended for improving relevancy of reporting
fetch-depth: 0

- uses: actions/download-artifact@v4
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ More details:
- [Key Value](docs/key-value.md)
- [Abstract Item](docs/abstract-item.md)
- [Mapper](docs/mapper.md)
- [Collections Test Case](docs/abstract-collection-test-case.md)

## Contribute

Expand Down
10 changes: 10 additions & 0 deletions composer-dependency-analyser.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php
declare(strict_types=1);

use ShipMonk\ComposerDependencyAnalyser\Config\Configuration;
use ShipMonk\ComposerDependencyAnalyser\Config\ErrorType;

return (new Configuration())
->disableReportingUnmatchedIgnores()
->ignoreErrors([ErrorType::DEV_DEPENDENCY_IN_PROD])
->setFileExtensions(['php']);
5 changes: 5 additions & 0 deletions composer-require-checker.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"symbol-whitelist": [
"PHPUnit\\Framework\\TestCase"
]
}
33 changes: 22 additions & 11 deletions composer.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
{
"name": "kununu/collections",
"description": "To reduce boilerplate associated with collections",
"type": "library",
"license": "MIT",
"minimum-stability": "stable",
"type": "library",
"keywords": [
"collections"
],
Expand All @@ -14,12 +13,18 @@
}
],
"require": {
"php": ">=8.3"
"php": ">=8.3",
"ext-mbstring": "*"
},
"require-dev": {
"kununu/scripts": ">=6.0",
"phpunit/phpunit": "^12.2"
"kununu/scripts": ">=6.1",
"phpstan/phpstan": "^2.1",
"phpstan/phpstan-phpunit": "^2.0",
"phpunit/phpunit": "^12.3",
"rector/rector": "^2.1",
"shipmonk/composer-dependency-analyser": "^1.8"
},
"minimum-stability": "stable",
"autoload": {
"psr-4": {
"Kununu\\Collection\\": "src/"
Expand All @@ -30,18 +35,24 @@
"Kununu\\Collection\\Tests\\": "tests/"
}
},
"config": {
"allow-plugins": {
"kununu/scripts": true
},
"sort-packages": true
},
"scripts": {
"cs": "composer kununu:cs-fixer-code src/ tests/",
"phpstan": "phpstan",
"rector": "rector process --dry-run --config rector-ci.php src/ tests/",
"test": "phpunit --log-events-text phpunit.log --no-coverage --no-logging --no-progress --testsuite Full",
"test-coverage": "XDEBUG_MODE=coverage phpunit --log-events-text phpunit.log --no-progress --testsuite Full"
},
"scripts-descriptions": {
"cs": "Run PHP CS Fixer with kununu code standards",
"phpstan": "Run PHPStan",
"rector": "Run Rector in dry-run mode with CI rules",
"test": "Run all tests",
"test-coverage": "Run all tests with coverage report"
},
"config": {
"sort-packages": true,
"allow-plugins": {
"kununu/scripts": true
}
}
}
104 changes: 104 additions & 0 deletions docs/abstract-collection-test-case.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
# Abstract Collection Test Case

To test your collections you can make your test classes extend the `AbstractCollectionTestCase`.

## Tests

### Test populated collection

```php
public function testCollection(): void
```

This will test:

- The number of items in your populated collection

Override the following constant to the expected count of your populated collection:

```php
protected const int EXPECTED_COUNT = 0;
```

- The class of the item return by the `current` method

Override the following constant to the expected class of items of the collection:

```php
protected const string EXPECTED_ITEM_CLASS = '';
```

- (Optional) The value return by the `toArray` method

By default, it will test this. Override the following constant to `false` if you don't want to test this:

```php
protected const bool TEST_TO_ARRAY = true;
```

The populated collection being tested should be returned by implementing the following method:

```php
abstract protected function createCollection(): Collection
```

You can also do extra custom assertions to your populated collection.

In order to do that you can override the following method:

```php
protected function doExtraAssertions(Collection $collection): void
```

The `$collection` that is passed to the method is the same returned by the `createCollection` method.

## Test empty collection

```php
public function testEmptyCollection(): void
```

This will test:

- That the collection is empty
- That the `current` method return `null`

The empty collection being tested should be returned by implementing the following method:

```php
abstract protected function createEmptyCollection(): Collection
```

## Test adding an invalid value to the collection

```php
public function testAddInvalid(): void
```

This will test:

- That adding an invalid value to a collection will throw an exception

By default, it will test that an `InvalidArgumentException` is thrown.

Override the following constant if your collection throws a different exception:

```php
protected const string INVALID_EXCEPTION_CLASS = InvalidArgumentException::class;
```

If you also want to expect for a specific exception error message, then override the following constant:

```php
protected const ?string INVALID_ERROR_MESSAGE = null;
```

This test also uses the collection created with the `createEmptyCollection` method.

## Example

Take a look at [this](../tests/TestCase/AbstractCollectionTestCaseTest.php) test to see an example of using the test case.

---

[Back to Index](../README.md)
2 changes: 2 additions & 0 deletions docs/abstract-collections.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use Kununu\Collection\AbstractCollection;
* @method static self fromIterable(iterable $data)
* @method self add(mixed $value)
* @method self clear()
* @method int count()
* @method self diff(Collection $other)
* @method self duplicates(bool $strict = true, bool $uniques = false)
* @method self each(callable $function, bool $rewind = true)
Expand Down Expand Up @@ -43,6 +44,7 @@ use Kununu\Collection\AbstractFilterableCollection;
* @method static self fromIterable(iterable $data)
* @method self add(mixed $value)
* @method self clear()
* @method int count()
* @method self diff(Collection $other)
* @method self duplicates(bool $strict = true, bool $uniques = false)
* @method self each(callable $function, bool $rewind = true)
Expand Down
6 changes: 5 additions & 1 deletion docs/collection-interfaces.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,14 @@ public function chunk(int $size): array

This method [mirrors the behavior of `array_chunk`](https://www.php.net/manual/function.array-chunk.php) and returns a zero indexed numeric array of the current collection based on the chunk size provided.

## clear
### clear

This method should remove all the items of the collection and since is fluent it should return the collection.

### count

This method should return the number of items in your collection.

### diff

```php
Expand Down
4 changes: 4 additions & 0 deletions docs/collection-trait.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,10 @@ Internally it is calling the `ArrayIterator::append` and returning the instance

Internally it is calling the `keys` method and for each key it is call the `ArrayIterator::offsetUnset` and returning the instance to allow fluent calls.

## count

Internally it is calling the `ArrayIterator::count` method.

## chunk

Internally this method chunks the collection (by getting a copy with [getArrayCopy](https://www.php.net/manual/en/arrayiterator.getarraycopy.php) method) with the PHP [array_chunk](https://www.php.net/manual/function.array-chunk.php) function, returning a zero indexed array of collections of the same type as the initial one.
Expand Down
9 changes: 9 additions & 0 deletions phpstan.neon.dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
includes:
- vendor/phpstan/phpstan-phpunit/extension.neon
- vendor/phpstan/phpstan-phpunit/rules.neon
parameters:
level: 1
paths:
- src
- tests
errorFormat: table
8 changes: 6 additions & 2 deletions phpunit.xml.dist
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- https://docs.phpunit.de/en/12.2/ -->
<!-- https://docs.phpunit.de/en/12.3/ -->
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/12.2/phpunit.xsd"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/12.3/phpunit.xsd"
bootstrap="vendor/autoload.php"
colors="true"
beStrictAboutChangesToGlobalState="true"
Expand All @@ -26,5 +26,9 @@
<include>
<directory>src</directory>
</include>
<exclude>
<file>composer-dependency-analyser.php</file>
<file>rector-ci.php</file>
</exclude>
</source>
</phpunit>
19 changes: 19 additions & 0 deletions rector-ci.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php
declare(strict_types=1);

use Rector\Config\RectorConfig;
use Rector\Php83\Rector\ClassMethod\AddOverrideAttributeToOverriddenMethodsRector;
use Rector\Privatization\Rector\Class_\FinalizeTestCaseClassRector;

return RectorConfig::configure()
->withPhpSets(php83: true)
->withAttributesSets(phpunit: true)
->withComposerBased(phpunit: true)
->withRules([
FinalizeTestCaseClassRector::class,
])
->withSkip([
__DIR__ . '/rector-ci.php',
AddOverrideAttributeToOverriddenMethodsRector::class,
])
->withImportNames();
2 changes: 1 addition & 1 deletion sonar-project.properties
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ sonar.projectVersion=1.0
sonar.sourceEncoding=UTF-8

sonar.sources=.
sonar.exclusions=tests/**
sonar.exclusions=composer-dependency-analyser.php,rector-ci.php,tests/**
sonar.tests=tests

sonar.coverage.exclusion=tests/**
Expand Down
1 change: 1 addition & 0 deletions src/AbstractCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
* @method static self fromIterable(iterable $data)
* @method self add(mixed $value)
* @method self clear()
* @method int count()
* @method self diff(Collection $other)
* @method self duplicates(bool $strict = true, bool $uniques = false)
* @method self each(callable $function, bool $rewind = true)
Expand Down
1 change: 1 addition & 0 deletions src/AbstractFilterableCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
* @method static self fromIterable(iterable $data)
* @method self add(mixed $value)
* @method self clear()
* @method int count()
* @method self diff(Collection $other)
* @method self duplicates(bool $strict = true, bool $uniques = false)
* @method self each(callable $function, bool $rewind = true)
Expand Down
Loading