Adds test adapters for TypeScript and JavaScript only, exported as part of the test_lib module. These work with the Jasmine test framework, and allow use of the test injector within test blocks via the `inject` function. See #4572, #4177, #4035, #2783 This includes the TestComponentBuilder. It allows using the test injector with Jasmine bindings, and waits for returned promises before completing async test blocks.
161 lines
4.0 KiB
Dart
161 lines
4.0 KiB
Dart
library test_lib.test_lib;
|
|
|
|
import 'dart:async';
|
|
|
|
import 'package:guinness/guinness.dart' as gns;
|
|
export 'package:guinness/guinness.dart'
|
|
hide
|
|
Expect,
|
|
expect,
|
|
NotExpect,
|
|
beforeEach,
|
|
it,
|
|
iit,
|
|
xit,
|
|
SpyObject,
|
|
SpyFunction;
|
|
|
|
export 'matchers.dart' show expect, Expect, NotExpect;
|
|
|
|
import 'package:angular2/src/core/reflection/reflection.dart';
|
|
import 'package:angular2/src/core/reflection/reflection_capabilities.dart';
|
|
|
|
import 'package:angular2/src/core/di/provider.dart' show bind;
|
|
import 'package:angular2/src/core/di/injector.dart' show Injector;
|
|
import 'package:angular2/src/core/facade/collection.dart' show StringMapWrapper;
|
|
|
|
import 'test_injector.dart';
|
|
export 'test_injector.dart' show inject;
|
|
|
|
List _testBindings = [];
|
|
Injector _injector;
|
|
bool _isCurrentTestAsync;
|
|
bool _inIt = false;
|
|
|
|
class AsyncTestCompleter {
|
|
final _completer = new Completer();
|
|
|
|
void done() {
|
|
_completer.complete();
|
|
}
|
|
|
|
Future get future => _completer.future;
|
|
}
|
|
|
|
void testSetup() {
|
|
reflector.reflectionCapabilities = new ReflectionCapabilities();
|
|
// beforeEach configuration:
|
|
// - Priority 3: clear the bindings before each test,
|
|
// - Priority 2: collect the bindings before each test, see beforeEachBindings(),
|
|
// - Priority 1: create the test injector to be used in beforeEach() and it()
|
|
|
|
gns.beforeEach(() {
|
|
_testBindings.clear();
|
|
}, priority: 3);
|
|
|
|
var completerBinding = bind(AsyncTestCompleter).toFactory(() {
|
|
// Mark the test as async when an AsyncTestCompleter is injected in an it(),
|
|
if (!_inIt) throw 'AsyncTestCompleter can only be injected in an "it()"';
|
|
_isCurrentTestAsync = true;
|
|
return new AsyncTestCompleter();
|
|
});
|
|
|
|
gns.beforeEach(() {
|
|
_isCurrentTestAsync = false;
|
|
_testBindings.add(completerBinding);
|
|
_injector = createTestInjector(_testBindings);
|
|
}, priority: 1);
|
|
}
|
|
|
|
|
|
/**
|
|
* Allows overriding default bindings defined in test_injector.js.
|
|
*
|
|
* The given function must return a list of DI bindings.
|
|
*
|
|
* Example:
|
|
*
|
|
* beforeEachBindings(() => [
|
|
* bind(Compiler).toClass(MockCompiler),
|
|
* bind(SomeToken).toValue(myValue),
|
|
* ]);
|
|
*/
|
|
void beforeEachProviders(Function fn) {
|
|
gns.beforeEach(() {
|
|
var bindings = fn();
|
|
if (bindings != null) _testBindings.addAll(bindings);
|
|
}, priority: 2);
|
|
}
|
|
|
|
@Deprecated('using beforeEachProviders instead')
|
|
void beforeEachBindings(Function fn) {
|
|
beforeEachProviders(fn);
|
|
}
|
|
|
|
void beforeEach(fn) {
|
|
if (fn is! FunctionWithParamTokens) fn = new FunctionWithParamTokens([], fn, false);
|
|
gns.beforeEach(() {
|
|
fn.execute(_injector);
|
|
});
|
|
}
|
|
|
|
void _it(gnsFn, name, fn) {
|
|
if (fn is! FunctionWithParamTokens) fn = new FunctionWithParamTokens([], fn, false);
|
|
gnsFn(name, () {
|
|
_inIt = true;
|
|
fn.execute(_injector);
|
|
_inIt = false;
|
|
if (_isCurrentTestAsync) return _injector.get(AsyncTestCompleter).future;
|
|
});
|
|
}
|
|
|
|
void it(name, fn, [timeOut = null]) {
|
|
_it(gns.it, name, fn);
|
|
}
|
|
|
|
void iit(name, fn, [timeOut = null]) {
|
|
_it(gns.iit, name, fn);
|
|
}
|
|
|
|
void xit(name, fn, [timeOut = null]) {
|
|
_it(gns.xit, name, fn);
|
|
}
|
|
|
|
class SpyFunction extends gns.SpyFunction {
|
|
SpyFunction(String name) : super(name);
|
|
|
|
// TODO: vsavkin move to guinness
|
|
andReturn(value) {
|
|
return andCallFake(([a0, a1, a2, a3, a4, a5]) => value);
|
|
}
|
|
}
|
|
|
|
class SpyObject extends gns.SpyObject {
|
|
final Map<String, SpyFunction> _spyFuncs = {};
|
|
|
|
SpyObject([arg]) {}
|
|
|
|
SpyFunction spy(String funcName) =>
|
|
_spyFuncs.putIfAbsent(funcName, () => new SpyFunction(funcName));
|
|
|
|
void prop(String funcName, value) {
|
|
_spyFuncs.putIfAbsent("get:${funcName}", () => new SpyFunction(funcName)).andReturn(value);
|
|
}
|
|
|
|
static stub([object = null, config = null, overrides = null]) {
|
|
if (object is! SpyObject) {
|
|
overrides = config;
|
|
config = object;
|
|
object = new SpyObject();
|
|
}
|
|
|
|
var m = StringMapWrapper.merge(config, overrides);
|
|
StringMapWrapper.forEach(m, (value, key) {
|
|
object.spy(key).andReturn(value);
|
|
});
|
|
return object;
|
|
}
|
|
}
|
|
|
|
bool isInInnerZone() => Zone.current['_innerZone'] == true;
|