ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
ResolverTest.php
Go to the documentation of this file.
1<?php
2
19declare(strict_types=1);
20
22
23use PHPUnit\Framework\TestCase;
27
28class ResolverTest extends TestCase
29{
31
32 public function setUp(): void
33 {
34 $this->resolver = new Resolver();
35 }
36
37 public function testEmptyComponentSet(): void
38 {
39 $result = $this->resolver->resolveDependencies([]);
40
41 $this->assertEquals([], $result);
42 }
43
44 public function testResolvePull(): void
45 {
46 $component = $this->createMock(Component::class);
47
48 $name = TestInterface::class;
49
50 $pull = new D\In(D\InType::PULL, $name);
51 $provide = new D\Out(D\OutType::PROVIDE, $name, null, []);
52
53 $c1 = new D\OfComponent($component, $pull);
54 $c2 = new D\OfComponent($component, $provide);
55
56 $result = $this->resolver->resolveDependencies([], $c1, $c2);
57
58 $pull = new D\In(D\InType::PULL, $name);
59 $provide = new D\Out(D\OutType::PROVIDE, $name, null, []);
60 $pull->addResolution($provide);
61
62 $c1 = new D\OfComponent($component, $pull);
63 $c2 = new D\OfComponent($component, $provide);
64
65 $this->assertEquals([$c1, $c2], $result);
66 }
67
68 public function testPullFailsNotExistent(): void
69 {
70 $this->expectException(\LogicException::class);
71
72 $component = $this->createMock(Component::class);
73
74 $name = TestInterface::class;
75
76 $pull = new D\In(D\InType::PULL, $name);
77
78 $c1 = new D\OfComponent($component, $pull);
79
80 $this->resolver->resolveDependencies([], $c1);
81 }
82
83 public function testPullFailsDuplicate(): void
84 {
85 $this->expectException(\LogicException::class);
86
87 $component = $this->createMock(Component::class);
88
89 $name = TestInterface::class;
90
91 $pull = new D\In(D\InType::PULL, $name);
92 $provide1 = new D\Out(D\OutType::PROVIDE, $name, null, []);
93 $provide2 = new D\Out(D\OutType::PROVIDE, $name, null, []);
94
95 $c1 = new D\OfComponent($component, $pull);
96 $c2 = new D\OfComponent($component, $provide1);
97 $c3 = new D\OfComponent($component, $provide2);
98
99 $this->resolver->resolveDependencies([], $c1, $c2, $c3);
100 }
101
102 public function testEmptySeek(): void
103 {
104 $component = $this->createMock(Component::class);
105
106 $name = TestInterface::class;
107
108 $seek = new D\In(D\InType::SEEK, $name);
109
110 $c1 = new D\OfComponent($component, $seek);
111
112 $result = $this->resolver->resolveDependencies([], $c1);
113
114 $this->assertEquals([$c1], $result);
115 }
116
117 public function testResolveSeek(): void
118 {
119 $component = $this->createMock(Component::class);
120
121 $name = TestInterface::class;
122
123 $seek = new D\In(D\InType::SEEK, $name);
124 $contribute1 = new D\Out(D\OutType::CONTRIBUTE, $name, null, []);
125 $contribute2 = new D\Out(D\OutType::CONTRIBUTE, $name, null, []);
126
127 $c1 = new D\OfComponent($component, $seek);
128 $c2 = new D\OfComponent($component, $contribute1);
129 $c3 = new D\OfComponent($component, $contribute2);
130
131 $result = $this->resolver->resolveDependencies([], $c1, $c2, $c3);
132
133
134 $seek = new D\In(D\InType::SEEK, $name);
135 $contribute1 = new D\Out(D\OutType::CONTRIBUTE, $name, null, []);
136 $contribute2 = new D\Out(D\OutType::CONTRIBUTE, $name, null, []);
137 $seek->addResolution($contribute1);
138 $seek->addResolution($contribute2);
139
140 $c1 = new D\OfComponent($component, $seek);
141 $c2 = new D\OfComponent($component, $contribute1);
142 $c3 = new D\OfComponent($component, $contribute2);
143
144 $this->assertEquals([$c1, $c2, $c3], $result);
145 }
146
147 public function testResolveUseOneOption(): void
148 {
149 $component = $this->createMock(Component::class);
150
151 $name = TestInterface::class;
152
153 $use = new D\In(D\InType::USE, $name);
154 $implement = new D\Out(D\OutType::IMPLEMENT, $name, ["class" => "Some\\Class"], []);
155
156 $c1 = new D\OfComponent($component, $use);
157 $c2 = new D\OfComponent($component, $implement);
158
159 $result = $this->resolver->resolveDependencies([], $c1, $c2);
160
161 $use = new D\In(D\InType::USE, $name);
162 $implement = new D\Out(D\OutType::IMPLEMENT, $name, ["class" => "Some\\Class"], []);
163 $use->addResolution($implement);
164
165 $c1 = new D\OfComponent($component, $use);
166 $c2 = new D\OfComponent($component, $implement);
167
168 $this->assertEquals([$c1, $c2], $result);
169 }
170
171 public function testUseFailsNotExistent(): void
172 {
173 $this->expectException(\LogicException::class);
174
175 $component = $this->createMock(Component::class);
176
177 $name = TestInterface::class;
178
179 $use = new D\In(D\InType::USE, $name);
180
181 $c1 = new D\OfComponent($component, $use);
182
183 $this->resolver->resolveDependencies([], $c1);
184 }
185
186 public function testUseFailsDuplicate(): void
187 {
188 $this->expectException(\LogicException::class);
189
190 $component = $this->createMock(Component::class);
191
192 $name = TestInterface::class;
193
194 $use = new D\In(D\InType::USE, $name);
195 $implement1 = new D\Out(D\OutType::IMPLEMENT, $name, ["class" => "Some\\Class"], []);
196 $implement2 = new D\Out(D\OutType::IMPLEMENT, $name, ["class" => "Some\\Class"], []);
197
198 $c1 = new D\OfComponent($component, $use);
199 $c2 = new D\OfComponent($component, $implement1);
200 $c3 = new D\OfComponent($component, $implement2);
201
202 $this->resolver->resolveDependencies([], $c1, $c2, $c3);
203 }
204
206 {
207 $component = $this->createMock(Component::class);
208
209 $name = TestInterface::class;
210
211 $use = new D\In(D\InType::USE, $name);
212 $implement1 = new D\Out(D\OutType::IMPLEMENT, $name, ["class" => "Some\\Class"], []);
213 $implement2 = new D\Out(D\OutType::IMPLEMENT, $name, ["class" => "Some\\OtherClass"], []);
214
215 $c1 = new D\OfComponent($component, $use);
216 $c2 = new D\OfComponent($component, $implement1);
217 $c3 = new D\OfComponent($component, $implement2);
218
219 $disambiguation = [
220 get_class($component) => [
221 TestInterface::class => "Some\\OtherClass"
222 ]
223 ];
224
225 $result = $this->resolver->resolveDependencies($disambiguation, $c1, $c2, $c3);
226
227 $use = new D\In(D\InType::USE, $name);
228 $implement1 = new D\Out(D\OutType::IMPLEMENT, $name, ["class" => "Some\\Class"], []);
229 $implement2 = new D\Out(D\OutType::IMPLEMENT, $name, ["class" => "Some\\OtherClass"], []);
230 $use->addResolution($implement2);
231
232 $c1 = new D\OfComponent($component, $use);
233 $c2 = new D\OfComponent($component, $implement1);
234 $c3 = new D\OfComponent($component, $implement2);
235
236 $this->assertEquals([$c1, $c2, $c3], $result);
237 }
238
240 {
241 $component = $this->createMock(Component::class);
242
243 $name = TestInterface::class;
244
245 $use = new D\In(D\InType::USE, $name);
246 $implement1 = new D\Out(D\OutType::IMPLEMENT, $name, ["class" => "Some\\Class"], []);
247 $implement2 = new D\Out(D\OutType::IMPLEMENT, $name, ["class" => "Some\\OtherClass"], []);
248
249 $c1 = new D\OfComponent($component, $use);
250 $c2 = new D\OfComponent($component, $implement1);
251 $c3 = new D\OfComponent($component, $implement2);
252
253 $disambiguation = [
254 "*" => [
255 TestInterface::class => "Some\\OtherClass"
256 ]
257 ];
258
259 $result = $this->resolver->resolveDependencies($disambiguation, $c1, $c2, $c3);
260
261 $use = new D\In(D\InType::USE, $name);
262 $implement1 = new D\Out(D\OutType::IMPLEMENT, $name, ["class" => "Some\\Class"], []);
263 $implement2 = new D\Out(D\OutType::IMPLEMENT, $name, ["class" => "Some\\OtherClass"], []);
264 $use->addResolution($implement2);
265
266
267 $c1 = new D\OfComponent($component, $use);
268 $c2 = new D\OfComponent($component, $implement1);
269 $c3 = new D\OfComponent($component, $implement2);
270
271 $this->assertEquals([$c1, $c2, $c3], $result);
272 }
273
274 public function testFindSimpleCycle(): void
275 {
276 $this->expectException(\LogicException::class);
277
278 $component = $this->createMock(Component::class);
279
280 $name = TestInterface::class;
281 $name2 = TestInterface2::class;
282
283 $pull = new D\In(D\InType::PULL, $name);
284 $provide = new D\Out(D\OutType::PROVIDE, $name2, "Some\\Class", [$pull], []);
285 $c1 = new D\OfComponent($component, $pull, $provide);
286
287 $pull = new D\In(D\InType::PULL, $name2);
288 $provide = new D\Out(D\OutType::PROVIDE, $name, "Some\\OtherClass", [$pull], []);
289 $c2 = new D\OfComponent($component, $pull, $provide);
290
291
292 $result = $this->resolver->resolveDependencies([], $c1, $c2);
293 }
294
295 public function testFindLongerCycle(): void
296 {
297 $this->expectException(\LogicException::class);
298
299 $component = $this->createMock(Component::class);
300
301 $name = TestInterface::class;
302 $name2 = TestInterface2::class;
303 $name3 = TestInterface3::class;
304
305 $pull = new D\In(D\InType::PULL, $name);
306 $provide = new D\Out(D\OutType::PROVIDE, $name2, "Some\\Class", [$pull], []);
307 $c1 = new D\OfComponent($component, $pull, $provide);
308
309 $pull = new D\In(D\InType::PULL, $name2);
310 $provide = new D\Out(D\OutType::PROVIDE, $name3, "Some\\OtherClass", [$pull], []);
311 $c2 = new D\OfComponent($component, $pull, $provide);
312
313 $pull = new D\In(D\InType::PULL, $name3);
314 $provide = new D\Out(D\OutType::PROVIDE, $name, "Some\\OtherOtherClass", [$pull], []);
315 $c3 = new D\OfComponent($component, $pull, $provide);
316
317
318 $result = $this->resolver->resolveDependencies([], $c1, $c2, $c3);
319 }
320}
A dependency where the component needs something from the world.
Definition: In.php:27
A dependency where the component gives something to the world.
Definition: Out.php:27