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

Unified Diff: third_party/pkg/di/test/main.dart

Issue 107003007: Adding Angular's DI package & Dart unittests which test it. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « third_party/pkg/di/test/fixed-unittest.dart ('k') | third_party/pkg/di/test_tf_gen.sh » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: third_party/pkg/di/test/main.dart
diff --git a/third_party/pkg/di/test/main.dart b/third_party/pkg/di/test/main.dart
new file mode 100644
index 0000000000000000000000000000000000000000..4233a35357e4e2be7587f06806e8e5f322b87bcc
--- /dev/null
+++ b/third_party/pkg/di/test/main.dart
@@ -0,0 +1,519 @@
+@Injectables(const [
+ ClassOne,
+ CircularA,
+ CircularB,
+ MultipleConstructors,
+ NumDependency,
+ IntDependency,
+ DoubleDependency,
+ BoolDependency,
+ StringDependency
+])
+library di.tests;
+
+import 'fixed-unittest.dart';
+import 'package:di/di.dart';
+import 'package:di/dynamic_injector.dart';
+import 'package:di/static_injector.dart';
+import 'package:di/annotations.dart';
+
+// Generated file. Run ../test_tf_gen.sh.
+import 'type_factories_gen.dart' as type_factories_gen;
+
+/**
+ * Annotation used to mark classes for which static type factory must be
+ * generated. For testing purposes not all classes are marked with this
+ * annotation, some classes are included in @Injectables at the top.
+ */
+class Injectable {
+ const Injectable();
+}
+
+// just some classes for testing
+@Injectable()
+class Engine {
+ String id = 'v8-id';
+}
+
+@Injectable()
+class MockEngine implements Engine {
+ String id = 'mock-id';
+}
+
+@Injectable()
+class MockEngine2 implements Engine {
+ String id = 'mock-id-2';
+}
+
+@Injectable()
+class Car {
+ Engine engine;
+ Injector injector;
+
+ Car(this.engine, this.injector);
+}
+
+class NumDependency {
+ NumDependency(num value) {}
+}
+
+class IntDependency {
+ IntDependency(int value) {}
+}
+
+class DoubleDependency {
+ DoubleDependency(double value) {}
+}
+
+class StringDependency {
+ StringDependency(String value) {}
+}
+
+class BoolDependency {
+ BoolDependency(bool value) {}
+}
+
+
+class CircularA {
+ CircularA(CircularB b) {}
+}
+
+class CircularB {
+ CircularB(CircularA a) {}
+}
+
+typedef int CompareInt(int a, int b);
+
+int compareIntAsc(int a, int b) => b.compareTo(a);
+
+class WithTypeDefDependency {
+ CompareInt compare;
+
+ WithTypeDefDependency(CompareInt c) {
+ compare = c;
+ }
+}
+
+class MultipleConstructors {
+ String instantiatedVia;
+ MultipleConstructors() : instantiatedVia = 'default';
+ MultipleConstructors.named() : instantiatedVia = 'named';
+}
+
+class InterfaceOne {
+}
+
+class ClassOne implements InterfaceOne {
+ ClassOne(Log log) {
+ log.add('ClassOne');
+ }
+}
+
+@Injectable()
+class Log {
+ var log = [];
+
+ add(String message) => log.add(message);
+}
+
+class EmulatedMockEngineFactory {
+ call(Injector i) => new MockEngine();
+}
+
+void main() {
+ createInjectorSpec('DynamicInjector',
+ (modules, [name]) => new DynamicInjector(modules: modules, name: name));
+
+ // Initialize generated type factories.
+ type_factories_gen.main();
+
+ createInjectorSpec('StaticInjector',
+ (modules, [name]) => new StaticInjector(modules: modules, name: name,
+ typeFactories: type_factories_gen.typeFactories));
+}
+
+typedef Injector InjectorFactory(List<Module> modules, [String name]);
+
+createInjectorSpec(String injectorName, InjectorFactory injectorFactory) {
+
+ describe(injectorName, () {
+
+ it('should instantiate a type', () {
+ var injector = injectorFactory([new Module()..type(Engine)]);
+ var instance = injector.get(Engine);
+
+ expect(instance, instanceOf(Engine));
+ expect(instance.id, toEqual('v8-id'));
+ });
+
+ it('should fail if no binding is found', () {
+ var injector = injectorFactory([]);
+ expect(() {
+ injector.get(Engine);
+ }, toThrow(NoProviderError, 'No provider found for Engine! '
+ '(resolving Engine)'));
+ });
+
+
+ it('should resolve basic dependencies', () {
+ var injector = injectorFactory([new Module()..type(Car)..type(Engine)]);
+ var instance = injector.get(Car);
+
+ expect(instance, instanceOf(Car));
+ expect(instance.engine.id, toEqual('v8-id'));
+ });
+
+
+ it('should allow modules and overriding providers', () {
+ var module = new Module()..type(Engine, implementedBy: MockEngine);
+
+ // injector is immutable
+ // you can't load more modules once it's instantiated
+ // (you can create a child injector)
+ var injector = injectorFactory([module]);
+ var instance = injector.get(Engine);
+
+ expect(instance.id, toEqual('mock-id'));
+ });
+
+
+ it('should only create a single instance', () {
+ var injector = injectorFactory([new Module()..type(Engine)]);
+ var first = injector.get(Engine);
+ var second = injector.get(Engine);
+
+ expect(first, toBe(second));
+ });
+
+
+ it('should allow providing values', () {
+ var module = new Module()
+ ..value(Engine, 'str value')
+ ..value(Car, 123);
+
+ var injector = injectorFactory([module]);
+ var abcInstance = injector.get(Engine);
+ var complexInstance = injector.get(Car);
+
+ expect(abcInstance, toEqual('str value'));
+ expect(complexInstance, toEqual(123));
+ });
+
+
+ it('should allow providing factory functions', () {
+ var module = new Module()..factory(Engine, (Injector injector) {
+ return 'factory-product';
+ });
+
+ var injector = injectorFactory([module]);
+ var instance = injector.get(Engine);
+
+ expect(instance, toEqual('factory-product'));
+ });
+
+
+ it('should allow providing with emulated factory functions', () {
+ var module = new Module();
+ module.factory(Engine, new EmulatedMockEngineFactory());
+
+ var injector = injectorFactory([module]);
+ var instance = injector.get(Engine);
+
+ expect(instance, new isInstanceOf<MockEngine>());
+ });
+
+
+ it('should inject injector into factory function', () {
+ var module = new Module()
+ ..type(Engine)
+ ..factory(Car, (Injector injector) {
+ return new Car(injector.get(Engine), injector);
+ });
+
+ var injector = injectorFactory([module]);
+ var instance = injector.get(Car);
+
+ expect(instance, instanceOf(Car));
+ expect(instance.engine.id, toEqual('v8-id'));
+ });
+
+
+ it('should throw an exception when injecting a primitive type', () {
+ var injector = injectorFactory([
+ new Module()
+ ..type(NumDependency)
+ ..type(IntDependency)
+ ..type(DoubleDependency)
+ ..type(BoolDependency)
+ ..type(StringDependency)
+ ]);
+
+ expect(() {
+ injector.get(NumDependency);
+ }, toThrow(NoProviderError, 'Cannot inject a primitive type of num! '
+ '(resolving NumDependency -> num)'));
+
+ expect(() {
+ injector.get(IntDependency);
+ }, toThrow(NoProviderError, 'Cannot inject a primitive type of int! '
+ '(resolving IntDependency -> int)'));
+
+ expect(() {
+ injector.get(DoubleDependency);
+ }, toThrow(NoProviderError, 'Cannot inject a primitive type of double! '
+ '(resolving DoubleDependency -> double)'));
+
+ expect(() {
+ injector.get(BoolDependency);
+ }, toThrow(NoProviderError, 'Cannot inject a primitive type of bool! '
+ '(resolving BoolDependency -> bool)'));
+
+ expect(() {
+ injector.get(StringDependency);
+ }, toThrow(NoProviderError, 'Cannot inject a primitive type of String! '
+ '(resolving StringDependency -> String)'));
+ });
+
+
+ it('should throw an exception when circular dependency', () {
+ var injector = injectorFactory([new Module()..type(CircularA)..type(CircularB)]);
+
+ expect(() {
+ injector.get(CircularA);
+ }, toThrow(CircularDependencyError, 'Cannot resolve a circular dependency! '
+ '(resolving CircularA -> '
+ 'CircularB -> CircularA)'));
+ });
+
+
+ it('should provide the injector as Injector', () {
+ var injector = injectorFactory([]);
+
+ expect(injector.get(Injector), toBe(injector));
+ });
+
+
+ // Typedef injection is not supported in dart2js: http://dartbug.com/11612
+ xit('should inject a typedef', () {
+ var module = new Module()..value(CompareInt, compareIntAsc);
+
+ var injector = injectorFactory([module]);
+ var compare = injector.get(CompareInt);
+
+ expect(compare(1, 2), toBe(1));
+ expect(compare(5, 2), toBe(-1));
+ });
+
+
+ // Typedef injection is not supported in dart2js: http://dartbug.com/11612
+ xit('should throw an exception when injecting typedef without providing it', () {
+ var injector = injectorFactory([new Module()..type(WithTypeDefDependency)]);
+
+ expect(() {
+ injector.get(WithTypeDefDependency);
+ }, toThrow(NoProviderError, 'No provider found for CompareInt! '
+ '(resolving WithTypeDefDependency -> CompareInt)'));
+ });
+
+
+ it('should instantiate via the default/unnamed constructor', () {
+ var injector = injectorFactory([new Module()..type(MultipleConstructors)]);
+ MultipleConstructors instance = injector.get(MultipleConstructors);
+ expect(instance.instantiatedVia, 'default');
+ });
+
+ // CHILD INJECTORS
+ it('should inject from child', () {
+ var module = new Module()..type(Engine, implementedBy: MockEngine);
+
+ var parent = injectorFactory([new Module()..type(Engine)]);
+ var child = parent.createChild([module]);
+
+ var abcFromParent = parent.get(Engine);
+ var abcFromChild = child.get(Engine);
+
+ expect(abcFromParent.id, toEqual('v8-id'));
+ expect(abcFromChild.id, toEqual('mock-id'));
+ });
+
+
+ it('should enumerate across children', () {
+ var parent = injectorFactory([new Module()..type(Engine)]);
+ var child = parent.createChild([new Module()..type(MockEngine)]);
+
+ expect(parent.types, unorderedEquals(new Set.from([Engine, Injector])));
+ expect(child.types, unorderedEquals(new Set.from([Engine, MockEngine, Injector])));
+ });
+
+
+ it('should inject instance from parent if not provided in child', () {
+ var module = new Module()..type(Car);
+
+ var parent = injectorFactory([new Module()..type(Car)..type(Engine)]);
+ var child = parent.createChild([module]);
+
+ var complexFromParent = parent.get(Car);
+ var complexFromChild = child.get(Car);
+ var abcFromParent = parent.get(Engine);
+ var abcFromChild = child.get(Engine);
+
+ expect(complexFromChild, not(toBe(complexFromParent)));
+ expect(abcFromChild, toBe(abcFromParent));
+ });
+
+
+ it('should inject instance from parent but never use dependency from child', () {
+ var module = new Module()..type(Engine, implementedBy: MockEngine);
+
+ var parent = injectorFactory([new Module()..type(Car)..type(Engine)]);
+ var child = parent.createChild([module]);
+
+ var complexFromParent = parent.get(Car);
+ var complexFromChild = child.get(Car);
+ var abcFromParent = parent.get(Engine);
+ var abcFromChild = child.get(Engine);
+
+ expect(complexFromChild, toBe(complexFromParent));
+ expect(complexFromChild.engine, toBe(abcFromParent));
+ expect(complexFromChild.engine, not(toBe(abcFromChild)));
+ });
+
+
+ it('should force new instance in child even if already instantiated in parent', () {
+ var parent = injectorFactory([new Module()..type(Engine)]);
+ var abcAlreadyInParent = parent.get(Engine);
+
+ var child = parent.createChild([], forceNewInstances: [Engine]);
+ var abcFromChild = child.get(Engine);
+
+ expect(abcFromChild, not(toBe(abcAlreadyInParent)));
+ });
+
+
+ it('should force new instance in child using provider from grand parent', () {
+ var module = new Module()..type(Engine, implementedBy: MockEngine);
+
+ var grandParent = injectorFactory([module]);
+ var parent = grandParent.createChild([]);
+ var child = parent.createChild([], forceNewInstances: [Engine]);
+
+ var abcFromGrandParent = grandParent.get(Engine);
+ var abcFromChild = child.get(Engine);
+
+ expect(abcFromChild.id, toEqual(('mock-id')));
+ expect(abcFromChild, not(toBe(abcFromGrandParent)));
+ });
+
+
+ it('should provide child injector as Injector', () {
+ var injector = injectorFactory([]);
+ var child = injector.createChild([]);
+
+ expect(child.get(Injector), toBe(child));
+ });
+
+
+ it('should set the injector name', () {
+ var injector = injectorFactory([], 'foo');
+ expect(injector.name, 'foo');
+ });
+
+
+ it('should set the child injector name', () {
+ var injector = injectorFactory([], 'foo');
+ var childInjector = injector.createChild(null, name: 'bar');
+ expect(childInjector.name, 'bar');
+ });
+
+
+ it('should instantiate class only once (Issue #18)', () {
+ var injector = injectorFactory([
+ new Module()
+ ..type(Log)
+ ..type(ClassOne)
+ ..factory(InterfaceOne, (i) => i.get(ClassOne))
+ ]);
+
+ expect(injector.get(InterfaceOne), same(injector.get(ClassOne)));
+ expect(injector.get(Log).log.join(' '), 'ClassOne');
+ });
+
+
+ describe('creation strategy', () {
+
+ it('should get called for instance creation', () {
+
+ List creationLog = [];
+ dynamic creation(Injector requesting, Injector defining, factory) {
+ creationLog.add([requesting, defining]);
+ return factory();
+ }
+
+ var parentModule = new Module()
+ ..type(Engine, implementedBy: MockEngine, creation: creation)
+ ..type(Car, creation: creation);
+
+ var parentInjector = injectorFactory([parentModule]);
+ var childInjector = parentInjector.createChild([]);
+ childInjector.get(Car);
+ expect(creationLog, [
+ [childInjector, parentInjector],
+ [childInjector, parentInjector]
+ ]);
+ });
+
+ it('should be able to prevent instantiation', () {
+
+ List creationLog = [];
+ dynamic creation(Injector requesting, Injector defining, factory) {
+ throw 'not allowing';
+ }
+
+ var module = new Module()
+ ..type(Engine, implementedBy: MockEngine, creation: creation);
+ var injector = injectorFactory([module]);
+ expect(() {
+ injector.get(Engine);
+ }, throwsA('not allowing'));
+ });
+ });
+
+
+ describe('visiblity', () {
+
+ it('should hide instances', () {
+
+ var rootMock = new MockEngine();
+ var childMock = new MockEngine();
+
+ var parentModule = new Module()
+ ..value(Engine, rootMock);
+ var childModule = new Module()
+ ..value(Engine, childMock, visibility: (_, __) => false);
+
+ var parentInjector = injectorFactory([parentModule]);
+ var childInjector = parentInjector.createChild([childModule]);
+
+ var val = childInjector.get(Engine);
+ expect(val, same(rootMock));
+ });
+
+ it('should throw when an instance in not visible in the root injector', () {
+ var module = new Module()
+ ..value(Car, 'Invisible', visibility: (_, __) => false);
+
+ var injector = injectorFactory([module]);
+
+ expect(() {
+ injector.get(Car);
+ }, toThrow(
+ NoProviderError,
+ 'No provider found for Car! (resolving Car)'
+ ));
+ });
+
+ });
+
+ });
+
+}
« no previous file with comments | « third_party/pkg/di/test/fixed-unittest.dart ('k') | third_party/pkg/di/test_tf_gen.sh » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698