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();
- }
-}
-