ILIAS  trunk Revision v11.0_alpha-1702-gfd3ecb7f852
All Data Structures Namespaces Files Functions Variables Enumerations Enumerator Modules Pages
ResolverTest.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
22 
27 
28 class ResolverTest extends TestCase
29 {
30  protected Resolver $resolver;
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 
205  public function testUseDisambiguateDuplicateSpecific(): void
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 
239  public function testUseDisambiguateDuplicateGeneric(): void
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 }
while($session_entry=$r->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) return null