Skip to content

Commit a9b68ab

Browse files
committed
Explain tests and organize them
Library tests are now separated from "feature" tests, which explain better what each feature of the component is and how it works. Works better than a README if you ask me, or Respect\Doc for that matter - which suffered an overhaul that I still haven't take the time to understand. Previous coverage is unchanged, although more tests were added for clarity and better coverage of each feature usage. Changes ------- You can now indent INI declarations, every blank space before the start of any declaration will be removed. A bug happened when you manipulated the container by defining an item entry with an instance. The "ifs" surrounding `$this->configure()` were unnecessary. Describes development dependencies better on `composer.json` to run the test suite.
1 parent ae1bae9 commit a9b68ab

15 files changed

+1121
-636
lines changed

composer.json

+2
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
"psr/container": "^1.0"
2222
},
2323
"require-dev": {
24+
"ext-PDO": "*",
25+
"ext-pdo_sqlite": "*",
2426
"phpunit/phpunit": "~4.4",
2527
"respect/test": "dev-master"
2628
},

library/Respect/Config/Container.php

+12-13
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,10 @@ public function __isset($name)
2121
{
2222
return $this->has($name);
2323
}
24-
25-
public function has($name)
24+
25+
public function has($name)
2626
{
27-
if ($this->configurator) {
28-
$this->configure();
29-
}
27+
$this->configure();
3028

3129
return parent::offsetExists($name);
3230
}
@@ -70,9 +68,7 @@ function ($param) use ($container) {
7068
parent::offsetSet($name, $item);
7169
}
7270

73-
if ($this->configurator) {
74-
$this->configure();
75-
}
71+
$this->configure();
7672

7773
return $this;
7874
}
@@ -107,12 +103,10 @@ protected function configure()
107103

108104
throw new Argument("Invalid input. Must be a valid file or array");
109105
}
110-
106+
111107
public function getItem($name, $raw = false)
112108
{
113-
if ($this->configurator) {
114-
$this->configure();
115-
}
109+
$this->configure();
116110

117111
if (!isset($this[$name])) {
118112
throw new NotFoundException("Item $name not found");
@@ -124,14 +118,15 @@ public function getItem($name, $raw = false)
124118

125119
return $this->lazyLoad($name);
126120
}
127-
121+
128122
public function get($name)
129123
{
130124
return $this->getItem($name);
131125
}
132126

133127
public function loadString($configurator)
134128
{
129+
$configuration = preg_replace('/^[\s\t]+/', '', $configurator);
135130
$iniData = parse_ini_string($configurator, true);
136131
if (false === $iniData || count($iniData) == 0) {
137132
throw new Argument("Invalid configuration string");
@@ -268,6 +263,10 @@ protected function hasCompleteBrackets($value)
268263

269264
protected function parseSingleValue($value)
270265
{
266+
if (is_object($value)) {
267+
return $value;
268+
}
269+
271270
$value = trim($value);
272271
if ($this->hasCompleteBrackets($value)) {
273272
return $this->parseBrackets($value);

tests/feature/Callback.php

+98
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
<?php
2+
3+
namespace Test\Feature;
4+
5+
use Respect\Config\Container;
6+
7+
class ItemConsuptionViaCallback extends \PHPUnit_Framework_TestCase
8+
{
9+
public function testLateDefinitionOfVariableExpansionThroughContainerCallbackReturnsContainer()
10+
{
11+
$c = new Container(<<<INI
12+
foo = [undef]
13+
bar = [foo]
14+
INI
15+
);
16+
$definition = array('undef' => 'Hello');
17+
$result = $c($definition);
18+
19+
$this->assertEquals(
20+
'Hello',
21+
$result->bar,
22+
'Calling the container as a function will append the array passed as content to it.' . PHP_EOL .
23+
'It will return the itself, as well.'
24+
);
25+
$this->assertSame(
26+
$result->bar,
27+
$c->bar,
28+
"But it doesn't matter on which instance of the container you call."
29+
);
30+
}
31+
32+
public function testLateDefinitionOfVariableExpansionThroughItemCallbackReturnsValue()
33+
{
34+
$c = new Container(<<<INI
35+
foo = [undef]
36+
bar = [foo]
37+
INI
38+
);
39+
40+
$result = $c->bar(array('undef'=>'Hello'));
41+
$this->assertEquals('Hello', $result);
42+
}
43+
44+
public function testRetrievalOfItemThroughInstanceTypeOnContainerCallbackReturnsValue()
45+
{
46+
$called = false;
47+
$c = new Container(<<<INI
48+
[instanceof DateTime]
49+
time = now
50+
INI
51+
);
52+
$result = $c(function(\DateTime $date) use (&$called) {
53+
$called = true;
54+
return $date;
55+
});
56+
57+
$result2 = $c['DateTime'];
58+
$this->assertInstanceOf('DateTime', $result);
59+
$this->assertInstanceOf('DateTime', $result2);
60+
$this->assertTrue($called);
61+
}
62+
63+
public function testRetrievalOfInstanceTypeThroughContainerCallbackReturnsValueEvenWithoutDeclaringItsType()
64+
{
65+
$c = new Container();
66+
$c(new \DateTime);
67+
$called = false;
68+
69+
$result = $c(function(\DateTime $date) use (&$called) {
70+
$called = true;
71+
return $date;
72+
});
73+
74+
$result2 = $c['DateTime'];
75+
$this->assertInstanceOf('DateTime', $result);
76+
$this->assertInstanceOf('DateTime', $result2);
77+
$this->assertTrue($called);
78+
}
79+
80+
public function testContainerCallbackReceivingACallableCallsItAndReturnsValue()
81+
{
82+
$c = new Container();
83+
$c(new \DateTime);
84+
$result = $c(array('Test\Stub\TimePrinter', 'returnTimePassedAsArgument'));
85+
$this->assertInstanceOf('DateTime', $result);
86+
}
87+
}
88+
89+
namespace Test\Stub;
90+
91+
class TimePrinter
92+
{
93+
public function returnTimePassedAsArgument(\DateTime $time)
94+
{
95+
return $time;
96+
}
97+
}
98+

tests/feature/ContainerAsArray.php

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<?php
2+
3+
namespace Test\Feature;
4+
5+
use Respect\Config\Container;
6+
7+
class ContainerAsArray extends \PHPUnit_Framework_TestCase
8+
{
9+
/**
10+
* @TODO Fix issue where passing INI to container construction does not
11+
* allow ArrayAccess usage. T.T
12+
*/
13+
public function testUsingItemsAsContainerWasAnArray()
14+
{
15+
$c = new Container();
16+
$c->loadString(<<<INI
17+
fibonacci = [1, 1, 2, 3, 5]
18+
INI
19+
);
20+
21+
$this->assertInstanceOf(
22+
'ArrayAccess',
23+
$c,
24+
'The container implements the \ArrayAccess interface, so it behaves like an array.'
25+
);
26+
$this->assertTrue(
27+
isset($c['fibonacci'])
28+
);
29+
$this->assertEquals(
30+
array(1, 1, 2, 3, 5),
31+
$c['fibonacci'],
32+
'The container implements the \ArrayAccess interface, so it behaves like an array.'
33+
);
34+
}
35+
36+
public function testDefiningItemWithArrayLikeNotation()
37+
{
38+
$c = new Container;
39+
40+
$c['not'] = false;
41+
$this->assertTrue(isset($c['not']));
42+
$this->assertFalse($c['not']);
43+
}
44+
}
45+
+92
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
<?php
2+
3+
namespace Test\Feature;
4+
5+
use Respect\Config\Container;
6+
7+
class ContainerManipulation extends \PHPUnit_Framework_TestCase
8+
{
9+
public function testDefiningNewItemOnContainer()
10+
{
11+
$c = new Container;
12+
13+
$c->name = 'John Snow';
14+
15+
$this->assertEquals(
16+
'John Snow',
17+
$c->name,
18+
'You can define new items just like you would define a property on an instance.'
19+
);
20+
}
21+
22+
public function testDefinitionOfItemWithAnonymousFunctionExecutesItAndReturnsItsValueUponUsage()
23+
{
24+
$c = new Container;
25+
26+
$c->name = function() { return 'John Doe'; };
27+
28+
$this->assertEquals(
29+
'John Doe',
30+
$c->name,
31+
'The function gets executed and the return value is stored in the container.'
32+
);
33+
}
34+
35+
public function testDefinitionOfItemOnContainerWithItems()
36+
{
37+
$c = new Container(<<<INI
38+
respect_blah = ""
39+
INI
40+
);
41+
42+
$c->panda = function() { return 'ok'; };
43+
44+
$this->assertEquals(
45+
'ok',
46+
$c->panda,
47+
'It works if the container has stuff or not.'
48+
);
49+
}
50+
51+
/**
52+
* @group issue
53+
* @ticket 14
54+
*/
55+
public function testItemOverwrrite()
56+
{
57+
$c = new Container(<<<INI
58+
[pdo StdClass]
59+
60+
[db Test\Stub\DatabaseWow]
61+
con = [pdo];
62+
INI
63+
);
64+
65+
$c->pdo = new \PDO('sqlite::memory:');
66+
67+
$this->assertNotInstanceOf(
68+
'StdClass',
69+
$c->pdo,
70+
'Although PDO was defined with StdClass we overwritten it to a proper instance of PDO manually.'
71+
);
72+
73+
$this->assertSame(
74+
$c->pdo,
75+
$c->db->c,
76+
'This should overwrite every usage of that element inside the container.'
77+
);
78+
}
79+
}
80+
81+
namespace Test\Stub;
82+
83+
class DatabaseWow
84+
{
85+
public $c;
86+
87+
public function __construct($con)
88+
{
89+
$this->c = $con;
90+
}
91+
}
92+

0 commit comments

Comments
 (0)