<?php
/*
* This file is part of Chevere.
*
* (c) Rodolfo Berrios <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
declare(strict_types=1);
namespace Chevere\Tests;
use Chevere\Parameter\Interfaces\TypeInterface;
use Chevere\Parameter\UnionParameter;
use InvalidArgumentException;
use LogicException;
use PHPUnit\Framework\TestCase;
use function Chevere\Parameter\arguments;
use function Chevere\Parameter\float;
use function Chevere\Parameter\int;
use function Chevere\Parameter\null;
use function Chevere\Parameter\parameters;
use function Chevere\Parameter\string;
use function Chevere\Parameter\union;
final class UnionParameterTest extends TestCase
{
public function testConstructError(): void
{
$parameters = parameters(
foo: string(),
);
$this->expectException(LogicException::class);
$this->expectExceptionMessage('Must pass at least two parameters for union');
new UnionParameter($parameters);
}
public function testConstruct(): void
{
$parameters = parameters(
foo: string(),
bar: int()
);
$parameter = new UnionParameter($parameters);
$this->assertSame(
TypeInterface::UNION,
$parameter->type()->primitive()
);
$this->assertCount(2, $parameter->parameters());
$this->assertSame(TypeInterface::UNION, $parameter->typeSchema());
$parameter('string');
$parameter(123);
}
public function testWithAdded(): void
{
$foo = string();
$bar = int();
$baz = float();
$pun = null();
$parameters = parameters(
foo: $foo,
bar: $bar
);
$parameter = new UnionParameter($parameters);
$with = $parameter->withAdded(
baz: $baz,
pun: $pun
);
$this->assertNotSame($parameter, $with);
$this->assertCount(4, $with->parameters());
$this->assertSame($foo, $with->parameters()->get('foo'));
$this->assertSame($bar, $with->parameters()->get('bar'));
$this->assertSame($baz, $with->parameters()->get('baz'));
$this->assertSame($pun, $with->parameters()->get('pun'));
}
public function testAssertCompatible(): void
{
$parameters = parameters(
int: int(),
string: string(),
);
$parametersAlt = parameters(
string: string(description: 'one'),
int: int(),
);
$parameter = new UnionParameter($parameters);
$compatible = new UnionParameter($parametersAlt);
$this->expectNotToPerformAssertions();
$parameter->assertCompatible($compatible);
}
public function testAssertNotCompatible(): void
{
$parameters = parameters(
string(),
int(),
);
$parametersAlt = parameters(
int(),
string(),
);
$parameter = new UnionParameter($parameters);
$compatible = new UnionParameter($parametersAlt);
$this->expectException(InvalidArgumentException::class);
$parameter->assertCompatible($compatible);
}
public function testUnionArguments(): void
{
$parameter = union(
string(),
int()
);
$array = [
0 => 'foo',
1 => 1,
];
$arguments = arguments($parameter, $array);
$this->assertSame($array['0'], $arguments->required('0')->string());
$this->assertSame($array['1'], $arguments->required('1')->int());
}
public function testInvoke(): void
{
$parameter = union(
string(),
int()
);
$parameter(10);
$parameter('10');
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage(
<<<PLAIN
Argument provided doesn't match union: Parameter `0` <Chevere\Parameter\StringParameter>: Argument must be of type Stringable|string, float given; Parameter `1` <Chevere\Parameter\IntParameter>: Argument must be of type int, float given
PLAIN
);
$parameter(1.1);
}
public function testWithDefault(): void
{
$parameter = union(
string(),
int()
);
$this->assertSame(null, $parameter->default());
$with = $parameter->withDefault(10);
$this->assertNotSame($parameter, $with);
$this->assertSame(10, $with->default());
$this->expectException(InvalidArgumentException::class);
$this->expectExceptionMessage(
<<<PLAIN
Argument provided doesn't match union: Parameter `0` <Chevere\Parameter\StringParameter>: Argument must be of type Stringable|string, array given; Parameter `1` <Chevere\Parameter\IntParameter>: Argument must be of type int, array given
PLAIN
);
$parameter->withDefault([]);
}
}
|