diff --git a/composer.json b/composer.json index 432743e..6b936c2 100644 --- a/composer.json +++ b/composer.json @@ -3,7 +3,7 @@ "type": "library", "homepage": "https://github.com/Respect/Config", "description": "A powerful, small, deadly simple configurator and dependency injection container made to be easy.", - "keywords": ["respect", "config", "dic", "dependency injection"], + "keywords": ["respect", "config", "dic", "dependency injection", "psr-11", "container"], "license": "BSD-3-Clause", "authors": [ { @@ -18,9 +18,11 @@ }, "require": { "php": ">=5.3.0", - "container-interop/container-interop": "^1.1" + "psr/container": "^1.0" }, "require-dev": { + "ext-PDO": "*", + "ext-pdo_sqlite": "*", "phpunit/phpunit": "~4.4", "respect/test": "dev-master" }, diff --git a/library/Respect/Config/Container.php b/library/Respect/Config/Container.php index f74c580..8d80f2a 100644 --- a/library/Respect/Config/Container.php +++ b/library/Respect/Config/Container.php @@ -2,11 +2,11 @@ namespace Respect\Config; -use InvalidArgumentException as Argument; +use Respect\Config\InvalidArgumentException as Argument; use ArrayObject; use ReflectionClass; use ReflectionFunction; -use Interop\Container\ContainerInterface; +use Psr\Container\ContainerInterface; class Container extends ArrayObject implements ContainerInterface { @@ -21,12 +21,10 @@ public function __isset($name) { return $this->has($name); } - - public function has($name) + + public function has($name) { - if ($this->configurator) { - $this->configure(); - } + $this->configure(); return parent::offsetExists($name); } @@ -70,9 +68,7 @@ function ($param) use ($container) { parent::offsetSet($name, $item); } - if ($this->configurator) { - $this->configure(); - } + $this->configure(); return $this; } @@ -107,12 +103,10 @@ protected function configure() throw new Argument("Invalid input. Must be a valid file or array"); } - + public function getItem($name, $raw = false) { - if ($this->configurator) { - $this->configure(); - } + $this->configure(); if (!isset($this[$name])) { throw new NotFoundException("Item $name not found"); @@ -124,7 +118,7 @@ public function getItem($name, $raw = false) return $this->lazyLoad($name); } - + public function get($name) { return $this->getItem($name); @@ -132,6 +126,7 @@ public function get($name) public function loadString($configurator) { + $configurator = preg_replace('/^[\s\t]+/', '', $configurator); $iniData = parse_ini_string($configurator, true); if (false === $iniData || count($iniData) == 0) { throw new Argument("Invalid configuration string"); @@ -268,6 +263,10 @@ protected function hasCompleteBrackets($value) protected function parseSingleValue($value) { + if (is_object($value)) { + return $value; + } + $value = trim($value); if ($this->hasCompleteBrackets($value)) { return $this->parseBrackets($value); diff --git a/library/Respect/Config/InvalidArgumentException.php b/library/Respect/Config/InvalidArgumentException.php new file mode 100644 index 0000000..839f0d7 --- /dev/null +++ b/library/Respect/Config/InvalidArgumentException.php @@ -0,0 +1,10 @@ + - - tests + + tests/library + + + tests/feature diff --git a/tests/feature/Callback.php b/tests/feature/Callback.php new file mode 100644 index 0000000..b18361b --- /dev/null +++ b/tests/feature/Callback.php @@ -0,0 +1,98 @@ + 'Hello'); + $result = $c($definition); + + $this->assertEquals( + 'Hello', + $result->bar, + 'Calling the container as a function will append the array passed as content to it.' . PHP_EOL . + 'It will return the itself, as well.' + ); + $this->assertSame( + $result->bar, + $c->bar, + "But it doesn't matter on which instance of the container you call." + ); + } + + public function testLateDefinitionOfVariableExpansionThroughItemCallbackReturnsValue() + { + $c = new Container(<<bar(array('undef'=>'Hello')); + $this->assertEquals('Hello', $result); + } + + public function testRetrievalOfItemThroughInstanceTypeOnContainerCallbackReturnsValue() + { + $called = false; + $c = new Container(<<assertInstanceOf('DateTime', $result); + $this->assertInstanceOf('DateTime', $result2); + $this->assertTrue($called); + } + + public function testRetrievalOfInstanceTypeThroughContainerCallbackReturnsValueEvenWithoutDeclaringItsType() + { + $c = new Container(); + $c(new \DateTime); + $called = false; + + $result = $c(function(\DateTime $date) use (&$called) { + $called = true; + return $date; + }); + + $result2 = $c['DateTime']; + $this->assertInstanceOf('DateTime', $result); + $this->assertInstanceOf('DateTime', $result2); + $this->assertTrue($called); + } + + public function testContainerCallbackReceivingACallableCallsItAndReturnsValue() + { + $c = new Container(); + $c(new \DateTime); + $result = $c(array('Test\Stub\TimePrinter', 'returnTimePassedAsArgument')); + $this->assertInstanceOf('DateTime', $result); + } +} + +namespace Test\Stub; + +class TimePrinter +{ + public function returnTimePassedAsArgument(\DateTime $time) + { + return $time; + } +} + diff --git a/tests/feature/ContainerAsArray.php b/tests/feature/ContainerAsArray.php new file mode 100644 index 0000000..33db0de --- /dev/null +++ b/tests/feature/ContainerAsArray.php @@ -0,0 +1,45 @@ +loadString(<<assertInstanceOf( + 'ArrayAccess', + $c, + 'The container implements the \ArrayAccess interface, so it behaves like an array.' + ); + $this->assertTrue( + isset($c['fibonacci']) + ); + $this->assertEquals( + array(1, 1, 2, 3, 5), + $c['fibonacci'], + 'The container implements the \ArrayAccess interface, so it behaves like an array.' + ); + } + + public function testDefiningItemWithArrayLikeNotation() + { + $c = new Container; + + $c['not'] = false; + $this->assertTrue(isset($c['not'])); + $this->assertFalse($c['not']); + } +} + diff --git a/tests/feature/ContainerManipulation.php b/tests/feature/ContainerManipulation.php new file mode 100644 index 0000000..12b866b --- /dev/null +++ b/tests/feature/ContainerManipulation.php @@ -0,0 +1,92 @@ +name = 'John Snow'; + + $this->assertEquals( + 'John Snow', + $c->name, + 'You can define new items just like you would define a property on an instance.' + ); + } + + public function testDefinitionOfItemWithAnonymousFunctionExecutesItAndReturnsItsValueUponUsage() + { + $c = new Container; + + $c->name = function() { return 'John Doe'; }; + + $this->assertEquals( + 'John Doe', + $c->name, + 'The function gets executed and the return value is stored in the container.' + ); + } + + public function testDefinitionOfItemOnContainerWithItems() + { + $c = new Container(<<panda = function() { return 'ok'; }; + + $this->assertEquals( + 'ok', + $c->panda, + 'It works if the container has stuff or not.' + ); + } + + /** + * @group issue + * @ticket 14 + */ + public function testItemOverwrrite() + { + $c = new Container(<<pdo = new \PDO('sqlite::memory:'); + + $this->assertNotInstanceOf( + 'StdClass', + $c->pdo, + 'Although PDO was defined with StdClass we overwritten it to a proper instance of PDO manually.' + ); + + $this->assertSame( + $c->pdo, + $c->db->c, + 'This should overwrite every usage of that element inside the container.' + ); + } +} + +namespace Test\Stub; + +class DatabaseWow +{ + public $c; + + public function __construct($con) + { + $this->c = $con; + } +} + diff --git a/tests/feature/IniDsl/ConstantExpansion.php b/tests/feature/IniDsl/ConstantExpansion.php new file mode 100644 index 0000000..f2d5a30 --- /dev/null +++ b/tests/feature/IniDsl/ConstantExpansion.php @@ -0,0 +1,108 @@ +assertEquals( + E_USER_ERROR, + $c->error_reporting, + 'Constants are always UPPER CASE, the one being used is already declared by PHP.' + ); + } + + public function testConstantDeclaredBeforeUsageGetsExpandedCorrectly() + { + $c = new Container(<<assertEquals( + MY_SWEET_CONSTANT_FOR_TESTING, + $c->expansion_happens_on_usage, + 'Constant expansion happens on first usage, so declaring constants after INI parsing is fine.' + ); + } + + public function testNonExistingConstantUsageExpandsToItsName() + { + $c = new Container(<<assertEquals( + 'NON_EXISTING_CONSTANT', + $c->test_value, + 'Non existing constants are expanded to their name, mimicing PHP behavior.' + ); + } + + public function testClassConstantExpansionInsideASequence() + { + $c = new Container(<<assertEquals( + array(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION), + $c->pdo_error_mode, + 'Class constants also get expanded! Every feature (e.g: sequences) still works.' + ); + } + + public function testNonExistingClassConstantExpandsToItsName() + { + $c = new Container(<<assertEquals( + 'PDO::ERRMODE', + $c->pdo_error_mode, + 'Non existing class constants get expanded to their full name when used.' + ); + } + + public function testNonExistingClassConstantInsideASequenceExpandsToItsName() + { + $c = new Container(<<assertEquals( + array('PDO::ERRMODE2', \PDO::ERRMODE_EXCEPTION), + $c->pdo_error_mode, + 'Class constants also get expanded to their name while inside a sequence.' + ); + } + + public function testConstantExpansionStringInterpolation() + { + $c = new Container(<<assertEquals( + "/var/log", + $c->file_system_path, + 'Constants can be used with string values as well.' + ); + } +} diff --git a/tests/feature/IniDsl/Instantiation.php b/tests/feature/IniDsl/Instantiation.php new file mode 100644 index 0000000..c0d82eb --- /dev/null +++ b/tests/feature/IniDsl/Instantiation.php @@ -0,0 +1,347 @@ +assertInstanceOf( + 'StdClass', + $c->foo, + 'INI sections with space in their names create new instances: ' . PHP_EOL . + ' * The string before the space is the instance name' . PHP_EOL . + ' * The string after the space is the instance type' + ); + } + + public function testInstanceNameWithUnderline() + { + $c = new Container(<<assertInstanceOf( + 'StdClass', + $c->foo_bar, + 'Instances with underline in their names should work as expected.' + ); + } + + public function testCreatingAnInstanceOfStdclassWithinAValueName() + { + $c = new Container(<<assertInstanceOf( + 'StdClass', + $c->foo, + 'INI value names can also trigger class instantiation, we prefer the section-way though.' + ); + } + + public function testInstancePropertyDefinition() + { + $c = new Container(<<assertInstanceOf( + 'StdClass', + $c->person, + 'Every item in the section is treated as a public property and, therefore, defined in the instance.' + ); + $this->assertEquals( + 'Rhaegar Targaryen', + $c->person->father, + 'Did you guess that in the show?' + ); + $this->assertEquals( + 'John Snow', + $c->person->name, + 'Most boring character. Ever.' + ); + $this->assertEquals( + 'Lyanna Stark', + $c->person->mother, + 'Feel like talking about *that* butterfly effect?' + ); + } + + public function testInstancePropertyDefinitionWithExpansionOfAnotherInstance() + { + $c = new Container(<<assertEquals( + get_class($c->foo_bar), + get_class($c->bar_foo->test) + ); + } + + + public function testInstancePropertyOfTypeArray() + { + $ini = <<loadArray(parse_ini_string($ini, true)); + $instantiator = $c->getItem('foo', true); + $expected = array( + 'abc' => 'bar', + 'def' => 'bat' + ); + $this->assertEquals($expected, $instantiator->getParam('foo')); + } + + public function testPropertyDefinitionWithSequences() + { + $ini = <<loadArray(parse_ini_string($ini, true)); + $instantiator = $c->getItem('foo', true); + $expectedFoo = array( + 'abc' => array('bat', 'blz'), + 'def' => 'bat' + ); + $expectedBaz = array('bat', 'blz'); + $this->assertEquals($expectedFoo, $instantiator->getParam('foo')); + $this->assertEquals($expectedBaz, $instantiator->getParam('baz')); + } + + public function testPropertyDefinitionWithVariableExpansion() + { + $ini = <<loadArray(parse_ini_string($ini, true)); + $instantiator = $c->getItem('foo', true); + $expectedFoo = array( + 'abc' => array('bat', 'blz'), + 'def' => 'bat' + ); + $expectedBaz = array('bat', 'someName'); + $this->assertEquals($expectedFoo, $instantiator->getParam('foo')); + $this->assertEquals($expectedBaz, $instantiator->getParam('baz')); + } + + public function testUsingTheSameInstanceTwiceReusesThePreviouslyCreatedInstances() + { + $c = new Container(<<now; + $this->assertInstanceOf( + 'DateTime', + $firstValue, + 'Instance type given should be respected.' + ); + $this->assertSame( + $firstValue, + $c->now, + 'After instantiation, the instance remains the same. No matter how many times you use it.' + ); + } + + public function testNewInstanceWithConstructorArgument() + { + $c = new Container(<<assertInstanceOf( + 'DateTimeZone', + $c->home, + 'Constructor parameters can be defined as a sequence (array) passed as value to the "__construct".' + ); + $this->assertEquals( + 'America/Sao_Paulo', + $c->home->getName(), + 'Instances work like in any other place, you can call methods on them later...' + ); + } + + /** + * @group issue + * @ticket 40 + */ + public function testInstanceExpansionWithTypeConstructorParameter() + { + $c = new Container(<<assertInstanceOf( + 'Test\Stub\TypeHintWowMuchType', + $c->typed, + 'That object requires a DateTime as constructor argument.' + ); + } + + /** + * @group issue + * @ticket 9 + */ + public function testInstanceThroughStaticFactoryAlwaysCreateNewObjects() + { + $c = new Container(<<y2k; + $secondCall = $c->y2k; + $this->assertInstanceOf( + 'DateTime', + $firstCall, + 'Static factory behavior is to create an instance after calling a method.' . PHP_EOL . + 'When you define an instance as INI section and pass it a method name (which is always' . PHP_EOL . + 'followed by brackets), we will call "DateTime::createFromFormat" to retrieve the instance.' + ); + $this->assertSame( + $firstCall, + $secondCall, + 'Even through we are creating instances from a method call, after the first instantiation the' . PHP_EOL . + 'instance is not changed. No matter how many times you use it.' + ); + } + + public function testInstatiationOfNewObjectEveryTimeItIsUsed() + { + $c = new Container(<<assertInstanceOf( + 'DateTime', + $c->now, + 'Instance type should always be respected.' + ); + $this->assertNotSame( + $c->now, + $c->now, + 'When "new" is used before declaring the type of instance, we will always create new instances.' + ); + } + + public function testCallingMethodWithValueOnAnInstanceMultipleTimes() + { + $c = new Container(<<assertEquals( + 'one', + $c->day->dequeue(), + 'Queue was created and two items were enqueued.' + ); + $this->assertEquals( + 'two', + $c->day->dequeue(), + 'Methods are called in the order they are defined inside the section.' + ); + } + + public function testCallingMethodWithoutValue() + { + $c = new Container(<<assertNotEmpty( + $c->db->query('SELECT * FROM sqlite_master')->fetch() + ); + } + + public function testInstanceOfDefinesTheInstanceNameAsItsOwnInstance() + { + $c = new Container(<<assertInstanceOf( + 'DateTime', + $c->DateTime, + 'Although the "DateTime" item is not defined, the `instanceof` operator registers it.' + ); + $this->assertSame( + $c->DateTime, + $c->person->birthday, + 'You can use this kind of thing when you full class name is a nice one, and a single instance is relavant.' + ); + } +} + +namespace Test\Stub; + +class WheneverWithAProperty +{ + public $test; +} + +class TypeHintWowMuchType +{ + public $d; + + public function __construct(\DateTime $date) + { + $this->d = $date; + } +} + diff --git a/tests/feature/IniDsl/Sequence.php b/tests/feature/IniDsl/Sequence.php new file mode 100644 index 0000000..3262708 --- /dev/null +++ b/tests/feature/IniDsl/Sequence.php @@ -0,0 +1,64 @@ +assertEquals( + array(1, 1, 2, 3, 5), + $c->fibonacci, + 'Sequences are arrays declared much like in PHP (after 5.4 introduction of short array syntax).' + ); + } + + public function testSectionSequenceDeclarationTranslatesToArrayUponUsage() + { + $c = new Container(<<assertEquals( + array(1, 1, 2, 3, 5), + $c->fibonacci, + 'INI sections are also sequences, where the name is the index of the resulting array.' + ); + } + + public function testSectionSequenceDeclarationUsingAssociativeArrayIndexes() + { + $c = new Container(<<assertEquals( + array( + "Config" => "unstable", + "Rest" => "stable", + "Template" => "experimental", + "Foundation" => "deprecated" + ), + $c->components, + 'Sequences declared as INI sections can also use associative indexes.' + ); + } +} diff --git a/tests/feature/IniDsl/VariableExpansion.php b/tests/feature/IniDsl/VariableExpansion.php new file mode 100644 index 0000000..85451af --- /dev/null +++ b/tests/feature/IniDsl/VariableExpansion.php @@ -0,0 +1,126 @@ +assertEquals( + 'John Snow', + $c->getItem('who_knows_nothing'), + "INI values between brackets should be treated as variables and suffer expansion." + ); + } + + public function testVariableExpansionUsingStringInterpolation() + { + $c = new Container(<<assertEquals( + 'mysql:host=localhost;dbname=my_database', + $c->getItem('db_dsn'), + 'Variables can be used inside a INI value multiple times.' + ); + } + + public function testExpansionOfNonExistingVariableDoesNotFailParsing() + { + $c = new Container(<<who_knows_nothing; + } + + /** + * @expectedException Respect\Config\NotFoundException + * @expectedExceptionMessage Item my_name not found + */ + public function testExpansionAndUsageOfAnEmptyValueThrowsException() + { + $c = new Container(<<who_knows_nothing; + } + + /** + * @expectedException Respect\Config\NotFoundException + * @expectedExceptionMessage Item my_name not found + */ + public function testExpansionAndUsageOfAnEmptyStringAsValueThrowsException() + { + $c = new Container(<<who_knows_nothing; + } + + /** + * @expectedException Respect\Config\NotFoundException + * @expectedExceptionMessage Item my_name not found + */ + public function testExpansionAndUsageOfANullValueThrowsException() + { + $c = new Container(<<who_knows_nothing; + } + + public function testExpansionInsideASequence() + { + $c = new Container(<<assertEquals( + array(1, 1, 2, 3, 5, 8, 13), + $c->fibonacci, + 'Variable declaration also works inside sequences (or arrays).' + ); + } +} diff --git a/tests/feature/LazyLoading.php b/tests/feature/LazyLoading.php new file mode 100644 index 0000000..627ffc9 --- /dev/null +++ b/tests/feature/LazyLoading.php @@ -0,0 +1,200 @@ +me = 'John Snow'; + + $this->assertEquals( + $c->me, + $c->john, + 'Although the [me] variable didn\'t exist upon container creation, as everything is evaluated through lazy loading.' + ); + } + + /** + * @TODO We should lazy load just what we need. This test should work + * without throwing an Exception. + * @expectedException Respect\Config\NotFoundException + * @expectedExceptionMessage Item me not found + */ + public function testLateExpansionOfJustWhatWeNeed() + { + $c = new Container(<<assertEquals( + 'Jane Doe', + $c->jane, + 'We lazy load just the items we need.' + ); + } + + public function testLazyLoadinessOnMultipleConfigLevels() + { + $c = new Container(<<assertFalse( + $GLOBALS['_SHIT_'], + 'If no instatiation happened, this global variable should be `false`.' + ); + $this->assertInstanceOf( + 'Test\Stub\WheneverIBornIPopulateAGlobalCalled_SHIT_', + $c->foo, + 'Using something to force instatiation.' + ); + $this->assertTrue( + $GLOBALS['_SHIT_'], + 'Believe me now?' + ); + } + + public function testSequencesConstructingLazy() + { + $c = new Container(<<assertInstanceOf( + 'Test\Stub\Bar', + $c->foo->bar + ); + } + + /** + * @group issue + * @ticket 14 + * @ticket 24 + */ + public function testOverwriteOfItemBeforeExpansionOnAnother() + { + $c = new Container(<<my_string = 'Hello World!'; + + $this->assertEquals( + 'Hello World!', + (string) $c->hello + ); + } + + /** + * @group issue + * @ticket 26 + */ + public function testLazyLoadedInstance() + { + $config = " +my_string = 'Hey you!' + +[hello Test\Stub\MyLazyLoadedHelloWorld] +string = [my_string] + +[consumer Test\Stub\MyLazyLoadedHelloWorldConsumer] +hello = [hello] + "; + $expected = 'Hello World!'; + $container = new Container($config); + $container->my_string = $expected; + $this->assertEquals($expected, (string) $container->hello); + $container = new Container($config); + $container->{"hello Test\\Stub\\MyLazyLoadedHelloWorld"} = array('string' => $expected); + $this->assertEquals($expected, (string) $container->hello); + $container = new Container($config); + $container->hello = new \Test\Stub\MyLazyLoadedHelloWorld($expected); + $this->assertEquals($expected, (string) $container->hello); + } +} + +namespace Test\Stub; + +class WheneverIBornIPopulateAGlobalCalled_SHIT_ +{ + function __construct() + { + $GLOBALS['_SHIT_'] = true; + } +} + +class Bar {} + +class Foo +{ + function hey(\DateTime $date) + { + return $date; + } + + function hello($some, Bar $bar) + { + $this->bar = $bar; + } +} + +class MyLazyLoadedHelloWorldConsumer +{ + protected $string; + + public function __construct($hello) + { + $this->string = $hello; + } + + public function __toString() + { + return $this->string; + } +} + +class MyLazyLoadedHelloWorld +{ + protected $string; + + public function __construct($string) + { + $this->string = $string; + } + + public function __toString() + { + return $this->string; + } +} diff --git a/tests/feature/Psr11.php b/tests/feature/Psr11.php new file mode 100644 index 0000000..ba1c7fe --- /dev/null +++ b/tests/feature/Psr11.php @@ -0,0 +1,106 @@ +loadArray(parse_ini_string($ini, true)); + + $this->assertTrue( + $c->has('foo'), + 'Searching an existing item must succeed.' + ); + $this->assertEquals( + 'bar', + $c->get('foo'), + 'Retrieving an existing item must succeed.' + ); + $this->assertEquals( + 'bat', + $c->get('baz'), + 'Retrieving an existing item must succeed.' + ); + } + + /** + * @expectedException Psr\Container\NotFoundExceptionInterface + * @expectedExceptionMessage Item baz not found + */ + public function testItemNotFoundInContainerMatchesInteropException() + { + $this->loadInvalidItem(); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage Item baz not found + */ + public function testItemNotFoundInContainerMatchesPreviousRespectConfigException() + { + $this->loadInvalidItem(); + } + + /** + * @expectedException Respect\Config\InvalidArgumentException + * @expectedExceptionMessage Item baz not found + */ + public function testItemNotFoundInContainerMatchesCustomRespectException() + { + $this->loadInvalidItem(); + } + + private function loadInvalidItem() + { + $ini = <<loadArray(parse_ini_string($ini, true)); + $c->get('baz'); + } + + /** + * @expectedException Psr\Container\ContainerExceptionInterface + */ + public function testContainerExceptionMatchesInteropException() + { + $this->parseInvalidIni(); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testContainerExceptionMatchesPreviousRespectConfigException() + { + $this->parseInvalidIni(); + } + + /** + * @expectedException Respect\Config\InvalidArgumentException + */ + public function testContainerExceptionUsesCustomRespectException() + { + $this->parseInvalidIni(); + } + + private function parseInvalidIni() + { + $c = new Container(14); + $c->foo; + } +} + diff --git a/tests/library/Respect/Config/ContainerTest.php b/tests/library/Respect/Config/ContainerTest.php index 81c3417..c7bd184 100644 --- a/tests/library/Respect/Config/ContainerTest.php +++ b/tests/library/Respect/Config/ContainerTest.php @@ -25,7 +25,8 @@ protected function setUp() )); } - public function tearDown() { + public function tearDown() + { StreamWrapper::releaseOverrides(); } @@ -48,467 +49,50 @@ public function testLoadFile() $this->assertEquals('bar', $c->getItem('foo')); $this->assertEquals('bat', $c->getItem('baz')); } - - public function testContainerInterop() - { - $ini = <<loadArray(parse_ini_string($ini, true)); - $this->assertTrue($c->has('foo')); - $this->assertEquals('bar', $c->get('foo')); - $this->assertEquals('bat', $c->get('baz')); - } - - /** - * @expectedException Interop\Container\Exception\NotFoundException - * @expectedExceptionMessage Item baz not found - */ - public function testLoadInvalidName() - { - $ini = <<loadArray(parse_ini_string($ini, true)); - $c->get('baz'); - } /** * @expectedException InvalidArgumentException * @expectedExceptionMessage Invalid input. Must be a valid file or array */ - public function testConfigure() { + public function testLoadStringWithInvalidIni() + { $c = new Container(1); $c->a; } - public function testLoadInvalid() + /** + * @expectedException InvalidArgumentException + * @expectedExceptionMessage Invalid configuration string + */ + public function testLoadFileThatDoesNotExistsThrowException() { - $this->setExpectedException('InvalidArgumentException'); $c = new Container('inexistent.ini'); $c->foo; } - public function testLoadArraySections() - { - $ini = <<loadArray(parse_ini_string($ini, true)); - $d = $c->getItem('sec'); - $this->assertEquals('bar', $d['foo']); - $this->assertEquals('bat', $d['baz']); - } - - public function testExpandVars() - { - $ini = <<loadArray(parse_ini_string($ini, true)); - $this->assertEquals( - 'mysql:host=localhost;dbname=my_database', $c->getItem('db_dsn') - ); - } - - public function testInstantiator() - { - $ini = <<loadArray(parse_ini_string($ini, true)); - $instantiator = $c->getItem('foo', true); - $this->assertEquals('stdClass', $instantiator->getClassName()); - } - - public function testInstantiator2() - { - $ini = <<loadArray(parse_ini_string($ini, true)); - $instantiator = $c->getItem('foo', true); - $this->assertEquals('stdClass', $instantiator->getClassName()); - } - - public function testConstants() - { - $ini = <<loadArray(parse_ini_string($ini, true)); - $this->assertEquals(E_USER_ERROR, $c->foo); - $this->assertEquals(\PDO::ATTR_ERRMODE, $c->bar); - $this->assertEquals(array(E_USER_ERROR, E_USER_WARNING), $c->faa); - $this->assertEquals(array(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION), $c->bor); - $this->assertEquals(array("foo".DIRECTORY_SEPARATOR."bar", PATH_SEPARATOR), $c->lorem); - $this->assertEquals(array(PATH_SEPARATOR, "foo".DIRECTORY_SEPARATOR."bar"), $c->ipsum); - } - - public function testInstantiatorParams() - { - $ini = <<loadArray(parse_ini_string($ini, true)); - $instantiator = $c->getItem('foo', true); - $this->assertEquals('bar', $instantiator->getParam('foo')); - $this->assertEquals('bat', $instantiator->getParam('baz')); - } - public function testInstantiatorMethodCalls() - { - $ini = <<loadArray(parse_ini_string($ini, true)); - $dateTime = $c->date; - } - public function testInstantiatorNullMethodCalls() - { - $ini = <<loadArray(parse_ini_string($ini, true)); - $conn = $c->conn; - $this->assertNotEmpty($conn->query('SELECT * FROM sqlite_master')->fetch()); - } - - public function testInstantiatorParamsArray() - { - $ini = <<loadArray(parse_ini_string($ini, true)); - $instantiator = $c->getItem('foo', true); - $expected = array( - 'abc' => 'bar', - 'def' => 'bat' - ); - $this->assertEquals($expected, $instantiator->getParam('foo')); - } - - public function testInstantiatorParamsBrackets() - { - $ini = <<loadArray(parse_ini_string($ini, true)); - $instantiator = $c->getItem('foo', true); - $expectedFoo = array( - 'abc' => array('bat', 'blz'), - 'def' => 'bat' - ); - $expectedBaz = array('bat', 'blz'); - $this->assertEquals($expectedFoo, $instantiator->getParam('foo')); - $this->assertEquals($expectedBaz, $instantiator->getParam('baz')); - } - public function testInstantiatorParamsBracketsReferences() - { - $ini = <<loadArray(parse_ini_string($ini, true)); - $instantiator = $c->getItem('foo', true); - $expectedFoo = array( - 'abc' => array('bat', 'blz'), - 'def' => 'bat' - ); - $expectedBaz = array('bat', 'someName'); - $this->assertEquals($expectedFoo, $instantiator->getParam('foo')); - $this->assertEquals($expectedBaz, $instantiator->getParam('baz')); - } - - public function testGetItemLazyLoad() - { - $c = new Container; - $c->foo = function() { return 'ok'; }; - $this->assertEquals('ok', $c->getItem('foo', false)); - } - - public function testClosureWithLoadedFile() - { - $ini = <<panda = function() { return 'ok'; }; - $this->assertEquals('ok', $c->getItem('panda', false)); - } - - public function testLazyLoadinessOnMultipleConfigLevels() - { - $GLOBALS['_SHIT_'] = false; - $ini = <<loadArray(parse_ini_string($ini, true)); - $this->assertFalse($GLOBALS['_SHIT_']); - $GLOBALS['_SHIT_'] = false; - } - - public function testSequencesConstructingLazy() + /** + * @group issue + * @ticket 30 + */ + public function testLateExpansionWhenItemDefinitionIsDonePassingAnArray() { - $ini = <<loadArray(parse_ini_string($ini, true)); - $this->assertInstanceOf('Respect\Config\Bar', $c->foo->bar); - } + $config = " +account = [user] - public function testPascutti() - { - $GLOBALS['_SHIT_'] = false; - $ini = <<loadArray(parse_ini_string($ini, true)); - $c->pdo = new \PDO('sqlite::memory:'); - $this->assertSame($c->pdo, $c->db->c); - } +[production] +user = respect +"; + $config = parse_ini_string($config,true); + $config = array_merge($config['production'], $config); + $container = new Container($config); - public function testPascuttiTypeHintIssue40() - { - $GLOBALS['_MERD_'] = false; - $ini = <<loadArray(parse_ini_string($ini, true)); - $this->assertInstanceOf( - 'Respect\Config\TypeHintWowMuchType', - $c->typed + $this->assertEquals( + 'respect', + $container->account ); } - - public function testLockedContainer() - { - $ini = <<'Hello')); - $this->assertEquals('Hello', $result->bar); - } - public function testLockedContainer2() - { - $ini = <<bar(array('undef'=>'Hello')); - $this->assertEquals('Hello', $result); - } - public function testFactory() - { - $ini = <<now; - $result2 = $c->now; - $this->assertNotSame($result, $result2); - } - public function testDependenciesDoesNotAffectFactories() - { - $ini = <<now; - $result2 = $c->now; - $this->assertSame($result, $result2); - } - public function testByInstanceCallback() - { - $ini = <<assertInstanceOf('DateTime', $result); - $this->assertInstanceOf('DateTime', $result2); - $this->assertTrue($called); - } - public function testByInstanceCallback2() - { - $c = new Container(); - $c(new \DateTime); - $called = false; - $result = $c(function(\DateTime $date) use (&$called) { - $called = true; - return $date; - }); - $result2 = $c['DateTime']; - $this->assertInstanceOf('DateTime', $result); - $this->assertInstanceOf('DateTime', $result2); - $this->assertTrue($called); - } - public function testByMethodCallback() - { - $c = new Container(); - $c(new \DateTime); - $result = $c(array(__NAMESPACE__.'\\Foo', 'hey')); - $this->assertInstanceOf('DateTime', $result); - } - - - public function testClassConstants() - { - $ini = <<loadArray(parse_ini_string($ini, true)); - $this->assertEquals(\Respect\Config\TestConstant::CONS_TEST, $c->foo); - } - - public function testClassConstantsAnotherNamespace() - { - class_alias('Respect\Config\TestConstant', 'Respect\Test\Another\Cons'); - $ini = <<loadArray(parse_ini_string($ini, true)); - $this->assertEquals(\Respect\Test\Another\Cons::CONS_TEST, $c->foo); - } - - - public function testInstantiatorWithUnderline() - { - $ini = <<loadArray(parse_ini_string($ini, true)); - $instantiator = $c->getItem('foo_bar', true); - $this->assertEquals('stdClass', $instantiator->getClassName()); - } - - public function testClassWithAnotherAndUnderline() - { - $ini = <<loadArray(parse_ini_string($ini, true)); - $this->assertEquals(get_class($c->foo_bar), get_class($c->bar_foo->test)); - } - -} -class Bar {} -class Foo -{ - function hey(\DateTime $date) { - return $date; - } - - function hello($some, Bar $bar) { - $this->bar = $bar; - } -} - -class WheneverIBornIPopulateAGlobalCalled_SHIT_ -{ - public function __construct(){ - $GLOBALS['_SHIT_'] = true; - } -} - -class DatabaseWow { - public $c; - public function __construct($con) { - $this->c = $con; - } -} - - -class TypeHintWowMuchType { - public $d; - public function __construct(\DateTime $date) { - $this->d = $date; - } } -class TestConstant { - const CONS_TEST = "XPTO"; -} - - -class WheneverWithAProperty -{ - public $test; - -} diff --git a/tests/library/Respect/Config/Issues/EnviromentConfigurationTest.php b/tests/library/Respect/Config/Issues/EnviromentConfigurationTest.php deleted file mode 100644 index f990718..0000000 --- a/tests/library/Respect/Config/Issues/EnviromentConfigurationTest.php +++ /dev/null @@ -1,28 +0,0 @@ -assertEquals($expected, $container->account); //respect - } -} - diff --git a/tests/library/Respect/Config/Issues/InstantiatorImplementsInvoke.php b/tests/library/Respect/Config/Issues/InstantiatorImplementsInvoke.php deleted file mode 100644 index 9d8a909..0000000 --- a/tests/library/Respect/Config/Issues/InstantiatorImplementsInvoke.php +++ /dev/null @@ -1,76 +0,0 @@ -my_string = $expected; - $this->assertEquals($expected, (string) $container->hello); - } - - public function testLazyLoadedInstance() - { - $config = " -my_string = 'Hey you!' - -[hello Respect\Config\MyLazyLoadedHelloWorld] -string = [my_string] - -[consumer Respect\Config\MyLazyLoadedHelloWorldConsumer] -hello = [hello] - "; - $expected = 'Hello World!'; - $container = new Container($config); - $container->my_string = $expected; - $this->assertEquals($expected, (string) $container->hello); - $container = new Container($config); - $container->{"hello Respect\\Config\\MyLazyLoadedHelloWorld"} = array('string' => $expected); - $this->assertEquals($expected, (string) $container->hello); - $container = new Container($config); - $container->hello = new MyLazyLoadedHelloWorld($expected); - $this->assertEquals($expected, (string) $container->hello); - } -} -class MyLazyLoadedHelloWorldConsumer -{ - protected $string; - - public function __construct($hello) - { - $this->string = $hello; - } - - public function __toString() - { - return $this->string; - } -} - -class MyLazyLoadedHelloWorld -{ - protected $string; - - public function __construct($string) - { - $this->string = $string; - } - - public function __toString() - { - return $this->string; - } -} - diff --git a/tests/library/Respect/Config/Issues/LazyLoadTest.php b/tests/library/Respect/Config/Issues/LazyLoadTest.php deleted file mode 100644 index 85f21ca..0000000 --- a/tests/library/Respect/Config/Issues/LazyLoadTest.php +++ /dev/null @@ -1,76 +0,0 @@ -my_string = $expected; - $this->assertEquals($expected, (string) $container->hello); - } - - public function testLazyLoadedInstance() - { - $config = " -my_string = 'Hey you!' - -[hello Respect\Config\MyLazyLoadedHelloWorld] -string = [my_string] - -[consumer Respect\Config\MyLazyLoadedHelloWorldConsumer] -hello = [hello] - "; - $expected = 'Hello World!'; - $container = new Container($config); - $container->my_string = $expected; - $this->assertEquals($expected, (string) $container->hello); - $container = new Container($config); - $container->{"hello Respect\\Config\\MyLazyLoadedHelloWorld"} = array('string' => $expected); - $this->assertEquals($expected, (string) $container->hello); - $container = new Container($config); - $container->hello = new MyLazyLoadedHelloWorld($expected); - $this->assertEquals($expected, (string) $container->hello); - } -} -class MyLazyLoadedHelloWorldConsumer -{ - protected $string; - - public function __construct($hello) - { - $this->string = $hello; - } - - public function __toString() - { - return $this->string; - } -} - -class MyLazyLoadedHelloWorld -{ - protected $string; - - public function __construct($string) - { - $this->string = $string; - } - - public function __toString() - { - return $this->string; - } -} - diff --git a/tests/library/Respect/Config/Issues/StaticFactoryTest.php b/tests/library/Respect/Config/Issues/StaticFactoryTest.php deleted file mode 100644 index a306633..0000000 --- a/tests/library/Respect/Config/Issues/StaticFactoryTest.php +++ /dev/null @@ -1,27 +0,0 @@ -setParam('factory', array(array())); - $this->assertAttributeNotEmpty('staticMethodCalls', $i); - $this->assertInstanceOf('DateTime', $i->getInstance()); - } -} - -class StaticTest -{ - private function __construct() {} - public static function factory() - { - return new \DateTime(); - } -} -