<?php
// VersionTest.php
// Created: 2021-04-30
// Updated: 2024-07-31

declare(strict_types=1);

use PHPUnit\Framework\TestCase;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\UsesClass;
use Index\Version;
use Index\XArray;

#[CoversClass(Version::class)]
#[UsesClass(XArray::class)]
final class VersionTest extends TestCase {
    public function testParse(): void {
        $tests = [
            '1.0.0',
            'v2.4.2',
            '1.0.0-alpha',
            '1.0.0-alpha.1',
            '1.0.0-0.3.7',
            '1.0.0-0.3.7',
            'v1.0.0-alpha+001',
            '1.0.0-beta+exp.sha.5114f85',
            'v1.0.0+21AF26D3--117B344092BD',
        ];

        foreach($tests as $test) {
            $version = Version::parse($test);
            $this->assertEquals($test, (string)$test);
        }

        $build = Version::parse('v1.0.0+21AF26D3--117B344092BD');
        $pre = Version::parse('1.0.0-alpha');
        $both = Version::parse('1.0.0-beta+exp.sha.5114f85');

        $this->assertFalse($build->isPrerelease());
        $this->assertTrue($pre->isPrerelease());
        $this->assertTrue($both->isPrerelease());

        $this->assertTrue(XArray::sequenceEquals($build->getBuild(), ['21AF26D3--117B344092BD']));
        $this->assertTrue(XArray::sequenceEquals($pre->getPrerelease(), ['alpha']));
        $this->assertTrue(XArray::sequenceEquals($both->getPrerelease(), ['beta']));
        $this->assertTrue(XArray::sequenceEquals($both->getBuild(), ['exp', 'sha', '5114f85']));
    }

    public function testCompare(): void {
        $v1_0_0_alpha = Version::parse('v1.0.0-alpha');
        $v1_0_0 = Version::parse('1.0.0');
        $v1_0_0_build = Version::parse('1.0.0+build');
        $v2_0_0 = Version::parse('v2.0.0');
        $v2_1_0 = new Version(2, 1);
        $v2_1_1 = new Version(2, 1, 1);

        $this->assertEquals(0, $v1_0_0->compare($v1_0_0_build));
        $this->assertEquals(-1, $v2_0_0->compare($v2_1_0));
        $this->assertEquals(-1, $v2_0_0->compare($v2_1_0));
        $this->assertEquals(-1, $v1_0_0->compare($v2_0_0));
        $this->assertEquals(-1, $v1_0_0_alpha->compare($v1_0_0));
    }

    public function testEquals(): void {
        $v1_0_0_alpha = Version::parse('v1.0.0-alpha');
        $v1_0_0 = Version::parse('1.0.0');
        $v1_0_0_build = Version::parse('1.0.0+build');
        $v2_0_0 = Version::parse('v2.0.0');
        $v2_1_0 = new Version(2, 1);
        $v2_1_1 = new Version(2, 1, 1);

        $this->assertTrue($v1_0_0->equals($v1_0_0_build));
        $this->assertFalse($v2_0_0->equals($v2_1_0));
        $this->assertFalse($v2_0_0->equals($v2_1_0));
        $this->assertFalse($v1_0_0->equals($v2_0_0));
        $this->assertFalse($v1_0_0_alpha->equals($v1_0_0));
    }
}