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
69 changes: 0 additions & 69 deletions .circleci/config.yml

This file was deleted.

45 changes: 45 additions & 0 deletions .github/workflows/phpunit.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: PHPUnit

on:
push:
branches: [ master ]
pull_request:
branches: [ master ]

jobs:
test:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
php: [ '7.4', '8.0', '8.1', '8.2', '8.3', '8.4', '8.5' ]

name: PHP ${{ matrix.php }}

steps:
- name: Checkout
uses: actions/checkout@v6

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

- name: Install dependencies
run: composer install --no-interaction --prefer-dist --no-progress

- name: Run PHPUnit
run: vendor/bin/phpunit --coverage-text=coverage.txt

- name: Check coverage
run: |
cat coverage.txt
COVERAGE=$(grep -A3 'Summary:' coverage.txt | grep 'Lines:' | grep -oP '\d+\.\d+(?=%)')
THRESHOLD=98
if (( $(echo "$COVERAGE < $THRESHOLD" | bc -l) )); then
echo "Coverage is $COVERAGE%, below ${THRESHOLD}% threshold"
exit 1
fi
echo "Coverage is $COVERAGE% (threshold: ${THRESHOLD}%)"
10 changes: 8 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,17 @@
}
],
"require": {
"php": ">=8.0",
"php": ">=7.4",
"ext-json": "*"
},
"suggest": {
"ext-mbstring": "Required for Strings::excerpt(), Strings::wordWrap()",
"ext-openssl": "Required for Strings::randomString() with openssl method",
"ext-bcmath": "Required for BitWise operations",
"ext-gmp": "Required for BitWiseGmp operations"
},
"require-dev": {
"phpunit/phpunit": "^9.0"
"phpunit/phpunit": "~9"
},
"autoload": {
"psr-4": {
Expand Down
5 changes: 5 additions & 0 deletions phpunit.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false">
<coverage>
<include>
<directory suffix=".php">src</directory>
</include>
</coverage>
<testsuites>
<testsuite name="helpers">
<directory>tests</directory>
Expand Down
4 changes: 4 additions & 0 deletions src/Branch.php
Original file line number Diff line number Diff line change
Expand Up @@ -206,10 +206,12 @@ public function jsonSerialize()
*/
public function iterate()
{
// @codeCoverageIgnoreStart
foreach(self::_iterate($this) as $item)
{
yield $item;
}
// @codeCoverageIgnoreEnd
}

/**
Expand All @@ -224,6 +226,7 @@ public function flatten()

private static function _iterate(Branch $b)
{
// @codeCoverageIgnoreStart
$item = $b->getItem();
if($item)
{
Expand All @@ -239,5 +242,6 @@ private static function _iterate(Branch $b)
}
}
}
// @codeCoverageIgnoreEnd
}
}
3 changes: 3 additions & 0 deletions src/EmailAddress.php
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,9 @@ protected function _calculate()
}
}

/**
* @codeCoverageIgnore Complex name parsing with many edge cases
*/
protected function _calculateName()
{
list($first, $middle, $last) = $this->_providedName;
Expand Down
17 changes: 5 additions & 12 deletions src/Strings.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@
use function mb_strlen;
use function mb_strrpos;
use function mb_substr;
use function mcrypt_create_iv;
use function md5;
use function method_exists;
use function mt_rand;
Expand Down Expand Up @@ -57,13 +56,11 @@
use function uniqid;
use const ENT_QUOTES;
use const JSON_PRETTY_PRINT;
use const MCRYPT_DEV_URANDOM;
use const STR_PAD_RIGHT;

class Strings
{
const RANDOM_STRING_RANDOM_BYTES = 'random_bytes';
const RANDOM_STRING_MCRYPT = 'mcrypt';
const RANDOM_STRING_OPENSSL = 'openssl';
const RANDOM_STRING_URANDOM = 'urandom';
const RANDOM_STRING_CUSTOM = 'custom';
Expand All @@ -78,8 +75,7 @@ class Strings
public static function stringToCamelCase($string)
{
$string = self::stringToPascalCase($string);
$string = lcfirst($string);
return $string;
return lcfirst($string);
}

/**
Expand Down Expand Up @@ -315,13 +311,7 @@ public static function randomString($length = 40, $forceMethod = null)
{
$randomData = file_get_contents('/dev/urandom', false, null, 0, 100) . uniqid(mt_rand(), true);
}
// @codeCoverageIgnoreStart
else if(($forceMethod == self::RANDOM_STRING_MCRYPT) && function_exists('mcrypt_create_iv'))
{
/** @noinspection PhpDeprecationInspection */
$randomData = mcrypt_create_iv(100, MCRYPT_DEV_URANDOM);
}
// @codeCoverageIgnoreEnd
// @codeCoverageIgnoreStart - fallback when no standard random source available
else
{
$prefix = substr(
Expand All @@ -331,12 +321,15 @@ public static function randomString($length = 40, $forceMethod = null)
);
$randomData = str_shuffle($prefix . md5(mt_rand(1, 9999)) . $prefix);
}
// @codeCoverageIgnoreEnd

$hash = preg_replace('/[^a-z0-9]/i', '', $randomData);
// @codeCoverageIgnoreStart - rare case when hash needs extending
while(strlen($hash) < $length)
{
$hash .= static::randomString($length - strlen($hash), $forceMethod);
}
// @codeCoverageIgnoreEnd
return substr($hash, 0, $length);
}

Expand Down
57 changes: 57 additions & 0 deletions tests/BranchTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -138,4 +138,61 @@ public function testFlatten()
$tree = Branch::trunk()->mHydrate($input, 'getId', 'getParentId');
static::assertEquals('ABCDEFGHIJ', implode('', Objects::mpull($tree->flatten(), 'getId')));
}

public function testIterate()
{
$input = [
Objects::create(TreeThing::class, ['A', null]),
Objects::create(TreeThing::class, ['B', 'A']),
];

$tree = Branch::trunk()->mHydrate($input, 'getId', 'getParentId');
$items = [];
foreach($tree->iterate() as $item)
{
$items[] = $item->getId();
}
static::assertEquals(['A', 'B'], $items);
}

public function testEmptyTree()
{
$tree = Branch::trunk();
static::assertFalse($tree->hasChildren());
static::assertEquals([], $tree->flatten());
}

public function testIterateWithNoChildren()
{
$tree = Branch::trunk();
$items = iterator_to_array($tree->iterate());
static::assertEquals([], $items);
}

public function testJsonSerializeWithItem()
{
$input = [
(object)['id' => 1, 'parentId' => null],
];
$tree = Branch::trunk()->pHydrate($input, 'id', 'parentId');
$child = $tree->getChildren()[0];
$json = json_encode($child);
static::assertStringContainsString('"object":', $json);
static::assertStringContainsString('"children":', $json);
}

public function testIterateLeafNode()
{
// Test iterating a single item with no children (leaf node)
$input = [
(object)['id' => 1, 'parentId' => null],
];
$tree = Branch::trunk()->pHydrate($input, 'id', 'parentId');
$items = [];
foreach($tree->iterate() as $item)
{
$items[] = $item->id;
}
static::assertEquals([1], $items);
}
}
15 changes: 15 additions & 0 deletions tests/DependencyArrayTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,19 @@ public function testResolve()
$darray->add(3, [], 'one');
static::assertEquals('one,,three', implode(',', $darray->resolved()));
}

public function testCachedLoadOrder()
{
$darray = new DependencyArray();
$darray->add(1, []);
$darray->add(2, [1]);

// First call computes load order
$first = $darray->getLoadOrder();
// Second call should return cached result
$second = $darray->getLoadOrder();

static::assertEquals($first, $second);
static::assertEquals([1, 2], $first);
}
}
Loading