Skip to content

Commit 9ed2957

Browse files
committed
Convert to class for lazy-autoload and add tests
1 parent 8ee941d commit 9ed2957

File tree

11 files changed

+265
-34
lines changed

11 files changed

+265
-34
lines changed

.github/workflows/commit.yml

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
name: Continuous Integration
2+
on: [push]
3+
4+
jobs:
5+
phpunit:
6+
name: Unit Tests
7+
runs-on: ubuntu-latest
8+
strategy:
9+
matrix:
10+
php: [7.4, 8.0, 8.1]
11+
steps:
12+
- name: Setup PHP
13+
uses: shivammathur/setup-php@v2
14+
with:
15+
php-version: ${{ matrix.php }}
16+
coverage: xdebug
17+
tools: composer:v2
18+
19+
- name: Checkout Repository
20+
uses: actions/checkout@v2
21+
22+
- name: Install Dependencies
23+
run: composer install
24+
25+
- name: Test
26+
run: vendor/bin/phpunit tests --testdox --coverage-clover coverage.xml
27+
28+
- name: Upload to CodeCov
29+
uses: codecov/codecov-action@v1
30+
with:
31+
token: ${{ secrets.CODECOV_TOKEN }}
32+
files: coverage.xml
33+
fail_ci_if_error: true
34+
35+
phpstan:
36+
name: Static Analysis Check
37+
runs-on: ubuntu-latest
38+
strategy:
39+
matrix:
40+
php: [7.4, 8.0, 8.1]
41+
steps:
42+
- name: Setup PHP
43+
uses: shivammathur/setup-php@v2
44+
with:
45+
php-version: ${{ matrix.php }}
46+
tools: composer:v2
47+
48+
- name: Checkout Repository
49+
uses: actions/checkout@v2
50+
51+
- name: Install Dependencies
52+
run: composer install
53+
54+
- name: Run PHPStan
55+
run: vendor/bin/phpstan
56+
57+
phpcs:
58+
name: Code Style (PSR-12)
59+
runs-on: ubuntu-latest
60+
steps:
61+
- name: Setup PHP
62+
uses: shivammathur/setup-php@v2
63+
with:
64+
php-version: 8.0
65+
tools: composer:v2
66+
67+
- name: Checkout Repository
68+
uses: actions/checkout@v2
69+
70+
- name: Install Dependencies
71+
run: composer install
72+
73+
- name: PHP Code Sniffer
74+
run: vendor/bin/phpcs
75+
76+
infection:
77+
name: Infection Check
78+
runs-on: ubuntu-latest
79+
strategy:
80+
matrix:
81+
php: [ 7.4, 8.0, 8.1 ]
82+
continue-on-error: true
83+
steps:
84+
- name: Setup PHP
85+
uses: shivammathur/setup-php@v2
86+
with:
87+
php-version: ${{ matrix.php }}
88+
coverage: xdebug
89+
tools: composer:v2
90+
91+
- name: Checkout Repository
92+
uses: actions/checkout@v2
93+
94+
- name: Install dependencies
95+
run: composer install
96+
97+
- name: Check for Mutants
98+
run: vendor/bin/infection --threads=$(nproc) --no-progress --logger-github

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
vendor/
2+
composer.lock
3+
/.phpunit.result.cache

README.md

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,27 @@
1-
# iterable_to_array
2-
PHP function iterable_to_array
1+
# IterableToArray::convert
2+
3+
A simple utility class that handles the boilerplate of converting an iterable into an array.
4+
5+
The goal of this utility is to be an in-place replacement for iterator_to_array whenever one must handle an iterable.
6+
7+
## Installation
8+
9+
composer require navarr/iterable-to-array
10+
11+
## Usage
12+
13+
```php
14+
<?php
15+
16+
use Navarr\Utils\IterableToArray
17+
18+
// ...
19+
20+
$array = IterableToArray::convert($iterable);
21+
22+
// This replaces:
23+
24+
$array = is_array($iterable) ? $iterable : iterator_to_array($iterable);
25+
```
26+
27+
This also has (what should be unnecessary) forward compatibility for a scenario where an object passes the `iterable` type check but is neither an `array` nor a `\Traversable`.

composer.json

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"name": "navarr/iterable-to-array",
3+
"description": "A method for converting an iterable to an array, no matter what type of iterable",
4+
"require": {
5+
"php": ">=7.4"
6+
},
7+
"require-dev": {
8+
"phpstan/phpstan": "^1",
9+
"roave/security-advisories": "dev-master",
10+
"phpunit/phpunit": "^9.5",
11+
"infection/infection": "^0.25.3",
12+
"squizlabs/php_codesniffer": "^3.6",
13+
"jetbrains/phpstorm-attributes": "^1.0"
14+
},
15+
"autoload": {
16+
"psr-4": {
17+
"Navarr\\Utils\\": "src"
18+
}
19+
}
20+
}

infection.json.dist

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"source": {
3+
"directories": [
4+
"src"
5+
]
6+
},
7+
"phpUnit": {
8+
"configDir": "."
9+
},
10+
"mutators": {
11+
"@default": true
12+
}
13+
}

iterable_to_array.func.php

Lines changed: 0 additions & 32 deletions
This file was deleted.

phpcs.xml.dist

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<ruleset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="vendor/squizlabs/php_codesniffer/phpcs.xsd">
3+
<rule ref="PSR12"/>
4+
<file>src</file>
5+
</ruleset>

phpstan.neon

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
parameters:
2+
level: 9
3+
paths:
4+
- src

phpunit.xml.dist

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" colors="true" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd">
3+
<testsuite name="unit">
4+
<directory>tests</directory>
5+
</testsuite>
6+
<coverage cacheDirectory="/tmp">
7+
<include>
8+
<directory suffix=".php">src</directory>
9+
</include>
10+
</coverage>
11+
</phpunit>

src/IterableToArray.php

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<?php
2+
3+
/**
4+
* Copyright (C) 2021 Navarr T. Barnier. All rights reserved.
5+
* Licensed under MIT License.
6+
*/
7+
8+
declare(strict_types=1);
9+
10+
namespace Navarr\Utils;
11+
12+
use JetBrains\PhpStorm\Pure;
13+
use Traversable;
14+
15+
use function is_array;
16+
use function iterator_to_array;
17+
18+
class IterableToArray
19+
{
20+
/**
21+
* Converts any iterable into an array
22+
*
23+
* Designed to reduce boilerplate of testing if an iterable is an array before calling {@see iterator_to_array}
24+
*
25+
* @template T
26+
* @param iterable<T> $iterable <p>
27+
* The iterator being copied.
28+
* </p>
29+
* @param bool $preserve_keys [optional] <p>
30+
* Whether to use the iterator element keys as index. If an array is passed, keys are always preserved.
31+
* </p>
32+
* @return array<T> An array containing the elements of the iterable.
33+
*/
34+
#[Pure]
35+
public static function convert(iterable $iterable, bool $preserve_keys = true): array
36+
{
37+
if (is_array($iterable)) {
38+
return $iterable;
39+
}
40+
41+
if ($iterable instanceof Traversable) {
42+
return iterator_to_array($iterable, $preserve_keys);
43+
}
44+
45+
// Fallback for supposedly impossible scenario
46+
$result = [];
47+
foreach ($iterable as $key => $value) {
48+
if ($preserve_keys) {
49+
$result[$key] = $value;
50+
continue;
51+
}
52+
$result[] = $value;
53+
}
54+
return $result;
55+
}
56+
}

tests/IterableToArrayTest.php

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
/**
4+
* Copyright (C) 2021 Navarr T. Barnier. All rights reserved.
5+
* Licensed under MIT License.
6+
*/
7+
8+
declare(strict_types=1);
9+
10+
namespace Navarr\Utils;
11+
12+
use ArrayIterator;
13+
use PHPUnit\Framework\TestCase;
14+
15+
class IterableToArrayTest extends TestCase
16+
{
17+
public function testConvertWithArray()
18+
{
19+
$array = ['a', 'b'];
20+
$this->assertEquals($array, IterableToArray::convert(['a', 'b']));
21+
}
22+
23+
public function testConvertWithIterator()
24+
{
25+
$iterator = new ArrayIterator(['a', 'b']);
26+
$this->assertEquals(['a', 'b'], IterableToArray::convert($iterator));
27+
}
28+
}

0 commit comments

Comments
 (0)