Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(296)

Side by Side Diff: third_party/pkg/di/test/main.dart

Issue 1086713003: Remove everything but markdown from third_party (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 @Injectables(const [
2 ClassOne,
3 CircularA,
4 CircularB,
5 MultipleConstructors,
6 NumDependency,
7 IntDependency,
8 DoubleDependency,
9 BoolDependency,
10 StringDependency
11 ])
12 library di.tests;
13
14 import 'fixed-unittest.dart';
15 import 'package:di/di.dart';
16 import 'package:di/dynamic_injector.dart';
17 import 'package:di/static_injector.dart';
18 import 'package:di/annotations.dart';
19
20 // Generated file. Run ../test_tf_gen.sh.
21 import 'type_factories_gen.dart' as type_factories_gen;
22
23 /**
24 * Annotation used to mark classes for which static type factory must be
25 * generated. For testing purposes not all classes are marked with this
26 * annotation, some classes are included in @Injectables at the top.
27 */
28 class Injectable {
29 const Injectable();
30 }
31
32 // just some classes for testing
33 @Injectable()
34 class Engine {
35 final String id = 'v8-id';
36 }
37
38 @Injectable()
39 class MockEngine implements Engine {
40 final String id = 'mock-id';
41 }
42
43 @Injectable()
44 class MockEngine2 implements Engine {
45 String id = 'mock-id-2';
46 }
47
48 class HiddenConstructor {
49 HiddenConstructor._();
50 }
51
52 @Injectable()
53 class Car {
54 Engine engine;
55 Injector injector;
56
57 Car(this.engine, this.injector);
58 }
59
60 class Lemon {
61 final engine;
62 final Injector injector;
63
64 Lemon(this.engine, this.injector);
65 }
66
67 class NumDependency {
68 NumDependency(num value) {}
69 }
70
71 class IntDependency {
72 IntDependency(int value) {}
73 }
74
75 class DoubleDependency {
76 DoubleDependency(double value) {}
77 }
78
79 class StringDependency {
80 StringDependency(String value) {}
81 }
82
83 class BoolDependency {
84 BoolDependency(bool value) {}
85 }
86
87
88 class CircularA {
89 CircularA(CircularB b) {}
90 }
91
92 class CircularB {
93 CircularB(CircularA a) {}
94 }
95
96 typedef int CompareInt(int a, int b);
97
98 int compareIntAsc(int a, int b) => b.compareTo(a);
99
100 class WithTypeDefDependency {
101 CompareInt compare;
102
103 WithTypeDefDependency(this.compare);
104 }
105
106 class MultipleConstructors {
107 String instantiatedVia;
108 MultipleConstructors() : instantiatedVia = 'default';
109 MultipleConstructors.named() : instantiatedVia = 'named';
110 }
111
112 class InterfaceOne {
113 }
114
115 class ClassOne implements InterfaceOne {
116 ClassOne(Log log) {
117 log.add('ClassOne');
118 }
119 }
120
121 @Injectable()
122 class ParameterizedType<T1, T2> {
123 ParameterizedType();
124 }
125
126 @Injectable()
127 class ParameterizedDependency {
128 final ParameterizedType<bool, int> _p;
129 ParameterizedDependency(this._p);
130 }
131
132 @Injectable()
133 class GenericParameterizedDependency {
134 final ParameterizedType _p;
135 GenericParameterizedDependency(this._p);
136 }
137
138 @Injectable()
139 class Log {
140 var log = [];
141
142 add(String message) => log.add(message);
143 }
144
145 class EmulatedMockEngineFactory {
146 call(Injector i) => new MockEngine();
147 }
148
149 void main() {
150 createInjectorSpec('DynamicInjector',
151 (modules, [name]) => new DynamicInjector(modules: modules, name: name));
152
153 createInjectorSpec('StaticInjector',
154 (modules, [name]) => new StaticInjector(modules: modules, name: name,
155 typeFactories: type_factories_gen.typeFactories));
156
157 dynamicInjectorTest();
158 staticInjectorTest();
159 }
160
161 typedef Injector InjectorFactory(List<Module> modules, [String name]);
162
163 createInjectorSpec(String injectorName, InjectorFactory injectorFactory) {
164
165 describe(injectorName, () {
166
167 it('should instantiate a type', () {
168 var injector = injectorFactory([new Module()..type(Engine)]);
169 var instance = injector.get(Engine);
170
171 expect(instance, instanceOf(Engine));
172 expect(instance.id, toEqual('v8-id'));
173 });
174
175 it('should fail if no binding is found', () {
176 var injector = injectorFactory([]);
177 expect(() {
178 injector.get(Engine);
179 }, toThrow(NoProviderError, 'No provider found for Engine! '
180 '(resolving Engine)'));
181 });
182
183
184 it('should resolve basic dependencies', () {
185 var injector = injectorFactory([new Module()..type(Car)..type(Engine)]);
186 var instance = injector.get(Car);
187
188 expect(instance, instanceOf(Car));
189 expect(instance.engine.id, toEqual('v8-id'));
190 });
191
192
193 it('should inject generic parameterized types', () {
194 var injector = injectorFactory([new Module()
195 ..type(ParameterizedType)
196 ..type(GenericParameterizedDependency)
197 ]);
198 expect(injector.get(GenericParameterizedDependency),
199 new isInstanceOf<GenericParameterizedDependency>());
200 });
201
202
203 xit('should error while resolving parameterized types', () {
204 var injector = injectorFactory([new Module()
205 ..type(ParameterizedType)
206 ..type(ParameterizedDependency)
207 ]);
208 expect(() => injector.get(ParameterizedDependency), throws);
209 });
210
211
212 it('should allow modules and overriding providers', () {
213 var module = new Module()..type(Engine, implementedBy: MockEngine);
214
215 // injector is immutable
216 // you can't load more modules once it's instantiated
217 // (you can create a child injector)
218 var injector = injectorFactory([module]);
219 var instance = injector.get(Engine);
220
221 expect(instance.id, toEqual('mock-id'));
222 });
223
224
225 it('should only create a single instance', () {
226 var injector = injectorFactory([new Module()..type(Engine)]);
227 var first = injector.get(Engine);
228 var second = injector.get(Engine);
229
230 expect(first, toBe(second));
231 });
232
233
234 it('should allow providing values', () {
235 var module = new Module()
236 ..value(Engine, 'str value')
237 ..value(Car, 123);
238
239 var injector = injectorFactory([module]);
240 var abcInstance = injector.get(Engine);
241 var complexInstance = injector.get(Car);
242
243 expect(abcInstance, toEqual('str value'));
244 expect(complexInstance, toEqual(123));
245 });
246
247
248 it('should allow providing factory functions', () {
249 var module = new Module()..factory(Engine, (Injector injector) {
250 return 'factory-product';
251 });
252
253 var injector = injectorFactory([module]);
254 var instance = injector.get(Engine);
255
256 expect(instance, toEqual('factory-product'));
257 });
258
259
260 it('should allow providing with emulated factory functions', () {
261 var module = new Module();
262 module.factory(Engine, new EmulatedMockEngineFactory());
263
264 var injector = injectorFactory([module]);
265 var instance = injector.get(Engine);
266
267 expect(instance, new isInstanceOf<MockEngine>());
268 });
269
270
271 it('should inject injector into factory function', () {
272 var module = new Module()
273 ..type(Engine)
274 ..factory(Car, (Injector injector) {
275 return new Car(injector.get(Engine), injector);
276 });
277
278 var injector = injectorFactory([module]);
279 var instance = injector.get(Car);
280
281 expect(instance, instanceOf(Car));
282 expect(instance.engine.id, toEqual('v8-id'));
283 });
284
285
286 it('should throw an exception when injecting a primitive type', () {
287 var injector = injectorFactory([
288 new Module()
289 ..type(NumDependency)
290 ..type(IntDependency)
291 ..type(DoubleDependency)
292 ..type(BoolDependency)
293 ..type(StringDependency)
294 ]);
295
296 expect(() {
297 injector.get(NumDependency);
298 }, toThrow(NoProviderError, 'Cannot inject a primitive type of num! '
299 '(resolving NumDependency -> num)'));
300
301 expect(() {
302 injector.get(IntDependency);
303 }, toThrow(NoProviderError, 'Cannot inject a primitive type of int! '
304 '(resolving IntDependency -> int)'));
305
306 expect(() {
307 injector.get(DoubleDependency);
308 }, toThrow(NoProviderError, 'Cannot inject a primitive type of double! '
309 '(resolving DoubleDependency -> double)'));
310
311 expect(() {
312 injector.get(BoolDependency);
313 }, toThrow(NoProviderError, 'Cannot inject a primitive type of bool! '
314 '(resolving BoolDependency -> bool)'));
315
316 expect(() {
317 injector.get(StringDependency);
318 }, toThrow(NoProviderError, 'Cannot inject a primitive type of String! '
319 '(resolving StringDependency -> String)'));
320 });
321
322
323 it('should throw an exception when circular dependency', () {
324 var injector = injectorFactory([new Module()..type(CircularA)..type(Circul arB)]);
325
326 expect(() {
327 injector.get(CircularA);
328 }, toThrow(CircularDependencyError, 'Cannot resolve a circular dependency! '
329 '(resolving CircularA -> '
330 'CircularB -> CircularA)'));
331 });
332
333
334 it('should provide the injector as Injector', () {
335 var injector = injectorFactory([]);
336
337 expect(injector.get(Injector), toBe(injector));
338 });
339
340
341 it('should inject a typedef', () {
342 var module = new Module()..value(CompareInt, compareIntAsc);
343
344 var injector = injectorFactory([module]);
345 var compare = injector.get(CompareInt);
346
347 expect(compare(1, 2), toBe(1));
348 expect(compare(5, 2), toBe(-1));
349 });
350
351
352 it('should throw an exception when injecting typedef without providing it', () {
353 var injector = injectorFactory([new Module()..type(WithTypeDefDependency)] );
354
355 expect(() {
356 injector.get(WithTypeDefDependency);
357 }, throws);
358 });
359
360
361 it('should instantiate via the default/unnamed constructor', () {
362 var injector = injectorFactory([new Module()..type(MultipleConstructors)]) ;
363 MultipleConstructors instance = injector.get(MultipleConstructors);
364 expect(instance.instantiatedVia, 'default');
365 });
366
367 // CHILD INJECTORS
368 it('should inject from child', () {
369 var module = new Module()..type(Engine, implementedBy: MockEngine);
370
371 var parent = injectorFactory([new Module()..type(Engine)]);
372 var child = parent.createChild([module]);
373
374 var abcFromParent = parent.get(Engine);
375 var abcFromChild = child.get(Engine);
376
377 expect(abcFromParent.id, toEqual('v8-id'));
378 expect(abcFromChild.id, toEqual('mock-id'));
379 });
380
381
382 it('should enumerate across children', () {
383 var parent = injectorFactory([new Module()..type(Engine)]);
384 var child = parent.createChild([new Module()..type(MockEngine)]);
385
386 expect(parent.types, unorderedEquals(new Set.from([Engine, Injector])));
387 expect(child.types, unorderedEquals(new Set.from([Engine, MockEngine, Inje ctor])));
388 });
389
390
391 it('should inject instance from parent if not provided in child', () {
392 var module = new Module()..type(Car);
393
394 var parent = injectorFactory([new Module()..type(Car)..type(Engine)]);
395 var child = parent.createChild([module]);
396
397 var complexFromParent = parent.get(Car);
398 var complexFromChild = child.get(Car);
399 var abcFromParent = parent.get(Engine);
400 var abcFromChild = child.get(Engine);
401
402 expect(complexFromChild, not(toBe(complexFromParent)));
403 expect(abcFromChild, toBe(abcFromParent));
404 });
405
406
407 it('should inject instance from parent but never use dependency from child', () {
408 var module = new Module()..type(Engine, implementedBy: MockEngine);
409
410 var parent = injectorFactory([new Module()..type(Car)..type(Engine)]);
411 var child = parent.createChild([module]);
412
413 var complexFromParent = parent.get(Car);
414 var complexFromChild = child.get(Car);
415 var abcFromParent = parent.get(Engine);
416 var abcFromChild = child.get(Engine);
417
418 expect(complexFromChild, toBe(complexFromParent));
419 expect(complexFromChild.engine, toBe(abcFromParent));
420 expect(complexFromChild.engine, not(toBe(abcFromChild)));
421 });
422
423
424 it('should force new instance in child even if already instantiated in paren t', () {
425 var parent = injectorFactory([new Module()..type(Engine)]);
426 var abcAlreadyInParent = parent.get(Engine);
427
428 var child = parent.createChild([], forceNewInstances: [Engine]);
429 var abcFromChild = child.get(Engine);
430
431 expect(abcFromChild, not(toBe(abcAlreadyInParent)));
432 });
433
434
435 it('should force new instance in child using provider from grand parent', () {
436 var module = new Module()..type(Engine, implementedBy: MockEngine);
437
438 var grandParent = injectorFactory([module]);
439 var parent = grandParent.createChild([]);
440 var child = parent.createChild([], forceNewInstances: [Engine]);
441
442 var abcFromGrandParent = grandParent.get(Engine);
443 var abcFromChild = child.get(Engine);
444
445 expect(abcFromChild.id, toEqual(('mock-id')));
446 expect(abcFromChild, not(toBe(abcFromGrandParent)));
447 });
448
449
450 it('should provide child injector as Injector', () {
451 var injector = injectorFactory([]);
452 var child = injector.createChild([]);
453
454 expect(child.get(Injector), toBe(child));
455 });
456
457
458 it('should set the injector name', () {
459 var injector = injectorFactory([], 'foo');
460 expect(injector.name, 'foo');
461 });
462
463
464 it('should set the child injector name', () {
465 var injector = injectorFactory([], 'foo');
466 var childInjector = injector.createChild(null, name: 'bar');
467 expect(childInjector.name, 'bar');
468 });
469
470
471 it('should instantiate class only once (Issue #18)', () {
472 var injector = injectorFactory([
473 new Module()
474 ..type(Log)
475 ..type(ClassOne)
476 ..factory(InterfaceOne, (i) => i.get(ClassOne))
477 ]);
478
479 expect(injector.get(InterfaceOne), same(injector.get(ClassOne)));
480 expect(injector.get(Log).log.join(' '), 'ClassOne');
481 });
482
483
484 describe('creation strategy', () {
485
486 it('should get called for instance creation', () {
487
488 List creationLog = [];
489 dynamic creation(Injector requesting, Injector defining, factory) {
490 creationLog.add([requesting, defining]);
491 return factory();
492 }
493
494 var parentModule = new Module()
495 ..type(Engine, implementedBy: MockEngine, creation: creation)
496 ..type(Car, creation: creation);
497
498 var parentInjector = injectorFactory([parentModule]);
499 var childInjector = parentInjector.createChild([]);
500 childInjector.get(Car);
501 expect(creationLog, [
502 [childInjector, parentInjector],
503 [childInjector, parentInjector]
504 ]);
505 });
506
507 it('should be able to prevent instantiation', () {
508
509 List creationLog = [];
510 dynamic creation(Injector requesting, Injector defining, factory) {
511 throw 'not allowing';
512 }
513
514 var module = new Module()
515 ..type(Engine, implementedBy: MockEngine, creation: creation);
516 var injector = injectorFactory([module]);
517 expect(() {
518 injector.get(Engine);
519 }, throwsA('not allowing'));
520 });
521 });
522
523
524 describe('visiblity', () {
525
526 it('should hide instances', () {
527
528 var rootMock = new MockEngine();
529 var childMock = new MockEngine();
530
531 var parentModule = new Module()
532 ..value(Engine, rootMock);
533 var childModule = new Module()
534 ..value(Engine, childMock, visibility: (_, __) => false);
535
536 var parentInjector = injectorFactory([parentModule]);
537 var childInjector = parentInjector.createChild([childModule]);
538
539 var val = childInjector.get(Engine);
540 expect(val, same(rootMock));
541 });
542
543 it('should throw when an instance in not visible in the root injector', () {
544 var module = new Module()
545 ..value(Car, 'Invisible', visibility: (_, __) => false);
546
547 var injector = injectorFactory([module]);
548
549 expect(() {
550 injector.get(Car);
551 }, toThrow(
552 NoProviderError,
553 'No provider found for Car! (resolving Car)'
554 ));
555 });
556
557 });
558
559 });
560
561 }
562
563 void dynamicInjectorTest() {
564 describe('DynamicInjector', () {
565
566 it('should throw a comprehensible error message on untyped argument', () {
567 var module = new Module()..type(Lemon)..type(Engine);
568 var injector = new DynamicInjector(modules : [module]);
569
570 expect(() {
571 injector.get(Lemon);
572 }, toThrow(NoProviderError, "The 'engine' parameter must be typed "
573 "(resolving Lemon)"));
574 });
575
576 it('should throw a comprehensible error message when no default constructor found', () {
577 var module = new Module()..type(HiddenConstructor);
578 var injector = new DynamicInjector(modules: [module]);
579
580 expect(() {
581 injector.get(HiddenConstructor);
582 }, toThrow(NoProviderError, startsWith('Unable to find default '
583 'constructor for HiddenConstructor. Make sure class has a '
584 'default constructor.')));
585 });
586
587 });
588 }
589
590 void staticInjectorTest() {
591 describe('StaticInjector', () {
592
593 it('should use type factories passed in the constructor', () {
594 var module = new Module()
595 ..type(Engine);
596 var injector = new StaticInjector(modules: [module], typeFactories: {
597 Engine: (f) => new Engine()
598 });
599
600 var engine;
601 expect(() {
602 engine = injector.get(Engine);
603 }, isNot(throws));
604 expect(engine, new isInstanceOf<Engine>());
605 });
606
607 it('should use type factories passes in one module', () {
608 var module = new Module()
609 ..type(Engine)
610 ..typeFactories = {
611 Engine: (f) => new Engine()
612 };
613 var injector = new StaticInjector(modules: [module]);
614
615 var engine;
616 expect(() {
617 engine = injector.get(Engine);
618 }, isNot(throws));
619 expect(engine, new isInstanceOf<Engine>());
620 });
621
622 it('should use type factories passes in many modules', () {
623 var module1 = new Module()
624 ..type(Engine)
625 ..typeFactories = {
626 Engine: (f) => new Engine()
627 };
628 var module2 = new Module()
629 ..type(Car)
630 ..typeFactories = {
631 Car: (f) => new Car(f(Engine), f(Injector))
632 };
633
634 var injector = new StaticInjector(modules: [module1, module2]);
635
636 var engine;
637 expect(() {
638 engine = injector.get(Car);
639 }, isNot(throws));
640 expect(engine, new isInstanceOf<Car>());
641 });
642
643 it('should use type factories passes in hierarchical module', () {
644 var module = new Module()
645 ..type(Engine)
646 ..typeFactories = {
647 Engine: (f) => new Engine()
648 };
649
650 module.install(new Module()
651 ..type(Car)
652 ..typeFactories = {
653 Car: (f) => new Car(f(Engine), f(Injector))
654 });
655
656 var injector = new StaticInjector(modules: [module]);
657
658 var engine;
659 expect(() {
660 engine = injector.get(Car);
661 }, isNot(throws));
662 expect(engine, new isInstanceOf<Car>());
663 });
664
665 it('should find type factories from parent injector', () {
666 var module1 = new Module()
667 ..type(Engine)
668 ..typeFactories = {
669 Engine: (f) => new Engine()
670 };
671 var module2 = new Module()
672 ..type(Car)
673 ..typeFactories = {
674 Car: (f) => new Car(f(Engine), f(Injector))
675 };
676
677 var rootInjector = new StaticInjector(modules: [module1]);
678 var childInjector = rootInjector.createChild([module2]);
679
680 expect(() {
681 rootInjector.get(Car);
682 }, throws);
683
684 var engine;
685 expect(() {
686 engine = childInjector.get(Car);
687 }, isNot(throws));
688 expect(engine, new isInstanceOf<Car>());
689 });
690
691 });
692 }
OLDNEW
« no previous file with comments | « third_party/pkg/di/test/generator_test.dart ('k') | third_party/pkg/di/test/type_factories_gen.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698