<?php

namespace App\Tests\Unit\Service\Utils;

use App\Service\Utils\ArrayUtils;
use PHPUnit\Framework\TestCase;

class ArrayUtilsTest extends TestCase
{
    /**
     * @øee ArrayUtils::getChanges()
     */
    public function testGetChanges(): void
    {
        $arrayUtils = new ArrayUtils();

        // Non-recursive (default)
        $this->assertEquals(
            ['b' => -2, 'c' => ['d' => 4, 'e' => ['f' => -5]], 'g' => 7],
            $arrayUtils->getChanges(
                ['a' => 1, 'b' => 2, 'c' => ['d' => 4, 'e' => ['f' => 5]]],
                ['a' => 1, 'b' => -2, 'c' => ['d' => 4, 'e' => ['f' => -5]], 'g' => 7],
            )
        );

        // Recursive
        $this->assertEquals(
            ['b' => -2, 'c' => ['e' => ['f' => -5]], 'g' => 7],
            $arrayUtils->getChanges(
                ['a' => 1, 'b' => 2, 'c' => ['d' => 4, 'e' => ['f' => 5]]],
                ['a' => 1, 'b' => -2, 'c' => ['d' => 4, 'e' => ['f' => -5]], 'g' => 7],
                true
            )
        );

        // Recursive with unchanged sub array
        $this->assertEquals(
            ['b' => -2],
            $arrayUtils->getChanges(
                ['a' => 1, 'b' => 2, 'c' => ['d' => 4, 'e' => ['f' => 5]]],
                ['a' => 1, 'b' => -2, 'c' => ['d' => 4, 'e' => ['f' => 5]]],
                true
            )
        );

        // No changes
        $this->assertEquals(
            [],
            $arrayUtils->getChanges(
                ['a' => 1, 'b' => 2, 'c' => ['d' => 4, 'e' => ['f' => 5]]],
                ['a' => 1, 'b' => 2, 'c' => ['d' => 4, 'e' => ['f' => 5]]],
            )
        );

        // Empty arrays
        $this->assertEquals(
            [],
            $arrayUtils->getChanges(
                [],
                [],
            )
        );

        // First array is empty
        $this->assertEquals(
            ['a' => 1],
            $arrayUtils->getChanges(
                [],
                ['a' => 1],
            )
        );

        // With callback
        $this->assertEquals(
            ['a' => 2],
            $arrayUtils->getChanges(
                ['a' => 1, 'b' => ''],
                ['a' => 2, 'b' => null],
                false,
                static function ($v1, $v2) { return ($v1 ?? '') === ($v2 ?? ''); }
            )
        );
    }
}
