-
Notifications
You must be signed in to change notification settings - Fork 9
/
bucket.test.php
237 lines (221 loc) · 7.37 KB
/
bucket.test.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
<?php
require_once 'vendor/simpletest/simpletest/unit_tester.php';
if (realpath($_SERVER['PHP_SELF']) == __FILE__) {
error_reporting(E_ALL | E_STRICT);
require_once 'vendor/simpletest/simpletest/autorun.php';
}
require_once 'lib/bucket.inc.php';
class NoDependencies {}
class ExtendsNoDependencies extends NoDependencies {}
class SingleClassDependency {
public $val;
function __construct(NoDependencies $val) {
$this->val = $val;
}
}
class DefaultValue {
public $val;
function __construct($val = 42) {
$this->val = $val;
}
}
class UnTypedDependency {
public $val;
function __construct($val) {
$this->val = $val;
}
}
interface AnInterface {};
class ConcreteImplementation implements AnInterface {}
class DependsOnInterface {
public $val;
function __construct(AnInterface $val) {
$this->val = $val;
}
}
class TestFactory {
public $invoked = false;
function new_NoDependencies($container) {
$this->invoked = true;
return new NoDependencies();
}
function new_ConcreteImplementation($container) {
$this->invoked = true;
return new NoDependencies();
}
}
class RequireUndefinedClass {
function __construct(ClassThatDoesntExist $autoloaded) {}
}
class TriedToAutoloadException extends Exception {
public $classname;
function __construct($classname) {
$this->classname = $classname;
parent::__construct();
}
}
class TestUnderscoreCallFactory {
public $invoked = false;
function __call($name, $args) {
$this->invoked = true;
return new StdClass();
}
}
class TestOfBucketResolving extends UnitTestCase {
function test_can_create_empty_container() {
$bucket = new bucket_Container();
}
function test_can_create_class_with_no_dependencies() {
$bucket = new bucket_Container();
$this->assertIsA($bucket->create('NoDependencies'), 'NoDependencies');
}
function test_can_create_class_with_class_dependency() {
$bucket = new bucket_Container();
$o = $bucket->create('SingleClassDependency');
$this->assertIsA($o, 'SingleClassDependency');
$this->assertIsA($o->val, 'NoDependencies');
}
function test_can_create_class_with_default_value() {
$bucket = new bucket_Container();
$o = $bucket->create('DefaultValue');
$this->assertIsA($o, 'DefaultValue');
$this->assertEqual($o->val, 42);
}
function test_barks_on_untyped_dependency() {
$bucket = new bucket_Container();
try {
$bucket->create('UnTypedDependency');
$this->fail("Expected exception");
} catch (bucket_CreationException $ex) {
$this->pass("Exception caught");
}
}
function test_barks_on_interface_dependency_when_unregistered() {
$bucket = new bucket_Container();
try {
$bucket->create('DependsOnInterface');
$this->fail("Expected exception");
} catch (bucket_CreationException $ex) {
$this->pass("Exception caught");
}
}
function test_can_create_class_with_interface_dependency() {
$bucket = new bucket_Container();
$bucket->registerImplementation('AnInterface', 'ConcreteImplementation');
$o = $bucket->create('DependsOnInterface');
$this->assertIsA($o, 'DependsOnInterface');
$this->assertIsA($o->val, 'ConcreteImplementation');
}
function test_can_set_different_implementation_for_concrete_class() {
$bucket = new bucket_Container();
$bucket->registerImplementation('NoDependencies', 'ExtendsNoDependencies');
$o = $bucket->create('SingleClassDependency');
$this->assertIsA($o, 'SingleClassDependency');
$this->assertIsA($o->val, 'ExtendsNoDependencies');
}
}
class TestOfBucketContainer extends UnitTestCase {
function test_get_creates_new_object() {
$bucket = new bucket_Container();
$this->assertIsA($bucket->get('NoDependencies'), 'NoDependencies');
}
function test_get_returns_same_instance_on_subsequent_calls() {
$bucket = new bucket_Container();
$this->assertSame(
$bucket->get('NoDependencies'),
$bucket->get('NoDependencies'));
}
}
class TestOfBucketFactory extends UnitTestCase {
function test_container_delegates_to_factory_method() {
$factory = new TestFactory();
$bucket = new bucket_Container($factory);
$this->assertIsA($bucket->get('NoDependencies'), 'NoDependencies');
$this->assertTrue($factory->invoked);
}
function test_container_can_return_different_implementation() {
$bucket = new bucket_Container(new TestFactory());
$this->assertIsA($bucket->get('ConcreteImplementation'), 'NoDependencies');
}
function test_container_delegates_to_factory_callback() {
$factory = new TestFactory();
$factory->new_defaultvalue = create_function('', 'return new StdClass();');
// For PHP 5.3+
// $factory->new_defaultvalue = function($container) {
// return new StdClass();
// }
$bucket = new bucket_Container($factory);
$this->assertIsA($bucket->get('DefaultValue'), 'StdClass');
}
function test_callback_takes_precedence_over_method() {
$factory = new TestFactory();
$factory->new_nodependencies = create_function('', 'return new StdClass();');
// For PHP 5.3+
// $factory->new_nodependencies = function($container) {
// return new StdClass();
// }
$bucket = new bucket_Container($factory);
$this->assertIsA($bucket->get('NoDependencies'), 'StdClass');
}
function test_container_can_take_array_of_callbacks_as_argument() {
$bucket = new bucket_Container(
array(
'DefaultValue' => create_function('', 'return new StdClass();')
)
);
// For PHP 5.3+
// $bucket = new bucket_Container(
// array(
// 'DefaultValue' => function($container) {
// return new StdClass();
// }
// )
// );
$this->assertIsA($bucket->get('DefaultValue'), 'StdClass');
}
function test_underscore_call_is_callable() {
$factory = new TestUnderscoreCallFactory();
$bucket = new bucket_Container($factory);
$this->assertIsA($bucket->get('StdClass'), 'StdClass');
$this->assertTrue($factory->invoked);
}
}
class TestOfBucketScope extends UnitTestCase {
function test_a_child_scope_uses_parent_factory() {
$factory = new TestFactory();
$bucket = new bucket_Container($factory);
$scope = $bucket->makeChildContainer();
$this->assertIsA($scope->get('NoDependencies'), 'NoDependencies');
$this->assertTrue($factory->invoked);
}
function test_get_on_a_child_scope_returns_same_instance_on_subsequent_calls() {
$factory = new TestFactory();
$bucket = new bucket_Container($factory);
$scope = $bucket->makeChildContainer();
$this->assertSame(
$scope->get('NoDependencies'),
$scope->get('NoDependencies'));
}
function test_get_on_a_child_scope_returns_parent_state() {
$factory = new TestFactory();
$bucket = new bucket_Container($factory);
$scope = $bucket->makeChildContainer();
$o = $bucket->get('NoDependencies');
$this->assertSame(
$o,
$scope->get('NoDependencies'));
}
function test_parent_scope_doesnt_see_child_state() {
$factory = new TestFactory();
$bucket = new bucket_Container($factory);
$scope = $bucket->makeChildContainer();
$o = $scope->get('NoDependencies');
$this->assertFalse($o === $bucket->get('NoDependencies'));
}
function test_setting_an_instance_and_getting_it_should_return_same_instance() {
$bucket = new bucket_Container();
$obj = new StdClass();
$bucket->set($obj);
$this->assertSame($bucket->get('StdClass'), $obj);
}
}