diff --git a/composer.json b/composer.json
index 1423da7..e2052d1 100644
--- a/composer.json
+++ b/composer.json
@@ -11,6 +11,7 @@
],
"require": {
"php": "^7.4",
+ "ext-bcmath": "*",
"symfony/polyfill": "^1.12"
},
"require-dev": {
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
index 3335207..746074a 100644
--- a/phpunit.xml.dist
+++ b/phpunit.xml.dist
@@ -16,12 +16,15 @@
tests/Psl/Arr
-
- tests/Psl/Random
-
tests/Psl/Collection
+
+ tests/Psl/Math
+
+
+ tests/Psl/Random
+
@@ -31,6 +34,12 @@
src
+
+ src/bootstrap.php
+ src/Psl/internal.php
+ src/Psl/Str/constants.php
+ src/Psl/Math/constants.php
+
\ No newline at end of file
diff --git a/src/Psl/Math/base_convert.php b/src/Psl/Math/base_convert.php
index 25de988..9785fe1 100644
--- a/src/Psl/Math/base_convert.php
+++ b/src/Psl/Math/base_convert.php
@@ -12,25 +12,35 @@ use Psl\Str\Byte;
* Converts the given string in base `$from_base` to base `$to_base`, assuming
* letters a-z are used for digits for bases greater than 10. The conversion is
* done to arbitrary precision.
+ *
+ * Example:
+ *
+ * Math\base_convert('10', 2, 10)
+ * => Str(2)
+ *
+ * Math\base_convert('5497', 10, 2)
+ * => Str('1010101111001')
+ *
+ * Math\base_convert('2014587925987', 10, 36)
+ * => Str('pphlmw9v')
*/
function base_convert(string $value, int $from_base, int $to_base): string
{
Psl\invariant('' !== $value, 'Unexpected empty string, expected number in base %d', $from_base);
Psl\invariant($from_base >= 2 && $from_base <= 36, 'Expected $from_base to be between 2 and 36, got %d', $from_base);
Psl\invariant($to_base >= 2 && $to_base <= 36, 'Expected $to_base to be between 2 and 36, got %d', $to_base);
- Psl\invariant(true === \bcscale(0), 'Unexpected bcscale failure');
$from_alphabet = Byte\slice(Str\ALPHABET_ALPHANUMERIC, 0, $from_base);
$result_decimal = '0';
/** @var string $place_value */
- $place_value = \bcpow((string) $from_base, (string) (Byte\length($value) - 1));
+ $place_value = \bcpow((string)$from_base, (string)(Byte\length($value) - 1));
/** @var string $digit */
foreach (Byte\chunk($value) as $digit) {
$digit_numeric = Byte\search_ci($from_alphabet, $digit);
Psl\invariant(null !== $digit_numeric, 'Invalid digit %s in base %d', $digit, $from_base);
- $result_decimal = \bcadd($result_decimal, \bcmul((string) $digit_numeric, $place_value));
+ $result_decimal = \bcadd($result_decimal, \bcmul((string)$digit_numeric, $place_value));
/** @var string $place_value */
- $place_value = \bcdiv($place_value, (string) $from_base);
+ $place_value = \bcdiv($place_value, (string)$from_base);
}
if (10 === $to_base) {
@@ -40,9 +50,9 @@ function base_convert(string $value, int $from_base, int $to_base): string
$to_alphabet = Byte\slice(Str\ALPHABET_ALPHANUMERIC, 0, $to_base);
$result = '';
do {
- $result = $to_alphabet[(int) \bcmod($result_decimal, (string) $to_base)] . $result;
+ $result = $to_alphabet[(int)\bcmod($result_decimal, (string)$to_base)] . $result;
/** @var string $result_decimal */
- $result_decimal = \bcdiv($result_decimal, (string) $to_base);
+ $result_decimal = \bcdiv($result_decimal, (string)$to_base);
} while (\bccomp($result_decimal, '0') > 0);
return $result;
diff --git a/src/Psl/Math/ceil.php b/src/Psl/Math/ceil.php
index 7304747..aa1f129 100644
--- a/src/Psl/Math/ceil.php
+++ b/src/Psl/Math/ceil.php
@@ -6,6 +6,17 @@ namespace Psl\Math;
/**
* Return the smallest integer value greater than or equal to the given number.
+ *
+ * Example:
+ *
+ * Math\ceil(5.5)
+ * => Float(6.0)
+ *
+ * Math\ceil(-10.0)
+ * => Float(-10.0)
+ *
+ * Math\ceil(-5.5)
+ * => Float(-5.0)
*/
function ceil(float $float): float
{
diff --git a/src/Psl/Math/constants.php b/src/Psl/Math/constants.php
index ec050c7..e41e6b8 100644
--- a/src/Psl/Math/constants.php
+++ b/src/Psl/Math/constants.php
@@ -21,6 +21,9 @@ const UINT16_MAX = 65535;
const PI = 3.141592653589793238462643;
+/**
+ * The base of the natural system of logarithms, or approximately 2.7182818284590452353602875.
+ */
const E = 2.7182818284590452353602875;
const INFINITY = \INF;
diff --git a/src/Psl/Math/cos.php b/src/Psl/Math/cos.php
index f074ccd..fa2006f 100644
--- a/src/Psl/Math/cos.php
+++ b/src/Psl/Math/cos.php
@@ -6,6 +6,14 @@ namespace Psl\Math;
/**
* Return the cosine of the given number.
+ *
+ * Example:
+ *
+ * Math\cos(0.0)
+ * => Float(1.0)
+ *
+ * Math\ceil(1.0)
+ * => Float(0.5403023058681398)
*/
function cos(float $num): float
{
diff --git a/src/Psl/Math/div.php b/src/Psl/Math/div.php
index 18f1b72..8310622 100644
--- a/src/Psl/Math/div.php
+++ b/src/Psl/Math/div.php
@@ -7,6 +7,17 @@ namespace Psl\Math;
/**
* Returns the result of integer division of the given numerator by the given denominator.
*
+ * Example:
+ *
+ * Math\div(10, 2)
+ * => Int(5)
+ *
+ * Math\div(5, 2)
+ * => Int(2)
+ *
+ * Math\div(15, 20)
+ * => Int(0)
+ *
* If the denominator is 0, a DivisionByZeroError exception is thrown.
* If the numerator is Math\INT64_MAX and the denominator is -1 then an ArithmeticError exception is thrown.
*/
diff --git a/src/Psl/Math/exp.php b/src/Psl/Math/exp.php
index d2e35ca..5c2264d 100644
--- a/src/Psl/Math/exp.php
+++ b/src/Psl/Math/exp.php
@@ -5,7 +5,15 @@ declare(strict_types=1);
namespace Psl\Math;
/**
- * Returns e to th power of the given number.
+ * Returns Math\E to the power of the given number.
+ *
+ * Example:
+ *
+ * Math\exp(12)
+ * => Float(162754.79141900392)
+ *
+ * Math\exp(5.7)
+ * => Float(298.8674009670603)
*/
function exp(float $num): float
{
diff --git a/src/Psl/Math/from_base.php b/src/Psl/Math/from_base.php
index 3dd005e..0039c3e 100644
--- a/src/Psl/Math/from_base.php
+++ b/src/Psl/Math/from_base.php
@@ -10,6 +10,14 @@ use Psl\Str\Byte;
/**
* Converts the given string in the given base to an int, assuming letters a-z
* are used for digits when `$from_base` > 10.
+ *
+ * Example:
+ *
+ * Math\from_base('10', 2)
+ * => Int(2)
+ *
+ * Math\from_base('ff', 15)
+ * => Int(255)
*/
function from_base(string $number, int $from_base): int
{
diff --git a/src/Psl/Math/max_by.php b/src/Psl/Math/max_by.php
index 9f248d2..cca047d 100644
--- a/src/Psl/Math/max_by.php
+++ b/src/Psl/Math/max_by.php
@@ -4,6 +4,8 @@ declare(strict_types=1);
namespace Psl\Math;
+use Psl;
+
/**
* Returns the largest element of the given iterable, or null if the
* iterable is empty.
@@ -24,6 +26,7 @@ function max_by(iterable $values, callable $num_func)
$max_num = null;
foreach ($values as $value) {
$value_num = $num_func($value);
+ Psl\invariant(\is_numeric($value_num), 'Expected $num_func to return a numeric value, %s returned.', \gettype($value_num));
if (null === $max_num || $value_num >= $max_num) {
$max = $value;
$max_num = $value_num;
diff --git a/tests/Psl/Math/AbsTest.php b/tests/Psl/Math/AbsTest.php
index 12fb1df..e0162ab 100644
--- a/tests/Psl/Math/AbsTest.php
+++ b/tests/Psl/Math/AbsTest.php
@@ -5,8 +5,40 @@ declare(strict_types=1);
namespace Psl\Tests\Math;
use PHPUnit\Framework\TestCase;
+use Psl\Math;
class AbsTest extends TestCase
{
- // TODO: add tests.
+ /**
+ * @dataProvider provideData
+ */
+ public function testAbs($expected, $number): void
+ {
+ self::assertSame($expected, Math\abs($number));
+ }
+
+ public function provideData(): array
+ {
+ return [
+ [
+ 5,
+ 5
+ ],
+
+ [
+ 5,
+ -5
+ ],
+
+ [
+ 5.5,
+ -5.5
+ ],
+
+ [
+ 10.5,
+ 10.5
+ ]
+ ];
+ }
}
diff --git a/tests/Psl/Math/BaseConvertTest.php b/tests/Psl/Math/BaseConvertTest.php
index ab8a0c2..387c419 100644
--- a/tests/Psl/Math/BaseConvertTest.php
+++ b/tests/Psl/Math/BaseConvertTest.php
@@ -5,8 +5,76 @@ declare(strict_types=1);
namespace Psl\Tests\Math;
use PHPUnit\Framework\TestCase;
+use Psl\Math;
class BaseConvertTest extends TestCase
{
- // TODO: add tests.
+ /**
+ * @dataProvider provideData
+ */
+ public function testBaseConvert(string $expected, string $value, int $from, int $to): void
+ {
+ self::assertSame($expected, Math\base_convert($value, $from, $to));
+ }
+
+ public function provideData(): array
+ {
+ return [
+ [
+ '2',
+ '10',
+ 2,
+ 16
+ ],
+
+ [
+ '2',
+ '10',
+ 2,
+ 10
+ ],
+
+ [
+ 'f',
+ '15',
+ 10,
+ 16
+ ],
+
+ [
+ '10',
+ '2',
+ 16,
+ 2
+ ],
+
+ [
+ '1010101111001',
+ '5497',
+ 10,
+ 2
+ ],
+
+ [
+ '48p',
+ '1010101111001',
+ 2,
+ 36
+ ],
+
+ [
+ 'pphlmw9v',
+ '2014587925987',
+ 10,
+ 36
+ ],
+
+ [
+ 'zik0zj',
+ (string) Math\INT32_MAX,
+ 10,
+ 36
+ ]
+ ];
+ }
}
diff --git a/tests/Psl/Math/CeilTest.php b/tests/Psl/Math/CeilTest.php
index 726c934..0ef708f 100644
--- a/tests/Psl/Math/CeilTest.php
+++ b/tests/Psl/Math/CeilTest.php
@@ -5,8 +5,45 @@ declare(strict_types=1);
namespace Psl\Tests\Math;
use PHPUnit\Framework\TestCase;
+use Psl\Math;
class CeilTest extends TestCase
{
- // TODO: add tests.
+ /**
+ * @dataProvider provideData
+ */
+ public function testCiel(float $expected, float $number): void
+ {
+ self::assertSame($expected, Math\ceil($number));
+ }
+
+ public function provideData(): array
+ {
+ return [
+ [
+ 5.0,
+ 5.0
+ ],
+
+ [
+ 5.0,
+ 4.8
+ ],
+
+ [
+ 0.0,
+ 0.0
+ ],
+
+ [
+ 1.0,
+ 0.4
+ ],
+
+ [
+ -6.0,
+ -6.5
+ ]
+ ];
+ }
}
diff --git a/tests/Psl/Math/CosTest.php b/tests/Psl/Math/CosTest.php
index 5ad5221..8070c75 100644
--- a/tests/Psl/Math/CosTest.php
+++ b/tests/Psl/Math/CosTest.php
@@ -5,8 +5,45 @@ declare(strict_types=1);
namespace Psl\Tests\Math;
use PHPUnit\Framework\TestCase;
+use Psl\Math;
class CosTest extends TestCase
{
- // TODO: add tests.
+ /**
+ * @dataProvider provideData
+ */
+ public function testCos(float $expected, float $number): void
+ {
+ self::assertSame($expected, Math\cos($number));
+ }
+
+ public function provideData(): array
+ {
+ return [
+ [
+ 0.5403023058681398,
+ 1.0
+ ],
+
+ [
+ 1.0,
+ 0.0
+ ],
+
+ [
+ 0.10291095660695612,
+ 45.45,
+ ],
+
+ [
+ 0.28366218546322625,
+ -5
+ ],
+
+ [
+ -0.9983206000589924,
+ -15.65
+ ]
+ ];
+ }
}
diff --git a/tests/Psl/Math/DivTest.php b/tests/Psl/Math/DivTest.php
index 7d5c8c1..28bb8b2 100644
--- a/tests/Psl/Math/DivTest.php
+++ b/tests/Psl/Math/DivTest.php
@@ -5,8 +5,44 @@ declare(strict_types=1);
namespace Psl\Tests\Math;
use PHPUnit\Framework\TestCase;
+use Psl\Math;
class DivTest extends TestCase
{
- // TODO: add tests.
+ /**
+ * @dataProvider provideData
+ */
+ public function testDiv(int $expected, int $numerator, int $denominator): void
+ {
+ self::assertSame($expected, Math\div($numerator, $denominator));
+ }
+
+ public function provideData(): array
+ {
+ return[
+ [
+ 2,
+ 5,
+ 2,
+ ],
+
+ [
+ 5,
+ 10,
+ 2
+ ],
+
+ [
+ 0,
+ 15,
+ 20
+ ],
+
+ [
+ 1,
+ 10,
+ 10
+ ]
+ ];
+ }
}
diff --git a/tests/Psl/Math/ExpTest.php b/tests/Psl/Math/ExpTest.php
index 4a12c82..c58cd4b 100644
--- a/tests/Psl/Math/ExpTest.php
+++ b/tests/Psl/Math/ExpTest.php
@@ -5,8 +5,35 @@ declare(strict_types=1);
namespace Psl\Tests\Math;
use PHPUnit\Framework\TestCase;
+use Psl\Math;
class ExpTest extends TestCase
{
- // TODO: add tests.
+ /**
+ * @dataProvider provideData
+ */
+ public function testExp(float $expected, float $number): void
+ {
+ self::assertSame($expected, Math\exp($number));
+ }
+
+ public function provideData(): array
+ {
+ return [
+ [
+ 162754.79141900392,
+ 12.0,
+ ],
+
+ [
+ 298.8674009670603,
+ 5.7,
+ ],
+
+ [
+ Math\INFINITY,
+ 1000000,
+ ]
+ ];
+ }
}
diff --git a/tests/Psl/Math/FloorTest.php b/tests/Psl/Math/FloorTest.php
index ba97502..fb3e875 100644
--- a/tests/Psl/Math/FloorTest.php
+++ b/tests/Psl/Math/FloorTest.php
@@ -5,8 +5,45 @@ declare(strict_types=1);
namespace Psl\Tests\Math;
use PHPUnit\Framework\TestCase;
+use Psl\Math;
class FloorTest extends TestCase
{
- // TODO: add tests.
+ /**
+ * @dataProvider provideData
+ */
+ public function testFloor(float $expected, float $number): void
+ {
+ self::assertSame($expected, Math\floor($number));
+ }
+
+ public function provideData(): array
+ {
+ return [
+ [
+ 4,
+ 4.3,
+ ],
+
+ [
+ 9,
+ 9.9,
+ ],
+
+ [
+ 3,
+ Math\PI
+ ],
+
+ [
+ -4,
+ -Math\PI
+ ],
+
+ [
+ 2,
+ Math\E
+ ]
+ ];
+ }
}
diff --git a/tests/Psl/Math/FromBaseTest.php b/tests/Psl/Math/FromBaseTest.php
index e5a8feb..c156e5a 100644
--- a/tests/Psl/Math/FromBaseTest.php
+++ b/tests/Psl/Math/FromBaseTest.php
@@ -5,8 +5,77 @@ declare(strict_types=1);
namespace Psl\Tests\Math;
use PHPUnit\Framework\TestCase;
+use Psl\Exception;
+use Psl\Math;
class FromBaseTest extends TestCase
{
- // TODO: add tests.
+ /**
+ * @dataProvider provideData
+ */
+ public function testFromBase(int $expected, string $value, int $from_base): void
+ {
+ self::assertSame($expected, Math\from_base($value, $from_base));
+ }
+
+ public function provideData(): array
+ {
+ return [
+ [
+ 5497,
+ '1010101111001',
+ 2
+ ],
+
+ [
+ 2014587925987,
+ 'pphlmw9v',
+ 36
+ ],
+
+ [
+ Math\INT32_MAX,
+ 'zik0zj',
+ 36
+ ],
+
+ [
+ 15,
+ 'F',
+ 16
+ ]
+ ];
+ }
+
+ public function testInvalidDigitThrows(): void
+ {
+ $this->expectException(Exception\InvariantViolationException::class);
+ $this->expectExceptionMessage('Invalid digit Z in base 16');
+
+ Math\from_base('Z', 16);
+ }
+
+ public function testSpecialCharThrows(): void
+ {
+ $this->expectException(Exception\InvariantViolationException::class);
+ $this->expectExceptionMessage('Invalid digit * in base 16');
+
+ Math\from_base('*', 16);
+ }
+
+ public function testEmptyValueThrows(): void
+ {
+ $this->expectException(Exception\InvariantViolationException::class);
+ $this->expectExceptionMessage('Unexpected empty string, expected number in base 16');
+
+ Math\from_base('', 16);
+ }
+
+ public function testInvalidFromBaseThrows(): void
+ {
+ $this->expectException(Exception\InvariantViolationException::class);
+ $this->expectExceptionMessage('Expected $from_base to be between 2 and 36, got 64');
+
+ Math\from_base('z', 64);
+ }
}
diff --git a/tests/Psl/Math/LogTest.php b/tests/Psl/Math/LogTest.php
index fa503cc..f0f663a 100644
--- a/tests/Psl/Math/LogTest.php
+++ b/tests/Psl/Math/LogTest.php
@@ -5,8 +5,69 @@ declare(strict_types=1);
namespace Psl\Tests\Math;
use PHPUnit\Framework\TestCase;
+use Psl\Exception;
+use Psl\Math;
class LogTest extends TestCase
{
- // TODO: add tests.
+ /**
+ * @dataProvider provideData
+ */
+ public function testLog(float $expected, float $number, ?float $base = null): void
+ {
+ self::assertSame($expected, Math\log($number, $base));
+ }
+
+ public function provideData(): array
+ {
+ return [
+ [
+ 1.6863989535702288,
+ 5.4,
+ null
+ ],
+
+ [
+ 0.6574784600188808,
+ 5.4,
+ 13
+ ],
+
+ [
+ 1.7323937598229686,
+ 54.0,
+ 10
+ ],
+
+ [
+ 0,
+ 1,
+ null
+ ],
+ ];
+ }
+
+ public function testNegativeInputThrows(): void
+ {
+ $this->expectException(Exception\InvariantViolationException::class);
+ $this->expectExceptionMessage('Expected positive number for log, got -45');
+
+ Math\log(-45);
+ }
+
+ public function testNonPositiveBaseThrows(): void
+ {
+ $this->expectException(Exception\InvariantViolationException::class);
+ $this->expectExceptionMessage('Expected positive base for log, got 0.0');
+
+ Math\log(4.4, 0.0);
+ }
+
+ public function testBaseOneThrowsForUndefinedLogarithm(): void
+ {
+ $this->expectException(Exception\InvariantViolationException::class);
+ $this->expectExceptionMessage('Logarithm undefined for base 1');
+
+ Math\log(4.4, 1.0);
+ }
}
diff --git a/tests/Psl/Math/MaxByTest.php b/tests/Psl/Math/MaxByTest.php
index 183d0e7..31ed39f 100644
--- a/tests/Psl/Math/MaxByTest.php
+++ b/tests/Psl/Math/MaxByTest.php
@@ -5,8 +5,50 @@ declare(strict_types=1);
namespace Psl\Tests\Math;
use PHPUnit\Framework\TestCase;
+use Psl\Iter;
+use Psl\Math;
+use Psl\Str;
class MaxByTest extends TestCase
{
- // TODO: add tests.
+ /**
+ * @dataProvider provideData
+ */
+ public function testMaxBy($expected, iterable $values, callable $fun): void
+ {
+ self::assertSame($expected, Math\max_by($values, $fun));
+ }
+
+ public function provideData(): array
+ {
+ return [
+ [
+ 'bazqux',
+ ['foo', 'bar', 'baz', 'qux', 'foobar', 'bazqux'],
+ fn ($value) => Str\length($value)
+ ],
+
+ [
+ ['foo', 'bar', 'baz'],
+ [
+ ['foo'],
+ ['foo', 'bar'],
+ ['foo', 'bar', 'baz']
+ ],
+ fn ($arr) => Iter\count($arr)
+ ],
+
+ [
+ 9,
+ Iter\range(0, 9),
+ fn ($i) => $i
+ ],
+
+ [
+ null,
+ [],
+ fn ($i) => $i
+ ]
+ ];
+ }
}
diff --git a/tests/Psl/Math/MaxTest.php b/tests/Psl/Math/MaxTest.php
index 450e802..b2d8782 100644
--- a/tests/Psl/Math/MaxTest.php
+++ b/tests/Psl/Math/MaxTest.php
@@ -5,8 +5,36 @@ declare(strict_types=1);
namespace Psl\Tests\Math;
use PHPUnit\Framework\TestCase;
+use Psl\Iter;
+use Psl\Math;
class MaxTest extends TestCase
{
- // TODO: add tests.
+ /**
+ * @dataProvider provideData
+ */
+ public function testMax($expected, iterable $numbers): void
+ {
+ self::assertSame($expected, Math\max($numbers));
+ }
+
+ public function provideData(): array
+ {
+ return [
+ [
+ 10,
+ Iter\range(0, 10, 2)
+ ],
+
+ [
+ 15,
+ [...Iter\to_array(Iter\range(0, 10)), 15]
+ ],
+
+ [
+ null,
+ []
+ ]
+ ];
+ }
}
diff --git a/tests/Psl/Math/MaxvaTest.php b/tests/Psl/Math/MaxvaTest.php
index 7278068..3dbe0dc 100644
--- a/tests/Psl/Math/MaxvaTest.php
+++ b/tests/Psl/Math/MaxvaTest.php
@@ -5,8 +5,45 @@ declare(strict_types=1);
namespace Psl\Tests\Math;
use PHPUnit\Framework\TestCase;
+use Psl\Iter;
+use Psl\Math;
class MaxvaTest extends TestCase
{
- // TODO: add tests.
+ /**
+ * @dataProvider provideData
+ */
+ public function testMaxva($expected, $first, $second, ...$rest): void
+ {
+ self::assertSame($expected, Math\maxva($first, $second, ...$rest));
+ }
+
+ public function provideData(): array
+ {
+ return [
+ [
+ 10,
+ 10,
+ 5,
+ ...Iter\range(0, 9, 2)
+ ],
+
+ [
+ 18,
+ 18,
+ 15,
+ ...Iter\to_array(Iter\range(0, 10)),
+ 15
+ ],
+
+ [
+ 64,
+ 19,
+ 15,
+ ...Iter\range(0, 45, 5),
+ 52,
+ 64
+ ]
+ ];
+ }
}
diff --git a/tests/Psl/Math/MeanTest.php b/tests/Psl/Math/MeanTest.php
index b4cd89d..c1466cd 100644
--- a/tests/Psl/Math/MeanTest.php
+++ b/tests/Psl/Math/MeanTest.php
@@ -5,8 +5,63 @@ declare(strict_types=1);
namespace Psl\Tests\Math;
use PHPUnit\Framework\TestCase;
+use Psl\Arr;
+use Psl\Iter;
+use Psl\Math;
class MeanTest extends TestCase
{
- // TODO: add tests.
+ /**
+ * @dataProvider provideData
+ */
+ public function testMean($expected, iterable $numbers): void
+ {
+ self::assertSame($expected, Math\mean($numbers));
+ }
+
+ public function provideData(): array
+ {
+ return [
+ [
+ 5.0,
+ [
+ 10,
+ 5,
+ ...Iter\range(0, 9, 2),
+ ],
+ ],
+
+ [
+ 7.357142857142858,
+ [
+ 18,
+ 15,
+ ...Iter\to_array(Iter\range(0, 10)),
+ 15,
+ ],
+ ],
+
+ [
+ 26.785714285714285,
+ [
+ 19,
+ 15,
+ ...Iter\range(0, 45, 5),
+ 52,
+ 64,
+ ],
+ ],
+
+ [
+ 100.0,
+ Arr\fill(100, 0, 100)
+ ],
+
+
+ [
+ null,
+ []
+ ]
+ ];
+ }
}
diff --git a/tests/Psl/Math/MedianTest.php b/tests/Psl/Math/MedianTest.php
index f015040..e3877b8 100644
--- a/tests/Psl/Math/MedianTest.php
+++ b/tests/Psl/Math/MedianTest.php
@@ -5,8 +5,62 @@ declare(strict_types=1);
namespace Psl\Tests\Math;
use PHPUnit\Framework\TestCase;
+use Psl\Arr;
+use Psl\Iter;
+use Psl\Math;
class MedianTest extends TestCase
{
- // TODO: add tests.
+ /**
+ * @dataProvider provideData
+ */
+ public function testMedian($expected, iterable $numbers): void
+ {
+ self::assertSame($expected, Math\median($numbers));
+ }
+
+ public function provideData(): array
+ {
+ return [
+ [
+ 5.0,
+ [
+ 10,
+ 5,
+ ...Iter\range(0, 9, 2),
+ ],
+ ],
+
+ [
+ 6.5,
+ [
+ 18,
+ 15,
+ ...Iter\to_array(Iter\range(0, 10)),
+ 15,
+ ],
+ ],
+
+ [
+ 22.5,
+ [
+ 19,
+ 15,
+ ...Iter\range(0, 45, 5),
+ 52,
+ 64,
+ ],
+ ],
+
+ [
+ 100.0,
+ Arr\fill(100, 0, 100)
+ ],
+
+ [
+ null,
+ []
+ ]
+ ];
+ }
}
diff --git a/tests/Psl/Math/MinByTest.php b/tests/Psl/Math/MinByTest.php
index dcd6fb9..30c6ef4 100644
--- a/tests/Psl/Math/MinByTest.php
+++ b/tests/Psl/Math/MinByTest.php
@@ -5,8 +5,50 @@ declare(strict_types=1);
namespace Psl\Tests\Math;
use PHPUnit\Framework\TestCase;
+use Psl\Iter;
+use Psl\Math;
+use Psl\Str;
class MinByTest extends TestCase
{
- // TODO: add tests.
+ /**
+ * @dataProvider provideData
+ */
+ public function testMinBy($expected, iterable $values, callable $fun): void
+ {
+ self::assertSame($expected, Math\min_by($values, $fun));
+ }
+
+ public function provideData(): array
+ {
+ return [
+ [
+ 'qux',
+ ['foo', 'bar', 'baz', 'qux', 'foobar', 'bazqux'],
+ fn ($value) => Str\length($value)
+ ],
+
+ [
+ ['foo'],
+ [
+ ['foo'],
+ ['foo', 'bar'],
+ ['foo', 'bar', 'baz']
+ ],
+ fn ($arr) => Iter\count($arr)
+ ],
+
+ [
+ 0,
+ Iter\range(0, 9),
+ fn ($i) => $i
+ ],
+
+ [
+ null,
+ [],
+ fn ($i) => $i
+ ]
+ ];
+ }
}
diff --git a/tests/Psl/Math/MinTest.php b/tests/Psl/Math/MinTest.php
index e5de154..23c0d7c 100644
--- a/tests/Psl/Math/MinTest.php
+++ b/tests/Psl/Math/MinTest.php
@@ -5,8 +5,37 @@ declare(strict_types=1);
namespace Psl\Tests\Math;
use PHPUnit\Framework\TestCase;
+use Psl\Iter;
+use Psl\Math;
class MinTest extends TestCase
{
- // TODO: add tests.
+
+ /**
+ * @dataProvider provideData
+ */
+ public function testMin($expected, iterable $numbers): void
+ {
+ self::assertSame($expected, Math\min($numbers));
+ }
+
+ public function provideData(): array
+ {
+ return [
+ [
+ 0,
+ Iter\range(0, 10, 2)
+ ],
+
+ [
+ 4,
+ [...Iter\to_array(Iter\range(5, 10)), 4]
+ ],
+
+ [
+ null,
+ []
+ ]
+ ];
+ }
}
diff --git a/tests/Psl/Math/MinvaTest.php b/tests/Psl/Math/MinvaTest.php
index 22ce2e6..919b1ed 100644
--- a/tests/Psl/Math/MinvaTest.php
+++ b/tests/Psl/Math/MinvaTest.php
@@ -5,8 +5,45 @@ declare(strict_types=1);
namespace Psl\Tests\Math;
use PHPUnit\Framework\TestCase;
+use Psl\Iter;
+use Psl\Math;
class MinvaTest extends TestCase
{
- // TODO: add tests.
+ /**
+ * @dataProvider provideData
+ */
+ public function testMainva($expected, $first, $second, ...$rest): void
+ {
+ self::assertSame($expected, Math\minva($first, $second, ...$rest));
+ }
+
+ public function provideData(): array
+ {
+ return [
+ [
+ 5,
+ 10,
+ 5,
+ ...Iter\range(7, 9, 2)
+ ],
+
+ [
+ 4,
+ 18,
+ 15,
+ ...Iter\to_array(Iter\range(4, 10)),
+ 15
+ ],
+
+ [
+ 15,
+ 19,
+ 15,
+ ...Iter\range(40, 45, 5),
+ 52,
+ 64
+ ]
+ ];
+ }
}
diff --git a/tests/Psl/Math/RoundTest.php b/tests/Psl/Math/RoundTest.php
index 7cab6a9..7f0c56c 100644
--- a/tests/Psl/Math/RoundTest.php
+++ b/tests/Psl/Math/RoundTest.php
@@ -5,8 +5,63 @@ declare(strict_types=1);
namespace Psl\Tests\Math;
use PHPUnit\Framework\TestCase;
+use Psl\Math;
class RoundTest extends TestCase
{
- // TODO: add tests.
+
+ /**
+ * @dataProvider provideData
+ */
+ public function testRound(float $expected, float $number, int $precision = 0): void
+ {
+ self::assertSame($expected, Math\round($number, $precision));
+ }
+
+ public function provideData(): array
+ {
+ return [
+ [
+ 5.46,
+ 5.45663,
+ 2,
+ ],
+
+ [
+ 4.8,
+ 4.811,
+ 1,
+ ],
+
+ [
+ 5.0,
+ 5.42,
+ 0
+ ],
+
+ [
+ 5.0,
+ 4.8,
+ 0
+ ],
+
+ [
+ 0.0,
+ 0.4242,
+ 0,
+ ],
+
+ [
+ 0.5,
+ 0.4634,
+ 1,
+ ],
+
+ [
+ -6.57778,
+ -6.5777777777,
+ 5,
+ ],
+ ];
+ }
}
diff --git a/tests/Psl/Math/SinTest.php b/tests/Psl/Math/SinTest.php
index fa920e6..e812a23 100644
--- a/tests/Psl/Math/SinTest.php
+++ b/tests/Psl/Math/SinTest.php
@@ -5,8 +5,46 @@ declare(strict_types=1);
namespace Psl\Tests\Math;
use PHPUnit\Framework\TestCase;
+use Psl\Math;
class SinTest extends TestCase
{
- // TODO: add tests.
+
+ /**
+ * @dataProvider provideData
+ */
+ public function testSin(float $expected, float $number): void
+ {
+ self::assertSame($expected, Math\sin($number));
+ }
+
+ public function provideData(): array
+ {
+ return [
+ [
+ -0.9589242746631385,
+ 5.0
+ ],
+
+ [
+ -0.9961646088358407,
+ 4.8
+ ],
+
+ [
+ 0.0,
+ 0.0
+ ],
+
+ [
+ 0.3894183423086505,
+ 0.4
+ ],
+
+ [
+ -0.21511998808781552,
+ -6.5
+ ]
+ ];
+ }
}
diff --git a/tests/Psl/Math/SqrtTest.php b/tests/Psl/Math/SqrtTest.php
index a00ef6a..3286fce 100644
--- a/tests/Psl/Math/SqrtTest.php
+++ b/tests/Psl/Math/SqrtTest.php
@@ -5,8 +5,51 @@ declare(strict_types=1);
namespace Psl\Tests\Math;
use PHPUnit\Framework\TestCase;
+use Psl\Math;
class SqrtTest extends TestCase
{
- // TODO: add tests.
+
+ /**
+ * @dataProvider provideData
+ */
+ public function testSqrt(float $expected, float $number): void
+ {
+ self::assertSame($expected, Math\sqrt($number));
+ }
+
+ public function provideData(): array
+ {
+ return [
+ [
+ 2.23606797749979,
+ 5.0
+ ],
+
+ [
+ 2.1908902300206643,
+ 4.8
+ ],
+
+ [
+ 0.6324555320336759,
+ 0.4
+ ],
+
+ [
+ 2.5495097567963922,
+ 6.5
+ ],
+
+ [
+ 1.4142135623730951,
+ 2
+ ],
+
+ [
+ 1,
+ 1
+ ]
+ ];
+ }
}
diff --git a/tests/Psl/Math/SumFloatsTest.php b/tests/Psl/Math/SumFloatsTest.php
index 1bc5778..36a4251 100644
--- a/tests/Psl/Math/SumFloatsTest.php
+++ b/tests/Psl/Math/SumFloatsTest.php
@@ -5,8 +5,51 @@ declare(strict_types=1);
namespace Psl\Tests\Math;
use PHPUnit\Framework\TestCase;
+use Psl\Iter;
+use Psl\Math;
class SumFloatsTest extends TestCase
{
- // TODO: add tests.
+ /**
+ * @dataProvider provideData
+ */
+ public function testSumFloats(float $expected, iterable $numbers): void
+ {
+ self::assertSame($expected, Math\sum_floats($numbers));
+ }
+
+ public function provideData(): array
+ {
+ return [
+ [
+ 116.70000000000005,
+ [
+ 10.9,
+ 5,
+ ...Iter\range(0, 9.8798, 0.48),
+ ],
+ ],
+
+ [
+ 103.0,
+ [
+ 18,
+ 15,
+ ...Iter\to_array(Iter\range(0, 10)),
+ 15,
+ ],
+ ],
+
+ [
+ 323.54,
+ [
+ 19.5,
+ 15.8,
+ ...Iter\range(0.5, 45, 5.98),
+ 52.8,
+ 64,
+ ]
+ ],
+ ];
+ }
}
diff --git a/tests/Psl/Math/SumTest.php b/tests/Psl/Math/SumTest.php
index a3a5d24..2f6038b 100644
--- a/tests/Psl/Math/SumTest.php
+++ b/tests/Psl/Math/SumTest.php
@@ -5,8 +5,51 @@ declare(strict_types=1);
namespace Psl\Tests\Math;
use PHPUnit\Framework\TestCase;
+use Psl\Iter;
+use Psl\Math;
class SumTest extends TestCase
{
- // TODO: add tests.
+ /**
+ * @dataProvider provideData
+ */
+ public function testSum(int $expected, iterable $numbers): void
+ {
+ self::assertSame($expected, Math\sum($numbers));
+ }
+
+ public function provideData(): array
+ {
+ return [
+ [
+ 60,
+ [
+ 10,
+ 5,
+ ...Iter\range(0, 9),
+ ],
+ ],
+
+ [
+ 103,
+ [
+ 18,
+ 15,
+ ...Iter\to_array(Iter\range(0, 10)),
+ 15,
+ ],
+ ],
+
+ [
+ 534,
+ [
+ 178,
+ 15,
+ ...Iter\range(0, 45, 5),
+ 52,
+ 64,
+ ]
+ ],
+ ];
+ }
}
diff --git a/tests/Psl/Math/TanTest.php b/tests/Psl/Math/TanTest.php
index aa476c2..4576952 100644
--- a/tests/Psl/Math/TanTest.php
+++ b/tests/Psl/Math/TanTest.php
@@ -5,8 +5,46 @@ declare(strict_types=1);
namespace Psl\Tests\Math;
use PHPUnit\Framework\TestCase;
+use Psl\Math;
class TanTest extends TestCase
{
- // TODO: add tests.
+
+ /**
+ * @dataProvider provideData
+ */
+ public function testTan(float $expected, float $number): void
+ {
+ self::assertSame($expected, Math\tan($number));
+ }
+
+ public function provideData(): array
+ {
+ return [
+ [
+ -3.380515006246586,
+ 5.0
+ ],
+
+ [
+ -11.384870654242922,
+ 4.8
+ ],
+
+ [
+ 0.0,
+ 0.0
+ ],
+
+ [
+ 0.4227932187381618,
+ 0.4
+ ],
+
+ [
+ -0.22027720034589682,
+ -6.5
+ ]
+ ];
+ }
}
diff --git a/tests/Psl/Math/ToBaseTest.php b/tests/Psl/Math/ToBaseTest.php
index f8b6640..c8b1921 100644
--- a/tests/Psl/Math/ToBaseTest.php
+++ b/tests/Psl/Math/ToBaseTest.php
@@ -5,8 +5,62 @@ declare(strict_types=1);
namespace Psl\Tests\Math;
use PHPUnit\Framework\TestCase;
+use Psl\Exception;
+use Psl\Math;
class ToBaseTest extends TestCase
{
- // TODO: add tests.
+
+ /**
+ * @dataProvider provideData
+ */
+ public function testFromBase(string $expected, int $value, int $to_base): void
+ {
+ self::assertSame($expected, Math\to_base($value, $to_base));
+ }
+
+ public function provideData(): array
+ {
+ return [
+ [
+ '1010101111001',
+ 5497,
+ 2
+ ],
+
+ [
+ 'pphlmw9v',
+ 2014587925987,
+ 36
+ ],
+
+ [
+ 'zik0zj',
+ Math\INT32_MAX,
+ 36
+ ],
+
+ [
+ 'f',
+ 15,
+ 16
+ ]
+ ];
+ }
+
+ public function testNegativeValueThrows(): void
+ {
+ $this->expectException(Exception\InvariantViolationException::class);
+ $this->expectExceptionMessage('Expected non-negative base conversion input, got -5');
+
+ Math\to_base(-5, 16);
+ }
+
+ public function testInvalidToBaseThrows(): void
+ {
+ $this->expectException(Exception\InvariantViolationException::class);
+ $this->expectExceptionMessage('Expected $to_base to be between 2 and 36, got 64');
+
+ Math\to_base(1, 64);
+ }
}