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
54 changes: 53 additions & 1 deletion .github/workflows/mutation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,59 @@ jobs:
mutation:
uses: php-forge/actions/.github/workflows/infection.yml@main
with:
extensions: pdo, pdo_pgsql, pdo_sqlite
framework-options: --test-framework-options="--group=sqlite,mutation"
hook: |
# Config MySQL with Docker
docker run -d \
--name mysql-test \
-e MYSQL_ROOT_PASSWORD=root \
-e MYSQL_DATABASE=yiitest \
-e MYSQL_USER=test \
-e MYSQL_PASSWORD=test \
-p 3306:3306 \
--health-cmd="mysqladmin ping -h localhost" \
--health-interval=10s \
--health-timeout=5s \
--health-retries=5 \
mysql:8.0

# Config PostgreSQL with Docker
docker run -d \
--name postgres-test \
-e POSTGRES_DB=yiitest \
-e POSTGRES_USER=root \
-e POSTGRES_PASSWORD=root \
-p 5432:5432 \
--health-cmd="pg_isready -U postgres" \
--health-interval=10s \
--health-timeout=5s \
--health-retries=3 \
postgres:16

# Wait for MySQL to be ready
echo "Waiting for MySQL to be ready..."
timeout 120s bash -c 'until docker exec mysql-test mysqladmin ping -h localhost --silent; do sleep 3; done'

# Wait for PostgreSQL to be ready
echo "Waiting for PostgreSQL to be ready..."
timeout 60s bash -c 'until docker exec postgres-test pg_isready -U postgres; do sleep 2; done'

# Check if MySQL is running
echo "Testing MySQL connection..."
docker exec mysql-test mysql -u root -proot -e "SELECT VERSION();"

# Check if PostgreSQL is running
echo "Testing PostgreSQL connection..."
docker exec postgres-test psql -U root -d yiitest -c "SELECT version();"

# Set environment variables for MySQL and PostgreSQL
echo "MYSQL_DSN=mysql:host=localhost;port=3306;dbname=yiitest" >> $GITHUB_ENV
echo "MYSQL_USERNAME=root" >> $GITHUB_ENV
echo "MYSQL_PASSWORD=root" >> $GITHUB_ENV
echo "PGSQL_DSN=pgsql:host=localhost;port=5432;dbname=yiitest" >> $GITHUB_ENV
echo "PGSQL_USERNAME=root" >> $GITHUB_ENV
echo "PGSQL_PASSWORD=root" >> $GITHUB_ENV
phpstan: true
framework-options: --test-framework-options="--group=sqlite"
secrets:
STRYKER_DASHBOARD_API_KEY: ${{ secrets.STRYKER_DASHBOARD_API_KEY }}
84 changes: 84 additions & 0 deletions tests/mysql/MutationTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<?php

declare(strict_types=1);

namespace yii2\extensions\nestedsets\tests\mysql;

use PHPUnit\Framework\Attributes\Group;
use yii2\extensions\nestedsets\tests\support\model\MultipleTree;
use yii2\extensions\nestedsets\tests\TestCase;

#[Group('mutation')]
final class MutationTest extends TestCase
{
protected string $driverName = 'mysql';
protected string|null $dsn = 'mysql:host=127.0.0.1;dbname=yiitest;charset=utf8mb4';
protected string $password = 'root';
protected string $username = 'root';

public function testLeavesMethodRequiresLeftAttributeOrderingForConsistentResults(): void
{
$this->createDatabase();

$root = new MultipleTree(['name' => 'Root']);

$root->makeRoot();

$leaf1 = new MultipleTree(['name' => 'Leaf A']);

$leaf1->appendTo($root);

$leaf2 = new MultipleTree(['name' => 'Leaf B']);

$leaf2->appendTo($root);

$initialLeaves = MultipleTree::find()->leaves()->all();

self::assertCount(
2,
$initialLeaves,
"Should have exactly '2' initial leaf nodes.",
);

$command = $this->getDb()->createCommand();

$command->update('multiple_tree', ['lft' => 3, 'rgt' => 4], ['name' => 'Leaf B'])->execute();
$command->update('multiple_tree', ['lft' => 5, 'rgt' => 6], ['name' => 'Leaf A'])->execute();
$command->update('multiple_tree', ['lft' => 1, 'rgt' => 7], ['name' => 'Root'])->execute();

$leaves = MultipleTree::find()->leaves()->all();

/** @phpstan-var array<array{name: string, lft: int}> */
$expectedLeaves = [
['name' => 'Leaf B', 'lft' => 3],
['name' => 'Leaf A', 'lft' => 5],
];

self::assertCount(
2,
$leaves,
"Should return exactly '2' leaf nodes.",
);

foreach ($leaves as $index => $leaf) {
self::assertInstanceOf(
MultipleTree::class,
$leaf,
"Leaf at index {$index} should be an instance of 'MultipleTree'.",
);

if (isset($expectedLeaves[$index])) {
self::assertEquals(
$expectedLeaves[$index]['name'],
$leaf->getAttribute('name'),
"Leaf at index {$index} should be {$expectedLeaves[$index]['name']} in correct order.",
);
self::assertEquals(
$expectedLeaves[$index]['lft'],
$leaf->getAttribute('lft'),
"Leaf at index {$index} should have left value {$expectedLeaves[$index]['lft']}.",
);
}
}
}
}
38 changes: 38 additions & 0 deletions tests/pgsql/MutationTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

declare(strict_types=1);

namespace yii2\extensions\nestedsets\tests\pgsql;

use PHPUnit\Framework\Attributes\Group;
use yii2\extensions\nestedsets\tests\TestCase;

#[Group('mutation')]
final class MutationTest extends TestCase
{
protected string $driverName = 'pgsql';
protected string|null $dsn = 'pgsql:host=localhost;dbname=yiitest;port=5432;';
protected string $password = 'root';
protected string $username = 'root';

public function testChildrenMethodRequiresOrderByForCorrectTreeTraversal(): void
{
$expectedOrder = ['Child A', 'Child B', 'Child C'];

$treeStructure = [
['name' => 'Root', 'children' => ['Child B', 'Child C', 'Child A']],
];

$updates = [
['name' => 'Child B', 'lft' => 4, 'rgt' => 5],
['name' => 'Child C', 'lft' => 6, 'rgt' => 7],
['name' => 'Child A', 'lft' => 2, 'rgt' => 3],
['name' => 'Root', 'rgt' => 8],
];

$tree = $this->createTreeStructure($treeStructure, $updates);
$nodeList = $tree->children()->all();

$this->assertNodesInCorrectOrder($nodeList, $expectedOrder, 'Child');
}
}