Skip to content

Commit 74c34f9

Browse files
author
nix
committed
added PHP unit tests
currently covering 93% of code lines
1 parent 6ffda4a commit 74c34f9

File tree

11 files changed

+479
-4
lines changed

11 files changed

+479
-4
lines changed

composer.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
"require": {
66
"php": ">=8.2"
77
},
8+
"require-dev": {
9+
"phpunit/phpunit": "^11.5.41"
10+
},
811
"authors": [
912
{
1013
"name": "nix"
@@ -16,6 +19,11 @@
1619
"nixn\\php\\": "src/"
1720
}
1821
},
22+
"autoload-dev": {
23+
"psr-4": {
24+
"Test\\": "tests/"
25+
}
26+
},
1927
"extra": {
2028
"branch-alias": {
2129
"dev-main": "1.2.x-dev"

src/Arr.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
/** @since 1.0 */
55
final class Arr
66
{
7-
private function __construct()
8-
{}
7+
/** @codeCoverageIgnore */
8+
private function __construct() {}
99

1010
/**
1111
* Returns a new array with only the key => value mappings left, whose keys are in $keys.

src/Str.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
/** @since 1.0 */
55
final class Str
66
{
7-
private function __construct()
8-
{}
7+
/** @codeCoverageIgnore */
8+
private function __construct() {}
99

1010
/**
1111
* Trims a string prefix when it matches. Example: `trim_prefix("Hello all", "Hello ") === "all"`.

src/Util.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
/** @since 1.0 */
55
final class Util
66
{
7+
/** @codeCoverageIgnore */
78
private function __construct() {}
89

910
/**

tests/ArrTest.php

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
namespace Test;
5+
6+
use nixn\php\Arr;
7+
use PHPUnit\Framework\Attributes\DataProvider;
8+
use PHPUnit\Framework\TestCase;
9+
10+
final class ArrTest extends TestCase
11+
{
12+
use HandleTrait;
13+
14+
public static function provider_pick(): array
15+
{
16+
$array = [0, 1, 2, 'a' => 'a', 'b' => 'b', 'c' => 'c'];
17+
return [
18+
[[$array], []],
19+
[[$array, 3, 'd'], []],
20+
[[$array, 1], [1 => 1]],
21+
[[$array, 1, 2, 3, 'c', 'd'], [1 => 1, 2 => 2, 'c' => 'c']],
22+
];
23+
}
24+
25+
#[DataProvider('provider_pick')]
26+
public function test_pick(array $args, mixed $result): void
27+
{
28+
$this->assertSame($result, Arr::pick(...$args));
29+
}
30+
31+
public static function provider_find_by(): array
32+
{
33+
$array = [0, 2, 4, 'a' => 'A', 'b' => 'B', 'c' => 'C'];
34+
return [
35+
[[$array, fn($v, $k) => is_int($v) && $v > 0], 2],
36+
[[$array, fn($v, $k) => is_int($v) && $v > 2, true], 2],
37+
[[$array, fn($v, $k) => $k === 'a'], 'A'],
38+
[[$array, fn($v, $k) => $v === 'B', true], 'b'],
39+
[[$array, fn($v, $k) => false], null],
40+
];
41+
}
42+
43+
#[DataProvider('provider_find_by')]
44+
public function test_find_by(array $args, mixed $result): void
45+
{
46+
$this->assertSame($result, Arr::find_by(...$args));
47+
}
48+
49+
public static function provider_reduce(): array
50+
{
51+
$add = fn(int $carry, int $next) => $carry + $next;
52+
return [
53+
[[[], $add], -1, 'exception' => [\RuntimeException::class, '/no elements and no initial value/']],
54+
[[[], $add, 1], 1],
55+
[[[], $add, 1, true], 1],
56+
[[[2], $add], 2],
57+
[[[2], $add, 1], 3],
58+
[[[2], $add, 1, true], 2],
59+
[[[2, 3], $add], 5],
60+
[[[2, 3], $add, 1], 6],
61+
[[[2, 3], $add, 1, true], 5],
62+
];
63+
}
64+
65+
#[DataProvider('provider_reduce')]
66+
public function test_reduce(array $args, mixed $result, string $message = '', ?array $exception = null): void
67+
{
68+
$this->handle_exception($exception);
69+
$this->assertSame($result, Arr::reduce(...$args), $message);
70+
}
71+
72+
public static function provider_kvjoin(): array
73+
{
74+
return [
75+
[[[]], ''],
76+
[[['a' => 'A']], 'a=A'],
77+
[[['a' => 'A'], ';'], 'a=A'],
78+
[[['a' => 'A'], ';', ':'], 'a:A'],
79+
[[['a' => 'A', 'b' => 'B']], 'a=A, b=B'],
80+
[[['a' => 'A', 'b' => 'B'], ';'], 'a=A;b=B'],
81+
[[['a' => 'A', 'b' => 'B'], ';', ':'], 'a:A;b:B'],
82+
];
83+
}
84+
85+
#[DataProvider('provider_kvjoin')]
86+
public function test_kvjoin(array $args, string $result, string $message = ''): void
87+
{
88+
$this->assertSame($result, Arr::kvjoin(...$args), $message);
89+
}
90+
91+
public static function provider_first(): array
92+
{
93+
$none = ['k' => null, 'v' => null];
94+
return [
95+
[[], $none],
96+
[[1], ['k' => 0, 'v' => 1]],
97+
[[1, 2], ['k' => 0, 'v' => 1]],
98+
[[1 => 1, 2], ['k' => 1, 'v' => 1]],
99+
[['a' => 1, 'b' => 2], ['k' => 'a', 'v' => 1]],
100+
];
101+
}
102+
103+
#[DataProvider('provider_first')]
104+
public function test_first(array $data, array $result, string $message = ''): void
105+
{
106+
$this->assertSame($result, Arr::first($data), $message);
107+
}
108+
109+
public static function provider_find(): array
110+
{
111+
$array = [0, 2, 4, 'a' => 'A', 'b' => 'B', 'c' => 'C'];
112+
$none = ['k' => null, 'v' => null];
113+
return [
114+
[[$array], $none],
115+
[[$array, 0], ['k' => 0, 'v' => 0]],
116+
[[$array, 1], ['k' => 1, 'v' => 2]],
117+
[[$array, 3], $none],
118+
[[$array, 0, 1], ['k' => 0, 'v' => 0]],
119+
[[$array, 1, 2], ['k' => 1, 'v' => 2]],
120+
[[$array, 'a', 'b', 'c'], ['k' => 'a', 'v' => 'A']],
121+
[[$array, 'x'], $none],
122+
[[$array, 'x', 3], $none],
123+
[[$array, 'a', 2, 'b'], ['k' => 2, 'v' => 4]],
124+
[[$array, 3, 'b'], ['k' => 'b', 'v' => 'B']],
125+
[[$array, 3, 'b', 2], ['k' => 2, 'v' => 4]],
126+
];
127+
}
128+
129+
#[DataProvider('provider_find')]
130+
public function test_find(array $args, mixed $result, string $message = ''): void
131+
{
132+
$this->assertSame($result, Arr::find(...$args), $message);
133+
}
134+
}

tests/HandleTrait.php

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
namespace Test;
5+
6+
/**
7+
* @method expectException(string $class)
8+
* @method expectExceptionMessageMatches(string $message)
9+
*/
10+
trait HandleTrait
11+
{
12+
private function handle_exception(?array $exception): void
13+
{
14+
if ($exception)
15+
{
16+
$this->expectException($exception['class'] ?? $exception['c'] ?? $exception[0]);
17+
if ($message = $exception['message'] ?? $exception['m'] ?? $exception[1] ?? null)
18+
$this->expectExceptionMessageMatches($message);
19+
}
20+
}
21+
22+
private function handle_suppress_warnings(bool $suppress_warnings, callable $callable, mixed ...$args): mixed
23+
{
24+
return $suppress_warnings ? @$callable(...$args) : $callable(...$args);
25+
}
26+
}

tests/PartialTest.php

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
namespace Test;
5+
6+
use nixn\php\Partial;
7+
use PHPUnit\Framework\Attributes\DataProvider;
8+
use PHPUnit\Framework\TestCase;
9+
10+
final class PartialTest extends TestCase
11+
{
12+
use HandleTrait;
13+
14+
public static function stringify_args(mixed ...$args): string
15+
{
16+
return join(',', $args);
17+
}
18+
19+
public static function power(int $a, int $b): int
20+
{
21+
return pow($a, $b);
22+
}
23+
24+
public static function provider_partial(): array
25+
{
26+
return [
27+
[[self::stringify_args(...)], [], ''],
28+
[[self::stringify_args(...), 1, 2], [], '1,2'],
29+
[[self::stringify_args(...), 1, Partial::PLACEHOLDER], [2], '1,2'],
30+
[[self::stringify_args(...), 1, 2], [3, 4], '1,2,3,4'],
31+
[[self::stringify_args(...), 1, Partial::PLACEHOLDER, 3], [2, 4], '1,2,3,4'],
32+
[[self::stringify_args(...), 1, Partial::PLACEHOLDER, 3, Partial::PLACEHOLDER, 5], [2, 4, 6], '1,2,3,4,5,6'],
33+
[[self::power(...), 'b' => 10], [2], 1024, 'exception' => [\Error::class, '/positional argument/']],
34+
[[self::power(...), 'b' => 10], ['a' => 2], 1024],
35+
];
36+
}
37+
38+
#[DataProvider('provider_partial')]
39+
public function test_partial(array $args1, array $args2, mixed $result, ?array $exception = null): void
40+
{
41+
$this->handle_exception($exception);
42+
$this->assertSame($result, Partial::partial(...$args1)(...$args2));
43+
}
44+
}

tests/PipeTest.php

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
namespace Test;
5+
6+
use nixn\php\Pipe;
7+
use PHPUnit\Framework\Attributes\DataProvider;
8+
use PHPUnit\Framework\TestCase;
9+
10+
final class PipeTest extends TestCase
11+
{
12+
use HandleTrait;
13+
14+
public function test(): void
15+
{
16+
$pipe = new Pipe('2025-01-01t00:00:00');
17+
$this->assertSame('2025-01-01t00:00:00', $pipe->value);
18+
$pipe(strtoupper(...));
19+
$this->assertSame('2025-01-01T00:00:00', $pipe->value);
20+
$pipe->new(\DateTimeImmutable::class, Pipe::PLACEHOLDER, new \DateTimeZone('UTC'));
21+
$this->assertInstanceOf(\DateTimeImmutable::class, $pipe->value);
22+
$pipe->format('Y_m_d');
23+
$this->assertSame('2025_01_01', $pipe->value);
24+
$pipe(explode(...), '_', Pipe::PLACEHOLDER, 2);
25+
$this->assertSame(['2025', '01_01'], $pipe->value);
26+
$pipe->get(0);
27+
$this->assertSame('2025', $pipe->value);
28+
$pipe(intval(...));
29+
$this->assertSame(2025, $pipe->value);
30+
$pipe(fn($x) => $x + 1);
31+
$this->assertSame(2026, $pipe->value);
32+
}
33+
34+
public static function provider_get(): array
35+
{
36+
return [
37+
[new Pipe(new \stdClass()), ['one'], null, 'empty object', 'suppress_warnings' => true],
38+
[(new Pipe(new \stdClass()))->set('one', 1), ['one'], 1, 'object->one'],
39+
[(new Pipe(new \stdClass()))->set('one', 1), ['one', true], null, 'object->one', 'exception' => [\Error::class, '/cannot use object .*as array/i']],
40+
[new Pipe([]), ['one', true], null, 'empty array', 'suppress_warnings' => true],
41+
[new Pipe(['one' => 1]), ['one'], null, 'assoc array', 'suppress_warnings' => true],
42+
[new Pipe(['one' => 1]), ['one', true], 1, 'assoc array'],
43+
[new Pipe([1 => 'one']), [1], 'one', 'indexed array'],
44+
];
45+
}
46+
47+
#[DataProvider('provider_get')]
48+
public function test_get(Pipe $pipe, array $get, mixed $result, string $message = '', ?array $exception = null, bool $suppress_warnings = false): void
49+
{
50+
$this->handle_exception($exception);
51+
$this->handle_suppress_warnings($suppress_warnings, $pipe->get(...), ...$get);
52+
$this->assertSame($result, $pipe->value, $message);
53+
}
54+
55+
public static function provider_set(): array
56+
{
57+
return [
58+
[['v' => 1], ['v', 2, true], ['v', true], 2, 'assoc array'],
59+
[[1], [0, 2], [0], 2, 'indexed array'],
60+
[(new Pipe(new \stdClass))->set('v', 1)->value, ['v', 2], ['v'], 2, 'object'],
61+
];
62+
}
63+
64+
#[DataProvider('provider_set')]
65+
public function test_set(mixed $initial, array $set, array $get, mixed $result, string $message = ''): void
66+
{
67+
$this->assertSame($result, (new Pipe($initial))->set(...$set)->get(...$get)->value, $message);
68+
}
69+
70+
public function test_toString(): void
71+
{
72+
$v = 'a string';
73+
$w = new Pipe($v);
74+
$this->assertSame("$v", "$w");
75+
}
76+
}

tests/StrTest.php

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
namespace Test;
5+
6+
use nixn\php\Str;
7+
use PHPUnit\Framework\Attributes\DataProvider;
8+
use PHPUnit\Framework\TestCase;
9+
10+
final class StrTest extends TestCase
11+
{
12+
public static function provider_trim_prefix(): array
13+
{
14+
return [
15+
['', '', ''],
16+
['a', '', 'a'],
17+
['', 'a', ''],
18+
['a', 'a', ''],
19+
['abc', 'a', 'bc'],
20+
['aaa', 'a', 'aa'],
21+
['Aaa', 'a', 'Aaa'],
22+
['AAA', 'A', 'AA'],
23+
['aAA', 'A', 'aAA'],
24+
['abcdef', 'abc', 'def'],
25+
['abcdef', 'def', 'abcdef'],
26+
];
27+
}
28+
29+
#[DataProvider('provider_trim_prefix')]
30+
public function test_trim_prefix(string $string, string $prefix, string $result): void
31+
{
32+
$this->assertSame($result, Str::trim_prefix($string, $prefix));
33+
}
34+
35+
public static function provider_trim_suffix(): array
36+
{
37+
return [
38+
['', '', ''],
39+
['a', '', 'a'],
40+
['', 'a', ''],
41+
['a', 'a', ''],
42+
['abc', 'c', 'ab'],
43+
['aaa', 'a', 'aa'],
44+
['aaA', 'a', 'aaA'],
45+
['AAA', 'A', 'AA'],
46+
['AAa', 'A', 'AAa'],
47+
['abcdef', 'def', 'abc'],
48+
['abcdef', 'abc', 'abcdef'],
49+
];
50+
}
51+
52+
#[DataProvider('provider_trim_suffix')]
53+
public function test_trim_suffix(string $string, string $suffix, string $result): void
54+
{
55+
$this->assertSame($result, Str::trim_suffix($string, $suffix));
56+
}
57+
}

0 commit comments

Comments
 (0)