* * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ declare(strict_types=1); namespace League\Uri\UriTemplate; use ArrayIterator; use PHPUnit\Framework\Attributes\CoversClass; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\Attributes\Test; use PHPUnit\Framework\TestCase; use stdClass; use TypeError; #[CoversClass(VariableBag::class)] final class VariableBagTest extends TestCase { /** * @param array> $expected */ #[DataProvider('provideValidIterable')] public function testItCanBeInstantiatedWithAnIterable( iterable $iterable, array $expected, bool $isEmpty, int $count ): void { $bag = new VariableBag($iterable); self::assertSame($isEmpty, $bag->isEmpty()); self::assertSame(!$isEmpty, $bag->isNotEmpty()); self::assertCount($count, $bag); self::assertEquals($expected, iterator_to_array($bag)); } public static function provideValidIterable(): iterable { return [ 'array' => [ 'iterable' => ['name' => 'value'], 'expected' => ['name' => 'value'], 'isEmpty' => false, 'count' => 1, ], 'iterable' => [ 'iterable' => new ArrayIterator(['name' => 'value']), 'expected' => ['name' => 'value'], 'isEmpty' => false, 'count' => 1, ], 'empty array' => [ 'iterable' => [], 'expected' => [], 'isEmpty' => true, 'count' => 0, ], ]; } /** * @param int|float|string|bool|array $value the value to be assigned to the name * @param string|array $expected */ #[DataProvider('provideValidAssignParameters')] public function testItCanAssignNameAndValuesToTheBag( string $name, int|float|string|bool|array $value, string|array $expected ): void { $bag = new VariableBag(); $bag->assign($name, $value); self::assertSame($expected, $bag->fetch($name)); } public static function provideValidAssignParameters(): iterable { return [ 'string' => [ 'name' => 'foo', 'value' => 'bar', 'expected' => 'bar', ], 'integer' => [ 'name' => 'foo', 'value' => 12, 'expected' => '12', ], 'bool' => [ 'name' => 'foo', 'value' => false, 'expected' => '0', ], 'list' => [ 'name' => 'foo', 'value' => ['bar', true, 42], 'expected' => ['bar', '1', '42'], ], 'empty string' => [ 'name' => 'foo', 'value' => '', 'expected' => '', ], ]; } public function testItWillFailToAssignUnsupportedType(): void { self::expectException(TypeError::class); new VariableBag(['name' => new stdClass()]); /* @phpstan-ignore-line */ } public function testItWillFailToAssignNestedList(): void { self::expectException(TemplateCanNotBeExpanded::class); new VariableBag(['name' => ['foo' => ['bar' => 'baz']]]); /* @phpstan-ignore-line */ } public function testArrayAccess(): void { $bag = new VariableBag(['foo' => 'bar', 'yolo' => 42, 'list' => [1, 2, 'three']]); self::assertSame('bar', $bag['foo']); self::assertFalse(isset($bag['foobar'])); self::assertTrue(isset($bag['list'])); $bag['foobar'] = ['I am added']; self::assertTrue(isset($bag['foobar'])); unset($bag['yolo']); self::assertFalse(isset($bag['yolo'])); } public function testAssigningANullOffsetWillThrow(): void { $this->expectException(TypeError::class); $bag = new VariableBag(); $bag[] = 'yolo'; } public function testItCanReplaceItsValueWithThatOfAnotherInstance(): void { $bag = new VariableBag([ 'foo' => 'bar', 'list' => [1, 2, 'three'], ]); $defaultBag = new VariableBag([ 'foo' => 'bar', 'yolo' => 42, 'list' => 'this is a list', ]); $expected = new VariableBag([ 'foo' => 'bar', 'yolo' => 42, 'list' => [1, 2, 'three'], ]); self::assertEquals($expected, $bag->replace($defaultBag)); self::assertEquals($defaultBag, $defaultBag->replace($bag)); } #[Test] public function it_can_evaluate_if_the_bag_is_identical(): void { $bag = new VariableBag([ 'foo' => 'bar', 'yolo' => 42, 'list' => 'this is a list', ]); self::assertFalse($bag->equals(new ArrayIterator())); self::assertFalse($bag->equals(new stdClass())); self::assertFalse($bag->equals('bag')); self::assertFalse($bag->equals(new VariableBag())); self::assertTrue($bag->equals($bag)); } #[Test] public function it_can_filter_its_content(): void { $bag = new VariableBag([ 'foo' => 'bar', 'yolo' => 42, 'list' => 'this is a list', ]); self::assertCount(3, $bag); $newBag = $bag->filter(fn ($value, $key) => 'foo' === $key); self::assertFalse($newBag->equals($bag)); self::assertCount(1, $newBag); } }