123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610 |
- <?php
- /*
- * This file is part of Pimple.
- *
- * Copyright (c) 2009 Fabien Potencier
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is furnished
- * to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
- namespace Pimple\Tests;
- use PHPUnit\Framework\TestCase;
- use Pimple\Container;
- /**
- * @author Igor Wiedler <igor@wiedler.ch>
- */
- class PimpleTest extends TestCase
- {
- public function testWithString()
- {
- $pimple = new Container();
- $pimple['param'] = 'value';
- $this->assertEquals('value', $pimple['param']);
- }
- public function testWithClosure()
- {
- $pimple = new Container();
- $pimple['service'] = function () {
- return new Fixtures\Service();
- };
- $this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $pimple['service']);
- }
- public function testServicesShouldBeDifferent()
- {
- $pimple = new Container();
- $pimple['service'] = $pimple->factory(function () {
- return new Fixtures\Service();
- });
- $serviceOne = $pimple['service'];
- $this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $serviceOne);
- $serviceTwo = $pimple['service'];
- $this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $serviceTwo);
- $this->assertNotSame($serviceOne, $serviceTwo);
- }
- public function testShouldPassContainerAsParameter()
- {
- $pimple = new Container();
- $pimple['service'] = function () {
- return new Fixtures\Service();
- };
- $pimple['container'] = function ($container) {
- return $container;
- };
- $this->assertNotSame($pimple, $pimple['service']);
- $this->assertSame($pimple, $pimple['container']);
- }
- public function testIsset()
- {
- $pimple = new Container();
- $pimple['param'] = 'value';
- $pimple['service'] = function () {
- return new Fixtures\Service();
- };
- $pimple['null'] = null;
- $this->assertTrue(isset($pimple['param']));
- $this->assertTrue(isset($pimple['service']));
- $this->assertTrue(isset($pimple['null']));
- $this->assertFalse(isset($pimple['non_existent']));
- }
- public function testConstructorInjection()
- {
- $params = ['param' => 'value'];
- $pimple = new Container($params);
- $this->assertSame($params['param'], $pimple['param']);
- }
- public function testOffsetGetValidatesKeyIsPresent()
- {
- $this->expectException(\Pimple\Exception\UnknownIdentifierException::class);
- $this->expectExceptionMessage('Identifier "foo" is not defined.');
- $pimple = new Container();
- echo $pimple['foo'];
- }
- /**
- * @group legacy
- */
- public function testLegacyOffsetGetValidatesKeyIsPresent()
- {
- $this->expectException(\InvalidArgumentException::class);
- $this->expectExceptionMessage('Identifier "foo" is not defined.');
- $pimple = new Container();
- echo $pimple['foo'];
- }
- public function testOffsetGetHonorsNullValues()
- {
- $pimple = new Container();
- $pimple['foo'] = null;
- $this->assertNull($pimple['foo']);
- }
- public function testUnset()
- {
- $pimple = new Container();
- $pimple['param'] = 'value';
- $pimple['service'] = function () {
- return new Fixtures\Service();
- };
- unset($pimple['param'], $pimple['service']);
- $this->assertFalse(isset($pimple['param']));
- $this->assertFalse(isset($pimple['service']));
- }
- /**
- * @dataProvider serviceDefinitionProvider
- */
- public function testShare($service)
- {
- $pimple = new Container();
- $pimple['shared_service'] = $service;
- $serviceOne = $pimple['shared_service'];
- $this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $serviceOne);
- $serviceTwo = $pimple['shared_service'];
- $this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $serviceTwo);
- $this->assertSame($serviceOne, $serviceTwo);
- }
- /**
- * @dataProvider serviceDefinitionProvider
- */
- public function testProtect($service)
- {
- $pimple = new Container();
- $pimple['protected'] = $pimple->protect($service);
- $this->assertSame($service, $pimple['protected']);
- }
- public function testGlobalFunctionNameAsParameterValue()
- {
- $pimple = new Container();
- $pimple['global_function'] = 'strlen';
- $this->assertSame('strlen', $pimple['global_function']);
- }
- public function testRaw()
- {
- $pimple = new Container();
- $pimple['service'] = $definition = $pimple->factory(function () {
- return 'foo';
- });
- $this->assertSame($definition, $pimple->raw('service'));
- }
- public function testRawHonorsNullValues()
- {
- $pimple = new Container();
- $pimple['foo'] = null;
- $this->assertNull($pimple->raw('foo'));
- }
- public function testFluentRegister()
- {
- $pimple = new Container();
- $this->assertSame($pimple, $pimple->register($this->getMockBuilder('Pimple\ServiceProviderInterface')->getMock()));
- }
- public function testRawValidatesKeyIsPresent()
- {
- $this->expectException(\Pimple\Exception\UnknownIdentifierException::class);
- $this->expectExceptionMessage('Identifier "foo" is not defined.');
- $pimple = new Container();
- $pimple->raw('foo');
- }
- /**
- * @group legacy
- */
- public function testLegacyRawValidatesKeyIsPresent()
- {
- $this->expectException(\InvalidArgumentException::class);
- $this->expectExceptionMessage('Identifier "foo" is not defined.');
- $pimple = new Container();
- $pimple->raw('foo');
- }
- /**
- * @dataProvider serviceDefinitionProvider
- */
- public function testExtend($service)
- {
- $pimple = new Container();
- $pimple['shared_service'] = function () {
- return new Fixtures\Service();
- };
- $pimple['factory_service'] = $pimple->factory(function () {
- return new Fixtures\Service();
- });
- $pimple->extend('shared_service', $service);
- $serviceOne = $pimple['shared_service'];
- $this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $serviceOne);
- $serviceTwo = $pimple['shared_service'];
- $this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $serviceTwo);
- $this->assertSame($serviceOne, $serviceTwo);
- $this->assertSame($serviceOne->value, $serviceTwo->value);
- $pimple->extend('factory_service', $service);
- $serviceOne = $pimple['factory_service'];
- $this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $serviceOne);
- $serviceTwo = $pimple['factory_service'];
- $this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $serviceTwo);
- $this->assertNotSame($serviceOne, $serviceTwo);
- $this->assertNotSame($serviceOne->value, $serviceTwo->value);
- }
- public function testExtendDoesNotLeakWithFactories()
- {
- if (\extension_loaded('pimple')) {
- $this->markTestSkipped('Pimple extension does not support this test');
- }
- $pimple = new Container();
- $pimple['foo'] = $pimple->factory(function () {
- return;
- });
- $pimple['foo'] = $pimple->extend('foo', function ($foo, $pimple) {
- return;
- });
- unset($pimple['foo']);
- $p = new \ReflectionProperty($pimple, 'values');
- $p->setAccessible(true);
- $this->assertEmpty($p->getValue($pimple));
- $p = new \ReflectionProperty($pimple, 'factories');
- $p->setAccessible(true);
- $this->assertCount(0, $p->getValue($pimple));
- }
- public function testExtendValidatesKeyIsPresent()
- {
- $this->expectException(\Pimple\Exception\UnknownIdentifierException::class);
- $this->expectExceptionMessage('Identifier "foo" is not defined.');
- $pimple = new Container();
- $pimple->extend('foo', function () {
- });
- }
- /**
- * @group legacy
- */
- public function testLegacyExtendValidatesKeyIsPresent()
- {
- $this->expectException(\InvalidArgumentException::class);
- $this->expectExceptionMessage('Identifier "foo" is not defined.');
- $pimple = new Container();
- $pimple->extend('foo', function () {
- });
- }
- public function testKeys()
- {
- $pimple = new Container();
- $pimple['foo'] = 123;
- $pimple['bar'] = 123;
- $this->assertEquals(['foo', 'bar'], $pimple->keys());
- }
- /** @test */
- public function settingAnInvokableObjectShouldTreatItAsFactory()
- {
- $pimple = new Container();
- $pimple['invokable'] = new Fixtures\Invokable();
- $this->assertInstanceOf('Pimple\Tests\Fixtures\Service', $pimple['invokable']);
- }
- /** @test */
- public function settingNonInvokableObjectShouldTreatItAsParameter()
- {
- $pimple = new Container();
- $pimple['non_invokable'] = new Fixtures\NonInvokable();
- $this->assertInstanceOf('Pimple\Tests\Fixtures\NonInvokable', $pimple['non_invokable']);
- }
- /**
- * @dataProvider badServiceDefinitionProvider
- */
- public function testFactoryFailsForInvalidServiceDefinitions($service)
- {
- $this->expectException(\Pimple\Exception\ExpectedInvokableException::class);
- $this->expectExceptionMessage('Service definition is not a Closure or invokable object.');
- $pimple = new Container();
- $pimple->factory($service);
- }
- /**
- * @group legacy
- * @dataProvider badServiceDefinitionProvider
- */
- public function testLegacyFactoryFailsForInvalidServiceDefinitions($service)
- {
- $this->expectException(\InvalidArgumentException::class);
- $this->expectExceptionMessage('Service definition is not a Closure or invokable object.');
- $pimple = new Container();
- $pimple->factory($service);
- }
- /**
- * @dataProvider badServiceDefinitionProvider
- */
- public function testProtectFailsForInvalidServiceDefinitions($service)
- {
- $this->expectException(\Pimple\Exception\ExpectedInvokableException::class);
- $this->expectExceptionMessage('Callable is not a Closure or invokable object.');
- $pimple = new Container();
- $pimple->protect($service);
- }
- /**
- * @group legacy
- * @dataProvider badServiceDefinitionProvider
- */
- public function testLegacyProtectFailsForInvalidServiceDefinitions($service)
- {
- $this->expectException(\InvalidArgumentException::class);
- $this->expectExceptionMessage('Callable is not a Closure or invokable object.');
- $pimple = new Container();
- $pimple->protect($service);
- }
- /**
- * @dataProvider badServiceDefinitionProvider
- */
- public function testExtendFailsForKeysNotContainingServiceDefinitions($service)
- {
- $this->expectException(\Pimple\Exception\InvalidServiceIdentifierException::class);
- $this->expectExceptionMessage('Identifier "foo" does not contain an object definition.');
- $pimple = new Container();
- $pimple['foo'] = $service;
- $pimple->extend('foo', function () {
- });
- }
- /**
- * @group legacy
- * @dataProvider badServiceDefinitionProvider
- */
- public function testLegacyExtendFailsForKeysNotContainingServiceDefinitions($service)
- {
- $this->expectException(\InvalidArgumentException::class);
- $this->expectExceptionMessage('Identifier "foo" does not contain an object definition.');
- $pimple = new Container();
- $pimple['foo'] = $service;
- $pimple->extend('foo', function () {
- });
- }
- /**
- * @group legacy
- * @expectedDeprecation How Pimple behaves when extending protected closures will be fixed in Pimple 4. Are you sure "foo" should be protected?
- */
- public function testExtendingProtectedClosureDeprecation()
- {
- $pimple = new Container();
- $pimple['foo'] = $pimple->protect(function () {
- return 'bar';
- });
- $pimple->extend('foo', function ($value) {
- return $value.'-baz';
- });
- $this->assertSame('bar-baz', $pimple['foo']);
- }
- /**
- * @dataProvider badServiceDefinitionProvider
- */
- public function testExtendFailsForInvalidServiceDefinitions($service)
- {
- $this->expectException(\Pimple\Exception\ExpectedInvokableException::class);
- $this->expectExceptionMessage('Extension service definition is not a Closure or invokable object.');
- $pimple = new Container();
- $pimple['foo'] = function () {
- };
- $pimple->extend('foo', $service);
- }
- /**
- * @group legacy
- * @dataProvider badServiceDefinitionProvider
- */
- public function testLegacyExtendFailsForInvalidServiceDefinitions($service)
- {
- $this->expectException(\InvalidArgumentException::class);
- $this->expectExceptionMessage('Extension service definition is not a Closure or invokable object.');
- $pimple = new Container();
- $pimple['foo'] = function () {
- };
- $pimple->extend('foo', $service);
- }
- public function testExtendFailsIfFrozenServiceIsNonInvokable()
- {
- $this->expectException(\Pimple\Exception\FrozenServiceException::class);
- $this->expectExceptionMessage('Cannot override frozen service "foo".');
- $pimple = new Container();
- $pimple['foo'] = function () {
- return new Fixtures\NonInvokable();
- };
- $foo = $pimple['foo'];
- $pimple->extend('foo', function () {
- });
- }
- public function testExtendFailsIfFrozenServiceIsInvokable()
- {
- $this->expectException(\Pimple\Exception\FrozenServiceException::class);
- $this->expectExceptionMessage('Cannot override frozen service "foo".');
- $pimple = new Container();
- $pimple['foo'] = function () {
- return new Fixtures\Invokable();
- };
- $foo = $pimple['foo'];
- $pimple->extend('foo', function () {
- });
- }
- /**
- * Provider for invalid service definitions.
- */
- public function badServiceDefinitionProvider()
- {
- return [
- [123],
- [new Fixtures\NonInvokable()],
- ];
- }
- /**
- * Provider for service definitions.
- */
- public function serviceDefinitionProvider()
- {
- return [
- [function ($value) {
- $service = new Fixtures\Service();
- $service->value = $value;
- return $service;
- }],
- [new Fixtures\Invokable()],
- ];
- }
- public function testDefiningNewServiceAfterFreeze()
- {
- $pimple = new Container();
- $pimple['foo'] = function () {
- return 'foo';
- };
- $foo = $pimple['foo'];
- $pimple['bar'] = function () {
- return 'bar';
- };
- $this->assertSame('bar', $pimple['bar']);
- }
- public function testOverridingServiceAfterFreeze()
- {
- $this->expectException(\Pimple\Exception\FrozenServiceException::class);
- $this->expectExceptionMessage('Cannot override frozen service "foo".');
- $pimple = new Container();
- $pimple['foo'] = function () {
- return 'foo';
- };
- $foo = $pimple['foo'];
- $pimple['foo'] = function () {
- return 'bar';
- };
- }
- /**
- * @group legacy
- */
- public function testLegacyOverridingServiceAfterFreeze()
- {
- $this->expectException(\RuntimeException::class);
- $this->expectExceptionMessage('Cannot override frozen service "foo".');
- $pimple = new Container();
- $pimple['foo'] = function () {
- return 'foo';
- };
- $foo = $pimple['foo'];
- $pimple['foo'] = function () {
- return 'bar';
- };
- }
- public function testRemovingServiceAfterFreeze()
- {
- $pimple = new Container();
- $pimple['foo'] = function () {
- return 'foo';
- };
- $foo = $pimple['foo'];
- unset($pimple['foo']);
- $pimple['foo'] = function () {
- return 'bar';
- };
- $this->assertSame('bar', $pimple['foo']);
- }
- public function testExtendingService()
- {
- $pimple = new Container();
- $pimple['foo'] = function () {
- return 'foo';
- };
- $pimple['foo'] = $pimple->extend('foo', function ($foo, $app) {
- return "$foo.bar";
- });
- $pimple['foo'] = $pimple->extend('foo', function ($foo, $app) {
- return "$foo.baz";
- });
- $this->assertSame('foo.bar.baz', $pimple['foo']);
- }
- public function testExtendingServiceAfterOtherServiceFreeze()
- {
- $pimple = new Container();
- $pimple['foo'] = function () {
- return 'foo';
- };
- $pimple['bar'] = function () {
- return 'bar';
- };
- $foo = $pimple['foo'];
- $pimple['bar'] = $pimple->extend('bar', function ($bar, $app) {
- return "$bar.baz";
- });
- $this->assertSame('bar.baz', $pimple['bar']);
- }
- }
|