2016-06-23 12:47:54 -04:00
|
|
|
/**
|
|
|
|
* @license
|
|
|
|
* Copyright Google Inc. All Rights Reserved.
|
|
|
|
*
|
|
|
|
* Use of this source code is governed by an MIT-style license that can be
|
|
|
|
* found in the LICENSE file at https://angular.io/license
|
|
|
|
*/
|
|
|
|
|
2016-04-28 20:50:03 -04:00
|
|
|
import {provide} from '../index';
|
2016-06-08 19:38:52 -04:00
|
|
|
import {StringMapWrapper} from '../src/facade/collection';
|
|
|
|
import {Math, global, isFunction, isPromise} from '../src/facade/lang';
|
2015-05-20 20:19:46 -04:00
|
|
|
|
2016-06-08 19:38:52 -04:00
|
|
|
import {AsyncTestCompleter} from './async_test_completer';
|
|
|
|
import {getTestInjector, inject} from './test_injector';
|
2015-10-08 18:33:17 -04:00
|
|
|
|
2016-07-01 19:01:57 -04:00
|
|
|
export {MockAnimationPlayer} from '@angular/platform-browser/testing/mock_animation_player';
|
2016-06-08 19:38:52 -04:00
|
|
|
export {AsyncTestCompleter} from './async_test_completer';
|
|
|
|
export {inject} from './test_injector';
|
|
|
|
export {expect} from './testing';
|
2016-06-23 20:10:22 -04:00
|
|
|
export * from './logger';
|
|
|
|
export * from './ng_zone_mock';
|
|
|
|
export * from './mock_application_ref';
|
2016-05-31 18:15:38 -04:00
|
|
|
|
2016-06-08 18:45:15 -04:00
|
|
|
export var proxy: ClassDecorator = (t: any /** TODO #9100 */) => t;
|
2015-05-20 20:19:46 -04:00
|
|
|
|
2016-02-01 13:28:57 -05:00
|
|
|
var _global = <any>(typeof window === 'undefined' ? global : window);
|
2015-05-20 20:19:46 -04:00
|
|
|
|
2015-09-03 17:45:25 -04:00
|
|
|
export var afterEach: Function = _global.afterEach;
|
2015-05-21 19:30:07 -04:00
|
|
|
|
2015-05-20 20:19:46 -04:00
|
|
|
var jsmBeforeEach = _global.beforeEach;
|
|
|
|
var jsmDescribe = _global.describe;
|
|
|
|
var jsmDDescribe = _global.fdescribe;
|
|
|
|
var jsmXDescribe = _global.xdescribe;
|
|
|
|
var jsmIt = _global.it;
|
|
|
|
var jsmIIt = _global.fit;
|
|
|
|
var jsmXIt = _global.xit;
|
|
|
|
|
2016-06-08 18:45:15 -04:00
|
|
|
var runnerStack: any[] /** TODO #9100 */ = [];
|
2015-05-20 20:19:46 -04:00
|
|
|
var inIt = false;
|
2016-04-28 20:50:03 -04:00
|
|
|
jasmine.DEFAULT_TIMEOUT_INTERVAL = 3000;
|
|
|
|
var globalTimeOut = jasmine.DEFAULT_TIMEOUT_INTERVAL;
|
2015-05-20 20:19:46 -04:00
|
|
|
|
2015-12-08 22:03:21 -05:00
|
|
|
var testInjector = getTestInjector();
|
2015-05-20 20:19:46 -04:00
|
|
|
|
2015-08-28 19:23:28 -04:00
|
|
|
/**
|
|
|
|
* Mechanism to run `beforeEach()` functions of Angular tests.
|
|
|
|
*
|
2015-10-11 01:11:13 -04:00
|
|
|
* Note: Jasmine own `beforeEach` is used by this library to handle DI providers.
|
2015-08-28 19:23:28 -04:00
|
|
|
*/
|
2015-05-20 20:19:46 -04:00
|
|
|
class BeforeEachRunner {
|
2016-04-26 16:06:50 -04:00
|
|
|
private _fns: Array<Function> = [];
|
2015-05-20 20:19:46 -04:00
|
|
|
|
2015-08-28 19:23:28 -04:00
|
|
|
constructor(private _parent: BeforeEachRunner) {}
|
2015-05-20 20:19:46 -04:00
|
|
|
|
2016-04-26 16:06:50 -04:00
|
|
|
beforeEach(fn: Function): void { this._fns.push(fn); }
|
2015-08-28 19:23:28 -04:00
|
|
|
|
2015-12-08 22:03:21 -05:00
|
|
|
run(): void {
|
|
|
|
if (this._parent) this._parent.run();
|
2016-04-26 16:06:50 -04:00
|
|
|
this._fns.forEach((fn) => { fn(); });
|
2015-05-20 20:19:46 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-10-11 01:11:13 -04:00
|
|
|
// Reset the test providers before each test
|
2015-12-08 22:03:21 -05:00
|
|
|
jsmBeforeEach(() => { testInjector.reset(); });
|
2015-05-20 20:19:46 -04:00
|
|
|
|
2016-06-08 18:45:15 -04:00
|
|
|
function _describe(jsmFn: any /** TODO #9100 */, ...args: any[] /** TODO #9100 */) {
|
2015-05-20 20:19:46 -04:00
|
|
|
var parentRunner = runnerStack.length === 0 ? null : runnerStack[runnerStack.length - 1];
|
|
|
|
var runner = new BeforeEachRunner(parentRunner);
|
|
|
|
runnerStack.push(runner);
|
2015-06-02 12:51:40 -04:00
|
|
|
var suite = jsmFn(...args);
|
2015-05-20 20:19:46 -04:00
|
|
|
runnerStack.pop();
|
|
|
|
return suite;
|
|
|
|
}
|
|
|
|
|
2016-06-08 18:45:15 -04:00
|
|
|
export function describe(...args: any[] /** TODO #9100 */): void {
|
2015-06-02 12:51:40 -04:00
|
|
|
return _describe(jsmDescribe, ...args);
|
2015-05-20 20:19:46 -04:00
|
|
|
}
|
|
|
|
|
2016-06-08 18:45:15 -04:00
|
|
|
export function ddescribe(...args: any[] /** TODO #9100 */): void {
|
2015-06-02 12:51:40 -04:00
|
|
|
return _describe(jsmDDescribe, ...args);
|
2015-05-20 20:19:46 -04:00
|
|
|
}
|
|
|
|
|
2016-06-08 18:45:15 -04:00
|
|
|
export function xdescribe(...args: any[] /** TODO #9100 */): void {
|
2015-06-02 12:51:40 -04:00
|
|
|
return _describe(jsmXDescribe, ...args);
|
2015-05-20 20:19:46 -04:00
|
|
|
}
|
|
|
|
|
2016-04-26 16:06:50 -04:00
|
|
|
export function beforeEach(fn: Function): void {
|
2015-05-20 20:19:46 -04:00
|
|
|
if (runnerStack.length > 0) {
|
|
|
|
// Inside a describe block, beforeEach() uses a BeforeEachRunner
|
2015-08-28 19:23:28 -04:00
|
|
|
runnerStack[runnerStack.length - 1].beforeEach(fn);
|
2015-05-20 20:19:46 -04:00
|
|
|
} else {
|
|
|
|
// Top level beforeEach() are delegated to jasmine
|
2016-04-26 16:06:50 -04:00
|
|
|
jsmBeforeEach(fn);
|
2015-05-20 20:19:46 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2015-10-11 01:11:13 -04:00
|
|
|
* Allows overriding default providers defined in test_injector.js.
|
2015-05-20 20:19:46 -04:00
|
|
|
*
|
2015-10-11 01:11:13 -04:00
|
|
|
* The given function must return a list of DI providers.
|
2015-05-20 20:19:46 -04:00
|
|
|
*
|
|
|
|
* Example:
|
|
|
|
*
|
2015-11-11 08:28:23 -05:00
|
|
|
* beforeEachProviders(() => [
|
2016-06-02 20:30:40 -04:00
|
|
|
* {provide: Compiler, useClass: MockCompiler},
|
|
|
|
* {provide: SomeToken, useValue: myValue},
|
2015-05-20 20:19:46 -04:00
|
|
|
* ]);
|
|
|
|
*/
|
2016-06-08 18:45:15 -04:00
|
|
|
export function beforeEachProviders(fn: any /** TODO #9100 */): void {
|
2015-05-20 20:19:46 -04:00
|
|
|
jsmBeforeEach(() => {
|
2015-11-11 08:28:23 -05:00
|
|
|
var providers = fn();
|
|
|
|
if (!providers) return;
|
feat(testing): add implicit test module
Every test now has an implicit module. It can be configured via `configureModule` (from @angular/core/testing)
to add providers, directives, pipes, ...
The compiler now has to be configured separately via `configureCompiler` (from @angular/core/testing)
to add providers or define whether to use jit.
BREAKING CHANGE:
- Application providers can no longer inject compiler internals (i.e. everything
from `@angular/compiler). Inject `Compiler` instead. This reflects the
changes to `bootstrap` for module support (3f55aa609f60f130f1d69188ed057214b1267cb3).
- Compiler providers can no longer be added via `addProviders` / `withProviders`.
Use the new method `configureCompiler` instead.
- Platform directives / pipes need to be provided via
`configureModule` and can no longer be provided via the
`PLATFORM_PIPES` / `PLATFORM_DIRECTIVES` tokens.
- `setBaseTestProviders()` was renamed into `initTestEnvironment` and
now takes a `PlatformRef` and a factory for a
`Compiler`.
- E.g. for the browser platform:
BEFORE:
```
import {setBaseTestProviders} from ‘@angular/core/testing’;
import {TEST_BROWSER_DYNAMIC_PLATFORM_PROVIDERS,
TEST_BROWSER_DYNAMIC_APPLICATION_PROVIDERS} from ‘@angular/platform-browser-dynamic/testing’;
setBaseTestProviders(TEST_BROWSER_DYNAMIC_PLATFORM_PROVIDERS,
TEST_BROWSER_DYNAMIC_APPLICATION_PROVIDERS);
```
AFTER:
```
import {setBaseTestProviders} from ‘@angular/core/testing’;
import {browserTestCompiler, browserDynamicTestPlatform,
BrowserDynamicTestModule} from ‘@angular/platform-browser-dynamic/testing’;
initTestEnvironment(
browserTestCompiler,
browserDynamicTestPlatform(),
BrowserDynamicTestModule);
```
- E.g. for the server platform:
BEFORE:
```
import {setBaseTestProviders} from ‘@angular/core/testing’;
import {TEST_SERVER_PLATFORM_PROVIDERS,
TEST_SERVER_APPLICATION_PROVIDERS} from ‘@angular/platform-server/testing/server’;
setBaseTestProviders(TEST_SERVER_PLATFORM_PROVIDERS,
TEST_SERVER_APPLICATION_PROVIDERS);
```
AFTER:
```
import {setBaseTestProviders} from ‘@angular/core/testing’;
import {serverTestCompiler, serverTestPlatform,
ServerTestModule} from ‘@angular/platform-browser-dynamic/testing’;
initTestEnvironment(
serverTestCompiler,
serverTestPlatform(),
ServerTestModule);
```
Related to #9726
Closes #9846
2016-07-04 12:37:30 -04:00
|
|
|
testInjector.configureModule({providers: providers});
|
2015-05-20 20:19:46 -04:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2015-10-11 01:11:13 -04:00
|
|
|
/**
|
|
|
|
* @deprecated
|
|
|
|
*/
|
2016-06-08 18:45:15 -04:00
|
|
|
export function beforeEachBindings(fn: any /** TODO #9100 */): void {
|
2015-10-11 01:11:13 -04:00
|
|
|
beforeEachProviders(fn);
|
|
|
|
}
|
|
|
|
|
2016-04-26 16:06:50 -04:00
|
|
|
function _it(jsmFn: Function, name: string, testFn: Function, testTimeOut: number): void {
|
2016-04-28 20:50:03 -04:00
|
|
|
if (runnerStack.length == 0) {
|
|
|
|
// This left here intentionally, as we should never get here, and it aids debugging.
|
|
|
|
debugger;
|
2016-06-08 19:38:52 -04:00
|
|
|
throw new Error('Empty Stack!');
|
2016-04-28 20:50:03 -04:00
|
|
|
}
|
2015-05-20 20:19:46 -04:00
|
|
|
var runner = runnerStack[runnerStack.length - 1];
|
2015-09-09 10:41:11 -04:00
|
|
|
var timeOut = Math.max(globalTimeOut, testTimeOut);
|
2015-05-20 20:19:46 -04:00
|
|
|
|
2016-06-08 18:45:15 -04:00
|
|
|
jsmFn(name, (done: any /** TODO #9100 */) => {
|
2016-06-02 20:30:40 -04:00
|
|
|
var completerProvider = {
|
|
|
|
provide: AsyncTestCompleter,
|
2016-04-26 16:06:50 -04:00
|
|
|
useFactory: () => {
|
|
|
|
// Mark the test as async when an AsyncTestCompleter is injected in an it()
|
|
|
|
return new AsyncTestCompleter();
|
|
|
|
}
|
2016-06-02 20:30:40 -04:00
|
|
|
};
|
feat(testing): add implicit test module
Every test now has an implicit module. It can be configured via `configureModule` (from @angular/core/testing)
to add providers, directives, pipes, ...
The compiler now has to be configured separately via `configureCompiler` (from @angular/core/testing)
to add providers or define whether to use jit.
BREAKING CHANGE:
- Application providers can no longer inject compiler internals (i.e. everything
from `@angular/compiler). Inject `Compiler` instead. This reflects the
changes to `bootstrap` for module support (3f55aa609f60f130f1d69188ed057214b1267cb3).
- Compiler providers can no longer be added via `addProviders` / `withProviders`.
Use the new method `configureCompiler` instead.
- Platform directives / pipes need to be provided via
`configureModule` and can no longer be provided via the
`PLATFORM_PIPES` / `PLATFORM_DIRECTIVES` tokens.
- `setBaseTestProviders()` was renamed into `initTestEnvironment` and
now takes a `PlatformRef` and a factory for a
`Compiler`.
- E.g. for the browser platform:
BEFORE:
```
import {setBaseTestProviders} from ‘@angular/core/testing’;
import {TEST_BROWSER_DYNAMIC_PLATFORM_PROVIDERS,
TEST_BROWSER_DYNAMIC_APPLICATION_PROVIDERS} from ‘@angular/platform-browser-dynamic/testing’;
setBaseTestProviders(TEST_BROWSER_DYNAMIC_PLATFORM_PROVIDERS,
TEST_BROWSER_DYNAMIC_APPLICATION_PROVIDERS);
```
AFTER:
```
import {setBaseTestProviders} from ‘@angular/core/testing’;
import {browserTestCompiler, browserDynamicTestPlatform,
BrowserDynamicTestModule} from ‘@angular/platform-browser-dynamic/testing’;
initTestEnvironment(
browserTestCompiler,
browserDynamicTestPlatform(),
BrowserDynamicTestModule);
```
- E.g. for the server platform:
BEFORE:
```
import {setBaseTestProviders} from ‘@angular/core/testing’;
import {TEST_SERVER_PLATFORM_PROVIDERS,
TEST_SERVER_APPLICATION_PROVIDERS} from ‘@angular/platform-server/testing/server’;
setBaseTestProviders(TEST_SERVER_PLATFORM_PROVIDERS,
TEST_SERVER_APPLICATION_PROVIDERS);
```
AFTER:
```
import {setBaseTestProviders} from ‘@angular/core/testing’;
import {serverTestCompiler, serverTestPlatform,
ServerTestModule} from ‘@angular/platform-browser-dynamic/testing’;
initTestEnvironment(
serverTestCompiler,
serverTestPlatform(),
ServerTestModule);
```
Related to #9726
Closes #9846
2016-07-04 12:37:30 -04:00
|
|
|
testInjector.configureModule({providers: [completerProvider]});
|
2016-04-26 16:06:50 -04:00
|
|
|
runner.run();
|
|
|
|
|
|
|
|
inIt = true;
|
|
|
|
if (testFn.length == 0) {
|
|
|
|
let retVal = testFn();
|
|
|
|
if (isPromise(retVal)) {
|
|
|
|
// Asynchronous test function that returns a Promise - wait for completion.
|
|
|
|
(<Promise<any>>retVal).then(done, done.fail);
|
|
|
|
} else {
|
|
|
|
// Synchronous test function - complete immediately.
|
|
|
|
done();
|
|
|
|
}
|
2015-08-28 19:23:28 -04:00
|
|
|
} else {
|
2016-04-26 16:06:50 -04:00
|
|
|
// Asynchronous test function that takes in 'done' parameter.
|
|
|
|
testFn(done);
|
2015-08-28 19:23:28 -04:00
|
|
|
}
|
2016-04-26 16:06:50 -04:00
|
|
|
inIt = false;
|
|
|
|
}, timeOut);
|
2015-05-20 20:19:46 -04:00
|
|
|
}
|
|
|
|
|
2016-06-08 19:38:52 -04:00
|
|
|
export function it(
|
|
|
|
name: any /** TODO #9100 */, fn: any /** TODO #9100 */,
|
|
|
|
timeOut: any /** TODO #9100 */ = null): void {
|
2015-06-02 10:29:09 -04:00
|
|
|
return _it(jsmIt, name, fn, timeOut);
|
2015-05-20 20:19:46 -04:00
|
|
|
}
|
|
|
|
|
2016-06-08 19:38:52 -04:00
|
|
|
export function xit(
|
|
|
|
name: any /** TODO #9100 */, fn: any /** TODO #9100 */,
|
|
|
|
timeOut: any /** TODO #9100 */ = null): void {
|
2015-06-02 10:29:09 -04:00
|
|
|
return _it(jsmXIt, name, fn, timeOut);
|
2015-05-20 20:19:46 -04:00
|
|
|
}
|
|
|
|
|
2016-06-08 19:38:52 -04:00
|
|
|
export function iit(
|
|
|
|
name: any /** TODO #9100 */, fn: any /** TODO #9100 */,
|
|
|
|
timeOut: any /** TODO #9100 */ = null): void {
|
2015-06-02 10:29:09 -04:00
|
|
|
return _it(jsmIIt, name, fn, timeOut);
|
2015-05-20 20:19:46 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
export interface GuinessCompatibleSpy extends jasmine.Spy {
|
|
|
|
/** By chaining the spy with and.returnValue, all calls to the function will return a specific
|
|
|
|
* value. */
|
|
|
|
andReturn(val: any): void;
|
|
|
|
/** By chaining the spy with and.callFake, all calls to the spy will delegate to the supplied
|
|
|
|
* function. */
|
|
|
|
andCallFake(fn: Function): GuinessCompatibleSpy;
|
2015-06-24 16:46:39 -04:00
|
|
|
/** removes all recorded calls */
|
2016-06-08 18:45:15 -04:00
|
|
|
reset(): any /** TODO #9100 */;
|
2015-05-20 20:19:46 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
export class SpyObject {
|
2016-06-08 18:45:15 -04:00
|
|
|
constructor(type: any /** TODO #9100 */ = null) {
|
2015-05-20 20:19:46 -04:00
|
|
|
if (type) {
|
|
|
|
for (var prop in type.prototype) {
|
2016-06-08 18:45:15 -04:00
|
|
|
var m: any /** TODO #9100 */ = null;
|
2015-05-20 20:19:46 -04:00
|
|
|
try {
|
|
|
|
m = type.prototype[prop];
|
|
|
|
} catch (e) {
|
|
|
|
// As we are creating spys for abstract classes,
|
|
|
|
// these classes might have getters that throw when they are accessed.
|
|
|
|
// As we are only auto creating spys for methods, this
|
|
|
|
// should not matter.
|
|
|
|
}
|
|
|
|
if (typeof m === 'function') {
|
2015-06-18 18:40:12 -04:00
|
|
|
this.spy(prop);
|
2015-05-20 20:19:46 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2015-09-11 17:51:43 -04:00
|
|
|
// Noop so that SpyObject has the same interface as in Dart
|
2016-06-08 18:45:15 -04:00
|
|
|
noSuchMethod(args: any /** TODO #9100 */) {}
|
2015-05-26 12:25:16 -04:00
|
|
|
|
2016-06-08 18:45:15 -04:00
|
|
|
spy(name: any /** TODO #9100 */) {
|
|
|
|
if (!(this as any /** TODO #9100 */)[name]) {
|
|
|
|
(this as any /** TODO #9100 */)[name] = this._createGuinnessCompatibleSpy(name);
|
2015-05-20 20:19:46 -04:00
|
|
|
}
|
2016-06-08 18:45:15 -04:00
|
|
|
return (this as any /** TODO #9100 */)[name];
|
2015-05-20 20:19:46 -04:00
|
|
|
}
|
|
|
|
|
2016-06-08 19:38:52 -04:00
|
|
|
prop(name: any /** TODO #9100 */, value: any /** TODO #9100 */) {
|
|
|
|
(this as any /** TODO #9100 */)[name] = value;
|
|
|
|
}
|
2015-08-26 14:41:41 -04:00
|
|
|
|
2016-06-08 19:38:52 -04:00
|
|
|
static stub(
|
|
|
|
object: any /** TODO #9100 */ = null, config: any /** TODO #9100 */ = null,
|
|
|
|
overrides: any /** TODO #9100 */ = null) {
|
2015-05-20 20:19:46 -04:00
|
|
|
if (!(object instanceof SpyObject)) {
|
|
|
|
overrides = config;
|
|
|
|
config = object;
|
|
|
|
object = new SpyObject();
|
|
|
|
}
|
|
|
|
|
|
|
|
var m = StringMapWrapper.merge(config, overrides);
|
2016-06-08 19:38:52 -04:00
|
|
|
StringMapWrapper.forEach(m, (value: any /** TODO #9100 */, key: any /** TODO #9100 */) => {
|
|
|
|
object.spy(key).andReturn(value);
|
|
|
|
});
|
2015-05-20 20:19:46 -04:00
|
|
|
return object;
|
|
|
|
}
|
|
|
|
|
2016-05-27 12:16:46 -04:00
|
|
|
/** @internal */
|
2016-06-08 18:45:15 -04:00
|
|
|
_createGuinnessCompatibleSpy(name: any /** TODO #9100 */): GuinessCompatibleSpy {
|
2015-05-20 20:19:46 -04:00
|
|
|
var newSpy: GuinessCompatibleSpy = <any>jasmine.createSpy(name);
|
|
|
|
newSpy.andCallFake = <any>newSpy.and.callFake;
|
|
|
|
newSpy.andReturn = <any>newSpy.and.returnValue;
|
2015-06-24 16:46:39 -04:00
|
|
|
newSpy.reset = <any>newSpy.calls.reset;
|
2015-09-09 22:00:22 -04:00
|
|
|
// revisit return null here (previously needed for rtts_assert).
|
2015-05-20 20:19:46 -04:00
|
|
|
newSpy.and.returnValue(null);
|
|
|
|
return newSpy;
|
|
|
|
}
|
|
|
|
}
|