This repository was archived by the owner on Feb 22, 2018. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 248
/
Copy pathtest_injection.dart
163 lines (149 loc) · 4.29 KB
/
test_injection.dart
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
library angular.mock.test_injection;
import 'package:angular/application_factory.dart';
import 'package:angular/mock/module.dart';
import 'package:di/di.dart';
import 'dart:mirrors';
_SpecInjector _currentSpecInjector = null;
class _SpecInjector {
Injector moduleInjector;
Injector injector;
dynamic injectorCreateLocation;
final modules = <Module>[];
final initFns = <Function>[];
_SpecInjector() {
var moduleModule = new Module()
..bind(Module, toFactory: () => addModule(new Module()));
moduleInjector = new ModuleInjector([moduleModule]);
}
addModule(module) {
if (injector != null) {
throw ["Injector already created, can not add more modules."];
}
modules.add(module);
return module;
}
module(fnOrModule, [declarationStack]) {
if (injectorCreateLocation != null) {
throw "Injector already created at:\n$injectorCreateLocation";
}
try {
if (fnOrModule is Function) {
var initFn = _invoke(moduleInjector, fnOrModule);
if (initFn is Function) initFns.add(initFn);
} else if (fnOrModule is Module) {
addModule(fnOrModule);
} else {
throw 'Unsupported type: $fnOrModule';
}
} catch (e, s) {
throw "$e\n$s\nDECLARED AT:$declarationStack";
}
}
inject(Function fn, [declarationStack]) {
try {
if (injector == null) {
injectorCreateLocation = declarationStack;
injector = new ModuleInjector(modules); // Implicit injection is disabled.
initFns.forEach((fn) {
_invoke(injector, fn);
});
}
_invoke(injector, fn);
} catch (e, s) {
throw "$e\n$s\nDECLARED AT:$declarationStack";
}
}
reset() {
injector = null;
injectorCreateLocation = null;
}
_invoke(Injector injector, Function fn) {
ClosureMirror cm = reflect(fn);
MethodMirror mm = cm.function;
List args = mm.parameters.map((ParameterMirror parameter) {
var metadata = parameter.metadata;
Key key = new Key(
(parameter.type as ClassMirror).reflectedType,
metadata.isEmpty ? null : metadata.first.type.reflectedType);
return injector.getByKey(key);
}).toList();
return cm.apply(args).reflectee;
}
}
/**
* Allows the injection of instances into a test. See [module] on how to install new
* types into injector.
*
* NOTE: Calling inject creates an injector, which prevents any more calls to [module].
*
* NOTE: [inject] will never return the result of [fn]. If you need to return a [Future]
* for unittest to consume, take a look at [async], [clockTick], and [microLeap] instead.
*
* Typical usage:
*
* test('wrap whole test', inject((TestBed tb) {
* tb.compile(...);
* }));
*
* test('wrap part of a test', () {
* module((Module module) {
* module.bind(Foo);
* });
* inject((TestBed tb) {
* tb.compile(...);
* });
* });
*
*/
inject(Function fn) {
try {
throw '';
} catch (e, stack) {
return _currentSpecInjector == null
? () => _currentSpecInjector.inject(fn, stack)
: _currentSpecInjector.inject(fn, stack);
}
}
/**
* Allows the installation of new types/modules into the current test injector.
*
* This method can be called in declaration or inline in test. The method can be called
* repeatedly, as long as [inject] is not called. Invocation of [inject] creates the injector and
* hence no more calls to [module] can be made.
*
* setUp(module((Module module) {
* module.bind(Foo);
* });
*
* test('foo', () {
* module((Module module) {
* module.bind(Foo);
* });
* });
*/
module(fnOrModule) {
try {
throw '';
} catch(e, stack) {
return _currentSpecInjector == null
? () => _currentSpecInjector.module(fnOrModule, stack)
: _currentSpecInjector.module(fnOrModule, stack);
}
}
/**
* Call this method in your test harness [setUp] method to setup the injector.
*/
void setUpInjector() {
_currentSpecInjector = new _SpecInjector();
_currentSpecInjector.module((Module m) {
m
..install(applicationFactory().ngModule)
..install(new AngularMockModule());
});
}
/**
* Call this method in your test harness [tearDown] method to cleanup the injector.
*/
void tearDownInjector() {
_currentSpecInjector = null;
}