/
BuilderTest.php
279 lines (239 loc) · 13.7 KB
/
BuilderTest.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
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
<?php
/*
* This file is part of the symfony package.
* (c) Fabien Potencier <fabien.potencier@symfony-project.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
require_once __DIR__.'/../../../bootstrap.php';
use Symfony\Components\DependencyInjection\Builder;
use Symfony\Components\DependencyInjection\BuilderConfiguration;
use Symfony\Components\DependencyInjection\Definition;
use Symfony\Components\DependencyInjection\Reference;
$fixturesPath = __DIR__.'/../../../../fixtures/Symfony/Components/DependencyInjection/';
$t = new LimeTest(55);
// ->setDefinitions() ->addDefinitions() ->getDefinitions() ->setDefinition() ->getDefinition() ->hasDefinition()
$t->diag('->setDefinitions() ->addDefinitions() ->getDefinitions() ->setDefinition() ->getDefinition() ->hasDefinition()');
$builder = new Builder();
$definitions = array(
'foo' => new Definition('FooClass'),
'bar' => new Definition('BarClass'),
);
$builder->setDefinitions($definitions);
$t->is($builder->getDefinitions(), $definitions, '->setDefinitions() sets the service definitions');
$t->ok($builder->hasDefinition('foo'), '->hasDefinition() returns true if a service definition exists');
$t->ok(!$builder->hasDefinition('foobar'), '->hasDefinition() returns false if a service definition does not exist');
$builder->setDefinition('foobar', $foo = new Definition('FooBarClass'));
$t->is($builder->getDefinition('foobar'), $foo, '->getDefinition() returns a service definition if defined');
$t->ok($builder->setDefinition('foobar', $foo = new Definition('FooBarClass')) === $foo, '->setDefinition() implements a fuild interface by returning the service reference');
$builder->addDefinitions($defs = array('foobar' => new Definition('FooBarClass')));
$t->is($builder->getDefinitions(), array_merge($definitions, $defs), '->addDefinitions() adds the service definitions');
try
{
$builder->getDefinition('baz');
$t->fail('->getDefinition() throws an InvalidArgumentException if the service definition does not exist');
}
catch (InvalidArgumentException $e)
{
$t->pass('->getDefinition() throws an InvalidArgumentException if the service definition does not exist');
}
// ->register()
$t->diag('->register()');
$builder = new Builder();
$builder->register('foo', 'FooClass');
$t->ok($builder->hasDefinition('foo'), '->register() registers a new service definition');
$t->ok($builder->getDefinition('foo') instanceof Definition, '->register() returns the newly created Definition instance');
// ->hasService()
$t->diag('->hasService()');
$builder = new Builder();
$t->ok(!$builder->hasService('foo'), '->hasService() returns false if the service does not exist');
$builder->register('foo', 'FooClass');
$t->ok($builder->hasService('foo'), '->hasService() returns true if a service definition exists');
$builder->bar = new stdClass();
$t->ok($builder->hasService('bar'), '->hasService() returns true if a service exists');
// ->getService()
$t->diag('->getService()');
$builder = new Builder();
try
{
$builder->getService('foo');
$t->fail('->getService() throws an InvalidArgumentException if the service does not exist');
}
catch (InvalidArgumentException $e)
{
$t->pass('->getService() throws an InvalidArgumentException if the service does not exist');
}
$builder->register('foo', 'stdClass');
$t->ok(is_object($builder->getService('foo')), '->getService() returns the service definition associated with the id');
$builder->bar = $bar = new stdClass();
$t->is($builder->getService('bar'), $bar, '->getService() returns the service associated with the id');
$builder->register('bar', 'stdClass');
$t->is($builder->getService('bar'), $bar, '->getService() returns the service associated with the id even if a definition has been defined');
$builder->register('baz', 'stdClass')->setArguments(array(new Reference('baz')));
try
{
@$builder->getService('baz');
$t->fail('->getService() throws a LogicException if the service has a circular reference to itself');
}
catch (LogicException $e)
{
$t->pass('->getService() throws a LogicException if the service has a circular reference to itself');
}
$builder->register('foobar', 'stdClass')->setShared(true);
$t->ok($builder->getService('bar') === $builder->getService('bar'), '->getService() always returns the same instance if the service is shared');
// ->getServiceIds()
$t->diag('->getServiceIds()');
$builder = new Builder();
$builder->register('foo', 'stdClass');
$builder->bar = $bar = new stdClass();
$builder->register('bar', 'stdClass');
$t->is($builder->getServiceIds(), array('foo', 'bar', 'service_container'), '->getServiceIds() returns all defined service ids');
// ->setAlias()
$t->diag('->setAlias()');
$builder = new Builder();
$builder->register('foo', 'stdClass');
$builder->setAlias('bar', 'foo');
$t->ok($builder->hasService('bar'), '->setAlias() defines a new service');
$t->ok($builder->getService('bar') === $builder->getService('foo'), '->setAlias() creates a service that is an alias to another one');
// ->getAliases()
$t->diag('->getAliases()');
$builder = new Builder();
$builder->setAlias('bar', 'foo');
$builder->setAlias('foobar', 'foo');
$t->is($builder->getAliases(), array('bar' => 'foo', 'foobar' => 'foo'), '->getAliases() returns all service aliases');
$builder->register('bar', 'stdClass');
$t->is($builder->getAliases(), array('foobar' => 'foo'), '->getAliases() does not return aliased services that have been overridden');
$builder->setService('foobar', 'stdClass');
$t->is($builder->getAliases(), array(), '->getAliases() does not return aliased services that have been overridden');
// ->createService() # file
$t->diag('->createService() # file');
$builder = new Builder();
$builder->register('foo1', 'FooClass')->setFile($fixturesPath.'/includes/foo.php');
$t->ok($builder->getService('foo1'), '->createService() requires the file defined by the service definition');
$builder->register('foo2', 'FooClass')->setFile($fixturesPath.'/includes/%file%.php');
$builder->setParameter('file', 'foo');
$t->ok($builder->getService('foo2'), '->createService() replaces parameters in the file provided by the service definition');
// ->createService() # class
$t->diag('->createService() # class');
$builder = new Builder();
$builder->register('foo1', '%class%');
$builder->setParameter('class', 'stdClass');
$t->ok($builder->getService('foo1') instanceof stdClass, '->createService() replaces parameters in the class provided by the service definition');
// ->createService() # arguments
$t->diag('->createService() # arguments');
$builder = new Builder();
$builder->register('bar', 'stdClass');
$builder->register('foo1', 'FooClass')->addArgument(array('foo' => '%value%', '%value%' => 'foo', new Reference('bar')));
$builder->setParameter('value', 'bar');
$t->is($builder->getService('foo1')->arguments, array('foo' => 'bar', 'bar' => 'foo', $builder->getService('bar')), '->createService() replaces parameters and service references in the arguments provided by the service definition');
// ->createService() # constructor
$t->diag('->createService() # constructor');
$builder = new Builder();
$builder->register('bar', 'stdClass');
$builder->register('foo1', 'FooClass')->setConstructor('getInstance')->addArgument(array('foo' => '%value%', '%value%' => 'foo', new Reference('bar')));
$builder->setParameter('value', 'bar');
$t->ok($builder->getService('foo1')->called, '->createService() calls the constructor to create the service instance');
$t->is($builder->getService('foo1')->arguments, array('foo' => 'bar', 'bar' => 'foo', $builder->getService('bar')), '->createService() passes the arguments to the constructor');
// ->createService() # method calls
$t->diag('->createService() # method calls');
$builder = new Builder();
$builder->register('bar', 'stdClass');
$builder->register('foo1', 'FooClass')->addMethodCall('setBar', array(array('%value%', new Reference('bar'))));
$builder->setParameter('value', 'bar');
$t->is($builder->getService('foo1')->bar, array('bar', $builder->getService('bar')), '->createService() replaces the values in the method calls arguments');
// ->createService() # configurator
require_once $fixturesPath.'/includes/classes.php';
$t->diag('->createService() # configurator');
$builder = new Builder();
$builder->register('foo1', 'FooClass')->setConfigurator('sc_configure');
$t->ok($builder->getService('foo1')->configured, '->createService() calls the configurator');
$builder->register('foo2', 'FooClass')->setConfigurator(array('%class%', 'configureStatic'));
$builder->setParameter('class', 'BazClass');
$t->ok($builder->getService('foo2')->configured, '->createService() calls the configurator');
$builder->register('baz', 'BazClass');
$builder->register('foo3', 'FooClass')->setConfigurator(array(new Reference('baz'), 'configure'));
$t->ok($builder->getService('foo3')->configured, '->createService() calls the configurator');
$builder->register('foo4', 'FooClass')->setConfigurator('foo');
try
{
$builder->getService('foo4');
$t->fail('->createService() throws an InvalidArgumentException if the configure callable is not a valid callable');
}
catch (InvalidArgumentException $e)
{
$t->pass('->createService() throws an InvalidArgumentException if the configure callable is not a valid callable');
}
// ::resolveValue()
$t->diag('::resolveValue()');
$t->is(Builder::resolveValue('foo', array()), 'foo', '->resolveValue() returns its argument unmodified if no placeholders are found');
$t->is(Builder::resolveValue('I\'m a %foo%', array('foo' => 'bar')), 'I\'m a bar', '->resolveValue() replaces placeholders by their values');
$t->ok(Builder::resolveValue('%foo%', array('foo' => true)) === true, '->resolveValue() replaces arguments that are just a placeholder by their value without casting them to strings');
$t->is(Builder::resolveValue(array('%foo%' => '%foo%'), array('foo' => 'bar')), array('bar' => 'bar'), '->resolveValue() replaces placeholders in keys and values of arrays');
$t->is(Builder::resolveValue(array('%foo%' => array('%foo%' => array('%foo%' => '%foo%'))), array('foo' => 'bar')), array('bar' => array('bar' => array('bar' => 'bar'))), '->resolveValue() replaces placeholders in nested arrays');
$t->is(Builder::resolveValue('I\'m a %%foo%%', array('foo' => 'bar')), 'I\'m a %foo%', '->resolveValue() supports % escaping by doubling it');
$t->is(Builder::resolveValue('I\'m a %foo% %%foo %foo%', array('foo' => 'bar')), 'I\'m a bar %foo bar', '->resolveValue() supports % escaping by doubling it');
try
{
Builder::resolveValue('%foobar%', array());
$t->fail('->resolveValue() throws a RuntimeException if a placeholder references a non-existant parameter');
}
catch (RuntimeException $e)
{
$t->pass('->resolveValue() throws a RuntimeException if a placeholder references a non-existant parameter');
}
try
{
Builder::resolveValue('foo %foobar% bar', array());
$t->fail('->resolveValue() throws a RuntimeException if a placeholder references a non-existant parameter');
}
catch (RuntimeException $e)
{
$t->pass('->resolveValue() throws a RuntimeException if a placeholder references a non-existant parameter');
}
// ->resolveServices()
$t->diag('->resolveServices()');
$builder = new Builder();
$builder->register('foo', 'FooClass');
$t->is($builder->resolveServices(new Reference('foo')), $builder->getService('foo'), '->resolveServices() resolves service references to service instances');
$t->is($builder->resolveServices(array('foo' => array('foo', new Reference('foo')))), array('foo' => array('foo', $builder->getService('foo'))), '->resolveServices() resolves service references to service instances in nested arrays');
// ->merge()
$t->diag('->merge()');
$container = new Builder();
$container->merge(null);
$t->is($container->getParameters(), array(), '->merge() accepts null as an argument');
$t->is($container->getDefinitions(), array(), '->merge() accepts null as an argument');
$container = new Builder(array('bar' => 'foo'));
$config = new BuilderConfiguration();
$config->setParameters(array('foo' => 'bar'));
$container->merge($config);
$t->is($container->getParameters(), array('bar' => 'foo', 'foo' => 'bar'), '->merge() merges current parameters with the loaded ones');
$container = new Builder(array('bar' => 'foo', 'foo' => 'baz'));
$config = new BuilderConfiguration();
$config->setParameters(array('foo' => 'bar'));
$container->merge($config);
$t->is($container->getParameters(), array('bar' => 'foo', 'foo' => 'baz'), '->merge() does not change the already defined parameters');
$container = new Builder(array('bar' => 'foo'));
$config = new BuilderConfiguration();
$config->setParameters(array('foo' => '%bar%'));
$container->merge($config);
$t->is($container->getParameters(), array('bar' => 'foo', 'foo' => 'foo'), '->merge() evaluates the values of the parameters towards already defined ones');
$container = new Builder(array('bar' => 'foo'));
$config = new BuilderConfiguration();
$config->setParameters(array('foo' => '%bar%', 'baz' => '%foo%'));
$container->merge($config);
$t->is($container->getParameters(), array('bar' => 'foo', 'foo' => 'foo', 'baz' => 'foo'), '->merge() evaluates the values of the parameters towards already defined ones');
$container = new Builder();
$container->register('foo', 'FooClass');
$container->register('bar', 'BarClass');
$config = new BuilderConfiguration();
$config->setDefinition('baz', new Definition('BazClass'));
$config->setAlias('alias_for_foo', 'foo');
$container->merge($config);
$t->is(array_keys($container->getDefinitions()), array('foo', 'bar', 'baz'), '->merge() merges definitions already defined ones');
$t->is($container->getAliases(), array('alias_for_foo' => 'foo'), '->merge() registers defined aliases');
$container = new Builder();
$container->register('foo', 'FooClass');
$config->setDefinition('foo', new Definition('BazClass'));
$container->merge($config);
$t->is($container->getDefinition('foo')->getClass(), 'BazClass', '->merge() overrides already defined services');